{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:////home/vsts/work/1/s/platform/core/src/log.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/sopClassDictionary.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/layoutButton/LayoutChooser.js","webpack:////home/vsts/work/1/s/platform/ui/src/viewer/ToolbarButton.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/layoutButton/LayoutButton.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/tableList/TableListItem.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/measurementTable/MeasurementTableItem.js","webpack:////home/vsts/work/1/s/platform/ui/src/ScrollableArea/ScrollableArea.js","webpack:////home/vsts/work/1/s/platform/ui/src/utils/throttled.js","webpack:////home/vsts/work/1/s/platform/ui/src/utils/getScrollbarSize.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/tableList/TableList.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/measurementTable/MeasurementTable.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/content/aboutContent/AboutContent.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/tabComponents/TabComponents.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/tabComponents/TabFooter.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/customForm/HotkeyField.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/languageSwitcher/LanguageSwitcher.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/checkbox/checkbox.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/cineDialog/CineDialog.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/content/viewportDownloadForm/ViewportDownloadForm.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/quickSwitch/StudiesItem.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/quickSwitch/StudiesList.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/quickSwitch/SeriesList.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/quickSwitch/QuickSwitch.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/roundedButtonGroup/RoundedButtonGroup.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/selectTree/InputRadio.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/selectTree/SelectTreeBreadcrumb.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/selectTree/SelectTree.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/simpleDialog/SimpleDialog.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/ohifModal/OHIFModal.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/contextMenu/ContextMenu.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/errorPage/ErrorPage.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/errorPage/index.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/studyList/CustomDateRangePicker.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/studyList/TableSearchFilter.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/studyList/StudyListLoadingText.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/studyList/StudyList.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/studyList/TablePagination.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/studyList/PageToolbar.js","webpack:////home/vsts/work/1/s/platform/ui/src/viewer/ExpandableToolMenu.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/toolbarSection/ToolbarSection.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/errorBoundary/ErrorBoundary.js","webpack:////home/vsts/work/1/s/platform/ui/src/hooks/useMedia.js","webpack:////home/vsts/work/1/s/platform/ui/src/hooks/useDebounce.js","webpack:////home/vsts/work/1/s/platform/ui/src/elements/form/OldSelect.js","webpack:////home/vsts/work/1/s/platform/ui/src/elements/form/Select.js","webpack:////home/vsts/work/1/s/platform/ui/src/elements/form/Label.js","webpack:////home/vsts/work/1/s/platform/ui/src/elements/form/Range.js","webpack:////home/vsts/work/1/s/platform/ui/src/elements/form/TextArea.js","webpack:////home/vsts/work/1/s/platform/ui/src/elements/form/TextInput.js","webpack:////home/vsts/work/1/s/platform/ui/src/elements/form/DropdownMenu.js","webpack:////home/vsts/work/1/s/platform/ui/src/viewer/PlayClipButton.js","webpack:////home/vsts/work/1/s/platform/ui/src/viewer/SimpleToolbarButton.js","webpack:////home/vsts/work/1/s/platform/ui/src/viewer/Toolbar.js","webpack:////home/vsts/work/1/s/platform/ui/src/utils/viewerbaseDragDropContext.js","webpack:////home/vsts/work/1/s/platform/ui/src/utils/asyncComponent/asyncComponent.js","webpack:////home/vsts/work/1/s/platform/ui/src/index.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMWeb/index.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMWeb/getAttribute.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMWeb/getAuthorizationHeader.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMWeb/getModalities.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMWeb/getName.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMWeb/getNumber.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMWeb/getString.js","webpack:////home/vsts/work/1/s/platform/core/src/cornerstone.js","webpack:////home/vsts/work/1/s/platform/core/src/lib/cornerstone.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/lib/validate.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/customAttributes.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/HPMatcher.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/customViewportSettings.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/lib/comparators.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/classes/Rule.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/classes/rules.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/lib/removeFromArray.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/classes/ViewportStructure.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/classes/Viewport.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/classes/Stage.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/classes/Protocol.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/ProtocolEngine.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/lib/sortByScore.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/protocolStore/classes/ProtocolStore.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/protocolStore/defaultProtocol.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/index.js","webpack:////home/vsts/work/1/s/platform/core/src/hanging-protocols/protocolStore/classes/ProtocolStrategy.js","webpack:////home/vsts/work/1/s/platform/core/src/header.js","webpack:////home/vsts/work/1/s/platform/core/src/object.js","webpack:////home/vsts/work/1/s/platform/core/src/string.js","webpack:////home/vsts/work/1/s/platform/core/src/ui/index.js","webpack:////home/vsts/work/1/s/platform/core/src/ui/getScrollbarSize.js","webpack:////home/vsts/work/1/s/platform/core/src/ui/getOffset.js","webpack:////home/vsts/work/1/s/platform/core/src/ui/isCharacterKeyPress.js","webpack:////home/vsts/work/1/s/platform/core/src/ui/handleError.js","webpack:////home/vsts/work/1/s/platform/core/src/index.js","webpack:////home/vsts/work/1/s/platform/ui/src/elements/Icon/getIcon.js","webpack:////home/vsts/work/1/s/platform/ui/src/elements/Icon/Icon.js","webpack:////home/vsts/work/1/s/platform/ui/src/elements/Icon/index.js","webpack:////home/vsts/work/1/s/platform/ui/src/contextProviders/ModalProvider.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/snackbar/SnackbarItem.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/snackbar/SnackbarContainer.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/snackbar/SnackbarTypes.js","webpack:////home/vsts/work/1/s/platform/ui/src/contextProviders/SnackbarProvider.js","webpack:////home/vsts/work/1/s/platform/ui/src/contextProviders/LanguageProvider.js","webpack:////home/vsts/work/1/s/platform/ui/src/contextProviders/DialogProvider.js","webpack:////home/vsts/work/1/s/platform/ui/src/contextProviders/LoggerProvider.js","webpack:////home/vsts/work/1/s/platform/ui/src/contextProviders/index.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/guid.js","webpack:////home/vsts/work/1/s/platform/core/src/errorHandler.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/OHIFError.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/xhrRetryRequestHook.js","webpack:////home/vsts/work/1/s/platform/core/src/user.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/metadata/Metadata.js","webpack:////home/vsts/work/1/s/extensions/cornerstone/src/state.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/metadata/InstanceMetadata.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/metadata/SeriesMetadata.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/overlayTrigger/Fade.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/overlayTrigger/Overlay.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/overlayTrigger/createChainedFunction.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/overlayTrigger/OverlayTrigger.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/overlayTrigger/index.js","webpack:///./context/AppContext.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/tooltip/Tooltip.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/tooltip/index.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/metadataProvider/fetchPaletteColorLookupTableData.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/metadataProvider/unpackOverlay.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/metadataProvider/fetchOverlayData.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/metadataProvider/validNumber.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/MetadataProvider.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/metadataProvider/getPixelSpacingInformation.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/hotkeys/pausePlugin.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/hotkeys/recordPlugin.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/hotkeys/index.js","webpack:////home/vsts/work/1/s/platform/core/src/enums.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/studyMetadataManager.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/metadata/OHIFInstanceMetadata.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/metadata/OHIFSeriesMetadata.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/metadata/OHIFStudyMetadata.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/metadata/index.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/isDisplaySetReconstructable.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/metadata/StudyMetadata.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/naturalizeSOPClassUID.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/ImageSet.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/getImageId.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/StudyMetadataSource.js","webpack:////home/vsts/work/1/s/platform/i18n/src/config.js","webpack:////home/vsts/work/1/s/platform/i18n/src/debugger.js","webpack:////home/vsts/work/1/s/platform/i18n/src/locales/index.js","webpack:////home/vsts/work/1/s/platform/i18n/src/locales/de/index.js","webpack:////home/vsts/work/1/s/platform/i18n/src/locales/en-US/index.js","webpack:////home/vsts/work/1/s/platform/i18n/src/locales/es/index.js","webpack:////home/vsts/work/1/s/platform/i18n/src/locales/fr/index.js","webpack:////home/vsts/work/1/s/platform/i18n/src/locales/ja-JP/index.js","webpack:////home/vsts/work/1/s/platform/i18n/src/locales/nl/index.js","webpack:////home/vsts/work/1/s/platform/i18n/src/locales/pt-BR/index.js","webpack:////home/vsts/work/1/s/platform/i18n/src/locales/ru/index.js","webpack:////home/vsts/work/1/s/platform/i18n/src/locales/vi/index.js","webpack:////home/vsts/work/1/s/platform/i18n/src/locales/zh/index.js","webpack:////home/vsts/work/1/s/platform/i18n/src/getAvailableLanguagesInfo.js","webpack:////home/vsts/work/1/s/platform/i18n/src/index.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/retrieveStudyMetadata.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/str2ab.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/objectPath.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/absoluteUrl.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/addServers.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/dicomLoaderService.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/b64toBlob.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/loadAndCacheDerivedDisplaySets.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/urlUtil.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/makeDeferred.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/Queue.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/hierarchicalListUtils.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/progressTrackingUtils.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/index.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/writeScript.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/makeCancelable.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/isDicomUid.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/resolveObjectPath.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/StudyPrefetcher.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/StudyLoadingListener.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/PubSub.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/LogManager.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/OHIFStudyMetadataSource.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/index.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/isImage.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/isLowPriorityModality.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/sortBy.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/StackManager.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/TypeSafeCollection.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/tools/arrowAnnotate.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/tools/bidirectional.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/tools/ellipticalRoi.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/tools/circleRoi.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/tools/freehandMouse.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/tools/length.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/tools/nonTarget.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/tools/rectangleRoi.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/tools/angle.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/tools/targetCR.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/tools/targetNE.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/tools/targetUN.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/tools/dicomSRDisplayTool.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/toolGroups/allTools.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/configuration.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/dataExchange.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/classes/TimepointApi.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/lib/getLabel.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/lib/getDescription.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/lib/getImageIdForImagePath.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/classes/MeasurementApi.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/conformance/criteria/BaseCriterion.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/conformance/criteria/Location.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/conformance/criteria/MaxTargetsPerOrgan.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/conformance/criteria/MaxTargets.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/conformance/criteria/MeasurementsLength.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/conformance/criteria/Modality.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/conformance/criteria/NonTargetResponse.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/conformance/criteria/TargetType.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/conformance/CriteriaEvaluator.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/conformance/evaluations/index.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/conformance/ConformanceCriteria.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/lib/getImageAttributes.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/lib/refreshCornerstoneViewports.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/measurementHandlers/handleSingleMeasurementAdded.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/measurementHandlers/handleChildMeasurementAdded.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/measurementHandlers/handleSingleMeasurementModified.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/measurementHandlers/handleChildMeasurementModified.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/measurementHandlers/handleSingleMeasurementRemoved.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/measurementHandlers/handleChildMeasurementRemoved.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/measurementHandlers/index.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/toolGroups/targets.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/toolGroups/nonTargets.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/toolGroups/temp.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/ltTools.js","webpack:////home/vsts/work/1/s/platform/core/src/measurements/index.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/services/qido/instances.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/services/qido/studies.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/services/index.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/searchStudies.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/index.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/retrieveStudiesMetadata.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/getStudyBoxData.js","webpack:////home/vsts/work/1/s/platform/core/src/utils/getWADORSImageId.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/getSeriesInfo.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/sortStudy.js","webpack:///./routes/routesUtil.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/services/wado/getReferencedSeriesSequence.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/services/wado/studyInstanceHelpers.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/services/wado/retrieveMetadataLoader.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/services/wado/retrieveMetadataLoaderSync.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/services/wado/retrieveMetadataLoaderAsync.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/services/wado/retrieveMetadata.js","webpack:////home/vsts/work/1/s/platform/ui/src/viewer/ViewportErrorIndicator.js","webpack:////home/vsts/work/1/s/platform/ui/src/viewer/ViewportLoadingIndicator.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/studyBrowser/ImageThumbnail.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/studyBrowser/Thumbnail.js","webpack:////home/vsts/work/1/s/platform/core/src/studies/services/qido/StaticWadoClient.js","webpack:///./store/layout/selectors.js","webpack:///./context/WhiteLabelingContext.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/CommandsManager.js","webpack:////home/vsts/work/1/s/platform/core/src/classes/HotkeysManager.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/enums.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/utils/getSequenceAsArray.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/utils/getMergedContentSequencesByTrackingUniqueIdentifiers.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/utils/getLabelFromMeasuredValueSequence.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/utils/getCoordsFromSCOORDOrSCOORD3D.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/utils/processTID1410Measurement.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/utils/processNonGeometricallyDefinedMeasurement.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/utils/processMeasurement.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/utils/getMeasurements.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/utils/getReferencedImagesList.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/utils/isRehydratable.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/constants/toolNames.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/constants/scoordTypes.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/utils/getRenderableData.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/utils/addMeasurement.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/SCOORD3D/parseSCOORD3D.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/utils/findInstanceMetadataBySopInstanceUid.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/parseDicomStructuredReport.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/utils/isToolSupported.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/parseMeasurementsData.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/utils/getAllDisplaySets.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/handleStructuredReport.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/utils/findMostRecentStructuredReport.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/dataExchange.js","webpack:////home/vsts/work/1/s/platform/core/src/DICOMSR/index.js","webpack:////home/vsts/work/1/s/platform/core/src/redux/constants/ActionTypes.js","webpack:////home/vsts/work/1/s/platform/core/src/redux/actions.js","webpack:////home/vsts/work/1/s/platform/core/src/redux/reducers/extensions.js","webpack:////home/vsts/work/1/s/platform/core/src/redux/reducers/preferences.js","webpack:////home/vsts/work/1/s/platform/core/src/redux/reducers/servers.js","webpack:////home/vsts/work/1/s/platform/core/src/redux/reducers/studies.js","webpack:////home/vsts/work/1/s/platform/core/src/redux/reducers/timepointManager.js","webpack:////home/vsts/work/1/s/platform/core/src/redux/reducers/viewports.js","webpack:////home/vsts/work/1/s/platform/core/src/redux/reducers/index.js","webpack:////home/vsts/work/1/s/platform/core/src/redux/localStorage.js","webpack:////home/vsts/work/1/s/platform/core/src/redux/sessionStorage.js","webpack:////home/vsts/work/1/s/platform/core/src/redux/index.js","webpack:////home/vsts/work/1/s/extensions/cornerstone/src/initCornerstoneTools.js","webpack:////home/vsts/work/1/s/extensions/cornerstone/src/utils/measurementServiceMappings/measurementServiceMappingsFactory.js","webpack:////home/vsts/work/1/s/extensions/cornerstone/src/tools/modules/dicomSRModule.js","webpack:////home/vsts/work/1/s/extensions/cornerstone/src/init.js","webpack:////home/vsts/work/1/s/extensions/cornerstone/src/utils/setCornerstoneLayout.js","webpack:////home/vsts/work/1/s/extensions/cornerstone/src/CornerstoneViewportDownloadForm.js","webpack:////home/vsts/work/1/s/extensions/cornerstone/src/commandsModule.js","webpack:////home/vsts/work/1/s/extensions/cornerstone/src/toolbarModule.js","webpack:////home/vsts/work/1/s/extensions/cornerstone/src/index.js","webpack:///./version.js","webpack:///./utils/getUserManagerForOpenIdConnectClient.js","webpack:///./utils/initWebWorkers.js","webpack:///./store/index.js","webpack:///./appExtensions/GenericViewerCommands/commandsModule.js","webpack:///./appExtensions/GenericViewerCommands/index.js","webpack:///./appExtensions/MeasurementsPanel/jumpToRowItem.js","webpack:///./appExtensions/MeasurementsPanel/ConnectedMeasurementTable.js","webpack:///./components/Labelling/LabellingTransition.js","webpack:///./components/Labelling/OHIFLabellingData.js","webpack:///./components/SimpleDialog/SimpleDialog.js","webpack:///./components/EditDescriptionDialog/EditDescriptionDialog.js","webpack:///./components/Labelling/LabellingFlow.js","webpack:///./connectedComponents/ToolContextMenu.js","webpack:///./appExtensions/MeasurementsPanel/init.js","webpack:///./appExtensions/MeasurementsPanel/index.js","webpack:///./components/LoadingBar/Bar.js","webpack:///./components/LoadingBar/Container.js","webpack:///./OHIFStandaloneViewer.js","webpack:///./App.js","webpack:///./config.js","webpack:///./routes/NotFound.js","webpack:////home/vsts/work/1/s/platform/ui/src/components/studyBrowser/StudyBrowser.js","webpack:////home/vsts/work/1/s/extensions/cornerstone/src/tools/id.js","webpack:///./context/UserManagerContext.js","webpack:///./components/OHIFLogo/OHIFLogo.js","webpack:////home/vsts/work/1/s/platform/core/src/extensions/MODULE_TYPES.js","webpack:////home/vsts/work/1/s/extensions/vtk/src/VTKViewport.js","webpack:////home/vsts/work/1/s/extensions/vtk/src/ConnectedVTKViewport.js","webpack:////home/vsts/work/1/s/extensions/vtk/src/LoadingIndicator.js","webpack:////home/vsts/work/1/s/extensions/vtk/src/OHIFVTKViewport.js","webpack:////home/vsts/work/1/s/node_modules/moment/locale sync ^\\.\\/.*$","webpack:////home/vsts/work/1/s/extensions/vtk/src/utils/setLayoutAndViewportData.js","webpack:////home/vsts/work/1/s/extensions/vtk/src/utils/setMPRLayout.js","webpack:////home/vsts/work/1/s/extensions/vtk/src/utils/setViewportToVTK.js","webpack:////home/vsts/work/1/s/extensions/vtk/src/commandsModule.js","webpack:////home/vsts/work/1/s/extensions/vtk/src/toolbarComponents/SlabThicknessToolbarComponent.js","webpack:////home/vsts/work/1/s/extensions/vtk/src/toolbarComponents/VTKMPRToolbarButton.js","webpack:////home/vsts/work/1/s/extensions/vtk/src/toolbarModule.js","webpack:////home/vsts/work/1/s/extensions/vtk/src/withCommandsManager.js","webpack:////home/vsts/work/1/s/extensions/vtk/src/index.js","webpack:////home/vsts/work/1/s/extensions/dicom-html/src/OHIFDicomHtmlSopClassHandler.js","webpack:////home/vsts/work/1/s/extensions/dicom-html/src/index.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/utils/drawCanvasCrosshairs.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/tools/DICOMSegTempCrosshairsTool.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/tools/TOOL_NAMES.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/toolbarModule.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/loadSegmentation.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/utils/refreshViewports.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/utils/setActiveLabelMap.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/getSourceDisplaySet.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/getOHIFDicomSegSopClassHandler.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/components/BrushColorSelector/BrushColorSelector.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/components/BrushRadius/BrushRadius.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/components/SegmentationItem/SegmentationItem.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/components/SegmentationSettings/SegmentationSettings.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/components/SegmentItem/SegmentItem.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/components/SegmentationSelect.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/components/SegmentationPanel/SegmentationPanel.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/index.js","webpack:////home/vsts/work/1/s/extensions/dicom-segmentation/src/init.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/utils/toolNames.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/utils/drawCanvasCrosshairs.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/tools/RTStructDisplayTool.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/tools/modules/lib/getImageIdOfCenterFrameOfROIContour.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/tools/modules/rtStructModule.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/tools/modules/lib/structureSetReferencesSeriesInstanceUid.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/init.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/utils/transformPointsToImagePlane.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/loadRTStruct.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/getSourceDisplaySet.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/OHIFDicomRTStructSopClassHandler.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/components/StructureSetItem/StructureSetItem.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/components/RTSettings/RTSettings.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/components/LoadingIndicator/LoadingIndicator.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/components/PanelSection/PanelSection.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/components/RTPanel/RTPanel.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/index.js","webpack:////home/vsts/work/1/s/extensions/dicom-rt/src/id.js","webpack:////home/vsts/work/1/s/extensions/dicom-microscopy/src/DicomMicroscopySopClassHandler.js","webpack:////home/vsts/work/1/s/extensions/dicom-microscopy/src/index.js","webpack:////home/vsts/work/1/s/extensions/dicom-pdf/src/OHIFDicomPDFSopClassHandler.js","webpack:////home/vsts/work/1/s/extensions/dicom-pdf/src/index.js","webpack:///./index.js","webpack:////home/vsts/work/1/s/platform/core/src/extensions/ExtensionManager.js","webpack:////home/vsts/work/1/s/platform/core/src/services/ServicesManager.js","webpack:////home/vsts/work/1/s/platform/core/src/services/UINotificationService/index.js","webpack:////home/vsts/work/1/s/platform/core/src/services/UIModalService/index.js","webpack:////home/vsts/work/1/s/platform/core/src/services/UIDialogService/index.js","webpack:////home/vsts/work/1/s/platform/core/src/services/LoggerService/index.js","webpack:////home/vsts/work/1/s/platform/core/src/services/_shared/pubSubServiceInterface.js","webpack:////home/vsts/work/1/s/platform/core/src/services/MeasurementService/MeasurementService.js","webpack:////home/vsts/work/1/s/platform/core/src/services/MeasurementService/index.js"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","executeModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","deferredModules","apply","checkDeferredModules","result","deferredModule","fulfilled","j","depId","splice","__webpack_require__","s","installedModules","installedCssChunks","8","exports","module","l","e","promises","Promise","resolve","reject","href","fullhref","p","existingLinkTags","document","getElementsByTagName","dataHref","tag","getAttribute","rel","existingStyleTags","linkTag","createElement","type","onload","onerror","event","request","target","src","err","Error","code","parentNode","removeChild","appendChild","then","installedChunkData","promise","onScriptComplete","script","charset","timeout","nc","setAttribute","jsonpScriptSrc","error","clearTimeout","chunk","errorType","realSrc","message","name","undefined","setTimeout","head","all","m","c","d","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","oe","console","jsonpArray","window","oldJsonpFunction","slice","log","warn","info","trace","debug","time","timeEnd","sopClassDictionary","ComputedRadiographyImageStorage","DigitalXRayImageStorageForPresentation","DigitalXRayImageStorageForProcessing","DigitalMammographyXRayImageStorageForPresentation","DigitalMammographyXRayImageStorageForProcessing","DigitalIntraOralXRayImageStorageForPresentation","DigitalIntraOralXRayImageStorageForProcessing","CTImageStorage","EnhancedCTImageStorage","LegacyConvertedEnhancedCTImageStorage","UltrasoundMultiframeImageStorage","MRImageStorage","EnhancedMRImageStorage","MRSpectroscopyStorage","EnhancedMRColorImageStorage","LegacyConvertedEnhancedMRImageStorage","UltrasoundImageStorage","EnhancedUSVolumeStorage","SecondaryCaptureImageStorage","MultiframeSingleBitSecondaryCaptureImageStorage","MultiframeGrayscaleByteSecondaryCaptureImageStorage","MultiframeGrayscaleWordSecondaryCaptureImageStorage","MultiframeTrueColorSecondaryCaptureImageStorage","Sop12LeadECGWaveformStorage","GeneralECGWaveformStorage","AmbulatoryECGWaveformStorage","HemodynamicWaveformStorage","CardiacElectrophysiologyWaveformStorage","BasicVoiceAudioWaveformStorage","GeneralAudioWaveformStorage","ArterialPulseWaveformStorage","RespiratoryWaveformStorage","GrayscaleSoftcopyPresentationStateStorage","ColorSoftcopyPresentationStateStorage","PseudoColorSoftcopyPresentationStateStorage","BlendingSoftcopyPresentationStateStorage","XAXRFGrayscaleSoftcopyPresentationStateStorage","XRayAngiographicImageStorage","EnhancedXAImageStorage","XRayRadiofluoroscopicImageStorage","EnhancedXRFImageStorage","XRay3DAngiographicImageStorage","XRay3DCraniofacialImageStorage","BreastTomosynthesisImageStorage","BreastProjectionXRayImageStorageForPresentation","BreastProjectionXRayImageStorageForProcessing","IntravascularOpticalCoherenceTomographyImageStorageForPresentation","IntravascularOpticalCoherenceTomographyImageStorageForProcessing","NuclearMedicineImageStorage","RawDataStorage","SpatialRegistrationStorage","SpatialFiducialsStorage","DeformableSpatialRegistrationStorage","SegmentationStorage","SurfaceSegmentationStorage","RealWorldValueMappingStorage","SurfaceScanMeshStorage","SurfaceScanPointCloudStorage","VLEndoscopicImageStorage","VideoEndoscopicImageStorage","VLMicroscopicImageStorage","VideoMicroscopicImageStorage","VLSlideCoordinatesMicroscopicImageStorage","VLPhotographicImageStorage","VideoPhotographicImageStorage","OphthalmicPhotography8BitImageStorage","OphthalmicPhotography16BitImageStorage","StereometricRelationshipStorage","OphthalmicTomographyImageStorage","VLWholeSlideMicroscopyImageStorage","LensometryMeasurementsStorage","AutorefractionMeasurementsStorage","KeratometryMeasurementsStorage","SubjectiveRefractionMeasurementsStorage","VisualAcuityMeasurementsStorage","SpectaclePrescriptionReportStorage","OphthalmicAxialMeasurementsStorage","IntraocularLensCalculationsStorage","MacularGridThicknessandVolumeReport","OphthalmicVisualFieldStaticPerimetryMeasurementsStorage","OphthalmicThicknessMapStorage","CornealTopographyMapStorage","BasicTextSR","EnhancedSR","ComprehensiveSR","Comprehensive3DSR","ProcedureLog","MammographyCADSR","KeyObjectSelection","ChestCADSR","XRayRadiationDoseSR","RadiopharmaceuticalRadiationDoseSR","ColonCADSR","ImplantationPlanSRDocumentStorage","EncapsulatedPDFStorage","EncapsulatedCDAStorage","PositronEmissionTomographyImageStorage","EnhancedPETImageStorage","LegacyConvertedEnhancedPETImageStorage","BasicStructuredDisplayStorage","RTImageStorage","RTDoseStorage","RTStructureSetStorage","RTBeamsTreatmentRecordStorage","RTPlanStorage","RTBrachyTreatmentRecordStorage","RTTreatmentSummaryRecordStorage","RTIonPlanStorage","RTIonBeamsTreatmentRecordStorage","RTBeamsDeliveryInstructionStorage","GenericImplantTemplateStorage","ImplantAssemblyTemplateStorage","ImplantTemplateGroupStorage","LayoutChooser","props","cell","parentCell","row","col","currentCell","table","Rows","newRow","Columns","isRange","className","emptyCell","state","selectedCell","setState","column","this","highlightCells","onClick","onChange","style","display","visible","minWidth","boxSize","cellBorder","role","map","width","height","border","onMouseEnter","onMouseLeave","PureComponent","PropTypes","number","isRequired","bool","func","ToolbarButton","isActive","icon","labelWhenActive","classnames","active","iconProps","label","arrowIconName","isExpanded","arrowIcon","isExpandable","Icon","cypressSelectorId","toLowerCase","data-cy","propTypes","id","string","oneOfType","shape","defaultProps","withTranslation","LayoutButton","dropdownVisible","prevProps","TableListItem","onItemClick","preventDefault","stopPropagation","itemKey","itemClass","itemMetaClass","itemIndex","itemMeta","children","Component","node","MeasurementTableItem","btnLabel","onClickCallback","marginRight","hasWarningClass","measurementData","hasWarnings","isReadOnly","actionButtons","onRelabel","relabelButton","getActionButton","onRelabelClick","onEditDescription","descriptionButton","onEditDescriptionClick","onDelete","deleteButton","onDeleteClick","measurementNumber","keySeparator","nsSeparator","getDataDisplayText","index","displayText","warningList","Array","isArray","listedWarnings","Fragment","warningTitle","placement","overlay","getWarningContent","getTableListItem","connectedComponent","ScrollableArea","delay","callback","args","context","isThrottled","scrollableElement","currentTop","scrollTop","offsetHeight","limit","scrollHeight","scrollStep","hideScrollbar","x","scrollX","y","scrollY","scrollbarSize","inner","outer","position","top","left","visibility","overflow","body","w1","offsetWidth","h1","w2","h2","clientWidth","clientHeight","getScrollbarSize","marginBottom","scrollAreaClasses","scrollHandlerThrottled","scrollHandler","wrapper","arguments","scrollableClass","class","ref","element","onScroll","onTransitionEnd","scrollNavUp","scrollNavDown","adjustMargins","addEventListener","removeEventListener","TableList","customHeader","headerTitle","headless","onHeaderClick","getHeader","defaultItems","MeasurementTable","selectedKey","saveFunction","onSaveComplete","title","measurementCollection","measureGroup","getCustomHeader","getMeasurements","selectedMeasurementNumber","measurements","measurement","itemNumber","readOnly","groupName","maxMeasurements","timepoints","timepoint","date","overallWarnings","hasOverallWarnings","getTimepointsHeader","getMeasurementsGroups","array","AboutContent","useTranslation","detect","os","version","link","process","substr","toUpperCase","item","backgroundColor","renderTableRow","getDataCy","split","join","TabComponents","tabs","customProps","useState","currentTabIndex","setCurrentTabIndex","tab","hidden","tabCustomProps","arrayOf","any","translate","word","TabFooter","onResetPreferences","onSave","onCancel","hasErrors","disabled","formatKeysForInput","keys","getKeys","sequence","modifier_keys","keysArray","modifiers","forEach","includes","HotkeyField","handleChange","classNames","inputValue","onKeyDown","hotkeys","record","unpause","onFocus","pause","startRecording","allowed_keys","LanguageSwitcher","language","onLanguageChange","languages","lng","Checkbox","checked","checkbox","CineDialog","parseFloat","onFrameRateChanged","isPlaying","onPlayPauseChanged","onClickNextButton","onClickBackButton","onClickSkipToStart","onClickSkipToEnd","cineFrameRate","data-toggle","onClickPlayPause","min","cineMinFrameRate","max","cineMaxFrameRate","step","cineStepFrameRate","handleInputChange","toFixed","FILE_TYPE_OPTIONS","ViewportDownloadForm","activeViewport","onClose","updateViewportPreview","enableViewport","disableViewport","toggleAnnotations","loadImage","downloadBlob","defaultSize","minimumSize","maximumSize","canvasClass","filename","setFilename","fileType","setFileType","dimensions","setDimensions","showAnnotations","setShowAnnotations","keepAspect","setKeepAspect","aspectMultiplier","setAspectMultiplier","viewportElement","setViewportElement","viewportElementDimensions","setViewportElementDimensions","createRef","downloadCanvas","setDownloadCanvas","viewportPreview","setViewportPreview","setError","hasError","values","refreshViewport","useRef","onDimensionsChange","dimension","oppositeDimension","sanitizedTargetValue","replace","isEmpty","newDimensions","updatedDimension","Math","round","error_messages","renderErrorHandler","validSize","loadAndUpdateViewports","useCallback","scaledWidth","scaledHeight","scaledDimensions","current","dataUrl","viewportElementWidth","viewportElementHeight","useEffect","evt","alt","base","options","htmlFor","StudiesItem","studyData","StudyDate","StudyDescription","modalities","studyAvailable","activeClass","hasDescriptionAndDate","getModalitiesStyle","StudiesList","studyListData","StudyInstanceUID","activeStudyInstanceUID","getBrowserItems","SeriesList","seriesItems","seriesData","Thumbnail","displaySetInstanceUID","activeDisplaySetInstanceUID","getSeriesItems","QuickSwitch","find","study","thumbnails","studyDataSelected","onStudySelected","seriesQuickSwitchOpen","seriesDataSelected","onSeriesSelected","sideClass","side","quickSwitchClass","hideSeriesSwitch","showSeriesSwitch","getSmallListItems","onSeriesClick","onStudyClick","RoundedButtonGroup","badgeNumbers","newValue","onValueChanged","onStateEvent","optionIndex","findIndex","detail","badgeNumber","option","stateEvent","prevState","buttons","roundedButtonWrapper","noselect","optionText","bottomLabel","badgeNumberOverflow","String","onClickOption","InputRadio","onSelected","itemData","labelClass","SelectTreeBreadcrumb","SelectTree","onComponentChange","items","searchTerm","selectTreeFirstTitle","currentNode","selectTreeSecondTitle","searchEnabled","placeholder","autoFocus","searchLocations","currentTarget","isLeafSelected","treeItems","getTreeItems","headerItem","onBreadcrumbSelected","filteredItems","cloneDeep","indexOf","filterItems","getLabelClass","SimpleDialog","onConfirm","isOpen","rootClass","componentRef","componentStyle","onSubmit","defaultValue","setValue","customStyle","zIndex","alignItems","justifyContent","Modal","setAppElement","getElementById","OHIFModal","closeButton","shouldCloseOnEsc","fullscreen","classes","ContextMenu","onContextMenu","ErrorPage","description","onRetry","stack","location","reload","CustomDateRangePicker","moment","locale","i18n","onDatesChange","startDate","endDate","dateRangePickerProps","presets","renderCalendarInfo","text","start","end","isSelected","preset","renderMonthElement","month","onMonthSelect","onYearSelect","containerStyle","margin","months","year","renderYearsOptions","startDatePlaceholderText","endDatePlaceholderText","phrases","closeDatePicker","clearDates","required","instanceOf","Date","getDateEntry","datePicked","rangeDatePicked","getDateEntryFromRange","today","numOfDays","edge","subtract","TableSearchFilter","meta","onSort","onValueChange","sortFieldName","sortDirection","studyListDateFilterNumDays","studyDateTo","studyDateFrom","focusedInput","setFocusedInput","translationsAreReady","ready","sortIcons","sortIconForSortField","lastWeek","lastMonth","defaultStartDate","defaultEndDate","studyDatePresets","field","fieldName","inputType","sortIcon","fontSize","startDateId","endDateId","onFocusChange","updatedVal","numberOfMonths","showClearDates","anchorDirection","hideKeyboardShortcutsPanel","isOutsideRange","day","isInclusivelyBeforeDay","oneOf","size","animation","getContentFromUseMediaValue","displaySize","contentArrayMap","defaultContent","StudyList","isLoading","studies","sort","handleSort","filterValues","handleFilterChange","onFilterChange","handleSelectItem","onSelectItem","largeTableMeta","mediumTableMeta","smallTableMeta","tableMeta","large","medium","small","totalSize","reduce","prev","next","percentWidth","direction","colSpan","TableRow","AccessionNumber","PatientID","PatientName","isHighlighted","handleClick","largeRowTemplate","mediumRowTemplate","color","whiteSpace","flexGrow","flexDirection","maxWidth","aria-label","textOverflow","textAlign","smallRowTemplate","fontWeight","paddingTop","paddingLeft","patientNameOrId","accessionOrModalityOrDescription","allFields","TablePagination","nextPageFunc","currentPage","prevPageFunc","onRowsPerPageChange","parseInt","prevPage","nextPage","recordCount","rowsPerPage","pageOptions","pageNumber","renderRowsPerPageDropdown","renderPaginationButtons","PageToolbar","onImport","getImportTool","ExpandableToolMenu","random","getButtons","button","activeCommand","btn","onGroupMenuClick","toolbarComponent","activeIcon","trigger","rootClose","handleHide","onOverlayHide","onExpandableToolClick","toolbarMenuOverlay","React","ToolbarSection","activeButton","activeButtons","ErrorFallback","componentStack","resetErrorBoundary","OHIFErrorBoundary","onReset","onError","fallbackComponent","FallbackComponent","getDisplaySize","mediaQueryMap","mediaTypesAliases","defaultDisplaySize","mql","matches","getMediaQueryMap","mediaQueriesStringList","q","matchMedia","useMedia","defaultMediaType","_mediaQueryMap","mount","onMediaQueryChange","mediaQuery","nextDisplaySize","media","originalMediaQuery","getMediaTypeAlias","_mediaQueriesStringList","_mediaTypesAliases","isEqual","updateState","removeListener","addListener","useDebounce","debouncedValue","setDebouncedValue","handler","Select","selected","for","Range","showPercentage","showValue","valueRenderer","cols","TextInput","toTimeString","DropdownMenu","open","list","align","handleOnClick","getListItems","toggleList","contains","titleElement","handleMouseClick","renderTitleElement","renderList","PlayClipButton","iconName","data-container","data-placement","SimpleToolbarButton","Toolbar","maybePlayClipButton","maybeLayoutButton","includePlayClipButton","includeLayoutButton","isTouchDevice","navigator","maxTouchPoints","viewerbaseDragDropContext","DecoratedClass","backend","TouchBackend","HTML5Backend","opts","enableMouseEvents","retryImport","fn","retriesLeft","interval","catch","retry","component","asyncComponent","importComponent","isFunction","default","onLoaded","toString","addDynamicallyLoadedComponentToState","DICOMWeb","Value","input","padFour","output","charCodeAt","convertToInt","getAuthorizationHeader","requestOptions","headers","accessToken","user","getAccessToken","auth","Authorization","btoa","getModalities","Modality","ModalitiesInStudy","vr","getName","Alphabetic","getNumber","getString","cornerstone","metadataProvider","getBoundingBox","textLines","font","cornerstoneTools","textStyle","getFont","getFontSize","save","textBaseline","measureText","boundingBox","padding","centering","restore","pixelToPage","enabledElement","getEnabledElement","canvas","canvasOffset","$","offset","canvasPosition","pixelToCanvas","repositionTextBox","eventData","config","isCreating","image","allowedBorders","OHIF","uiSettings","autoPositionMeasurementsTextCallOuts","allow","T","R","B","L","getRenderingInformation","limits","tool","mid","directions","diffX","cornerAxis","x1","y1","calculateAxisCenter","axis","a","b","lowest","handles","textBox","$canvas","canvasWidth","outerWidth","canvasHeight","outerHeight","canvasDimensions","bounds","getHandlePosition","cornerAxisPosition","availableAreas","labelWidth","labelHeight","topLeft","bottomRight","getAvailableBlankAreas","tempDirections","assign","tempCornerAxis","foundPlace","renderingInformation","pageToPixel","toolAxis","getTextBoxSizeInPixels","textBoxOffset","centerX","centerY","halfBoxSizeX","halfBoxSizeY","offsetY","offsetX","getTextBoxOffset","canvasBorders","x0","y0","pixelPosition","validate","validators","equals","attributes","doesNotEqual","doesNotContain","startsWith","endsWith","CustomAttributeRetrievalCallbacks","InstanceMetadata","metadata","HPMatcher","metadataInstance","rules","OHIFError","format","details","passed","failed","requiredFailed","score","rule","attribute","customAttribute","setCustomAttribute","errorMessages","testConstraint","constraint","attributeMap","customAttributeExists","getCustomAttribute","getTagValue","weight","CustomViewportSettings","comparators","validator","validatorOption","freeze","EQUALS_REGEXP","Rule","guid","_constraintInfo","_validatorAndValue","constraintInfo","ruleConstraint","comparator","isRuleForPrior","ruleValidatorAndValue","getConstraintValidatorAndValue","intValue","test","validatorAndValue","getConstraintInfo","currentValidator","ProtocolMatchingRule","StudyMatchingRule","SeriesMatchingRule","ImageMatchingRule","removeFromArray","indexToRemove","ViewportStructure","properties","Viewport","viewportSettings","imageMatchingRules","seriesMatchingRules","studyMatchingRules","ruleObject","fromObject","Stage","viewportStructure","viewports","createdDate","currentStage","clonedStage","viewportObject","viewport","Protocol","locked","hasUpdatedPriorsInformation","modifiedDate","userLoggedIn","createdBy","getUserId","modifiedBy","availableTo","Set","editableBy","protocolMatchingRules","stages","numberOfPriorsReferenced","skipCache","stage","priorsReferenced","getNumberOfPriorsReferenced","updateNumberOfPriorsReferenced","stageObject","currentProtocol","clonedProtocol","protocolWasModified","StudyMetadata","ProtocolEngine","protocolStore","priorStudies","studyMetadataSource","Map","StudyMetadataSource","every","reset","newStageIds","protocol","getBestProtocolMatch","setHangingProtocol","matched","studyInstance","getFirstInstance","numberOfAvailablePriors","getNumberOfAvailablePriors","getObjectID","getProtocol","matchedProtocols","clear","matchedProtocolScores","_clearMatchedProtocols","findMatchByStudy","matchedDetail","has","set","obj","highestScoringProtocolId","_largestKeyByValue","updateProtocolMatches","bestMatch","_getHighestScoringProtocol","studyObjectID","getAvailableStudyPriors","priors","viewportIndex","instanceMatchingRules","matchingScores","currentStudy","firstInstance","highestStudyMatchingScore","highestSeriesMatchingScore","priorStudy","validatorType","abstractPriorValue","studyIndex","priorStudyObjectID","loadStudy","studyMetadata","updateViewports","studyMatchDetails","forEachSeries","series","seriesMatchDetails","forEachInstance","instance","isImage","instanceMatchDetails","matchDetails","concat","totalMatchScore","currentSOPInstanceUID","getSOPInstanceUID","imageDetails","getStudyInstanceUID","SeriesInstanceUID","getSeriesInstanceUID","SOPInstanceUID","currentImageIdIndex","matchingScore","sortingInfo","displaySet","findDisplaySet","images","getUID","imageId","getImageId","sortingFunction","sortBy","reverse","numRows","numColumns","setLayout","numViewports","getNumProtocolStages","stageModel","getCurrentStageModel","getLayoutTemplateName","layoutProps","viewportData","matchImages","cornerstoneViewportParams","viewportSettingsKeys","currentViewportData","customSettings","renderedCallback","customSetting","currentMatch","currentPosition","scoresLength","setViewportSpecificData","viewportSpecificData","newProtocol","isPrototypeOf","numberOfStages","stageAction","isPreviousStageAvailable","isNextStageAvailable","setCurrentProtocolStage","ProtocolStore","strategy","protocolObject","protocolInstance","onReady","protocolId","getProtocolInstance","addProtocol","updateProtocol","removeProtocol","defaultProtocol","oneByOne","first","getDefaultProtocol","hangingProtocols","ProtocolStrategy","defaultsAdded","from","delete","addCustomAttribute","attributeId","attributeName","addCustomViewportSetting","settingId","settingName","header","getNestedObject","shallowObject","nestedObject","propertyArray","currentObject","currentProperty","getShallowObject","putValues","baseKey","resultObject","currentKey","currentValue","isString","subject","search","query","pattern","RegExp","trim","encodeId","match","ui","getOffset","offsetParent","offsetLeft","offsetTop","isCharacterKeyPress","which","ctrlKey","metaKey","altKey","handleError","hideConfirm","cancelLabel","cancelClass","MODULE_TYPES","CommandsManager","ExtensionManager","HotkeysManager","ServicesManager","utils","redux","errorHandler","DICOMSR","viewer","UINotificationService","UIModalService","UIDialogService","MeasurementService","LoggerService","adjust","angleDoubleDown","angleDoubleUp","angleLeft","arrows","arrowsAltH","arrowsAltV","bars","brain","brush","caretDown","caretUp","check","checkCircle","checkCircleO","chevronDown","circle","circleNotch","circleO","clipboard","cog","createComment","createScreenCapture","crosshairs","cube","d3Rotate","database","dotCircle","edit","ellipseCircle","ellipseH","ellipseV","exclamationCircle","exclamationTriangle","fastBackward","fastForward","stop","inlineEdit","level","linkCircles","liver","lock","lockAlt","lung","measureNonTarget","measureTarget","measureTargetCr","measureTargetNe","measureTargetUn","measureTemp","objectGroup","ohifLogo","ohifTextLogo","oval","palette","play","plus","powerOff","rotate","rotateRight","saveRegular","scissors","searchPlus","softTissue","sortDown","sortUp","sphere","squareO","star","stepBackward","stepForward","sun","th","thLarge","thList","times","trash","unlink","youtube","eye","eyeClosed","envelopeSquare","ICONS","getIcon","ModalContext","createContext","Provider","ModalProvider","modal","service","DEFAULT_OPTIONS","content","contentProps","showScrollbar","customClassName","setOptions","show","hide","setServiceImplementation","ModalContent","noScroll","visibleScrollbar","withModal","useContext","Consumer","SnackbarItem","handleClose","autoClose","duration","action","close","SnackbarContainer","useSnackbarContext","snackbarItems","topCenter","topRight","bottomLeft","bottomCenter","pos","itemId","renderItem","LogManager","SnackbarContext","SnackbarProvider","SnackbarTypes","count","setCount","setSnackbarItems","onLogHandler","notify","subscribe","EVENTS","OnLog","unsubscribe","newItem","filter","hideAll","snackbar","namespace","WrapperI18n","I18NextWithTranslation","DialogContext","DialogProvider","isDragging","setIsDragging","dialogs","setDialogs","lastDialogId","setLastDialogId","lastDialogPosition","setLastDialogPosition","centerPositions","setCenterPositions","dialog","getCenterPosition","root","querySelector","itemBounds","getBoundingClientRect","dialogId","dismiss","dismissAll","_bringToFront","topDialog","_updateLastDialogPosition","draggableItemBounds","validCallback","DialogContent","defaultPosition","centralize","preservePosition","isDraggable","onStart","onStop","onDrag","showOverlay","dragableItem","srcElement","tagName","withDialog","LoggerContext","useLogger","LoggerProvider","errors","infos","onErrorHandler","errorObject","displayOnConsole","getFourRandomValues","floor","substring","getHTTPErrorHandler","constructor","defaultRetryOptions","retries","factor","minTimeout","maxTimeout","randomize","retryableStatusCodes","retryOptions","xhrRetryRequestHook","url","method","originalRequestSend","send","operation","attempt","currentAttempt","originalOnReadyStateChange","onreadystatechange","status","errorMessage","attemptFailedError","getXHRRetryRequestHook","login","logout","getData","setData","Metadata","uid","configurable","writable","_data","propertyName","propertyValue","_uid","_custom","_hasOwn","enabledElements","setEnabledElement","defineProperties","_imageId","_definePublicProperties","hasIndexValues","splitValues","isValidIndex","indexedValue","tagOrProperty","getIndexedValue","val","idx","frame","SeriesMetadata","_seriesInstanceUID","_instances","_firstInstance","getInstanceByUID","found","getInstanceByIndex","isValidUID","isValidCallback","in","mountOnEnter","unmountOnExit","appear","onEnter","onEntering","onEntered","onExit","onExiting","onExited","fadeStyles","ENTERING","ENTERED","Fade","innerProps","cloneElement","onHide","elementType","Overlay","child","transition","createChainedFunction","funcs","f","acc","isOneOf","one","of","triggerType","delayShow","delayHide","defaultOverlayShown","onBlur","onMouseOut","onMouseOver","OverlayTrigger","handleToggle","handleDelayedShow","handleDelayedHide","handleMouseOver","handleMouseOverOut","handleMouseOut","_mountNode","renderOverlay","ReactDOM","unmountComponentAtNode","_hoverShowDelay","_hoverHideDelay","relatedNative","related","relatedTarget","nativeEvent","unstable_renderSubtreeIntoContainer","_overlay","Children","only","childProps","triggerProps","warning","makeOverlay","AppContext","CONTEXTS","CORNERSTONE","VTK","useAppContext","AppProvider","activeContexts","useSelector","getActiveContexts","appConfig","withAppContext","positionTop","positionLeft","arrowOffsetTop","arrowOffsetLeft","Tooltip","outerStyle","arrowStyle","fetchPaletteColorLookupTableData","server","PaletteColorLookupTableUID","RedPaletteColorLookupTableDescriptor","GreenPaletteColorLookupTableDescriptor","BluePaletteColorLookupTableDescriptor","RedPaletteColorLookupTableData","GreenPaletteColorLookupTableData","BluePaletteColorLookupTableData","entry","_paletteColorCache","_getPaletteColor","add","maxAge","entries","now","paletteColorLookupTableData","lutDescriptor","numLutEntries","bits","arrayBufferToPaletteColorLUT","arraybuffer","byteArray","Uint16Array","Uint8Array","lut","BulkDataURI","uri","wadoRoot","errorInterceptor","requestHooks","api","DICOMwebClient","retrieveBulkData","InlineBinary","inlineBinaryData","atob","str2ab","unpackOverlay","arrayBuffer","bitArray","byteIndex","bitIndex","bitByteIndex","fetchOverlayData","OverlayDataPromises","OverlayDataTags","overlayGroup","groupStr","OverlayDataTag","_getOverlayData","ArrayBuffer","results","dicomWeb","validNumber","v","Number","datasets","dicomJSONDatasetOrP10ArrayBuffer","dicomData","DicomMessage","readFile","dicomJSONDataset","dict","naturalizedDataset","dcmjs","DicomMetaDictionary","naturalizeDataset","_getAndCacheStudyDataset","_getAndCacheStudy","_getAndCacheSeriesFromStudy","_getAndCacheInstanceFromStudy","_checkBulkDataAndInlineBinaries","uids","imageIdToUIDs","dataset","instances","PhotometricInterpretation","_getUIDsFromImageID","_getInstanceData","fallback","_getInstance","INSTANCE","getTagFromInstance","naturalizedTagOrWADOImageLoaderTag","_getCornerstoneWADOImageLoaderTag","wadoImageLoaderTag","WADO_IMAGE_LOADER_TAGS","GENERAL_SERIES_MODULE","seriesDate","seriesTime","SeriesDate","SeriesTime","dicomParser","parseDA","parseTM","modality","seriesInstanceUID","seriesNumber","SeriesNumber","studyInstanceUID","PATIENT_STUDY_MODULE","patientAge","PatientAge","patientSize","PatientSize","patientWeight","PatientWeight","IMAGE_PLANE_MODULE","rowPixelSpacing","columnPixelSpacing","rowCosines","columnCosines","ImageOrientationPatient","PixelSpacing","ImagerPixelSpacing","SOPClassUID","PixelSpacingCalibrationType","PixelSpacingCalibrationDescription","EstimatedRadiographicMagnificationFactor","SequenceOfUltrasoundRegions","isProjection","TYPES","CorrectedImagerPixelSpacing","pixelSpacing","PhysicalDeltaX","PhysicalDeltaY","getPixelSpacingInformation","frameOfReferenceUID","FrameOfReferenceUID","rows","columns","imageOrientationPatient","imagePositionPatient","ImagePositionPatient","sliceThickness","SliceThickness","sliceLocation","SliceLocation","IMAGE_PIXEL_MODULE","samplesPerPixel","SamplesPerPixel","photometricInterpretation","bitsAllocated","BitsAllocated","bitsStored","BitsStored","highBit","HighBit","pixelRepresentation","PixelRepresentation","planarConfiguration","PlanarConfiguration","pixelAspectRatio","PixelAspectRatio","smallestPixelValue","SmallestPixelValue","largestPixelValue","LargestPixelValue","redPaletteColorLookupTableDescriptor","greenPaletteColorLookupTableDescriptor","bluePaletteColorLookupTableDescriptor","redPaletteColorLookupTableData","greenPaletteColorLookupTableData","bluePaletteColorLookupTableData","VOI_LUT_MODULE","WindowCenter","WindowWidth","windowCenter","windowWidth","MODALITY_LUT_MODULE","rescaleSlope","RescaleSlope","rescaleIntercept","RescaleIntercept","rescaleType","RescaleType","SOP_COMMON_MODULE","sopClassUID","sopInstanceUID","PET_ISOTOPE_MODULE","RadiopharmaceuticalInformationSequence","RadiopharmaceuticalInformation","RadiopharmaceuticalStartTime","RadionuclideTotalDose","RadionuclideHalfLife","radiopharmaceuticalInfo","radiopharmaceuticalStartTime","radionuclideTotalDose","radionuclideHalfLife","OVERLAY_PLANE_MODULE","overlays","OverlayData","OverlayRowsTag","OverlayColumnsTag","OverlayType","OverlayOriginTag","OverlayDescriptionTag","OverlayLabelTag","ROIAreaTag","ROIMeanTag","ROIStandardDeviationTag","OverlayOrigin","pixelData","roiArea","roiMean","roiStandardDeviation","PATIENT_MODULE","patientName","patientId","GENERAL_IMAGE_MODULE","sopInstanceUid","instanceNumber","InstanceNumber","lossyImageCompression","LossyImageCompression","lossyImageCompressionRatio","LossyImageCompressionRatio","lossyImageCompressionMethod","LossyImageCompressionMethod","GENERAL_STUDY_MODULE","studyDescription","studyDate","studyTime","StudyTime","accessionNumber","CINE_MODULE","frameTime","FrameTime","splitImageId","qs","queryString","parse","studyUID","seriesUID","objectUID","Mousetrap","_originalStopCallback","_recordedSequence","_recordedSequenceCallback","_currentRecordedKeys","_recordedCharacterKey","_origHandleKey","handleKey","_handleKey","character","recording","_recordCurrentCombo","_recordKey","_finishRecording","_normalizeSequence","self","stopRecord","init","recordPlugin","stopCallback","combo","paused","ReconstructionIssues","DATASET_4D","VARYING_IMAGESDIMENSIONS","VARYING_IMAGESCOMPONENTS","VARYING_IMAGESORIENTATION","MISSING_FRAMES","IRREGULAR_SPACING","MULTIFFRAMES","studyMetadataList","TypeSafeCollection","insert","findBy","remove","purge","removeAll","OHIFInstanceMetadata","_sopInstanceUID","_study","_series","_instance","_cache","bypassCache","rawValue","instanceData","thumbnail","OHIFSeriesMetadata","addInstance","OHIFStudyMetadata","addSeries","isDisplaySetReconstructable","isMultiframe","NumberOfFrames","constructableModalities","reconstructionIssues","MULTIFRAMES","firstImage","firstImageRows","firstImageColumns","firstImageSamplesPerPixel","firstImageOrientationPatient","ii","_isSameArray","instanceMetadataControl","jj","instanceMetadata","_isDataset4D","processSingleframe","iop1","iop2","abs","iopTolerance","spacingTolerance","_getSpacingIssue","spacing","averageSpacing","multipleOfAverageSpacing","numberOfSpacings","issue","missingFrames","_getPerpendicularDistance","sqrt","pow","_studyInstanceUID","_displaySets","_derivedDisplaySets","_firstSeries","derivatedDisplaySet","allDisplaySets","displaySets","otherDisplaySets","ds","referencedSeriesInstanceUIDs","SourceImageSequence","firstFunctionalGroups","_toArray","PerFrameFunctionalGroupsSequence","DerivationImageSequence","sourceImageArray","ReferencedSOPInstanceUID","_findReferencedSeriesInstanceUIDsFromSOPInstanceUID","_findReferencedSeriesInstanceUIDsFromSourceImageSequence","noReferencedSeriesAvailable","ReferencedSeriesSequence","ReferencedSeries","_findReferencedSeriesInstanceUIDsFromReferencedSeriesSequence","ReferencedImageSequence","referencedImageArray","_findReferencedSeriesInstanceUIDsFromReferencedImageSequence","sopClassHandlerModules","getInstanceCount","ImageSet","setAttributes","SeriesDescription","sopClassUIDs","uniqueSopClassUIDsInSeries","instanceSopClassUID","getSopClassUIDs","sopClassHandlerExtensions","handlersForSopClassUID","extension","plugin","dicomWebClient","dwc","getDisplaySetFromSeries","_getDisplaySetFromSopClassModule","sopClassModule","isDerived","_addDerivedDisplaySet","stackableInstances","naturalizedName","isMultiFrame","makeDisplaySet","isClip","numImageFrames","AcquisitionDatetime","isSingleImageModality","frameRate","isReconstructable","isSOPClassUIDSupported","SOPClassUIDNaturalized","referencedSeriesInstanceUID","referencedFrameOfReferenceUID","filteredDerivedDisplaySets","referencedDisplaySet","getReferencedDisplaySet","getSeriesCount","_createDisplaySetsForSeries","_insertDisplaySet","containsSeries","addDisplaySet","firstIndexWithSameSeriesNumber","insertIndex","isLowPriorityModality","startingIndex","seriesDateTime","displaySetI","some","getSeriesByUID","sum","getSeriesByIndex","firstSeries","getFirstSeries","findInstance","findSeriesAndInstanceByInstance","imageSet","getImage","displayReconstructableInfo","displaySpacingInfo","sortByImagePositionPatient","datasetIs4D","firstImagePositionPatient","lastIpp","averageSpacingBetweenFrames","previousImagePositionPatient","spacingBetweenFrames","spacingIssue","isUniform","isSpacingUniform","imageSets","arrayOrObject","hasOwn","sortingCallback","referenceImagePositionPatient","_getImagePositionPatient","refIppVec","Vector3","scanAxisNormal","cross","distanceImagePairs","ippVec","distance","clone","sub","dot","sortedImages","regex","separator","renderingAttr","wadorsuri","getWADORSImageId","wadouri","debugMode","detectionOptions","order","lookupQuerystring","lookupCookie","lookupLocalStorage","lookupFromPathIndex","lookupFromSubdomainIndex","caches","excludeCacheFor","htmlTag","documentElement","AboutModal","Buttons","Common","DatePicker","Header","UserPreferencesModal","languagesMap","ar","am","bg","bn","ca","cs","da","de","el","en","es","et","fa","fi","fil","fr","gu","he","hi","hr","hu","it","ja","kn","ko","lt","lv","ml","mr","ms","nl","no","pl","ro","ru","sk","sl","sr","sv","sw","ta","te","tr","uk","vi","zh","locizeOptions","projectId","apiKey","referenceLng","fallbacklng","envUseLocize","envApiKeyAvailable","DEFAULT_LANGUAGE","initI18n","initialized","detection","useLocize","apiKeyAvailable","customDebug","use","Backend","LastUsed","Editor","LanguageDetector","initReactI18next","fallbackLng","saveMissing","interpolation","escapeValue","locizeLastUsed","editor","onEditorSaved","reloadResources","emit","react","useSuspense","wait","bindI18n","resources","locales","pkg","initializing","addLocales","newLocales","resourceBundle","addResourceBundle","defaultLanguage","availableLanguages","availableLanguagesInfo","getAvailableLanguagesInfo","moduleName","StudyMetaDataPromises","retrieveStudyMetadata","filters","separateSeriesInstanceUIDFilters","seriesInstanceUIDs","seriesSpecificFilters","RetrieveMetadata","__separateSeriesRequestToAggregatePromiseateSeriesRequestToAggregatePromise","deleteStudyMetadataPromise","str","strLen","bytes","buffer","ObjectPath","path","components","getPathComponents","isValidObject","last","isValid","absoluteUrl","absolutePath","origin","absoluteUrlParts","rootUrlPrefixIndex","addServers","servers","store","serverType","endpoint","dispatch","imageObj","someInvalidStrings","strings","getImageInstance","getImageInstanceId","imageInstance","fetchIt","fetch","response","cornerstoneRetriever","loadAndCacheImage","wadorsRetriever","retrieveInstance","dicomLoaderService","localFile","findImageIdOnStudies","cornerstoneWADOImageLoader","loadFileRequest","getDicomDataMethod","loaderRegExp","loaderType","exec","lastIndex","getImageLoaderType","authorizationHeaders","wadoUri","getLocalData","getDataByImageType","getDataByDatasetType","loaderIterator","getLoaderIterator","loader","b64toBlob","b64Data","contentType","sliceSize","byteCharacters","byteArrays","byteNumbers","blob","Blob","logger","studyMetadataManager","derivedDisplaySets","getDerivedDatasets","displaySetsPerModality","isLoaded","loadError","recentDateTime","recentDisplaySet","dateTime","getSourceDisplaySet","onDisplaySetLoadFailureHandler","activatedLabelmapIndex","activatedLabelmapPromise","selectionFired","CustomEvent","dispatchEvent","lastDateTime","load","loadAndCacheDerivedDisplaySets","toLowerCaseFirstLetter","toParse","lib","getQueryFilters","searchParameters","paramString","isValidPath","paramPatternPiece","parseParam","paramStr","_paramDecoded","strToDecode","decoded","decode","replaceParam","paramKey","paramValue","paramPattern","makeDeferred","res","rej","Queue","awaiting","task","boundTask","queue","cleaner","clean","chain","SEPARATOR","addToList","addValuesToList","isSublist","sublist","toSublist","forEachValue","getItem","indexOrPath","subpath","print","prevLen","repeat","TYPE","TASK","LIST","createList","objectWithType","named","observers","isList","isOfType","createTask","isTask","progress","increaseList","getOverallProgress","update","isValidProgress","finish","seal","total","partial","failures","waitOn","thenable","addDeferred","deferred","setTaskName","getTaskByName","addObserver","observer","removeObserver","writeScript","fileName","StackManager","DicomLoaderService","urlUtil","makeCancelable","isCanceled","cancel","isDicomUid","resolveObjectPath","hierarchicalListUtils","progressTrackingUtils","noop","StudyPrefetcher","displaySetCount","onImageCached","requestType","preventCache","prefetchDisplaySetsTimeout","maxNumPrefetchRequests","includeActiveDisplaySet","stopPrefetching","events","cacheFullHandler","prefetchDisplaySets","imageLoadPoolManager","clearRequestStack","prefetchDisplaySetsHandler","displaySetsToPrefetch","getDisplaySetsToPrefetch","imageIds","getImageIdsFromDisplaySets","prefetchImageIds","requestFn","nonCachedImageIds","filterCachedImageIds","maxNumRequests","prefetch","addRequest","metaData","displaySetImage","getActiveViewportImage","getStudy","getSeries","getInstance","activeDisplaySet","getDisplaySetByUID","getDisplaySetBySOPInstanceUID","prefetchOrder","getDisplaySets","topdown","downward","upward","closest","selectedDisplaySets","activeDisplaySetIndex","begin","right","getImageIdsFromDisplaySet","numFrames","isImageCached","imageCache","sizeInBytes","BaseLoadingListener","getNewId","statsItemsLimit","stats","elapsedTime","speed","_setProgressData","_clearProgressById","_addStatsData","_updateProgress","oldestItem","getTime","progressId","_getProgressId","stopListening","_clearProgress","timeSlice","randomNumber","DICOMFileLoadingListener","dataSetUrl","_convertImageIdToDataSetUrl","bytesDiff","loaded","_lastLoaded","_dataSetUrl","imageLoadProgressEventHandler","_imageLoadProgressEventHandler","_getDataSetUrl","_checkCachedData","startListening","dataSet","dataSetCacheManager","dataSetLength","percentComplete","imageLoadProgressEventName","_getImageLoadProgressEventName","imageLoadProgressEventHandle","progressData","multiFrame","bytesLoaded","bytesTotal","bytesPerSecond","StudyLoadingListenerEvents","OnProgress","promiseState","uniqueValue","race","reason","StackLoadingListener","imageLoadedEventHandler","_imageLoadedEventHandler","imageCachePromiseRemovedEventHandler","_imageCachePromiseRemovedEventHandler","imageDataMap","_convertImageIdsArrayToMap","framesStatus","_createArray","loadedCount","_debouncedSetProgressData","debounce","studyPrefetcher","getElement","imageIdsMap","debounced","imageObject","getImageLoadObject","_updateFrameStatus","IMAGE_LOADED","IMAGE_CACHE_PROMISE_REMOVED","imageLoadedEventName","_getImageLoadedEventName","imageCachePromiseRemovedEventName","_getImageCachePromiseRemoveEventName","imageData","totalFramesCount","loadedFramesCount","loadingFramesCount","ceil","framesPerSecond","progressBar","ch","StudyLoadingListener","listeners","stackMetaData","listener","_createListener","findOrCreateStack","addStack","addStudy","displaySetInstanceUIDs","destroy","_getSchema","colonIndex","_subscriptions","_lastSubscriptionId","PubSub","eventName","subscriptionId","callbacks","payload","LogEvents","OHIFStudyMetadataSource","studyInfo","Studies","_updateStudyCollections","getByInstanceUID","createDisplaySets","MetadataProvider","imagesTypes","LOW_PRIORITY_MODALITIES","fields","n_fields","A","primer","stackMap","configuration","stackUpdatedCallbacks","createAndAddStack","numImages","imageIndex","naturalizedInstance","frameNumber","addImageIdToUIDs","clearStacks","makeAndAddStack","findStack","getAllStacks","addStackUpdatedCallback","getConfiguration","setConfiguration","PROPERTY_SEPARATOR","ORDER_ASC","ORDER_DESC","MIN_COUNT","_operationCount","_elementList","_handlers","silent","_elements","handlers","_isFunction","_elementWithPayload","_invalidate","_elementWithId","_trigger","propertyMap","findAllEntriesBy","foundCount","removed","_isObject","_compareToPropertyMapStrict","_sortListBy","_isString","_hasOwnProperty","_getPropertyValue","targetObject","fragments","fragmentCount","firstFragment","remainingFragments","specifiers","_isValidSortingSpecifier","specifierCount","specifier","aValue","bValue","arrowAnnotate","toolGroup","cornerstoneToolType","measurementTable","displayFunction","caseProgress","include","evaluate","bidirectional","shortestDiameter","longestDiameter","ellipticalRoi","meanValue","cachedStats","mean","isNaN","circleRoi","freehandMouse","meanStdDev","lengthValue","nonTarget","rectangleRoi","angle","rAngle","fromCharCode","targetCR","targetNE","targetUN","dicomSRDisplayTool","lesionNamingNumber","childTools","tools","measurementApiDefaultConfig","measurementTools","newLesions","toolGroupId","dataExchange","retrieve","timepointIds","timepointData","timepointId","disassociate","TIMEPOINT_TYPE_NAMES","prebaseline","baseline","followup","TimepointApi","currentTimepointId","Instance","initialize","comparisonTimepointKey","onTimepointsUpdated","visitNumber","tp1","tp2","visitDate","tp","timepointType","retrievalFn","timepointIndex","storeFn","JSON","stringify","disassociateFn","retrieveTimepoints","removeFn","tpIndex","updateFn","prior","comparisonTimepoint","comparison","userComparison","nextBaselineAfterCurrent","currentTimepoint","allNextTimepoints","latestInitialBeforeNextFUIndex","timepointToCheck","latestInitialTimepointAfterCurrent","visitDateToCheck","preBaselineTimepointIds","baselineTimepointIds","currentVisitDate","nadir","timepointKey","resultIncludes","studyInstanceUIDs","timepointTypeName","calculateVisitNumber","timepointName","currentIndex","parenthesis","0","1","parenthesisText","toolType","imagePath","frameIndex","MeasurementApi","timepointApi","toolsGroupsMap","getToolsGroupsMap","measurementLabel","getLabel","labels","toolState","globalImageIdSpecificToolStateManager","saveToolState","getToolConfiguration","childToolKey","childMeasurement","_id","syncMeasurementAndToolData","getImageIdForImagePath","currentToolState","toolData","alreadyExists","restoreToolState","toolGroups","toolGroupTools","getToolGroupTools","onMeasurementsUpdated","measurementTypeId","addMeasurement","syncMeasurementsAndToolData","getEnabledElements","updateImage","isToolIncluded","timepointFilter","sortedMeasurements","toolId","toolItemId","includedChildTools","toolConfig","parentTool","currentMeasurement","initialTimepointIds","initialtpid","lesionExistsAtTimepoints","groupId","toolGroupMeasurement","isNewLesionsMeasurement","maxTargetMeasurementNumber","calculateLesionMaxMeasurementNumber","maxNonTargetMeasurementNumber","maxNewTargetMeasurementNumber","calculateNewLesionMaxMeasurementNumber","maxNewNonTargetMeasurementNumber","additionalData","TrialPatientLocationUID","childToolTypes","childToolType","collectionToUpdate","propertyFilter","increment","updateNumbering","groupCollection","collection","relatedMeasurement","emptyItem","groupTool","createdAt","measurementsInTimepoint","calculateLesionNamingNumber","calculateMeasurementNumber","addedMeasurement","updateObject","getPreviousMeasurement","isSplitLesion","isNodal","getDescription","hasDuplicateMeasurementNumber","updateMeasurementNumberForAllMeasurements","toolIndex","groupIndex","group","lesionNamingNumberFilter","tGroup","childTool","filterKeys","groupItems","filterKey","groupItem","measurementsData","measurementEntries","measurementEntry","mEntry","onMeasurementRemoved","syncFilter","syncFilterKeys","syncFilterKey","BaseCriterion","criterionName","isGlobal","baselineMeasurementNumbers","newTargetNumbers","newTarget","targets","LocationSchema","LocationCriterion","nonTargets","generateResponse","MaxTargetsPerOrganSchema","minimum","MaxTargetsPerOrganCriterion","targetsPerOrgan","getNewTargetNumbers","MaxTargetsSchema","locationIn","minItems","uniqueItems","locationNotIn","MaxTargetsCriterion","measurementNumbers","lesionType","plural","amount","MeasurementsLengthSchema","longAxis","shortAxis","longAxisSliceThicknessMultiplier","shortAxisSliceThicknessMultiplier","modalityIn","modalityNotIn","anyOf","MeasurementsLengthCriterion","longMultiplier","shortMultiplier","childToolsCount","ModalitySchema","enum","measurementTypes","ModalityCriterion","modalitiesSet","validationMethod","invalidModalities","measurementType","uniqueModalities","uniqueModalitiesText","modalityText","NonTargetResponseSchema","NonTargetResponseCriterion","TargetTypeSchema","TargetTypeCriterion","Criteria","initialCriteria","CriteriaEvaluator","criteriaObject","criteriaValidator","getCriteriaValidator","criteria","dataPath","criterionkey","optionsObject","Criterion","criterionKey","criterionDefinitions","criterion","newTargetMatch","schema","definitions","criterionDefinition","$ref","Ajv","compile","nonconformities","criterionResult","recist11","evaluations","initialEvaluations","ConformanceCriteria","measurementApi","groupedNonConformities","maxTargets","maxNewTargets","trialCriteriaType","baselinePromise","followupPromise","baselineData","followupData","mergedData","resultBoth","validateTimepoint","resultBaseline","resultFollowup","groupNonConformities","groups","nonConformity","globals","messages","measureNumber","evaluators","getEvaluators","evaluator","getMaxTargets","resultItem","trialCriteriaTypeId","evaluation","evaluationTimepoint","studyPromises","fillData","evaluationKey","evaluationDefinitions","refreshCornerstoneViewports","handleSingleMeasurementAdded","cancelled","imageAttributes","getImageAttributes","userId","additionalProperties","parentMeasurement","updateMeasurement","getViewport","handleSingleMeasurementRemoved","deleteMeasurements","measurementIndex","getEventData","toolName","MeasurementHandlers","handleChildMeasurementAdded","handleSingleMeasurementModified","handleChildMeasurementModified","handleChildMeasurementRemoved","onAdded","params","onModified","onRemoved","temp","ltTools","resultDataToStudyMetadata","resultData","seriesMap","wadoUriRoot","dateToString","getFullYear","getMonth","getDate","resultDataToStudies","referringPhysicianName","PatientBirthdate","patientSex","studyId","numberOfStudyRelatedSeries","numberOfStudyRelatedInstances","staticWado","qidoRoot","StaticWadoClient","qidoSupportsIncludeField","queryParams","serverSupportsQIDOIncludeField","commaSeparatedFields","parameters","fuzzymatching","includefield","dateFrom","dateTo","studyUIDs","getQIDOQueryParams","searchForStudies","WADO","QIDO","Instances","searchForInstances","studySearchPromises","services","loadingDict","retrieveStudiesMetadata","getStudyBoxData","searchStudies","promiseKeyObj","promiseKey","sortStudy","getWADORSImageUrl","INFO","getSeriesInfo","isLowPriority","seriesSortCriteria","seriesInfoSortingCriteria","secondSeries","instancesSortCriteria","sortingCriteria","sortStudySeries","seriesSortingCriteria","sortStudyInstances","instancesList","instancesSortingCriteria","deepSort","UrlUtil","IHEInvokeImageDisplay","ViewerRouting","StudyListRouting","StandaloneRouting","ViewerLocalFileData","ROUTES_DEF","standaloneViewer","condition","showStudyList","local","gcloud","enableGoogleCloudAdapter","getRoutes","routes","keyConfig","routesConfig","routeKey","route","parsePath","_path","_paramsCopy","parseViewerPath","viewerPath","parseStudyListPath","studyListPath","getReferencedSeriesSequence","referencedSeriesSequenceRaw","referencedSeriesSequence","referencedSeries","referencedInstanceSequenceRaw","referencedInstanceSequence","referencedInstance","referencedSOPClassUID","referencedSOPInstanceUID","createStudy","aSopInstance","seriesLoader","NumberOfStudyRelatedInstances","InstitutionName","buildInstanceWadoUrl","buildInstanceWadoRsUri","buildInstanceFrameWadoRsUri","baseWadoRsUri","makeSOPInstance","sopInstance","imageRendering","thumbnailRendering","wadoRSMetadata","wadorsImageId","wadors","metaDataManager","addInstancesToStudy","sopInstanceList","createStudyFromSOPInstanceList","firstSopInstance","RetrieveMetadataLoader","configLoad","preLoad","preLoadData","loadData","posLoad","postLoadData","loaders","done","RetrieveMetadataLoaderSync","client","retrieveSeriesMetadata","getLoaders","runLoaders","attachSeriesLoader","hasNext","sopInstances","makeSeriesAsyncLoader","seriesInstanceUIDList","RetrieveMetadataLoaderAsync","preLoaders","searchForSeries","getPreLoaders","seriesSorted","seriesInstanceUIDsMap","seriesAsyncLoader","asyncLoader","seriesDataFromQIDO","enableStudyLazyLoad","retrieveMetadataLoader","execLoad","ViewportErrorIndicator","bottom","pointerEvents","ViewportLoadingIndicator","ImageThumbnail","loadingOrError","cancelablePromise","imageSrc","stackPercentComplete","propsError","showProgressBar","setLoading","setImage","canvasRef","showStackLoadingProgressBar","shouldRenderToCanvas","fetchImagePromise","setImagePromise","purgeCancelablePromise","renderToCanvas","ThumbnailFooter","hasDerivedDisplaySets","inconsistencyWarnings","inconsistencyWarningsSet","derivedDisplaySetsActive","derivedDisplaySetsActiveSet","unmounted","infoOnly","getInfo","getDerivedInfo","getWarningInfo","getSeriesInformation","altImageText","onDoubleClick","onMouseDown","supportsDrag","setStackPercentComplete","onProgressChange","throttle","percent","useDrag","canDrag","monitor","drag","hasImage","hasAltText","qidoConfig","searchResult","filtered","filterItem","desired","actual","compareValues","actualItem","range","dash","testValue","valueElem","compareDateRange","createSelector","activeViewportIndex","layout","layoutViewports","activeLayoutViewport","activeViewportSpecificData","activeViewportPluginName","activeViewportExtension","defaultContextValues","createLogoComponentFn","OHIFLogo","WhiteLabelingContext","getAppState","contexts","_getAppState","_getActiveContexts","contextName","clearContext","commandName","definition","getContext","foundCommand","activeContext","getCommand","commandFn","storeContexts","definitionOptions","commandParams","appState","commandsManager","servicesManager","hotkeyDefinitions","hotkeyDefaults","isEnabled","_servicesManager","_commandsManager","_getValidDefinitions","registerHotkeys","_parseToArrayLike","hotkeyDefinitionsObj","copy","entryValue","_parseToHotKeyObj","previouslyRegisteredDefinition","previouslyRegisteredKeys","_unbindHotkeys","_bindHotkeys","setHotkeys","combinedKeys","runCommand","unbind","CodeNameCodeSequenceValues","ImagingMeasurementReport","ImageLibrary","ImagingMeasurements","MeasurementGroup","ImageLibraryGroup","TrackingUniqueIdentifier","TrackingIdentifier","Finding","FindingSite","CornerstoneFreeText","Score","RELATIONSHIP_TYPE","INFERRED_FROM","SELECTED_FROM","CodingSchemeDesignators","SRT","cornerstoneTools4","getSequenceAsArray","getMergedContentSequencesByTrackingUniqueIdentifiers","MeasurementGroups","mergedContentSequencesByTrackingUniqueIdentifiers","ContentSequence","TrackingUniqueIdentifierItem","ConceptNameCodeSequence","CodeValue","trackingUniqueIdentifier","UID","getLabelFromMeasuredValueSequence","MeasuredValueSequence","CodeMeaning","NumericValue","MeasurementUnitsCodeSequence","formatedNumericValue","getCoordsFromSCOORDOrSCOORD3D","graphicItem","ValueType","coords","RelationshipType","GraphicType","GraphicData","ReferencedSOPSequence","ReferencedFrameOfReferenceUID","ReferencedFrameOfReferenceSequence","processTID1410Measurement","mergedContentSequence","UIDREFContentItem","TrackingIdentifierContentItem","NUMContentItems","TextValue","coord","processNonGeometricallyDefinedMeasurement","FindingSites","CodingSchemeDesignator","ConceptCodeSequence","cornerstoneFreeTextFindingSite","processMeasurement","ImagingMeasurementReportContentSequence","getReferencedImagesList","referencedImages","ReferencedSOPClassUID","cornerstoneAdapters","adapters","Cornerstone","TOOL_NAMES","DICOM_SR_DISPLAY_TOOL","getRenderableData","imageMetadata","renderableData","orientation","sliceSpacing","M","M1","inv","worldToIJK","point","z","SCOORD_TYPES","center","onPerimeter","radius","csMath","majorAxis","minorAxis","minorAxisLength","minorAxisDirection","halfMinorAxisLength","corner1","corner2","csTools","addToMeasurementApi","checkIfCanAddMeasurementsToDisplaySet","srDisplaySet","imageDisplaySet","sliceNormal","distanceAlongNormal","SOPInstanceUIDs","imageIdToolState","parseSCOORD3D","mappings","getSourceMappings","isHydrated","isRehydratable","mappingDefinitions","adapterKeys","adapterKey","isValidCornerstoneTrackingIdentifier","adapter","findInstanceMetadataBySopInstanceUID","instanceFound","getImagePath","parseDicomStructuredReport","part10SRArrayBuffer","external","storedMeasurementByToolType","MeasurementReport","generateToolState","seriesDescription","publish","isToolSupported","parseMeasurementsData","unsupportedTools","annotation","generateReport","getAllDisplaySets","retrieveMeasurementFromSR","serverUrl","stowSRFromMeasurements","DicomDict","FileMetaInformationVersion","_meta","MediaStorageSOPClassUID","MediaStorageSOPInstanceUID","TransferSyntaxUID","ImplementationClassUID","ImplementationVersionName","denaturalized","denaturalizeDataset","dicomDict","part10Buffer","write","storeInstances","isStructuredReportSeries","compareSeriesDate","series1","series2","findMostRecentStructuredReport","mostRecentStructuredReport","retrieveMeasurements","latestSeries","storeMeasurements","firstMeasurementKey","firstMeasurement","actions","setViewportActive","setViewportLayoutAndData","clearViewportSpecificData","setActiveViewportSpecificData","setUserPreferences","setExtensionData","setTimepoints","setMeasurements","setStudyData","setServers","defaultState","extensions","extensionName","currentData","incomingData","windowLevelData","2","3","4","5","6","7","9","10","generalPreferences","preferences","uniqBy","newServer","newServers","updatedStudyData","timepointManager","setAutoFreeze","DEFAULT_STATE","findActiveViewportSpecificData","currentViewportSpecificData","numberOfViewports","getActiveViewportIndex","currentActiveViewportIndex","reducers","useActiveViewport","produce","draftState","LocalStorageApi","localStorage","saveState","serializedState","setItem","loadState","SessionStorageApi","sessionStorage","Hammer","cornerstoneMath","loadHandlerManager","setErrorLoadingHandler","fontFamily","setFont","toolStyle","setToolWidth","toolColors","setToolColor","setActiveColor","touchProximity","stackPrefetch","maxImagesToPrefetch","preserveExistingPool","maxSimultaneousRequests","SUPPORTED_TOOLS","measurementServiceMappingsFactory","measurementService","_getAttributes","_getValueTypeFromToolType","VALUE_TYPES","POLYLINE","Length","EllipticalRoi","ELLIPSE","RectangleRoi","ArrowAnnotate","POINT","_getPointsFromHandles","points","handle","_getHandlesFromPoints","toAnnotation","unit","referenceSeriesUID","_measurementServiceId","toMeasurement","csToolsAnnotation","area","trackingIdentifiersByEnabledElementUUID","getters","trackingUniqueIdentifiersForElement","uuid","trackingUniqueIdentifiers","setters","activeIndex","activeTrackingUniqueIdentifierForElement","trackingIdentifiersForElement","tuid","register","srModuleId","dicomSRModule","callInputDialog","InputDialog","useLastPosition","csToolsConfig","Infinity","addProvider","initCornerstoneTools","globalToolSyncEnabled","showSVGCursors","autoResizeViewports","toolsGroupedByType","touch","PanMultiTouchTool","ZoomTouchPinchTool","annotations","ArrowAnnotateTool","BidirectionalTool","LengthTool","AngleTool","FreehandRoiTool","EllipticalRoiTool","DragProbeTool","RectangleRoiTool","other","PanTool","ZoomTool","WwwcTool","WwwcRegionTool","MagnifyTool","StackScrollTool","StackScrollMouseWheelTool","OverlayTool","toolsGroup","_connectToolsToMeasurementService","internalToolsConfig","getTextCallback","eventDetails","changeTextCallback","externalToolProps","internalToolProps","merge","toolsWithHideableHandles","parsedProps","hideHandles","drawHandlesOnHover","parseToolProps","addTool","BaseAnnotationTool","importInternal","setToolPassive","setToolActive","mouseButtonMask","pointers","setToolEnabled","csToolsVer4MeasurementSource","createSource","matchingCriteria","valueType","addMapping","_initMeasurementService","sourceId","addOrUpdate","getAnnotation","ELEMENT_ENABLED","MEASUREMENT_ADDED","MEASUREMENT_UPDATED","source","addMeasurementServiceId","MEASUREMENT_MODIFIED","csToolsEvtName","csTool","measurementServiceId","addOrUpdateMeasurement","setCornerstoneLayout","CornerstoneViewportDownloadForm","activeEnabledElement","enable","disable","fitToWindow","updateViewport","toDataURL","newWidth","newHeight","multiplier","scale","translation","displayImage","setViewport","resize","toggle","setToolEnabledForElement","setToolDisabledForElement","file","mimetype","msToBlob","msSaveBlob","toBlob","URLObj","URL","webkitURL","createObjectURL","download","click","scroll","import","commandsModule","rotateViewport","rotation","flipViewportHorizontal","hflip","flipViewportVertical","vflip","scaleViewport","resetViewport","invertViewport","invert","clearAnnotations","measurementsToRemove","nextImage","previousImage","getActiveViewportEnabledElement","showDownloadViewportModal","updateTableWithNewMeasurementData","getNearbyToolData","canvasCoordinates","availableToolTypes","nearbyTool","pointNearTool","elementToolData","getToolState","elementToolInstance","getToolForElement","removeToolState","setWindowLevel","voi","jumpToImage","refreshViewports","rotateViewportCW","rotateViewportCCW","scaleUpViewport","scaleDownViewport","fitViewportToWindow","setZoomTool","defaultContext","TOOLBAR_BUTTON_TYPES","COMMAND","SET_TOOL_ACTIVE","BUILT_IN","TOOLBAR_BUTTON_BEHAVIORS","CINE","DOWNLOAD_SCREEN_SHOT","commandOptions","behavior","togglable","lazy","OHIFCornerstoneViewport","Suspense","preRegistration","getViewportModule","isStackPrefetchEnabled","enabled","onNewImage","jumpData","getToolbarModule","toolbarModule","getCommandsModule","oidcSettings","settings","automaticSilentRenew","revokeAccessTokenOnSignout","filterProtocolClaims","userManager","createUserManager","loadUser","MAX_CONCURRENCY","middleware","thunkMiddleware","composeEnhancers","__REDUX_DEVTOOLS_EXTENSION_COMPOSE__","compose","oidc","oidcReducer","rootReducer","combineReducers","preloadedState","disableServersCache","createStore","applyMiddleware","getState","updateActiveViewport","maxIndex","newIndex","setWindowLevelPreset","updateViewportDisplaySet","currentDisplaySetIndex","newDisplaySetData","incrementActiveViewport","decrementActiveViewport","windowLevelPreset1","windowLevelPreset2","windowLevelPreset3","windowLevelPreset4","windowLevelPreset5","windowLevelPreset6","windowLevelPreset7","windowLevelPreset8","windowLevelPreset9","nextViewportDisplaySet","previousViewportDisplaySet","getMeasurementText","getDataForEachMeasurementNumber","measurementNumberList","eachData","convertMeasurementsToTableData","toolCollections","getAllTools","tableMeasurements","toolMeasurements","groupedMeasurements","groupedMeasurementsIndex","measurementId","tableMeasurement","tm","m1","m2","convertTimepointsToTableData","latestDate","ConnectedMeasurementTable","connect","getSaveFunction","ownProps","dispatchRelabel","viewportsState","persist","toolForLocation","dispatchEditDescription","dispatchJumpToRowItem","timepointManagerState","invertViewportTimepointsOrder","numTimepoints","numViewportsToUpdate","measurementsForToolGroup","measurementsToJumpTo","dataAtThisTimepoint","displaySetContainsSopInstance","jumpToRowItem","measurementToActive","propsFromState","propsFromDispatch","LabellingTransition","displayComponent","onTransitionExit","OHIFLabellingData","EditDescriptionDialog","onUpdate","autoComplete","LabellingFlow","editLocation","editDescription","skipAddLabelButton","updateLabelling","labellingDoneCallback","editDescriptionOnDialog","fadeOutTimer","setFadeOutTimer","showComponent","setShowComponent","descriptionInput","newMeasurementData","newEditLocation","focus","relabel","setDescriptionUpdateMode","descriptionCancel","handleKeyPress","descriptionSave","selectTreeSelectCallback","itemSelected","locationLabel","showLabelling","fadeOutAndLeaveFast","onKeyPress","labellingStateFragment","initialTopDistance","toolTypes","ToolContextMenu","onSetLabel","onSetDescription","isTouchEvent","defaultDropdownItems","actionType","nearbyToolData","dropdownItems","currentPoints","getDropdownItems","MEASUREMENT_ACTION_MAP","added","modified","onMeasurementsChanged","onMeasurementAdded","onMeasurementModified","onLabelmapModified","_getDefaultPosition","showLabellingDialog","labellingData","_updateLabellingHandler","onTouchPress","onTouchStart","resetLabelligAndContextMenu","cornerstoneMouseClickEvent","onRightClick","MEASUREMENT_REMOVED","LABELMAP_MODIFIED","TOUCH_PRESS","MOUSE_CLICK","TOUCH_START","ELEMENT_DISABLED","getPanelModule","menuOptions","Bar","animationDuration","background","marginLeft","boxShadow","opacity","transform","Container","isFinished","CallbackPage","OHIFStandaloneViewer","unlisten","history","listen","setContext","pathname","expired","exact","RoutesUtil","render","successCallback","errorCallback","URLSearchParams","iss","loginHint","targetLinkUri","authority","removeUser","ohifRedirectTo","signinRedirect","login_hint","getUser","signinSilent","currentPath","noMatchingRoutes","matchPath","isAnimating","NotFound","ConnectedOHIFStandaloneViewer","ViewerbaseDragDropContext","withRouter","extensionManager","commandsManagerConfig","hotkeysManager","ohif","app","App","defaultExtensions","_appConfig","cornerstoneExtensionConfig","routerBasename","homepage","appConfigHotkeys","env","PUBLIC_URL","access_token","httpErrorHandler","configure","beforeSend","xhr","setRequestHeader","initUserManager","registerServices","hooks","requiredExtensions","GenericViewerCommands","OHIFCornerstoneExtension","disableMeasurementPanel","MeasurementsPanel","mergedExtensions","registerExtensions","_initExtensions","userPreferredHotkeys","setDefaultHotKeys","_initHotkeys","_initServers","maxWebWorkers","hardwareConcurrency","startWebWorkersOnDemand","taskConfiguration","decodeTask","initializeCodecsOnStartup","usePDFJS","strict","webWorkerManager","initWebWorkers","whiteLabeling","_userManager","UserManagerContext","basename","firstOpenIdClient","host","baseUri","redirect_uri","silent_redirect_uri","post_logout_redirect_uri","openIdConnectConfiguration","_makeAbsoluteIfNecessary","getUserManagerForOpenIdConnectClient","base_url","_isAbsoluteUrl","ExportedApp","showGoBackButton","to","StudyBrowser","onThumbnailClick","onThumbnailDoubleClick","showThumbnailProgressBar","thumb","thumbIndex","derivedDisplaySetsNumber","flat","COMMANDS","PANEL","SOP_CLASS_HANDLER","TOOLBAR","VIEWPORT","VTKViewport","setViewportActiveHandler","handleScrollEvent","ConnectedVTKViewport","dataFromStore","vtk","pluginDetails","enableStackPrefetch","afterCreation","onCreated","LoadingIndicator","percComplete","segmentationModule","getModule","volumeCache","labelmapCache","OHIFVTKViewport","volumes","paintFilterLabelMapImageData","paintFilterBackgroundImageData","labelmapDataObject","labelmapColorLUT","getCornerstoneStack","imageDataObject","getImageData","firstImageId","brushStackState","activeLabelmapIndex","labelmap3D","labelmaps3D","segmentsDefaultProperties","segmentsHidden","isHidden","vtkLabelmapID","labelmapBuffer","vtkImageData","newInstance","dataArray","vtkDataArray","numberOfComponents","getPointData","setScalars","setSpacing","getSpacing","setOrigin","getOrigin","setDirection","getDirection","colorLutTables","colorLUTIndex","storedStack","imageMetaData0","lower","upper","_getRangeFromWindowLevels","volumeActor","vtkVolume","volumeMapper","vtkVolumeMapper","setMapper","setInputData","getProperty","getRGBTransferFunction","setRange","sampleDistance","setSampleDistance","setMaximumSamplesPerRay","dataDetails","getViewportData","getOrCreateVolume","loadProgressively","setStateFromProps","prevDisplaySet","loadImageData","onPixelDataInserted","numberProcessed","onAllPixelDataInserted","onPixelDataInsertedError","childrenWithProps","labelmapRenderingOptions","colorLUT","globalOpacity","fillAlpha","renderFill","outlineThickness","outlineWidth","renderOutline","onNewSegmentationRequested","webpackContext","req","webpackContextResolve","setLayoutAndViewportData","setMPRLayout","viewportPropsArray","apis","viewportProps","setViewportToVTK","BlendMode","Constants","defaultVOI","_getActiveViewportVTKApi","_setView","viewUp","renderWindow","genericRenderWindow","getRenderWindow","istyle","getInteractor","getInteractorStyle","setSliceNormal","setViewUp","getVOIFromCornerstoneViewport","dom","cornerstoneElement","setVOI","updateVOI","_convertModelToWorldSpace","indexToWorld","getIndexToWorld","vec3","transformMat4","getVtkApis","resetMPRView","resetOrientation","svgWidgets","rotatableCrosshairsWidget","resetCrosshairs","axial","sagittal","coronal","requestNewSegmentation","allViewports","jumpToSlice","segmentNumber","pixelIndex","worldPos","moveCrosshairs","setSegmentationConfiguration","setGlobalOpacity","setVisibility","setOutlineThickness","setOutlineRendering","setSegmentConfiguration","setSegmentVisibility","enableRotateTool","apiIndex","vtkInteractorStyleMPRRotate","setInteractorStyle","enableCrosshairsTool","vtkInteractorStyleRotatableMPRCrosshairs","getReferenceLines","enableLevelTool","throttledUpdateVOIs","trailing","setOnLevelsChanged","vtkInteractorStyleMPRWindowLevel","setSlabThickness","slabThickness","changeSlabThickness","change","getSlabThickness","setBlendModeToComposite","mapper","getMapper","setBlendModeToMaximumIntensity","setBlendMode","blendMode","mpr2d","cornerstoneVOI","addSVGWidget","vtkSVGRotatableCrosshairsWidget","setApiIndex","setApis","firstApi","openGLRenderWindow","getOpenGLRenderWindow","getWebgl2","openGLContext","maxTextureSizeInBytes","getParameter","MAX_TEXTURE_SIZE","maxBufferLengthFloat32","getInputData","getDimensions","vtkActions","COMPOSITE_BLEND","MAXIMUM_INTENSITY_BLEND","setBlendModeToMinimumIntensity","MINIMUM_INTENSITY_BLEND","setBlendModeToAverageIntensity","AVERAGE_INTENSITY_BLEND","increaseSlabThickness","decreaseSlabThickness","getVtkApiForViewportIndex","SLIDER","ToolbarLabel","ToolbarSlider","_getSelectOptions","operationButtons","_getClassNames","_applySlabThickness","modeChecked","toolbarClickCallback","generatedOperation","generateOperation","actionButton","_applyModeOperation","deactivateButton","_operation","_getInitialState","currentSelectedOption","sliderMin","sliderMax","INITIAL_OPTION_INDEX","_getInitialtSelectedOption","SlabThicknessToolbarComponent","parentContext","_className","selectOptions","selectedValue","isVisible","_isDisplaySetReconstructable","VTKMPRToolbarButton","CustomComponent","withCommandsManager","vtkExtension","BASIC_TEXT_SR","ENHANCED_SR","COMPREHENSIVE_SR","COMPREHENSIVE_3D_SR","PROCEDURE_LOG_STORAGE","MAMMOGRAPHY_CAD_SR","CHEST_CAD_SR","X_RAY_RADIATION_DOSE_SR","ACQUISITION_CONTEXT_SR_STORAGE","OHIFDicomHtmlSopClassHandler","sopClassUids","OHIFDicomHtmlViewport","getSopClassHandlerModule","draw","drawLine","getNewContext","_drawCanvasCrosshairs","canvasContext","centerCanvas","DICOM_SEG_TEMP_CROSSHAIRS_TOOL","DICOMSegTempCrosshairsTool","mixins","initialProps","_rtStructModule","drawCanvasCrosshairs","getActiveColor","lineWidth","pop","addCrosshair","stackToolState","imageIdIndex","imgId","labelmaps2D","xCenter","yCenter","globalToolState","imageIdSpecificToolState","loadSegmentation","segDisplaySet","segMetadata","segmentsOnFrame","labelmapSegments","labelmapIndex","_getNextLabelmapIndex","_makeColorLUTAndGetIndex","labelmap3DByFirstImageId","_getNextColorLUTIndex","segment","ROIDisplayColor","RecommendedDisplayCIELabValue","rgb","Colors","dicomlab2RGB","setActiveLabelmap","onDisplaySetLoadFailure","getFirstImageId","hasOverlapping","originLabelMapIndex","segLoadErrorMessagge","activateLabelMap","DICOM_SEG","_parseSeg","Segmentation","_getImageIdsForDisplaySet","BrushColorSelector","defaultColor","onNext","onPrev","BrushRadius","SegmentationItem","SegmentationSettings","onBack","disabledFields","shouldRenderInactiveLabelmaps","outlineAlpha","fillAlphaInactive","outlineAlphaInactive","toFloat","CustomCheck","CustomRange","ColoredCircle","SegmentItem","onVisibilityChange","setIsVisible","data-tip","data-for","place","newVisibility","computedstyle","getComputedStyle","uiGrayDarker","getPropertyValue","activeColor","uiGrayDark","segmentationSelectStyles","singleValue","control","cursor","borderRadius","isFocused","borderColor","minHeight","menu","borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius","SegmentationSelect","formatOptionLabel","styles","SegmentationPanel","onSegmentItemClick","onSegmentVisibilityChange","onConfigurationChange","onSelectedSegmentationChange","isVTK","DEFAULT_BRUSH_RADIUS","brushRadius","brushColor","selectedSegment","selectedSegmentation","showSettings","labelMapList","segmentList","segmentNumbers","isDisabled","getActiveViewport","getActiveLabelMaps3D","getBrushStackState","getActiveSegmentIndex","activeSegmentIndex","getActiveLabelMaps2D","setActiveSegment","segmentIndex","newLabelmapIndex","labelmapModifiedHandler","refreshSegmentations","updateSegmentationComboBox","getLabelMapList","getSegmentList","numbers","_getReferencedSegDisplaysets","segDisplay","dateStr","displayDate","setCurrentSelectedSegment","validIndexList","labelMap2D","segmentsOnLabelmap","average","curr","labelMaps3D","currentDisplaySet","getCurrentDisplaySet","getColorLUTTable","onSegmentVisibilityChangeHandler","segmentationSeriesInstanceUID","uniqueSegmentIndexes","labelmap2D","segmentIndexes","colorLutTable","hasLabelmapMeta","segmentLabel","segmentMeta","SegmentNumber","SegmentLabel","sameSegment","selectedSegmentationOption","newConfiguration","referencedDisplaysets","aNumber","SegmentsSection","defaultVisibility","BrushTool","SphericalBrushTool","CorrectionScissorsTool","alwaysEraseOnClick","triggerSegmentationPanelTabUpdatedEvent","seriesInstanceUid","referencedDS","referencedDisplaySetUID","findDicomDataPromise","segArrayBuffer","namifyDataset","labelmapBufferArray","segmentsOnFrameArray","labelmapIndexes","RTSTRUCT_DISPLAY_TOOL","drawCircle","drawJoinedLines","RTStructDisplayTool","rtstructModule","crossHairCenter","highlightOpacity","structureSet","structureSetSeriesInstanceUid","ROIContourData","ROIContour","ROINumber","colorArray","highlight","_renderClosedPlanar","_renderPoint","_renderOpenPlanar","_toolDataContainsROIContour","toolDataI","StructureSets","getStructureSet","getROIContour","ROIContours","_setStructureSetVisible","StructureSet","_setROIContourVisible","structuresSetsWhichReferenceSeriesInstanceUid","structureSetReferencesSeriesInstanceUid","imageIdOfCenterFrameOfROIContour","imageIdsInStack","rtStructDisplayToolName","imageIdIndicies","structureSetData","hideROIContour","showROIContour","toggleROIContour","hideStructureSet","showStructureSet","toggleStructureSet","defaultConfig","RT_STRUCT_DISPLAY_TOOL","transformPointsToImagePlane","imagePlane","deltaI","deltaJ","X","Y","S","ix","iy","largestDirectionCosineMagnitude","ci","directionCosineMagnitude","pointI","rtStructDisplaySet","rtStructModule","rtStructDataset","StructureSetROISequence","ROIContourSequence","RTROIObservationsSequence","StructureSetLabel","imageIdSopInstanceUidPairs","_getImageIdSopInstanceUidPairsForDisplaySet","ReferencedROINumber","ContourSequence","isSupported","objOrArray","ContourSequenceArray","ContourImageSequence","ContourData","NumberOfContourPoints","ContourGeometricType","_getClosestSOPInstanceUID","_getImageId","imageIdSpecificToolData","_getOrCreateImageIdSpecificToolData","_setROIContourMetadata","_setToolEnabledIfNotEnabled","StructureSetROI","structureSetROI","ROIName","ROIGenerationAlgorithm","ROIDescription","colorForSegmentIndexColorLUT","_setROIContourDataColor","RTROIObservations","ObservationNumber","ROIObservationDescription","RTROIInterpretedType","ROIInterpreter","_setROIContourRTROIObservations","imageIdSopInstanceUidPairsEntry","pair","imagePlaneModule","P","Q","N","C","D","distanceFromPointToPlane","DICOM_RT_STRUCT","_getSequenceAsArray","OHIFDicomRTStructSopClassHandler","referencedFrameOfReference","RTReferencedStudySequence","rtReferencedStudy","RTReferencedSeriesSequence","rtReferencedSeries","ReferencedInstanceSequence","contourImage","_deriveReferencedSeriesSequenceFromFrameOfReferenceSequence","loadRTStruct","StructureSetItem","dcmrtClassNames","warningIcon","tableListItem","RTSettings","expand","shapeRendering","viewBox","preserveAspectRatio","rx","ry","fill","keyTimes","dur","repeatCount","PanelSection","expanded","loading","hideVisibleButton","onExpandChange","setIsExpanded","newExpandValue","RTPanel","onContourItemClick","selectedContour","setSelectedContour","sets","selectedSet","isLocked","setShowSettings","updateStructureSets","viewportSets","defaultSet","toContourItem","loadedSet","interpretedType","isSameContour","rtData","conifg","triggerRTPanelUpdatedEvent","referencedDisplaySets","contourData","sopClassHandlerModule","DicomMicroscopySopClassHandler","ContentDate","ContentTime","OHIFDicomPDFSopClassHandler","ConnectedOHIFDicomPDFViewer","appProps","OHIFVTKExtension","OHIFDicomHtmlExtension","OHIFDicomMicroscopyExtension","OHIFDicomPDFExtension","OHIFDicomSegmentationExtension","OHIFDicomRtExtension","registeredExtensionIds","registeredExtensionVesions","moduleTypeNames","_api","moduleType","ohifExtension","registerExtension","extensionId","extensionModule","_getExtensionModule","_initSpecialModuleTypes","getModuleFnName","charAt","getModuleFn","ex","_initCommandsModule","commandDefinitions","commandDefinition","registerCommand","registeredServiceNames","ohifService","registerService","serviceShowRequestQueue","publicAPI","serviceImplementation","_hide","_show","hideImplementation","showImplementation","showArguments","_dismiss","_dismissAll","_create","dismissImplementation","dismissAllImplementation","createImplementation","_info","_error","infoImplementation","errorImplementation","_isValidEvent","listenerId","subscription","_unsubscribe","callbackProps","hasListeners","hasCallbacks","MEASUREMENT_SCHEMA_KEYS","INTERNAL_MEASUREMENT_UPDATED","RAW_MEASUREMENT_ADDED","MEASUREMENTS_CLEARED","JUMP_TO_MEASUREMENT","BIDIRECTIONAL","MULTIPOINT","CIRCLE","sources","_jumpToMeasurementCache","pubSubServiceInterface","_arrayOfObjects","_getSourceId","toSourceSchema","toMeasurementSchema","_isValidSource","mapping","_getSourceInfo","_getMappingByMeasurementSource","getMeasurement","matchingMapping","_getMatchingMapping","notYetUpdatedAtSource","updatedMeasurement","modifiedTimestamp","dataSource","sourceInfo","_sourceHasMappings","_isValidMeasurement","internalId","newMeasurement","sourceMeasurement","_addJumpToMeasurement"],"mappings":"aACE,SAASA,EAAqBC,GAQ7B,IAPA,IAMIC,EAAUC,EANVC,EAAWH,EAAK,GAChBI,EAAcJ,EAAK,GACnBK,EAAiBL,EAAK,GAIHM,EAAI,EAAGC,EAAW,GACpCD,EAAIH,EAASK,OAAQF,IACzBJ,EAAUC,EAASG,GAChBG,OAAOC,UAAUC,eAAeC,KAAKC,EAAiBX,IAAYW,EAAgBX,IACpFK,EAASO,KAAKD,EAAgBX,GAAS,IAExCW,EAAgBX,GAAW,EAE5B,IAAID,KAAYG,EACZK,OAAOC,UAAUC,eAAeC,KAAKR,EAAaH,KACpDc,EAAQd,GAAYG,EAAYH,IAKlC,IAFGe,GAAqBA,EAAoBhB,GAEtCO,EAASC,QACdD,EAASU,OAATV,GAOD,OAHAW,EAAgBJ,KAAKK,MAAMD,EAAiBb,GAAkB,IAGvDe,IAER,SAASA,IAER,IADA,IAAIC,EACIf,EAAI,EAAGA,EAAIY,EAAgBV,OAAQF,IAAK,CAG/C,IAFA,IAAIgB,EAAiBJ,EAAgBZ,GACjCiB,GAAY,EACRC,EAAI,EAAGA,EAAIF,EAAed,OAAQgB,IAAK,CAC9C,IAAIC,EAAQH,EAAeE,GACG,IAA3BX,EAAgBY,KAAcF,GAAY,GAE3CA,IACFL,EAAgBQ,OAAOpB,IAAK,GAC5Be,EAASM,EAAoBA,EAAoBC,EAAIN,EAAe,KAItE,OAAOD,EAIR,IAAIQ,EAAmB,GAGnBC,EAAqB,CACxBC,EAAG,GAMAlB,EAAkB,CACrBkB,EAAG,GAGAb,EAAkB,GAQtB,SAASS,EAAoB1B,GAG5B,GAAG4B,EAAiB5B,GACnB,OAAO4B,EAAiB5B,GAAU+B,QAGnC,IAAIC,EAASJ,EAAiB5B,GAAY,CACzCK,EAAGL,EACHiC,GAAG,EACHF,QAAS,IAUV,OANAjB,EAAQd,GAAUW,KAAKqB,EAAOD,QAASC,EAAQA,EAAOD,QAASL,GAG/DM,EAAOC,GAAI,EAGJD,EAAOD,QAKfL,EAAoBQ,EAAI,SAAuBjC,GAC9C,IAAIkC,EAAW,GAKZN,EAAmB5B,GAAUkC,EAAStB,KAAKgB,EAAmB5B,IACzB,IAAhC4B,EAAmB5B,IAFX,CAAC,EAAI,EAAE,EAAI,EAAE,EAAI,EAAE,EAAI,EAAE,GAAK,EAAE,GAAK,EAAE,GAAK,GAELA,IACtDkC,EAAStB,KAAKgB,EAAmB5B,GAAW,IAAImC,SAAQ,SAASC,EAASC,GAIzE,IAHA,IAAIC,EAAYtC,EAAU,4BACtBuC,EAAWd,EAAoBe,EAAIF,EACnCG,EAAmBC,SAASC,qBAAqB,QAC7CvC,EAAI,EAAGA,EAAIqC,EAAiBnC,OAAQF,IAAK,CAChD,IACIwC,GADAC,EAAMJ,EAAiBrC,IACR0C,aAAa,cAAgBD,EAAIC,aAAa,QACjE,GAAe,eAAZD,EAAIE,MAAyBH,IAAaN,GAAQM,IAAaL,GAAW,OAAOH,IAErF,IAAIY,EAAoBN,SAASC,qBAAqB,SACtD,IAAQvC,EAAI,EAAGA,EAAI4C,EAAkB1C,OAAQF,IAAK,CACjD,IAAIyC,EAEJ,IADID,GADAC,EAAMG,EAAkB5C,IACT0C,aAAa,gBAChBR,GAAQM,IAAaL,EAAU,OAAOH,IAEvD,IAAIa,EAAUP,SAASQ,cAAc,QACrCD,EAAQF,IAAM,aACdE,EAAQE,KAAO,WACfF,EAAQG,OAAShB,EACjBa,EAAQI,QAAU,SAASC,GAC1B,IAAIC,EAAUD,GAASA,EAAME,QAAUF,EAAME,OAAOC,KAAOlB,EACvDmB,EAAM,IAAIC,MAAM,qBAAuB3D,EAAU,cAAgBuD,EAAU,KAC/EG,EAAIE,KAAO,wBACXF,EAAIH,QAAUA,SACP3B,EAAmB5B,GAC1BiD,EAAQY,WAAWC,YAAYb,GAC/BZ,EAAOqB,IAERT,EAAQX,KAAOC,EAEJG,SAASC,qBAAqB,QAAQ,GAC5CoB,YAAYd,MACfe,MAAK,WACPpC,EAAmB5B,GAAW,MAMhC,IAAIiE,EAAqBtD,EAAgBX,GACzC,GAA0B,IAAvBiE,EAGF,GAAGA,EACF/B,EAAStB,KAAKqD,EAAmB,QAC3B,CAEN,IAAIC,EAAU,IAAI/B,SAAQ,SAASC,EAASC,GAC3C4B,EAAqBtD,EAAgBX,GAAW,CAACoC,EAASC,MAE3DH,EAAStB,KAAKqD,EAAmB,GAAKC,GAGtC,IACIC,EADAC,EAAS1B,SAASQ,cAAc,UAGpCkB,EAAOC,QAAU,QACjBD,EAAOE,QAAU,IACb7C,EAAoB8C,IACvBH,EAAOI,aAAa,QAAS/C,EAAoB8C,IAElDH,EAAOX,IAnGV,SAAwBzD,GACvB,OAAOyB,EAAoBe,EAAI,IAAM,CAAC,EAAI,sGAAsG,EAAI,qFAAqF,EAAI,eAAe,EAAI,6BAA6B,EAAI,wBAAwB,EAAI,mBAAmB,EAAI,sBAAsB,EAAI,gBAAgB,EAAI,8BAA8B,GAAK,mCAAmCxC,IAAUA,GAAW,WAAa,CAAC,EAAI,uBAAuB,EAAI,uBAAuB,EAAI,uBAAuB,EAAI,uBAAuB,EAAI,uBAAuB,EAAI,uBAAuB,EAAI,uBAAuB,EAAI,uBAAuB,EAAI,uBAAuB,GAAK,uBAAuB,GAAK,uBAAuB,GAAK,uBAAuB,GAAK,uBAAuB,GAAK,uBAAuB,GAAK,uBAAuB,GAAK,uBAAuB,GAAK,wBAAwBA,GAAW,MAkG37ByE,CAAezE,GAG5B,IAAI0E,EAAQ,IAAIf,MAChBQ,EAAmB,SAAUb,GAE5Bc,EAAOf,QAAUe,EAAOhB,OAAS,KACjCuB,aAAaL,GACb,IAAIM,EAAQjE,EAAgBX,GAC5B,GAAa,IAAV4E,EAAa,CACf,GAAGA,EAAO,CACT,IAAIC,EAAYvB,IAAyB,SAAfA,EAAMH,KAAkB,UAAYG,EAAMH,MAChE2B,EAAUxB,GAASA,EAAME,QAAUF,EAAME,OAAOC,IACpDiB,EAAMK,QAAU,iBAAmB/E,EAAU,cAAgB6E,EAAY,KAAOC,EAAU,IAC1FJ,EAAMM,KAAO,iBACbN,EAAMvB,KAAO0B,EACbH,EAAMnB,QAAUuB,EAChBF,EAAM,GAAGF,GAEV/D,EAAgBX,QAAWiF,IAG7B,IAAIX,EAAUY,YAAW,WACxBf,EAAiB,CAAEhB,KAAM,UAAWK,OAAQY,MAC1C,MACHA,EAAOf,QAAUe,EAAOhB,OAASe,EACjCzB,SAASyC,KAAKpB,YAAYK,GAG5B,OAAOjC,QAAQiD,IAAIlD,IAIpBT,EAAoB4D,EAAIxE,EAGxBY,EAAoB6D,EAAI3D,EAGxBF,EAAoB8D,EAAI,SAASzD,EAASkD,EAAMQ,GAC3C/D,EAAoBgE,EAAE3D,EAASkD,IAClCzE,OAAOmF,eAAe5D,EAASkD,EAAM,CAAEW,YAAY,EAAMC,IAAKJ,KAKhE/D,EAAoBoE,EAAI,SAAS/D,GACX,oBAAXgE,QAA0BA,OAAOC,aAC1CxF,OAAOmF,eAAe5D,EAASgE,OAAOC,YAAa,CAAEC,MAAO,WAE7DzF,OAAOmF,eAAe5D,EAAS,aAAc,CAAEkE,OAAO,KAQvDvE,EAAoBwE,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQvE,EAAoBuE,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAK7F,OAAO8F,OAAO,MAGvB,GAFA5E,EAAoBoE,EAAEO,GACtB7F,OAAOmF,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOvE,EAAoB8D,EAAEa,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIR3E,EAAoB+E,EAAI,SAASzE,GAChC,IAAIyD,EAASzD,GAAUA,EAAOoE,WAC7B,WAAwB,OAAOpE,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAN,EAAoB8D,EAAEC,EAAQ,IAAKA,GAC5BA,GAIR/D,EAAoBgE,EAAI,SAASgB,EAAQC,GAAY,OAAOnG,OAAOC,UAAUC,eAAeC,KAAK+F,EAAQC,IAGzGjF,EAAoBe,EAAI,IAGxBf,EAAoBkF,GAAK,SAASjD,GAA2B,MAApBkD,QAAQlC,MAAMhB,GAAYA,GAEnE,IAAImD,EAAaC,OAAqB,aAAIA,OAAqB,cAAK,GAChEC,EAAmBF,EAAWjG,KAAK2F,KAAKM,GAC5CA,EAAWjG,KAAOf,EAClBgH,EAAaA,EAAWG,QACxB,IAAI,IAAI5G,EAAI,EAAGA,EAAIyG,EAAWvG,OAAQF,IAAKP,EAAqBgH,EAAWzG,IAC3E,IAAIU,EAAsBiG,EAI1B/F,EAAgBJ,KAAK,CAAC,KAAK,KAEpBM,I,wCC1QT,IAAM+F,EAAM,CACVvC,MAAOkC,QAAQlC,MACfwC,KAAMN,QAAQM,KACdC,KAAMP,QAAQK,IACdG,MAAOR,QAAQQ,MACfC,MAAOT,QAAQS,MACfC,KAAMV,QAAQU,KACdC,QAASX,QAAQW,SAGJN,O,6BCVf,kCACO,IAAMO,EAAqB,CAChCC,gCAAiC,4BACjCC,uCAAwC,8BACxCC,qCAAsC,gCACtCC,kDACE,8BACFC,gDACE,gCACFC,gDACE,8BACFC,8CACE,gCACFC,eAAgB,4BAChBC,uBAAwB,8BACxBC,sCAAuC,8BACvCC,iCAAkC,8BAClCC,eAAgB,4BAChBC,uBAAwB,8BACxBC,sBAAuB,8BACvBC,4BAA6B,8BAC7BC,sCAAuC,8BACvCC,uBAAwB,8BACxBC,wBAAyB,8BACzBC,6BAA8B,4BAC9BC,gDACE,8BACFC,oDACE,8BACFC,oDACE,8BACFC,gDACE,8BACFC,4BAA6B,gCAC7BC,0BAA2B,gCAC3BC,6BAA8B,gCAC9BC,2BAA4B,gCAC5BC,wCAAyC,gCACzCC,+BAAgC,gCAChCC,4BAA6B,gCAC7BC,6BAA8B,gCAC9BC,2BAA4B,gCAC5BC,0CAA2C,+BAC3CC,sCAAuC,+BACvCC,4CAA6C,+BAC7CC,yCAA0C,+BAC1CC,+CACE,+BACFC,6BAA8B,+BAC9BC,uBAAwB,iCACxBC,kCAAmC,+BACnCC,wBAAyB,iCACzBC,+BAAgC,iCAChCC,+BAAgC,iCAChCC,gCAAiC,iCACjCC,gDACE,iCACFC,8CACE,iCACFC,mEACE,+BACFC,iEACE,+BACFC,4BAA6B,6BAC7BC,eAAgB,6BAChBC,2BAA4B,+BAC5BC,wBAAyB,+BACzBC,qCAAsC,+BACtCC,oBAAqB,+BACrBC,2BAA4B,+BAC5BC,6BAA8B,6BAC9BC,uBAAwB,+BACxBC,6BAA8B,+BAC9BC,yBAA0B,iCAC1BC,4BAA6B,mCAC7BC,0BAA2B,iCAC3BC,6BAA8B,mCAC9BC,0CAA2C,iCAC3CC,2BAA4B,iCAC5BC,8BAA+B,mCAC/BC,sCAAuC,mCACvCC,uCAAwC,mCACxCC,gCAAiC,mCACjCC,iCAAkC,mCAClCC,mCAAoC,iCACpCC,8BAA+B,+BAC/BC,kCAAmC,+BACnCC,+BAAgC,+BAChCC,wCAAyC,+BACzCC,gCAAiC,+BACjCC,mCAAoC,+BACpCC,mCAAoC,+BACpCC,mCAAoC,+BACpCC,oCAAqC,+BACrCC,wDACE,+BACFC,8BAA+B,+BAC/BC,4BAA6B,+BAC7BC,YAAa,gCACbC,WAAY,gCACZC,gBAAiB,gCACjBC,kBAAmB,gCACnBC,aAAc,gCACdC,iBAAkB,gCAClBC,mBAAoB,gCACpBC,WAAY,gCACZC,oBAAqB,gCACrBC,mCAAoC,gCACpCC,WAAY,gCACZC,kCAAmC,gCACnCC,uBAAwB,gCACxBC,uBAAwB,gCACxBC,uCAAwC,8BACxCC,wBAAyB,8BACzBC,uCAAwC,gCACxCC,8BAA+B,8BAC/BC,eAAgB,gCAChBC,cAAe,gCACfC,sBAAuB,gCACvBC,8BAA+B,gCAC/BC,cAAe,gCACfC,+BAAgC,gCAChCC,gCAAiC,gCACjCC,iBAAkB,gCAClBC,iCAAkC,gCAClCC,kCAAmC,2BACnCC,8BAA+B,2BAC/BC,+BAAgC,2BAChCC,4BAA6B,6B,07BCtHzBC,E,YAwBJ,WAAYC,GAAO,M,IAAA,O,4FAAA,S,EACjB,K,EAAA,eAAMA,GAAN,G,gDADiB,kBA0BT,SAACC,EAAMC,GACf,OAAOD,EAAKE,KAAOD,EAAWC,KAAOF,EAAKG,KAAOF,EAAWE,OA3B3C,yBA6BF,SAAAC,GAEf,IADA,IAAIC,EAAQ,GACHH,EAAM,EAAGA,EAAM,EAAKH,MAAMO,KAAMJ,IAAO,CAE9C,IADA,IAAIK,EAAS,GACJJ,EAAM,EAAGA,EAAM,EAAKJ,MAAMS,QAASL,IAAO,CACjD,IAAIH,EAAO,CAAEE,IAAKA,EAAKC,IAAKA,GACxB,EAAKM,QAAQT,EAAMI,GACrBJ,EAAKU,UAAY,QAEjB,EAAKD,QAAQL,EAAa,EAAKO,YAC/B,EAAKF,QAAQT,EAAM,EAAKY,MAAMC,gBAE9Bb,EAAKU,UAAY,kBAEnBH,EAAOvO,KAAKgO,GAEdK,EAAMrO,KAAKuO,GAEb,EAAKO,SAAS,CAAET,MAAOA,OA7CvB,EAAKM,UAAY,CACfT,KAAM,EACNa,QAAS,GAEX,EAAKH,MAAQ,CACXP,MAAO,CAAC,IACRQ,aAAc,EAAKd,MAAMc,cARV,E,2SAYjBG,KAAKC,eAAeD,KAAKL,a,8BAEnBP,GACNY,KAAKF,SAAS,CACZD,aAAcT,IAEhBY,KAAKC,eAAeb,GAChBY,KAAKjB,MAAMmB,SACbF,KAAKjB,MAAMmB,QAAQd,GAEjBY,KAAKjB,MAAMoB,UACbH,KAAKjB,MAAMoB,SAASf,K,+BA2Bf,WACHI,EAAUQ,KAAKjB,MAAMS,QACnBY,EAAQ,CACZC,QAASL,KAAKjB,MAAMuB,QAAU,QAAU,OACxCC,SACEf,EAAUQ,KAAKjB,MAAMyB,SAAWhB,EAAU,GAAKQ,KAAKjB,MAAM0B,YAE9D,OACE,yBACEf,UAAU,4CACVgB,KAAK,OACLN,MAAOA,GAEP,+BACE,+BACGJ,KAAKJ,MAAMP,MAAMsB,KAAI,SAACzB,EAAK1O,GAC1B,OACE,wBAAIkG,IAAKlG,GACN0O,EAAIyB,KAAI,SAAC3B,EAAMtN,GACd,OACE,wBACEgO,UAAWV,EAAKU,UAChBU,MAAO,CACLQ,MAAO,EAAK7B,MAAMyB,QAClBK,OAAQ,EAAK9B,MAAMyB,QACnBM,OAAQ,mBAEVpK,IAAKhF,EACLqP,aAAc,kBAAM,EAAKd,eAAejB,IACxCgC,aAAc,kBAAM,EAAKf,eAAe,EAAKN,YAC7CO,QAAS,kBAAM,EAAKA,QAAQlB,qB,8BAxGxBiC,iB,EAAtBnC,E,YACe,CACjBQ,KAAM4B,IAAUC,OAAOC,WACvB5B,QAAS0B,IAAUC,OAAOC,WAC1Bd,QAASY,IAAUG,KAAKD,WACxBvB,aAAcqB,IAAUrK,OACxB2J,QAASU,IAAUC,OAAOC,WAC1BX,WAAYS,IAAUC,OAAOC,WAC7BlB,QAASgB,IAAUI,KACnBnB,SAAUe,IAAUI,O,EATlBxC,E,eAYkB,CACpBQ,KAAM,EACNE,QAAS,EACTc,SAAS,EACTE,QAAS,GACTC,WAAY,EACZZ,aAAc,CACZX,KAAM,EACNC,KAAM,K,4CCtBL,SAASoC,EAAcxC,GAAO,IAC3ByC,EAAgDzC,EAAhDyC,SAAUC,EAAsC1C,EAAtC0C,KAAMC,EAAgC3C,EAAhC2C,gBAAiBxB,EAAenB,EAAfmB,QAAS7J,EAAM0I,EAAN1I,EAC5CqJ,EAAYiC,IAAW5C,EAAMW,UAAW,CAAEkC,OAAQJ,IAClDK,EAA4B,iBAATJ,EAAoB,CAAErM,KAAMqM,GAASA,EACxDK,EAAQN,GAAYE,EAAkBA,EAAkB3C,EAAM+C,MAE9DC,EAAgBhD,EAAMiD,WAAa,WAAa,aAChDC,EAAYlD,EAAMmD,cACtB,kBAACC,EAAA,EAAD,CAAM/M,KAAM2M,EAAerC,UAAU,iBASjC0C,EAAoBrD,EAAM+C,MAAMO,cAEtC,OACE,yBACE3C,UAAWA,EACXQ,QAXgB,SAAAxM,GACdwM,GACFA,EAAQxM,EAAOqL,IAUfuD,UAASF,GAERP,GAAa,kBAACM,EAAA,EAASN,GACxB,yBAAKnC,UAAU,wBACZrJ,EAAEyL,GACFG,IAMTV,EAAcgB,UAAY,CACxBC,GAAItB,IAAUuB,OACdjB,SAAUN,IAAUG,KAEpBS,MAAOZ,IAAUuB,OAAOrB,WAExBM,gBAAiBR,IAAUuB,OAC3B/C,UAAWwB,IAAUuB,OAAOrB,WAC5BK,KAAMP,IAAUwB,UAAU,CACxBxB,IAAUuB,OACVvB,IAAUyB,MAAM,CACdvN,KAAM8L,IAAUuB,OAAOrB,eAG3BlB,QAASgB,IAAUI,KAEnBY,aAAchB,IAAUG,KAExBW,WAAYd,IAAUG,KACtBhL,EAAG6K,IAAUI,KAAKF,YAGpBG,EAAcqB,aAAe,CAC3BpB,UAAU,EACV9B,UAAW,kBAGEmD,kBAAgB,UAAhBA,CAA2BtB,G,21BC/DnC,IAAMuB,EAAb,iC,iGAAA,wF,EAAA,K,GAAA,0C,gDAAA,eAaU,CACNC,gBAAiB,EAAKhE,MAAMgE,kBAdhC,kBAyBY,WACR,EAAKjD,SAAS,CACZiD,iBAAkB,EAAKnD,MAAMmD,qBA3BnC,mBA+Ba,SAAAlD,GACL,EAAKd,MAAMoB,UACb,EAAKpB,MAAMoB,SAASN,MAjC1B,E,UAAA,O,kOAAA,M,EAAA,G,EAAA,0CAiBqBmD,GACbhD,KAAKjB,MAAMgE,kBAAoBC,EAAUD,iBAC3C/C,KAAKF,SAAS,CACZiD,gBAAiB/C,KAAKjB,MAAMgE,oBApBpC,+BAsCI,OACE,yBAAKrD,UAAU,aACb,kBAAC,EAAD,CACE8B,SAAUxB,KAAKJ,MAAMmD,gBACrBjB,MAAO,SACPL,KAAK,KACLvB,QAASF,KAAKE,UAEhB,kBAAC,EAAD,CACEI,QAASN,KAAKJ,MAAMmD,gBACpB5C,SAAUH,KAAKG,SACfD,QAASF,KAAKE,QACdL,aAAcG,KAAKjB,MAAMc,qB,2BAlDnC,GAAkCoB,iB,EAArB6B,E,eACW,CACpBC,iBAAiB,I,EAFRD,E,YAKQ,CACjBC,gBAAiB7B,IAAUG,KAAKD,WAEhCjB,SAAUe,IAAUI,KAEpBzB,aAAcqB,IAAUrK,S,OA+CbiM,I,k3BCxDR,IAAMG,EAAb,iC,iGAAA,wF,EAAA,K,GAAA,0C,gDAAA,sBAqCgB,SAAAvP,GACR,EAAKqL,MAAMmE,cACbxP,EAAMyP,iBACNzP,EAAM0P,kBAEN,EAAKrE,MAAMmE,YAAYxP,EAAO,EAAKqL,MAAMsE,aA1C/C,E,UAAA,O,kOAAA,M,EAAA,G,EAAA,gCAoBI,OACE,yBACE3D,UAAS,wBAAmBM,KAAKjB,MAAMuE,WACvCpD,QAASF,KAAKkD,aAEd,yBAAKxD,UAAS,oBAAeM,KAAKjB,MAAMwE,gBACrCvD,KAAKjB,MAAMyE,UACXxD,KAAKjB,MAAM0E,SACZ,0BAAM/D,UAAU,gBACd,kBAACyC,EAAA,EAAD,CAAM/M,KAAK,2BAGf,yBAAKsK,UAAU,eAAeM,KAAKjB,MAAM2E,gB,2BAhCjD,GAAmCC,a,EAAtBV,E,YACQ,CACjBS,SAAUxC,IAAU0C,KACpBN,UAAWpC,IAAUuB,OACrBe,UAAWtC,IAAUC,OACrBsC,SAAUvC,IAAU0C,KACpBL,cAAerC,IAAUuB,OACzBY,QAASnC,IAAUwB,UAAU,CAC3BxB,IAAUuB,OACVvB,IAAUC,SAEZ+B,YAAahC,IAAUI,KAAKF,a,EAXnB6B,E,eAcW,CACpBQ,SAAU,KACVF,cAAe,K,s2BCZbM,E,wVA6Cc,SAACC,EAAUC,GAC3B,OACE,4BAAQrN,IAAKoN,EAAUpE,UAAU,YAAYQ,QAAS6D,GACpD,0BAAM3D,MAAO,CAAE4D,YAAa,QAC1B,kBAAC7B,EAAA,EAAD,CAAM/M,KAAK,OAAOwL,MAAM,OAAOC,OAAO,UAEvC,EAAK9B,MAAM1I,EAAEyN,O,2BAKD,WACjB,IAAMG,EACJ,EAAKlF,MAAMmF,gBAAgBC,cAC1B,EAAKpF,MAAMmF,gBAAgBE,WACxB,cACA,GAEAC,EAAgB,GAEtB,GAAoC,mBAAzB,EAAKtF,MAAMuF,UAA0B,CAC9C,IAAMC,EAAgB,EAAKC,gBACzB,UACA,EAAKC,gBAEPJ,EAAcrT,KAAKuT,GAErB,GAA4C,mBAAjC,EAAKxF,MAAM2F,kBAAkC,CACtD,IAAMC,EAAoB,EAAKH,gBAC7B,cACA,EAAKI,wBAEPP,EAAcrT,KAAK2T,GAErB,GAAmC,mBAAxB,EAAK5F,MAAM8F,SAAyB,CAC7C,IAAMC,EAAe,EAAKN,gBAAgB,SAAU,EAAKO,eACzDV,EAAcrT,KAAK8T,GAGrB,OACE,kBAAC,EAAD,CACEzB,QAAS,EAAKtE,MAAMmF,gBAAgBc,kBACpC1B,UAAS,0BAAqB,EAAKvE,MAAMuE,UAAhC,YAA6CW,GACtDT,UAAW,EAAKzE,MAAMyE,UACtBN,YAAa,EAAKA,aAElB,6BACE,yBAAKxD,UAAU,uBACZ,EAAKX,MAAM1I,EAAE,EAAK0I,MAAMmF,gBAAgBpC,MAAO,CAC9CmD,aAAc,IACdC,YAAa,OAGjB,yBAAKxF,UAAU,gBAAgB,EAAKyF,uBAClC,EAAKpG,MAAMmF,gBAAgBE,YAC3B,yBAAK1E,UAAU,cAAc2E,Q,sBAOzB,SAAA3Q,GACZ,EAAKqL,MAAMmE,YAAYxP,EAAO,EAAKqL,MAAMmF,oB,yBAG1B,SAAAxQ,GAEfA,EAAM0P,kBAEN,EAAKrE,MAAMuF,UAAU5Q,EAAO,EAAKqL,MAAMmF,oB,iCAGhB,SAAAxQ,GAEvBA,EAAM0P,kBAEN,EAAKrE,MAAM2F,kBAAkBhR,EAAO,EAAKqL,MAAMmF,oB,wBAGjC,SAAAxQ,GAEdA,EAAM0P,kBAEN,EAAKrE,MAAM8F,SAASnR,EAAO,EAAKqL,MAAMmF,oB,6BAGnB,WACnB,OAAO,EAAKnF,MAAMmF,gBAAgBhU,KAAKyQ,KAAI,SAACzQ,EAAMkV,GAChD,OACE,yBAAK1O,IAAG,sBAAiB0O,GAAS1F,UAAU,0BACzCxP,EAAKmV,YAAcnV,EAAKmV,YAAc,a,4BAM3B,WAAM,MACK,EAAKtG,MAAMmF,gBAAhCoB,mBADgB,MACF,GADE,EAGxB,GAAIC,MAAMC,QAAQF,GAAc,CAC9B,IAAMG,EAAiBH,EAAY3E,KAAI,SAACrJ,EAAM8N,GAC5C,OAAO,wBAAI1O,IAAK0O,GAAQ9N,MAG1B,OAAO,4BAAKmO,GAEZ,OAAO,kBAAC,IAAMC,SAAP,KAAiBJ,M,kSA5InB,MAKHtF,KAAKjB,MAAMmF,gBALR,IAELyB,oBAFK,MAEU,GAFV,EAGLxB,EAHK,EAGLA,YACAC,EAJK,EAILA,WAGF,OACE,kBAAC,IAAMsB,SAAP,KACGvB,IAAgBC,EACf,kBAAC,IAAD,CACE1N,IAAKsJ,KAAKjB,MAAMyE,UAChBoC,UAAU,OACVC,QACE,kBAAC,IAAD,CACED,UAAU,OACVlG,UAAU,qBACV8C,GAAG,gBAEH,yBAAK9C,UAAU,gBAAgBM,KAAKjB,MAAM1I,EAAEsP,IAC5C,yBAAKjG,UAAU,kBAAkBM,KAAK8F,uBAI1C,6BAAM9F,KAAK+F,qBAGb,kBAAC,IAAML,SAAP,KAAiB1F,KAAK+F,0B,8BAvCGpC,a,EAA7BE,E,YACe,CACjBK,gBAAiBhD,IAAUrK,OAAOuK,WAClC8B,YAAahC,IAAUI,KAAKF,WAC5BkD,UAAWpD,IAAUI,KACrBuD,SAAU3D,IAAUI,KACpBoD,kBAAmBxD,IAAUI,KAC7BgC,UAAWpC,IAAUuB,OACrBe,UAAWtC,IAAUC,OACrB9K,EAAG6K,IAAUI,OAoJjB,IAAM0E,EAAqBnD,YAAgB,mBAAhBA,CACzBgB,G,k2BChKK,IAAMoC,EAAb,YAmBE,WAAYlH,GAAO,M,IC5BamH,EAAOC,EAErCC,EACAC,EAFEC,ED2Be,O,4FAAA,S,EACjB,K,EAAA,eAAMvH,GAAN,G,gDADiB,wBAiEH,SAAArL,GAAS,MAKnB,EAAK6S,kBAHIC,EAFU,EAErBC,UACc5F,EAHO,EAGrB6F,aAIIC,EAPiB,EAIrBC,aAG2B/F,EACzB4F,EAAYD,EAAa,EAAKzH,MAAM8H,WACxCJ,EAAYA,EAAYE,EAAQA,EAAQF,EACxC,EAAKF,kBAAkBE,UAAYA,KA3ElB,sBA8EL,SAAA/S,GAAS,IAGjB+S,EAF8B,EAAKF,kBAA/BE,UAEqB,EAAK1H,MAAM8H,WACxCJ,EAAYA,EAAY,EAAI,EAAIA,EAEhC,EAAKF,kBAAkBE,UAAYA,KApFlB,wBAuFH,WACd,GAAI,EAAK1H,MAAM+H,cAAe,CAC5B,IAAMC,EAAI,EAAKhI,MAAMiI,QAAU,EAAI,EAC7BC,EAAI,EAAKlI,MAAMmI,QAAU,EAAI,EAC7BC,EEjHG,WACb,IAAMC,EAAQtU,SAASQ,cAAc,KACrC8T,EAAMhH,MAAMQ,MAAQ,OACpBwG,EAAMhH,MAAMS,OAAS,OAErB,IAAMwG,EAAQvU,SAASQ,cAAc,OACrC+T,EAAMjH,MAAMkH,SAAW,WACvBD,EAAMjH,MAAMmH,IAAM,MAClBF,EAAMjH,MAAMoH,KAAO,MACnBH,EAAMjH,MAAMqH,WAAa,SACzBJ,EAAMjH,MAAMQ,MAAQ,QACpByG,EAAMjH,MAAMS,OAAS,QACrBwG,EAAMjH,MAAMsH,SAAW,SACvBL,EAAMlT,YAAYiT,GAElBtU,SAAS6U,KAAKxT,YAAYkT,GAE1B,IAAMO,EAAKR,EAAMS,YACXC,EAAKV,EAAMV,aACjBW,EAAMjH,MAAMsH,SAAW,SACvB,IAAIK,EAAKX,EAAMS,YACXG,EAAKZ,EAAMV,aAYf,OAVIkB,IAAOG,IACTA,EAAKV,EAAMY,aAGTH,IAAOE,IACTA,EAAKX,EAAMa,cAGbpV,SAAS6U,KAAKzT,YAAYmT,GAEnB,CAACO,EAAKG,EAAID,EAAKE,GFgFIG,GACtB,EAAK5B,kBAAkBnG,MAAM4D,YAA7B,UAA8C,EAC5CmD,EAAc,GAAKF,EADrB,MAEA,EAAKV,kBAAkBnG,MAAMgI,aAA7B,UAA+C,EAC7CjB,EAAc,GAAKJ,EADrB,UA9Fe,wBAmGH,WAAM,MAKhB,EAAKR,kBAHO1F,EAFI,EAElB6F,aACWD,EAHO,EAGlBA,UAGE4B,EAAoB,GAGpB5B,IACF4B,GAAqB,eAInB5B,EAAY5F,EAdI,EAIlB+F,eAWAyB,GAAqB,kBAGnB,EAAKzI,MAAMyI,oBAAsBA,GACnC,EAAKvI,SAAS,CACZuI,yBApHJ,EAAKzI,MAAQ,CACXyI,kBAAmB,IAGrB,EAAKC,wBCnCyBpC,EDmCU,ICnCHC,EDmCQ,EAAKoC,cClChDjC,GAAc,EAIlB,SAASkC,IACP,GAAIlC,EAGF,OAFAF,EAAOqC,eACPpC,EAAUrG,MAIZsG,GAAc,EACdH,EAAS9U,MAAM2O,KAAMyI,WAErBnT,YAAW,WACTgR,GAAc,EACVF,IACFoC,EAAQnX,MAAMgV,EAASD,GACvBA,EAAOC,EAAU,QAElBH,KDOc,E,UAnBrB,O,kOAAA,M,EAAA,G,EAAA,gCA6BW,WACHwC,EAAkB,aAWtB,OAVI1I,KAAKjB,MAAM2J,kBACbA,GAAmB,IAAJ,OAAQ1I,KAAKjB,MAAM2J,kBAEhC1I,KAAKjB,MAAMiI,UACb0B,GAAmB,YAEjB1I,KAAKjB,MAAMmI,UACbwB,GAAmB,YAInB,yBACEhJ,UAAS,qBAAgBM,KAAKjB,MAAM4J,MAA3B,YACP3I,KAAKJ,MAAMyI,oBAGb,yBACE3I,UAAWgJ,EACXE,IAAK,SAAAC,GACH,EAAKtC,kBAAoBsC,GAE3BC,SAAU9I,KAAKsI,uBACfvH,aAAcf,KAAKsI,uBACnBS,gBAAiB/I,KAAKsI,wBAErBtI,KAAKjB,MAAM2E,UAEd,yBAAKhE,UAAU,wBAAwBQ,QAASF,KAAKgJ,aAEnD,kBAAC7G,EAAA,EAAD,CAAM/M,KAAK,qBAEb,yBAAKsK,UAAU,0BAA0BQ,QAASF,KAAKiJ,eACrD,kBAAC9G,EAAA,EAAD,CAAM/M,KAAK,0BA/DrB,0CAsEI4K,KAAKkJ,gBACLlJ,KAAKuI,gBACLrR,OAAOiS,iBAAiB,SAAUnJ,KAAKkJ,iBAxE3C,2CA4EIlJ,KAAKkJ,gBACLlJ,KAAKuI,kBA7ET,6CAiFIrR,OAAOkS,oBAAoB,SAAUpJ,KAAKkJ,oB,2BAjF9C,GAAoCvF,a,EAAvBsC,E,YACQ,CACjBvC,SAAUxC,IAAU0C,KAAKxC,WACzBuH,MAAOzH,IAAUuB,OACjBiG,gBAAiBxH,IAAUuB,OAC3BuE,QAAS9F,IAAUG,KACnB6F,QAAShG,IAAUG,KACnByF,cAAe5F,IAAUG,KACzBwF,WAAY3F,IAAUC,S,EARb8E,E,eAWW,CACpBa,eAAe,EACf6B,MAAO,gBACPzB,SAAS,EACTF,SAAS,EACTH,WAAY,M,w2BGpBT,IAAMwC,GAAb,iC,iGAAA,wF,EAAA,K,GAAA,2C,iDAAA,sBA0Bc,WACV,OAAI,EAAKtK,MAAMuK,aACN,EAAKvK,MAAMuK,aAGhB,kBAAC,IAAM5D,SAAP,KACE,yBAAKhG,UAAU,wBAAwB,EAAKX,MAAMwK,aAClD,yBAAK7J,UAAU,iBAAiB,EAAKX,MAAM2E,SAAShT,YAjC9D,E,UAAA,O,mOAAA,M,EAAA,G,EAAA,gCAcI,OACE,yBAAKgP,UAAU,cACXM,KAAKjB,MAAMyK,UACX,yBAAK9J,UAAU,kBAAkBQ,QAASF,KAAKyJ,eAC5CzJ,KAAK0J,aAGV,yBAAKhK,UAAU,oBAAoBM,KAAKjB,MAAM2E,gB,2BArBtD,GAA+BC,a,i+BAAlB0F,G,YACQ,CACjBC,aAAcpI,IAAU0C,KACxB+F,aAAczI,IAAUrK,OACxB6M,SAAUxC,IAAU0C,KAAKxC,WACzBmI,YAAarI,IAAUuB,OACvB+G,SAAUtI,IAAUG,O,GANXgI,G,eASW,CACpBG,UAAU,I,ICFRI,G,kVAuBI,CACNC,YAAa,O,uEA0DA,WAAMnW,GAAN,iGAC4B,EAAKqL,MAAtC+K,EADK,EACLA,aAAcC,EADT,EACSA,gBAClBD,EAFS,0CAIYA,IAJZ,OAIHvY,EAJG,OAKLwY,GACFA,EAAe,CACbC,MAAO,UACP7U,QAAS5D,EAAO4D,QAChB5B,KAAM,YATD,gDAaLwW,GACFA,EAAe,CACbC,MAAO,UACP7U,QAAS,KAAMA,QACf5B,KAAM,UAjBD,wD,0QAwBS,WACtB,OAAO,EAAKwL,MAAMkL,sBAAsBtJ,KAAI,SAACuJ,EAAc9E,GACzD,OACE,kBAAC,GAAD,CACE1O,IAAK0O,EACLkE,aAAc,EAAKa,gBAAgBD,IAElC,EAAKE,gBAAgBF,U,4BAMZ,SAAAA,GAChB,IAAML,EAAc,EAAK9K,MAAMsL,0BAC3B,EAAKtL,MAAMsL,0BACX,EAAKzK,MAAMiK,YACf,OAAOK,EAAaI,aAAa3J,KAAI,SAAC4J,EAAanF,GACjD,IAAM1O,EAAM6T,EAAYvF,kBAClBxB,EAAY+G,EAAYC,YAAcpF,EAAQ,EAC9C9B,EACJuG,IAAgBnT,GAAQ,EAAKqI,MAAM0L,SAAwB,GAAb,WAChD,OACE,kBAAC,EAAD,CACE/T,IAAKA,EACL8M,UAAWA,EACXF,UAAWA,EACXY,gBAAiBqG,EACjBrH,YAAa,EAAKA,YAClBoB,UAAW,EAAKvF,MAAM0F,eACtBI,SAAU,EAAK9F,MAAMgG,cACrBL,kBAAmB,EAAK3F,MAAM6F,+B,wBAMxB,SAAClR,EAAOwQ,GAChB,EAAKnF,MAAM0L,WAEf,EAAK3K,SAAS,CACZ+J,YAAa3F,EAAgBc,oBAG3B,EAAKjG,MAAMmE,aACb,EAAKnE,MAAMmE,YAAYxP,EAAOwQ,O,4BAIhB,SAAAgG,GAChB,OACE,kBAAC,IAAMxE,SAAP,KACE,yBAAKhG,UAAU,wBACZ,EAAKX,MAAM1I,EAAE6T,EAAaQ,YAE5BR,EAAaS,iBACZ,yBAAKjL,UAAU,mBACZ,EAAKX,MAAM1I,EAAE,OADhB,IACyB6T,EAAaS,iBAGxC,yBAAKjL,UAAU,iBAAiBwK,EAAaI,aAAa5Z,Y,gCAK1C,WAAM,MACA,EAAKqO,MAAvB6L,EADkB,EAClBA,WAAYvU,EADM,EACNA,EAEpB,OAAOuU,EAAWjK,KAAI,SAACkK,EAAWzF,GAChC,OACE,yBAAK1O,IAAK0O,EAAO1F,UAAU,8BACzB,yBAAKA,UAAU,kBAAkBrJ,EAAEwU,EAAUnU,MAC7C,yBAAKgJ,UAAU,iBAAiBmL,EAAUC,a,8BAM9B,WAAM,MACK,EAAK/L,MAAMgM,gBAAhCzF,mBADgB,MACF,GADE,EAGxB,GAAIC,MAAMC,QAAQF,GAAc,CAC9B,IAAMG,EAAiBH,EAAY3E,KAAI,SAACrJ,EAAM8N,GAC5C,OAAO,wBAAI1O,IAAK0O,GAAQ9N,MAG1B,OAAO,4BAAKmO,GAEZ,OAAO,kBAAC,IAAMC,SAAP,KAAiBJ,M,mSAvKnB,MACsCtF,KAAKjB,MAA1CgM,EADD,EACCA,gBAAiBjB,EADlB,EACkBA,aAAczT,EADhC,EACgCA,EACjC2U,EAAqBD,EAAgBzF,YAAY5U,OAAS,EAEhE,OACE,yBAAKgP,UAAU,oBACb,yBAAKA,UAAU,0BACZsL,GACC,kBAAC,IAAD,CACEtU,IAAK,mBACLkP,UAAU,OACVC,QACE,kBAAC,IAAD,CACED,UAAU,OACVlG,UAAU,qBACV8C,GAAG,eACHpC,MAAO,IAEP,yBAAKV,UAAU,gBACZrJ,EAAE,6BAEL,yBAAKqJ,UAAU,kBACZM,KAAK8F,uBAKZ,0BAAMpG,UAAU,kBACd,0BAAMA,UAAU,kBACd,kBAACyC,EAAA,EAAD,CAAM/M,KAAK,4BAKlB4K,KAAKiL,uBAER,kBAAC,EAAD,KACE,6BAAMjL,KAAKkL,0BAEb,yBAAKxL,UAAU,0BACZoK,GACC,4BACE5J,QAASF,KAAK8J,aACdpK,UAAU,UACV4C,UAAQ,yBAER,kBAACH,EAAA,EAAD,CAAM/M,KAAK,OAAOwL,MAAM,OAAOC,OAAO,SALxC,yB,gCApEmB8C,a,GAAzBiG,G,YACe,CACjBK,sBAAuB/I,IAAUiK,MAAM/J,WACvCwJ,WAAY1J,IAAUiK,MAAM/J,WAC5B2J,gBAAiB7J,IAAUrK,OAAOuK,WAClCqJ,SAAUvJ,IAAUG,KACpB6B,YAAahC,IAAUI,KACvBmD,eAAgBvD,IAAUI,KAC1ByD,cAAe7D,IAAUI,KACzBsD,uBAAwB1D,IAAUI,KAClC+I,0BAA2BnJ,IAAUC,OACrC9K,EAAG6K,IAAUI,KACbwI,aAAc5I,IAAUI,KACxByI,eAAgB7I,IAAUI,O,GAbxBsI,G,eAgBkB,CACpBmB,gBAAiB,CACfzF,YAAa,IAEfmF,UAAU,IAmLd,IAAMzE,GAAqBnD,YAAgB,CAAC,mBAAoB,UAArCA,CACzB+G,I,mBC/MIwB,I,OAAe,WAAM,IAINtZ,EAHXuE,EAAMgV,aAAe,gBAArBhV,EADiB,EAGKiV,eAAtBC,EAHiB,EAGjBA,GAAIC,EAHa,EAGbA,QAASpW,EAHI,EAGJA,KAkDrB,OACE,yBAAKsK,UAAU,eAAe4C,UAAQ,eACpC,yBAAK5C,UAAU,aACb,uBACEA,UAAU,kBACV9L,OAAO,SACPT,IAAI,sBACJT,KAAK,gEAEJ2D,EAAE,oBAPP,IAUE,uBACEqJ,UAAU,kBACV9L,OAAO,SACPT,IAAI,sBACJT,KAAK,qDAEJ2D,EAAE,oBAhBP,IAmBE,uBACEqJ,UAAU,kBACV9L,OAAO,SACPT,IAAI,sBACJT,KAAK,mBAEJ2D,EAAE,kBAGP,6BACE,4BAAKA,EAAE,wBACP,2BAAOqJ,UAAU,0BACf,+BACE,4BACE,4BAAKrJ,EAAE,SACP,4BAAKA,EAAE,YAGX,+BApFC,CACL,CACEjB,KAAMiB,EAAE,kBACRD,MAAO,mCACPqV,KAAM,oCAER,CACErW,KAAMiB,EAAE,yBACRD,MAAO,iDACPqV,KAAM,kDAER,CACErW,KAAM,iBACNgB,MAAOsV,WAET,CACEtW,KAAMiB,EAAE,gBACRD,MAAOsV,KAET,CACEtW,KAAMiB,EAAE,WACRD,MAAO,GAAF,QAzBQtE,EAyBQsD,EAxBzBtD,EAAE6Z,OAAO,EAAG,GAAGC,cAAgB9Z,EAAE6Z,OAAO,GAAGtJ,eAwBlC,YAAyBmJ,IAEhC,CACEpW,KAAMiB,EAAE,MACRD,MAAOmV,IA2DiB5K,KAAI,SAAAkL,GAAI,OAtDf,SAAC,GAAD,IAAGzW,EAAH,EAAGA,KAAMgB,EAAT,EAASA,MAAOqV,EAAhB,EAAgBA,KAAhB,OACrB,wBAAI/U,IAAKtB,EAAMgL,MAAO,CAAE0L,gBAAiB,gBACvC,4BAAK1W,GACL,4BACGqW,EACC,uBAAG7X,OAAO,SAAST,IAAI,sBAAsBT,KAAM+Y,GAChDrV,GAGHA,IA6CkC2V,CAAeF,Y,+sBCrF3D,IAAMG,GAAY,WAAe,IAAd5W,EAAc,uDAAP,GACxB,OAAOA,EACJ6W,MAAM,KACNC,KAAK,KACL7J,eAoBL,SAAS8J,GAAT,GAAmD,IAA1BC,EAA0B,EAA1BA,KAA0B,IAApBC,mBAAoB,MAAN,GAAM,OACHC,mBAAS,GADN,GAC1CC,EAD0C,KACzBC,EADyB,KAGjD,OACEJ,EAAK1b,OAAS,GACZ,yBAAKgP,UAAU,iBACb,yBAAKA,UAAU,2BACb,yBAAKA,UAAU,oCACb,yBAAKA,UAAU,0BACb,wBAAIA,UAAU,gBACX0M,EAAKzL,KAAI,SAAC8L,EAAKrH,GAAU,IAChBhQ,EAAyBqX,EAAzBrX,KADgB,EACSqX,EAAnBC,OACd,aAFwB,WAIpB,wBACEhW,IAAK0O,EACLlF,QAAS,WACPsM,EAAmBpH,IAErB1F,UAAWiC,IACT,WACAyD,IAAUmH,GAAmB,UAE/BjK,UAAS0J,GAAU5W,IAEnB,gCAASA,WASxBgX,EAAKzL,KAAI,SAAC8L,EAAKrH,GAAU,IAEtBzB,EAGE8I,EAHF9I,UACagJ,EAEXF,EAFFJ,YAHsB,EAKpBI,EADFC,OAEF,aANwB,WAQpB,yBACEhW,IAAK0O,EACL1F,UAAWiC,IACT,wBACAyD,IAAUmH,GAAmB,WAG/B,kBAAC5I,EAAD,MAAe0I,EAAiBM,SAUhDR,GAAc5J,UAAY,CACxB6J,KAAMlL,IAAU0L,QACd1L,IAAUyB,MAAM,CACdvN,KAAM8L,IAAUuB,OAChBkB,UAAWzC,IAAU2L,IACrBR,YAAanL,IAAUrK,OACvB6V,OAAQxL,IAAUG,QAGtBgL,YAAanL,IAAUrK,Q,WCnGnBiW,GAAY,SAAAC,GAAI,OAAIA,GAE1B,SAASC,GAAT,GAMG,IALDC,EAKC,EALDA,mBACAC,EAIC,EAJDA,OACAC,EAGC,EAHDA,SACAC,EAEC,EAFDA,UAEC,IADD/W,SACC,MADGyW,GACH,EACD,OACE,yBAAKpN,UAAU,UACb,4BACEA,UAAU,2BACV4C,UAAQ,oBACRpC,QAAS+M,GAER5W,EAAE,sBAEL,6BACE,yBACE6J,QAASiN,EACT7K,UAAQ,aACR5C,UAAU,mBAETrJ,EAAE,WAEL,4BACEqJ,UAAU,kBACV4C,UAAQ,WACR+K,SAAUD,EACVlN,QAASgN,GAER7W,EAAE,WAOb2W,GAAUzK,UAAY,CACpB0K,mBAAoB/L,IAAUI,KAC9B4L,OAAQhM,IAAUI,KAClB6L,SAAUjM,IAAUI,KACpB8L,UAAWlM,IAAUG,KACrBhL,EAAG6K,IAAUI,M,aCvCTgM,GAAqB,eAACC,EAAD,uDAAQ,GAAR,OAAeA,EAAKrB,KAAK,MAO9CsB,GAAU,SAAC,GAAgC,IAA9BC,EAA8B,EAA9BA,SAAUC,EAAoB,EAApBA,cACrBC,EAAYF,EAASvB,KAAK,KAAKD,MAAM,KACvCsB,EAAO,GACPK,EAAY,GAQhB,OAPAD,EAAUE,SAAQ,SAAAnX,GACZgX,GAAiBA,EAAcI,SAASpX,GAC1CkX,EAAU5c,KAAK0F,GAEf6W,EAAKvc,KAAK0F,MAGd,UAAWkX,EAAcL,IAa3B,SAASQ,GAAT,GAAwE,IAAjDR,EAAiD,EAAjDA,KAAMS,EAA2C,EAA3CA,aAAcC,EAA6B,EAA7BA,WAAYP,EAAiB,EAAjBA,cAC/CQ,EAAaZ,GAAmBC,GAkBtC,OACE,2BACE9C,UAAU,EACVlX,KAAK,OACL6C,MAAO8X,EACPxO,UAAWuO,EACXE,UAtBmB,SAAAza,GACrBA,EAAM0P,kBACN1P,EAAMyP,iBAENiL,KAAQC,QAAO,SAAAZ,GACb,IAAMF,EAAOC,GAAQ,CAAEC,WAAUC,kBACjCU,KAAQE,UACRN,EAAaT,OAgBbgB,QAZY,WACdH,KAAQI,QACRJ,KAAQK,oBAeZV,GAAYxL,UAAY,CACtBgL,KAAMrM,IAAUiK,MAAM/J,WACtB4M,aAAc9M,IAAUI,KAAKF,WAC7B6M,WAAY/M,IAAUuB,OACtBiL,cAAexM,IAAUiK,MACzBuD,aAAcxN,IAAUiK,O,WCzEpBwD,GAAmB,SAAC,GAA8C,IAA5CC,EAA4C,EAA5CA,SAAUC,EAAkC,EAAlCA,iBAAkBC,EAAgB,EAAhBA,UAMtD,OACE,4BACE1Z,KAAK,kBACLoN,GAAG,kBACH9C,UAAU,kBACVtJ,MAAOwY,EACPzO,SAXa,SAAAzM,GAAS,IAChB0C,EAAU1C,EAAME,OAAhBwC,MACRyY,EAAiBzY,KAWd0Y,EAAUnO,KAAI,SAAAoO,GAAG,OAChB,4BAAQrY,IAAKqY,EAAI3Y,MAAOA,MAAO2Y,EAAI3Y,OAChC2Y,EAAIjN,YAOf6M,GAAiBpM,UAAY,CAC3BqM,SAAU1N,IAAUuB,OAAOrB,WAC3B0N,UAAW5N,IAAUiK,MAAM/J,WAC3ByN,iBAAkB3N,IAAUI,KAAKF,Y,uzBC3B5B,I,SAAM4N,GAAb,YAOE,WAAYjQ,GAAO,a,4FAAA,UACjB,0BAAMA,KACDa,MAAQ,CAAEqP,UAAWlQ,EAAMkQ,QAASnN,MAAO/C,EAAM+C,OAFrC,E,UAPrB,O,mOAAA,M,EAAA,G,EAAA,oCAYezP,GACX,IAAM4c,EAAU5c,EAAEuB,OAAOqb,QACzBjP,KAAKF,SAAS,CAAEmP,YACZjP,KAAKjB,MAAMoB,UAAUH,KAAKjB,MAAMoB,SAAS8O,KAfjD,yCAkBqBlQ,GAAO,MACWA,EAA3BkQ,eADgB,SACCnN,EAAU/C,EAAV+C,MAErB9B,KAAKJ,MAAMqP,UAAYA,GAAWjP,KAAKJ,MAAMkC,QAAUA,GACzD9B,KAAKF,SAAS,CACZmP,UACAnN,YAxBR,+BA8BI,IAAIoN,EAOJ,OALEA,EADElP,KAAKJ,MAAMqP,QACF,0BAAMvP,UAAU,+BAEhB,0BAAMA,UAAU,kBAI3B,yBAAKA,UAAU,wBACb,8BACE,2BAAOA,UAAU,oBACf,2BACEnM,KAAK,WACL0b,QAASjP,KAAKJ,MAAMqP,QACpB9O,SAAUH,KAAKgO,aAAarX,KAAKqJ,QAElCkP,EACAlP,KAAKJ,MAAMkC,c,6BA/CxB,GAA8B6B,a,GAAjBqL,G,kBACQ,CACjBlN,MAAOZ,IAAUuB,OAAOrB,WACxB6N,QAAS/N,IAAUG,KACnBlB,SAAUe,IAAUI,M,o9BCDlB6N,G,YACJ,WAAYpQ,GAAO,M,IAAA,O,4FAAA,S,EACjB,K,EAAA,gBAAMA,GAAN,G,kDADiB,8BA2DC,SAAArL,GAClB,IAAME,EAASF,EAAME,OAEjBwC,EAAQxC,EAAOwC,MAEC,UAAhBxC,EAAOL,OACT6C,EAAQgZ,WAAWxb,EAAOwC,QAG5B,IAAMhB,EAAOxB,EAAOwB,KAEpB,EAAK0K,SAAL,MACG1K,EAAOgB,IAGG,kBAAThB,GAA4B,EAAK2J,MAAMsQ,oBACzC,EAAKtQ,MAAMsQ,mBAAmBD,WAAWhZ,OA3E1B,6BA+EA,WACjB,IAAMA,GAAS,EAAKwJ,MAAM0P,UAE1B,EAAKxP,SAAS,CACZwP,UAAWlZ,IAGT,EAAK2I,MAAMwQ,oBACb,EAAKxQ,MAAMwQ,mBAAmBnZ,MAvFf,8BA2FC,SAAA1C,GACd,EAAKqL,MAAMyQ,mBACb,EAAKzQ,MAAMyQ,kBAAkB9b,MA7Fd,8BAiGC,SAAAA,GACd,EAAKqL,MAAM0Q,mBACb,EAAK1Q,MAAM0Q,kBAAkB/b,MAnGd,+BAuGE,SAAAA,GACf,EAAKqL,MAAM2Q,oBACb,EAAK3Q,MAAM2Q,mBAAmBhc,MAzGf,6BA6GA,SAAAA,GACb,EAAKqL,MAAM4Q,kBACb,EAAK5Q,MAAM4Q,iBAAiBjc,MA5G9B,EAAKkM,MAAQ,CACXgQ,cAAe7Q,EAAM6Q,cACrBN,UAAWvQ,EAAMuQ,WALF,E,2SAqCAtM,GAIfhD,KAAKjB,MAAMuQ,YAActM,EAAUsM,WACnCtP,KAAKjB,MAAMuQ,YAActP,KAAKJ,MAAM0P,WAEpCtP,KAAKF,SAAS,CACZwP,UAAWtP,KAAKjB,MAAMuQ,YAKxBtP,KAAKjB,MAAM6Q,gBAAkB5M,EAAU4M,eACvC5P,KAAKjB,MAAM6Q,gBAAkB5P,KAAKJ,MAAMgQ,eAExC5P,KAAKF,SAAS,CACZ8P,cAAe5P,KAAKjB,MAAM6Q,kB,+BA6DvB,IACCvZ,EAAM2J,KAAKjB,MAAX1I,EACR,OACE,yBAAKqJ,UAAU,cACb,yBAAKA,UAAU,6BACb,yBAAKA,UAAU,iBACb,yBAAKA,UAAU,aACb,4BACEsK,MAAO3T,EAAE,uBACTqJ,UAAU,MACVmQ,cAAY,UACZ3P,QAASF,KAAK0P,oBAEd,kBAACvN,EAAA,EAAD,CAAM/M,KAAK,mBAEb,4BACE4U,MAAO3T,EAAE,kBACTqJ,UAAU,MACVmQ,cAAY,UACZ3P,QAASF,KAAKyP,mBAEd,kBAACtN,EAAA,EAAD,CAAM/M,KAAK,mBAEb,4BACE4U,MAAO3T,EAAE,eACTqJ,UAAU,MACVmQ,cAAY,UACZ3P,QAASF,KAAK8P,kBAEd,kBAAC3N,EAAA,EAAD,CAAM/M,KAAM4K,KAAKJ,MAAM0P,UAAY,OAAS,UAE9C,4BACEtF,MAAO3T,EAAE,cACTqJ,UAAU,MACVmQ,cAAY,UACZ3P,QAASF,KAAKwP,mBAEd,kBAACrN,EAAA,EAAD,CAAM/M,KAAK,kBAEb,4BACE4U,MAAO3T,EAAE,sBACTqJ,UAAU,MACVmQ,cAAY,UACZ3P,QAASF,KAAK2P,kBAEd,kBAACxN,EAAA,EAAD,CAAM/M,KAAK,oBAIjB,yBAAKsK,UAAU,gBACb,yBAAKA,UAAU,eACb,2BACEnM,KAAK,QACL6B,KAAK,gBACL2a,IAAK/P,KAAKjB,MAAMiR,iBAChBC,IAAKjQ,KAAKjB,MAAMmR,iBAChBC,KAAMnQ,KAAKjB,MAAMqR,kBACjBha,MAAO4J,KAAKJ,MAAMgQ,cAClBzP,SAAUH,KAAKqQ,qBAGnB,0BAAM3Q,UAAU,OACbM,KAAKJ,MAAMgQ,cAAcU,QAAQ,GADpC,IACyCja,EAAE,gB,gCAlL9B4K,iB,GAAnBkO,G,YAUe,CAEjBa,iBAAkB9O,IAAUC,OAAOC,WAEnC8O,iBAAkBhP,IAAUC,OAAOC,WAEnCgP,kBAAmBlP,IAAUC,OAAOC,WACpCwO,cAAe1O,IAAUC,OAAOC,WAEhCkO,UAAWpO,IAAUG,KAAKD,WAC1BmO,mBAAoBrO,IAAUI,KAC9B+N,mBAAoBnO,IAAUI,KAC9BkO,kBAAmBtO,IAAUI,KAC7BmO,kBAAmBvO,IAAUI,KAC7BoO,mBAAoBxO,IAAUI,KAC9BqO,iBAAkBzO,IAAUI,KAE5BjL,EAAG6K,IAAUI,KAAKF,a,GA3BhB+N,G,eA8BkB,CACpBa,iBAAkB,EAClBE,iBAAkB,GAClBE,kBAAmB,EACnBR,cAAe,GACfN,WAAW,IAwJf,IAEetJ,GAFYnD,YAAgB,aAAhBA,CAA8BsM,I,2+CCpLzD,IAAMoB,GAAoB,CACxB,CACE7Z,IAAK,MACLN,MAAO,OAET,CACEM,IAAK,MACLN,MAAO,QAOLoa,GAAuB,SAAC,GAaxB,IAZJC,EAYI,EAZJA,eACAC,EAWI,EAXJA,QACAC,EAUI,EAVJA,sBACAC,EASI,EATJA,eACAC,EAQI,EARJA,gBACAC,EAOI,EAPJA,kBACAC,EAMI,EANJA,UACAC,EAKI,EALJA,aACAC,EAII,EAJJA,YACAC,EAGI,EAHJA,YACAC,EAEI,EAFJA,YACAC,EACI,EADJA,YAEO/a,EADH,GACQgV,aAAe,wBADvB,WAG4BiB,mBAnBT,SAgBnB,GAGG+E,EAHH,KAGaC,EAHb,UAI4BhF,mBAAS,OAJrC,GAIGiF,EAJH,KAIaC,EAJb,UAMgClF,mBAAS,CAC3C1L,MAAOqQ,EACPpQ,OAAQoQ,IARN,GAMGQ,EANH,KAMeC,EANf,UAW0CpF,oBAAS,GAXnD,GAWGqF,EAXH,KAWoBC,EAXpB,UAagCtF,oBAAS,GAbzC,GAaGuF,EAbH,KAaeC,EAbf,UAc4CxF,mBAAS,CACvD1L,MAAO,EACPC,OAAQ,IAhBN,GAcGkR,EAdH,KAcqBC,EAdrB,UAmB0C1F,qBAnB1C,GAmBG2F,EAnBH,KAmBoBC,EAnBpB,UAoB8D5F,mBAAS,CACzE1L,MAAOqQ,EACPpQ,OAAQoQ,IAtBN,GAoBGkB,EApBH,KAoB8BC,EApB9B,UAyBwC9F,mBAAS,CACnD1D,IAAKyJ,sBACLzR,MAAOqQ,EACPpQ,OAAQoQ,IA5BN,GAyBGqB,EAzBH,KAyBmBC,EAzBnB,UA+B0CjG,mBAAS,CACrDzY,IAAK,KACL+M,MAAOqQ,EACPpQ,OAAQoQ,IAlCN,GA+BGuB,EA/BH,KA+BoBC,EA/BpB,UAqCsBnG,mBAAS,CACjC1L,OAAO,EACPC,QAAQ,EACRwQ,UAAU,IAxCR,GAqCGvc,EArCH,KAqCU4d,EArCV,KA2CEC,EAAWhiB,OAAOiiB,OAAO9d,GAAOgZ,UAAS,GAEzC+E,EAAkBC,iBAAO,MAezBC,EAAqB,SAACrf,EAAOsf,GACjC,IAAMC,EAAkC,WAAdD,EAAyB,QAAU,SACvDE,EAAuBxf,EAAME,OAAOwC,MAAM+c,QAAQ,KAAM,IACxDC,EAAmC,KAAzBF,EACVG,EAAgB,GAAH,GAAQ5B,GACrB6B,EAAmBF,EACrB,GACAG,KAAKxD,IAAImD,EAAsB/B,GAE/BmC,IAAqB7B,EAAWuB,KAIpCK,EAAcL,GAAaM,EAEvBzB,GAAmD,KAArCwB,EAAcJ,KAC9BI,EAAcJ,GAAqBM,KAAKC,MACtCH,EAAcL,GAAajB,EAAiBkB,KAMhDvB,EAAc2B,GAGTD,IACHhB,EAA6BiB,GAC7Bd,GAAkB,SAAA3S,GAAK,aAClBA,EADkB,GAElByT,SAKHI,GAAiB,CACrB7S,MAAOvK,EAAE,iBACTwK,OAAQxK,EAAE,kBACVgb,SAAUhb,EAAE,uBAGRqd,GAAqB,SAAAze,GACzB,OAAKH,EAAMG,GAIJ,yBAAKyK,UAAU,eAAe+T,GAAexe,IAH3C,MAmBL0e,GAAY,SAAAvd,GAAK,OAAKA,GAAS8a,EAAc9a,EAAQ8a,GACrD0C,GAAyBC,sBAAW,4BAAC,iIACkB9C,EACzDN,EACAwB,EACAR,EAAW7Q,MACX6Q,EAAW5Q,QAL4B,uBAC1BiT,EAD0B,EACjClT,MAA4BmT,EADK,EACblT,OAO5BiQ,EAAkBa,EAAiBM,GAE7B+B,EAAmB,CACvBnT,OAAQ8S,GAAUI,GAClBnT,MAAO+S,GAAUG,IAGnB1B,EAA6B4B,GAC7BzB,GAAkB,SAAA3S,GAAK,aAClBA,EADkB,GAElBoU,MAlBoC,UAyB/BrD,EACRsB,EACAK,EAAe1J,IAAIqL,QACnB1C,GA5BuC,iBAsBvC2C,EAtBuC,EAsBvCA,QACOC,EAvBgC,EAuBvCvT,MACQwT,EAxB+B,EAwBvCvT,OAOF4R,GAAmB,SAAA7S,GAAK,aACnBA,EADmB,CAEtB/L,IAAKqgB,EACLtT,MAAO+S,GAAUQ,GACjBtT,OAAQ8S,GAAUS,QAnCqB,4CAqCxC,CACD3D,EACAwB,EACAN,EACAZ,EACAD,EACAH,EACAY,EACAe,EAAe1J,IACfsI,EACAC,EACAgB,IA6CF,OA1CAkC,qBAAU,WAGR,OAFAzD,EAAeqB,GAER,WACLpB,EAAgBoB,MAEjB,CAACpB,EAAiBD,EAAgBqB,IAErCoC,qBAAU,WACwB,OAA5BxB,EAAgBoB,SAClBlf,aAAa8d,EAAgBoB,SAG/BpB,EAAgBoB,QAAU3e,YAAW,WACnCud,EAAgBoB,QAAU,KAC1BL,OA5M2B,OA8M5B,CACDnD,EACAwB,EACAN,EACAF,EACAV,EACAD,EACAH,EACAY,EACAe,EAAe1J,IACfsI,EACAC,IAGFkD,qBAAU,WAAM,IACNzT,EAAkB6Q,EAAlB7Q,MAAOC,EAAW4Q,EAAX5Q,OAOf6R,EAAS,GAAD,GANS,CACf9R,MAAOA,EAAQsQ,EACfrQ,OAAQA,EAASqQ,EACjBG,UAAWA,OAIZ,CAACI,EAAYJ,EAAUH,IAGxB,yBAAKxR,UAAU,wBACb,yBAAKA,UAAU,SAASrJ,EAAE,cAE1B,yBAAKqJ,UAAU,sBAAsB4C,UAAQ,uBAC3C,yBAAK5C,UAAU,qBACb,yBAAKA,UAAU,cACb,yBAAKA,UAAU,SACb,kBAAC,GAAD,CACEnM,KAAK,SACLwc,IAAKmB,EACLjB,IAAKkB,EACL/a,MAAOqb,EAAW7Q,MAClBkB,MAAOzL,EAAE,cACT8J,SAAU,SAAAmU,GAAG,OAAIvB,EAAmBuB,EAAK,UACzChS,UAAQ,gBAEToR,GAAmB,UAEtB,yBAAKhU,UAAU,UACb,kBAAC,GAAD,CACEnM,KAAK,SACLwc,IAAKmB,EACLjB,IAAKkB,EACL/a,MAAOqb,EAAW5Q,OAClBiB,MAAOzL,EAAE,eACT8J,SAAU,SAAAmU,GAAG,OAAIvB,EAAmBuB,EAAK,WACzChS,UAAQ,iBAEToR,GAAmB,YAGxB,yBAAKhU,UAAU,uBACb,4BACE8C,GAAG,cACH9C,UAAWiC,IACT,kBACAkQ,EAAa,SAAW,IAE1BvP,UAAQ,cACRiS,IAAKle,EAAE,mBACP6J,QApJe,WAAM,IACvBU,EAAkB6Q,EAAlB7Q,MAAOC,EAAW4Q,EAAX5Q,OACTkR,EAAmB,GAAH,GAAQA,GAC9B,IAAKF,EAAY,CACf,IAAM2C,EAAOjB,KAAKxD,IAAInP,EAAOC,GAC7BkR,EAAiBnR,MAAQA,EAAQ4T,EACjCzC,EAAiBlR,OAASA,EAAS2T,EACnCxC,EAAoBD,GAGtBD,GAAeD,KA4IL,kBAAC1P,EAAA,EAAD,CACE/M,KAAMyc,EAAa,OAAS,SAC5B0C,IAAK1C,EAAa,iBAAmB,mBAM7C,yBAAKnS,UAAU,OACb,yBAAKA,UAAU,aACb,kBAAC,GAAD,CACEnM,KAAK,OACL+O,UAAQ,YACRlM,MAAOib,EACPlR,SAAU,SAAAzM,GAAK,OAAI4d,EAAY5d,EAAME,OAAOwC,QAC5C0L,MAAOzL,EAAE,YACTmM,GAAG,cAEJkR,GAAmB,aAEtB,yBAAKhU,UAAU,aACb,kBAAC,GAAD,CACEtJ,MAAOmb,EACPjP,UAAQ,YACRnC,SAAU,SAAAzM,GAAK,OAAI8d,EAAY9d,EAAME,OAAOwC,QAC5Cqe,QAASlE,GACTzO,MAAOzL,EAAE,gBAKf,yBAAKqJ,UAAU,OACb,yBAAKA,UAAU,oBACb,2BAAOgV,QAAQ,mBAAmBhV,UAAU,oBAC1C,2BACE8C,GAAG,mBACHF,UAAQ,mBACR/O,KAAK,WACLmM,UAAU,mBACVuP,QAAS0C,EACTxR,SAAU,SAAAzM,GAAK,OAAIke,EAAmBle,EAAME,OAAOqb,YAEpD5Y,EAAE,uBAMX,yBACE+J,MAAO,CACLS,OAAQsR,EAA0BtR,OAClCD,MAAOuR,EAA0BvR,MACjC0G,SAAU,WACVE,KAAM,UAERoB,IAAK,SAAAA,GAAG,OAAIsJ,EAAmBtJ,KAE/B,4BACElJ,UAAW0R,EACXhR,MAAO,CACLS,OAAQyR,EAAezR,OACvBD,MAAO0R,EAAe1R,MACtBP,QAAS,SAEXO,MAAO0R,EAAe1R,MACtBC,OAAQyR,EAAezR,OACvB+H,IAAK0J,EAAe1J,OAIvB4J,EAAgB3e,IACf,yBAAK6L,UAAU,UAAU4C,UAAQ,iBAC/B,yBAAK5C,UAAU,kBAAf,IAAkCrJ,EAAE,iBACpC,4BACEqJ,UAAU,mBACV7L,IAAK2e,EAAgB3e,IACrB0gB,IAAKle,EAAE,gBACPiM,UAAQ,iBAJV,UAKU,0BAIZ,yBAAK5C,UAAU,iBACb,kBAACyC,EAAA,EAAD,CAAM/M,KAAK,eAAesK,UAAU,cACnCrJ,EAAE,mBAIP,yBAAKqJ,UAAU,WACb,yBAAKA,UAAU,iBACb,4BACEnM,KAAK,SACL+O,UAAQ,aACR5C,UAAU,iBACVQ,QAASwQ,GAERra,EAAE,oBAGP,yBAAKqJ,UAAU,eACb,4BACE2N,SAAUsF,EACVzS,QA1TY,WACpB8Q,EACEK,GAjEmB,QAkEnBE,EACAU,EACAK,EAAe1J,IAAIqL,UAsTbvU,UAAU,kBACV4C,UAAQ,gBAEPjM,EAAE,yBAQfma,GAAqBjO,UAAY,CAC/BmO,QAASxP,IAAUI,KAAKF,WACxBqP,eAAgBvP,IAAUrK,OAC1B8Z,sBAAuBzP,IAAUI,KAAKF,WACtCwP,eAAgB1P,IAAUI,KAAKF,WAC/ByP,gBAAiB3P,IAAUI,KAAKF,WAChC0P,kBAAmB5P,IAAUI,KAAKF,WAClC2P,UAAW7P,IAAUI,KAAKF,WAC1B4P,aAAc9P,IAAUI,KAAKF,WAE7B6P,YAAa/P,IAAUC,OAAOC,WAC9B8P,YAAahQ,IAAUC,OAAOC,WAC9B+P,YAAajQ,IAAUC,OAAOC,WAC9BgQ,YAAalQ,IAAUuB,OAAOrB,YAGjBoP,U,22BCzaR,IAAMmE,GAAb,iC,iGAAA,wF,EAAA,S,GAAA,0C,+CAAA,+BAmDuB,WACnB,MAAO,MApDX,E,UAAA,O,mOAAA,M,EAAA,G,EAAA,gCAOW,MAMH3U,KAAKjB,MAAM6V,UAJbC,EAFK,EAELA,UACAC,EAHK,EAGLA,iBACAC,EAJK,EAILA,WACAC,EALK,EAKLA,eAEIC,EAAcjV,KAAKjB,MAAM6C,OAAS,UAAY,GAC9CsT,EAAwBL,GAAaC,EAC3C,OACE,yBACEpV,UAAS,yBAAoBuV,GAC7B/U,QAASF,KAAKjB,MAAMmB,SAEpB,yBAAKR,UAAU,gBACb,yBAAKA,UAAU,iBACb,yBACEA,UAAU,oBACVU,MAAOJ,KAAKmV,sBAEXJ,IAGL,yBAAKrV,UAAU,aACZwV,EACC,kBAAC,IAAMxP,SAAP,KACE,yBAAKhG,UAAU,aAAamV,GAC5B,yBAAKnV,UAAU,oBAAoBoV,IAGrC,yBAAKpV,UAAU,qBACZsV,EACC,kBAAC,IAAMtP,SAAP,YAEA,kBAAC,IAAMA,SAAP,+B,6BAzClB,GAAiC/B,a,GAApBgR,G,YACQ,CACjBzU,QAASgB,IAAUI,KAAKF,WACxBwT,UAAW1T,IAAUrK,OAAOuK,WAC5BQ,OAAQV,IAAUG,O,22BCHf,IAAM+T,GAAb,iC,iGAAA,wF,EAAA,K,GAAA,2C,kDAAA,4BAgBoB,WAChB,OAAO,EAAKrW,MAAMsW,cAAc1U,KAAI,SAACiU,EAAWxP,GAC9C,OACE,kBAAC,GAAD,CACE1O,IAAK0O,EACLwP,UAAWA,EACXhT,OACEgT,EAAUU,mBAAqB,EAAKvW,MAAMwW,uBAE5CrV,QAAS,SAAAxM,GAAK,OAAI,EAAKqL,MAAMmB,QAAQ0U,YAzB/C,E,UAAA,O,mOAAA,M,EAAA,G,EAAA,gCASI,OACE,yBAAKlV,UAAS,sBAAiBM,KAAKjB,MAAM4J,QACvC3I,KAAKwV,wB,6BAXd,GAAiC7R,a,GAApByR,G,YACQ,CACjBzM,MAAOzH,IAAUuB,OACjB4S,cAAenU,IAAUiK,MAAM/J,WAC/BlB,QAASgB,IAAUI,KAAKF,WACxBmU,uBAAwBrU,IAAUuB,S,4jCCL/B,IAAMgT,GAAb,iC,iGAAA,wF,EAAA,K,GAAA,2C,kDAAA,2BAiBmB,WACf,OAAO,EAAK1W,MAAM2W,YAAY/U,KAAI,SAACgV,EAAYvQ,GAC7C,OACE,kBAACwQ,EAAA,EAAD,IACElf,IAAKif,EAAWE,sBAChBrT,GAAE,uBAAkB4C,IAChBuQ,EAHN,CAIE/T,OACE+T,EAAWE,wBACX,EAAK9W,MAAM+W,4BAEb5V,QAAS,kBAAM,EAAKnB,MAAMmB,QAAQyV,aA5B5C,E,UAAA,O,mOAAA,M,EAAA,G,EAAA,gCAQI,OACE,kBAAC,IAAMjQ,SAAP,KACE,yBAAKhG,UAAU,oDACb,yBAAKA,UAAU,0BAA0BM,KAAK+V,yB,6BAXxD,GAAgCpS,a,GAAnB8R,G,YACQ,CACjBC,YAAaxU,IAAUiK,MAAM/J,WAC7BlB,QAASgB,IAAUI,KAAKF,WACxB0U,4BAA6B5U,IAAUuB,S,22BCDpC,IAAMuT,GAAb,YAWE,WAAYjX,GAAO,M,IAAA,O,4FAAA,S,EACjB,K,EAAA,gBAAMA,GAAN,G,kDADiB,2BAuEF,WACf,IAAI4W,EAEJ,GAAI,EAAK5W,MAAM4W,WACbA,EAAa,EAAK5W,MAAM4W,gBACnB,GAAI,EAAK/V,MAAM2V,uBAAwB,CAK5CI,EAJc,EAAK5W,MAAMsW,cAAcY,MACrC,SAAAC,GAAK,OAAIA,EAAMZ,mBAAqB,EAAK1V,MAAM2V,0BAG9BY,gBAEnBR,EAAa,EAAK5W,MAAMsW,cAAc,GAAGc,WAG3C,OAAOR,GAAc,MAtFJ,8BAyFC,WAElB,OADoB,EAAKI,kBAAoB,IAC1BpV,KAAI,SAACgV,EAAYvQ,GAClC,IAAMxD,EACJ+T,EAAWE,wBACX,EAAKjW,MAAMkW,4BACb,OACE,yBAAKpf,IAAK0O,EAAO1F,UAAS,sBAAiBkC,EAAS,SAAW,YAhGlD,yBAqGJ,SAAAwU,GACT,EAAKrX,MAAMsX,iBACb,EAAKtX,MAAMsX,gBAAgBD,GAE7B,EAAKtW,SAAS,CACZyV,uBAAwBa,EAAkBd,iBAC1CgB,uBAAuB,OA3GR,0BA+GH,SAAAC,GACd,EAAKzW,SAAS,CACZgW,4BAA6BS,EAAmBV,wBAGlD,EAAK9W,MAAMyX,iBAAiBD,MApHX,6BAuHA,WACjB,EAAKzW,SAAS,CACZwW,uBAAuB,OAzHR,6BA6HA,WACjB,EAAKxW,SAAS,CACZwW,uBAAuB,OA5HzB,EAAK1W,MAAQ,CACX0W,uBAAuB,EACvBG,UAAW,EAAK1X,MAAM2X,MAAQ,GAC9BnB,uBAAwB,EAAKxW,MAAMwW,uBACnCO,4BAA6B,EAAK/W,MAAM+W,6BAPzB,E,UAXrB,O,mOAAA,M,EAAA,G,EAAA,0CAsBqB9S,GACjB,IAAMjE,EAAQiB,KAAKjB,MAEfA,EAAMwW,yBAA2BvS,EAAUuS,wBAC7CvV,KAAKF,SAAS,CACZyV,uBAAwBxW,EAAMwW,yBAKhCxW,EAAM+W,8BACN9S,EAAU8S,6BAEV9V,KAAKF,SAAS,CACZgW,4BAA6B/W,EAAM+W,gCApC3C,+BA0CI,IAAMa,EAAmB3W,KAAKJ,MAAM0W,sBAChC,mBACA,GAEJ,OACE,yBACE5W,UAAS,gDAA2CM,KAAKJ,MAAM6W,UAAtD,YAAmEE,GAC5E3V,aAAchB,KAAK4W,kBAEnB,yBAAKlX,UAAU,gBAAgBqB,aAAcf,KAAK6W,kBAChD,yBAAKnX,UAAU,eAAf,UACA,yBAAKA,UAAU,cACZM,KAAK8W,oBACN,kBAAC,EAAD,CAAgBjQ,WAAY,IAAK8B,MAAM,kBACrC,kBAAC,GAAD,CACE+M,YAAa1V,KAAK+V,iBAClB7V,QAASF,KAAK+W,cACdjB,4BACE9V,KAAKJ,MAAMkW,iCAMrB,yBAAKpW,UAAU,gBACb,yBAAKA,UAAU,eAAf,SACA,yBAAKA,UAAU,aACb,kBAAC,EAAD,CAAgBmH,WAAY,GAAI8B,MAAM,iBACpC,kBAAC,GAAD,CACE0M,cAAerV,KAAKjB,MAAMsW,cAC1BnV,QAASF,KAAKgX,aACdzB,uBAAwBvV,KAAKJ,MAAM2V,kC,6BAzEnD,GAAiC5R,a,GAApBqS,G,YACQ,CACjBU,KAAMxV,IAAUuB,OAChB4S,cAAenU,IAAUiK,MAAM/J,WAC/BoV,iBAAkBtV,IAAUI,KAAKF,WACjCuU,WAAYzU,IAAUiK,MACtBkL,gBAAiBnV,IAAUI,KAC3BiU,uBAAwBrU,IAAUuB,OAClCqT,4BAA6B5U,IAAUuB,S,+2BCVrCwU,G,YA8BJ,aAAc,M,IAAA,O,4FAAA,S,EACZ,K,EAAA,oB,kDADY,iBAJN,CACNC,aAAc,KAGF,0BAKE,SAAA9gB,GACd,IAAI+gB,EAAW/gB,EACX,EAAK2I,MAAM3I,QAAUA,IACvB+gB,EAAW,MAGT,EAAKpY,MAAMqY,gBACb,EAAKrY,MAAMqY,eAAeD,MAV5B,EAAKE,aAAe,EAAKA,aAAa1gB,KAAlB,OAFR,E,qSAgBDjD,GACX,IAAM4jB,EAActX,KAAKjB,MAAM0V,QAAQ8C,WACrC,SAAA1hB,GAAC,OAAIA,EAAEO,QAAU1C,EAAM8jB,OAAO5jB,UAEhC,GAAI0jB,GAAe,EAAG,CACpB,IAAMJ,EAAelX,KAAKJ,MAAMsX,aAChCA,EAAaI,GAAe5jB,EAAM8jB,OAAOC,YACzCzX,KAAKF,SAAS,CAAEoX,oB,0CAIA,WAClBlX,KAAKjB,MAAM0V,QAAQ5G,SAAQ,SAAA6J,GACrBA,EAAOC,YACT7kB,SAASqW,iBAAiBuO,EAAOC,WAAY,EAAKN,mB,yCAKrCrU,EAAW4U,GAAW,WACvC5X,KAAKjB,MAAM0V,QAAQ5G,SAAQ,SAAC6J,EAAQtS,GAEhCsS,EAAOC,YACPD,EAAOC,cACJ3U,EAAUyR,QAAQrP,GACfpC,EAAUyR,QAAQrP,GAAOuS,WACzB,QAEN7kB,SAASsW,oBAAoBsO,EAAOC,WAAY,EAAKN,cACrDvkB,SAASqW,iBAAiBuO,EAAOC,WAAY,EAAKN,oB,6CAKjC,WACrBrX,KAAKjB,MAAM0V,QAAQ5G,SAAQ,SAAA6J,GACrBA,EAAOC,YACT7kB,SAASsW,oBAAoBsO,EAAOC,WAAY,EAAKN,mB,+BAKlD,WACH3X,EAAYiC,IACdsV,EAAmBvX,UACnB,yBAGImY,EAAU7X,KAAKjB,MAAM0V,QAAQ9T,KAAI,SAAC+W,EAAQtS,GAC9C,IAAM1F,EAAYiC,IAAW,CAC3BmW,sBAAsB,EACtBC,UAAU,EACVnW,OAAQ,EAAK7C,MAAM3I,QAAUshB,EAAOthB,QAGhC4hB,EAAaN,EAAO5V,OAAS,8BAAO4V,EAAO5V,OAC3CD,EACmB,iBAAhB6V,EAAOjW,KAAoB,CAAErM,KAAMsiB,EAAOjW,MAASiW,EAAOjW,KAE7DwW,EAAcP,EAAOO,aACzB,yBAAKvY,UAAU,eAAegY,EAAOO,aAGnCR,EAAc,EAAK7X,MAAMsX,aAAa9R,GACpC8S,EAAsBC,OAAOV,GAAa/mB,OAAS,EAOzD,OANA+mB,EAAcA,EACVS,EACE,GACAT,EACF,KAGF,yBACE/gB,IAAK0O,EACL1F,UAAWA,EACXQ,QAAS,kBAAM,EAAKkY,cAAcV,EAAOthB,SAEzC,yBAAKsJ,UAAU,iBACZsY,EACAP,GACC,yBAAK/X,UAAU,yBACb,0BAAMA,UAAU,eACb+X,EACAS,GAAuB,MAI7BrW,GAAa,kBAACM,EAAA,EAASN,IAEzBoW,MAKP,OAAO,yBAAKvY,UAAWA,GAAYmY,Q,gCA5INlU,a,GAA3BsT,G,YACe,sB,GADfA,G,YAGe,CACjBxC,QAASvT,IAAU0L,QACjB1L,IAAUyB,MAAM,CACdvM,MAAO8K,IAAU2L,IACjB/K,MAAOZ,IAAUuB,OACjBkV,WAAYzW,IAAUuB,OACtBhB,KAAMP,IAAUwB,UAAU,CACxBxB,IAAUuB,OACVvB,IAAUyB,MAAM,CACdvN,KAAM8L,IAAUuB,OAAOrB,kBAK/BhL,MAAO8K,IAAUuB,OACjB2U,eAAgBlW,IAAUI,O,GAlBxB2V,G,eAqBkB,CACpBxC,QAAS,GACTre,MAAO,O,+2BC1BUiiB,G,wVA6BN,SAAA/D,GACX,EAAKvV,MAAMuZ,WAAWhE,EAAK,EAAKvV,MAAMwZ,a,mSAnBtC,IAAMC,EAAaxY,KAAKjB,MAAMyZ,WAAaxY,KAAKjB,MAAMyZ,WAAa,GACnE,OACE,2BACE9Y,UAAW,2BAA6B8Y,EACxC9D,QAAS1U,KAAKjB,MAAMyD,IAEpB,2BACEjP,KAAK,QACLiP,GAAIxC,KAAKjB,MAAMyD,GACf9C,UAAU,aACVtJ,MAAO4J,KAAKjB,MAAM3I,MAClB+J,SAAUH,KAAKsY,aAEjB,0BAAM5Y,UAAU,eAAeM,KAAKjB,MAAM+C,a,gCAxBV6B,a,mzBAAnB0U,G,YACA,CACjBjiB,MAAO8K,IAAUuB,OACjBX,MAAOZ,IAAUuB,OAAOrB,WACxBmX,SAAUrX,IAAUrK,OAAOuK,WAC3BoX,WAAYtX,IAAUuB,OACtBD,GAAItB,IAAUuB,OAAOrB,WACrBkX,WAAYpX,IAAUI,KAAKF,a,ICNVqX,G,2cAQjB,OACE,yBAAK/Y,UAAU,wBACb,2BACEA,UAAU,0BACVgV,QAAQ,wBAER,2BACEnhB,KAAK,QACLiP,GAAG,uBACH9C,UAAU,sBACVtJ,MAAO4J,KAAKjB,MAAM3I,MAClB+J,SAAUH,KAAKjB,MAAMuZ,aAEvB,0BAAM5Y,UAAU,eACd,0BAAMA,UAAU,YACd,kBAACyC,EAAA,EAAD,CAAM/M,KAAK,mBAEZ4K,KAAKjB,MAAM+C,c,gCAzB0B6B,c,8GAA7B8U,G,YACA,CACjB3W,MAAOZ,IAAUuB,OAAOrB,WACxBhL,MAAO8K,IAAUuB,OAAOrB,WACxBkX,WAAYpX,IAAUI,KAAKF,a,43BCCxB,IAAMsX,GAAb,YAqBE,WAAY3Z,GAAO,M,IAAA,O,4FAAA,S,EACjB,K,EAAA,gBAAMA,GAAN,G,kDADiB,+BAkCE,WACf,EAAKA,MAAM4Z,mBACb,EAAK5Z,MAAM4Z,uBApCI,2BAwCF,SAAA9M,GAAI,OAAIA,IAAStG,MAAMC,QAAQqG,EAAK+M,UAxClC,0BA0CH,SAAA/M,GACd,IAAI2M,EAAa,WAIjB,OAHI,EAAK5Y,MAAMiZ,YAActT,MAAMC,QAAQqG,EAAK+M,UAC9CJ,EAAa,YAERA,KA/CU,uBAyGN,WACX,IAAIxO,EAAQ,EAAKjL,MAAM+Z,qBAKvB,OAJI,EAAKlZ,MAAMmZ,aAAe,EAAKha,MAAMia,wBACvChP,EAAQ,EAAKjL,MAAMia,uBAInB,yBAAKtZ,UAAU,2BACb,yBAAKA,UAAU,eAAesK,GAC7B,EAAKjL,MAAMka,eACV,yBAAKvZ,UAAU,iBACb,yBAAKA,UAAU,cACb,kBAACyC,EAAA,EAAD,CAAM/M,KAAK,YAEb,2BACE7B,KAAK,OACLmM,UAAU,cACVwZ,YAAY,gBACZC,UAAW,EAAKpa,MAAMoa,UACtBhZ,SAAU,EAAKiZ,gBACfhjB,MAAO,EAAKwJ,MAAMiZ,WAAa,EAAKjZ,MAAMiZ,WAAa,UA7HhD,4BAqID,SAAAvE,GAChB,EAAKxU,SAAS,CACZiZ,YAAa,KACbF,WAAYvE,EAAI+E,cAAcjjB,WAxIf,uBA4IN,SAAC1C,EAAOmY,GAYnB,OAXI,EAAKyN,eAAezN,GACtB,EAAK/L,SAAS,CACZ+Y,WAAY,KACZE,YAAa,KACb3iB,MAAO,OAGT,EAAK0J,SAAS,CACZiZ,YAAalN,IAGV,EAAK9M,MAAMuZ,WAAW5kB,EAAOmY,MAxJnB,iCA2JI,WACrB,EAAK/L,SAAS,CACZiZ,YAAa,UA1Jf,EAAKnZ,MAAQ,CACXiZ,WAAY,KACZE,YAAa,KACb3iB,MAAO,MANQ,E,UArBrB,O,mOAAA,M,EAAA,G,EAAA,gCAgCI,IAAMmjB,EAAYvZ,KAAKwZ,eAEvB,OACE,yBAAK9Z,UAAU,6BACb,yBAAKA,UAAU,eACZM,KAAKyZ,aACN,yBAAK/Z,UAAU,eACZM,KAAKJ,MAAMmZ,aACV,kBAAC,GAAD,CACET,WAAYtY,KAAK0Z,qBACjB5X,MAAO9B,KAAKJ,MAAMmZ,YAAYjX,MAC9B1L,MAAO4J,KAAKJ,MAAMmZ,YAAY3iB,QAGlC,yBAAKsJ,UAAU,qBACb,yBAAKA,UAAU,cAAc6Z,SA/C3C,oCAuEgB,WACNI,EAAgB,GAmBtB,OAlBiBC,KAAU5Z,KAAKjB,MAAM6Z,OAC7B/K,SAAQ,SAAAhC,GACf,GAAItG,MAAMC,QAAQqG,EAAK+M,OACrB/M,EAAK+M,MAAM/K,SAAQ,SAAAhC,GACjB,IAAM/J,EAAQ+J,EAAK/J,MAAMO,cACnBwW,EAAa,EAAKjZ,MAAMiZ,WAAWxW,eACN,IAA/BP,EAAM+X,QAAQhB,IAChBc,EAAc3oB,KAAK6a,UAGlB,CACL,IAAM/J,EAAQ+J,EAAK/J,MAAMO,cACnBwW,EAAa,EAAKjZ,MAAMiZ,WAAWxW,eACN,IAA/BP,EAAM+X,QAAQhB,IAChBc,EAAc3oB,KAAK6a,OAIlB8N,IA3FX,qCA8FiB,WAYb,OARI3Z,KAAKJ,MAAMiZ,WACD7Y,KAAK8Z,cACR9Z,KAAKJ,MAAMmZ,YACRa,KAAU5Z,KAAKJ,MAAMmZ,YAAYH,OAEjCgB,KAAU5Z,KAAKjB,MAAM6Z,QAGlBjY,KAAI,SAACkL,EAAMzG,GAC1B,IAAI/B,EAAU+B,EAId,OAHI,EAAKxF,MAAMmZ,cACb1V,GAAW,IAAJ,OAAQ,EAAKzD,MAAMmZ,YAAY3iB,QAGtC,kBAAC,GAAD,CACEM,IAAK2M,EACLb,GAAE,UAnBW,aAmBX,YAAmBqJ,EAAKzV,OAC1BhB,KAAMgQ,EACNmT,SAAU1M,EACVzV,MAAOyV,EAAKzV,MACZ0L,MAAO+J,EAAK/J,MACZ0W,WAAY,EAAKuB,cAAclO,GAC/ByM,WAAY,EAAKA,qB,6BAxH3B,GAAgC3U,a,GAAnB+U,G,YACQ,CACjBS,UAAWjY,IAAUG,KACrB4X,cAAe/X,IAAUG,KACzByX,qBAAsB5X,IAAUuB,OAChCuW,sBAAuB9X,IAAUuB,OAEjCkW,kBAAmBzX,IAAUI,KAE7BsX,MAAO1X,IAAUiK,MAAM/J,WAEvBkX,WAAYpX,IAAUI,KAAKF,a,GAXlBsX,G,eAcW,CACpBO,eAAe,EACfE,WAAW,EACXL,qBAAsB,oBACtBF,MAAO,K,s2CCtBLoB,G,qVA2EM,SAAAtmB,GACRA,EAAMyP,iBACNzP,EAAM0P,kBACN,EAAKrE,MAAM2R,a,sBAGD,SAAAhd,GACVA,EAAMyP,iBACNzP,EAAM0P,kBACN,EAAKrE,MAAMkb,e,mSAxCX,OACE,kBAAC,IAAMvU,SAAP,KACG1F,KAAKjB,MAAMmb,QACV,yBACExa,UAAS,uBAAkBM,KAAKjB,MAAMob,UAA7B,KACTvR,IAAK5I,KAAKjB,MAAMqb,aAChBha,MAAOJ,KAAKjB,MAAMsb,gBAElB,8BACE,yBAAK3a,UAAU,UACb,0BAAMA,UAAU,WAAWQ,QAASF,KAAK0Q,SACvC,0BAAMhR,UAAU,aAAhB,MAEF,wBAAIA,UAAU,SAASM,KAAKjB,MAAMwK,cAEpC,yBAAK7J,UAAU,WAAWM,KAAKjB,MAAM2E,UACrC,yBAAKhE,UAAU,UACb,4BAAQA,UAAU,kBAAkBQ,QAASF,KAAK0Q,SAAlD,UAGA,4BAAQhR,UAAU,kBAAkBQ,QAASF,KAAKia,WAAlD,oB,gCAhEWtW,a,GAArBqW,G,YACe,CACjBtW,SAAUxC,IAAU0C,KACpBwW,aAAclZ,IAAU2L,IACxBwN,eAAgBnZ,IAAUrK,OAC1BsjB,UAAWjZ,IAAUuB,OACrByX,OAAQhZ,IAAUG,KAClBkI,YAAarI,IAAUuB,OAAOrB,WAC9BsP,QAASxP,IAAUI,KAAKF,WACxB6Y,UAAW/Y,IAAUI,KAAKF,a,GATxB4Y,G,eAYkB,CACpBE,QAAQ,EACRG,eAAgB,GAChBF,UAAW,K,GAfTH,G,eAkBiB,YAAuD,IAApDM,EAAoD,EAApDA,SAAUC,EAA0C,EAA1CA,aAAcvQ,EAA4B,EAA5BA,MAAOlI,EAAqB,EAArBA,MAAO4O,EAAc,EAAdA,QAAc,KAChDpE,mBAASiO,GADuC,GACnEnkB,EADmE,KAC5DokB,EAD4D,KAO1E,OACE,yBAAK9a,UAAU,eACb,kBAAC,GAAD,CACE6J,YAAaS,EACb0G,QAASA,EACTuJ,UATkB,WACtBK,EAASlkB,KAUL,kBAAC,GAAD,CACE7C,KAAK,OACL6C,MAAOA,EACP+J,SAAU,SAAAzM,GAAK,OAAI8mB,EAAS9mB,EAAME,OAAOwC,QACzC0L,MAAOA,S,yBCnCb2Y,I,OAAc,CAClB5U,QAAS,CACP6U,OAAQ,KACR5O,gBAAiB,oBACjBzL,QAAS,OACTsa,WAAY,SACZC,eAAgB,YAIpBC,KAAMC,cAAchoB,SAASioB,eAAe,SAE5C,IAAMC,GAAY,SAAC,GASb,IARJtb,EAQI,EARJA,UACAub,EAOI,EAPJA,YACAC,EAMI,EANJA,iBACAhB,EAKI,EALJA,OACAiB,EAII,EAJJA,WACAnR,EAGI,EAHJA,MACA0G,EAEI,EAFJA,QACAhN,EACI,EADJA,SAiBM0X,EAAUD,EACZlN,IAAW,YAAavO,EAAW,wBACnCuO,IAAW,YAAavO,GAE5B,OACE,kBAAC,KAAD,CACEA,UAAW0b,EACX9Y,UAAQ,QACR4Y,iBAAkBA,EAClBhB,OAAQA,EACRlQ,MAAOA,EACP5J,MAAOqa,IAEP,oCA1BAzQ,GACE,yBAAKtK,UAAU,oBAAoB4C,UAAQ,gBACzC,4BAAK0H,GACJiR,GACC,4BAAQ3Y,UAAQ,eAAepC,QAASwQ,GAAxC,MAwBJ,yBAAKhR,UAAU,qBAAqB4C,UAAQ,iBACzCoB,MAOXsX,GAAUzY,UAAY,CACpB7C,UAAWwB,IAAUuB,OACrBwY,YAAa/Z,IAAUG,KACvB6Z,iBAAkBha,IAAUG,KAC5B6Y,OAAQhZ,IAAUG,KAClB2I,MAAO9I,IAAUuB,OACjBiO,QAASxP,IAAUI,KACnBoC,SAAUxC,IAAUwB,UAAU,CAC5BxB,IAAU0L,QAAQ1L,IAAU0C,MAC5B1C,IAAU0C,OACTxC,YAGU4Z,UC5ETK,I,OAAc,SAAC,GAAuB,IAArBzC,EAAqB,EAArBA,MAAO1Y,EAAc,EAAdA,QAC5B,OACE,yBAAKR,UAAU,cAAc4b,cAAe,SAAAjpB,GAAC,OAAIA,EAAE8Q,mBACjD,4BACGyV,EAAMjY,KAAI,SAACkL,EAAMzG,GAAP,OACT,wBAAI1O,IAAK0O,GACP,4BAAQ1F,UAAU,cAAcQ,QAAS,kBAAMA,EAAQ2L,KACrD,0BAAMnV,IAAK0O,GAAQyG,EAAK/J,gBAStCuZ,GAAY9Y,UAAY,CACtBqW,MAAO1X,IAAUiK,MAAM/J,WACvBlB,QAASgB,IAAUI,KAAKF,YAGXia,UCnBTE,I,OAAY,SAAC,GAA2C,IAAzCzmB,EAAyC,EAAzCA,MAAOkV,EAAkC,EAAlCA,MAAOwR,EAA2B,EAA3BA,YAAaC,EAAc,EAAdA,QAC9C,OACE,yBAAK/b,UAAU,aACZsK,GAAS,4BAAKA,GACf,2BAAIwR,GACJ,kBAACrZ,EAAA,EAAD,CACEzC,UAAU,aACVtK,KAAK,eACLwL,MAAM,OACNC,OAAO,OACPX,QAASub,IAEV3mB,GACC,yBAAK4K,UAAU,mBACb,6BAAM5K,EAAMK,SACZ,6BAAML,EAAM4mB,WAOtBH,GAAUhZ,UAAY,CACpBzN,MAAOoM,IAAUrK,OACjBmT,MAAO9I,IAAUuB,OACjB+Y,YAAata,IAAUuB,OACvBgZ,QAASva,IAAUI,MAGrBia,GAAU3Y,aAAe,CACvB4Y,YAAa,sDACbC,QAAS,kBAAMvkB,OAAOykB,SAASC,WAGlBL,ICvCAA,GDuCAA,G,6oBE3Bf,SAASM,GAAsB9c,GAC7B+c,KAAOC,OAAOC,KAAKpN,UADiB,IAG5BvY,EAAMgV,aAAe,cAArBhV,EAGN4lB,EAKEld,EALFkd,cACAC,EAIEnd,EAJFmd,UACAC,EAGEpd,EAHFod,QAEGC,GACDrd,EAFFsd,QATkC,GAWhCtd,EAXgC,oDA8FpC,OACE,kBAAC,mBAAD,MACMqd,EADN,CAEEF,UAAWA,EACXC,QAASA,EACTG,mBAtFsB,WAAM,IACtBD,EAAYtd,EAAZsd,QAER,OACE,yBAAK3c,UAAU,+BACZ2c,EAAQ1b,KAAI,YAA0B,IAAvB4b,EAAuB,EAAvBA,KAAMC,EAAiB,EAAjBA,MAAOC,EAAU,EAAVA,IACrBC,EAAaR,IAAcM,GAASL,IAAYM,EAEtD,OACE,4BACE/lB,IAAK6lB,EACLhpB,KAAK,SACLmM,UAAS,uCACPgd,EAAa,yCAA2C,IAE1Dxc,QAAS,kBACP+b,EAAc,CACZC,UAAWM,EACXL,QAASM,EACTE,QAAQ,MAIXJ,QAgETN,cAAeA,EACfW,mBA1DuB,SAArBA,EAAsB,GAA2C,IAAzCC,EAAyC,EAAzCA,MAAOC,EAAkC,EAAlCA,cAAeC,EAAmB,EAAnBA,aAC5CC,EAAiB,CACrBC,OAAQ,SAoBV,OALAL,EAAmBra,UAAY,CAC7Bua,cAAe5b,IAAUI,KACzByb,aAAc7b,IAAUI,MAIxB,yBAAKlB,MAAO,CAAEC,QAAS,OAAQua,eAAgB,WAC7C,yBAAKxa,MAAO4c,GACV,4BACEtd,UAAU,yBACVtJ,MAAOymB,EAAMA,QACb1c,SAAU,SAAA9N,GAAC,OAAIyqB,EAAcD,EAAOxqB,EAAEuB,OAAOwC,SAE5C0lB,KAAOoB,SAASvc,KAAI,SAACmB,EAAO1L,GAAR,OACnB,4BAAQM,IAAKN,EAAOA,MAAOA,GACxB0L,QAKT,yBAAK1B,MAAO4c,GAEV,4BACEtd,UAAU,yBACVtJ,MAAOymB,EAAMM,OACbhd,SAAU,SAAA9N,GAAC,OAAI0qB,EAAaF,EAAOxqB,EAAEuB,OAAOwC,SArCzB,WAIzB,IAHA,IACMqe,EAAU,GAEPjkB,EAAI,EAAGA,EAHG,GAGaA,IAAK,CACnC,IAAM2sB,EAAOrB,OAASqB,OAAS3sB,EAC/BikB,EAAQzjB,KAAK,4BAAQoF,MAAO+mB,GAAOA,IAGrC,OAAO1I,EA8BA2I,OAePC,yBAA0BhnB,EAAE,cAC5BinB,uBAAwBjnB,EAAE,YAC1BknB,QAAS,CACPC,gBAAiBnnB,EAAE,gBACnBonB,WAAYpnB,EAAE,mBAMtBwlB,GAAsBtZ,UAAY,CAChC8Z,QAASnb,IAAU0L,QACjB1L,IAAUyB,MAAM,CACd4Z,KAAMrb,IAAUuB,OAChB+Z,MAAOtb,IAAUwc,SACjBjB,IAAKvb,IAAUwc,YAGnBzB,cAAe/a,IAAUI,KAAKF,WAC9B8a,UAAWhb,IAAUyc,WAAWC,MAChCzB,QAASjb,IAAUyc,WAAWC,MAC9Bf,MAAO3b,IAAUyc,WAAWC,OAGf/B,U,ufCnIf,IAAMgC,GAAe,SAACC,EAAYC,GAChC,OAAOA,GAAmBD,GAAc,MAGpCE,GAAwB,SAACC,EAAOC,GAA8B,IAAnBC,EAAmB,uDAAZ,QACtD,GAAyB,iBAAdD,EAIX,MAAa,QAATC,EACKF,OAEPA,EAAMG,SAASF,EAAW,SAI9B,SAASG,GAAkBtf,GAAO,IAE9Buf,EAQEvf,EARFuf,KACA1L,EAOE7T,EAPF6T,OACA2L,EAMExf,EANFwf,OACAC,EAKEzf,EALFyf,cACAC,EAIE1f,EAJF0f,cACAC,EAGE3f,EAHF2f,cAEAC,EACE5f,EADF4f,2BAT8B,EAYO/L,GAAU,GAAzCgM,EAZwB,EAYxBA,YAAaC,EAZW,EAYXA,cAZW,KAaQvS,mBAAS,MAbjB,GAazBwS,EAbyB,KAaXC,EAbW,OAcW1T,aAAe,UAAlDhV,EAdwB,EAcxBA,EAAU2oB,EAdc,EAcrBC,MAELC,EAAY,CAAC,OAAQ,UAAW,aAChCC,EACc,QAAlBT,EAA0BQ,EAAU,GAAKA,EAAU,GAE/CjB,EAAQnC,OACRsD,EAAWtD,OAASsC,SAAS,EAAG,OAChCiB,EAAYvD,OAASsC,SAAS,EAAG,SAEjCkB,EAAmBtB,GACvBC,EACAU,EACA,SAEIY,EAAiBvB,GACrBC,EACAU,EACA,OAGIa,EAAmB,CACvB,CACEjD,KAAMlmB,EAAE,SACRmmB,MAAOyB,EACPxB,IAAKwB,GAEP,CACE1B,KAAMlmB,EAAE,eACRmmB,MAAO4C,EACP3C,IAAKwB,GAEP,CACE1B,KAAMlmB,EAAE,gBACRmmB,MAAO6C,EACP5C,IAAKwB,IAIT,OAAOe,EACHV,EAAK3d,KAAI,SAAC8e,EAAOjvB,GAAM,IACb6U,EAAsCoa,EAAtCpa,YAAaqa,EAAyBD,EAAzBC,UAAWC,EAAcF,EAAdE,UAE1BC,EADcnB,IAAkBiB,EACPP,EAAuBD,EAAU,GAEhE,OACE,wBAAIxoB,IAAG,UAAKgpB,EAAL,YAAkBlvB,IACvB,2BACEkkB,QAAO,iBAAYgL,GACnBxf,QAAS,kBAAMqe,EAAOmB,KAFxB,UAIMra,GACJ,kBAAClD,EAAA,EAAD,CAAM/M,KAAMwqB,EAAUxf,MAAO,CAAEyf,SAAU,WAE5B,SAAdF,GACC,2BACEpsB,KAAK,OACLiP,GAAE,iBAAYkd,GACdhgB,UAAU,gCACVtJ,MAAOwc,EAAO8M,GACdvf,SAAU,SAAA9N,GAAC,OAAImsB,EAAckB,EAAWrtB,EAAEuB,OAAOwC,UAGtC,eAAdupB,GAEC,kBAAC,GAAD,CAEEzD,UAAW2B,GAAagB,EAAeS,GACvCQ,YAAY,aACZ3D,QAAS0B,GAAae,EAAaW,GACnCQ,UAAU,WAEV9D,cAAe,YAA4C,IAAzCC,EAAyC,EAAzCA,UAAWC,EAA8B,EAA9BA,QAA8B,EAArBQ,OACpC6B,EAAc,gBAAiBtC,GAC/BsC,EAAc,cAAerC,IAE/B2C,aAAcA,EACdkB,cAAe,SAAAC,GAAU,OAAIlB,EAAgBkB,IAE7CC,eAAgB,EAChBC,gBAAgB,EAChBC,gBAAgB,OAChB/D,QAASmD,EACTa,4BAA4B,EAC5BC,eAAgB,SAAAC,GAAG,OAAKC,kCAAuBD,EAAKzE,eAM9D,KAGNuC,GAAkB9b,UAAY,CAC5B+b,KAAMpd,IAAU0L,QACd1L,IAAUyB,MAAM,CACd0C,YAAanE,IAAUuB,OAAOrB,WAC9Bse,UAAWxe,IAAUuB,OAAOrB,WAC5Bue,UAAWze,IAAUuf,MAAM,CAAC,OAAQ,eAAerf,WACnDsf,KAAMxf,IAAUC,OAAOC,cAEzBA,WACFwR,OAAQ1R,IAAUrK,OAAOuK,WACzBmd,OAAQrd,IAAUI,KAAKF,WACvBqd,cAAevd,IAAUuB,OACzBic,cAAexd,IAAUuf,MAAM,CAAC,KAAM,MAAO,UAG/CpC,GAAkBzb,aAAe,GAGlByb,UCxIf,IAAMrY,GAAqBnD,YAAgB,uBAAhBA,EAR3B,YAAgD,IAAbiK,EAAa,EAAhBzW,EAC9B,OACE,yBAAKqJ,UAAU,gBACZoN,EAAU,WADb,OAC4B,kBAAC3K,EAAA,EAAD,CAAM/M,KAAK,eAAeurB,UAAU,cCC9DC,GAA8B,SAClCC,EACAC,EACAC,GAOA,OAJEF,KAAeC,EACXA,EAAgBD,GAChBE,GAUR,SAASC,GAAUjiB,GAAO,IAEtBkiB,EAUEliB,EAVFkiB,UACAtO,EASE5T,EATF4T,SACAuO,EAQEniB,EARFmiB,QACAC,EAOEpiB,EAPFoiB,KACQC,EAMNriB,EANFwf,OACA8C,EAKEtiB,EALFsiB,aACgBC,EAIdviB,EAJFwiB,eACcC,EAGZziB,EAHF0iB,aACA9C,EAEE5f,EAFF4f,2BACAkC,EACE9hB,EADF8hB,YAXsB,EAamBxV,aAAe,aAAlDhV,EAbgB,EAahBA,EAAU2oB,EAbM,EAabC,MAELyC,EAAiB,CACrB,CACErc,YAAahP,EAAE,eACfqpB,UAAW,cACXC,UAAW,OACXe,KAAM,KAER,CACErb,YAAahP,EAAE,OACfqpB,UAAW,YACXC,UAAW,OACXe,KAAM,KAER,CACErb,YAAahP,EAAE,mBACfqpB,UAAW,kBACXC,UAAW,OACXe,KAAM,KAER,CACErb,YAAahP,EAAE,aACfqpB,UAAW,YACXC,UAAW,aACXe,KAAM,KAER,CACErb,YAAahP,EAAE,YACfqpB,UAAW,aACXC,UAAW,OACXe,KAAM,KAER,CACErb,YAAahP,EAAE,oBACfqpB,UAAW,mBACXC,UAAW,OACXe,KAAM,MAIJiB,EAAkB,CACtB,CACEtc,YAAa,GAAF,OAAKhP,EAAE,eAAP,cAA2BA,EAAE,QACxCqpB,UAAW,kBACXC,UAAW,OACXe,KAAM,KAER,CACErb,YAAahP,EAAE,eACfqpB,UAAW,mCACXC,UAAW,OACXe,KAAM,KAER,CACErb,YAAahP,EAAE,aACfqpB,UAAW,YACXC,UAAW,aACXe,KAAM,MAIJkB,EAAiB,CACrB,CACEvc,YAAahP,EAAE,UACfqpB,UAAW,YACXC,UAAW,OACXe,KAAM,MAIJmB,EAAYjB,GAChBC,EACA,CAAEiB,MAAOJ,EAAgBK,OAAQJ,EAAiBK,MAAOJ,GACzDA,GAGIK,EAAYJ,EACflhB,KAAI,SAAA8e,GAAK,OAAIA,EAAMiB,QACnBwB,QAAO,SAACC,EAAMC,GAAP,OAAgBD,EAAOC,KAEjC,OAAOpD,EACL,2BAAOtf,UAAU,yCACf,kCACGmiB,EAAUlhB,KAAI,SAAC8e,EAAOjvB,GACrB,IACM6xB,EADO5C,EAAMiB,KACUuB,EAAa,IAE1C,OAAO,yBAAKvrB,IAAKlG,EAAG4P,MAAO,CAAEQ,MAAO,GAAF,OAAKyhB,EAAL,YAGtC,2BAAO3iB,UAAU,cACf,wBAAIA,UAAU,WACZ,kBAAC,GAAD,CACE4e,KAAMuD,EACNjP,OAAQyO,EACR9C,OAAQ6C,EACR5C,cAAe8C,EACf7C,cAAe0C,EAAKzB,UACpBhB,cAAeyC,EAAKmB,UACpB3D,2BAA4BA,MAIlC,2BAAOjf,UAAU,aAAa4C,UAAQ,sBASnC2e,GACC,wBAAIvhB,UAAU,YACZ,wBAAI6iB,QAASV,EAAUnxB,QACrB,kBAAC,GAAD,SAIJuwB,GAAatO,GACb,wBAAIjT,UAAU,YACZ,wBAAI6iB,QAASV,EAAUnxB,QACrB,yBAAKgP,UAAU,YACZrJ,EAAE,2CAMT4qB,IAAcC,EAAQxwB,QACtB,wBAAIgP,UAAU,YACZ,wBAAI6iB,QAASV,EAAUnxB,QACrB,yBAAKgP,UAAU,YAAYrJ,EAAE,2BAIjC4qB,GACAC,EAAQvgB,KAAI,SAACuV,EAAO9Q,GAAR,OACV,kBAACod,GAAD,CACE9rB,IAAG,UAAKwf,EAAMZ,iBAAX,YAA+BlQ,GAClClF,QAAS,SAAAoV,GAAgB,OAAIkM,EAAiBlM,IAC9CmN,gBAAiBvM,EAAMuM,iBAAmB,GAC1C1N,WAAYmB,EAAMnB,WAClB2N,UAAWxM,EAAMwM,WAAa,GAC9BC,YAAazM,EAAMyM,aAAe,GAClC9N,UAAWqB,EAAMrB,UACjBC,iBAAkBoB,EAAMpB,kBAAoB,GAC5CQ,iBAAkBY,EAAMZ,iBACxBuL,YAAaA,SAKrB,KAmCN,SAAS2B,GAASzjB,GAAO,IAErB0jB,EAUE1jB,EAVF0jB,gBACAG,EASE7jB,EATF6jB,cACA7N,EAQEhW,EARFgW,WACA2N,EAOE3jB,EAPF2jB,UACAC,EAME5jB,EANF4jB,YACA9N,EAKE9V,EALF8V,UACAC,EAIE/V,EAJF+V,iBACAQ,EAGEvW,EAHFuW,iBACSuN,EAEP9jB,EAFFmB,QACA2gB,EACE9hB,EADF8hB,YAGMxqB,EAAMgV,aAAe,aAArBhV,EAEFysB,EACJ,wBACE5iB,QAAS,kBAAM2iB,EAAYvN,IAC3B5V,UAAWuO,IAAW,CAAErM,OAAQghB,KAEhC,wBAAIljB,UAAWuO,IAAW,CAAE,eAAgB0U,KACzCA,GAAe,IAAJ,OAAQtsB,EAAE,SAAV,MAEd,4BAAKqsB,GACL,4BAAKD,GACL,4BAAK5N,GACL,wBAAInV,UAAWuO,IAAW,CAAE,eAAgB8G,KACzCA,GAAc,IAAJ,OAAQ1e,EAAE,SAAV,MAEb,4BAAKye,IAIHiO,EACJ,wBACE7iB,QAAS,kBAAM2iB,EAAYvN,IAC3B5V,UAAWuO,IAAW,CAAErM,OAAQghB,KAEhC,wBAAIljB,UAAWuO,IAAW,CAAE,eAAgB0U,KACzCA,GAAe,IAAJ,OAAQtsB,EAAE,SAAV,KACZ,yBAAK+J,MAAO,CAAE4iB,MAAO,YAAcN,IAErC,4BACE,yBAAKtiB,MAAO,CAAEC,QAAS,OAAQua,eAAgB,kBAE7C,yBACElb,UAAU,UACVU,MAAO,CACL6iB,WAAY,WACZC,SAAU,IAGXpO,GAIH,yBACE1U,MAAO,CACLC,QAAS,OACT8iB,cAAe,SACfC,SAAU,OACVxiB,MAAO,SAGT,yBACElB,UAAWuO,IAAW,CACpB8G,WAAYA,EACZ,eAAgBA,IAElBsO,aAAYtO,EACZ/K,MAAO+K,GAENA,GAAc,IAAJ,OAAQ1e,EAAE,SAAV,MAEb,yBACE+J,MAAO,CACLkjB,aAAc,WACdL,WAAY,SACZvb,SAAU,UAEZ2b,aAAYZ,EACZzY,MAAOyY,GAENA,MAMT,wBAAIriB,MAAO,CAAEmjB,UAAW,WAAa1O,IAInC2O,EACJ,wBACEtjB,QAAS,kBAAM2iB,EAAYvN,IAC3B5V,UAAWuO,IAAW,CAAErM,OAAQghB,KAEhC,wBAAIxiB,MAAO,CAAEkH,SAAU,WAAYI,SAAU,WAC3C,yBAAKtH,MAAO,CAAEC,QAAS,OAAQua,eAAgB,kBAE7C,yBACElb,UAAWuO,IAAW,CAAE,eAAgB0U,IACxCviB,MAAO,CAAEQ,MAAO,QAASL,SAAU,UAEnC,yBAAKH,MAAO,CAAEqjB,WAAY,IAAKC,WAAY,QACxCf,GAAe,IAAJ,OAAQtsB,EAAE,SAAV,MAEd,yBAAK+J,MAAO,CAAE4iB,MAAO,YAAcN,IAIrC,yBACEhjB,UAAU,UACVU,MAAO,CACL6iB,WAAY,WACZC,SAAU,EACVS,YAAa,SAGd7O,GAIH,yBACE1U,MAAO,CACLC,QAAS,OACT8iB,cAAe,SACfC,SAAU,OACVxiB,MAAO,SAGT,yBACElB,UAAWuO,IAAW,CACpB8G,WAAYA,EACZ,eAAgBA,IAElBsO,aAAYtO,EACZ/K,MAAO+K,GAENA,GAAc,IAAJ,OAAQ1e,EAAE,SAAV,MAEb,6BAAMwe,OAiBhB,OAVoB+L,GAClBC,EACA,CACEiB,MAAOgB,EACPf,OAAQgB,EACRf,MAAOwB,GAETA,GA7LJxC,GAAUze,UAAY,CACpB0e,UAAW/f,IAAUG,KAAKD,WAC1BuR,SAAUzR,IAAUG,KAAKD,WACzB8f,QAAShgB,IAAUiK,MAAM/J,WACzBqgB,aAAcvgB,IAAUI,KAAKF,WAE7B+f,KAAMjgB,IAAUyB,MAAM,CACpB+c,UAAWxe,IAAUuB,OACrB6f,UAAWphB,IAAUuf,MAAM,CAAC,OAAQ,MAAO,SAC1Crf,WACHmd,OAAQrd,IAAUI,KAAKF,WAEvBigB,aAAcngB,IAAUyB,MAAM,CAC5BggB,YAAazhB,IAAUuB,OAAOrB,WAC9BshB,UAAWxhB,IAAUuB,OAAOrB,WAC5BqhB,gBAAiBvhB,IAAUuB,OAAOrB,WAClCyT,UAAW3T,IAAUuB,OAAOrB,WAC5B2T,WAAY7T,IAAUuB,OAAOrB,WAC7B0T,iBAAkB5T,IAAUuB,OAAOrB,WACnCwiB,gBAAiB1iB,IAAUuB,OAAOrB,WAClCyiB,iCAAkC3iB,IAAUuB,OAAOrB,WACnD0iB,UAAW5iB,IAAUuB,OAAOrB,WAC5Bwd,YAAa1d,IAAU2L,IACvBgS,cAAe3d,IAAU2L,MACxBzL,WACHmgB,eAAgBrgB,IAAUI,KAAKF,WAC/Bud,2BAA4Bzd,IAAUC,OACtC0f,YAAa3f,IAAUuB,QAGzBue,GAAUpe,aAAe,GAqKzB4f,GAASjgB,UAAY,CACnBkgB,gBAAiBvhB,IAAUuB,OAAOrB,WAClCwhB,cAAe1hB,IAAUG,KACzB0T,WAAY7T,IAAUuB,OACtBigB,UAAWxhB,IAAUuB,OAAOrB,WAC5BuhB,YAAazhB,IAAUuB,OAAOrB,WAC9ByT,UAAW3T,IAAUuB,OAAOrB,WAC5B0T,iBAAkB5T,IAAUuB,OAAOrB,WACnCkU,iBAAkBpU,IAAUuB,OAAOrB,WACnCyf,YAAa3f,IAAUuB,QAGzB+f,GAAS5f,aAAe,CACtBggB,eAAe,G,+2BChZXmB,G,sVAkBO,WACT,EAAKhlB,MAAMilB,aAAa,EAAKjlB,MAAMklB,gB,qBAG1B,WACT,EAAKllB,MAAMmlB,aAAa,EAAKnlB,MAAMklB,gB,gCAGf,SAAAvwB,GACpB,EAAKqL,MAAMolB,oBAAoBC,SAAS1wB,EAAME,OAAOwC,W,oTAIrD,OACE,yBAAKsJ,UAAU,8BACb,yBAAKA,UAAU,gDACb,kBAAC,IAAMgG,SAAP,KACE,wBAAIhG,UAAU,iCACZ,wBAAIA,UAAU,kBACZ,4BACEQ,QAASF,KAAKqkB,SACdhX,SAAqC,IAA3BrN,KAAKjB,MAAMklB,YACrBvkB,UAAU,iBAETM,KAAKjB,MAAM1I,EAAE,cAGlB,wBAAIqJ,UAAU,kBACZ,4BACEQ,QAASF,KAAKskB,SACdjX,SAC6B,IAA3BrN,KAAKjB,MAAMwlB,aACXvkB,KAAKjB,MAAMylB,YAAcxkB,KAAKjB,MAAMwlB,YAEtC7kB,UAAU,iBAETM,KAAKjB,MAAM1I,EAAE,gB,kDAW5B,OACE,yBAAKqJ,UAAU,wCACb,8BAAOM,KAAKjB,MAAM1I,EAAE,SACpB,4BACE8J,SAAUH,KAAKmkB,oBACf5J,aAAcva,KAAKjB,MAAMylB,aAExBxkB,KAAKjB,MAAM0lB,YAAY9jB,KAAI,SAAA+jB,GAC1B,OACE,4BAAQhuB,IAAKguB,EAAYtuB,MAAOsuB,GAC7BA,OAKT,8BAAO1kB,KAAKjB,MAAM1I,EAAE,mB,+BAMxB,OACE,yBAAKqJ,UAAU,mBACb,yBAAKA,UAAU,iBAAiBM,KAAK2kB,6BACrC,yBAAKjlB,UAAU,sBACb,yBAAKA,UAAU,iDACZM,KAAK4kB,kC,gCA3FY3jB,iB,GAAxB8iB,G,eACkB,CACpBU,YAAa,CAAC,EAAG,GAAI,GAAI,GAAI,KAC7BD,YAAa,GACbP,YAAa,I,GAJXF,G,YAOe,CAEjBU,YAAavjB,IAAUiK,MACvBqZ,YAAatjB,IAAUC,OAAOC,WAC9B6iB,YAAa/iB,IAAUC,OAAOC,WAC9B4iB,aAAc9iB,IAAUI,KACxB4iB,aAAchjB,IAAUI,KACxB6iB,oBAAqBjjB,IAAUI,KAC/BijB,YAAarjB,IAAUC,OAAOC,aAoFlC,IAAM4E,GAAqBnD,YAAgB,SAAhBA,CAA0BkhB,I,w2BCnG/Cc,G,sVAKO,SAAAnxB,GACL,EAAKqL,MAAM+lB,UACb,EAAK/lB,MAAM+lB,SAASpxB,M,0SAKtB,GAAIsM,KAAKjB,MAAM+lB,SACb,OACE,yBAAKplB,UAAU,wBACb,2BACEgV,QAAQ,YACRtU,MAAO,CAAEQ,MAAO,QAChBV,QAASF,KAAK8kB,UAEd,kBAAC3iB,EAAA,EAAD,CAAM/M,KAAK,a,+BAQnB,OAAO,yBAAKsK,UAAU,oBAAoBM,KAAK+kB,sB,gCA5BzB9jB,iB,GAApB4jB,G,YACe,CACjBC,SAAU5jB,IAAUI,O,ukCCClB0jB,G,YAiCJ,WAAYjmB,GAAO,M,IAAA,O,4FAAA,S,EACjB,K,EAAA,gBAAMA,GAAN,G,kDADiB,+BAOE,kBACnB,kBAAC,IAAD,CACE6G,UAAU,SACVlG,UAAU,0BACV8C,GAAE,UAAK+Q,KAAK0R,SAAV,8BAED,EAAKC,iBAbS,uBAiBN,WACX,OAAO,EAAKnmB,MAAM8Y,QAAQlX,KAAI,SAACwkB,EAAQ/f,GACrC,OACE,kBAAC,EAAD,IACE1O,IAAK0O,GACD+f,EAFN,CAGE3jB,SAAU2jB,EAAO3iB,KAAO,EAAKzD,MAAMqmB,uBAvBxB,qBA6BR,WACT,IAAI5jB,GAAW,EASf,OARI,EAAKzC,MAAMqmB,eACb,EAAKrmB,MAAM8Y,QAAQhK,SAAQ,SAAAsX,GACrB,EAAKpmB,MAAMqmB,gBAAkBD,EAAO3iB,KACtChB,GAAW,MAKVA,KAvCU,uBA0CN,WACX,OAAI,EAAKzC,MAAMqmB,eAEX,EAAKrmB,MAAM8Y,QAAQ5B,MAAK,SAAAoP,GAAG,OAAI,EAAKtmB,MAAMqmB,gBAAkBC,EAAI7iB,MAC7Df,MAIA,EAAK1C,MAAM0C,QAlDD,kCAqDK,WAClB,EAAK1C,MAAMumB,kBACb,EAAKvmB,MAAMumB,mBAEb,EAAKxlB,SAAS,CACZkC,YAAa,EAAKpC,MAAMoC,gBA1DT,0BA8DH,WACd,EAAKlC,SAAS,CACZkC,YAAY,OA9Dd,EAAKpC,MAAQ,CACXoC,YAAY,GAHG,E,iSAoEV,WAgBDujB,EAbF,kBAAC,EAAD,CACE7uB,IAAI,cACJnD,KAAK,OACLuO,MAAO,EAAK/C,MAAM+C,MAClBL,KAAM,EAAK+jB,aACX9lB,UAAW,oCACX8B,SAAU,EAAKA,WACfU,cAAc,EACdF,WAAY,EAAKpC,MAAMoC,aAO7B,OACE,kBAAC,IAAD,CACEtL,IAAI,cACJ+uB,QAAQ,QACR7f,UAAU,SACV8f,WAAW,EACXC,WAAY3lB,KAAK4lB,cACjB1lB,QAASF,KAAK6lB,sBACdhgB,QAAS7F,KAAK8lB,sBAEbP,Q,gCAjIwBQ,IAAMpiB,W,GAAjCqhB,G,YACe,CAEjBljB,MAAOZ,IAAUuB,OAAOrB,WAExByW,QAAS3W,IAAU0L,QACjB1L,IAAUyB,MAAM,CACdH,GAAItB,IAAUuB,OACdX,MAAOZ,IAAUuB,OAAOrB,WACxBK,KAAMP,IAAUwB,UAAU,CACxBxB,IAAUuB,OACVvB,IAAUyB,MAAM,CACdvN,KAAM8L,IAAUuB,OAAOrB,kBAI7BA,WACFK,KAAMP,IAAUwB,UAAU,CACxBxB,IAAUuB,OACVvB,IAAUyB,MAAM,CACdvN,KAAM8L,IAAUuB,OAAOrB,eAG3BkkB,iBAAkBpkB,IAAUI,KAC5B8jB,cAAelkB,IAAUuB,S,GAxBvBuiB,G,eA2BkB,CACpBnN,QAAS,GACTpW,KAAM,iBACNK,MAAO,SAyGIkjB,U,8nCCtITgB,G,2cA0BK,WACDpN,EAAQ5Y,KAAKjB,MAAM8Y,QAAQlX,KAAI,SAACwkB,EAAQ/f,GAC5C,OAAI+f,EAAOtN,SAAWtS,MAAMC,QAAQ2f,EAAOtN,SAEvC,kBAAC,GAAD,IACEnhB,IAAG,qBAAgB0O,IACf+f,EAFN,CAGEC,cAAeD,EAAOc,gBAKxB,kBAAC,EAAD,IACEvvB,IAAK0O,GACD+f,EAFN,CAGE3jB,SAAU,EAAKzC,MAAMmnB,cAAcpY,SAASqX,EAAO3iB,UAM3D,OACE,yBAAK9C,UAAWiC,IAAW,iBAAkB3B,KAAKjB,MAAMW,YACrDkZ,Q,gCAjDoB3X,iB,GAAvB+kB,G,eACkB,CACpBtmB,UAAW,K,GAFTsmB,G,YAKe,CACjBnO,QAAS3W,IAAU0L,QACjB1L,IAAUyB,MAAM,CACdH,GAAItB,IAAUuB,OACdX,MAAOZ,IAAUuB,OAAOrB,WACxBK,KAAMP,IAAUwB,UAAU,CACxBxB,IAAUuB,OACVvB,IAAUyB,MAAM,CACdvN,KAAM8L,IAAUuB,OAAOrB,eAI3ByW,QAAS3W,IAAU0L,QAAQ1L,IAAUyB,MAAM,QAE7CvB,WAEF8kB,cAAehlB,IAAU0L,QAAQ1L,IAAUuB,QAAQrB,WAEnD1B,UAAWwB,IAAUuB,S,cC3BnB0jB,I,OAAgB,SAAC,GAAkD,IAAhDrxB,EAAgD,EAAhDA,MAAOsxB,EAAyC,EAAzCA,eAAyC,EAAzBC,mBAC9C,OACE,yBAAK3mB,UAAU,gBAAgBgB,KAAK,SAClC,oDACA,6BAAM5L,EAAMK,SACZ,6BAAMixB,MAKNE,GAAoB,SAAC,GAMrB,QALJjgB,eAKI,MALM,OAKN,MAJJkgB,eAII,MAJM,aAIN,MAHJC,eAGI,MAHM,aAGN,EAFJC,EAEI,EAFJA,kBACA/iB,EACI,EADJA,SAWA,OACE,kBAAC,iBAAD,CACEgjB,kBAAmBD,GAAqBN,GACxCI,QAPmB,WACrBA,KAOEC,QAbmB,SAAC1xB,EAAOsxB,GAC7BpvB,QAAQlC,MAAR,UAAiBuR,EAAjB,mBAA2CvR,EAAOsxB,GAClDI,EAAQ1xB,EAAOsxB,KAaZ1iB,IAKP4iB,GAAkB/jB,UAAY,CAC5B8D,QAASnF,IAAUuB,OACnB8jB,QAASrlB,IAAUI,KACnBklB,QAAStlB,IAAUI,KACnBoC,SAAUxC,IAAU0C,KAAKxC,WACzBqlB,kBAAmBvlB,IAAUwB,UAAU,CAACxB,IAAU0C,KAAM1C,IAAUI,KAAMJ,IAAU2H,WAGrEyd,U,yrCC1Cf,IAAMK,GAAiB,SACrBC,EACAC,EACAC,GAEA,IAAMD,GAAsBC,IAAwBF,EAApD,CAKA,IAAMxhB,EAAQwhB,EAAcrP,WAAU,SAAAwP,GAAG,OAAIA,EAAIC,WAGjD,OAAO5hB,GAAS,QAAyC,IAA7ByhB,EAAkBzhB,GAC1CyhB,EAAkBzhB,GAClB0hB,IAMAG,GAAmB,SAAAC,GACvB,OACEA,GACAA,EAAuBvmB,KAAI,SAAAwmB,GAAC,OAAIjwB,OAAOkwB,WAAWD,OAwChDE,GAAW,SACfH,EACAL,EACAS,GACG,SAEuBhb,oBAAS,WACjC,IAAMib,EAAiBN,GAAiBC,GAOxC,MAAO,CACLN,cAAeW,EACf1G,YARmB8F,GACnBY,EACAV,EACAS,GAMAJ,yBACAL,oBACAS,uBAfD,GAEI1nB,EAFJ,KAEWE,EAFX,KAkBC0nB,EAAQ1U,kBAAO,GAkCb2U,EAAqB5T,uBAAY,SAAA6T,GACrC,GAAIA,EAAWV,QAAS,CACtB,IAAMW,EA9Fc,SAACD,EAAY9nB,GAAU,IACvCgoB,EAAUF,EAAVE,MACAV,EAA8CtnB,EAA9CsnB,uBAOR,OAPsDtnB,EAAtBinB,kBAElBK,EAAuB3P,WAAU,SAAAsQ,GAE7C,OADkC3wB,OAAOkwB,WAAWS,GAA5CD,QACkBA,MAwFAE,CAAkBJ,EAAY9nB,GAlChCihB,EAmCJ8G,EAlChBH,EAAMvT,SACRnU,EAAS,MAAKF,EAAN,CAAaihB,iBAFC,IAAAA,IAqCvB,IAyCH,OAtCAxM,qBAAU,WAAM,IAEY0T,EAEtBnoB,EAFFsnB,uBACmBc,EACjBpoB,EADFinB,mBAGCK,IACEe,KAAQf,EAAwBa,IAClClB,IAAsBoB,KAAQpB,EAAmBmB,KA1ClC,SAAA5xB,GAAS,IAEzB8wB,EAGE9wB,EAHF8wB,uBACAL,EAEEzwB,EAFFywB,kBACAS,EACElxB,EADFkxB,iBAGIV,EAAgBK,GAAiBC,GACjCrG,EAAc8F,GAClBC,EACAC,EACAS,GAIEE,EAAMvT,SACRnU,EAAS,MACJF,EADG,CAENsnB,yBACAL,oBACAhG,cACA+F,mBAuBFsB,CAAY,CACVhB,yBACAL,wBAGH,CAACK,EAAwBL,IAG5BxS,qBAAU,WACkBzU,EAAlBgnB,cACM/Y,SAAQ,SAAAkZ,GACpBA,EAAIoB,eAAeV,GACnBV,EAAIqB,YAAYX,QAEjB,CAAC7nB,EAAMgnB,gBAEVvS,qBAAU,WAGR,OAFAmT,EAAMvT,SAAU,EAET,WACLuT,EAAMvT,SAAU,EACUrU,EAAlBgnB,cACM/Y,SAAQ,SAAAkZ,GACpBA,EAAIoB,eAAeV,SAGtB,IAEI7nB,EAAMihB,a,ufCrKA,SAASwH,GAAYjyB,EAAO8P,GAAO,SACJoG,mBAASlW,GADL,GACzCkyB,EADyC,KACzBC,EADyB,KA8BhD,OA3BAlU,qBACE,WAEE,IAAMmU,EAAUlzB,YAAW,WACzBizB,EAAkBnyB,KACjB8P,GAYH,OAAO,WACLnR,aAAayzB,MAMjB,CAACpyB,IAGIkyB,E,svBCnCHG,G,YACJ,WAAY1pB,GAAO,M,IAAA,O,4FAAA,S,EACjB,K,EAAA,gBAAMA,GAAN,G,+JADiB,uBAOJ,SAAArL,GACb,IAAM0C,EAAQ1C,EAAME,OAAOwC,MAC3B,EAAK0J,SAAS,CAAE1J,UACZ,EAAK2I,MAAMoB,UAAU,EAAKpB,MAAMoB,SAAS/J,MAR7C,EAAKwJ,MAAQ,CACXxJ,MAAO,EAAK2I,MAAM3I,OAHH,E,iSAcjB,OACE,4BACEsJ,UAAU,cACVtJ,MAAO4J,KAAKJ,MAAM8oB,SAClBvoB,SAAUH,KAAKgO,cAEdhO,KAAKjB,MAAM0V,QAAQ9T,KAAI,YAAoB,IAAjBjK,EAAiB,EAAjBA,IAAKN,EAAY,EAAZA,MAC9B,OACE,4BAAQM,IAAKA,EAAKN,MAAOA,GACtBM,Y,gCAxBMiN,aAiCrB8kB,GAAOlmB,UAAY,CACjBkS,QAASvT,IAAU0L,QACjB1L,IAAUyB,MAAM,CACdjM,IAAKwK,IAAUuB,OAAOrB,WACtBhL,MAAO8K,IAAUuB,OAAOrB,cAG5BhL,MAAO8K,IAAUuB,OACjBtC,SAAUe,IAAUI,MAGPmnB,U,yjCC1CTA,G,YACJ,WAAY1pB,GAAO,M,IAAA,O,4FAAA,S,EACjB,K,EAAA,gBAAMA,GAAN,G,kDADiB,yBAeJ,SAAArL,GACb,IAAM0C,EAAQ1C,EAAME,OAAOwC,MAC3B,EAAK0J,SAAS,CAAE1J,UACZ,EAAK2I,MAAMoB,UAAU,EAAKpB,MAAMoB,SAAS/J,MAlB5B,E,iSAsBjB,OACE,yBAAKsJ,UAAU,yBACZM,KAAKjB,MAAM+C,OACV,2BAAOpC,UAAU,oBAAoBgV,QAAS1U,KAAKwC,IAAKxC,KAAKjB,MAAM+C,OAErE,+BAAQpC,UAAU,4BAA+BM,KAAKjB,OACnDiB,KAAKjB,MAAM0V,QAAQ9T,KAAI,YAAoB,IAAjBjK,EAAiB,EAAjBA,IAAKN,EAAY,EAAZA,MAC9B,OACE,4BAAQM,IAAKA,EAAKN,MAAOA,GACtBM,a,gCAhCIiN,a,GAAf8kB,G,YAKe,CACjBhU,QAASvT,IAAU0L,QACjB1L,IAAUyB,MAAM,CACdjM,IAAKwK,IAAUuB,OAAOrB,WACtBhL,MAAO8K,IAAUuB,OAAOrB,cAG5BhL,MAAO8K,IAAUuB,OACjBtC,SAAUe,IAAUI,O,o0BCZtB,WAAYvC,GAAO,a,4FAAA,UACjB,0BAAMA,KACDa,MAAQ,CAAExJ,MAAO,EAAK2I,MAAMwd,MAFhB,E,iSAMjB,OACE,2BAAO7c,UAAU,aAAagV,QAAS1U,KAAKjB,MAAM4pB,KAC/C3oB,KAAKjB,MAAMwd,W,gCATAwJ,IAAMpiB,YAepBpB,UAAY,CAChBga,KAAMrb,IAAUuB,OAAOrB,WACvBunB,IAAKznB,IAAUuB,Q,svBClBXmmB,G,YACJ,WAAY7pB,GAAO,M,IAAA,O,4FAAA,S,EACjB,K,EAAA,gBAAMA,GAAN,G,+JADiB,uBAKJ,SAAArL,GACb,EAAKoM,SAAS,CAAE1J,MAAO1C,EAAME,OAAOwC,QAChC,EAAK2I,MAAMoB,UAAU,EAAKpB,MAAMoB,SAASzM,MAL7C,EAAKkM,MAAQ,CAAExJ,MAAO2I,EAAM3I,OAAS,GAFpB,E,iSAWjB,OACE,oCACE,2BACE7C,KAAK,QACL6C,MAAO4J,KAAKJ,MAAMxJ,MAClB2Z,IAAK/P,KAAKjB,MAAMgR,IAChBE,IAAKjQ,KAAKjB,MAAMkR,IAChBE,KAAMnQ,KAAKjB,MAAMoR,MAAQ,EACzBhQ,SAAUH,KAAKgO,aACfxL,GAAIxC,KAAKjB,MAAMyD,GACf9C,UAAU,UAEXM,KAAKjB,MAAM8pB,gBAAkB,wCAAU7oB,KAAKJ,MAAMxJ,MAArB,MAC7B4J,KAAKjB,MAAM+pB,WACV,8BACG9oB,KAAKjB,MAAMgqB,cACR/oB,KAAKjB,MAAMgqB,cAAc/oB,KAAKJ,MAAMxJ,OACpC4J,KAAKJ,MAAMxJ,a,gCA7BPuN,aAqCpBilB,GAAMrmB,UAAY,CAChBnM,MAAO8K,IAAUC,OACjB4O,IAAK7O,IAAUC,OAAOC,WACtB6O,IAAK/O,IAAUC,OAAOC,WACtB+O,KAAMjP,IAAUC,OAChBqB,GAAItB,IAAUuB,OACdsmB,cAAe7nB,IAAUI,KACzBnB,SAAUe,IAAUI,KACpBunB,eAAgB3nB,IAAUG,KAC1BynB,UAAW5nB,IAAUG,MAGvBunB,GAAMhmB,aAAe,CACnBimB,gBAAgB,EAChBC,WAAW,G,+vBClDX,WAAY/pB,GAAO,M,IAAA,O,4FAAA,S,EACjB,K,EAAA,gBAAMA,GAAN,G,+JADiB,uBAKJ,SAAArL,GACb,EAAKoM,SAAS,CAAE1J,MAAO1C,EAAME,OAAOwC,QAChC,EAAK2I,MAAMoB,UAAU,EAAKpB,MAAMoB,cALpC,EAAKP,MAAQ,CAAExJ,MAAO,EAAK2I,MAAM3I,OAFhB,E,iSAWjB,OACE,8BACEsJ,UAAU,gBACVtJ,MAAO4J,KAAKJ,MAAMxJ,MAClBkJ,KAAMU,KAAKjB,MAAMO,KACjB0pB,KAAMhpB,KAAKjB,MAAMiqB,KACjB7oB,SAAUH,KAAKgO,aACfxL,GAAIxC,KAAKjB,MAAMyD,U,gCAnBAujB,IAAMpiB,YAyBpBpB,UAAY,CACnBnM,MAAO8K,IAAUuB,OACjBnD,KAAM4B,IAAUC,OAChB6nB,KAAM9nB,IAAUC,OAChBqB,GAAItB,IAAUuB,OACdtC,SAAUe,IAAUI,M,qoCC9BhB2nB,G,YACJ,WAAYlqB,GAAO,O,4FAAA,iCACXA,I,iSAqBN,OACE,yBAAKW,UAAU,wBACZM,KAAKjB,MAAM+C,OACV,2BAAOpC,UAAU,mBAAmBgV,QAAS1U,KAAKjB,MAAMyD,IAAKxC,KAAKjB,MAAM+C,OAE1E,8BACEvO,KAAMyM,KAAKjB,MAAMxL,KACjBiP,GAAIxC,KAAKjB,MAAMyD,GACf9C,UAAU,2BACNM,KAAKjB,c,gCAhCKgnB,IAAMpiB,W,GAAxBslB,G,YAKe,CACjB7yB,MAAO8K,IAAUwB,UAAU,CACzBxB,IAAUuB,OACVvB,IAAUC,SAEZqB,GAAItB,IAAUuB,OACdX,MAAOZ,IAAUuB,OACjBlP,KAAM2N,IAAUuB,S,GAZdwmB,G,eAekB,CACpB7yB,MAAO,GACPoM,GAAI,aAAF,QAAe,IAAIob,MAAOsL,gBAC5BpnB,WAAOzM,EACP9B,KAAM,S,gkCCjBJ41B,G,kVACI,CACNC,MAAM,I,yBAkBO,WAAM,MACK,EAAKrqB,MAArBsqB,EADW,EACXA,KADW,EACLC,MAEd,OAAOD,EAAK1oB,KAAI,WAAiCjK,GAAQ,IAAtC+K,EAAsC,EAAtCA,KAAMuI,EAAgC,EAAhCA,MAAOyB,EAAyB,EAAzBA,KAAMvL,EAAmB,EAAnBA,QACpC,OAAIuL,EAEA,uBACE/Y,KAAM+Y,GAAQ,IACd/U,IAAKA,EACLgJ,UAAU,UACVQ,QAAS,kBAAM,EAAKqpB,cAAcrpB,KAEjCuB,GAAQ,kBAACU,EAAA,EAAD,MAAUV,EAAV,CAAgB/B,UAAU,kBACnC,8BAAOsK,IAKT,4BACEtT,IAAKA,EACLgJ,UAAU,UACV4C,UAAQ,eACRpC,QAAS,kBAAM,EAAKqpB,cAAcrpB,KAEjCuB,GAAQ,kBAACU,EAAA,EAAD,MAAUV,EAAV,CAAgB/B,UAAU,kBACnC,8BAAOsK,U,uBAOJ,WAAM,IACTsf,EAAU,EAAKvqB,MAAfuqB,MAER,OAAK,EAAK1pB,MAAMwpB,KAKd,yBAAK1pB,UAAS,uBAAkB4pB,GAAS,SACtC,EAAKE,gBALD,Q,0BAUK,SAAAtpB,GACd,EAAKupB,aAEDvpB,GACFA,O,6BAIe,SAAA7N,GACb,EAAKuR,KAAK8lB,SAASr3B,EAAEuB,SAIzB,EAAK61B,gB,+BAGc,WAAM,MACO,EAAK1qB,MAA7B4qB,EADiB,EACjBA,aAAc3f,EADG,EACHA,MAEtB,OAAI2f,GAKF,kBAAC,IAAMjkB,SAAP,KACE,0BAAMhG,UAAU,YAAYsK,GAC5B,0BAAMtK,UAAU,sB,uBAKT,WAAM,IACT0pB,EAAS,EAAKxpB,MAAdwpB,KACJxpB,GAAQ,EAEZ9M,SAASqW,iBAAiB,YAAa,EAAKygB,kBAAkB,GAE1DR,IACFt2B,SAASsW,oBAAoB,YAAa,EAAKwgB,kBAAkB,GACjEhqB,GAAQ,GAGV,EAAKE,SAAS,CACZspB,KAAMxpB,O,mSAID,WACP,OACE,yBACEF,UAAU,UACV4C,UAAQ,eACRsG,IAAK,SAAAhF,GAAI,OAAK,EAAKA,KAAOA,IAE1B,yBAAKlE,UAAU,iBAAiBQ,QAASF,KAAKypB,YAC3CzpB,KAAK6pB,sBAGP7pB,KAAK8pB,mB,gCA5HanmB,a,46BAArBwlB,G,YAKe,CACjBQ,aAAczoB,IAAU0C,KACxBoG,MAAO9I,IAAUuB,OACjB6mB,MAAOpoB,IAAUuf,MAAM,CAAC,OAAQ,SAAU,UAE1C4I,KAAMnoB,IAAU0L,QACd1L,IAAUyB,MAAM,CACdqH,MAAO9I,IAAUuB,OAAOrB,WACxBK,KAAMP,IAAUrK,OAChBqJ,QAASgB,IAAUI,KACnBmK,KAAMvK,IAAUuB,Y,ICjBHsnB,G,2cAUjB,IAAMC,EAAWhqB,KAAKjB,MAAMuQ,UAAY,OAAS,OAEjD,OACE,yBAAK5P,UAAU,aACb,4BACE8C,GAAG,WACHjP,KAAK,SACLmM,UAAU,4CACVuqB,iBAAe,OACfpa,cAAY,UACZqa,iBAAe,SACflgB,MAAM,kBAEN,kBAAC7H,EAAA,EAAD,CAAM/M,KAAM40B,KAEd,4BACExnB,GAAG,mBACHjP,KAAK,SACLmM,UAAU,4CACVuqB,iBAAe,OACfpa,cAAY,UACZqa,iBAAe,SACflgB,MAAM,sBAEN,kBAAC7H,EAAA,EAAD,CAAM/M,KAAK,mB,gCAlCuBuO,aCArC,SAASwmB,GAAoBprB,GAClC,IAAMW,EAAYiC,IAAW5C,EAAMW,UAAW,0BAE9C,OACE,4BACE8C,GAAIzD,EAAMyD,GACVjP,KAAK,SACLmM,UAAWA,EACXuqB,iBAAe,OACfpa,cAAY,UACZqa,iBAAe,SACflgB,MAAOjL,EAAMiL,OAEZjL,EAAM0C,MAAQ,kBAACU,EAAA,EAAD,CAAM/M,KAAM2J,EAAM0C,Q,GDblBsoB,G,YACA,CACjBza,UAAWpO,IAAUG,KAAKD,a,GAFT2oB,G,eAKG,CACpBza,WAAW,ICYf6a,GAAoB5nB,UAAY,CAC9Bd,KAAMP,IAAUuB,OAChBuH,MAAO9I,IAAUuB,OACjB/C,UAAWwB,IAAUuB,OACrBD,GAAItB,IAAUuB,OACdvC,QAASgB,IAAUI,MAEN6oB,U,8nCCyEMC,G,2cAyBjB,IAAIC,EAKAC,EAKJ,OATItqB,KAAKjB,MAAMwrB,wBACbF,EAAsB,kBAAC,GAAD,OAIpBrqB,KAAKjB,MAAMyrB,sBACbF,EAAoB,kBAAC,EAAD,OAIpB,yBAAK9nB,GAAG,WACN,yBAAK9C,UAAU,aACZM,KAAKjB,MAAM8Y,QAAQlX,KAAI,SAACwkB,EAAQ30B,GAC/B,OAAO,kBAAC,GAAD,MAAyB20B,EAAzB,CAAiCzuB,IAAKlG,QAE9C65B,EACAC,S,gCA1C0B3mB,a,GAAhBymB,G,YACA,CACjBvS,QAAS3W,IAAU0L,QACjB1L,IAAUyB,MAAM,CACdH,GAAItB,IAAUuB,OAAOrB,WACrB4I,MAAO9I,IAAUuB,OAAOrB,WACxBK,KAAMP,IAAUwB,UAAU,CACxBxB,IAAUuB,OACVvB,IAAUyB,MAAM,CACdvN,KAAM8L,IAAUuB,OAAOrB,kBAI7BA,WACFopB,oBAAqBtpB,IAAUG,KAAKD,WACpCmpB,sBAAuBrpB,IAAUG,KAAKD,a,GAfrBgpB,G,eAkBG,CACpBvS,QAlHe,CACf,CACErV,GAAI,OACJwH,MAAO,QACPtK,UAAW,kBACX+B,KAAM,OAER,CACEe,GAAI,aACJwH,MAAO,mBACPtK,UAAW,kBACX+B,KAAM,QAER,CACEe,GAAI,UACJwH,MAAO,UACPtK,UAAW,kBACX+B,KAAM,UAER,CACEe,GAAI,WACJwH,MAAO,aACPtK,UAAW,kBACX+B,KAAM,gBAER,CACEe,GAAI,SACJwH,MAAO,SACPtK,UAAW,qBACX+B,KAAM,UAER,CACEe,GAAI,OACJwH,MAAO,OACPtK,UAAW,kBACX+B,KAAM,eAER,CACEe,GAAI,MACJwH,MAAO,MACPtK,UAAW,kBACX+B,KAAM,UAER,CACEe,GAAI,cACJwH,MAAO,eACPtK,UAAW,kBACX+B,KAAM,QAER,CACEe,GAAI,SACJwH,MAAO,qBACPtK,UAAW,kBACX+B,KAAM,gBAER,CACEe,GAAI,QACJwH,MAAO,oBACPtK,UAAW,kBACX+B,KAAM,oBAER,CACEe,GAAI,YACJwH,MAAO,cACPtK,UAAW,kBACX+B,KAAM,sBAER,CACEe,GAAI,gBACJwH,MAAO,iBACPtK,UAAW,kBACX+B,KAAM,YAER,CACEe,GAAI,eACJwH,MAAO,gBACPtK,UAAW,kBACX+B,KAAM,YAER,CACEe,GAAI,gBACJwH,MAAO,iBACPtK,UAAW,qBACX+B,KAAM,SAER,CACEe,GAAI,aACJwH,MAAO,cACPtK,UAAW,qBACX+B,KAAM,UA0BR+oB,qBAAqB,EACrBD,uBAAuB,I,kCCvHrBE,MAAmB,iBAAkBvzB,QAAUwzB,UAAUC,gBAMhD,SAASC,GAA0BC,GAChD,IAAMC,EAAUL,GAAgBM,KAAeC,KACzCC,EAAOR,GAAgB,CAAES,mBAAmB,GAAS,GAE3D,OAAO,SAACnsB,GAAD,OACL,kBAAC,KAAD,CAAa+rB,QAASA,EAASG,KAAMA,GACnC,kBAACJ,EAAmB9rB,K,uzBCdnB,IAAMosB,GAAc,SAACC,GAAD,IAAKC,EAAL,uDAAmB,EAAGC,EAAtB,uDAAiC,IAAjC,OACzB,IAAI/4B,SAAQ,SAACC,EAASC,GACpB24B,IAAKh3B,KAAK5B,GAAS+4B,OAAM,SAACz2B,GACxBQ,YAAW,WACW,IAAhB+1B,EAOJG,MAAMJ,EAAIC,EAAc,EAAGC,GAAUl3B,KAAK5B,EAASC,GALjDA,EAAOqC,KAMRw2B,UAIH9E,GAAU,SAAC1xB,EAAOgL,GAAR,OAAqBA,EAAS,CAAE2rB,UAAWlQ,MA0C5CmQ,GApCQ,SAACC,GAAD,IAAkBlX,EAAlB,uDAA4B,CAAE+R,YAA9B,OAA4C,SAAAznB,GAAS,SAChDuN,mBAAS,CAAEmf,UAAW,OAD0B,GACnE7rB,EADmE,KAC5DE,EAD4D,KAGpE8rB,EAAa,SAAA/f,GAAI,MAAoB,mBAATA,GAGlCwI,qBAAU,YACkC,6CAAG,8HAEJsX,IAFI,gBAExBF,EAFwB,EAEjCI,QACR/rB,EAAS,CAAE2rB,cACPhX,EAAQqX,UAAYF,EAAWnX,EAAQqX,WACzCrX,EAAQqX,SAASL,GALsB,mDAQzCz0B,QAAQlC,MAAM,2CAAd,OAEI2f,EAAQ+R,UAAWoF,EAAWnX,EAAQ+R,SAVD,wBAWvC/R,EAAQ+R,QAAR,KAAuB1mB,GAXgB,2BAexB,EAAD,GAlBcisB,WAAWlS,QAAQ,mBAAqB,IAmBpE7iB,QAAQlC,MAAM,iDACdoC,OAAOykB,SAASC,UAjBuB,yDAAH,qDAsB1CoQ,KACC,IAEH,IAAMroB,EAAY/D,EAAM6rB,UACxB,OAAO9nB,EAAY,kBAACA,EAAc5E,GAAY,OC1DhD,+iD,0CCOA,IAAMktB,EAAW,CACf/4B,aCDa,SAAsB2V,EAAS0R,GAC5C,OAAK1R,GAIAA,EAAQqjB,OAIRrjB,EAAQqjB,MAAMx7B,OAOrB,SAAsBy7B,GACpB,SAASC,EAAQD,GACf,IAAM/5B,EAAI+5B,EAAMz7B,OAEhB,OAAS,GAAL0B,EAAe,OACV,GAALA,EAAe,MAAQ+5B,EAClB,GAAL/5B,EAAe,KAAO+5B,EACjB,GAAL/5B,EAAe,IAAM+5B,EAElBA,EAIT,IADA,IAAIE,EAAS,GACJ77B,EAAI,EAAGA,EAAI27B,EAAMz7B,OAAQF,IAChC,IAAK,IAAIkB,EAAI,EAAGA,EAAIy6B,EAAM37B,GAAGE,OAAQgB,IACnC26B,GAAUD,EAAQD,EAAM37B,GAAG87B,WAAW56B,GAAGq6B,SAAS,KAItD,OAAO3H,SAASiI,EAAQ,IAtBjBE,CAAa1jB,EAAQqjB,OAXnB3R,GDATiS,uBEEa,WAAyD,IAAvBC,GAAuB,uDAAJ,IAAnBA,eACzCC,EAAU,GAGVC,EAAcC,KAAQA,IAAKC,gBAAkBD,IAAKC,iBAiBxD,OAdIJ,GAAkBA,EAAeK,KACA,mBAAxBL,EAAeK,KAExBJ,EAAQK,cAAgBN,EAAeK,KAAKL,GAG5CC,EAAQK,cAAR,gBAAiCC,KAAKP,EAAeK,OAIhDH,IACPD,EAAQK,cAAR,iBAAkCJ,IAG7BD,GFtBPO,cGVa,SAAuBC,EAAUC,GAC9C,IAAKD,IAAaC,EAChB,MAAO,GAGT,IAAMpY,EAAamY,GAAY,CAC7BE,GAAI,KACJlB,MAAO,IAGT,GAAIiB,EAAmB,CACrB,IAAIpY,EAAWqY,IAAMrY,EAAWqY,KAAOD,EAAkBC,GAQvD,OAAOD,EAPP,IAAK,IAAI38B,EAAI,EAAGA,EAAI28B,EAAkBjB,MAAMx7B,OAAQF,IAAK,CACvD,IAAM4F,EAAQ+2B,EAAkBjB,MAAM17B,IACG,IAArCukB,EAAWmX,MAAMrS,QAAQzjB,IAC3B2e,EAAWmX,MAAMl7B,KAAKoF,IAQ9B,OAAO2e,GHZPsY,QIJa,SAAiBxkB,EAAS0R,GACvC,OAAK1R,GAIAA,EAAQqjB,OAIRrjB,EAAQqjB,MAAMx7B,OAIfmY,EAAQqjB,MAAM,GAAGoB,WACZzkB,EAAQqjB,MAAM,GAAGoB,WAGnBzkB,EAAQqjB,MAAM,GAfZ3R,GJGTgT,UKNa,SAAmB1kB,EAAS0R,GACzC,OAAK1R,GAIAA,EAAQqjB,OAIRrjB,EAAQqjB,MAAMx7B,OAIZ0e,WAAWvG,EAAQqjB,MAAM,IAXvB3R,GLKTiT,UMNa,SAAmB3kB,EAAS0R,GACzC,OAAK1R,GAIAA,EAAQqjB,OAIRrjB,EAAQqjB,MAAMx7B,OAKZmY,EAAQqjB,MAAMhgB,KAAK,MAZjBqO,INOI0R,O,uXOTf,IAOewB,EAPK,CAClBC,qBACAC,eCNF,SAAwBtnB,EAASunB,EAAW7mB,EAAGE,EAAGwN,GACE,mBAA9C9jB,OAAOC,UAAUm7B,SAASj7B,KAAK88B,KACjCA,EAAY,CAACA,IAGf,IACMC,EAAOC,IAAiBC,UAAUC,UAClCnO,EAAWiO,IAAiBC,UAAUE,cAE5C5nB,EAAQ6nB,OACR7nB,EAAQwnB,KAAOA,EACfxnB,EAAQ8nB,aAAe,MAGvB,IAAI/K,EAAW,EAEfwK,EAAU/f,SAAQ,SAAA0O,GAEhB,IAAM3b,EAAQyF,EAAQ+nB,YAAY7R,GAAM3b,MAGxCwiB,EAAW7P,KAAKtD,IAAImT,EAAUxiB,MAIhC,IAAMytB,EAAc,CAClBztB,MAAOwiB,EAAWkL,GAClBztB,OAtBc,EAsBI+sB,EAAUl9B,QAAUmvB,EAtBxB,IAuChB,OAdIpL,GAAWA,EAAQ8Z,YAAqC,IAAxB9Z,EAAQ8Z,UAAUxnB,IACpDA,GAAKsnB,EAAYztB,MAAQ,GAGvB6T,GAAWA,EAAQ8Z,YAAqC,IAAxB9Z,EAAQ8Z,UAAUtnB,IACpDA,GAAKonB,EAAYxtB,OAAS,GAG5BwtB,EAAY7mB,KAAOT,EACnBsnB,EAAY9mB,IAAMN,EAElBZ,EAAQmoB,UAGDH,GDrCPI,YCwCF,SAAqB5lB,EAASvB,GAC5B,IAAMonB,EAAiBjB,IAAYkB,kBAAkB9lB,GAC/CtX,EAAS,CACbwV,EAAG,EACHE,EAAG,GAIL,IAAKynB,GAAsC,WAApB,EAAOpnB,GAC5B,OAAO/V,EAGT,IAAMq9B,EAASF,EAAeE,OAExBC,EAAeC,EAAEF,GAAQG,SAC/Bx9B,EAAOwV,GAAK8nB,EAAarnB,KACzBjW,EAAO0V,GAAK4nB,EAAatnB,IAEzB,IAAMynB,EAAiBvB,IAAYwB,cAAcpmB,EAASvB,GAI1D,OAHA/V,EAAOwV,GAAKioB,EAAejoB,EAC3BxV,EAAO0V,GAAK+nB,EAAe/nB,EAEpB1V,GD7DP29B,kBCgEF,SAA2BC,EAAWjrB,EAAiBkrB,GAErD,GAAKlrB,EAAgBmrB,WAArB,CAIA,IAAMxmB,EAAUsmB,EAAUtmB,QACpB6lB,EAAiBjB,IAAYkB,kBAAkB9lB,GAC/CymB,EAAQZ,EAAeY,MAEvBC,EAAiBC,KAAKC,WAAWC,qCACjCC,EAAQ,CACZC,GAAIL,GAAkBA,EAAezhB,SAAS,KAC9C+hB,GAAIN,GAAkBA,EAAezhB,SAAS,KAC9CgiB,GAAIP,GAAkBA,EAAezhB,SAAS,KAC9CiiB,GAAIR,GAAkBA,EAAezhB,SAAS,MA6B1CkiB,EAA0B,SAACC,EAAQC,GACvC,IAAMC,EAAM,GACZA,EAAIppB,EAAIkpB,EAAOlpB,EAAI,EACnBopB,EAAIlpB,EAAIgpB,EAAOhpB,EAAI,EAEnB,IAAMmpB,EAAa,GACnBA,EAAWrpB,EAAImpB,EAAKnpB,EAAIopB,EAAIppB,GAAK,EAAI,EACrCqpB,EAAWnpB,EAAIipB,EAAKjpB,EAAIkpB,EAAIlpB,GAAK,EAAI,EAcrC,IAZA,IAAMopB,EAAQD,EAAWrpB,EAAI,EAAImpB,EAAKnpB,EAAIkpB,EAAOlpB,EAAImpB,EAAKnpB,EAEtDupB,GADUF,EAAWnpB,EAAI,EAAIipB,EAAKjpB,EAAIgpB,EAAOhpB,EAAIipB,EAAKjpB,GACjCopB,EAAQ,IAAM,IAEjC1vB,EAAM,CACV,MAAO,IACP,MAAO,IACP4vB,GAAI,IACJC,GAAI,KAGFvc,EAAU,EACPA,EAAU,IAAM0b,EAAMhvB,EAAI2vB,EAAaF,EAAWE,MAEvDF,EAAWE,KAAgB,EAG3BA,EAA4B,MAAfA,EAAqB,IAAM,IAExCrc,IAGF,MAAO,CACLmc,aACAE,eAIEG,EAAsB,SAACC,EAAMlU,EAAOC,GACxC,IAAMkU,EAAInU,EAAMkU,GACVE,EAAInU,EAAIiU,GACRG,EAAStd,KAAKxD,IAAI4gB,EAAGC,GAE3B,OAAOC,GADStd,KAAKtD,IAAI0gB,EAAGC,GACDC,GAAU,GA2CjCC,EAAU5sB,EAAgB4sB,QAC1BC,EAAUD,EAAQC,QAElBC,EAAUlC,EAAEJ,EAAeE,QAC3BqC,EAAcD,EAAQE,aACtBC,EAAeH,EAAQI,cACvBrC,EAASiC,EAAQjC,SACjBsC,EAAmB,CACvBtqB,EAAGkqB,EACHhqB,EAAGkqB,GAGCG,EAAS,GACfA,EAAOvqB,EAAIgqB,EAAQ1C,YAAYztB,MAC/B0wB,EAAOrqB,EAAI8pB,EAAQ1C,YAAYxtB,OAE/B,IAAM0wB,EAAoB,SAAA76B,GAAO,MACdo6B,EAAQp6B,GAEzB,MAAO,CAAEqQ,EAHsB,EACvBA,EAEIE,EAHmB,EACpBA,IAIPuV,EAAQ+U,EAAkB,SAC1B9U,EAAM8U,EAAkB,OAExBrB,EAAO,GACbA,EAAKnpB,EAAI0pB,EAAoB,IAAKjU,EAAOC,GACzCyT,EAAKjpB,EAAIwpB,EAAoB,IAAKjU,EAAOC,GAEzC,IAAIwT,EAAS,GACbA,EAAOlpB,EAAIuoB,EAAM1uB,MACjBqvB,EAAOhpB,EAAIqoB,EAAMzuB,OAajB,IA5K6D,IA2LzD2wB,EA3LyD,EAiK5BxB,EAAwBC,EAAQC,GAA3DE,EAjKuD,EAiKvDA,WAAYE,EAjK2C,EAiK3CA,WAEZmB,EAjJyB,SAAC/C,EAAgBgD,EAAYC,GAAgB,IAClE9oB,EAA2B6lB,EAA3B7lB,QAAS+lB,EAAkBF,EAAlBE,OAAQU,EAAUZ,EAAVY,MAEnBsC,EAAUnE,IAAYwB,cAAcpmB,EAAS,CACjD9B,EAAG,EACHE,EAAG,IAGC4qB,EAAcpE,IAAYwB,cAAcpmB,EAAS,CACrD9B,EAAGuoB,EAAM1uB,MACTqG,EAAGqoB,EAAMzuB,SAGLmwB,EAAUlC,EAAEF,GACZqC,EAAcD,EAAQE,aACtBC,EAAeH,EAAQI,cAEvB7/B,EAAS,GAMf,OALAA,EAAO,OAASo+B,EAAMI,GAAK6B,EAAQ7qB,EAAI2qB,EACvCngC,EAAO,OAASo+B,EAAMC,GAAKgC,EAAQ3qB,EAAI0qB,EACvCpgC,EAAOg/B,GAAKZ,EAAME,GAAKoB,EAAcY,EAAY9qB,EAAI2qB,EACrDngC,EAAOi/B,GAAKb,EAAMG,GAAKqB,EAAeU,EAAY5qB,EAAI0qB,EAE/CpgC,EA0HcugC,CACrBpD,EACA4C,EAAOvqB,EACPuqB,EAAOrqB,GAEH8qB,EAAiBphC,OAAOqhC,OAAO,GAAI5B,GACrC6B,EAAiB3B,EACjB4B,GAAa,EACbje,EAAU,EACPA,EAAU,GAAG,CAClB,GAAIwd,EAAeQ,EAAiBF,EAAeE,IAAkB,CACnEC,GAAa,EACb,MAIFH,EAAeE,KAAoB,EAGnCA,EAAoC,MAAnBA,EAAyB,IAAM,IAEhDhe,IAIF,GAAIie,EAGFV,GAFApB,EAAaz/B,OAAOqhC,OAAO,GAAI5B,EAAY2B,IAC3CzB,EAAa2B,GACiC,EAAI,EAAIhC,EAAOK,OACxD,CAGL,IACM6B,EAAuBnC,EAH7BC,EAASt/B,OAAOqhC,OAAO,GAAI/B,EAAQoB,GAEN5D,IAAYwB,cAAcpmB,EAASqnB,IAKhEE,EAAa+B,EAAqB/B,WAClCE,EAAa6B,EAAqB7B,WAElC,IAAMhpB,EAAW,CACfP,EAAGqpB,EAAWrpB,EAAI,EAAIgoB,EAAOvnB,KAAOunB,EAAOvnB,KAAOypB,EAClDhqB,EAAGmpB,EAAWnpB,EAAI,EAAI8nB,EAAOxnB,IAAMwnB,EAAOxnB,IAAM4pB,GAQlDK,EALsB/D,IAAY2E,YAChCvpB,EACAvB,EAASP,EACTO,EAASL,GAEwBqpB,GAGrC,IAAM+B,EAA0B,MAAf/B,EAAqB,IAAM,IACtC9vB,EAhIyB,SAACqI,EAASyoB,GACvC,IAAMM,EAAUnE,IAAY2E,YAAYvpB,EAAS,EAAG,GAC9CgpB,EAAcpE,IAAY2E,YAAYvpB,EAASyoB,EAAOvqB,EAAGuqB,EAAOrqB,GACtE,MAAO,CACLF,EAAG8qB,EAAY9qB,EAAI6qB,EAAQ7qB,EAC3BE,EAAG4qB,EAAY5qB,EAAI2qB,EAAQ3qB,GA2HfqrB,CAAuBzpB,EAASyoB,GAEhDP,EAAQT,GAAckB,EACtBT,EAAQsB,GAAYnC,EAAKmC,GAGzB,IAAME,EA7HN,SAA0BnD,EAAQkB,EAAY+B,EAAU7xB,GAEtD,IAAM+tB,GADNa,EAASA,GAAU,IACMb,WAAa,GAChCiE,IAAYjE,EAAUxnB,EACtB0rB,IAAYlE,EAAUtnB,EACtByrB,EAAelyB,EAAQuG,EAAI,EAC3B4rB,EAAenyB,EAAQyG,EAAI,EAC3B8nB,EAAS,CACbhoB,EAAG,GACHE,EAAG,IAGL,GAAmB,MAAfqpB,EAAoB,CACtB,IAAMsC,EAAUH,EAAU,EAAIE,EAE9B5D,EAAOhoB,GAAG,GAAKyrB,EAAUE,EAAe,EACxC3D,EAAOhoB,EAAE,GAAKyrB,GAAWE,GAAgBlyB,EAAQuG,EACjDgoB,EAAO9nB,GAAG,GAAK2rB,EACf7D,EAAO9nB,EAAE,GAAK2rB,MACT,CACL,IAAMC,EAAUL,EAAU,EAAIE,EAE9B3D,EAAOhoB,GAAG,GAAK8rB,EACf9D,EAAOhoB,EAAE,GAAK8rB,EACd9D,EAAO9nB,GAAG,GAAKwrB,EAAUE,EAAe,EACxC5D,EAAO9nB,EAAE,GAAKwrB,GAAWE,GAAgBnyB,EAAQyG,EAGnD,OAAO8nB,EAiGa+D,CAAiB1D,EAAQkB,EAAY+B,EAAU7xB,GACrEuwB,EAAQT,IAAeiC,EAAcjC,GAAYF,EAAWE,IAG5D,IAAMsB,EAAUnE,IAAYwB,cAAcpmB,EAASkoB,GAC7Cc,EAAc,CAClB9qB,EAAG6qB,EAAQ7qB,EAAIuqB,EAAOvqB,EACtBE,EAAG2qB,EAAQ3qB,EAAIqqB,EAAOrqB,GAElB8rB,EAAgB,CACpBC,GAAIjE,EAAOvnB,KACXyrB,GAAIlE,EAAOxnB,IACXgpB,GAAIxB,EAAOvnB,KAAOypB,EAClBT,GAAIzB,EAAOxnB,IAAM4pB,GAEnB,GAAIS,EAAQS,GAAY,EAAG,CACzB,IAAMtrB,EAAIgsB,EAAcC,GAClB/rB,EAAI8rB,EAAcE,GAClBC,EAAgBzF,IAAY2E,YAAYvpB,EAAS9B,EAAGE,GAC1D8pB,EAAQsB,GAAYa,EAAcb,QAC7B,GAAIR,EAAYQ,GAAYhB,EAAiBgB,GAAW,CAC7D,IAAMtrB,EAAIgsB,EAAcxC,GAAKe,EAAOvqB,EAC9BE,EAAI8rB,EAAcvC,GAAKc,EAAOrqB,EAC9BisB,EAAgBzF,IAAY2E,YAAYvpB,EAAS9B,EAAGE,GAC1D8pB,EAAQsB,GAAYa,EAAcb,O,oDChUtCc,IAASC,WAAWC,OAAS,SAASj9B,EAAOqe,EAAS/d,EAAK48B,GACzD,GAAI7e,GAAWre,IAAUqe,EAAQre,MAC/B,OAAOM,EAAM,cAAgB+d,EAAQre,OAIzC+8B,IAASC,WAAWG,aAAe,SAASn9B,EAAOqe,EAAS/d,GAC1D,GAAI+d,GAAWre,IAAUqe,EAAQre,MAC/B,OAAOM,EAAM,gBAAkB+d,EAAQre,OAI3C+8B,IAASC,WAAW1J,SAAW,SAAStzB,EAAOqe,EAAS/d,GACtD,GAAI+d,GAAWre,EAAMyjB,UAA6C,IAAlCzjB,EAAMyjB,QAAQpF,EAAQre,OACpD,OAAOM,EAAM,gBAAkB+d,EAAQre,OAI3C+8B,IAASC,WAAWI,eAAiB,SAASp9B,EAAOqe,EAAS/d,GAC5D,GAAI+d,GAAWre,EAAMyjB,UAA6C,IAAlCzjB,EAAMyjB,QAAQpF,EAAQre,OACpD,OAAOM,EAAM,kBAAoB+d,EAAQre,OAI7C+8B,IAASC,WAAWK,WAAa,SAASr9B,EAAOqe,EAAS/d,GACxD,GAAI+d,GAAWre,EAAMq9B,aAAer9B,EAAMq9B,WAAWhf,EAAQre,OAC3D,OAAOM,EAAM,mBAAqB+d,EAAQre,OAI9C+8B,IAASC,WAAWM,SAAW,SAASt9B,EAAOqe,EAAS/d,GACtD,GAAI+d,GAAWre,EAAMs9B,WAAat9B,EAAMs9B,SAASjf,EAAQre,OACvD,OAAOM,EAAM,iBAAmB+d,EAAQre,OCtB5C,IAAMu9B,EAAoC,G,4HCJlCC,EAAqBC,IAArBD,iBAsGFE,EA9FQ,SAACC,EAAkBC,GAE/B,KAAMD,aAA4BH,GAChC,MAAM,IAAIK,IACR,6EAIJ,IAAMxf,EAAU,CACdyf,OAAQ,WAGJC,EAAU,CACdC,OAAQ,GACRC,OAAQ,IAGNC,GAAiB,EACjBC,EAAQ,EAqEZ,OAnEAP,EAAMnmB,SAAQ,SAAA2mB,GACZ,IAAMC,EAAYD,EAAKC,UAGvB,GAAId,EAAkC9iC,eAAe4jC,GAAY,CAC/D,IAAMC,EAAkBf,EAAkCc,GAC1DV,EAAiBY,mBACfF,EACAC,EAAgBvuB,SAAS4tB,IAK7B,IAcIa,EAdEC,EAAiB,EAAH,GACjBJ,EAAYD,EAAKM,YAQdC,EAAe,EAAH,GACfN,EAJoBV,EAAiBiB,sBAAsBP,GAC1DV,EAAiBkB,mBAAmBR,GACpCV,EAAiBmB,YAAYT,IAOjC,IACEG,EAAgBzB,IAAS4B,EAAcF,EAAgB,CAACpgB,IACxD,MAAOpiB,GACPuiC,EAAgB,CAAC,0CAA2CviC,GAGzDuiC,GAeCJ,EAAK9W,WACP4W,GAAiB,GAKnBH,EAAQE,OAAOrjC,KAAK,CAClBwjC,OACAI,oBAnBFL,GAASnQ,SAASoQ,EAAKW,OAAQ,IAG/BhB,EAAQC,OAAOpjC,KAAK,CAClBwjC,aAqBFF,IACFC,EAAQ,GAGH,CACLA,QACAJ,UACAG,mB,gBCxGEc,EAAyB,GCF/B,IAAMC,EAAc,CAClB,CACE7yB,GAAI,SACJpN,KAAM,aACNkgC,UAAW,SACXC,gBAAiB,QACjB/Z,YAAa,wCAEf,CACEhZ,GAAI,eACJpN,KAAM,sBACNkgC,UAAW,eACXC,gBAAiB,QACjB/Z,YAAa,4CAEf,CACEhZ,GAAI,WACJpN,KAAM,WACNkgC,UAAW,WACXC,gBAAiB,QACjB/Z,YAAa,0CAEf,CACEhZ,GAAI,iBACJpN,KAAM,mBACNkgC,UAAW,iBACXC,gBAAiB,QACjB/Z,YAAa,8CAEf,CACEhZ,GAAI,aACJpN,KAAM,cACNkgC,UAAW,aACXC,gBAAiB,QACjB/Z,YAAa,6CAEf,CACEhZ,GAAI,WACJpN,KAAM,YACNkgC,UAAW,WACXC,gBAAiB,QACjB/Z,YAAa,2CAEf,CACEhZ,GAAI,cACJpN,KAAM,gBACNkgC,UAAW,eACXC,gBAAiB,cACjB/Z,YAAa,kCAEf,CACEhZ,GAAI,cACJpN,KAAM,mBACNkgC,UAAW,eACXC,gBAAiB,cACjB/Z,YAAa,oDAEf,CACEhZ,GAAI,uBACJpN,KAAM,gCACNkgC,UAAW,eACXC,gBAAiB,uBACjB/Z,YAAa,gDAEf,CACEhZ,GAAI,oBACJpN,KAAM,6BACNkgC,UAAW,eACXC,gBAAiB,oBACjB/Z,YAAa,gDAEf,CACEhZ,GAAI,WACJpN,KAAM,gBACNkgC,UAAW,eACXC,gBAAiB,WACjB/Z,YAAa,iDAEf,CACEhZ,GAAI,MACJpN,KAAM,MACNkgC,UAAW,eACXC,gBAAiB,MACjB/Z,YAAa,gCAEf,CACEhZ,GAAI,OACJpN,KAAM,OACNkgC,UAAW,eACXC,gBAAiB,OACjB/Z,YAAa,kCAKjB7qB,OAAO6kC,OAAOH,G,kLC5Fd,IAAMI,EAAgB,WAmBDC,E,WAOnB,WAAYjB,EAAWK,EAAYpX,EAAUyX,I,4FAAQ,SAEnDn1B,KAAKwC,GAAKmzB,cAGV31B,KAAKm1B,OAASA,GAAU,EAGpBV,IACFz0B,KAAKy0B,UAAYA,GAIfK,IACF90B,KAAK80B,WAAaA,GAMlB90B,KAAK0d,cAFUroB,IAAbqoB,GAIcA,EAIlB1d,KAAK41B,qBAAkB,EAGvB51B,KAAK61B,wBAAqB,E,0DASjB1J,GAGTnsB,KAAKwC,GAAK2pB,EAAM3pB,IAAMmzB,cAGtB31B,KAAK0d,SAAWyO,EAAMzO,SACtB1d,KAAKm1B,OAAShJ,EAAMgJ,OACpBn1B,KAAKy0B,UAAYtI,EAAMsI,UACvBz0B,KAAK80B,WAAa3I,EAAM2I,a,0CASxB,IAAIgB,EAAiB91B,KAAK41B,gBAE1B,QAAuB,IAAnBE,EACF,OAAOA,EAGT,IAAMC,EAAiBplC,OAAO4c,KAAKvN,KAAK80B,YAAY,GAWpD,YATuB,IAAnBiB,IACFD,EAAiBT,EAAYpf,MAC3B,SAAA+f,GAAU,OAAID,IAAmBC,EAAWxzB,OAKhDxC,KAAK41B,gBAAkBE,EAEhBA,I,uCASP,MAA0B,uBAAnB91B,KAAKy0B,Y,oDAQZ,IAAKz0B,KAAKi2B,iBACR,OAAQ,EAIV,IAAMC,EAAwBl2B,KAAKm2B,iCAC3B//B,EAAqB8/B,EAArB9/B,MAAOk/B,EAAcY,EAAdZ,UACTc,EAAWhS,SAAShuB,EAAO,KAAO,EAGxC,OAAIq/B,EAAcY,KAAKf,GAEdc,EAAW,EAAI,EAAIA,EAIrB,I,uDAQP,IAAIE,EAAoBt2B,KAAK61B,mBAG7B,QAA0B,IAAtBS,EACF,OAAOA,EAIT,IAAMR,EAAiB91B,KAAKu2B,oBAG5B,QAAuB,IAAnBT,EAA2B,CAC7B,IAAMR,EAAYQ,EAAeR,UAC3BkB,EAAmBx2B,KAAK80B,WAAWQ,GAErCkB,IAIFF,EAAoB,CAClBlgC,MAHsBogC,EADIV,EAAeP,iBAKzCD,UAAWQ,EAAetzB,IAG5BxC,KAAK61B,mBAAqBS,GAI9B,OAAOA,O,u+BCnKLG,E,8FAA6Bf,GAQ7BgB,E,8FAA0BhB,GAQ1BiB,E,8FAA2BjB,GAQ3BkB,E,8FAA0BlB,GCxB1BmB,EAAkB,SAAC1rB,EAAOghB,GAE9B,SAAKhhB,IAAUA,EAAMza,UAIrBya,EAAM0C,SAAQ,SAACzX,EAAOgP,GAGpB,GAAIhP,IAAU+1B,EAEZ,OADA2K,cAAgB1xB,GACT,UAIW,IAAlB0xB,gBAIJ3rB,EAAMvZ,OAAOklC,cAAe,IACrB,K,0KCrBYC,E,WACnB,WAAYxjC,EAAMyjC,I,4FAAY,SAC5Bh3B,KAAKzM,KAAOA,EACZyM,KAAKg3B,WAAaA,E,0DAST7K,GACTnsB,KAAKzM,KAAO44B,EAAM54B,KAClByM,KAAKg3B,WAAa7K,EAAM6K,a,8CAUxB,OAAQh3B,KAAKzM,MACX,IAAK,OACH,MAAO,gB,wCAYX,OAAQyM,KAAKzM,MACX,IAAK,OAGH,OAAOyM,KAAKg3B,WAAW13B,KAAOU,KAAKg3B,WAAWx3B,c,0MCnCjCy3B,E,WACnB,c,4FAAc,SACZj3B,KAAKk3B,iBAAmB,GACxBl3B,KAAKm3B,mBAAqB,GAC1Bn3B,KAAKo3B,oBAAsB,GAC3Bp3B,KAAKq3B,mBAAqB,G,0DASjBlL,GAAO,WAGZA,EAAMgL,oBACRhL,EAAMgL,mBAAmBtpB,SAAQ,SAAAypB,GAC/B,IAAI9C,EAAO,IAAIoC,EACfpC,EAAK+C,WAAWD,GAChB,EAAKH,mBAAmBnmC,KAAKwjC,MAM7BrI,EAAMiL,qBACRjL,EAAMiL,oBAAoBvpB,SAAQ,SAAAypB,GAChC,IAAI9C,EAAO,IAAImC,EACfnC,EAAK+C,WAAWD,GAChB,EAAKF,oBAAoBpmC,KAAKwjC,MAM9BrI,EAAMkL,oBACRlL,EAAMkL,mBAAmBxpB,SAAQ,SAAAypB,GAC/B,IAAI9C,EAAO,IAAIkC,EACflC,EAAK+C,WAAWD,GAChB,EAAKD,mBAAmBrmC,KAAKwjC,MAK7BrI,EAAM+K,mBACRl3B,KAAKk3B,iBAAmB/K,EAAM+K,oB,iCAWvB1C,GACT,IAAIrpB,EACAqpB,aAAgBkC,EAClBvrB,EAAQnL,KAAKq3B,mBACJ7C,aAAgBmC,EACzBxrB,EAAQnL,KAAKo3B,oBACJ5C,aAAgBoC,IACzBzrB,EAAQnL,KAAKm3B,oBAGfN,EAAgB1rB,EAAOqpB,Q,0MCvENgD,E,WACnB,WAAYT,EAAmB3hC,I,4FAAM,SAEnC4K,KAAKwC,GAAKmzB,cAGV31B,KAAK5K,KAAOA,EACZ4K,KAAKy3B,kBAAoBV,EAGzB/2B,KAAK03B,UAAY,GAGjB13B,KAAK23B,YAAc,IAAI/Z,K,2DASbxoB,GAEV,IAAIwiC,EAAejnC,OAAOqhC,OAAO,GAAIhyB,MAGjC63B,EAAc,IAAIL,EAYtB,OATAI,EAAap1B,GAAKq1B,EAAYr1B,GAC9Bq1B,EAAYN,WAAWK,GAGnBxiC,IACFyiC,EAAYziC,KAAOA,GAIdyiC,I,iCASE1L,GAAO,WAGhBnsB,KAAKwC,GAAK2pB,EAAM3pB,IAAMmzB,cAGtB31B,KAAK5K,KAAO+2B,EAAM/2B,KAIlB4K,KAAKy3B,kBAAoB,IAAIV,EAC7B/2B,KAAKy3B,kBAAkBF,WAAWpL,EAAMsL,mBAGpCtL,EAAMuL,WACRvL,EAAMuL,UAAU7pB,SAAQ,SAAAiqB,GAEtB,IAAIC,EAAW,IAAId,EACnBc,EAASR,WAAWO,GAGpB,EAAKJ,UAAU1mC,KAAK+mC,W,oNCrEPC,G,WAOnB,WAAY5iC,I,4FAAM,SAEhB4K,KAAKwC,GAAKmzB,cAMV31B,KAAKi4B,QAAS,EAIdj4B,KAAKk4B,6BAA8B,EAGnCl4B,KAAK5K,KAAOA,EAGZ4K,KAAK23B,YAAc,IAAI/Z,KACvB5d,KAAKm4B,aAAe,IAAIva,KAIpBgP,KAAKwL,cAAgBxL,KAAKwL,iBAC5Bp4B,KAAKq4B,UAAYzL,KAAK0L,YACtBt4B,KAAKu4B,WAAa3L,KAAK0L,aAKzBt4B,KAAKw4B,YAAc,IAAIC,IACvBz4B,KAAK04B,WAAa,IAAID,IAItBz4B,KAAK24B,sBAAwB,GAC7B34B,KAAK44B,OAAS,GAGd54B,KAAK64B,0BAA4B,E,6EAGY,IAAnBC,EAAmB,wDACzCD,GACY,IAAdC,EAAqB94B,KAAK64B,0BAA4B,EAGxD,OAAIA,GAA4B,EACvBA,GAGTA,EAA2B,EAK3B74B,KAAK44B,OAAO/qB,SAAQ,SAAAkrB,GACbA,EAAMrB,WAIXqB,EAAMrB,UAAU7pB,SAAQ,SAAAkqB,GACjBA,EAASV,oBAIdU,EAASV,mBAAmBxpB,SAAQ,SAAA2mB,GAElC,IAAMwE,EAAmBxE,EAAKyE,8BAC1BD,EAAmBH,IACrBA,EAA2BG,YAMnCh5B,KAAK64B,yBAA2BA,EAEzBA,K,uDAIP74B,KAAKi5B,6BAA4B,K,4CAU7BrM,KAAKwL,cAAgBxL,KAAKwL,iBAC5Bp4B,KAAKu4B,WAAa3L,KAAK0L,aAKzBt4B,KAAKk4B,6BAA8B,EAGnCl4B,KAAKk5B,iCAGLl5B,KAAKm4B,aAAe,IAAIva,O,iCAUfuO,GAAO,WAGhBnsB,KAAKwC,GAAK2pB,EAAM3pB,IAAMmzB,cAGtB31B,KAAK5K,KAAO+2B,EAAM/2B,KAIlB4K,KAAKi4B,SAAW9L,EAAM8L,OAOlB9L,EAAMwM,uBACRxM,EAAMwM,sBAAsB9qB,SAAQ,SAAAypB,GAElC,IAAI9C,EAAO,IAAIiC,EACfjC,EAAK+C,WAAWD,GAGhB,EAAKqB,sBAAsB3nC,KAAKwjC,MAMhCrI,EAAMyM,QACRzM,EAAMyM,OAAO/qB,SAAQ,SAAAsrB,GAEnB,IAAIJ,EAAQ,IAAIvB,EAChBuB,EAAMxB,WAAW4B,GAGjB,EAAKP,OAAO5nC,KAAK+nC,Q,kCAWX3jC,GAEV,IAAIgkC,EAAkBzoC,OAAOqhC,OAAO,GAAIhyB,MAGpCq5B,EAAiB,IAAIrB,EAezB,OAZAoB,EAAgB52B,GAAK62B,EAAe72B,GACpC62B,EAAe9B,WAAW6B,GAGtBhkC,IACFikC,EAAejkC,KAAOA,GAIxBikC,EAAepB,QAAS,EAGjBoB,I,+BAQAN,GACP/4B,KAAK44B,OAAO5nC,KAAK+nC,GAIjB/4B,KAAKs5B,wB,8CAQiB9E,GACtBx0B,KAAK24B,sBAAsB3nC,KAAKwjC,GAIhCx0B,KAAKs5B,wB,iDAQoB9E,GACRqC,EAAgB72B,KAAK24B,sBAAuBnE,IAK3Dx0B,KAAKs5B,2B,qiBCjOHC,GAAoC1F,IAApC0F,cAAe3F,GAAqBC,IAArBD,iBAKF4F,G,WAYnB,WACEC,EACAvY,EACAwY,EACAC,GAEA,IADAllB,EACA,uDADU,GAIV,G,4FAHA,oCAjBiB,IAAImlB,KAiBrB,gCAhBsB,MAmBhBD,aAA+BE,KACnC,MAAM,IAAI5F,IACR,6FAIJ,KACI/S,aAAmB3b,OACpB2b,EAAQ4Y,OAAM,SAAA5jB,GAAK,OAAIA,aAAiBqjB,OAEzC,MAAM,IAAItF,IACR,wGAMJj0B,KAAKy5B,cAAgBA,EACrBz5B,KAAKkhB,QAAUA,EACflhB,KAAK05B,aAAeA,aAAwBE,IAAMF,EAAe,IAAIE,IACrE55B,KAAK25B,oBAAsBA,EAC3B35B,KAAKyU,QAAUA,EAGfzU,KAAK+5B,QAIL/5B,KAAKg6B,YAAc,G,uDAOnB,IAAMC,EAAWj6B,KAAKk6B,uBAEtBl6B,KAAKm6B,mBAAmBF,K,6CASxB,OAAOj6B,KAAKi6B,SAASrB,OAAO54B,KAAK+4B,S,uCAWlB7iB,GACf7e,IAAIG,MAAM,oCAEV,IAAM4iC,EAAU,GACVC,EAAgBnkB,EAAMokB,mBAGtBC,EAA0Bv6B,KAAKw6B,2BACnCtkB,EAAMukB,eAgCR,OA7BAz6B,KAAKy5B,cAAciB,cAAc7sB,SAAQ,SAAAosB,GAIvC,IAAIjG,EAAQiG,EAAStB,sBAAsBvhC,QAC3C,GAAK48B,KAK4BiG,EAAShB,8BACXsB,GAA/B,CAKA,IACMhG,EADiBT,EAAgBuG,EAAerG,GACzBO,MAGzBA,EAAQ,GACV6F,EAAQppC,KAAK,CACXujC,QACA0F,iBAMDG,EAAQ1pC,QAYD0pC,ECpJVjZ,MAAK,SAACwP,EAAGC,GACX,OAAOA,EAAE2D,MAAQ5D,EAAE4D,SDqJnBl9B,IAAIG,MAAM,2CAA4C4iC,GAE/CA,GAbE,CACL,CACE7F,MAAO,EACP0F,SALoBj6B,KAAKy5B,cAAciB,YAAY,uB,+CAmBzD16B,KAAK26B,iBAAiBC,QACtB56B,KAAK66B,sBAAwB,K,8CAKP,WACtBxjC,IAAIG,MAAM,yCAGVwI,KAAK86B,yBAGL96B,KAAKkhB,QAAQrT,SAAQ,SAAAqI,GACH,EAAK6kB,iBAAiB7kB,GAG9BrI,SAAQ,SAAAmtB,GACd,IAAMf,EAAWe,EAAcf,SAC1BA,IAKA,EAAKU,iBAAiBM,IAAIhB,EAASz3B,MACtCnL,IAAIG,MACF,iEACAwjC,GAEF,EAAKL,iBAAiBO,IAAIjB,EAASz3B,GAAIy3B,GACvC,EAAKY,sBAAsBZ,EAASz3B,IAAMw4B,EAAczG,gB,yCAM7C4G,GACjB,OAAOxqC,OAAO4c,KAAK4tB,GAAKjZ,QAAO,SAACyO,EAAGC,GAAJ,OAAWuK,EAAIxK,GAAKwK,EAAIvK,GAAKD,EAAIC,O,mDAIhE,IAAKjgC,OAAO4c,KAAKvN,KAAK66B,uBAAuBnqC,OAC3C,OAAOsP,KAAKy5B,cAAciB,YAAY,mBAExC,IAAMU,EAA2Bp7B,KAAKq7B,mBACpCr7B,KAAK66B,uBAEP,OAAO76B,KAAK26B,iBAAiB3kC,IAAIolC,K,6CASjCp7B,KAAKs7B,wBAGL,IAAMC,EAAYv7B,KAAKw7B,6BAIvB,OAFAnkC,IAAIG,MAAM,iDAAkD+jC,GAErDA,I,iDASkBE,GACzB,OAAOz7B,KAAK07B,wBAAwBD,GAAe/qC,S,8CAS7B+qC,GACtB,IAAME,EAAS37B,KAAK05B,aAAa1jC,IAAIylC,GAErC,OAAOE,aAAkBp2B,MAAQo2B,EAAS,K,kCAIhC5D,EAAU6D,GAAe,WACnCvkC,IAAIG,MAAM,+BADyB,IAuB/BkiC,EAnBFrC,EAGEU,EAHFV,mBACAD,EAEEW,EAFFX,oBACoByE,EAClB9D,EADFZ,mBAGI2E,EAAiB,GACjBC,EAAe/7B,KAAKkhB,QAAQ,GAC5B8a,EAAgBD,EAAazB,mBAE/B2B,EAA4B,EAC5BC,EAA6B,EAGjCH,EAAapH,mBAtPY,qBAsP6B,GAClDqH,aAAyBpI,IAC3BoI,EAAcrH,mBAxPS,qBAwPgC,GAMzD0C,EAAmBxpB,SAAQ,SAAA2mB,GACzB,GA/PuB,uBA+PnBA,EAAKC,UAAoC,CAC3C,IAiBI0H,EAjBEC,EAAgBzrC,OAAO4c,KAAKinB,EAAKM,YAAY,GAC7CQ,EAAY3kC,OAAO4c,KAAKinB,EAAKM,WAAWsH,IAAgB,GAE1DC,EAAqB7H,EAAKM,WAAWsH,GAAe9G,GAexD,GAdA+G,EAAqBjY,SAASiY,EAAoB,IAI7C3C,IACHA,EAAe,EAAKgC,wBAClBK,EAAatB,iBAQW,IAAxB4B,EACFF,EAAazC,EAAaA,EAAahpC,OAAS,OAC3C,CACL,IAAM4rC,EAAa/oB,KAAKtD,IAAIosB,EAAqB,EAAG,GACpDF,EAAazC,EAAa4C,GAI5B,IAAKH,aAAsB5C,GACzB,OAGF,IAAMgD,EAAqBJ,EAAW1B,cAGtC,GACE,EAAKvZ,QAAQjL,MAAK,SAAAC,GAAK,OAAIA,EAAMukB,gBAAkB8B,KAEnD,OAIF,EAAK5C,oBAAoB6C,UAAUL,GAAY/nC,MAC7C,SAAAqoC,GAEEA,EAAc9H,mBA3SG,qBA6Sf0H,GAIF,IAAML,EAAgBS,EAAcnC,mBAChC0B,aAAyBpI,IAC3BoI,EAAcrH,mBAnTC,qBAqTb0H,GAKJ,EAAKnb,QAAQlwB,KAAKyrC,GAGlB,EAAKC,gBAAgBd,MAEvB,SAAA9mC,GAEE,MADAuC,IAAIC,KAAKxC,GACH,IAAIm/B,IAAJ,8GACmGsI,WAQjHv8B,KAAKkhB,QAAQrT,SAAQ,SAAAqI,GACnB,IAAMymB,EAAoB7I,EACxB5d,EAAMokB,mBACNjD,IAKqC,IAArCsF,EAAkBrI,gBAClBqI,EAAkBpI,MAAQ0H,IAK5BA,EAA4BU,EAAkBpI,MAE9Cre,EAAM0mB,eAAc,SAAAC,GAClB,IAAMC,EAAqBhJ,EACzB+I,EAAOvC,mBACPlD,IAKsC,IAAtC0F,EAAmBxI,gBACnBwI,EAAmBvI,MAAQ2H,IAK7BA,EAA6BY,EAAmBvI,MAEhDsI,EAAOE,iBAAgB,SAACC,EAAU53B,GAIhC,GACG63B,YAAQD,EAAS9H,YAAY,iBAC7B8H,EAAS9H,YAAY,QAFxB,CAOA,IAAMgI,EAAuBpJ,EAC3BkJ,EACAnB,GAIF,IAA4C,IAAxCqB,EAAqB5I,eAAzB,CAIA,IAAM6I,EAAe,CACnB/I,OAAQ,GACRC,OAAQ,IAGV8I,EAAa/I,OAAS+I,EAAa/I,OAAOgJ,OACxCF,EAAqB/I,QAAQC,QAE/B+I,EAAa/I,OAAS+I,EAAa/I,OAAOgJ,OACxCN,EAAmB3I,QAAQC,QAE7B+I,EAAa/I,OAAS+I,EAAa/I,OAAOgJ,OACxCT,EAAkBxI,QAAQC,QAG5B+I,EAAa9I,OAAS8I,EAAa9I,OAAO+I,OACxCF,EAAqB/I,QAAQE,QAE/B8I,EAAa9I,OAAS8I,EAAa9I,OAAO+I,OACxCN,EAAmB3I,QAAQE,QAE7B8I,EAAa9I,OAAS8I,EAAa9I,OAAO+I,OACxCT,EAAkBxI,QAAQE,QAG5B,IAAMgJ,EACJH,EAAqB3I,MACrBuI,EAAmBvI,MACnBoI,EAAkBpI,MACd+I,EAAwBN,EAASO,oBAEjCC,EAAe,CACnBloB,iBAAkBY,EAAMunB,sBACxBC,kBAAmBb,EAAOc,uBAC1BC,eAAgBN,EAChBO,oBAAqBz4B,EACrB04B,cAAeT,EACfF,aAAcA,EACdY,YAAa,CACXxJ,MAAO8I,EACPnnB,MACE8mB,EAAS9H,YAAY,aACrB8H,EAAS9H,YAAY,aACvB2H,OAAQzY,SAAS4Y,EAAS9H,YAAY,iBACtC8H,SAAU5Y,SAAS4Y,EAAS9H,YAAY,qBAKtC8I,EAAa9nB,EAAM+nB,gBAAe,SAAAD,GAAU,OAChDA,EAAWE,OAAOjoB,MAChB,SAAAqZ,GAAK,OAAIA,EAAMiO,sBAAwBD,QAKvCU,IACFR,EAAa3nB,sBAAwBmoB,EAAWG,SAChDX,EAAaY,QAAUpB,EAASqB,cAGlCvC,EAAe9qC,KAAKwsC,gBAM1B,IAAMc,EAAkBC,YACtB,CACEnpC,KAAM,QACNopC,SAAS,GAEX,CACEppC,KAAM,QACNopC,SAAS,GAEX,CACEppC,KAAM,YAER,CACEA,KAAM,WAGV0mC,EAAe3a,MAAK,SAACwP,EAAGC,GAAJ,OAClB0N,EAAgB3N,EAAEoN,YAAanN,EAAEmN,gBAGnC,IAAMxC,EAAYO,EAAe,GAIjC,OAFAzkC,IAAIG,MAAM,wCAAyC+jC,GAE5C,CACLA,YACAO,oB,gCAUM2C,EAASC,GACjB,GAAID,EAAU,GAAKC,EAAa,EAC9BrnC,IAAIvC,MAAJ,yBAA4B2pC,EAA5B,cAAyCC,SAI3C,GAAsC,mBAA3B1+B,KAAKyU,QAAQkqB,UAAxB,CAQA,IAHA,IAAIjH,EAAY,GACVkH,EAAeH,EAAUC,EAEtBluC,EAAI,EAAGA,EAAIouC,EAAcpuC,IAChCknC,EAAU1mC,KAAK,IAGjBgP,KAAKyU,QAAQkqB,UAAU,CAAEF,UAASC,aAAYhH,mBAX5CrgC,IAAIvC,MAAM,+D,sCAuBE8mC,GAAe,WAM7B,GALAvkC,IAAIG,MAAJ,yDACoDokC,IAI/C57B,KAAK6+B,uBAAV,CAKA,IAAMC,EAAa9+B,KAAK++B,uBAIxB,GACGD,GACAA,EAAWrH,mBACXqH,EAAWpH,WACXoH,EAAWpH,UAAUhnC,QAOGouC,EAAWrH,kBAAkBuH,wBACxD,CAMA,IAAMC,EAAcH,EAAWrH,kBAAkBT,WACjD,GAAKiI,EAAL,CAKA,IAAMC,EAAe,GAKrBl/B,KAAKm9B,aAAe,GAGpB2B,EAAWpH,UAAU7pB,SAAQ,SAACkqB,EAAU6D,GACtC,IAAMzH,EAAU,EAAKgL,YAAYpH,EAAU6D,GAE3C,EAAKuB,aAAavB,GAAiBzH,EAGnC,IAAMiL,EAA4B,GAG5BC,EAAuB1uC,OAAO4c,KAAKwqB,EAASb,kBAElDmI,EAAqBxxB,SAAQ,SAAAnX,GAC3B,IAAIN,EAAQ2hC,EAASb,iBAAiBxgC,GACxB,QAAVN,EACFA,GAAQ,EACW,OAAVA,IACTA,GAAQ,GAGVgpC,EAA0B1oC,GAAON,KAKnC,IAAMkpC,E,kVAAsB,CAAH,CACvB1D,gBACA7D,SAAUqH,GACPH,GAGCM,EAAiB,GACvBF,EAAqBxxB,SAAQ,SAAArL,GACX4yB,EAAuB5yB,IAKvC+8B,EAAevuC,KAAK,CAClBwR,GAAIA,EACJpM,MAAO2hC,EAASb,iBAAiB10B,QAIrC88B,EAAoBE,iBAAmB,SAAA32B,GAErC02B,EAAe1xB,SAAQ,SAAA4xB,GACrBpoC,IAAIG,MAAJ,wFACmFioC,EAAcj9B,KAEjGnL,IAAIG,MAAJ,2EACsEioC,EAAcrpC,QAGpEg/B,EAAuBqK,EAAcj9B,IAC7C2D,SAAS0C,EAAS42B,EAAcrpC,WAO5C,IAHA,IAAIspC,EAAevL,EAAQoH,UACvBoE,EAAkB,EAChBC,EAAezL,EAAQ2H,eAAeprC,OAE1CivC,EAAkBC,GAClBV,EAAajpB,MAAK,SAAA0a,GAAC,OAAIA,EAAEyN,UAAYsB,EAAatB,YAElDsB,EAAevL,EAAQ2H,eAAe6D,GACtCA,IAGED,GAAgBA,EAAatB,UAC/BkB,EAAoBhqB,iBAAmBoqB,EAAapqB,iBACpDgqB,EAAoB5B,kBAAoBgC,EAAahC,kBACrD4B,EAAoB1B,eAAiB8B,EAAa9B,eAClD0B,EAAoBzB,oBAClB6B,EAAa7B,oBACfyB,EAAoBzpB,sBAClB6pB,EAAa7pB,sBACfypB,EAAoBlB,QAAUsB,EAAatB,SAQ7Cc,EAAaluC,KAAKsuC,MAGpBt/B,KAAK2+B,UAAUM,EAAY3/B,KAAM2/B,EAAYz/B,SAEO,mBAAzCQ,KAAKyU,QAAQorB,6BAQFxqC,IAAlBumC,GAA+BsD,EAAatD,GAC9C57B,KAAKyU,QAAQorB,wBACXjE,EACAsD,EAAatD,IAMjBsD,EAAarxB,SAAQ,SAAAiyB,GACnB,EAAKrrB,QAAQorB,wBACXC,EAAqBlE,cACrBkE,MAnBFzoC,IAAIvC,MACF,gF,yCA8BairC,GAAqC,IAAxBrD,IAAwB,yDACtDrlC,IAAIG,MAAM,iDAAkDuoC,GAC5D1oC,IAAIG,MAAJ,+DAC0DklC,IAI1D18B,KAAKg6B,YAAc,GAEfhC,GAASpnC,UAAUovC,cAAcD,GACnC//B,KAAKi6B,SAAW8F,GAEhB//B,KAAKi6B,SAAW,IAAIjC,GACpBh4B,KAAKi6B,SAAS1C,WAAWwI,IAG3B//B,KAAK+4B,MAAQ,EAGT2D,GACF18B,KAAK08B,oB,6CASP,IAAMuD,EAAiBjgC,KAAK6+B,uBAE5B,OAAO7+B,KAAK+4B,MAAQ,EAAIkH,I,iDAQxB,OAAOjgC,KAAK+4B,MAAQ,GAAK,I,8CAUHmH,GAEtB,SAAqB,IAAjBA,IAAuBlgC,KAAKmgC,4BAEL,IAAhBD,IAAsBlgC,KAAKogC,yBAKtCpgC,KAAK+4B,OAASmH,EAGd7oC,IAAIG,MAAJ,0DAA6DwI,KAAK+4B,QAIlE/4B,KAAK08B,kBAGE,M,6CAQP,GACG18B,KAAKi6B,UACLj6B,KAAKi6B,SAASrB,QACd54B,KAAKi6B,SAASrB,OAAOloC,OAKxB,OAAOsP,KAAKi6B,SAASrB,OAAOloC,S,0CAO5B2G,IAAIG,MAAM,qCAELwI,KAAKqgC,wBAAwB,IAChChpC,IAAIG,MAAM,8C,8CAQZH,IAAIG,MAAM,yCAELwI,KAAKqgC,yBAAyB,IACjChpC,IAAIG,MAAM,qD,6MElyBK8oC,G,WACnB,WAAYC,I,4FAAU,SACpBvgC,KAAKugC,SAAWA,E,kEAQSC,GACzB,IAAIjvC,EAASivC,EAGb,GAAIjvC,aAAkBgU,MACpBhU,EAAOsc,SAAQ,SAACosB,EAAU70B,GAExB,KAAM60B,aAAoBjC,IAAW,CACnC,IAAMyI,EAAmB,IAAIzI,GAC7ByI,EAAiBlJ,WAAW0C,GAC5B1oC,EAAO6T,GAASq7B,WAGf,QAAe,IAAXlvC,KAAuBA,aAAkBymC,IAAW,CAE7D,IAAMyI,EAAmB,IAAIzI,GAC7ByI,EAAiBlJ,WAAWhmC,GAC5BA,EAASkvC,EAGX,OAAOlvC,M,iCAUD4U,GACNnG,KAAKugC,SAASG,QAAQv6B,K,kCAWZw6B,GACV,IAAIpvC,EAASyO,KAAKugC,SAAS7F,YAAYiG,GACvC,OAAOL,EAAcM,oBAAoBrvC,K,kCAU/B0oC,GACVj6B,KAAKugC,SAASM,YAAY5G,K,qCAWb0G,EAAY1G,GACzBj6B,KAAKugC,SAASO,eAAeH,EAAY1G,K,qCAU5B0G,GACb3gC,KAAKugC,SAASQ,eAAeJ,Q,kCCtEjC,IAEeK,GArBf,WACE,IAAM/G,EAAW,IAAIjC,GAAS,WAC9BiC,EAASz3B,GAAK,kBACdy3B,EAAShC,QAAS,EAElB,IAAMgJ,EAAW,IAAIlK,EAAkB,OAAQ,CAC7Cz3B,KAAM,EACNE,QAAS,IAGLu4B,EAAW,IAAId,EACfiK,EAAQ,IAAI1J,EAAMyJ,EAAU,YAKlC,OAJAC,EAAMxJ,UAAU1mC,KAAK+mC,GAErBkC,EAASrB,OAAO5nC,KAAKkwC,GAEdjH,EAGekH,G,2KCXTC,GARU,CACvB5H,kBACA8G,iBACAe,iB,WCJA,c,4FAAc,SACZrhC,KAAKohC,iBAAmB,IAAIxH,IAC5B55B,KAAKshC,eAAgB,E,uDASfn7B,GACDnG,KAAKshC,gBACRjqC,IAAIE,KAAK,6CACTyI,KAAK6gC,YAAYG,IACjBhhC,KAAKshC,eAAgB,GAGvBn7B,M,kCASUw6B,GAEV,OAAIA,EACK3gC,KAAKohC,iBAAiBprC,IAAI2qC,GAI5Bp7B,MAAMg8B,KAAKvhC,KAAKohC,iBAAiBxuB,Y,kCAQ9BqnB,GACVj6B,KAAKohC,iBAAiBlG,IAAIjB,EAASz3B,GAAIy3B,K,qCAS1B0G,EAAY1G,GACpBj6B,KAAKohC,iBAAiBnG,IAAI0F,IAI/B3gC,KAAKohC,iBAAiBlG,IAAIyF,EAAY1G,K,qCAQzB0G,GACR3gC,KAAKohC,iBAAiBnG,IAAI0F,IAI/B3gC,KAAKohC,iBAAiBI,OAAOb,Q,kCDjE/Bc,mBfaF,SAA4BC,EAAaC,EAAex7B,GACtDwtB,EAAkC+N,GAAe,CAC/CtsC,KAAMusC,EACNx7B,SAAUA,IefZy7B,yBbEF,SAAkCC,EAAWC,EAAartB,EAAStO,GACjEivB,EAAuByM,GAAa,CAClCr/B,GAAIq/B,EACJtlB,KAAMulB,EACNrtB,QAASA,EACTtO,SAAUA,KeTC47B,GAFA,G,iPC2Cf,IAKelrC,GALA,CACbmrC,gBAjDF,SAAyBC,GACvB,IAAMC,EAAe,GACrB,IAAK,IAAIxrC,KAAOurC,EACd,GAAKA,EAAcpxC,eAAe6F,GAIlC,IAHA,IAAMN,EAAQ6rC,EAAcvrC,GACtByrC,EAAgBzrC,EAAIuV,MAAM,KAC5Bm2B,EAAgBF,EACbC,EAAczxC,QAAQ,CAC3B,IAAM2xC,EAAkBF,EAAchxC,QACjCgxC,EAAczxC,QAGZ0xC,EAAcC,KACjBD,EAAcC,GAAmB,IAGnCD,EAAgBA,EAAcC,IAN9BD,EAAcC,GAAmBjsC,EAWvC,OAAO8rC,GA6BPI,iBAzBF,SAA0BJ,GACxB,IAAMD,EAAgB,GAmBtB,OAlBkB,SAAZM,EAAaC,EAASN,EAAcO,GACxC,IAAK,IAAI/rC,KAAOwrC,EACd,GAAKA,EAAarxC,eAAe6F,GAAjC,CACA,IAAIgsC,EAAaF,EAAU,GAAH,OAAMA,EAAN,YAAiB9rC,GAAQA,EAC3CisC,EAAeT,EAAaxrC,GACN,WAAxB,GAAOisC,IACLA,aAAwBp9B,QAC1Bm9B,GAAc,MAGhBH,EAAUG,EAAYC,EAAcF,IAEpCA,EAAaC,GAAcC,GAKjCJ,CAAU,GAAIL,EAAcD,GACrBA,I,iPCrCT,SAASW,GAASC,GAChB,MAA0B,iBAAZA,EAmDhB,IAKepgC,GALA,CACbqgC,OAhDF,SAASA,EAAOjsC,EAAQksC,GAAqC,IAA9BjsC,EAA8B,uDAAnB,KAAMvF,EAAa,uDAAJ,GAEjDyxC,EAAU,IAAIC,OAAOF,EAAMG,OAAQ,KA0BzC,OAxBAvyC,OAAO4c,KAAK1W,GAAQgX,SAAQ,SAAAnX,GAC1B,IAAMmV,EAAOhV,EAAOH,GAGpB,GAAKmV,EAAL,CAKA,IA1Bcg3B,EA0BRzsC,EAAQwsC,GAAS9rC,GAAY+U,EAAK/U,GAAY+U,EAGhD+2B,GAASxsC,IAAU4sC,EAAQ3M,KAAKjgC,IAElC7E,EAAOP,KAAK6a,KA/BAg3B,EAkCDh3B,aAhCMlb,QACC,WAAnB,GAAOkyC,IAAoC,OAAZA,IAiC9BC,EAAOj3B,EAAMk3B,EAAOjsC,EAAUvF,OAK3BA,GAqBP4xC,SAjBF,SAAkBhX,GAChB,IAAM1pB,EAAS0pB,GAASA,EAAMJ,SAAWI,EAAMJ,WAAaI,EAG5D,MAAe,KAAX1pB,GAAmC,iBAAXA,EACnB,IAOFA,EAAO0Q,QAAQ,kBAHJ,SAAAiwB,GAAK,MAAI,IAAMA,EAAM,GAAG9W,WAAW,GAAGP,SAAS,IAAM,S,UCjDzE,IAOesX,GAPJ,CACTl7B,iBCDa,WACb,IAAMf,EAAQtU,SAASQ,cAAc,KACrC8T,EAAMhH,MAAMQ,MAAQ,OACpBwG,EAAMhH,MAAMS,OAAS,OAErB,IAAMwG,EAAQvU,SAASQ,cAAc,OACrC+T,EAAMjH,MAAMkH,SAAW,WACvBD,EAAMjH,MAAMmH,IAAM,MAClBF,EAAMjH,MAAMoH,KAAO,MACnBH,EAAMjH,MAAMqH,WAAa,SACzBJ,EAAMjH,MAAMQ,MAAQ,QACpByG,EAAMjH,MAAMS,OAAS,QACrBwG,EAAMjH,MAAMsH,SAAW,SACvBL,EAAMlT,YAAYiT,GAElBtU,SAAS6U,KAAKxT,YAAYkT,GAE1B,IAAMO,EAAKR,EAAMS,YACXC,EAAKV,EAAMV,aACjBW,EAAMjH,MAAMsH,SAAW,SACvB,IAAIK,EAAKX,EAAMS,YACXG,EAAKZ,EAAMV,aAYf,OAVIkB,IAAOG,IACTA,EAAKV,EAAMY,aAGTH,IAAOE,IACTA,EAAKX,EAAMa,cAGbpV,SAAS6U,KAAKzT,YAAYmT,GAEnB,CAACO,EAAKG,EAAID,EAAKE,ID/BtBs7B,UEFa,SAAmBz6B,GAChC,IAAItB,EAAM,EACNC,EAAO,EACX,GAAIqB,EAAQ06B,aACV,GACE/7B,GAAQqB,EAAQ26B,WAChBj8B,GAAOsB,EAAQ46B,gBACP56B,EAAUA,EAAQ06B,cAG9B,MAAO,CACL/7B,OACAD,QFTFm8B,oBGHa,SAA6BhwC,GAC1C,YAA2B,IAAhBA,EAAMiwC,OAGiB,iBAAhBjwC,EAAMiwC,OAAsBjwC,EAAMiwC,MAAQ,KAKvDjwC,EAAMkwC,UAAYlwC,EAAMmwC,UAAYnwC,EAAMowC,QAA0B,IAAhBpwC,EAAMiwC,QHL/DI,YIRa,SAAqBjvC,GAAO,IACnCkV,EAAmBlV,EAAnBkV,MAAO7U,EAAYL,EAAZK,QAER6U,GACClV,aAAiBf,QACnBiW,EAAQlV,EAAMM,MAIbD,GACCL,aAAiBf,QACnBoB,EAAUL,EAAMK,SAIPxE,OAAOqhC,OAClB,CACEhoB,QACA7U,UACAwT,MAAO,SACPq7B,aAAa,EACbC,YAAa,UACbC,YAAa,iBAEfpvC,GAAS,IAGXuC,IAAIvC,MAAMA,K,mFCGN06B,GAAO,CACX2U,iBAEAC,oBACAC,qBACAC,mBACAC,oBAEAC,WACAp2B,aACA8S,aACAujB,WACArpB,YACAyY,aACAkO,UACAtU,cACAhrB,UACA4gC,MACAzW,UACA8X,kBACA7tC,UACAQ,QACA40B,aACA0Y,YACAC,OAAQ,GACRt6B,kBACA82B,oBAEAyD,2BACAC,oBACAC,qBACAC,wBACAC,oBAyCazV,Q,mDCxGR0V,E,2PAAAA,E,uHAEAC,E,0fAAAA,E,yHACAC,E,2fAAAA,E,yHACAC,E,yTAAAA,E,yHACAC,E,4LAAAA,E,kMACAC,E,8cAAAA,E,yHACAC,E,4cAAAA,E,yHACAC,E,yZAAAA,E,2HACAC,E,o+BAAAA,E,wNACAC,E,qjBAAAA,E,yHACAC,E,4bAAAA,E,iIACAC,E,qUAAAA,E,+HACAC,E,0YAAAA,E,yHACAC,E,6MAAAA,E,uHACAC,E,onBAAAA,E,yHACAC,E,oKAAAA,E,sHACAC,E,8LAAAA,E,yHACAC,E,mlBAAAA,E,yHACAC,E,yRAAAA,E,yHACAC,E,+dAAAA,E,yHACAC,E,0xBAAAA,E,uHACAC,E,wTAAAA,E,uHACAC,E,0dAAAA,E,uHACAC,E,mjCAAAA,E,yHACAC,E,69FAAAA,E,8HACAC,E,inDAAAA,E,uHACAC,E,ihBAAAA,E,uHACAC,E,iaAAAA,E,yHACAC,E,knBAAAA,E,yHACAC,E,8RAAAA,E,uHACAC,E,ubAAAA,E,uHACAC,E,2aAAAA,E,sHACAC,E,oLAAAA,E,qJACAC,E,6KAAAA,E,uHACAC,E,0VAAAA,E,yHACAC,E,6VAAAA,E,yHACAC,E,gOAAAA,E,yHACA/vC,E,2aAAAA,E,yHACAgwC,E,sNAAAA,E,uHACAC,E,2PAAAA,E,6IACA/7B,E,4gCAAAA,E,uHACAg8B,E,6RAAAA,E,qIACApe,E,4LAAAA,E,uHACAqe,E,guBAAAA,E,2KACAC,E,mTAAAA,E,uHACAC,E,+RAAAA,E,uHACAC,E,wxBAAAA,E,uJACAC,E,+QAAAA,E,kLACAC,E,4fAAAA,E,uIACAC,G,wOAAAA,G,kLACAC,G,gQAAAA,G,kLACAC,G,wOAAAA,G,kLACAC,G,qWAAAA,G,qIACAC,G,mVAAAA,G,oKACAC,G,+aAAAA,G,uJACAC,G,0mfAAAA,G,uFACAC,G,wRAAAA,G,uHACAC,G,soBAAAA,G,uHACAC,G,+LAAAA,G,yHACAC,G,mQAAAA,G,uHACAC,G,yfAAAA,G,uHACA5O,G,gjBAAAA,G,uHACA6O,G,+hBAAAA,G,uHACAC,G,wiBAAAA,G,uHACAC,G,2mBAAAA,G,+FACAC,G,ytBAAAA,G,yHACAjG,G,oaAAAA,G,uHACAkG,G,2QAAAA,G,yHACAC,G,6xBAAAA,G,uNACA9nB,G,6TAAAA,G,yHACA+nB,G,+NAAAA,G,yHACAC,G,8NAAAA,G,yHACAC,G,k4BAAAA,G,yHACAC,G,iUAAAA,G,yHACAC,G,uXAAAA,G,yHACAC,G,sQAAAA,G,yHACAC,G,uQAAAA,G,yHACAC,G,89BAAAA,G,yHACAC,G,gyCAAAA,G,yHACAC,G,uKAAAA,G,uHACAC,G,8RAAAA,G,uHACAC,G,4IAAAA,G,4IACAC,G,+dAAAA,G,yHACAC,G,wmCAAAA,G,yHACAnd,G,gjBAAAA,G,yHACAod,G,opBAAAA,G,uHACAC,G,8aAAAA,G,4JACAC,G,m0BAAAA,G,wKACAC,G,uqBAAAA,G,qHAEP,IAAMC,GAAQ,CACZH,OACA,aAAcC,GACdvE,QACAoD,YACAnc,QACAzL,QACAuoB,MACAJ,QACA,UAAWH,GACXC,UACA,YAAaF,GACb3xC,OACAmvC,OACAD,aACA,aAAcI,EACd,aAAcxB,EACd,YAAasB,EACb+B,QACA,eAAgBzC,EAChB,oBAAqBd,EACrB,kBAAmBC,EACnB,eAAgBG,EAChB,eAAgBC,EAChBC,OACA,aAAcG,EACd,WAAYC,EACZ,iBAAkBG,EAClBF,QACAI,SACA,WAAYE,EACZyD,SACA,iBAAkBtD,EAClB,wBAAyBC,EACzBM,OACA,gBAAiBM,EACjB,eAAgBC,EAChB,eAAgBe,GAChBtF,UACA,YAAa6F,GACb,cAAepB,EACfle,OACA,YAAagf,GACb,iBAAkBC,GAClBX,OACAc,QACA7B,WACAN,MACA,eAAgBH,EAChB,WAAYkD,GACZ,eAAgBtD,EAChB,WAAY6B,EACZ,gBAAiB2B,GACjB,eAAgBC,GAChBnD,UAAWA,EACXiB,OACA,WAAYqC,GACZ,UAAWC,GACXH,OACAjB,WACAwB,WACAzB,QACA,YAAavB,EACb,YAAaC,EACb/B,SACAsC,QACA,eAAgBC,EAChB,cAAeuB,GACf,qBAAsBlB,EACtB,iBAAkBC,EAClB,oBAAqBC,GACrB,oBAAqBE,GACrB,oBAAqBD,GACrB,eAAgBE,GAChB,iBAAkBpB,EAClBzB,SACAvL,SACA6O,UACA,eAAgBC,GAChBiB,SACAC,UACA,qBAAsB7C,EACtBz7B,OACA,uBAAwB07B,EACxBzB,QACA,cAAeuD,GACfpB,OACAH,QACAxZ,KAAM4a,GACN,kBAAmBqB,I,mBChLfhoC,GAAO,SAAApD,GACX,ODuLa,SAAiBrI,EAAKqI,GACnC,OAAKrI,GAAQ0zC,GAAM1zC,GAIZqvB,IAAMzyB,cAAc82C,GAAM1zC,GAAMqI,GAH9BgnB,IAAMzyB,cAAc,MAAO,KAAM,gBCzLnC+2C,CAAQtrC,EAAM3J,KAAM2J,IAG7BoD,GAAKI,UAAY,CAEfnN,K,QAAM8L,EAAUuB,OAAOrB,YAGVe,UCdf,oC,qnCCUA,IAAMmoC,EAAeC,wBAAc,MAC3BC,EAAaF,EAAbE,SAiBFC,EAAgB,SAAC,GAAwC,IAAtC/mC,EAAsC,EAAtCA,SAAiBmX,EAAqB,EAA5B6vB,MAAcC,EAAc,EAAdA,QACzCC,EAAkB,CACtBC,QAAS,KACTC,aAAc,KACd5vB,kBAAkB,EAClBhB,QAAQ,EACRxJ,QAAS,KACTuK,aAAa,EACb8vB,eAAe,EACf/gC,MAAO,KACPghC,gBAAiB,GACjB7vB,YAAY,GAX+C,IAc/B7O,mBAASs+B,GAdsB,GActDn2B,EAdsD,KAc7Cw2B,EAd6C,KAsBvDC,EAAOr3B,uBAAY,SAAA9U,GAAK,OAAIksC,E,+UAAW,CAAD,GAAMx2B,EAAN,GAAkB1V,MAAU,CACtE0V,IAQI02B,EAAOt3B,uBAAY,kBAAMo3B,EAAWL,KAAkB,CAC1DA,IAQFv2B,qBAAU,WACJs2B,GACFA,EAAQS,yBAAyB,CAAED,OAAMD,WAE1C,CAACC,EAAMR,EAASO,IA5C0C,IA+ClDG,EAWP52B,EAXFo2B,QACAC,EAUEr2B,EAVFq2B,aACA5wB,EASEzF,EATFyF,OACAxJ,EAQE+D,EARF/D,QACA1G,EAOEyK,EAPFzK,MACAghC,EAMEv2B,EANFu2B,gBACA9vB,EAKEzG,EALFyG,iBACAC,EAIE1G,EAJF0G,WACAF,EAGExG,EAHFwG,YACA8vB,EAEEt2B,EAFFs2B,cACAO,EACE72B,EADF62B,SAGF,OACE,kBAACd,EAAD,CAAUp0C,MAAO,CAAE80C,OAAMC,SACtBE,GACC,kBAACxwB,EAAD,CACEnb,UAAWuO,IACT+8B,EACAK,EAAa3rC,UACb,CAAE6rC,iBAAkBR,GACpB,CAAEO,aAEJpwB,iBAAkBA,EAClBhB,OAAQA,EACRlQ,MAAOA,EACPmR,WAAYA,EACZF,YAAaA,EACbvK,QAAS,WACHA,GACFA,IAGFy6B,MAGF,kBAACE,EAAD,KAAkBP,EAAlB,CAAgCI,KAAMA,EAAMC,KAAMA,MAGrDznC,IAUM8nC,EAAY,SAAA7nC,GACvB,OAAO,SAA0B5E,GAAO,MAhHZ0sC,qBAAWnB,GAiH7BY,EAD8B,EAC9BA,KAAMC,EADwB,EACxBA,KACd,OAAO,kBAACxnC,EAAD,KAAe5E,EAAf,CAAsB2rC,MAAO,CAAEQ,OAAMC,aAIhDV,EAAc7nC,aAAe,CAC3B+nC,QAAS,MAGXF,EAAcloC,UAAY,CACxBmB,SAAUxC,IAAUwB,UAAU,CAC5BxB,IAAU0L,QAAQ1L,IAAU0C,MAC5B1C,IAAU0C,OACTxC,WACHspC,MAAOxpC,IAAUwB,UAAU,CACzBxB,IAAU0L,QAAQ1L,IAAU0C,MAC5B1C,IAAU0C,KACV1C,IAAUI,OACTF,WACHupC,QAASzpC,IAAUyB,MAAM,CACvByoC,yBAA0BlqC,IAAUI,QAIzBmpC,Q,GAEcH,EAAaoB,S,8VCtJ1C,IAqCeC,EArCM,SAAC,GAAyB,IAAvBl3B,EAAuB,EAAvBA,QAAS/D,EAAc,EAAdA,QACzBk7B,EAAc,WAClBl7B,EAAQ+D,EAAQjS,KAelB,OARA6R,qBAAU,WACJI,EAAQo3B,WACVv2C,YAAW,WACTs2C,MACCn3B,EAAQq3B,YAEZ,IAGD,yBACEpsC,UAAS,UAAK+U,EAAQnU,QAAU,GAAK,YAA5B,eACPmU,EAAQlhB,KADD,aAIT,0BAAMmM,UAAU,cAAcQ,QAAS0rC,GACrC,0BAAMlsC,UAAU,gBAAhB,MAED+U,EAAQzK,OAAS,yBAAKtK,UAAU,YAAY+U,EAAQzK,OACpDyK,EAAQtf,SAAW,yBAAKuK,UAAU,cAAc+U,EAAQtf,SACxDsf,EAAQs3B,QACP,4BAAQrsC,UAAU,YAAYQ,QAxBhB,WAClBuU,EAAQs3B,OAAO7rC,Q,+UAAf,IAA4BuU,EAA5B,CAAqCu3B,MAAOJ,OAwBrCn3B,EAAQs3B,OAAOjqC,SCoBXmqC,G,OA/CW,WAAM,MACEC,IAAxBC,EADsB,EACtBA,cAAehB,EADO,EACPA,KAMvB,IAAKgB,EACH,OAAO,KAGT,IACQvzB,EAgCR,OAAO,qCAhCCA,EAAQ,CACZgZ,QAAS,GACTwa,UAAW,GACXC,SAAU,GACVC,WAAY,GACZC,aAAc,GACd1a,YAAa,IAGfsa,EAAcxrC,KAAI,SAAAkL,GAChB+M,EAAM/M,EAAKvE,UAAUtW,KAAK6a,MAI1B,6BACGlb,OAAO4c,KAAKqL,GAAOjY,KAAI,SAAA6rC,GACtB,OAAK5zB,EAAM4zB,GAAK97C,OAKd,yBAAKgG,IAAK81C,EAAK9sC,UAAS,0BAAqB8sC,IAC1C5zB,EAAM4zB,GAAK7rC,KAAI,SAACkL,EAAMzG,GAAP,OACd,yBAAK1O,IAAKmV,EAAKrJ,GAAK4C,GAhCf,SAAAyG,GACjB,OAAO,kBAAC,EAAD,CAAcnV,IAAKmV,EAAK4gC,OAAQh4B,QAAS5I,EAAM6E,QAASy6B,IA+BvBuB,CAAW7gC,QANpC,aClCJ,EACP,O,s/CCYA8gC,EAAevxB,IAAfuxB,WAEFC,EAAkBrC,wBAAc,MAEzB2B,EAAqB,kBAAMT,qBAAWmB,IAE7CC,EAAmB,SAAC,GAA0B,IAAxBnpC,EAAwB,EAAxBA,SAAUinC,EAAc,EAAdA,QAC9BC,EAAkB,CACtB5gC,MAAO,GACP7U,QAAS,GACT22C,SAAU,IACVD,WAAW,EACXvkC,SAAU,cACV/T,KAAMu5C,EACNf,OAAQ,MARwC,IAWxBz/B,mBAAS,GAXe,GAW3CygC,EAX2C,KAWpCC,EAXoC,SAYR1gC,mBAAS,IAZD,GAY3C6/B,EAZ2C,KAY5Bc,EAZ4B,KAclD54B,qBAAU,WACR,IAAM64B,EAAe,SAAC,GAAqC,IAAnC35C,EAAmC,EAAnCA,KAAM45C,EAA6B,EAA7BA,OAAQnjC,EAAqB,EAArBA,MAAO7U,EAAc,EAAdA,QACvCg4C,GACFjC,EAAK,CAAE33C,OAAMyW,QAAO7U,aAMxB,OAFAw3C,EAAWS,UAAUT,EAAWU,OAAOC,MAAOJ,GAEvC,WACLP,EAAWY,YAAYZ,EAAWU,OAAOC,MAAOJ,MAEjD,CAAChC,IAEJ,IAAMA,EAAOr3B,uBACX,SAAAY,GACE,IAAKA,IAAaA,EAAQzK,QAAUyK,EAAQtf,QAK1C,OAJA6B,QAAQM,KACN,4EAGK,KAGY,UAAjBmd,EAAQlhB,MACVyD,QAAQlC,MAAM2f,EAAQ3f,OAGxB,IAAM04C,EAAU,KACX5C,EADQ,GAERn2B,EAFQ,CAGXjS,GAAIuqC,EACJzsC,SAAS,IAGX2sC,GAAiB,SAAArtC,GAAK,kBAAQA,GAAR,CAAe4tC,OACrCR,EAASD,EAAQ,KAEnB,CAACA,EAAOnC,IAGJO,EAAOt3B,uBACX,SAAArR,GAaEyqC,GAAiB,SAAArtC,GAAK,OAAaA,EAXVe,KAAI,SAAAkL,GAKzB,OAJIA,EAAKrJ,KAAOA,IACdqJ,EAAKvL,SAAU,GAGVuL,QAQXvW,YAAW,WACT23C,GAAiB,SAAArtC,GAAK,SAAQA,EAAM6tC,QAAO,SAAA5hC,GAAI,OAAIA,EAAKrJ,KAAOA,WAC9D,OAEL,CAACyqC,IAGGS,EAAU,WAEdV,EAAS,GAGTC,GAAiB,iBAAM,OAwBzB,OAhBA54B,qBAAU,WACJs2B,GACFA,EAAQS,yBAAyB,CAAED,OAAMD,WAE1C,CAACP,EAASQ,EAAMD,IAMnBh0C,OAAOy2C,SAAW,CAChBzC,OACAC,OACAuC,WAIA,kBAACd,EAAgBpC,SAAjB,CAA0Bp0C,MAAO,CAAE80C,OAAMC,OAAMuC,UAASvB,oBACnDA,GAAiB,kBAAC,EAAD,MACnBzoC,IAKPmpC,EAAiBjqC,aAAe,CAC9B+nC,QAAS,MAGXkC,EAAiBtqC,UAAY,CAC3BmB,SAAUxC,IAAUwB,UAAU,CAC5BxB,IAAU0L,QAAQ1L,IAAU0C,MAC5B1C,IAAU0C,KACV1C,IAAUI,OACTF,WACHupC,QAASzpC,IAAUyB,MAAM,CACvByoC,yBAA0BlqC,IAAUI,QASjC,IASQurC,I,iBCjJThqC,EAAkB,SAAA+qC,GAAS,OAAI,SAAAjqC,GAKnC,OAfkB,SAAAA,GAOlB,OANyB,SAAA5E,GAAK,OAC5B,kBAAC,IAAD,CAAiBid,KAAMA,KACrB,kBAACrY,EAAc5E,KAYZ8uC,CAAYC,YAAuBF,EAAvBE,EAJS,SAAA/uC,GAC1B,OAAO,kBAAC4E,EAAc5E,S,muDCL1B,IAAMgvC,EAAgBxD,wBAAc,MAI9ByD,EAAiB,SAAC,GAA0B,IAAxBtqC,EAAwB,EAAxBA,SAAUinC,EAAc,EAAdA,QAAc,IACZr+B,oBAAS,GADG,GACzC2hC,EADyC,KAC7BC,EAD6B,SAElB5hC,mBAAS,IAFS,GAEzC6hC,EAFyC,KAEhCC,EAFgC,SAGR9hC,mBAAS,MAHD,GAGzC+hC,EAHyC,KAG3BC,EAH2B,SAIIhiC,mBAAS,MAJb,GAIzCiiC,EAJyC,KAIrBC,EAJqB,SAKFliC,mBAAS,IALP,GAKzCmiC,EALyC,KAKxBC,EALwB,KAOhDr6B,qBAAU,WACRq6B,EACEP,EAAQxtC,KAAI,SAAAguC,GAAM,UAChBnsC,GAAImsC,EAAOnsC,IACRosC,EAAkBD,EAAOnsC,WAG/B,CAAC2rC,IAEJ,IAAMS,EAAoB,SAAApsC,GACxB,IAAMqsC,EAAO/7C,SAASg8C,cAAc,SAC9Btc,EAAUqc,EAAKrL,WAAaqL,EAAKhnC,YAAc,EAC/C4qB,EAAUoc,EAAKpL,UAAYoL,EAAKnoC,aAAe,EAE/CqoC,EADOj8C,SAASg8C,cAAT,yBAAyCtsC,IAC9BwsC,wBACxB,MAAO,CACLjoC,EAAGyrB,EAAUuc,EAAWnuC,MAAQ,EAChCqG,EAAGwrB,EAAUsc,EAAWluC,OAAS,IAU/BpK,EAASod,uBAAY,SAAA9U,GAAS,IAG9BkwC,EAFWlwC,EAAPyD,GAUR,OAPKysC,IACHA,EAAWzK,IAAM7O,QAGnByY,GAAW,SAAAD,GAAO,kBAAQA,GAAR,MAAsBpvC,EAAtB,CAA6ByD,GAAIysC,SACnDX,EAAgBW,GAETA,IACN,IASGC,EAAUr7B,uBACd,gBAAGrR,EAAH,EAAGA,GAAH,OACE4rC,GAAW,SAAAD,GAAO,OAAIA,EAAQV,QAAO,SAAAkB,GAAM,OAAIA,EAAOnsC,KAAOA,UAC/D,IAQF6R,qBAAU,WACJs2B,GACFA,EAAQS,yBAAyB,CAAE30C,SAAQy4C,UAASC,iBAErD,CAAC14C,EAAQy4C,EAASvE,IAQrB,IAAMyE,EAAgBv7B,uBAAY,SAAArR,GAChC4rC,GAAW,SAAAD,GACT,IAAMkB,EAAYlB,EAAQl4B,MAAK,SAAA04B,GAAM,OAAIA,EAAOnsC,KAAOA,KACvD,OAAO6sC,EAAS,YACRlB,EAAQV,QAAO,SAAAkB,GAAM,OAAIA,EAAOnsC,KAAOA,MAD/B,CACoC6sC,IAChDlB,OAEL,IAmBH95B,qBAAU,kBAAM+6B,EAAcf,KAAe,CAACe,EAAef,IAO7D,IAAMc,EAAa,WACjBf,EAAW,KAQPh7B,EAAU,kBAAM+6B,GAAWA,EAAQz9C,OAAS,GAgG5C4+C,EAA4B,SAAAL,GAChC,IAAMM,EAAsBz8C,SACzBg8C,cADyB,yBACOG,IAChCD,wBACHR,EAAsB,CACpBznC,EAAGwoC,EAAoBxoC,EACvBE,EAAGsoC,EAAoBtoC,KAIrBuoC,EAAgB,SAAArpC,GAAQ,OAAIA,GAAgC,mBAAbA,GAErD,OACE,kBAAC4nC,EAAcvD,SAAf,CAAwBp0C,MAAO,CAAEK,SAAQy4C,UAASC,aAAY/7B,aAC1DA,KAAa,yBAAK1T,UAAU,iBA3GhCyuC,EAAQxtC,KAAI,SAAAguC,GAAU,IAElBnsC,EAWEmsC,EAXFnsC,GACSitC,EAUPd,EAVF9D,QACAC,EASE6D,EATF7D,aACA4E,EAQEf,EARFe,gBALkB,EAahBf,EAPFgB,kBANkB,WAahBhB,EANFiB,wBAPkB,WAahBjB,EALFkB,mBARkB,SASlBC,EAIEnB,EAJFmB,QACAC,EAGEpB,EAHFoB,OACAC,EAEErB,EAFFqB,OACAC,EACEtB,EADFsB,YAGE3oC,EACDsoC,GAAoBrB,GAAuBmB,EAC1CC,IACFroC,EAAWmnC,EAAgBx4B,MAAK,SAAA3O,GAAQ,OAAIA,EAAS9E,KAAOA,MAG9D,IAAM0tC,EAAe,kBACnB,kBAAC,IAAD,CACEx5C,IAAK8L,EACL6K,UAAWwiC,EACXvoC,SAAUA,EACVooC,gBAAiBpoC,EACjBgqB,OAAO,SACPwe,QAAS,SAAAp8C,GACP,IAAMrB,EAAIqB,GAASwD,OAAOxD,MACpBE,EAASvB,EAAEuB,QAAUvB,EAAE89C,WAS7B,OARkB,CAChB,MACA,SACA,OACA,QACA,OACA,SAEYriC,SAASla,EAAOw8C,QAAQxkC,iBAIlC4jC,EAAcM,GACTA,EAAQp8C,QADjB,IAIFq8C,OAAQ,SAAAr8C,GAGN,GAFAw6C,GAAc,GAEVsB,EAAcO,GAChB,OAAOA,EAAOr8C,IAGlBs8C,OAAQ,SAAAt8C,GAKN,GAJAw6C,GAAc,GACdkB,EAAc5sC,GACd8sC,EAA0B9sC,GAEtBgtC,EAAcQ,GAChB,OAAOA,EAAOt8C,KAIlB,yBACE8O,GAAE,wBAAmBA,GACrB9C,UAAWuO,IACT,gBACAggC,GAAc,WACd4B,GAAe,aAEjBzvC,MAAO,CAAEsa,OAAQ,MAAOpT,SAAU,YAClCpH,QAAS,kBAAMkvC,EAAc5sC,KAE7B,kBAACitC,EAAD,KAAmBd,EAAY7D,OAKrC,OAAOmF,EACL,yBAAKvwC,UAAU,UAAUhJ,IAAK8L,GAC3B0tC,KAGHA,QAwBDxsC,IAUM2sC,EAAa,SAAA1sC,GACxB,OAAO,SAA0B5E,GAAO,MApPX0sC,qBAAWsC,GAqP9Bt3C,EAD8B,EAC9BA,OAAQy4C,EADsB,EACtBA,QAASC,EADa,EACbA,WAAY/7B,EADC,EACDA,QACrC,OACE,kBAACzP,EAAD,KAAe5E,EAAf,CAAsB4vC,OAAQ,CAAEl4C,SAAQy4C,UAASC,aAAY/7B,gBAKnE46B,EAAeprC,aAAe,CAC5B+nC,QAAS,MAGXqD,EAAezrC,UAAY,CACzBmB,SAAUxC,IAAUwB,UAAU,CAC5BxB,IAAU0L,QAAQ1L,IAAU0C,MAC5B1C,IAAU0C,KACV1C,IAAUI,OACTF,WACHupC,QAASzpC,IAAUyB,MAAM,CACvByoC,yBAA0BlqC,IAAUI,QAIzB0sC,Q,m/CCzRf,IAAMsC,GAAgB/F,wBAAc,MAC5BC,GAAa8F,GAAb9F,SAEK+F,GAAY,kBAAM9E,qBAAW6E,KAEpCE,GAAiB,SAAC,GAA0B,IAAxB9sC,EAAwB,EAAxBA,SAAUinC,EAAc,EAAdA,QAAc,KACtBr+B,mBAAS,CACjCmkC,OAAQ,GACRC,MAAO,KAHuC,GACzC9wC,EADyC,KAClCE,EADkC,KAMhDuU,qBAAU,WACR,IAAMs8B,EAAiB,SAAC,GAAoC,IAA3BC,EAA2B,EAAlC97C,MAAoBK,EAAc,EAAdA,QAC5CL,EAAM,CAAEA,MAAO87C,EAAaz7C,aAG9B,OADA+B,OAAOiS,iBAAiB,QAASwnC,GAC1B,WACLz5C,OAAOkS,oBAAoB,QAASunC,MAErC,IAQH,IAAM77C,EAAQ,YAKR,QAJJA,aAII,MAJI,GAIJ,MAHJ4mB,aAGI,MAHI,GAGJ,MAFJvmB,eAEI,MAFM,GAEN,MADJ07C,wBACI,SACED,EAAc,CAAE97C,QAAO4mB,QAAOvmB,UAAS07C,oBAC7C/wC,GAAS,SAAAF,GAAK,YAAUA,EAAV,CAAiB6wC,OAAQ,GAAF,SAAM7wC,EAAM6wC,QAAZ,CAAoBG,SAErDC,GACF75C,QAAQlC,MAAMA,IAUZyC,EAAO,SAAC,GAA8C,QAA5CpC,eAA4C,MAAlC,GAAkC,MAA9B07C,wBAA8B,SAC1D/wC,GAAS,SAAAF,GAAK,YACTA,EADS,CAEZ8wC,MAAO9wC,EAAM8wC,MAAM1/C,KAAK,CAAEmE,UAAS07C,0BAGjCA,GACF75C,QAAQO,KAAKpC,IAejB,OANAkf,qBAAU,WACJs2B,GACFA,EAAQS,yBAAyB,CAAEt2C,QAAOyC,WAE3C,CAACzC,EAAO61C,EAASpzC,IAEb,kBAAC,GAAD,CAAUnB,MAAO,CAAEmB,OAAMzC,QAAO8K,UAAU8D,IAenD8sC,GAAe5tC,aAAe,CAC5B+nC,QAAS,MAGX6F,GAAejuC,UAAY,CACzBmB,SAAUxC,IAAUwB,UAAU,CAC5BxB,IAAU0L,QAAQ1L,IAAU0C,MAC5B1C,IAAU0C,OACTxC,WACHupC,QAASzpC,IAAUyB,MAAM,CACvByoC,yBAA0BlqC,IAAUI,QAIzBkvC,UAEYF,GAAc5E,SCvGzC,qT,iCC2Be/V,IAtBF,WACX,IAAMmb,EAAsB,WAC1B,OAAOv9B,KAAKw9B,MAA4B,OAArB,EAAIx9B,KAAK0R,WACzB8G,SAAS,IACTilB,UAAU,IAEf,OACEF,IACAA,IACA,IACAA,IACA,IACAA,IACA,IACAA,IACA,IACAA,IACAA,IACAA,M,kCClBWpM,IAJM,CACnBuM,oBAAqB,kBAAM,Q,skDCEvBhd,E,YACJ,WAAY9+B,GAAS,a,4FAAA,UACnB,2BACKA,QAAUA,EACf,EAAKumB,OAAQ,IAAI3nB,OAAQ2nB,MACzB,EAAKtmB,KAAO,EAAK87C,YAAY97C,KAJV,E,oPADCrB,QASTkgC,O,8vBCXf,IAAMkd,EAAsB,CAC1BC,QAAS,EACTC,OAAQ,EACRC,WAAY,IACZC,WAAY,IACZC,WAAW,EACXC,qBAAsB,CAAC,IAAK,MAG1BC,EAAe,EAAH,GAAQP,GAWlBQ,EAAsB,SAACh+C,EAASkgC,GAAa,IACzC+d,EAAgB/d,EAAhB+d,IAAKC,EAAWhe,EAAXge,OA8Bb,IAAMC,EAAsBn+C,EAAQo+C,KAGpC,OAFAp+C,EAAQo+C,KA7BR,WACE,IAAMC,EAAYxmB,IAAMwmB,UAAUN,GAElCM,EAAUC,SAAQ,SAA0BC,GAC1C,IAAMC,EAA6Bx+C,EAAQy+C,mBAG3Cz+C,EAAQy+C,mBAAqB,WAAqC,2BAANhsC,EAAM,yBAANA,EAAM,gBAGhE,GAFA+rC,EAA2B9gD,MAAMsC,EAASyS,GAEtCsrC,EAAaD,qBAAqB3jC,SAASna,EAAQ0+C,QAAS,CAC9D,IAAMC,EAAe,sBAAH,OAAyBV,EAAzB,YACZW,EAAqB,IAAIx+C,MAAMu+C,GACrCN,EAAUxmB,MAAM+mB,KAKhBL,EAAiB,IACnBl7C,QAAQM,KAAR,qBAA2Bs6C,EAA3B,yBAA+CM,EAA/C,MACAv+C,EAAQy1B,KAAKyoB,EAAQD,GAAK,OApBW,2BAANxrC,EAAM,yBAANA,EAAM,gBAwBzC0rC,EAAoBzgD,MAAMsC,EAASyS,IAO9BzS,GAuBI6+C,EAAyB,WAAkB,IAAjB/9B,EAAiB,uDAAP,GAoB/C,OAnBAi9B,EAAe,EAAH,GAAQP,GAChB,YAAa18B,IACfi9B,EAAaN,QAAU38B,EAAQ28B,SAE7B,WAAY38B,IACdi9B,EAAaL,OAAS58B,EAAQ48B,QAE5B,eAAgB58B,IAClBi9B,EAAaJ,WAAa78B,EAAQ68B,YAEhC,eAAgB78B,IAClBi9B,EAAaH,WAAa98B,EAAQ88B,YAEhC,cAAe98B,IACjBi9B,EAAaF,UAAY/8B,EAAQ+8B,WAE/B,yBAA0B/8B,IAC5Bi9B,EAAaD,qBAAuBh9B,EAAQg9B,sBAEvCE,GAGMa,O,6BCrGf,IAAI5lB,EAAO,CACTwL,aAAc,kBAAM,GACpBE,UAAW,kBAAM,MACjBjL,QAAS,kBAAM,MACfR,eAAgB,kBAAM,MACtB4lB,MAAO,kBAAM,IAAIlgD,SAAQ,SAACC,EAASC,GAAV,OAAqBA,QAC9CigD,OAAQ,kBAAM,IAAIngD,SAAQ,SAACC,EAASC,GAAV,OAAqBA,QAC/CkgD,QAAS,SAAAj8C,GAAG,OAAI,MAChBk8C,QAAS,SAACl8C,EAAKN,GAAN,OAAgB,OAGZw2B,O,0cCRf,IASaimB,EAAb,WAKE,WAAY3iD,EAAM4iD,I,4FAAK,SAGrBniD,OAAOmF,eAAekK,KAAM,QAAS,CACnC+yC,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAOlG,IAKTS,OAAOmF,eAAekK,KAAM,OAAQ,CAClC+yC,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO08C,IAKTniD,OAAOmF,eAAekK,KAAM,UAAW,CACrC+yC,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAOzF,OAAO8F,OAAO,Q,UA9B3B,O,EAAA,E,EAAA,kCAsGoBq8C,GAChB,MAhHW,WAgHJ,EAAOA,IAAkBA,EAAIpiD,OAAS,IAvGjD,mCA0GsB0U,GAClB,MAnHW,WAmHJ,EAAOA,IAAoBA,GAAS,IAAc,EAARA,KAAeA,IA3GpE,sCA8GyBe,GACrB,MAtHa,aAsHN,EAAOA,O,EA/GlB,iCAmCI,OAAOnG,KAAKizC,QAnChB,sCAsCkBC,GACd,IAAIC,EACEF,EAAQjzC,KAAKizC,MAOnB,OALEA,aAAiBtiD,QAhDR,WAiDR,EAAOsiD,IAA8B,OAAVA,KAE5BE,EAAgBF,EAAMC,IAEjBC,IA/CX,oCAsDI,OAAOnzC,KAAKozC,OAtDhB,yCA8DqB3e,EAAWr+B,GAC5B4J,KAAKqzC,QAAQ5e,GAAar+B,IA/D9B,yCAuEqBq+B,GACjB,OAAOz0B,KAAKqzC,QAAQ5e,KAxExB,4CAgFwBA,GACpB,OAAOA,KAAaz0B,KAAKqzC,UAjF7B,0CAwFsBte,GAClB,IAAMue,EAAU3iD,OAAOC,UAAUC,eAC3BwiD,EAAUrzC,KAAKqzC,QACrB,IAAK,IAAI5e,KAAaM,EAChBue,EAAQxiD,KAAKikC,EAAcN,KAC7B4e,EAAQ5e,GAAaM,EAAaN,S,2BA7F1C,M,4CCbA,wEAAM70B,EAAQ,CACZ2zC,gBAAiB,IAQbC,EAAoB,SAAC5X,EAAe/yB,GAAhB,OACvBjJ,EAAM2zC,gBAAgB3X,GAAiB/yB,GAOpC8lB,EAAoB,SAAAiN,GAAa,OAAIh8B,EAAM2zC,gBAAgB3X,K,6zBCTjE,IAGahI,EAAb,YACE,WAAY1jC,EAAM4iD,GAAK,M,IAAA,O,4FAAA,S,EACrB,S,EAAA,eAAM5iD,EAAM4iD,K,6CAEZniD,OAAO8iD,iBAAP,KAA8B,CAC5BC,SAAU,CACRX,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO,QAIX,EAAKu9C,0BAZgB,E,UADzB,O,kOAAA,M,EAAA,E,EAAA,uCAgLyBv9C,EAAOgP,EAAOmV,GACnC,IAAIhpB,EAASgpB,EAEb,GArLW,WAqLP,EAAOnkB,GAAkB,CAC3B,IAAMw9C,GAA0C,IAAzBx9C,EAAMyjB,QAAQ,MAIrC,GAFAtoB,EAAS6E,EAELw9C,EAAgB,CAClB,IAAMC,EAAcz9C,EAAM6V,MAAM,MAChC,GAAI4mC,IAASiB,aAAa1uC,GAAQ,CAChC,IAAM2uC,EAAeF,EAAYzuC,GAEjC7T,EA/LK,WA+LI,EAAOwiD,GAA0Bx5B,EAAew5B,OAEzDxiD,EAASsiD,GAKf,OAAOtiD,M,EApMX,iDAiCIZ,OAAOmF,eAAekK,KAAM,iBAAkB,CAC5C+yC,cAAc,EACdh9C,YAAY,EACZC,IAAK,WACH,OAAOgK,KAAKu9B,yBArCpB,4CAkDI,OAAOv9B,KAAKk1B,YAAY,mBAAoB,QAlDhD,6CAyDI,OAAOl1B,KAAKk1B,YAAY,oBAAqB,QAzDjD,0CAgEI,OAAOl1B,KAAKk1B,YAAY,iBAAkB,QAhE9C,qCAoEiB8e,EAAe5uC,EAAOmV,GACnC,IAAInkB,EAAQ4J,KAAKk1B,YAAY8e,EAAez5B,GAM5C,MA7EW,WAyEP,EAAOnkB,IA1EG,cA0EiB,EAAOA,KACpCA,EAAQA,EAAM21B,YAGT6H,EAAiBqgB,gBAAgB79C,EAAOgP,EAAOmV,KA3E1D,oCA+EgBy5B,EAAe5uC,EAAOmV,GAClC,IAAInkB,EAAQ4J,KAAKk1B,YAAY8e,EAAez5B,GAG5C,OAFAnkB,EAAQw9B,EAAiBqgB,gBAAgB79C,EAAOgP,EAAOmV,cAElChV,OACnBnP,EAAMyX,SAAQ,SAACqmC,EAAKC,GAClB/9C,EAAM+9C,GAAO/kC,WAAW8kC,MAGnB99C,GA1FE,WA6FJ,EAAOA,GAAmBgZ,WAAWhZ,GAASA,IA3FzD,kCA+Fc49C,EAAe5uC,EAAOmV,GAChC,IAAInkB,EAAQ4J,KAAKk1B,YAAY8e,EAAez5B,GAG5C,OAFAnkB,EAAQw9B,EAAiBqgB,gBAAgB79C,EAAOgP,EAAOmV,cAElChV,OACnBnP,EAAMyX,SAAQ,SAACqmC,EAAKC,GAClB/9C,EAAM+9C,GAAO/kC,WAAW8kC,MAGnB99C,GA1GE,WA6GJ,EAAOA,GAAmBguB,SAAShuB,GAASA,IA3GvD,kCAiHc49C,EAAez5B,GAIzB,MAAM,IAAI0Z,IACR,sIAtHN,6BA+HS+I,GAEL,OACEA,IAFWh9B,MAGVg9B,aAAoBpJ,GACnBoJ,EAASO,sBAJAv9B,KAI6Bu9B,sBApI9C,gCA6IYyW,GAIR,MAAM,IAAI/f,IACR,oIAlJN,iCA0JamgB,GAIT,MAAM,IAAIngB,IACR,wI,2BA/JN,GAAsC4e,M,uzBCR/B,IAAMwB,EAAb,YACE,WAAYnkD,EAAM4iD,GAAK,M,IAAA,O,4FAAA,S,EACrB,S,EAAA,eAAM5iD,EAAM4iD,K,6CAEZniD,OAAO8iD,iBAAP,KAA8B,CAC5Ba,mBAAoB,CAClBvB,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO,MAETm+C,WAAY,CACVxB,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO,IAETo+C,eAAgB,CACdzB,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO,QAIX,EAAKu9C,0BAxBgB,E,UADzB,O,kOAAA,M,EAAA,G,EAAA,iDA6CIhjD,OAAOmF,eAAekK,KAAM,oBAAqB,CAC/C+yC,cAAc,EACdh9C,YAAY,EACZC,IAAK,WACH,OAAOgK,KAAK29B,4BAjDpB,6CA8DI,OAAO39B,KAAKs0C,qBA9DhB,kCAsEctX,GACV,IAAIzrC,GAAS,EAQb,OANEyrC,aAAoBpJ,UACoC,IAAxD5zB,KAAKy0C,iBAAiBzX,EAASO,uBAE/Bv9B,KAAKu0C,WAAWvjD,KAAKgsC,GACrBzrC,GAAS,GAEJA,IA/EX,yCAuFI,IAAIyrC,EAAWh9B,KAAKw0C,eACpB,KAAMxX,aAAoBpJ,KAAmB,CAC3CoJ,EAAW,KACX,IAAM0X,EAAQ10C,KAAK20C,mBAAmB,GAClCD,aAAiB9gB,MACnB5zB,KAAKw0C,eAAiBE,EACtB1X,EAAW0X,GAGf,OAAO1X,IAhGX,yCAwGqB53B,GACjB,IAAIsvC,EAIJ,OAHI7B,IAASiB,aAAa1uC,KACxBsvC,EAAQ10C,KAAKu0C,WAAWnvC,IAEnBsvC,IA7GX,uCAqHmB5B,GACf,IAAI4B,EAMJ,OALI7B,IAAS+B,WAAW9B,KACtB4B,EAAQ10C,KAAKu0C,WAAWt+B,MAAK,SAAA+mB,GAC3B,OAAOA,EAASO,sBAAwBuV,MAGrC4B,IA5HX,yCAoII,OAAO10C,KAAKu0C,WAAW7jD,SApI3B,sCA8IkByV,GACV0sC,IAASgC,gBAAgB1uC,IAC3BnG,KAAKu0C,WAAW1mC,SAAQ,SAACmvB,EAAU53B,GACjCe,EAASrV,KAAK,KAAMksC,EAAU53B,QAjJtC,sCA2JkB43B,GACd,OAAOh9B,KAAKu0C,WAAW16B,QAAQmjB,KA5JnC,mCAuKe72B,GACX,GAAI0sC,IAASgC,gBAAgB1uC,GAC3B,OAAOnG,KAAKu0C,WAAWt+B,MAAK,SAAC+mB,EAAU53B,GACrC,OAAOe,EAASrV,KAAK,KAAMksC,EAAU53B,QA1K7C,6BAoLSy3B,GAEL,OACEA,IAFW78B,MAGV68B,aAAkBwX,GACjBxX,EAAOc,yBAJE39B,KAI8B29B,4B,2BAzL/C,GAAoCkV,M,goDCKpC,IAAMtwC,EAAY,CAIhBuyC,GAAI5zC,IAAUG,KAKd0zC,aAAc7zC,IAAUG,KAKxB2zC,cAAe9zC,IAAUG,KAMzB4zC,OAAQ/zC,IAAUG,KAOlB3M,QAASwM,IAAUC,OAKnB+zC,QAASh0C,IAAUI,KAInB6zC,WAAYj0C,IAAUI,KAItB8zC,UAAWl0C,IAAUI,KAIrB+zC,OAAQn0C,IAAUI,KAIlBg0C,UAAWp0C,IAAUI,KAIrBi0C,SAAUr0C,IAAUI,MAWhBk0C,GAAU,OACbC,WAAW,MADE,IAEbC,UAAU,MAFG,GAKVC,E,wcACK,MACmC31C,KAAKjB,MAAvCW,EADD,EACCA,UAAWgE,EADZ,EACYA,SAAa3E,EADzB,8BAGP,OACE,kBAAC,IAAeA,GACb,SAACszC,EAAQuD,GAAT,OACC7vB,IAAM8vB,aAAanyC,E,+UAAnB,IACKkyC,EADL,CAEEl2C,UAAWuO,IACT,OACAvO,EACAgE,EAAS3E,MAAMW,UACf81C,EAAWnD,e,8BAbNtsB,IAAMpiB,WAsBzBgyC,EAAKpzC,UAAYA,EACjBozC,EAAK/yC,aApCgB,CACnBkyC,IAAI,EACJpgD,QAAS,IACTqgD,cAAc,EACdC,eAAe,EACfC,QAAQ,GAiCKU,Q,02CC5Ff,IAAMpzC,EAAY,CAIhB2oC,KAAMhqC,IAAUG,KAIhBqkB,UAAWxkB,IAAUG,KAKrBy0C,OAAQ50C,IAAUI,KAKlBqf,UAAWzf,IAAUwB,UAAU,CAACxB,IAAUG,KAAM00C,MAKhDb,QAASh0C,IAAUI,KAKnB6zC,WAAYj0C,IAAUI,KAKtB8zC,UAAWl0C,IAAUI,KAKrB+zC,OAAQn0C,IAAUI,KAKlBg0C,UAAWp0C,IAAUI,KAKrBi0C,SAAUr0C,IAAUI,KAKpBsE,UAAW1E,IAAUuf,MAAM,CAAC,MAAO,QAAS,SAAU,UAGlD7d,EAAe,CACnB+d,UAAWg1B,EACXjwB,WAAW,EACXwlB,MAAM,EACNtlC,UAAW,SAGPowC,E,wcACK,IAKHC,EALG,EACmCj2C,KAAKjB,MAAvC4hB,EADD,EACCA,UAAWjd,EADZ,EACYA,SAAa3E,EADzB,8BAGDm3C,GAA2B,IAAdv1B,EAAqBg1B,EAAOh1B,GAAa,KAY5D,OAHEs1B,EALGC,EAKKxyC,EAJAmyC,uBAAanyC,EAAU,CAC7BhE,UAAWuO,IAAWvK,EAAS3E,MAAMW,UAAW,QAOlD,kBAAC,UAAD,KAAiBX,EAAjB,CAAwBm3C,WAAYA,IACjCD,Q,8BAlBalwB,IAAMpiB,WAwB5BqyC,EAAQzzC,UAAYA,EACpByzC,EAAQpzC,aAAeA,EAEvB,IAAMoD,EAAqBnD,cAAkBmzC,G,qDCrE9BG,MArBf,WAAyC,2BAAPC,EAAO,yBAAPA,EAAO,gBACvC,OAAOA,EACJ3I,QAAO,SAAA4I,GAAC,OAAS,MAALA,KACZn0B,QAAO,SAACo0B,EAAKD,GACZ,GAAiB,mBAANA,EACT,MAAM,IAAItiD,MACR,2EAIJ,OAAY,OAARuiD,EACKD,EAGF,WAAkC,2BAANjwC,EAAM,yBAANA,EAAM,gBACvCkwC,EAAIjlD,MAAM2O,KAAMoG,GAChBiwC,EAAEhlD,MAAM2O,KAAMoG,MAEf,O,syCCVP,SAASmwC,EAAQC,EAAKC,GACpB,OAAIlxC,MAAMC,QAAQixC,GACTA,EAAG58B,QAAQ28B,IAAQ,EAErBA,IAAQC,EAGjB,IAAMC,GAAcx1C,IAAUuf,MAAM,CAAC,QAAS,QAAS,UAEjDle,GAAY,CAIhBkjB,QAASvkB,IAAUwB,UAAU,CAACg0C,GAAax1C,IAAU0L,QAAQ8pC,MAK7DxwC,MAAOhF,IAAUC,OAIjBw1C,UAAWz1C,IAAUC,OAIrBy1C,UAAW11C,IAAUC,OAOrB01C,oBAAqB31C,IAAUG,KAK/BwE,QAAS3E,IAAU0C,KAAKxC,WAKxBukB,WAAYzkB,IAAUI,KAKtBw1C,OAAQ51C,IAAUI,KAIlBpB,QAASgB,IAAUI,KAInBiN,QAASrN,IAAUI,KAInBy1C,WAAY71C,IAAUI,KAItB01C,YAAa91C,IAAUI,KAMvB1N,OAAQsN,IAAUuf,MAAM,CAAC,OAIzBq1B,OAAQ50C,IAAUuf,MAAM,CAAC,OAIzByqB,KAAMhqC,IAAUuf,MAAM,CAAC,QAQnBw2B,G,YACJ,WAAYl4C,EAAOsH,GAAS,M,IAAA,O,4FAAA,S,EAC1B,K,EAAA,eAAMtH,EAAOsH,IAAb,G,iDAEK6wC,aAAe,EAAKA,aAAavgD,KAAlB,MACpB,EAAKwgD,kBAAoB,EAAKA,kBAAkBxgD,KAAvB,MACzB,EAAKygD,kBAAoB,EAAKA,kBAAkBzgD,KAAvB,MACzB,EAAKgvB,WAAawwB,EAChB,EAAKxwB,WAAWhvB,KAAhB,MACAoI,EAAM4mB,YAGR,EAAK0xB,gBAAkB,SAAAhlD,GAAC,OACtB,EAAKilD,mBAAmB,EAAKH,kBAAmB9kD,EAAG,gBACrD,EAAKklD,eAAiB,SAAAllD,GAAC,OACrB,EAAKilD,mBAAmB,EAAKF,kBAAmB/kD,EAAG,cAErD,EAAKmlD,WAAa,KAElB,EAAK53C,MAAQ,CACXsrC,KAAMnsC,EAAM83C,qBAnBY,E,2SAwB1B72C,KAAKw3C,WAAa1kD,SAASQ,cAAc,OACzC0M,KAAKy3C,kB,2CAILz3C,KAAKy3C,kB,6CAILC,IAASC,uBAAuB33C,KAAKw3C,YACrCx3C,KAAKw3C,WAAa,KAElBziD,aAAaiL,KAAK43C,iBAClB7iD,aAAaiL,KAAK63C,mB,0CAGA,WAClB,GAA4B,MAAxB73C,KAAK43C,gBAGP,OAFA7iD,aAAaiL,KAAK43C,sBAClB53C,KAAK43C,gBAAkB,MAIzB,GAAK53C,KAAKJ,MAAMsrC,MAAgC,MAAxBlrC,KAAK63C,gBAA7B,CAIA,IAAM3xC,EACoB,MAAxBlG,KAAKjB,MAAM63C,UAAoB52C,KAAKjB,MAAM63C,UAAY52C,KAAKjB,MAAMmH,MAE9DA,EAKLlG,KAAK63C,gBAAkBviD,YAAW,WAChC,EAAKuiD,gBAAkB,KACvB,EAAK1M,SACJjlC,GAPDlG,KAAKmrC,U,0CAUW,WAClB,GAA4B,MAAxBnrC,KAAK63C,gBAGP,OAFA9iD,aAAaiL,KAAK63C,sBAClB73C,KAAK63C,gBAAkB,MAIzB,IAAI73C,KAAKJ,MAAMsrC,MAAgC,MAAxBlrC,KAAK43C,gBAA5B,CAIA,IAAM1xC,EACoB,MAAxBlG,KAAKjB,MAAM43C,UAAoB32C,KAAKjB,MAAM43C,UAAY32C,KAAKjB,MAAMmH,MAE9DA,EAKLlG,KAAK43C,gBAAkBtiD,YAAW,WAChC,EAAKsiD,gBAAkB,KACvB,EAAK1M,SACJhlC,GAPDlG,KAAKkrC,U,mCAWPlrC,KAAKmrC,S,yCAOY3iB,EAASn2B,EAAGylD,GAC7B,IAAMlkD,EAASvB,EAAEgnB,cACX0+B,EAAU1lD,EAAE2lD,eAAiB3lD,EAAE4lD,YAAYH,GAE3CC,GAAWA,IAAYnkD,GAAY81B,IAAS91B,EAAQmkD,IACxDvvB,EAAQn2B,K,qCAKN2N,KAAKJ,MAAMsrC,KACblrC,KAAKmrC,OAELnrC,KAAKkrC,S,6BAKPlrC,KAAKF,SAAS,CAAEorC,MAAM,M,kCAGZrlC,EAAS9G,GACnB,OACE,kBAAC,EAAD,KACMA,EADN,CAEEmsC,KAAMlrC,KAAKJ,MAAMsrC,KACjB4K,OAAQ91C,KAAK2lB,WACb/xB,OAAQoM,OAEP6F,K,6BAML7F,KAAKF,SAAS,CAAEorC,MAAM,M,sCAItBwM,IAASQ,oCACPl4C,KACAA,KAAKm4C,SACLn4C,KAAKw3C,c,+BAIA,MAWHx3C,KAAKjB,MATP0mB,EAFK,EAELA,QACA5f,EAHK,EAGLA,QACAnC,EAJK,EAILA,SACAozC,EALK,EAKLA,OACA52C,EANK,EAMLA,QACAqO,EAPK,EAOLA,QACAwoC,EARK,EAQLA,WACAC,EATK,EASLA,YACGj4C,EAVE,qGAaAA,EAAMmH,aACNnH,EAAM43C,iBACN53C,EAAM63C,iBACN73C,EAAM83C,oBAEb,IAAMZ,EAAQlwB,IAAMqyB,SAASC,KAAK30C,GAC5B40C,EAAarC,EAAMl3C,MACnBw5C,EAAe,GAsDrB,OApDIv4C,KAAKJ,MAAMsrC,OACbqN,EAAa,oBAAsB1yC,EAAQ9G,MAAMyD,IAMnD+1C,EAAar4C,QAAUi2C,EAAsBmC,EAAWp4C,QAASA,GAE7Dq2C,EAAQ,QAAS9wB,KACnB8yB,EAAar4C,QAAUi2C,EACrBoC,EAAar4C,QACbF,KAAKk3C,eAILX,EAAQ,QAAS9wB,KACnB+yB,MACgB,UAAZ/yB,GACF,sOAMF8yB,EAAavB,YAAcb,EACzBmC,EAAWtB,YACXA,EACAh3C,KAAKq3C,iBAEPkB,EAAaxB,WAAaZ,EACxBmC,EAAWvB,WACXA,EACA/2C,KAAKu3C,iBAILhB,EAAQ,QAAS9wB,KACnB8yB,EAAahqC,QAAU4nC,EACrBmC,EAAW/pC,QACXA,EACAvO,KAAKm3C,mBAEPoB,EAAazB,OAASX,EACpBmC,EAAWxB,OACXA,EACA92C,KAAKo3C,oBAITp3C,KAAKm4C,SAAWn4C,KAAKy4C,YAAY5yC,EAAS9G,GAEnC82C,uBAAaI,EAAOsC,Q,8BA3NFxyB,IAAMpiB,WA+NnCszC,GAAe10C,UAAYA,GAC3B00C,GAAer0C,aArOM,CACnBi0C,qBAAqB,EACrBpxB,QAAS,CAAC,QAAS,UCpGrB,oC,4ZCIA,IAAIizB,EAAa3yB,IAAMwkB,cAAc,IAExBoO,EAAW,CACtBC,YAAa,+BACbC,IAAK,wBAGMC,EAAgB,kBAAMrN,qBAAWiN,IAEjCK,EAAc,SAAC,GAAyB,IAAvBr1C,EAAuB,EAAvBA,SAAU0rB,EAAa,EAAbA,OAChC4pB,EAAiBC,aAAY,SAAAr5C,GAAK,OAAIs5C,YAAkBt5C,MAE9D,OACE,kBAAC84C,EAAWlO,SAAZ,CAAqBp0C,MAAO,CAAE+iD,UAAW/pB,EAAQ4pB,mBAC9Ct1C,IAKM01C,EAAiB,SAAAz1C,GAC5B,OAAO,SAA0B5E,GAAO,MACA+5C,IAA9BK,EAD8B,EAC9BA,UAAWH,EADmB,EACnBA,eACnB,OACE,kBAACr1C,EAAD,KAAe5E,EAAf,CAAsBo6C,UAAWA,EAAWH,eAAgBA,OAKnDN,O,wtCC1Bf,IAAMn2C,EAAY,CAEhBqD,UAAW1E,IAAUuf,MAAM,CAAC,MAAO,QAAS,SAAU,SAGtD44B,YAAan4C,IAAUwB,UAAU,CAACxB,IAAUC,OAAQD,IAAUuB,SAE9D62C,aAAcp4C,IAAUwB,UAAU,CAACxB,IAAUC,OAAQD,IAAUuB,SAG/D82C,eAAgBr4C,IAAUwB,UAAU,CAACxB,IAAUC,OAAQD,IAAUuB,SAEjE+2C,gBAAiBt4C,IAAUwB,UAAU,CAACxB,IAAUC,OAAQD,IAAUuB,UAO9Dg3C,E,wcACK,MAUHz5C,KAAKjB,MARP6G,EAFK,EAELA,UACAyzC,EAHK,EAGLA,YACAC,EAJK,EAILA,aACAC,EALK,EAKLA,eACAC,EANK,EAMLA,gBACA95C,EAPK,EAOLA,UACAU,EARK,EAQLA,MACAsD,EATK,EASLA,SAGIg2C,E,+UAAa,CAAH,CACdnyC,IAAK8xC,EACL7xC,KAAM8xC,GACHl5C,GAGCu5C,EAAa,CACjBpyC,IAAKgyC,EACL/xC,KAAMgyC,GAGR,OACE,yBACE94C,KAAK,UACLhB,UAAWuO,IAAWvO,EAAW,UAAWkG,GAC5CxF,MAAOs5C,GAEP,yBAAKh6C,UAAU,gBAAgBU,MAAOu5C,IACtC,yBAAKj6C,UAAU,iBAAiBgE,S,8BA/BlBqiB,IAAMpiB,WAqC5B81C,EAAQl3C,UAAYA,EACpBk3C,EAAQ72C,aA1Ca,CACnBgD,UAAW,SCtBb,mC,q9BCOe,SAAeg0C,EAA9B,oC,qDAAe,WACb5c,EACA6c,GAFa,yGAKXC,EAOE9c,EAPF8c,2BACAC,EAME/c,EANF+c,qCACAC,EAKEhd,EALFgd,uCACAC,EAIEjd,EAJFid,sCACAC,EAGEld,EAHFkd,+BACAC,EAEEnd,EAFFmd,iCACAC,EACEpd,EADFod,gCAXW,kBAcN,IAAI7nD,SAAQ,SAACC,EAASC,GAC3B,IAAI4nD,EACJ,GAAIC,EAAmB1F,WAAWkF,KAChCO,EAAQC,EAAmBtkD,IAAI8jD,IAG7B,OAAOtnD,EAAQ6nD,GAKnB,IAAM/nD,EAAW,CACfioD,EACEV,EACAK,EACAH,GAEFQ,EACEV,EACAM,EACAH,GAEFO,EACEV,EACAO,EACAH,IAIJ1nD,QAAQiD,IAAIlD,GAAU8B,MACpB,YAIM,aAHJ8lD,EAGI,KAFJC,EAEI,KADJC,EACI,KAEJE,EAAmBE,IAAI,CACrBN,iCACAC,mCACAC,kCACAN,+BAGF9c,EAASkd,+BAAiCA,EAC1Cld,EAASmd,iCAAmCA,EAC5Cnd,EAASod,gCAAkCA,EAE3C5nD,WA7DO,2C,uMAsEf,IAAM8nD,EAAqB,CACzBvN,MAAO,EACP0N,OAAQ,MACRC,QAAS,GACT9F,WAAY,SAASkF,GACnB,MACwC,iBAA/BA,GACPA,EAA2BppD,OAAS,GAGxCsF,IAAK,SAAS8jD,GACZ,IAAIO,EAAQ,KAWZ,OAVIr6C,KAAK06C,QAAQ7pD,eAAeipD,KAC9BO,EAAQr6C,KAAK06C,QAAQZ,GAEjBl8B,KAAK+8B,MAAQN,EAAM3iD,KAAOsI,KAAKy6C,gBAE1Bz6C,KAAK06C,QAAQZ,GACpB95C,KAAK+sC,QACLsN,EAAQ,OAGLA,GAETG,IAAK,SAASH,GACZ,GAAIr6C,KAAK40C,WAAWyF,EAAMvH,KAAM,CAC9B,IAAIgH,EAA6BO,EAAMvH,KACyB,IAA5D9yC,KAAK06C,QAAQ7pD,eAAeipD,IAC9B95C,KAAK+sC,QAEPsN,EAAM3iD,KAAOkmB,KAAK+8B,MAClB36C,KAAK06C,QAAQZ,GAA8BO,KAMjD,SAASE,EAAiBV,EAAQe,EAA6BC,GAC7D,IAAMC,EAAgBD,EAAc,GAAKA,EAAc,GAAK,MACtDE,EAAOF,EAAc,GAErBG,EAA+B,SAAAC,GAMnC,IALA,IAAMC,EAAqB,KAATH,EAChB,IAAII,YAAYF,GAChB,IAAIG,WAAWH,GACXI,EAAM,GAEH7qD,EAAI,EAAGA,EAAIsqD,EAAetqD,IACjC6qD,EAAI7qD,GAAK0qD,EAAU1qD,GAGrB,OAAO6qD,GAGT,GAAIT,EAA4BU,YAAa,CAC3C,IAAIC,EAAMX,EAA4BU,YAIG,IAArCzB,EAAO2B,SAAS3hC,QAAQ,UAAmB0hC,EAAIztC,SAAS,WAC1DytC,EAAMA,EAAIpoC,QAAQ,OAAQ,UAG5B,IAAMic,EAAS,CACbwiB,IAAKiI,EAAO2B,SACZ9uB,QAAST,IAASO,uBAAuBqtB,GACzC4B,iBAAkB/W,IAAauM,sBAC/ByK,aAAc,CAAClJ,gBAGX/9B,EAAU,CACd6mC,YAAaC,GAGf,OALiB,IAAII,IAAIC,eAAexsB,GAMrCysB,iBAAiBpnC,GACjBrgB,MAAK,SAAA7C,GAAM,OAAIA,EAAO,MACtB6C,KAAK4mD,GACH,GAAIJ,EAA4BkB,aAAc,CACnD,IAAMC,EAAmBC,KAAKpB,EAA4BkB,cACpDb,EAAcgB,YAAOF,GAE3B,OAAO,IAAIxpD,SAAQ,SAAAC,GACjBA,EAAQwoD,EAA6BC,OAGvC,OAAO1oD,QAAQC,QACbwoD,EAA6BJ,ICpKpB,SAASsB,EAAcC,GAIpC,IAHA,IAAMC,EAAW,IAAIhB,WAAWe,GAC1BjB,EAAY,IAAIE,WAAW,EAAIgB,EAAS1rD,QAErC2rD,EAAY,EAAGA,EAAYnB,EAAUxqD,OAAQ2rD,IAAa,CACjE,IAAMC,EAAWD,EAAY,EACvBE,EAAehpC,KAAKw9B,MAAMsL,EAAY,GAC5CnB,EAAUmB,GACR,IAAMD,EAASG,GAAiB,GAAKD,IAAcA,GAGvD,OAAOpB,E,4TCHM,SAAesB,EAA9B,oC,iDAAe,WAAgCxf,EAAU6c,GAA1C,+FACP4C,EAAsB,GACtBC,EAAkB,GAFX,kBAIN,IAAInqD,SAAQ,SAACC,EAASC,GAC3B,IAAK,IAAIkqD,EAAe,EAAMA,GAAgB,GAAMA,GAAgB,EAAM,CACxE,IAAIC,EAAW,KAAH,OAAQD,EAAa5wB,SAAS,KAElB,IAApB6wB,EAASlsD,SACXksD,EAAW,MAAH,OAASD,EAAa5wB,SAAS,MAGzC,IAAM8wB,EAAiB,GAAH,OAAMD,EAAN,QAEpB,GAAI5f,EAAS6f,IAAmB7f,EAAS6f,GAAgBf,aAAc,CACrE,IAAMC,EAAmBC,KAAKhf,EAAS6f,GAAgBf,cACjDb,EAAcgB,YAAOF,GAE3B/e,EAAS6f,GAAkBX,EAAcjB,QAEzCje,EAAS6f,IACT7f,EAAS6f,GAAgBvB,aAEzBmB,EAAoBzrD,KAClB8rD,EAAgB9f,EAAS6f,GAAiBhD,IAE5C6C,EAAgB1rD,KAAK6rD,IAErB7f,EAAS6f,IACT7f,EAAS6f,aAA2BE,cAEpC/f,EAAS6f,GAAkBX,EAAclf,EAAS6f,KAIlDJ,EAAoB/rD,OACtB6B,QAAQiD,IAAIinD,GAAqBroD,MAAK,SAAA4oD,GACpC,IAAK,IAAIxsD,EAAI,EAAGA,EAAIwsD,EAAQtsD,OAAQF,IAClCwsC,EAAS0f,EAAgBlsD,IAAMwsD,EAAQxsD,GAGzCgC,OAGFA,QA5CS,4C,+BAiDAsqD,E,qFAAf,WAA+B7pD,EAAK4mD,GAApC,qGACUyB,EAAgBroD,EAAhBqoD,YAEJC,EAAMD,EAI+B,IAArCzB,EAAO2B,SAAS3hC,QAAQ,UAAmB0hC,EAAIztC,SAAS,WAC1DytC,EAAMA,EAAIpoC,QAAQ,OAAQ,UAGtBic,EAAS,CACbwiB,IAAKiI,EAAO2B,SACZ9uB,QAAST,IAASO,uBAAuBqtB,GACzC4B,iBAAkB/W,IAAauM,sBAC/ByK,aAAc,CAAClJ,gBAEXyK,EAAW,IAAItB,IAAIC,eAAexsB,GAClC3a,EAAU,CACd6mC,YAAaC,GAnBjB,kBAsBS0B,EACJpB,iBAAiBpnC,GACjBrgB,MAAK,SAAA7C,GAAM,OAAIA,EAAO,MACtB6C,KAAK8nD,IAzBV,4C,sBCzDA,IAQegB,EARK,SAAAhJ,GAClB,OAAI3uC,MAAMC,QAAQ0uC,GACTA,EAAIvzC,KAAI,SAAAw8C,GAAC,YAAW9nD,IAAN8nD,EAAkBC,OAAOD,GAAKA,UAEpC9nD,IAAR6+C,EAAoBkJ,OAAOlJ,GAAOA,G,seCsevCxmB,EAAmB,I,WAjevB,c,4FAAc,SAEZ/8B,OAAOmF,eAAekK,KAAM,UAAW,CACrC+yC,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO,IAAIwjC,MAEbjpC,OAAOmF,eAAekK,KAAM,gBAAiB,CAC3C+yC,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO,IAAIwjC,MAEb55B,KAAKq9C,SAAW,G,+FAGAC,G,6HAAkC7oC,E,+BAAU,GAIxD6oC,aAA4CP,aACxCQ,EAAYC,aAAaC,SAASH,GAExCI,EAAmBH,EAAUI,MAE7BD,EAAmBJ,EAQnBM,OAD4CvoD,IAA1CqoD,EAAgB,kBACGG,IAAM3tD,KAAK4tD,oBAAoBC,kBAClDL,GAGmBA,EAIrBpoC,G,EAGEsoC,GAHFtoC,iBACAooB,E,EAAAA,kBACAE,E,EAAAA,eAGF59B,KAAKg+C,yBAAyB1oC,EAAkBooC,GAC1CxnC,EAAQlW,KAAKi+C,kBAAkB3oC,GAC/BunB,EAAS78B,KAAKk+C,4BAA4BhoC,EAAOwnB,GACjDV,EAAWh9B,KAAKm+C,8BAA8BthB,EAAQe,GAE5DjtC,OAAOqhC,OAAOgL,EAAU4gB,G,UAElB59C,KAAKo+C,gCAAgCphB,EAAUvoB,EAAQolC,Q,iCAEtD7c,G,sIAGQoB,EAASigB,GAKxBr+C,KAAKs+C,cAAcpjB,IAAIkD,EAASigB,K,+CAGT/oC,EAAkBipC,GACpCv+C,KAAKq9C,SAAS/nC,KACjBtV,KAAKq9C,SAAS/nC,GAAoBipC,K,sCAItBjpC,GACd,OAAOtV,KAAKq9C,SAAS/nC,K,wCAGLA,GAChB,IAAM4L,EAAUlhB,KAAKkhB,QAEjBhL,EAAQgL,EAAQlrB,IAAIsf,GAOxB,OALKY,IACHA,EAAQ,CAAE2mB,OAAQ,IAAIjD,KACtB1Y,EAAQga,IAAI5lB,EAAkBY,IAGzBA,I,kDAGmBA,EAAOwnB,GACjC,IAAIb,EAAS3mB,EAAM2mB,OAAO7mC,IAAI0nC,GAO9B,OALKb,IACHA,EAAS,CAAE2hB,UAAW,IAAI5kB,KAC1B1jB,EAAM2mB,OAAO3B,IAAIwC,EAAmBb,IAG/BA,I,oDAGqBA,EAAQe,GACpC,IAAIZ,EAAWH,EAAO2hB,UAAUxoD,IAAI4nC,GAOpC,OALKZ,IACHA,EAAW,GACXH,EAAO2hB,UAAUtjB,IAAI0C,EAAgBZ,IAGhCA,I,sFAG6BA,EAAU6c,G,gGACxC2C,EAAiBxf,EAAU6c,G,UAEU,kBAAvC7c,EAASyhB,0B,gCACL7E,EAAiC5c,EAAU6c,G,8HAIxCzb,GACX,IAAMigB,EAAOr+C,KAAK0+C,oBAAoBtgB,GAEtC,GAAKigB,EAAL,CAHoB,IAOZ/oC,EAAwD+oC,EAAxD/oC,iBAAkBooB,EAAsC2gB,EAAtC3gB,kBAAmBE,EAAmBygB,EAAnBzgB,eAE7C,OAAO59B,KAAK2+C,iBACVrpC,EACAooB,EACAE,M,0BAIAmF,EAAO3E,GAAwC,IAA/B3pB,EAA+B,uDAArB,CAAEmqC,UAAU,GAClC5hB,EAAWh9B,KAAK6+C,aAAazgB,GAEnC,OAAI2E,IAAU+b,EACL9hB,EAGFh9B,KAAK++C,mBAAmBhc,EAAO/F,EAAUvoB,K,6BAG3CsuB,EAAO3E,EAAS3pB,GACrB,OAAOzU,KAAKhK,IAAI+sC,EAAO3E,EAAS3pB,K,kCAGtB2pB,GACV,OAAOp+B,KAAKhK,IAAI8oD,EAAU1gB,K,yCAI1B4gB,EACAhiB,GAGA,GADA,wDACKA,EAKL,OAAIA,EAASgiB,GACJhiB,EAASgiB,GAIXh/C,KAAKi/C,kCACVD,EACAhiB,K,wDAI8BkiB,EAAoBliB,GACpD,IAAInJ,EAEJ,OAAQqrB,GACN,KAAKC,EAAuBC,sBAA5B,IAGMC,EACAC,EAHIC,EAA2BviB,EAA3BuiB,WAAYC,EAAexiB,EAAfwiB,WAKhBD,IACFF,EAAaI,IAAYC,QAAQH,IAG/BC,IACFF,EAAaG,IAAYE,QAAQH,IAGnC3rB,EAAW,CACT+rB,SAAU5iB,EAAS9P,SACnB2yB,kBAAmB7iB,EAASU,kBAC5BoiB,aAAc9iB,EAAS+iB,aACvBC,iBAAkBhjB,EAAS1nB,iBAC3B+pC,aACAC,cAEF,MACF,KAAKH,EAAuBc,qBAC1BpsB,EAAW,CACTqsB,WAAYljB,EAASmjB,WACrBC,YAAapjB,EAASqjB,YACtBC,cAAetjB,EAASujB,eAE1B,MACF,KAAKpB,EAAuBqB,mBAA5B,IAQMC,EACAC,EAEAC,EACAC,EAXIC,EAA4B7jB,EAA5B6jB,wBAKAC,EC9ND,SAAoC9jB,GAOjD,IAgBE8jB,EAOE9jB,EAPF8jB,aACAC,EAME/jB,EANF+jB,mBACAC,EAKEhkB,EALFgkB,YACAC,EAIEjkB,EAJFikB,4BACAC,EAGElkB,EAHFkkB,mCACAC,EAEEnkB,EAFFmkB,yCACAC,EACEpkB,EADFokB,4BAEIC,EAxBmC,CACvC,4BACA,8BACA,gCACA,8BACA,gCACA,8BACA,gCACA,+BACA,iCACA,+BACA,iCACA,gCAYoDvzC,SAASkzC,GAEzDM,EACY,iBAMlB,GAAID,IAAiBN,EAInB,MAAO,CACLD,eACAvtD,KAXO,UAYP8tD,gBAEG,GACLP,GACAC,GACAD,IAAiBC,EAIjB,MAAO,CACLD,eACAvtD,KArBQ,WAsBR8tD,gBAEG,GACLP,GACAC,GACAD,IAAiBC,EAMjB,MAAO,CACLD,eACAvtD,KApCU,aAqCV8tD,eACAJ,8BACAC,sCAEG,IAAKJ,GAAgBC,EAAoB,CAC9C,IAAIQ,EAA8BR,EAclC,OAbII,EAIFI,EAA8BR,EAAmBpgD,KAC/C,SAAA6gD,GAAY,OAAIA,EAAeL,KAGjC9pD,IAAIE,KACF,mGAIG,CACLupD,aAAcS,EACdF,gBAEG,GACLD,GACuC,WAAvC,EAAOA,GAKP,MAAO,CACLN,aAHqB,CAAkB,GADEM,EAAnCK,eACsD,GADnBL,EAAnBM,iBAMnB,GACLN,GACA77C,MAAMC,QAAQ47C,IACdA,EAA4B1wD,OAAS,EAErC2G,IAAIC,KACF,2HAEG,IAAqB,IAAjB+pD,IAA2BN,EAGpC,MAAO,CACLD,eACAvtD,KAAM+tD,EACND,gBAIFhqD,IAAIE,KACJ,uGDiG6BoqD,CAA2B3kB,GAA5C8jB,aAQJA,IACFL,EAAkBvD,EAAY4D,EAAa,IAC3CJ,EAAqBxD,EAAY4D,EAAa,KAG5CD,IACFF,EAAazD,EAAY2D,EAAwBzpD,MAAM,EAAG,IAC1DwpD,EAAgB1D,EAAY2D,EAAwBzpD,MAAM,EAAG,KAG/Dy8B,EAAW,CACT+tB,oBAAqB5kB,EAAS6kB,oBAC9BC,KAAM9kB,EAAS19B,KACfyiD,QAAS/kB,EAASx9B,QAClBwiD,wBAAyB9E,EAAY2D,GACrCF,aACAC,gBACAqB,qBAAsB/E,EAAYlgB,EAASklB,sBAC3CC,eAAgBjF,EAAYlgB,EAASolB,gBACrCC,cAAenF,EAAYlgB,EAASslB,eACpCd,aAActE,EAAY4D,GAC1BL,kBACAC,sBAEF,MACF,KAAKvB,EAAuBoD,mBAC1B1uB,EAAW,CACT2uB,gBAAiBxlB,EAASylB,gBAC1BC,0BAA2B1lB,EAASyhB,0BACpCqD,KAAM9kB,EAAS19B,KACfyiD,QAAS/kB,EAASx9B,QAClBmjD,cAAe3lB,EAAS4lB,cACxBC,WAAY7lB,EAAS8lB,WACrBC,QAAS/lB,EAASgmB,QAClBC,oBAAqBjmB,EAASkmB,oBAC9BC,oBAAqBnmB,EAASomB,oBAC9BC,iBAAkBrmB,EAASsmB,iBAC3BC,mBAAoBvmB,EAASwmB,mBAC7BC,kBAAmBzmB,EAAS0mB,kBAC5BC,qCACE3mB,EAAS+c,qCACX6J,uCACE5mB,EAASgd,uCACX6J,sCACE7mB,EAASid,sCACX6J,+BACE9mB,EAASkd,+BACX6J,iCACE/mB,EAASmd,iCACX6J,gCACEhnB,EAASod,iCAGb,MACF,KAAK+E,EAAuB8E,eAA5B,IACQC,EAA8BlnB,EAA9BknB,aAAcC,EAAgBnnB,EAAhBmnB,YAEdC,EAAe7+C,MAAMC,QAAQ0+C,GAC/BA,EACA,CAACA,GACCG,EAAc9+C,MAAMC,QAAQ2+C,GAC9BA,EACA,CAACA,GAELtwB,EAAW,CACTuwB,aAAclH,EAAYkH,GAC1BC,YAAanH,EAAYmH,IAG3B,MACF,KAAKlF,EAAuBmF,oBAC1B,IAAMC,EAAerH,EAAYlgB,EAASwnB,cAE1C3wB,EAAW,CACT4wB,iBAFuBvH,EAAYlgB,EAAS0nB,kBAG5CH,eACAI,YAAa3nB,EAAS4nB,aAExB,MACF,KAAKzF,EAAuB0F,kBAC1BhxB,EAAW,CACTixB,YAAa9nB,EAASgkB,YACtB+D,eAAgB/nB,EAASY,gBAE3B,MACF,KAAKuhB,EAAuB6F,mBAA5B,IACUC,EAA2CjoB,EAA3CioB,uCAER,GAAIA,EAAwC,CAC1C,IAAMC,EAAiC3/C,MAAMC,QAC3Cy/C,GAEEA,EAAuC,GACvCA,EAGFE,EAGED,EAHFC,6BACAC,EAEEF,EAFFE,sBACAC,EACEH,EADFG,qBAUFxxB,EAAW,CACTyxB,wBAR8B,CAC9BC,6BAA8B9F,IAAYE,QACxCwF,GAEFK,sBAAuBJ,EACvBK,qBAAsBJ,IAO1B,MACF,KAAKlG,EAAuBuG,qBAG1B,IAFA,IAAMC,EAAW,GAGXhJ,EAAe,EACnBA,GAAgB,GAChBA,GAAgB,EAChB,CACA,IAAIC,EAAW,KAAH,OAAQD,EAAa5wB,SAAS,KAElB,IAApB6wB,EAASlsD,SACXksD,EAAW,MAAH,OAASD,EAAa5wB,SAAS,MAGzC,IACM65B,EAAc5oB,EADG,GAAH,OAAM4f,EAAN,SAGpB,GAAKgJ,EAAL,CAIA,IAAMC,EAAiB,GAAH,OAAMjJ,EAAN,QACdkJ,EAAoB,GAAH,OAAMlJ,EAAN,QACjBmJ,EAAc,GAAH,OAAMnJ,EAAN,QACXoJ,EAAmB,GAAH,OAAMpJ,EAAN,QAChBqJ,EAAwB,GAAH,OAAMrJ,EAAN,QACrBsJ,EAAkB,GAAH,OAAMtJ,EAAN,QACfuJ,EAAa,GAAH,OAAMvJ,EAAN,QACVwJ,EAAa,GAAH,OAAMxJ,EAAN,QACVyJ,EAA0B,GAAH,OAAMzJ,EAAN,QACvB0J,EAAgBtpB,EAASgpB,GAEzBngD,EAAU,CACdi8C,KAAM9kB,EAAS6oB,GACf9D,QAAS/kB,EAAS8oB,GAClBvyD,KAAMypC,EAAS+oB,GACfh/C,EAAGu/C,EAAc,GACjBr/C,EAAGq/C,EAAc,GACjBC,UAAWX,EACXpqC,YAAawhB,EAASipB,GACtBnkD,MAAOk7B,EAASkpB,GAChBM,QAASxpB,EAASmpB,GAClBM,QAASzpB,EAASopB,GAClBM,qBAAsB1pB,EAASqpB,IAGjCV,EAAS30D,KAAK6U,IAGhBguB,EAAW,CACT8xB,YAGF,MAEF,KAAKxG,EAAuBwH,eAA5B,IAGMC,EAFIjkC,EAAgBqa,EAAhBra,YAGJA,IACFikC,EAAcjkC,EAAY2K,YAG5BuG,EAAW,CACT+yB,cACAC,UAAW7pB,EAASta,WAGtB,MAEF,KAAKy8B,EAAuB2H,qBAC1BjzB,EAAW,CACTkzB,eAAgB/pB,EAASY,eACzBopB,eAAgBhqB,EAASiqB,eACzBC,sBAAuBlqB,EAASmqB,sBAChCC,2BAA4BpqB,EAASqqB,2BACrCC,4BAA6BtqB,EAASuqB,6BAGxC,MACF,KAAKpI,EAAuBqI,qBAC1B3zB,EAAW,CACT4zB,iBAAkBzqB,EAASloB,iBAC3B4yC,UAAW1qB,EAASnoB,UACpB8yC,UAAW3qB,EAAS4qB,UACpBC,gBAAiB7qB,EAASva,iBAG5B,MACF,KAAK08B,EAAuB2I,YAC1Bj0B,EAAW,CACTk0B,UAAW/qB,EAASgrB,WAM1B,OAAOn0B,I,uCAGQve,EAAkBooB,EAAmBE,GACpD,IAAM1nB,EAAQlW,KAAKkhB,QAAQlrB,IAAIsf,GAE/B,GAAKY,EAAL,CAIA,IAAM2mB,EAAS3mB,EAAM2mB,OAAO7mC,IAAI0nC,GAEhC,GAAKb,EAML,OAFiBA,EAAO2hB,UAAUxoD,IAAI4nC,M,0CAKpBQ,GAClB,GAAIA,EAAQtwB,SAAS,WAAY,CAC/B,IACMm6C,EADkB7pB,EAAQnyB,MAAM,YAAY,GACbA,MAAM,KAE3C,MAAO,CACLqJ,iBAAkB2yC,EAAa,GAC/BvqB,kBAAmBuqB,EAAa,GAChCrqB,eAAgBqqB,EAAa,IAGjC,GAAI7pB,EAAQtwB,SAAS,yBAA0B,CAC7C,IAAMo6C,EAAKC,IAAYC,MAAMhqB,GAE7B,MAAO,CACL9oB,iBAAkB4yC,EAAGG,SACrB3qB,kBAAmBwqB,EAAGI,UACtB1qB,eAAgBsqB,EAAGK,WAIrB,OAAOvoD,KAAKs+C,cAActoD,IAAIooC,Q,iCAS9B+gB,GAFSzxB,MAEgB,CAE7B0xB,sBAAuB,sBACvBa,qBAAsB,qBACtBO,mBAAoB,mBACpB+B,mBAAoB,mBACpB0B,eAAgB,eAChBK,oBAAqB,oBACrBO,kBAAmB,kBACnBG,mBAAoB,mBACpBU,qBAAsB,qBAGtBiB,eAAgB,gBAChBG,qBAAsB,qBACtBU,qBAAsB,qBACtBM,YAAa,eAGThJ,EAAW,Y,mCE1fO0J,EAClBC,E,mBCFS,SAASD,GAMtB,IAAIE,EAAoB,GAMtBC,EAA4B,KAM5BC,EAAuB,GAOvBC,GAAwB,EAaxBC,EAAiBN,EAAU53D,UAAUm4D,UAUvC,SAASC,EAAWC,EAAWr7C,EAAWvb,GAGxC,GAFW2N,KAEDkpD,UAMV,GAAc,WAAV72D,EAAEkB,KAAmB,CACE,IAArB01D,EAAUv4D,QAAgBm4D,GAC5BM,IAGF,IAAK,IAAI34D,EAAI,EAAGA,EAAIod,EAAUld,SAAUF,EACtC44D,EAAWx7C,EAAUpd,IAEvB44D,EAAWH,OAIQ,SAAV52D,EAAEkB,MAAmBq1D,EAAqBl4D,OAAS,GAC5Dy4D,SAlBAL,EAAez3D,MAHN2O,KAGkByI,WA4B/B,SAAS2gD,EAAW1yD,GAElB,IAAK,IAAIlG,EAAI,EAAGA,EAAIo4D,EAAqBl4D,SAAUF,EACjD,GAAIo4D,EAAqBp4D,KAAOkG,EAC9B,OAIJkyD,EAAqB53D,KAAK0F,GAEP,IAAfA,EAAIhG,SACNm4D,GAAwB,GAU5B,SAASM,IACPT,EAAkB13D,KAAK43D,GACvBA,EAAuB,GACvBC,GAAwB,EACxBQ,IAqCF,SAASA,IACHV,KA1BN,SAA4Bl7C,GAC1B,IAAK,IAAIjd,EAAI,EAAGA,EAAIid,EAAS/c,SAAUF,EACrCid,EAASjd,GAAG2wB,MAAK,SAASpa,EAAGE,GAE3B,OAAIF,EAAErW,OAAS,GAAkB,IAAbuW,EAAEvW,QACZ,EACc,IAAbqW,EAAErW,QAAgBuW,EAAEvW,OAAS,EAC/B,EAKFqW,EAAIE,EAAI,GAAK,KAGtBwG,EAASjd,GAAKid,EAASjd,GAAG0b,KAAK,KAY/Bo9C,CAAmBZ,GACnBC,EAA0BD,IAI5BA,EAAoB,GACpBC,EAA4B,KAC5BC,EAAuB,GAuBzBJ,EAAU53D,UAAUyd,OAAS,SAASlI,GACpC,IAAIojD,EAAOvpD,KACXupD,EAAKL,WAAY,EACjBP,EAA4B,WAC1BY,EAAKL,WAAY,EACjB/iD,EAAS9U,MAAMk4D,EAAM9gD,aAUzB+/C,EAAU53D,UAAU44D,WAAa,WACpBxpD,KACNkpD,WAAY,GASnBV,EAAU53D,UAAU6d,eAAiB,WACxBzO,KACNkpD,WAAY,GAGnBV,EAAU53D,UAAUm4D,UAAY,WAC9B,IAAIQ,EAAOvpD,KACXgpD,EAAW33D,MAAMk4D,EAAM9gD,YAGzB+/C,EAAUiB,OCpNZC,CAAalB,KFGWA,EEFZA,IFGNC,EAAwBD,EAAU53D,UAAU+4D,aAEhDnB,EAAU53D,UAAU+4D,aAAe,SAASt3D,EAAGwW,EAAS+gD,GAGtD,QAFW5pD,KAEF6pD,QAIFpB,EAAsB33D,KANlBkP,KAM6B3N,EAAGwW,EAAS+gD,IAGtDpB,EAAU53D,UAAU4d,MAAQ,WACfxO,KACN6pD,QAAS,GAGhBrB,EAAU53D,UAAU0d,QAAU,WACjBtO,KACN6pD,QAAS,GAGhBrB,EAAUiB,OEvBGjB,MAAf,G,6BCPA,sCAAMsB,EAAuB,CAC3BC,WAAY,cACZC,yBAA0B,0BAC1BC,yBAA0B,0BAC1BC,0BAA2B,2BAC3BC,eAAgB,gBAChBC,kBAAmB,mBACnBC,aAAc,e,+BCPhB,IAEMC,EAAoB,IAF1B,OAE8BC,GAsBf,KACb/P,IArBF,SAAa/d,GACX6tB,EAAkBE,OAAO/tB,IAqBzBzmC,IAlBF,SAAagqD,GACX,OAAOsK,EAAkBG,OAAO,CAAEzK,sBAkBlCxqD,IAfF,SAAaif,GACX,OAAO61C,EAAkB90D,IAAIif,IAe7Bi2C,OAZF,SAAgB1K,GACdsK,EAAkBI,OAAO,CAAE1K,sBAY3B2K,MATF,WACEL,EAAkBM,e,i2BClBb,IAAMC,EAAb,YAIE,WAAY36D,EAAM2sC,EAAQ3mB,EAAO48B,GAAK,a,4FAAA,UACpC,wBAAM5iD,EAAM4iD,KACP2W,KAAK5sB,EAAQ3mB,GAFkB,E,UAJxC,O,kOAAA,M,EAAA,G,EAAA,4BASO2mB,EAAQ3mB,GACX,IAAM8mB,EAAWh9B,KAAK2yC,UAGtBhiD,OAAO8iD,iBAAiBzzC,KAAM,CAC5B8qD,gBAAiB,CACf/X,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO4mC,EAASY,gBAElBmtB,OAAQ,CACNhY,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO8f,GAET80C,QAAS,CACPjY,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAOymC,GAETouB,UAAW,CACTlY,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO4mC,GAETkuB,OAAQ,CACNnY,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAOzF,OAAO8F,OAAO,WA1C7B,kCAgDcu9C,EAAez5B,EAAc4wC,GAEvC,GAAInX,KAAiBh0C,KAAKkrD,SAA0B,IAAhBC,EAClC,OAAOnrD,KAAKkrD,OAAOlX,GAGrB,IAGIoX,EAHEC,EAAerrD,KAAKirD,UAAUp3B,SAYpC,OARImgB,KAAiBqX,EACnBD,EAAWC,EAAarX,GACfA,KAAiBh0C,KAAKgrD,QAC/BI,EAAWprD,KAAKgrD,QAAQhX,GACfA,KAAiBh0C,KAAK+qD,SAC/BK,EAAWprD,KAAK+qD,OAAO/W,SAGR,IAAboX,GAEFprD,KAAKkrD,OAAOlX,GAAiBoX,EACtBA,GAGF7wC,IAxEX,gCA4EYy5B,GACR,OACEA,KAAiBh0C,KAAKirD,UAAUp3B,UAChCmgB,KAAiBh0C,KAAKgrD,SACtBhX,KAAiBh0C,KAAK+qD,SAhF5B,iCAqFa3W,EAAOkX,GAMhB,OAJsB,OAAlBtrD,KAAK0zC,WACP1zC,KAAK0zC,SAAWrV,YAAWr+B,KAAK2yC,UAAWyB,EAAOkX,IAG7CtrD,KAAK0zC,c,2BA3FhB,GAA0C9f,K,+yBCAnC,IAAM23B,EAAb,YAIE,WAAYr7D,EAAMgmB,EAAO48B,GAAK,a,4FAAA,UAC5B,wBAAM5iD,EAAM4iD,KACP2W,KAAKvzC,GAFkB,E,UAJhC,O,kOAAA,M,EAAA,G,EAAA,4BASOA,GAAO,WACJ2mB,EAAS78B,KAAK2yC,UAGpBhiD,OAAOmF,eAAekK,KAAM,qBAAsB,CAChD+yC,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAOymC,EAAOa,oBAIhBb,EAAO2hB,UAAU3wC,SAAQ,SAAAmvB,GACvB,EAAKwuB,YAAY,IAAIX,EAAqB7tB,EAAUH,EAAQ3mB,Y,2BAtBlE,GAAwCm+B,K,+yBCAjC,IAAMoX,EAAb,YAIE,WAAYv7D,EAAM4iD,GAAK,a,4FAAA,UACrB,wBAAM5iD,EAAM4iD,KACP2W,OAFgB,E,UAJzB,O,kOAAA,M,EAAA,G,EAAA,8BASS,WACCvzC,EAAQlW,KAAK2yC,UAGnBhiD,OAAOmF,eAAekK,KAAM,oBAAqB,CAC/C+yC,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO8f,EAAMZ,mBAIfY,EAAM2mB,OAAOhvB,SAAQ,SAAAgvB,GACnB,EAAK6uB,UAAU,IAAIH,EAAmB1uB,EAAQ3mB,Y,2BAtBpD,GAAuCqjB,KCKjC1F,EAAW,CACfgf,aACAtZ,kBACA8a,mBACAzgB,qBACA63B,oBACAF,qBACAV,wBAaah3B,O,0GCnBf,SAAS83B,EAA4BnN,GACnC,IAAKA,EAAU9tD,OACb,MAAO,CAAE0F,OAAO,GAGlB,IAAM4lC,EAAgBwiB,EAAU,GAAG7L,UAAU9e,SAEvC3G,EAAW8O,EAAc9O,SACzB0+B,EAAe5vB,EAAc6vB,eAAiB,EAEpD,OAAKC,EAAwBh+C,SAASof,KAKjC0+B,GAAqC,IAArBpN,EAAU9tD,QAI3Bk7D,EAeG,CAAEx1D,OAAO,EAAO21D,qBADM,CAACjC,IAAqBkC,cAWrD,SAA4BxN,GAa1B,IAZA,IAAM5nD,EAAI4nD,EAAU9tD,OACdu7D,EAAazN,EAAU,GAAG7L,UAAU9e,SACpCq4B,EAAiBD,EAAW3sD,KAC5B6sD,EAAoBF,EAAWzsD,QAC/B4sD,EAA4BH,EAAWxJ,gBACvC4J,EAA+BJ,EAAWpL,wBAE1CkL,EAAuB,GAKpBO,EAAK,EAAGA,EAAK11D,IAAK01D,EAAI,CAC7B,IAAMtvB,EAAWwhB,EAAU8N,GAAI3Z,UAAU9e,SAEvCv0B,EAIE09B,EAJF19B,KACAE,EAGEw9B,EAHFx9B,QACAijD,EAEEzlB,EAFFylB,gBACA5B,EACE7jB,EADF6jB,wBAaF,GAVIvhD,IAAS4sD,GAAkB1sD,IAAY2sD,EACzCJ,EAAqB/6D,KAAK84D,IAAqBE,0BACtCvH,IAAoB2J,EAC7BL,EAAqB/6D,KAAK84D,IAAqBG,0BAE9CsC,EAAa1L,EAAyBwL,IAEvCN,EAAqB/6D,KAAK84D,IAAqBI,2BAGb,IAAhC6B,EAAqBr7D,OACvB,OAsGN,SAAsB8tD,GAEpB,IADA,IAAM5nD,EAAI4nD,EAAU9tD,OACX47D,EAAK,EAAGA,EAAK11D,IAAK01D,EAAI,CAC7B,IAAME,EAA0BhO,EAAU8N,GAAI3Z,UAAU9e,SACxD,GACG24B,QAC2Bn3D,IAA5Bm3D,GACCA,EAAwBtK,2BACwB7sD,IAAjDm3D,EAAwBtK,qBAI1B,IAAK,IAAIuK,EAAKH,EAAK,EAAGG,EAAK71D,IAAK61D,EAAI,CAClC,IAAMC,EAAmBlO,EAAUiO,GAAI9Z,UAAU9e,SACjD,GACG64B,QACoBr3D,IAArBq3D,GACCA,EAAiBxK,2BACwB7sD,IAA1Cq3D,EAAiBxK,sBAMjBqK,EACEC,EAAwBtK,qBACxBwK,EAAiBxK,sBAGnB,OAAO,GAKb,OAAO,GAnIHyK,CAAanO,IACfuN,EAAqB/6D,KAAK84D,IAAqBC,YAGjD,MAAO,CACL3zD,MAAuC,IAAhC21D,EAAqBr7D,OAC5Bq7D,wBAlEOa,CAAmBpO,GAXnB,CAAEpoD,OAAO,GA6MpB,SAASm2D,EAAaM,EAAMC,GAC1B,QAAaz3D,IAATw3D,QAAgCx3D,KAATy3D,EAI3B,OACEv5C,KAAKw5C,IAAIF,EAAK,GAAKC,EAAK,IAAME,GAC9Bz5C,KAAKw5C,IAAIF,EAAK,GAAKC,EAAK,IAAME,GAC9Bz5C,KAAKw5C,IAAIF,EAAK,GAAKC,EAAK,IAAME,EAKlC,IAAMC,EAAmB,GACnBD,EAAe,IAUrB,SAASE,EAAiBC,EAASC,GAIjC,KAFE75C,KAAKw5C,IAAII,EAAUC,GAAkBA,EAAiBH,GAExD,CAIA,IAAMI,EAA2BF,EAAUC,EAErCE,EAAmB/5C,KAAKC,MAAM65C,GAKpC,OAFE95C,KAAKw5C,IAAII,EAAUG,EAAmBF,GAAkBE,EAEhCL,EAAmBG,EACpC,CACLG,MAAOzD,IAAqBK,eAC5BqD,cAAeF,EAAmB,GAI/B,CAAEC,MAAOzD,IAAqBM,oBAGvC,SAASqD,EAA0B98B,EAAGC,GACpC,OAAOrd,KAAKm6C,KACVn6C,KAAKo6C,IAAIh9B,EAAE,GAAKC,EAAE,GAAI,GACpBrd,KAAKo6C,IAAIh9B,EAAE,GAAKC,EAAE,GAAI,GACtBrd,KAAKo6C,IAAIh9B,EAAE,GAAKC,EAAE,GAAI,IAI5B,IAAMk7B,EAA0B,CAAC,KAAM,KAAM,KAAM,M,kyBCvQ7CvyB,E,YACJ,WAAYrpC,EAAM4iD,GAAK,M,IAAA,O,4FAAA,S,EACrB,S,EAAA,eAAM5iD,EAAM4iD,K,6CAEZniD,OAAO8iD,iBAAP,KAA8B,CAC5Bma,kBAAmB,CACjB7a,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO,MAET40D,QAAS,CACPjY,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO,IAETy3D,aAAc,CACZ9a,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO,IAET03D,oBAAqB,CACnB/a,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO,IAET23D,aAAc,CACZhb,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO,MAETo+C,eAAgB,CACdzB,cAAc,EACdh9C,YAAY,EACZi9C,UAAU,EACV58C,MAAO,QAIX,EAAKu9C,0BA1CgB,E,8SAwPQqa,EAAqB9sC,GAClD,IAAI+sC,EAAiB,GAErB/sC,EAAQrT,SAAQ,SAAAqI,GACd+3C,EAAiBA,EAAe7wB,OAAOlnB,EAAMg4C,gBAG/C,IAAMC,EAAmBF,EAAexgB,QACtC,SAAA2gB,GAAE,OACAA,EAAGv4C,wBAA0Bm4C,EAAoBn4C,yBAG7Cge,EAAam6B,EAAbn6B,SAEJw6B,EAqyBR,SACEx6B,EACAq6B,GAEA,IAAII,EAEJ,GAAIz6B,EAASy6B,oBACXA,EAAsBz6B,EAASy6B,wBAC1B,KAECC,EAAwBC,EADe36B,EAArC46B,kCACiE,GACzE,GAAIF,EAAuB,KACjBG,EAA4BH,EAA5BG,wBACRJ,EAAsBI,GAI1B,GAAKJ,EAAL,CAOA,IAHA,IAEID,EAFEM,EAAmBH,EAASF,GAGzB99D,EAAI,EAAGA,EAAIm+D,EAAiBj+D,OAAQF,IAAK,KACxCo+D,EAA6BD,EAAiBn+D,GAA9Co+D,yBAKR,IAJAP,EAA+BQ,EAC7BX,EACAU,KAIwC,IAAxCP,EAA6B39D,OAE7B,MAIJ,OAAO29D,GA30B8BS,CACjCj7B,EACAs6B,GAGEY,GACDV,GACuC,IAAxCA,EAA6B39D,OAmB/B,GAlBIq+D,IACFV,EA6tBN,SACEx6B,GAEA,GAAKA,EAASm7B,yBAAd,CAIA,IACMA,EAA2BR,EAAS36B,EAASm7B,0BAMnD,OAJ+BA,EAAyBruD,KACtD,SAAAsuD,GAAgB,OAAIA,EAAiBvxB,sBAxuBJwxB,CAC7Br7B,KAIJk7B,GACGV,GACuC,IAAxCA,EAA6B39D,UAE7B29D,EA4uBN,SACEx6B,EACAq6B,GAEA,GAAKr6B,EAASs7B,wBAAd,CAMA,IAFA,IAAId,EACEe,EAAuBZ,EAAS36B,EAASs7B,yBACtC3+D,EAAI,EAAGA,EAAI4+D,EAAqB1+D,OAAQF,IAAK,KAC5Co+D,EAA6BQ,EAAqB5+D,GAAlDo+D,yBACR,GAAKA,IAILP,EAA+BQ,EAC7BX,EACAU,KAKwC,IAAxCP,EAA6B39D,OAE7B,MAIJ,OAAO29D,GAzwB4BgB,CAC7Bx7B,EACAs6B,IAKFE,GAAwE,IAAxCA,EAA6B39D,OAK7D,OAH6By9D,EAAiBl4C,MAAK,SAAAm4C,GAAE,OACnDC,EAA6BvgD,SAASsgD,EAAG1wB,0B,mDApO7C/sC,OAAOmF,eAAekK,KAAM,mBAAoB,CAC9C+yC,cAAc,EACdh9C,YAAY,EACZC,IAAK,WACH,OAAOgK,KAAKy9B,2B,uCAchB,OAAOz9B,KAAK6tD,aAAaz2D,U,kDASCk4D,EAAwBzyB,GAClD,IAAM3mB,EAAQlW,KACRkuD,EAAc,GAIpB,KAFqBrxB,EAAO0yB,mBAAqB,GAE9B,CACjB,IAAMvxB,EAAa,IAAIwxB,IAAS,IAC1B75C,EAAaknB,EAAO8V,UAY1B,OAVA3U,EAAWyxB,cAAc,CACvB55C,sBAAuBmoB,EAAW8U,IAClCpV,kBAAmB/nB,EAAW+nB,kBAC9BgyB,kBAAmB/5C,EAAW+5C,kBAC9B3P,aAAcpqC,EAAWoqC,aACzB7yB,SAAUvX,EAAWuX,WAGvBghC,EAAYl9D,KAAKgtC,GAEVkwB,EAGT,IAAMyB,EAizBV,SAAyB9yB,GACvB,IAAM+yB,EAA6B,IAAIn3B,IAQvC,OAPAoE,EAAOE,iBAAgB,SAAAC,GACrB,IAAM6yB,EAAsB7yB,EAAS9H,YAAY,eAEjD06B,EAA2BpV,IAAIqV,MAEZtqD,MAAMg8B,KAAKquB,GAxzBTE,CAAgBjzB,GAErC,GAAIyyB,GAA0BA,EAAuB5+D,OAAS,EAAG,CAC/D,IAAMstC,EAg0BZ,SACE+xB,EACAlzB,EACA3mB,EACAy5C,GAGA,GAA4B,IAAxBA,EAAaj/D,OAAjB,CAOA,IAAMswD,EAAc2O,EAAa,GAK3BK,EAJyBD,EAA0BpvD,KAAI,SAAAsvD,GAC3D,OAAOA,EAAU99D,UAGmCs7C,QAAO,SAAAt7C,GAC3D,OAAOA,EAAOw9D,aAAa7hD,SAASkzC,MAItC,GAAKgP,GAA2BA,EAAuBt/D,OAAvD,CAIA,IAAMw/D,EAASF,EAAuB,GAChCtjC,EAAUT,IAASO,yBACnBivB,EAAmB/W,IAAauM,sBAChCkf,EAAiB,IAAIC,EAAI,CAC7Bxe,IAAK17B,EAAMy8B,UAAU6I,SACrB9uB,UACA+uB,mBACAC,aAAc,CAAClJ,iBAGbxU,EAAakyB,EAAOG,wBACtBxzB,EACA3mB,EACAi6C,EACAzjC,GAEF,GAAIsR,IAAeA,EAAW9Q,SAAU,CACtC,IAAM8P,EAAWH,EAAOvC,mBACxB0D,EAAW9Q,SAAW8P,EAAS9H,YAAY,YAE7C,OAAO8I,QAxCLhnC,QAAQM,KACN,uGAz0BmBg5D,CACjBhB,EACAzyB,EACA3mB,EACAy5C,GAGF,GAAI3xB,EASF,OARAA,EAAWuyB,gBAAiB,EAExBvyB,EAAWwyB,WACbxwD,KAAKywD,sBAAsBzyB,GAG7BkwB,EAAYl9D,KAAKgtC,GAEVkwB,EAWX,IAAMwC,EAAqB,GAsE3B,GArEA7zB,EAAOE,iBAAgB,SAAAC,GACrB,IAAIgB,EC5J2BgjB,EAC/B2P,ED8JA,GACG1zB,YAAQD,EAAS9H,YAAY,iBAC7B8H,EAAS9H,YAAY,QAkClB07B,EAAa5zB,KACfgB,EAAa6yB,EAAeh0B,EAAQ,CAACG,KAE1ByyB,cAAc,CACvBE,eACAmB,QAAQ,EACRpzB,kBAAmBb,EAAOc,uBAC1BroB,iBAAkBY,EAAMunB,sBACxBszB,eAAgB/zB,EAAS9H,YAAY,kBACrC+xB,eAAgBjqB,EAAS9H,YAAY,kBACrC87B,oBAAqBh0B,EAAS9H,YAAY,yBAE5Cg5B,EAAYl9D,KAAKgtC,IACRizB,EAAsBj0B,EAAS9P,YACxC8Q,EAAa6yB,EAAeh0B,EAAQ,CAACG,KAC1ByyB,cAAc,CACvBE,eACAr6C,iBAAkBY,EAAMunB,sBACxBC,kBAAmBb,EAAOc,uBAC1BspB,eAAgBjqB,EAAS9H,YAAY,kBACrC87B,oBAAqBh0B,EAAS9H,YAAY,yBAE5Cg5B,EAAYl9D,KAAKgtC,IAEjB0yB,EAAmB1/D,KAAKgsC,OAzD1B,CAOA,IAAMgB,EAAa,IAAIwxB,IAAS,IAC1B75C,EAAaknB,EAAO8V,UAC1B3U,EAAWyxB,cAAc,CACvB55C,sBAAuBmoB,EAAW8U,IAClCyM,WAAY5pC,EAAW4pC,WACvBC,WAAY7pC,EAAW6pC,WACvB9hB,kBAAmBb,EAAOc,uBAC1BoiB,aAAc/iB,EAAS9H,YAAY,gBACnCw6B,kBAAmB1yB,EAAS9H,YAAY,qBACxC67B,eAAgB/zB,EAAS9H,YAAY,kBACrCg8B,UAAWl0B,EAAS9H,YAAY,aAChChI,SAAU8P,EAAS9H,YAAY,YAC/B07B,cAAc,EACdt7C,iBAAkBY,EAAMunB,sBACxBwpB,eAAgBjqB,EAAS9H,YAAY,kBACrC87B,oBAAqBh0B,EAAS9H,YAAY,uBAC1Ci8B,mBAAmB,EACnBC,wBAAwB,EACxBC,wBC3L2BrQ,ED4LzBhkB,EAAS9H,YAAY,eC3L3By7B,EAAkB,GACjB3P,GACA/jB,KAEDrlC,IAAmBc,wBAA0BsoD,EAC/C2P,EAAkB,iBACT/4D,IAAmBkB,0BAA4BkoD,EACxD2P,EAAkB,mBACT/4D,IAAmBwB,8BAAgC4nD,EAC5D2P,EAAkB,uBACT/4D,IAAmByB,4BAA8B2nD,EAC1D2P,EAAkB,qBACT/4D,IAAmB0B,+BAAiC0nD,EAC7D2P,EAAkB,6BACT/4D,IAAmB2B,6BAA+BynD,EAC3D2P,EAAkB,sBAElB/4D,IAAmB4B,0CAA4CwnD,EAE/D2P,EAAkB,mCAElB/4D,IAAmB6B,iCAAmCunD,EAEtD2P,EAAkB,0BACT/4D,IAAmB8B,8BAAgCsnD,EAC5D2P,EAAkB,0BACT/4D,IAAmB+B,+BAAiCqnD,EAC7D2P,EAAkB,2BACT/4D,IAAmBgC,6BAA+BonD,EAC3D2P,EAAkB,sBAElB/4D,IAAmBiC,4CAA8CmnD,EAEjE2P,EAAkB,qCAElB/4D,IAAmBkC,wCAA0CknD,EAE7D2P,EAAkB,iCAElB/4D,IAAmBmC,8CACnBinD,EAEA2P,EAAkB,uCAElB/4D,IAAmBoC,2CAA6CgnD,EAEhE2P,EAAkB,oCAElB/4D,IAAmBqC,iDACnB+mD,EAEA2P,EAAkB,0CACT/4D,IAAmBkD,iBAAmBkmD,EAC/C2P,EAAkB,UACT/4D,IAAmBmD,6BAA+BimD,EAC3D2P,EAAkB,sBACT/4D,IAAmBoD,0BAA4BgmD,EACxD2P,EAAkB,mBAElB/4D,IAAmBqD,uCAAyC+lD,EAE5D2P,EAAkB,gCACT/4D,IAAmBsD,sBAAwB8lD,EACpD2P,EAAkB,MACT/4D,IAAmBuD,6BAA+B6lD,EAC3D2P,EAAkB,aACT/4D,IAAmBwD,+BAAiC4lD,EAC7D2P,EAAkB,wBACT/4D,IAAmByD,yBAA2B2lD,EACvD2P,EAAkB,kBACT/4D,IAAmB0D,+BAAiC0lD,EAC7D2P,EAAkB,wBAElB/4D,IAAmBoE,kCAAoCglD,EAEvD2P,EAAkB,2BACT/4D,IAAmBuE,gCAAkC6kD,EAC9D2P,EAAkB,yBAElB/4D,IAAmBwE,oCAAsC4kD,EAEzD2P,EAAkB,6BAElB/4D,IAAmByE,iCAAmC2kD,EAEtD2P,EAAkB,0BAElB/4D,IAAmB0E,0CAA4C0kD,EAE/D2P,EAAkB,mCAElB/4D,IAAmB2E,kCAAoCykD,EAEvD2P,EAAkB,2BAElB/4D,IAAmB4E,qCAAuCwkD,EAE1D2P,EAAkB,8BAElB/4D,IAAmB6E,qCAAuCukD,EAE1D2P,EAAkB,8BAElB/4D,IAAmB8E,qCAAuCskD,EAE1D2P,EAAkB,8BAElB/4D,IAAmB+E,sCAAwCqkD,EAE3D2P,EAAkB,gCAElB/4D,IAAmBgF,0DACnBokD,EAEA2P,EAAkB,mDACT/4D,IAAmBiF,gCAAkCmkD,EAC9D2P,EAAkB,yBACT/4D,IAAmBkF,8BAAgCkkD,EAC5D2P,EAAkB,uBACT/4D,IAAmBmF,cAAgBikD,EAC5C2P,EAAkB,cACT/4D,IAAmBoF,aAAegkD,EAC3C2P,EAAkB,aACT/4D,IAAmBqF,kBAAoB+jD,EAChD2P,EAAkB,kBACT/4D,IAAmBsF,oBAAsB8jD,EAClD2P,EAAkB,oBACT/4D,IAAmBuF,eAAiB6jD,EAC7C2P,EAAkB,eACT/4D,IAAmBwF,mBAAqB4jD,EACjD2P,EAAkB,mBACT/4D,IAAmByF,qBAAuB2jD,EACnD2P,EAAkB,YACT/4D,IAAmB0F,aAAe0jD,EAC3C2P,EAAkB,aACT/4D,IAAmB2F,sBAAwByjD,EACpD2P,EAAkB,sBAElB/4D,IAAmB4F,qCAAuCwjD,EAE1D2P,EAAkB,qCACT/4D,IAAmB6F,aAAeujD,EAC3C2P,EAAkB,aAElB/4D,IAAmB8F,oCAAsCsjD,EAEzD2P,EAAkB,6BACT/4D,IAAmB+F,yBAA2BqjD,EACvD2P,EAAkB,kBACT/4D,IAAmBgG,yBAA2BojD,EACvD2P,EAAkB,kBACT/4D,IAAmBoG,gCAAkCgjD,EAC9D2P,EAAkB,yBACT/4D,IAAmBsG,gBAAkB8iD,EAC9C2P,EAAkB,SACT/4D,IAAmBuG,wBAA0B6iD,EACtD2P,EAAkB,iBACT/4D,IAAmBwG,gCAAkC4iD,EAC9D2P,EAAkB,yBACT/4D,IAAmByG,gBAAkB2iD,EAC9C2P,EAAkB,SAElB/4D,IAAmB0G,iCAAmC0iD,EAEtD2P,EAAkB,0BAElB/4D,IAAmB2G,kCAAoCyiD,EAEvD2P,EAAkB,2BACT/4D,IAAmB4G,mBAAqBwiD,EACjD2P,EAAkB,YAElB/4D,IAAmB6G,mCAAqCuiD,EAExD2P,EAAkB,4BAElB/4D,IAAmB8G,oCAAsCsiD,EAEzD2P,EAAkB,6BACT/4D,IAAmB+G,gCAAkCqiD,EAC9D2P,EAAkB,yBAElB/4D,IAAmBgH,iCAAmCoiD,EAEtD2P,EAAkB,0BACT/4D,IAAmBiH,8BAAgCmiD,IAC5D2P,EAAkB,wBAGbA,GA5LkBA,GD4LjB98B,SAAUmJ,EAAS2V,UAAU9e,WAG/Bq6B,EAAYl9D,KAAKgtC,OA+BjB0yB,EAAmBhgE,OAAQ,CAC7B,IAAMstC,EAAa6yB,EAAeh0B,EAAQ6zB,GAC1C1yB,EAAWppC,aAAa,mBAAoBshB,EAAMunB,uBAClDO,EAAWyxB,cAAc,CACvBE,iBAEFzB,EAAYl9D,KAAKgtC,GAGnB,OAAOkwB,I,4CAOalwB,GACpBh+B,KAAK8tD,oBAAoB98D,KAAKgtC,K,6CASTkwB,GAAa,WAClCA,EAAYvtD,KAAI,SAAAq9B,GAAU,OAAI,EAAK8vB,oBAAoB98D,KAAKgtC,Q,yCAiE3CyP,GAAQ,WAEvBvgB,EAGEugB,EAHFvgB,SACAokC,EAEE7jB,EAFF6jB,4BACAC,EACE9jB,EADF8jB,8BAGEC,EAA6BxxD,KAAK8tD,oBAkCtC,OAhCI5gC,IACFskC,EAA6BA,EAA2B/jB,QACtD,SAAAzP,GAAU,OAAIA,EAAW9Q,WAAaA,MAItCokC,IACFE,EAA6BA,EAA2B/jB,QACtD,SAAAzP,GACE,IAAMyzB,EAAuBl4B,EAAcm4B,wBACzC1zB,EACA,CAAC,IAEH,QAAIyzB,GAEAA,EAAqB/zB,oBACrB4zB,MASNC,IACFC,EAA6BA,EAA2B/jB,QACtD,SAAAzP,GAAU,OACRA,EAAW6jB,sBAAwB0P,MAIlCC,I,wCAeSlC,GAAwB,WAIxC,OAFuBtvD,KAAK2xD,kBAO5B3xD,KAAK48B,eAAc,SAAAC,GACY,EAAK+0B,4BAChCtC,EACAzyB,GAGmBhvB,SAAQ,SAAAugD,GAAE,OAAI,EAAKyD,kBAAkBzD,SAGrDpuD,KAAK6tD,cAjBQ,K,uDA0BWyB,EAAwBzyB,GAAQ,WAC/D,IAAK78B,KAAK8xD,eAAej1B,GACvB,OAAO,EAST,IANA,IAAMqxB,EAAcluD,KAAK4xD,4BACvBtC,EACAzyB,GAIOrsC,EAAIwP,KAAK6tD,aAAan9D,OAAS,EAAGF,GAAK,EAAGA,IAC9BwP,KAAK6tD,aAAar9D,GACtBktC,oBAAsBb,EAAOc,wBAC1C39B,KAAK6tD,aAAaj8D,OAAOpB,EAAG,GAQhC,OAJA09D,EAAYrgD,SAAQ,SAAAmwB,GAClB,EAAK+zB,cAAc/zB,OAGd,I,oCAQKA,GACZ,SAAIA,aAAsBwxB,KAAYxxB,EAAWuyB,kBAC/CvwD,KAAK6xD,kBAAkB7zB,IAChB,K,wCAYO73B,GACZ0sC,IAASgC,gBAAgB1uC,IAC3BnG,KAAK6tD,aAAahgD,SAAQ,SAACmwB,EAAY54B,GACrCe,EAASrV,KAAK,KAAMktC,EAAY54B,Q,wCAYpB44B,GAAY,IAIxBg0B,EAHIjS,EAAiB/hB,EAAjB+hB,aACFmO,EAAcluD,KAAK6tD,aACrBoE,EAAc/D,EAAYx9D,OAI9B,GAAIwhE,YAAsBl0B,EAAW9Q,UAAW,CAI9C,IAHA,IAAIilC,EAGK3hE,EAAI,EAAGA,EAAI09D,EAAYx9D,OAAQF,IACtC,GAAI0hE,YAAsBhE,EAAY19D,GAAG08B,UAAW,CAClDilC,EAAgB3hE,EAChB,MAIC2hE,IACHA,EAAgBjE,EAAYx9D,QAK9B,IAAK,IAAIF,EAAI2hE,EAAe3hE,EAAI09D,EAAYx9D,OAAQF,IAQlD,GANE09D,EAAY19D,GAAGuvD,eAAiBA,GAC/BiS,IAEDA,EAAiCxhE,GAG/B09D,EAAY19D,GAAGuvD,aAAeA,EAAc,CAC9CkS,EAAczhE,EACd,YAKJ,IAAK,IAAIA,EAAI,EAAGA,EAAI09D,EAAYx9D,OAAQF,IAQtC,GANE09D,EAAY19D,GAAGuvD,eAAiBA,GAC/BiS,IAEDA,EAAiCxhE,GAIjC09D,EAAY19D,GAAGuvD,aAAeA,GAC9BmS,YAAsBhE,EAAY19D,GAAG08B,UACrC,CACA+kC,EAAczhE,EACd,MAON,QAAuC6E,IAAnC28D,GAEEh0B,EAAWuhB,WAGb,IAFA,IAAM6S,EAAiB,GAAH,OAAMp0B,EAAWuhB,YAAjB,OAA8BvhB,EAAWwhB,YAEpDhvD,EAAIwhE,EAAgCxhE,EAAIyhE,EAAazhE,IAAK,CACjE,IAAM6hE,EAAcnE,EAAY19D,GAEhC,GACE6hE,EAAY9S,YACZ,UAAG8S,EAAY9S,YAAf,OAA4B8S,EAAY7S,YACtC4S,EACF,CACAH,EAAczhE,EACd,OAONwP,KAAK6tD,aAAayE,MAChB,SAAAlE,GAAE,OAAIA,EAAGv4C,wBAA0BmoB,EAAWnoB,2BAMlD7V,KAAK6tD,aAAaj8D,OAAOqgE,EAAa,EAAGj0B,GACzCh+B,KAAKkuD,YAAcluD,KAAK6tD,gB,qCAUX1nD,GACb,GAAI0sC,IAASgC,gBAAgB1uC,GAC3B,OAAOnG,KAAK6tD,aAAa53C,MAAK,SAAC+nB,EAAY54B,GACzC,OAAOe,EAASrV,KAAK,KAAMktC,EAAY54B,Q,2CAU3C,OAAOpF,KAAK6tD,aAAan9D,S,4CAOzB,OAAOsP,KAAK4tD,oB,kCAQZ,OAAO5tD,KAAKgrD,QAAQ5zD,U,gCAQZylC,GACR,IAAItrC,GAAS,EAQb,OANEsrC,aAAkBwX,UACqC,IAAvDr0C,KAAKuyD,eAAe11B,EAAOc,0BAE3B39B,KAAKgrD,QAAQh6D,KAAK6rC,GAClBtrC,GAAS,GAEJA,I,mCASImsC,EAAmBb,GAC9B,IAAMz3B,EAAQpF,KAAKgrD,QAAQzzC,WAAU,SAAAslB,GACnC,OAAOA,EAAOc,yBAA2BD,KAG3C,GAAIt4B,EAAQ,EACV,OAAO,EAGT,KAAMy3B,aAAkBwX,KACtB,MAAM,IAAItgD,MAAM,gDAKlB,OAFAiM,KAAKgrD,QAAQ5lD,GAASy3B,GAEf,I,uCAQQz3B,GACf,IAAIsvC,EAIJ,OAHI7B,IAASiB,aAAa1uC,KACxBsvC,EAAQ10C,KAAKgrD,QAAQ5lD,IAEhBsvC,I,qCAQM5B,GACb,IAAI4B,EAMJ,OALI7B,IAAS+B,WAAW9B,KACtB4B,EAAQ10C,KAAKgrD,QAAQ/0C,MAAK,SAAA4mB,GACxB,OAAOA,EAAOc,yBAA2BmV,MAGtC4B,I,qCAGM7X,GACb,OACEA,aAAkBwX,KAAkBr0C,KAAKgrD,QAAQnxC,QAAQgjB,IAAW,I,uCAStE,OAAO78B,KAAKgrD,QAAQt6D,S,yCAQpB,OAAOsP,KAAKgrD,QAAQ9oC,QAAO,SAACswC,EAAK31B,GAC/B,OAAO21B,EAAM31B,EAAO0yB,qBACnB,K,oCAUSppD,GACR0sC,IAASgC,gBAAgB1uC,IAC3BnG,KAAKgrD,QAAQn9C,SAAQ,SAACgvB,EAAQz3B,GAC5Be,EAASrV,KAAK,KAAM+rC,EAAQz3B,Q,oCAUpBy3B,GACZ,OAAO78B,KAAKgrD,QAAQnxC,QAAQgjB,K,6BAQvB3mB,GAEL,OACEA,IAFWlW,MAGVkW,aAAiBqjB,GAChBrjB,EAAMunB,wBAJGz9B,KAI4By9B,wB,uCASzC,IAAIZ,EAAS78B,KAAK+tD,aAClB,KAAMlxB,aAAkBwX,KAAiB,CACvCxX,EAAS,KACT,IAAM6X,EAAQ10C,KAAKyyD,iBAAiB,GAChC/d,aAAiBL,MACnBr0C,KAAK+tD,aAAerZ,EACpB7X,EAAS6X,GAGb,OAAO7X,I,sCAOOhnB,GACd,IAIE,OAHmB7V,KAAKi+B,gBACtB,SAAAD,GAAU,OAAIA,EAAWnoB,wBAA0BA,KAEnCqoB,OAAO,GAAGG,aAC5B,MAAOvpC,GAEP,OADAkC,QAAQlC,MAAM,qCACP,Q,yCAST,IAAIkoC,EAAWh9B,KAAKw0C,eACpB,KAAMxX,aAAoBpJ,KAAmB,CAC3CoJ,EAAW,KACX,IAAM01B,EAAc1yD,KAAK2yD,iBACzB,GAAID,aAAuBre,IAAgB,CACzC,IAAMK,EAAQge,EAAYp4B,mBACtBoa,aAAiB9gB,MACnB5zB,KAAKw0C,eAAiBE,EACtB1X,EAAW0X,IAIjB,OAAO1X,I,sDAWuB72B,GAC9B,IAAI5U,EAEJ,GAAIshD,IAASgC,gBAAgB1uC,GAAW,CACtC,IAAI62B,EAEEH,EAAS78B,KAAKgrD,QAAQ/0C,MAAK,SAAA4mB,GAE/B,OADAG,EAAWH,EAAO+1B,aAAazsD,cACJytB,OAIzBiJ,aAAkBwX,MACpB9iD,EAAS,CACPsrC,SACAG,aAKN,OAAOzrC,GAAU,K,2CAWE4U,GAGnB,OAFenG,KAAK6yD,gCAAgC1sD,GAEtC02B,S,mCAWH12B,GAGX,OAFenG,KAAK6yD,gCAAgC1sD,GAEtC62B,c,8BAjzBU6V,KAq0BtBud,EAAMzU,IAAIC,eAEVgV,EAAe,SAAA5zB,GACnB,OAAOA,EAAS9H,YAAY,kBAAoB,GAa5C27B,EAAiB,SAACh0B,EAAQ2hB,GAC9B,IAAMxhB,EAAWwhB,EAAU,GACrBsU,EAAW,IAAItD,IAAShR,GACxB7oC,EAAaknB,EAAO8V,UAG1BmgB,EAASrD,cAAc,CACrB55C,sBAAuBi9C,EAAShgB,IAChCyM,WAAY5pC,EAAW4pC,WACvBC,WAAY7pC,EAAW6pC,WACvB9hB,kBAAmBb,EAAOc,uBAC1BoiB,aAAc/iB,EAAS9H,YAAY,gBACnCw6B,kBAAmB1yB,EAAS9H,YAAY,qBACxC67B,eAAgBvS,EAAU9tD,OAC1BwgE,UAAWl0B,EAAS9H,YAAY,aAChChI,SAAU8P,EAAS9H,YAAY,YAC/B07B,aAAcA,EAAa5zB,KAM3B81B,EAASv0B,QAAO,SAAC5N,EAAGC,GAElB,OACGxM,SAASuM,EAAEuE,YAAY,iBAAkB,KAAO,IAChD9Q,SAASwM,EAAEsE,YAAY,iBAAkB,KAAO,MAMvD49B,EAASl+D,aACP,iBACAk+D,EAASC,SAAS,GAAG79B,YAAY,mBAGnC,IAAM89B,EAA6BrH,EAA4BnN,GAC/DsU,EAAS3B,kBAAoB6B,EAA2B58D,MAExD,IAAI68D,OAAqB59D,EACzB,GAAiBy9D,EAAS3B,kBAAmB,CAE3C2B,EAASI,6BAGT,IAAMC,EAAcH,EAA2BjH,qBAAqB91C,MAClE,SAAAs3C,GAAK,OAAIA,IAAUzD,qBAAqBC,cAE1CkJ,ED3yBJ,SAA0BzU,EAAW2U,GACnC,IAAMv8D,EAAI4nD,EAAU9tD,OAEd0iE,EADa5U,EAAU,GAAG7L,UAAU9e,SACGquB,qBAEvC6J,EAAuB,GACzByB,EAAgB,EAKpB,GAAI52D,EAAI,EAAG,CACT,IAAMy8D,EAAU7U,EAAU5nD,EAAI,GAAG+7C,UAAU9e,SAASquB,qBAGpD,GAAIkR,GAA6BC,EAM/B,IALA,IAAMC,EACJ7F,EAA0B2F,EAA2BC,IAAYz8D,EAAI,GAEnE28D,EAA+BH,EAE1B9G,EAAK,EAAGA,EAAK11D,IAAK01D,EAAI,CAC7B,IACQpK,EADS1D,EAAU8N,GAAI3Z,UAAU9e,SACjCquB,qBAEFsR,EAAuB/F,EAC3BvL,EACAqR,GAGF,KAAIJ,GAAeK,EAAuB,MAA1C,CAOA,IAAMC,EAAevG,EACnBsG,EACAF,GAGF,GAAIG,EAAc,CAChB,IAAMlG,EAAQkG,EAAalG,MAE3B,GAAIA,IAAUzD,IAAqBK,eACjCqD,GAAiBiG,EAAajG,mBACzB,GAAID,IAAUzD,IAAqBM,kBAAmB,CAC3D2B,EAAqB/6D,KAAKu8D,GAC1B,OAIJgG,EAA+BrR,IAKrC,MAAO,CACLwR,UAA2C,IAAhC3H,EAAqBr7D,OAChC88D,gBACAzB,wBC8uBqB4H,CAAiBb,EAAS50B,OAAQi1B,GACvDL,EAAS3B,kBAAoB8B,EAAmBS,UAE5CT,EAAmBzF,gBAGrBsF,EAAStF,cAAgByF,EAAmBzF,eAehD,OAXKsF,EAASE,6BAEZF,EAAS/G,qBAAuBkH,EAC5BD,EAA2BjH,qBAAqB3uB,OAC9C61B,EAAmBlH,sBAErBiH,EAA2BjH,sBAGjC+G,EAAS1B,wBAAyB,EAE3B0B,GAGH7B,EAAwB,SAAA/jC,GAC5B,MAAoB,OAAbA,GAAkC,OAAbA,GAAkC,OAAbA,GA6LnD,SAAS2hC,EACPX,EACAtwB,GAIA,IAFA,IAAMg2B,EAAY1F,EAAYzgB,QAAO,SAAA2gB,GAAE,OAAIA,aAAcoB,OAEhDh/D,EAAI,EAAGA,EAAIojE,EAAUljE,OAAQF,IAAK,KACjC0tC,EAAW01B,EAAUpjE,GAArB0tC,OACR,GAAKA,EAGL,IAAK,IAAIxsC,EAAI,EAAGA,EAAIwsC,EAAOxtC,OAAQgB,IAAK,CACtC,IAAM49B,EAAQ4O,EAAOxsC,GACrB,GAAK49B,GAGDA,EAAMsO,iBAAmBA,EAC3B,MAAO,CAACtO,EAAMqjB,UAAU9e,SAAS6J,qBAMzC,SAAS8wB,EAASqF,GAChB,OAAOtuD,MAAMC,QAAQquD,GAAiBA,EAAgB,CAACA,K,syCEnoCzD,IAQMrE,E,WACJ,WAAYtxB,GACV,G,4FADkB,UACY,IAA1B34B,MAAMC,QAAQ04B,GAChB,MAAM,IAAIjK,IAAU,uCAItBtjC,OAAOmF,eAAekK,KAAM,SAAU,CACpCjK,YAAY,EACZg9C,cAAc,EACdC,UAAU,EACV58C,MAAO8nC,IAITvtC,OAAOmF,eAAekK,KAAM,MAAO,CACjCjK,YAAY,EACZg9C,cAAc,EACdC,UAAU,EACV58C,MAAOu/B,gB,wDAKT,OAAO31B,KAAK8yC,M,mCAGDre,EAAWr+B,GACtB4J,KAAKy0B,GAAar+B,I,mCAGPq+B,GACX,OAAOz0B,KAAKy0B,K,oCAGAnB,GACZ,GA5CW,WA4CP,EAAOA,IAAwC,OAAfA,EAAqB,CACvD,IACEwgC,EAASnjE,OAAOC,UAAUC,eAC5B,IAAK,IAAI4jC,KAAanB,EAChBwgC,EAAOhjE,KAAKwiC,EAAYmB,KAHbz0B,KAIJy0B,GAAanB,EAAWmB,O,+BAMhCrvB,GACP,OAAOpF,KAAKk+B,OAAO94B,K,6BAGd2uD,GACL,OAAO/zD,KAAKk+B,OAAO/c,KAAK4yC,K,mDAIxB,IAAM71B,EAASl+B,KAAKk+B,OACd81B,EAAgCC,EAAyB/1B,EAAO,IAEhEg2B,EAAY,IAAIC,UACpBH,EAA8B,GAC9BA,EAA8B,GAC9BA,EAA8B,IAG1BnT,EAAsD3iB,EAAO,GA0CxDyU,UAAU9e,SAASgtB,wBAxCxBuT,EAAiB,IAAID,UACzBtT,EAAwB,GACxBA,EAAwB,GACxBA,EAAwB,IACxBwT,MACA,IAAIF,UACFtT,EAAwB,GACxBA,EAAwB,GACxBA,EAAwB,KAItByT,EAAqBp2B,EAAOv9B,KAAI,SAAS2uB,GAC7C,IAAMilC,EAAS,EAAIJ,UAAP,EAAkBF,EAAyB3kC,KAIvD,MAAO,CACLklC,SAJqBN,EAAUO,QAAQC,IAAIH,GACbI,IAAIP,GAIlC9kC,YAIJglC,EAAmBnzC,MAAK,SAASwP,EAAGC,GAClC,OAAOA,EAAE4jC,SAAW7jC,EAAE6jC,YAGxB,IAAMI,EAAeN,EAAmB3zD,KAAI,SAAAgwB,GAAC,OAAIA,EAAErB,SAEnD4O,EAAO/c,MAAK,SAASwP,EAAGC,GACtB,OAAOgkC,EAAa/6C,QAAQ8W,GAAKikC,EAAa/6C,QAAQ+W,W,gCAK5D,SAASqjC,EAAyB3kC,GAChC,OAAOA,EAAMqjB,UAAU9e,SAASquB,qBAOnBsN,O,0CC1Hf,+CAqBe,SAASnxB,EAAWrB,EAAUoX,GAA0B,IAAnBkX,EAAmB,wDACrE,GAAKtuB,EAAL,CAIA,GAAmC,mBAAxBA,EAASqB,WAClB,OAAOrB,EAASqB,aAGlB,GAAIrB,EAAS4U,IAKX,YAJcv8C,IAAV++C,IACFpX,EAAS4U,KA7BqB2J,EA6BYve,EAAS4U,IA7BhBl7C,EA6BqB,QA7BhBN,EA6ByBg+C,EA5B/DygB,EAAQ,IAAI5xB,OAAO,SAAWvsC,EAAM,YAAa,KACjDo+D,GAAkC,IAAtBvZ,EAAI1hC,QAAQ,KAAc,IAAM,IAC9C0hC,EAAInY,MAAMyxB,GACLtZ,EAAIpoC,QAAQ0hD,EAAO,KAAOn+D,EAAM,IAAMN,EAAQ,MAE9CmlD,EAAMuZ,EAAYp+D,EAAM,IAAMN,IA0B9B4mC,EAAS4U,IAhCpB,IAAoC2J,EAAK7kD,EAAKN,EACtCy+D,EACAC,EAiCAC,EAAgBzJ,EAAY,qBAAuB,iBAEzD,GACGtuB,EAAS+3B,IACkB,YAA5B/3B,EAAS+3B,IACR/3B,EAASg4B,UASV,OAAOC,YAAiBj4B,EAAUoX,EAAOkX,GAPzC,IAAIltB,EAAU,YAAcpB,EAASk4B,QAKrC,YAJc7/D,IAAV++C,IACFhW,GAAW,UAAYgW,GAGlBhW,K,sPC7CJ,IAAMvE,EAAb,yB,4FAAA,S,UAAA,O,EAAA,G,EAAA,wCAKmBmmB,GAIf,MAAM,IAAI/rB,IACR,iJAVN,gCAkBY/d,GAIR,MAAM,IAAI+d,IACR,6I,2BAvBN,M,+FCLMkhC,GAAY,EAIZC,EAAmB,CAEvBC,MAAO,CAAC,cAAe,SAAU,eAAgB,YAAa,UAAW,OAAQ,aAGjFC,kBAAmB,MACnBC,aAAc,UACdC,mBAAoB,aACpBC,oBAAqB,EACrBC,yBAA0B,EAG1BC,OAAQ,CAAC,eAAgB,UACzBC,gBAAiB,CAAC,UAGlBC,QAAS/iE,SAASgjE,iBClBL,WAAC3gE,GAA2B,IAAlBqyC,EAAkB,uDAAV,MAC3B2tB,GAEFn+D,QAAQwwC,GAAO,eAAgBryC,I,+VCMpB,M,+UAAA,ICAA,CACb,GAAM,CACJ4gE,W,OACAC,Q,OACA7mD,W,OACA8mD,O,OACAC,W,OACAC,O,OACAvsD,iB,OACAoX,U,OACAo1C,qB,OACA5lD,qB,SDXJ,GEAe,CACb,QAAS,CACPulD,W,OACAC,Q,OACA7mD,W,OACA8mD,O,OACAC,W,OACAC,O,OACAvsD,iB,OACAoX,U,OACAo1C,qB,OACA5lD,qB,SFXJ,GGAe,CACb,GAAM,CACJulD,W,OACAC,Q,OACA7mD,W,OACA8mD,O,OACAC,W,OACAC,O,OACAvsD,iB,OACAoX,U,OACAo1C,qB,OACA5lD,qB,SHXJ,GIAe,CACb,GAAM,CACJulD,W,OACAC,Q,OACA7mD,W,OACA8mD,O,OACAC,W,OACAC,O,OACAvsD,iB,OACAoX,U,OACAo1C,qB,OACA5lD,qB,SJXJ,GKAe,CACb,QAAS,CACPulD,W,OACAC,Q,OACA7mD,W,OACA8mD,O,OACAC,W,OACAC,O,OACAvsD,iB,OACAoX,U,OACAo1C,qB,OACA5lD,qB,SLXJ,GMAe,CACb,GAAM,CACJulD,W,OACAC,Q,OACA7mD,W,OACA8mD,O,OACAC,W,OACAC,O,OACAvsD,iB,OACAoX,U,OACAo1C,qB,OACA5lD,qB,SNXJ,GOAe,CACb,QAAS,CACPulD,W,OACAC,Q,OACA7mD,W,OACA8mD,O,OACAC,W,OACAC,O,OACAvsD,iB,OACAoX,U,OACAo1C,qB,OACA5lD,qB,SPXJ,GQAe,CACb,GAAM,CACJulD,W,OACAC,Q,OACA7mD,W,OACA8mD,O,OACAC,W,OACAC,O,OACAvsD,iB,OACAoX,U,OACAo1C,qB,OACA5lD,qB,SRXJ,GSAe,CACb,GAAM,CACJulD,W,OACAC,Q,OACA7mD,W,OACA8mD,O,OACAC,W,OACAC,O,OACAvsD,iB,OACAoX,U,OACAo1C,qB,OACA5lD,qB,STXJ,GUAe,CACb,GAAM,CACJulD,W,OACAC,Q,OACA7mD,W,OACA8mD,O,OACAC,W,OACAC,O,OACAvsD,iB,OACAoX,U,OACAo1C,qB,OACA5lD,qB,UCtBE6lD,EAAe,CACnBC,GAAI,SACJC,GAAI,UACJC,GAAI,YACJC,GAAI,UACJC,GAAI,UACJC,GAAI,QACJC,GAAI,SACJC,GAAI,SACJC,GAAI,QACJC,GAAI,UACJ,QAAS,0BACT,QAAS,gBACTC,GAAI,UACJC,GAAI,WACJC,GAAI,UACJC,GAAI,UACJC,IAAK,WACLC,GAAI,SACJC,GAAI,WACJC,GAAI,SACJC,GAAI,QACJC,GAAI,WACJC,GAAI,YACJl1D,GAAI,aACJm1D,GAAI,UACJC,GAAI,WACJ,QAAS,mBACTC,GAAI,UACJC,GAAI,SACJC,GAAI,aACJC,GAAI,UACJC,GAAI,YACJC,GAAI,UACJC,GAAI,QACJC,GAAI,QACJC,GAAI,YACJC,GAAI,SACJ,QAAS,sBACT,QAAS,wBACTC,GAAI,WACJC,GAAI,UACJC,GAAI,SACJC,GAAI,YACJC,GAAI,UACJC,GAAI,UACJC,GAAI,UACJC,GAAI,QACJC,GAAI,SACJrvB,GAAI,OACJsvB,GAAI,UACJC,GAAI,YACJC,GAAI,aACJC,GAAI,UACJ,QAAS,kBACT,QAAS,oB,gyBCnBX,IAAMC,EAAgB,CACpBC,UAAW3tD,GACX4tD,OAAQ5tD,GACR6tD,aAAc,QACdC,YAAa,SAGTC,GAAe,EACfC,GAAqB,EACrBC,EAAmB,QAEzB,SAASC,IAIP,IACIC,E,EAsCiB,EA1CrBC,EAGA,uDAHY1E,EACZ2E,EAEA,uDAFYN,EACZO,EACA,uDADkBN,EA+ElB,OA3EIK,GACFE,EAAY,qCAAsC,QAClDJ,EAAc79C,IAIXk+C,IAAIC,KAKJD,IAAIE,KAIJF,IAAIG,KAGJH,IAAII,KAEJJ,IAAIK,KAGJ9Q,KAAK,CACJ+Q,YAAab,EACbc,YAAaT,EACbviE,MAAO09D,EACPlwD,cAAc,EACdy1D,cAAe,CACbC,aAAa,GAEfb,YACAhvC,QAASsuC,EACTwB,eAAgBxB,EAChByB,OAAQ,KACHzB,EADC,CAEJ0B,e,EAAa,yBAAE,WAAO/rD,EAAKvY,GAAZ,gGAEPwlB,IAAK++C,gBAAgBhsD,EAAKvY,GAFnB,OAKbwlB,IAAKg/C,KAAK,eALG,0CAAF,E,8KAAA,iDAQfC,MAAO,CACLC,aAAa,EACbC,MAAM,EACNC,SAAU,mCAIhBnB,EAAY,gCAAiC,QAC7CJ,EAAc79C,IAGXk+C,IAAII,KAEJJ,IAAIK,KAGJ9Q,KAAK,CACJ+Q,YAAab,EACb0B,UAAWC,EACX7jE,MAAO09D,EACPlwD,cAAc,EACdy1D,cAAe,CACbC,aAAa,GAEfb,YACAmB,MAAO,CACLE,MAAM,MAKPtB,EAAYzlE,MAAK,SAASiC,GAC/B2lB,IAAK4T,EAAIv5B,EACT4jE,EAAY,wBAAyB,WAIzCA,EAAY,WAAD,OAAYsB,EAAI/vD,QAAhB,YAAmC,QAE9CwQ,IAAKw/C,aAAe5B,IACpB59C,IAAK49C,SAAWA,EAChB59C,IAAKy/C,WA7HL,SAAoBC,GAClBzB,EAAY,kBAAD,OAAmByB,GAAc,QAE5C,IAAIC,EAAiB,GAErBhrE,OAAO4c,KAAKmuD,GAAY/6D,KAAI,SAAAjK,GAC1B/F,OAAO4c,KAAKmuD,EAAWhlE,IAAMiK,KAAI,SAAAitC,GAC/B,IAAM7xB,EAAS2/C,EAAWhlE,GAAKk3C,GAC/B+tB,EAAe3qE,KAAK,CAAE0F,MAAKk3C,YAAW7xB,WACtCC,IAAK4/C,kBAAkBllE,EAAKk3C,EAAW7xB,GAAQ,GAAM,SAIzDk+C,EAAY,6BAA8B,QAC1CA,EAAY0B,EAAgB,SAgH9B3/C,IAAK6/C,gBAAkBlC,EAGvB39C,IAAK8/C,mBDrFU,SAAmCR,GAChD,IAAMS,EAAyB,GAS/B,OAPAprE,OAAO4c,KAAK+tD,GAASztD,SAAQ,SAAAnX,GAC3BqlE,EAAuB/qE,KAAK,CAC1BoF,MAAOM,EACPoL,MAAOu0D,EAAa3/D,IAAQA,OAIzBqlE,EC2EiBC,CAA0BV,GAErCt/C,MAAf,G,qcC/IA,IAAMigD,EAAa,wBAEbC,EAAwB,IAAItiC,IAa3B,SAASuiC,EACdtiB,EACAvkC,EACA8mD,GAEA,IAoBI9nE,EArBJ+nE,EACA,wDAKA,IAAKxiB,EACH,MAAM,IAAI9lD,MAAJ,UAAakoE,EAAb,gDAER,IAAK3mD,EACH,MAAM,IAAIvhB,MAAJ,UACDkoE,EADC,0DAMR,OAAIC,EAAsBjhC,IAAI3lB,GACrB4mD,EAAsBlmE,IAAIsf,IAWjChhB,EAJA8nE,GACAA,EAAQvc,mBACRwc,EA+BJ,SACExiB,EACAvkC,EACA8mD,GACA,IAEME,EADwBF,EAAtBvc,kBACqC5zC,MAAM,KAEnD,OAAO,IAAI1Z,SAAQ,SAACC,EAASC,GAC3B,IAAMH,EAAW,GAEjBgqE,EAAmBzuD,SAAQ,SAAAilC,GACzB,IAAMypB,EAAwB5rE,OAAOqhC,OAAO,GAAIoqC,EAAS,CACvDvc,kBAAmB/M,IAGrBxgD,EAAStB,KACPwrE,YAAiB3iB,EAAQvkC,EAAkBinD,OAI/ChqE,QAAQiD,IAAIlD,GAAU8B,MAAK,SAAA4oD,GACzB,IAAM9sD,EAAO8sD,EAAQ,GAEjBngB,EAAS,GAEbmgB,EAAQnvC,SAAQ,SAAAtc,GACdsrC,EAAS,GAAH,SAAOA,GAAP,EAAkBtrC,EAAOsrC,YAGjC3sC,EAAK2sC,OAASA,EAEdrqC,EAAQtC,KACPuC,MA9DOgqE,CACR5iB,EACAvkC,EACA8mD,GAGQI,YAAiB3iB,EAAQvkC,EAAkB8mD,GAYvDF,EAAsBhhC,IAAI5lB,EAAkBhhB,GAErCA,GAqDF,SAASooE,EAA2BpnD,GACrC4mD,EAAsBjhC,IAAI3lB,IAC5B4mD,EAAsB16B,OAAOlsB,K,mDCtHlB,SAAS2mC,EAAO0gB,GAI7B,IAHA,IAAMC,EAASD,EAAIjsE,OACbmsE,EAAQ,IAAIzhB,WAAWwhB,GAEpBpsE,EAAI,EAAGA,EAAIosE,EAAQpsE,IAC1BqsE,EAAMrsE,GAAKmsE,EAAIrwC,WAAW97B,GAG5B,OAAOqsE,EAAMC,OAdf,mC,k2CCAO,IAiGQC,EAjGf,yB,4FAAA,S,UAAA,O,EAAA,E,EAAA,2BAUalmE,EAAQmmE,EAAM5mE,GACvB,IAAI6mE,EAAaF,EAAWG,kBAAkBF,GAC5CtsE,EAAwB,OAAfusE,EAAsBA,EAAWvsE,OAAS,EACnDa,GAAS,EAEX,GAAIb,EAAS,GAAKqsE,EAAWI,cAActmE,GAAS,CAKlD,IAJA,IAAIrG,EAAI,EACN4sE,EAAO1sE,EAAS,EAChB0xC,EAAgBvrC,EAEXrG,EAAI4sE,GAAM,CACf,IAAI39C,EAAQw9C,EAAWzsE,GAEvB,GAAIivB,KAAS2iB,GACX,IAAK26B,EAAWI,cAAc/6B,EAAc3iB,IAC1C,WAGF2iB,EAAc3iB,GAAS,GAGzB2iB,EAAgBA,EAAc3iB,GAC9BjvB,IAGEA,IAAM4sE,IACRh7B,EAAc66B,EAAWG,IAAShnE,EAClC7E,GAAS,GAIb,OAAOA,IAzCX,0BAmDasF,EAAQmmE,GACjB,IAAItoB,EACFuoB,EAAaF,EAAWG,kBAAkBF,GAC1CtsE,EAAwB,OAAfusE,EAAsBA,EAAWvsE,OAAS,EAErD,GAAIA,EAAS,GAAKqsE,EAAWI,cAActmE,GAAS,CAKlD,IAJA,IAAIrG,EAAI,EACN4sE,EAAO1sE,EAAS,EAChB0xC,EAAgBvrC,EAEXrG,EAAI4sE,GAAM,CACf,IAAI39C,EAAQw9C,EAAWzsE,GAEjB6sE,EAAUN,EAAWI,cAAc/6B,EAAc3iB,IACvD,KAAIA,KAAS2iB,GAAiBi7B,GAI5B,MAHAj7B,EAAgBA,EAAc3iB,GAC9BjvB,IAMAA,IAAM4sE,GAAQH,EAAWG,KAASh7B,IACpCsS,EAAQtS,EAAc66B,EAAWG,KAIrC,OAAO1oB,IA9EX,oCAsFuB79C,GACnB,MACoB,WAAlB,EAAOA,IAAkC,OAAXA,GAAmBA,aAAkBlG,SAxFzE,wCA4F2BqsE,GACvB,MAAuB,iBAATA,EAAoBA,EAAK/wD,MAAM,KAAO,S,EA7FxD,O,2BAAA,K,SCmBeqxD,EAnBK,SAAAN,GAClB,IAAIO,EAAe,IAEnB,IAAKP,EAAM,OAAOO,EAGlB,IAAMD,EAAcpmE,OAAOykB,SAAS6hD,OAC9BC,EAAmBH,EAAYrxD,MAAM,KAE3C,GAAIwxD,EAAiB/sE,OAAS,EAAG,CAC/B,IAAMgtE,EAAqBJ,EAAYzjD,QAAQ4jD,EAAiB,IAChEF,GAAgBD,EAAYtsB,UAAU0sB,GAAsBV,OAE5DO,GAAgBP,EAGlB,OAAOO,EAAapqD,QAAQ,SAAU,MCIzBwqD,EAnBI,SAACC,EAASC,GAC3B,IAAKD,IAAYC,EACf,MAAM,IAAI9pE,MAAM,yCAGlBpD,OAAO4c,KAAKqwD,GAAS/vD,SAAQ,SAAAiwD,GACTF,EAAQE,GAChBjwD,SAAQ,SAAAkwD,GAChB,IAAMlkB,EAASlpD,OAAOqhC,OAAO,GAAI+rC,GACjClkB,EAAOtmD,KAAOuqE,EAEdD,EAAMG,SAAS,CACbzqE,KAAM,aACNsmD,kB,oQCNR,IAAMxb,EAAa,SAAA4/B,GACjB,GAAKA,EAIL,MAAsC,mBAAxBA,EAAS5/B,WACnB4/B,EAAS5/B,aACT4/B,EAASrsB,KAiBTssB,EAAqB,SAAAC,GAIzB,OAHqB54D,MAAMC,QAAQ24D,GAAWA,EAAU,CAACA,IAE9B7L,MADP,SAAA7vD,GAAM,OAAKA,MAK3B27D,EAAmB,SAAA7f,GACvB,OAAOA,GAAWA,EAAQrgB,QAAUqgB,EAAQrgB,OAAO,IAG/CmgC,EAAqB,SAAAC,GACzB,OAAOjgC,EAAWigC,IAGdC,EAAU,SAAC3sB,GAAqD,IAAhDllB,EAAgD,uDAAtCT,IAASO,yBACvC,OAAOgyC,MAAM5sB,EAAKllB,GAASt4B,MAAK,SAAAqqE,GAAQ,OAAIA,EAAStiB,kBAGjDuiB,EAAuB,SAAAtgC,GAC3B,OAAO3Q,IAAYkxC,kBAAkBvgC,GAAShqC,MAAK,SAAAk7B,GACjD,OAAOA,GAASA,EAAMp/B,MAAQo/B,EAAMp/B,KAAKgrD,UAAU4hB,WAIjD8B,EAAkB,SACtBhtB,EACAoO,EACAH,EACAkF,GAGG,IAFHr4B,EAEG,uDAFOT,IAASO,yBACnBivB,EACG,uDADgB/W,IAAauM,sBAE1B7hB,EAAS,CACbwiB,MACAllB,UACA+uB,mBACAC,aAAc,CAAClJ,gBAEXyK,EAAW,IAAItB,IAAIC,eAAexsB,GAExC,OAAO6tB,EAAS4hB,iBAAiB,CAC/B7e,mBACAH,oBACAkF,oBAkIW+Z,EAFY,I,0LA9GZvgB,EAASr9B,GACpB,GAAIq9B,GAAWA,EAAQwgB,UAAW,CAEhC,IAAMT,EAAgBF,EAAiB7f,GACnCngB,EAAUigC,EAAmBC,GAOjC,GAJIJ,EAAmB9/B,KACrBA,EApFqB,SAACld,EAASrL,GACrC,IAD+D,EACjDqL,EAAQjL,MAAK,SAAAC,GAIzB,OAHmBA,EAAMg4C,YAAYoE,MACnC,SAAAt0B,GAAU,OAAIA,EAAWnoB,wBAA0BA,QAI/CgnB,OAPuD,eAO9C,GAP8C,GAQ7B,IAAM,IAAhC2hB,UACFxhB,QATyD,MAQ3C,GAR2C,GASpC,GAE3B,OAAOqB,EAAWrB,GAyEFgiC,CAAqB99C,EAASq9B,EAAQ1oC,yBAG7CqoD,EAAmB9/B,GACtB,OAAO6gC,IAA2B/J,QAAQgK,gBAAgB9gC,M,yCAK7CmgB,GACjB,IAAM+f,EAAgBF,EAAiB7f,GAEvC,GAAI+f,EAAe,CACjB,IAAMlgC,EAAUigC,EAAmBC,GAC/Ba,EAAqBZ,EAGzB,OAvCqB,SAAAngC,GACzB,IAAMghC,EAAe,SACfC,EAAaD,EAAaE,KAAKlhC,GAErC,OAC8B,IAA3BghC,EAAaG,WACZF,GACAA,EAAW,IACXA,EAAW,GAAGlsD,QAAQ,IAAK,KAC7B,GA4BqBqsD,CAAmBphC,IAGpC,IAAK,YACH+gC,EAAqBT,EAAqB/nE,KAAKqJ,KAAMo+B,GACrD,MACF,IAAK,SACH,IAAMwT,EAAM0sB,EAAc3rB,UAAU6I,SAC9BwE,EAAmBse,EAAc7gC,sBACjCoiB,EAAoBye,EAAc3gC,uBAClConB,EAAiBuZ,EAAc/gC,oBAOrC,GANsB2gC,EAAmB,CACvCtsB,EACAoO,EACAH,EACAkF,IAGA,OAGFoa,EAAqBP,EAAgBjoE,KACnCqJ,KACA4xC,EACAoO,EACAH,EACAkF,GAEF,MACF,IAAK,UAIH,G,oDAFO,YAAP3mB,EAAUA,EAAQ4S,UAAU5S,EAAQvkB,QAAQ,KAAO,GAE/CqkD,EAAmB9/B,GACrB,OAEF+gC,EAAqBZ,EAAQ5nE,KAAKqJ,KAAMo+B,GAI5C,OAAO+gC,O,2CAIU5gB,GAAS,IAE1BjpC,EAMEipC,EANFjpC,iBACAooB,EAKE6gB,EALF7gB,kBACAE,EAIE2gB,EAJF3gB,eACA6hC,EAGElhB,EAHFkhB,qBACAjkB,EAEE+C,EAFF/C,SACAkkB,EACEnhB,EADFmhB,QAGF,OAAKxB,EAAmB1iB,GAQZ0iB,EAAmBwB,QAAxB,EACEnB,EAAQmB,EAAS,CAAEhzC,QAAS+yC,IAR5Bb,EACLpjB,EACAlmC,EACAooB,EACAE,EACA6hC,K,mEAOalhB,EAASr9B,G,gFAC1B,O,SAAMlhB,KAAK2/D,aAAaphB,EAASr9B,G,OACjC,O,SAAMlhB,KAAK4/D,mBAAmBrhB,G,OAC9B,O,SAAMv+C,KAAK6/D,qBAAqBthB,G,2FAGbA,EAASr9B,GAC5B,IAAM4+C,EAAiB9/D,KAAK+/D,kBAAkBxhB,EAASr9B,GADlB,uBAGrC,YAAqB4+C,EAArB,+CAAqC,KAA1BE,EAA0B,QACnC,GAAIA,EACF,OAAOA,GAL0B,kFAUrC,MAAM,IAAIjsE,MAAM,kC,iCCnLLksE,EApBG,SAACC,GAIjB,IAJgE,IAAtCC,EAAsC,uDAAxB,GAAIC,EAAoB,uDAAR,IAClDC,EAAiBrkB,KAAKkkB,GACtBI,EAAa,GAEVvxC,EAAS,EAAGA,EAASsxC,EAAe3vE,OAAQq+B,GAAUqxC,EAAW,CAIxE,IAHA,IAAMhpE,EAAQipE,EAAejpE,MAAM23B,EAAQA,EAASqxC,GAE9CG,EAAc,IAAIh7D,MAAMnO,EAAM1G,QAC3BF,EAAI,EAAGA,EAAI4G,EAAM1G,OAAQF,IAChC+vE,EAAY/vE,GAAK4G,EAAMk1B,WAAW97B,GAGpC,IAAM0qD,EAAY,IAAIE,WAAWmlB,GACjCD,EAAWtvE,KAAKkqD,GAGlB,IAAMslB,EAAO,IAAIC,KAAKH,EAAY,CAAE/sE,KAAM4sE,IAC1C,OAAOK,G,6WCiCT,WACE/O,EACAvwC,EACAw/C,EACA/yB,GAJF,qGAMUr4B,EAAwCm8C,EAAxCn8C,iBAAkBooB,EAAsB+zB,EAAtB/zB,kBACpBprC,EAAW,GACXmqC,EAAgBkkC,IAAqB3qE,IAAIsf,GARjD,yCAWWhjB,GAXX,WAcQsuE,EAAqBnkC,EAAcokC,mBAAmB,CAC1DvP,4BAA6B5zB,KAGPhtC,OAlB1B,yCAmBW4B,GAnBX,cAuBQwuE,EAAyB,GAE/BF,EAAmB/yD,SAAQ,SAAAmwB,GACzB,IAAM9Q,EAAW8Q,EAAW9Q,cAEa73B,IAArCyrE,EAAuB5zC,KACzB4zC,EAAuB5zC,GAAY,IAGrC4zC,EAAuB5zC,GAAUl8B,KAAKgtC,MAhC1C,UAoCQzrC,QAAQiD,IACZ7E,OAAO4c,KAAKuzD,GAAwBngE,IAApC,4CAAwC,WAAMjK,GAAN,mGAChCw3D,EAAc4S,EAAuBpqE,IAE1Bw3D,EAAYoE,MAAK,SAAAt0B,GAAU,OAAIA,EAAW+iC,YAHrB,qDAQlC7S,EAAYoE,MAAK,SAAAt0B,GAAU,OAAIA,EAAWgjC,aARR,oDAalCC,EAAiB,EACjBC,EAAmBhT,EAAY,GAEnCA,EAAYrgD,SAAQ,SAAAmwB,GAClB,IAAMmjC,EAAW/jB,OAAO,GAAD,OAClBpf,EAAWuhB,YADO,OACMvhB,EAAWwhB,aAEpC2hB,EAAWF,IACbA,EAAiBE,EACjBD,EAAmBljC,MAtBe,UA4BlCkjC,EAAiBrwE,eAAe,wBACgB,mBAAzCqwE,EAAiBE,oBA7BU,oBA+BA,QAA9BF,EAAiBh0C,WAAsBwzC,EA/BT,iBAgC1BW,EAAiC,SAAAvsE,GACrC4rE,EAAO5rE,MAAM,CAAEA,QAAOK,QAASL,EAAMK,UACrCw4C,EAASzC,KAAK,CACZlhC,MAAO,4BACP7U,QAASL,EAAMK,QACf5B,KAAM,QACNs4C,WAAW,KAIXy1B,GAA0B,EA1CE,oJA+CpBJ,EAAiBE,oBACzBlgD,GACA,EACAmgD,GAlD4B,yBA6C5B5P,qBACA8P,EA9C4B,EA8C5BA,yBA9C4B,SAqDCA,EArDD,OAqD9BD,EArD8B,OAsDxBE,EAAiB,IAAIC,YACzB,wCACA,CACEjqD,OAAQ,CAAE8pD,uBAAwBA,KAGtCxuE,SAAS4uE,cAAcF,GAEjBG,EAAevkB,OAAO,GAAD,OACtB8jB,EAAiB3hB,YADK,OACQ2hB,EAAiB1hB,aAEpDyhB,EAAiB,EACjB/S,EAAYrgD,SAAQ,SAAAmwB,GAClB,IAAMmjC,EAAW/jB,OAAO,GAAD,OAClBpf,EAAWuhB,YADO,OACMvhB,EAAWwhB,aAEpC2hB,EAAWF,GAAkBE,EAAWQ,IAC1CV,EAAiBE,EACjBD,EAAmBljC,MAxEO,uDA2CE,GAA3BsjC,EA3CyB,8HA6E1BJ,EAAiBE,oBAAoBlgD,GA7EX,iDAgF5BggD,EAAiBU,KAAKnQ,EAAsBvwC,GAhFhB,0DAmFpCggD,EAAiBH,UAAW,EAC5BG,EAAiBF,WAAY,EAC7BN,EAAO5rE,MAAM,CAAEA,MAAK,KAAEK,QAAS,KAAMA,UACrCw4C,EAASzC,KAAK,CACZlhC,MAAO,qCACP7U,QAAS,KAAMA,QACf5B,KAAM,QACNuB,MAAK,KACL+2C,WAAW,IA3FuB,0DAAxC,wDArCJ,QA2IQn4C,EAAQ,IAAI+tE,YAAY,qCAC9B3uE,SAAS4uE,cAAchuE,GA5IzB,6C,sBA+IemuE,M,0jBC7Lf,SAASC,EAAuB/0D,GAC9B,OAAOA,EAAK,GAAG1K,cAAgB0K,EAAK3V,MAAM,GAE5C,IA0BMgxD,EAAQ,SAAA2Z,GACZ,OAAIA,EACKC,IAAI5Z,MAAM2Z,GAGZ,IAuBH5Z,EAAc,CAClB8Z,gBAvDsB,WAAmB,IAAlBtmD,EAAkB,uDAAP,GAC1BmnB,EAAWnnB,EAAXmnB,OAER,GAAKA,EAAL,CAIA,IAAMo/B,EAAmB9Z,EAAMtlB,GACzBs5B,EAAU,GAMhB,OAJAzrE,OAAO+pD,QAAQwnB,GAAkBr0D,SAAQ,YAAkB,aAAhBnX,EAAgB,KAAXN,EAAW,KACzDgmE,EAAQ0F,EAAuBprE,IAAQN,KAGlCgmE,KA4CH+F,EAAc,CAClBC,YAVkB,SAAApF,GAClB,IAAMqF,EAAoB,IAAH,OAvDQ,KAwD/B,OAAOrF,EAAKnjD,QAAQwoD,GAAqB,GASzCC,WA3BiB,SAAAC,GACjB,IAAMC,EAjBO,WAAsB,IAArBC,EAAqB,uDAAP,GAC5B,IACE,IAAMC,EAAUxrE,OAAO8kD,KAAKymB,GAC5B,OAAOC,EACP,MAAOrwE,GACP,OAAOowE,GAYaE,CAAOJ,GAC7B,GAAIC,GAA0C,iBAAlBA,EAC1B,OAAOA,EAAcv2D,MA1CD,MAmEtB22D,aArBmB,WAAqC,IAApC5F,EAAoC,uDAA7B,GAAI6F,EAAyB,uCAAfC,EAAe,uCAClDC,EAAe,GAAH,OA9Ca,KA8Cb,OAAiCF,GACnD,OAAIC,EACK9F,EAAK7pD,QAAQ4vD,EAAcD,GAG7B9F,ICtDM,SAASgG,IACtB,IAAIvwE,EAAQD,EAAS8B,EAAU,IAAI/B,SAAQ,SAAU0wE,EAAKC,GACxD1wE,EAAUywE,EACVxwE,EAASywE,KAEX,OAAOvyE,OAAO6kC,OAAO,CAAElhC,UAAS9B,UAASC,W,u0BCJtB0wE,E,WAEnB,WAAYx8D,I,4FAAO,SACjB3G,KAAK2G,MAAQA,EACb3G,KAAK0gB,KAAO,EACZ1gB,KAAKojE,SAAW,K,oDAiBbC,GACH,OAAO1sE,EAAKqJ,KAAMqjE,K,+BAGXA,EAAM78C,GACb,IAAM88C,EAAY3sE,EAAKqJ,KAAMqjE,GAC7B,mDAAO,sIAEUC,EAAS,WAAT,KAFV,wEAIH98C,EAAQ,EAAD,IAJJ,wDAAP,2D,gCAcJ,SAAS7vB,EAAK4sE,EAAOF,GACnB,IAAMG,EAAUC,EAAM9sE,KAAK,KAAM4sE,GACjC,mDAAO,0HACDA,EAAM7iD,MAAQ6iD,EAAM58D,OADnB,sBAEG,IAAI5S,MAAM,uBAFb,sBAA4BqS,EAA5B,yBAA4BA,EAA5B,eAIC9R,EAAUovE,EAAMH,EAAMH,SAAUC,EAAMj9D,GAC5Cm9D,EAAMH,SAAW9uE,EAAQF,KAAKovE,EAASA,GACvCD,EAAM7iD,OAND,kBAOEpsB,GAPF,2CAAP,sDAWF,SAASmvE,EAAMF,GACTA,EAAM7iD,KAAO,GAAsB,KAAf6iD,EAAM7iD,OAC5B6iD,EAAMH,SAAW,M,SAINM,E,0FAAf,WAAqBvhD,EAAMkhD,EAAMj9D,GAAjC,gGACQ+b,EADR,gCAESkhD,EAAI,WAAJ,IAAQj9D,KAFjB,4C,6PC1DA,IAAMu9D,GAAY,IAmBlB,SAASC,GAAUv6C,GACjB,GAAI9jB,MAAMC,QAAQ6jB,GAAO,4BADCzW,EACD,iCADCA,EACD,kBAIvB,OAHIA,EAAOliB,OAAS,GAgHxB,SAASmzE,EAAgBx6C,EAAMzW,GAC7B,IAAIxc,EAAQwc,EAAOzhB,QACnB,IAAIiU,EAeN,SAAaikB,EAAMjzB,GACjB,IAAIgP,EAON,SAAcikB,EAAMjzB,GAClB,GAAqB,iBAAVA,EAAoB,CAC7B,IAAK,IAAI5F,EAAI,EAAG4B,EAAIi3B,EAAK34B,OAAQF,EAAI4B,IAAK5B,EAAG,CAC3C,IAAIqb,EAAOwd,EAAK74B,GAChB,GAAIqb,IAASzV,GAAU0tE,GAAUj4D,IAASA,EAAK,KAAOzV,EACpD,OAAO5F,EAGX,OAAQ,EAEV,OAAQ,EAjBIylB,CAAKoT,EAAMjzB,IACR,IAAXgP,IACFA,EAAQikB,EAAKr4B,KAAKoF,GAAS,GAE7B,OAAOgP,EApBKo1C,CAAInxB,EAAMjzB,GACtB,GAAIgP,GAAS,EAAG,CACd,GAAIwN,EAAOliB,OAAS,EAAG,CACrB,IAAIqzE,EAAU16C,EAAKjkB,GAKnB,OAJK0+D,GAAUC,KACbA,EAwCR,SAAmB3tE,GACjB,MAAO,CAACA,EAAQ,GAAI,IAzCJ4tE,CAAU5tE,GACpBizB,EAAKjkB,GAAS2+D,GAETF,EAAgBE,EAAQ,GAAInxD,GAErC,OAAO,EAET,OAAO,EA7HHixD,CAAgBx6C,EAAMzW,GAEjByW,EAET,OAAO,KAgBT,SAASxb,GAAQwb,EAAMljB,GACrB,OAAIZ,MAAMC,QAAQ6jB,IACQ,mBAAbljB,GACT89D,GAAa56C,EAAMljB,GAEdkjB,GAEF,KAeT,SAAS66C,GAAQ76C,EAAM86C,GACrB,GAAI5+D,MAAMC,QAAQ6jB,GAAO,CACvB,IAAI+6C,EAAU,KACVh/D,EAA+B,iBAAhB++D,EAA2BA,GAAe,EAC7D,GAA2B,iBAAhBA,EAA0B,CACnC,IAAMrP,EAAYqP,EAAYtqD,QAAQ8pD,IAClC7O,EAAY,GACd1vD,EAAQgf,SAAS+/C,EAAY/sE,MAAM,EAAG09D,GAAY,IAC9CA,EAAY,EAAIqP,EAAYzzE,SAC9B0zE,EAAUD,EAAY/sE,MAAM09D,EAAY,EAAGqP,EAAYzzE,UAGzD0U,EAAQgf,SAAS+/C,EAAa,IAGlC,GAAI/+D,GAAS,GAAKA,EAAQikB,EAAK34B,OAAQ,CACrC,IAAMmb,EAAOwd,EAAKjkB,GAClB,OAAI0+D,GAAUj4D,GACI,OAAZu4D,EACKF,GAAQr4D,EAAK,GAAIu4D,GAEnBv4D,EAAK,GAEPA,IAUb,SAASw4D,GAAMh7C,GACb,IAAI9M,EAAO,GACX,GAAIhX,MAAMC,QAAQ6jB,GAAO,CACvB,IAAIlH,EAAO,GACX8hD,GAAa56C,GAAM,WAAkB,IACnC,IAAIi7C,EAAUniD,EAAKzxB,OADgB,mBAAN0V,EAAM,yBAANA,EAAM,gBAEnC,IAAK,IAAI5V,EAAI,EAAG4B,EAAIgU,EAAK1V,OAAQF,EAAI4B,IAAK5B,EACpCA,EAAI8zE,GAAWl+D,EAAK5V,KAAO2xB,EAAK3xB,KAGpC+rB,GAAQ,KAAKgoD,OAAO/zE,GAAK4V,EAAK5V,GAAK,MAErC2xB,EAAO/b,KAGX,OAAOmW,EAOT,SAAS0nD,GAAa56C,EAAMljB,GAC1B,IAAK,IAAI3V,EAAI,EAAG4B,EAAIi3B,EAAK34B,OAAQF,EAAI4B,IAAK5B,EAAG,CAC3C,IAAIqb,EAAOwd,EAAK74B,GAChB,GAAIszE,GAAUj4D,GAAO,CACnB,GAAIA,EAAK,GAAGnb,OAAS,EAAG,CACtBuzE,GAAap4D,EAAK,GAAI1F,EAASxP,KAAK,KAAMkV,EAAK,KAC/C,SAEFA,EAAOA,EAAK,GAEd1F,EAAS0F,IA0Cb,SAASi4D,GAAUjhC,GACjB,OACEt9B,MAAMC,QAAQq9B,IACK,IAAnBA,EAAQnyC,QACc,iBAAfmyC,EAAQ,IACft9B,MAAMC,QAAQq9B,EAAQ,I,uOC9K1B,IAAM2hC,GAAOtuE,OAAO,QACduuE,GAAOvuE,OAAO,QACdwuE,GAAOxuE,OAAO,QAUpB,SAASyuE,KACP,OAAOC,GAAeF,GAAM,CAC1BnvE,KAAM,KACNsvE,MAAOl0E,OAAO8F,OAAO,MACrBquE,UAAW,KASf,SAASC,GAAOliC,GACd,OAAOmiC,GAASN,GAAM7hC,GASxB,SAASoiC,GAAW57C,EAAMjH,GACxB,OAAOwiD,GAAeH,GAAM,CAC1Bp7C,KAAM07C,GAAO17C,GAAQA,EAAO,KAC5BjH,KAAM8iD,GAAO9iD,GAAQA,EAAO,KAC5BiS,QAAQ,EACR+uC,SAAU,KACV+B,SAAU,IASd,SAASD,GAAOriC,GACd,OAAOmiC,GAASP,GAAM5hC,GASxB,SAASuiC,GAAa/7C,GACpB,GAAI07C,GAAO17C,GAAO,CAChB,IAAMg6C,EAAO4B,GAAW57C,EAAMA,EAAK9zB,MAGnC,OAFA8zB,EAAK9zB,KAAO8tE,EACZl2B,GAAO9jB,EAAMg8C,GAAmBh8C,IACzBg6C,EAET,OAAO,KAWT,SAASiC,GAAOjC,EAAMjtE,GAChB8uE,GAAO7B,IAASkC,GAAgBnvE,IAAUA,EAAQ,GAChDitE,EAAK8B,WAAa/uE,IACpBitE,EAAK8B,SAAW/uE,EACZ2uE,GAAO1B,EAAKh6C,OACd8jB,GAAOk2B,EAAKh6C,KAAMg8C,GAAmBhC,EAAKh6C,QAalD,SAASm8C,GAAOnC,GACV6B,GAAO7B,KACTA,EAAK8B,SAAW,EAChB9B,EAAKD,SAAW,KAChBzyE,OAAO6kC,OAAO6tC,GACV0B,GAAO1B,EAAKh6C,OACd8jB,GAAOk2B,EAAKh6C,KAAMg8C,GAAmBhC,EAAKh6C,QAUhD,SAASg8C,GAAmBh8C,GAC1B,IAAMgpB,EAgJC1hD,OAAO80E,KAAK,CACjBC,MAAO,EACPC,QAAS,EACTR,SAAU,EACVS,SAAU,IAnJZ,GAAIb,GAAO17C,GAET,IADA,IAAIg6C,EAAOh6C,EAAK9zB,KACT2vE,GAAO7B,IACZhxB,EAAOqzB,QACHH,GAAgBlC,EAAK8B,YACvB9yB,EAAOszB,SAAWtC,EAAK8B,SACD,IAAlB9B,EAAK8B,UAAoB9B,EAAKhvC,QAAQge,EAAOuzB,YAEnDvC,EAAOA,EAAKjhD,KAMhB,OAHIiwB,EAAOqzB,MAAQ,IACjBrzB,EAAO8yB,SAAW9yB,EAAOszB,QAAUtzB,EAAOqzB,OAErC/0E,OAAO6kC,OAAO6c,GAWvB,SAASwzB,GAAOx8C,EAAMy8C,GACpB,IAAMzC,EAAO+B,GAAa/7C,GAC1B,OAAI67C,GAAO7B,IACTA,EAAKD,SAAW7wE,QAAQC,QAAQszE,GAAU1xE,MACxC,WACEoxE,GAAOnC,MAET,WACEA,EAAKhvC,QAAS,EACdmxC,GAAOnC,MAGJA,GAEF,KAST,SAAS0C,GAAY18C,GACnB,IAAM28C,EAAWhD,IACXK,EAAOwC,GAAOx8C,EAAM28C,EAAS1xE,SACnC,OAAO3D,OAAO6kC,OAAO,CACnBwwC,WACA3C,SAWJ,SAAS4C,GAAY58C,EAAMg6C,EAAMjuE,GAC/B,SAoGF,SAAkBi0B,EAAMg6C,GACtB,GAAI0B,GAAO17C,IAAS67C,GAAO7B,GAEzB,IADA,IAAIx3D,EAAOwd,EAAK9zB,KACT2vE,GAAOr5D,IAAO,CACnB,GAAIA,IAASw3D,EACX,OAAO,EAETx3D,EAAOA,EAAKuW,KAGhB,OAAO,EA7GLsH,CAASL,EAAMg6C,IACA,OAAfh6C,EAAKw7C,OACiB,WAAtB,GAAOx7C,EAAKw7C,QACI,iBAATzvE,KAEPi0B,EAAKw7C,MAAMzvE,GAAQiuE,GACZ,GAWX,SAAS6C,GAAc78C,EAAMj0B,GAC3B,GACE2vE,GAAO17C,IACQ,OAAfA,EAAKw7C,OACiB,WAAtB,GAAOx7C,EAAKw7C,QACI,iBAATzvE,EACP,CACA,IAAMiuE,EAAOh6C,EAAKw7C,MAAMzvE,GACxB,GAAI8vE,GAAO7B,GACT,OAAOA,EAGX,OAAO,KAUT,SAAS8C,GAAY98C,EAAM+8C,GACzB,SACErB,GAAO17C,KACP9jB,MAAMC,QAAQ6jB,EAAKy7C,YACC,mBAAbsB,KAEP/8C,EAAKy7C,UAAU9zE,KAAKo1E,IACb,GAWX,SAASC,GAAeh9C,EAAM+8C,GAC5B,GACErB,GAAO17C,IACP9jB,MAAMC,QAAQ6jB,EAAKy7C,YACnBz7C,EAAKy7C,UAAUp0E,OAAS,EACxB,CACA,IAAM0U,EAAQikB,EAAKy7C,UAAUjrD,QAAQusD,GACrC,GAAIhhE,GAAS,EAEX,OADAikB,EAAKy7C,UAAUlzE,OAAOwT,EAAO,IACtB,EAGX,OAAO,EAgBT,SAASw/D,GAAerxE,EAAMsD,GAC5B,OAAOlG,OAAO80E,KAAK90E,OAAOmF,eAAee,EAAQ2tE,GAAM,CAAEpuE,MAAO7C,KAGlE,SAASyxE,GAASzxE,EAAMsvC,GACtB,OACc,OAAZA,GAAuC,WAAnB,GAAOA,IAAwBA,EAAQ2hC,MAAUjxE,EAIzE,SAASgyE,GAAgBnvE,GACvB,MAAwB,iBAAVA,GAAsBA,GAAS,GAAOA,GAAS,EAgB/D,SAAS+2C,GAAO9jB,EAAMn5B,GAElB60E,GAAO17C,IACP9jB,MAAMC,QAAQ6jB,EAAKy7C,YACnBz7C,EAAKy7C,UAAUp0E,OAAS,GAExB24B,EAAKy7C,UAAU1tE,QAAQyW,SAAQ,SAASu4D,GACtC,GAAwB,mBAAbA,EACT,IACEA,EAASl2E,EAAMm5B,GACf,MAAOh3B,QC9RjB,IAAMmyC,GAAQ,CACZ7O,SACAonC,aACAO,cACAK,aACAp/B,WACA+nC,YCzBa,SAAqBC,EAAUpgE,GAC5C,IAAM3R,EAAS1B,SAASQ,cAAc,UACtCkB,EAAOX,IAAMypE,EAAYiJ,GACzB/xE,EAAOhB,OAAS,WACU,mBAAb2S,GACTA,EAAS3R,IAIb1B,SAAS6U,KAAKxT,YAAYK,IDiB1ByrE,YACAuG,iBACA7F,yBACA8F,qBACAC,UACA7E,iCACAmB,eACA2D,eEpCa,SAAwBb,GACrC,IAAIc,GAAa,EACXtyE,EAAU/B,QAAQC,QAAQszE,GAAU1xE,MACxC,SAAS7C,GACP,GAAIq1E,EAAY,MAAMj2E,OAAO6kC,OAAO,CAAEoxC,eACtC,OAAOr1E,KAET,SAASuD,GACP,GAAI8xE,EAAY,MAAMj2E,OAAO6kC,OAAO,CAAEoxC,aAAY9xE,UAClD,MAAMA,KAGV,OAAOnE,OAAOqhC,OAAOrhC,OAAO8F,OAAOnC,GAAU,CAC3CF,KAAME,EAAQF,KAAKuC,KAAKrC,GACxBuyE,OAF2C,WAGzCD,GAAa,MFsBjBx4D,YACA+0D,QACA2D,WGvCa,SAAoBjkC,GAEjC,MAA0B,iBAAZA,GADA,kBAC8BxM,KAAKwM,EAAQK,SHsCzD6jC,kBIxCa,SAASA,EAAkBl4B,EAAMmuB,EAAMziD,GACpD,GAAa,OAATs0B,GAAiC,WAAhB,GAAOA,IAAqC,iBAATmuB,EAAmB,CACzE,IAAI5mE,EACF0+D,EAAYkI,EAAKnjD,QAAQ,KAC3B,OAAIi7C,GAAa,EACRiS,EACLl4B,EAAKmuB,EAAK5lE,MAAM,EAAG09D,IACnBkI,EAAK5lE,MAAM09D,EAAY,EAAGkI,EAAKtsE,QAC/B6pB,QAIallB,KADjBe,EAAQy4C,EAAKmuB,UACkC3nE,IAAjBklB,EAC1BA,EACAnkB,IJ2BN4wE,wBACAC,wBACAt1B,yBA2BanN,Q,o9BKnEf,IAAM0iC,EAAO,aAEAC,EAAb,WAYE,WAAYjmD,EAASzM,GAAS,Y,4FAAA,0BAXpB,CACR4gD,MAAO,UACP+R,gBAAiB,EACjBC,cAAeH,EACfI,YAAa,WACbC,cAAc,EACdC,2BAA4B,IAC5BC,uBAAwB,IACxBC,yBAAyB,IAGG,2BAsgBX,WACjBrwE,IAAIC,KAAK,cACT,EAAKqwE,qBAvgBL3nE,KAAKkhB,QAAUA,GAAW,GAEtBzM,IACFzU,KAAKyU,QAAL,KAAoBzU,KAAKyU,QAAzB,GAAqCA,GACrCzU,KAAKyU,QAAQ6yD,YAAc,YAG7B75C,IAAYm6C,OAAOz+D,iBACjB,4CACAnJ,KAAK6nE,kB,UAtBX,O,EAAA,E,EAAA,qCA4C4C,IAAvB3mD,EAAuB,uDAAb,GAAIzM,EAAS,uCAUxC,OATK0yD,EAAgBnqC,WACnBmqC,EAAgBnqC,SAAW,IAAImqC,EAAgBjmD,EAASzM,IAGtDA,IACFzU,KAAKyU,QAAL,KAAoBzU,KAAKyU,QAAzB,GAAqCA,GACrCzU,KAAKyU,QAAQ6yD,YAAc,YAGtBH,EAAgBnqC,a,EAtD3B,iCA8BIh9B,KAAK2nE,kBACLl6C,IAAYm6C,OAAOx+D,oBACjB,4CACApJ,KAAK6nE,oBAjCX,iCA8Da3mD,GACTlhB,KAAK2nE,kBACL3nE,KAAKkhB,QAAUA,IAhEnB,mCAyEI,OAAOlhB,KAAK6I,UAzEhB,+BAoFWA,EAASgN,GAChB,GAAK7V,KAAKkhB,SAAYlhB,KAAKkhB,QAAQxwB,OAAnC,CAIAsP,KAAK6I,QAAUA,EACf,IACE7I,KAAK0uB,eAAiBjB,IAAYkB,kBAAkB9lB,GACpD,SACA,MAAM,IAAI9U,MAAM,sCAGlBiM,KAAK2nE,kBACL3nE,KAAK8nE,oBAAoBjyD,MAjG7B,wCAwGI4X,IAAYs6C,qBAAqBC,kBAAkB,cAxGvD,+CAiH2Bn/D,EAASnU,GAAS,WACzC,IACEsL,KAAK0uB,eAAiBjB,IAAYkB,kBAAkB9lB,GACpD,SACA,MAAM,IAAI9U,MAAM,sCAElBW,EAAUA,GAAWsL,KAAKyU,QAAQ+yD,2BAClCzyE,aAAaiL,KAAKioE,4BAClBjoE,KAAKioE,2BAA6B3yE,YAAW,WAC3C,EAAKwyE,oBAAoBj/D,KACxBnU,KA3HP,0CAoIsBmhB,GAClB,IAAMqyD,EAAwBloE,KAAKmoE,yBACjCtyD,GAEIuyD,EAAWpoE,KAAKqoE,2BAA2BH,GACjDloE,KAAKsoE,iBAAiBF,KAzI1B,uCAiJmBA,GAAU,IASrBG,EATqB,OACnBC,EAAoBxoE,KAAKyoE,qBAAqBL,GAC9CL,EAAuBt6C,IAAYs6C,qBAEzCA,EAAqBW,eAArB,KACKX,EAAqBW,eAD1B,CAEEC,SAAU3oE,KAAKyU,QAAQgzD,yBAKvBc,EADEvoE,KAAKyU,QAAQ8yD,aACH,SAAA/kE,GAAE,OAAIirB,IAAY1c,UAAUvO,IAE5B,SAAAA,GAAE,OAAIirB,IAAYkxC,kBAAkBn8D,IAGlDgmE,EAAkB36D,SAAQ,SAAAuwB,GACxB2pC,EAAqBa,WACnBL,EAAU5xE,KAAK,EAAMynC,GACrB,EAAK3pB,QAAQ6yD,YACb,CACElpC,iBAtKV,+BAkLW9O,GACP,IAAMha,EAAmBmY,IAAYo7C,SAAS7yE,IAC5C,mBACAs5B,EAAM8O,SAGR,OADgBp+B,KAAKkhB,QACNjL,MACb,SAAAC,GAAK,OAAIA,EAAMy8B,UAAUr9B,mBAAqBA,OAzLpD,gCAoMYY,EAAOoZ,GACf,IAAMoO,EAAoBjQ,IAAYo7C,SAAS7yE,IAC7C,oBACAs5B,EAAM8O,SAER,OAAOloB,EAAMq8C,eAAe70B,KAzMhC,kCAmNcb,EAAQvN,GAClB,IAAMo9B,EAAmBj/B,IAAYo7C,SAAS7yE,IAC5C,WACAs5B,EAAM8O,SAER,OAAOvB,EAAO4X,iBAAiBiY,EAAiB9uB,kBAxNpD,yCAiOqB/nB,GACjB,IAAImoB,EASJ,OARAh+B,KAAKkhB,QAAQrT,SAAQ,SAAAqI,GACnB,IAAMk4C,EAAKl4C,EAAMg4C,YAAYj4C,MAC3B,SAAAm4C,GAAE,OAAIA,EAAGv4C,wBAA0BA,KAEjCu4C,IACFpwB,EAAaowB,MAGVpwB,IA3OX,oDAqPgCkwB,EAAalxB,GACzC,OAAOkxB,EAAYj4C,MAAK,SAAA+nB,GACtB,OAAOA,EAAWE,OAAOo0B,MAAK,SAAAwW,GAC5B,OAAOA,EAAgBlrC,iBAAmBZ,EAASY,uBAxP3D,+CAkQI,GAAK59B,KAAK0uB,eAIV,OAAO1uB,KAAK0uB,eAAeY,QAtQ/B,+CA+Q2BzZ,GACvB,IAAMyZ,EAAQtvB,KAAK+oE,yBAEnB,IAAKz5C,EACH,MAAO,GAGT,IAAMpZ,EAAQlW,KAAKgpE,SAAS15C,GACtBuN,EAAS78B,KAAKipE,UAAU/yD,EAAOoZ,GAC/B0N,EAAWh9B,KAAKkpE,YAAYrsC,EAAQvN,GACpC4+B,EAAch4C,EAAMg4C,YACpBib,EAAmBtzD,EACrB7V,KAAKopE,mBAAmBvzD,GACxB7V,KAAKqpE,8BAA8Bnb,EAAalxB,GAU9CssC,EAAgBtpE,KAAKyU,QAAQ4gD,MAE7BkU,EAAiBvpE,KAVG,CACxBwpE,QAAS,sBACTC,SAAU,qBACVC,OAAQ,yBACRC,QAAS,wBACTn0E,IAAK,qBAI8B8zE,IAGrC,OAAKC,EAQEA,EAAez4E,KACpBkP,KACAkuD,EACAib,EACAnpE,KAAKyU,QAAQ2yD,gBACbpnE,KAAKyU,QAAQizD,0BAZT4B,GACFjyE,IAAIC,KAAJ,gDAAkDgyE,EAAlD,MAGK,MA/Sb,wCAqUIpb,EACAib,EACA/B,EACAM,GAKA,IAHA,IAAMh3E,EAASw9D,EAAYx9D,OACrBk5E,EAAsB,GAEnBp5E,EAAI,EAAGA,EAAIE,EAAQF,IAAK,CAC/B,IAAMwtC,EAAakwB,EAAY19D,GAC/Bo5E,EAAoB54E,KAAKgtC,GAG3B,OAAO4rC,IAlVX,0CA+VI1b,EACAib,EACA/B,EACAM,GAKA,IAHA,IAAMh3E,EAASw9D,EAAYx9D,OACrBk5E,EAAsB,GAEnBp5E,EAAI,EAAGA,EAAIE,GAAU02E,EAAiB52E,IAAK,CAClD,IAAMwtC,EAAakwB,EAAY19D,IAE3Bk3E,GAA2B1pC,IAAemrC,KAC5CS,EAAoB54E,KAAKgtC,GACzBopC,KAIJ,OAAOwC,IAhXX,6CA6XI1b,EACAib,EACA/B,EACAM,GAEA,IAAMmC,EAAwB3b,EAAYr0C,QAAQsvD,GAC5C1sD,EAAMirD,EACRmC,EAAwB,EACxBA,EAEJ,OAD4B3b,EAAY92D,MAAM,EAAGqlB,GACtB+hB,UAAUpnC,MAAM,EAAGgwE,KAvYlD,yCAoZIlZ,EACAib,EACA/B,EACAM,GAEA,IAAMmC,EAAwB3b,EAAYr0C,QAAQsvD,GAC5CW,EAAQpC,EACVmC,EACAA,EAAwB,EACtBptD,EAAMlJ,KAAKxD,IAAI+5D,EAAQ1C,EAAiBlZ,EAAYx9D,QAC1D,OAAOw9D,EAAY92D,MAAM0yE,EAAOrtD,KA9ZpC,4CA2aIyxC,EACAib,EACA/B,EACAM,GAEA,IAAMmC,EAAwB3b,EAAYr0C,QAAQsvD,GAC5Cz4E,EAASw9D,EAAYx9D,OACrBk5E,EAAsB,GACxBpiE,EAAOqiE,EAAwB,EAC/BE,EAAQF,EAAwB,EAOpC,IALInC,IACFkC,EAAoB54E,KAAKk9D,EAAY2b,IACrCzC,MAGM5/D,GAAQ,GAAKuiE,EAAQr5E,IAAW02E,GAClC5/D,GAAQ,IACVoiE,EAAoB54E,KAAKk9D,EAAY1mD,IACrC4/D,IACA5/D,KAGEuiE,EAAQr5E,GAAU02E,IACpBwC,EAAoB54E,KAAKk9D,EAAY6b,IACrC3C,IACA2C,KAIJ,OAAOH,IAzcX,iDAkd6B1b,GAAa,WAClCka,EAAW,GAMf,OAJAla,EAAYrgD,SAAQ,SAAAmwB,GAClBoqC,EAAWA,EAAShrC,OAAO,EAAK4sC,0BAA0BhsC,OAGrDoqC,IAzdX,gDAke4BpqC,GACxB,IAAMoqC,EAAW,GAEjB,OAAKpqC,EAAWE,QAAUF,EAAWE,OAAOxtC,OAAS,EAC5C,IAITstC,EAAWE,OAAOrwB,SAAQ,SAAAyhB,GACxB,IAAM26C,EAAY36C,EAAM26C,UACxB,GAAIA,EAAY,EACd,IAAK,IAAIz5E,EAAI,EAAGA,EAAIy5E,EAAWz5E,IAAK,CAClC,IAAI4tC,EAAUC,YAAW/O,EAAO9+B,GAChC43E,EAASp3E,KAAKotC,OAEX,CACL,IAAIA,EAAUC,YAAW/O,GACzB84C,EAASp3E,KAAKotC,OAIXgqC,KAvfX,2CAggBuBA,GAAU,WAC7B,OAAOA,EAAS36B,QAAO,SAAArP,GAAO,OAAK,EAAK8rC,cAAc9rC,QAjgB1D,oCA0gBgBA,GACZ,IAAM9O,EAAQ7B,IAAY08C,WAAWA,WAAW/rC,GAChD,OAAO9O,GAASA,EAAM86C,iB,2BA5gB1B,K,iyCCEMC,E,WACJ,WAAY3uD,GAAqB,IAAdjH,EAAc,uDAAJ,GAAI,UAC/BzU,KAAKwC,GAAK6nE,EAAoBC,WAC9BtqE,KAAK0b,MAAQA,EACb1b,KAAKuqE,gBAAkB91D,EAAQ81D,iBAAmB,EAClDvqE,KAAKwqE,MAAQ,CACX5xD,MAAO,GACP8sD,MAAO,EACP+E,YAAa,EACbC,MAAO,GAGT1qE,KAAK2qE,iBAAmBl2D,EAAQk2D,iBAChC3qE,KAAK4qE,mBAAqBn2D,EAAQm2D,mBAIlC5qE,KAAK6qE,cAAc,GAInB7qE,KAAK8qE,kB,gDAGO10E,GACZ,IAAM0U,EAAO,IAAI8S,KACX4sD,EAAQxqE,KAAKwqE,MACb5xD,EAAQ4xD,EAAM5xD,MACd40B,EAAU,CACdp3C,QACA0U,QAOF,IAJA8N,EAAM5nB,KAAKw8C,GACXg9B,EAAM9E,OAASl4B,EAAQp3C,MAGhBwiB,EAAMloB,OAASsP,KAAKuqE,iBAAiB,CAC1C,IAAM1+D,EAAO+M,EAAMznB,QACnBq5E,EAAM9E,OAAS75D,EAAKzV,MAKtB,GAAIwiB,EAAMloB,OAAS,EAAG,CACpB,IAAMq6E,EAAanyD,EAAM,GACzB4xD,EAAMC,aACHj9B,EAAQ1iC,KAAKkgE,UAAYD,EAAWjgE,KAAKkgE,WAAa,IACzDR,EAAME,OAASF,EAAM9E,MAAQqF,EAAW30E,OAASo0E,EAAMC,e,uCASzD,MAAO,iBADuBzqE,KAAK0b,MAAM7F,wB,uCAKzC,IAAMo1D,EAAajrE,KAAKkrE,iBACxBlrE,KAAK4qE,mBAAmBK,K,uCAIxB,MAAM,IAAIl3E,MAAM,2D,sCAIhB,MAAM,IAAIA,MAAM,0D,gCAIhBiM,KAAKmrE,gBACLnrE,KAAKorE,oB,kCAIL,IAAMC,GAAY,IAAIztD,MACnBotD,UACAj/C,WACA30B,OAAO,GACJk0E,EAAelnD,SAAyB,IAAhB7Q,KAAK0R,UAEnC,OAAOomD,EAAUt/C,WAAau/C,EAAav/C,e,KAIzCw/C,E,YACJ,WAAY7vD,EAAOjH,GAAS,2BAC1B,wBAAMiH,EAAOjH,KADa,kCAwDK,SAAApiB,GAC/B,IAAM88B,EAAY98B,EAAEmlB,OACdg0D,EAAa,EAAKC,4BAA4Bt8C,EAAUiP,SACxDstC,EAAYv8C,EAAUw8C,OAAS,EAAKC,aAErC,EAAKC,cAAgBL,IAK1B,EAAKX,cAAca,GAGnB,EAAKZ,gBAAgB37C,GAGrB,EAAKy8C,YAAcz8C,EAAUw8C,WArE7B,EAAKG,8BAAgC,EAAKC,+BAA+Bp1E,KAApC,MAIrC,EAAKk1E,YAAc,EAAKG,eAAetwD,GACvC,EAAKkwD,YAAc,EAGnB,EAAKK,mBAEL,EAAKC,iBAbqB,E,4DAiB1B,IAAMC,EAAUlN,IAA2B/J,QAAQkX,oBAAoBp2E,IACrEgK,KAAK6rE,aAGP,GAAIM,EAAS,CACX,IAAME,EAAgBF,EAAQjxB,UAAUxqD,OAExCsP,KAAK8qE,gBAAgB,CACnBwB,gBAAiB,IACjBX,OAAQU,EACR3G,MAAO2G,O,uDAOX,MAAO,gCAAkCrsE,KAAKwC,K,uCAI9C,IAAM+pE,EAA6BvsE,KAAKwsE,iCAExCxsE,KAAKmrE,gBAEL19C,IAAYm6C,OAAOz+D,iBACjBojE,EACAvsE,KAAKysE,gC,sCAKP,IAAMF,EAA6BvsE,KAAKwsE,iCACxC/+C,IAAYm6C,OAAOx+D,oBACjBmjE,EACAvsE,KAAKysE,gC,sCAuBOt9C,GACd,IAAM87C,EAAajrE,KAAKkrE,iBAGlBwB,EAAe,CACnBC,YAAY,EACZL,iBAJFn9C,EAAYA,GAAa,IAIIm9C,gBAC3BM,YAAaz9C,EAAUw8C,OACvBkB,WAAY19C,EAAUu2C,MACtBoH,eAAgB9sE,KAAKwqE,MAAME,OAG7B1qE,KAAK2qE,iBAAiBM,EAAYyB,K,kDAGRtuC,GAU1B,OAFAA,GAHAA,GAHAA,EAAUA,EAAQjrB,QAAQ,yBAA0B,KAGlCA,QAAQ,eAAgB,KAGxBA,QAAQ,KAAM,M,qCAKnBuI,GACb,IAAM0iB,EAAU1iB,EAAM0sD,SAAS,GAC/B,OAAOpoE,KAAKyrE,4BAA4BrtC,O,GA1GLisC,GA8GjC0C,EAA6B,CACjCC,WAAY,yCAGd,SAASC,EAAa34E,EAAS6R,GAE7B,IAAI+mE,EAAch2E,OAAM,OAAahB,OAAO,UAAY,SAcxD,IAAIi3E,EAAO,CAAC74E,EAAS/B,QAAQC,QAAQ06E,IACrC36E,QAAQ46E,KAAKA,GAAM/4E,MAbnB,SAAiCgC,GAC/B,OACS+P,EADL/P,IAAU82E,EACI,UAEA,gBAIpB,SAAwBE,GACtB,OAAOjnE,EAAS,e,IAOdknE,E,YACJ,WAAY3xD,GAAqB,MAAdjH,EAAc,uDAAJ,GAAI,UAC/BA,EAAQ81D,gBAAkB,IAE1B,wBAAM7uD,EAAOjH,KAER64D,wBAA0B,EAAKC,yBAAyB52E,KAA9B,MAC/B,EAAK62E,qCAAuC,EAAKC,sCAAsC92E,KAA3C,MAI5C,EAAK+2E,aAAe,EAAKC,2BAA2BjyD,EAAM0sD,UAC1D,EAAKwF,aAAe,EAAKC,aAAanyD,EAAM0sD,SAAS13E,QAAQ,GAC7D,EAAKo9E,YAAc,EAGnB,EAAKC,0BAA4BC,KAAS,WAAa,OACrD,KAAKrD,iBAAL,mBAGA,IAAMsD,EAAkB9G,EAAgB+B,cACxC+E,EAAgBtF,SAASsF,EAAgBC,gBACxC,KArB4B,OAuB/B,EAAKjC,kBADa,GAGlB,EAAKC,iBAzB0B,E,oEA4BN9D,GAGzB,IAFA,IAAM+F,EAAc,IAAIv0C,IAEfppC,EAAI,EAAGA,EAAI43E,EAAS13E,OAAQF,IACnC29E,EAAYjzC,IAAIktC,EAAS53E,GAAI,CAC3B4U,MAAO5U,EACPm7E,QAAQ,IAIZ,OAAOwC,I,mCAGIz9E,EAAQ6pB,GAKnB,IAFA,IAAMpP,EAAQ,GAEL3a,EAAI,EAAGA,EAAIE,EAAQF,IAC1B2a,EAAM3a,GAAK+pB,EAGb,OAAOpP,I,oCASKizB,GACZ,IAAM9O,EAAQ7B,IAAY08C,WAAWA,WAAW/rC,GAChD,OAAO9O,GAASA,EAAM86C,c,yCAMtB,IAHkC,WAAnBgE,EAAmB,wDAC5BhG,EAAWpoE,KAAK0b,MAAM0sD,SADM,WAGzB53E,GACP,IAAM4tC,EAAUgqC,EAAS53E,GAEnB69E,EAAc5gD,IAAY08C,WAAWmE,mBAAmBlwC,GAE1D,EAAK8rC,cAAc9rC,IACrB,EAAKmwC,mBAAmBnwC,GAAS,EAAMgwC,GAGrCC,GAAeA,EAAY/5E,SAC7B24E,EAAaoB,EAAY/5E,SAAS,SAAAsL,GAClB,cAAVA,GACF,EAAK2uE,mBAAmBnwC,GAAS,EAAMgwC,OAZtC59E,EAAI,EAAGA,EAAI43E,EAAS13E,OAAQF,IAAK,EAAjCA,K,iDAoBT,gBAAUi9B,IAAY4f,OAAOmhC,aAA7B,YAA6CxuE,KAAKwC,M,6DAIlD,gBAAUirB,IAAY4f,OAAOohC,4BAA7B,YAA4DzuE,KAAKwC,M,+CAG1CnQ,GACvB2N,KAAKuuE,mBAAmBl8E,EAAEmlB,OAAO8X,MAAM8O,SAAS,K,4DAGZ/rC,GACpC2N,KAAKuuE,mBAAmBl8E,EAAEmlB,OAAO4mB,SAAS,K,uCAI1C,IAAMswC,EAAuB1uE,KAAK2uE,2BAC5BC,EAAoC5uE,KAAK6uE,uCAE/C7uE,KAAKmrE,gBAEL19C,IAAYm6C,OAAOz+D,iBACjBulE,EACA1uE,KAAKstE,yBAEP7/C,IAAYm6C,OAAOz+D,iBACjBylE,EACA5uE,KAAKwtE,wC,sCAKP,IAAMkB,EAAuB1uE,KAAK2uE,2BAC5BC,EAAoC5uE,KAAK6uE,uCAE/CphD,IAAYm6C,OAAOx+D,oBACjBslE,EACA1uE,KAAKstE,yBAEP7/C,IAAYm6C,OAAOx+D,oBACjBwlE,EACA5uE,KAAKwtE,wC,yCAIUpvC,EAASutC,EAAQyC,GAClC,IAAMU,EAAY9uE,KAAK0tE,aAAa13E,IAAIooC,GAEnC0wC,GAAaA,EAAUnD,SAAWA,IAKnCA,GACF3rE,KAAK6qE,cAAc,GAGrBiE,EAAUnD,OAASA,EACnB3rE,KAAK4tE,aAAakB,EAAU1pE,OAASumE,EACrC3rE,KAAK8tE,aAAenC,EAAS,GAAK,EAClC3rE,KAAK8qE,gBAAgBsD,M,uCAGNnD,EAAYyB,GAO3B,MAAM,IAAI34E,MACR,sF,yCAIek3E,GACjB,MAAM,IAAIl3E,MACR,wF,sCAIYq6E,GACd,IAAMW,EAAmB/uE,KAAK0b,MAAM0sD,SAAS13E,OACvCs+E,EAAoBhvE,KAAK8tE,YACzBmB,EAAqBF,EAAmBC,EACxC1C,EAAkB/4D,KAAK27D,KAC1BF,EAAoBD,EAAoB,KAErC9D,EAAajrE,KAAKkrE,iBAClBwB,EAAe,CACnBC,YAAY,EACZoC,mBACAC,oBACAC,qBACA3C,kBACA6C,gBAAiBnvE,KAAKwqE,MAAME,MAC5BkD,aAAc5tE,KAAK4tE,cAGjBQ,EACFpuE,KAAK+tE,0BAA0B9C,EAAYyB,GAI7C1sE,KAAK2qE,iBAAiBM,EAAYyB,K,qCAQlC,IAJA,IAAMqC,EAAmB/uE,KAAK0b,MAAM0sD,SAAS13E,OACvCmlB,EAAwB7V,KAAK0b,MAAM7F,sBACrCu5D,EAAc,IAET5+E,EAAI,EAAGA,EAAIu+E,EAAkBv+E,IAAK,CACzC,IAAM6+E,EAAKrvE,KAAK4tE,aAAap9E,GAAK,IAAM,IACxC4+E,GAAe,GAAJ,OAAOC,GAGpBD,GAAe,IACfp4E,QAAQO,KAAR,UAAgBse,EAAhB,aAA0Cu5D,Q,GA9MX/E,GAkN7BiF,E,WAGJ,WAAY76D,GAAS,UACnBzU,KAAKuvE,UAAY,GACjBvvE,KAAKyU,QAAUA,E,2CAGRiH,EAAO8zD,GAEd,GAAK9zD,EAAL,CAKA,IAAM7F,EAAwB6F,EAAM7F,sBAEpC,IAAK7V,KAAKuvE,UAAU15D,GAAwB,CAC1C,IAAM45D,EAAWzvE,KAAK0vE,gBAAgBh0D,EAAO8zD,GACzCC,IACFzvE,KAAKuvE,UAAU15D,GAAyB45D,O,+BAKrCv5D,GAAO,WACdA,EAAMg4C,YAAYrgD,SAAQ,SAAAmwB,GACxB,IAAMtiB,EAAQ8qD,IAAamJ,kBAAkBz5D,EAAO8nB,GAGpD,IAAKtiB,EAGH,OAFA1kB,QAAQM,KAAK,2DACbN,QAAQM,KAAK0mC,GAIf,EAAK4xC,SAASl0D,EAAO,CACnBk1C,aAAc5yB,EAAW4yB,oB,iCAKpB1vC,GAAS,WACbA,GAAYA,EAAQxwB,QAIzBwwB,EAAQrT,SAAQ,SAAAqI,GAAK,OAAI,EAAK25D,SAAS35D,Q,8BAOvC,IAHA,IAAM45D,EAAyBn/E,OAAO4c,KAAKvN,KAAKuvE,WAC1C7+E,EAASo/E,EAAuBp/E,OAE7BF,EAAI,EAAGA,EAAIE,EAAQF,IAAK,CAC/B,IAAMqlB,EAAwBi6D,EAAuBt/E,GAClCwP,KAAKuvE,UAAU15D,GAEvBk6D,UAGb/vE,KAAKuvE,UAAY,K,sCAGH7zD,EAAO8zD,GAQrB,MAAe,WAPAxvE,KAAKgwE,WAAWt0D,IAOH8zD,EAAc5e,aAGjC,IAAI2a,EAAyB7vD,EAAO1b,KAAKyU,SAFzC,IAAI44D,EAAqB3xD,EAAO1b,KAAKyU,W,iCAMrCiH,GACT,IAAM0iB,EAAU1iB,EAAM0sD,SAAS,GAC/B,GAAKhqC,EAAL,CAGA,IAAM6xC,EAAa7xC,EAAQvkB,QAAQ,KACnC,OAAOukB,EAAQ4S,UAAU,EAAGi/B,O,mCAGXx7D,GAIjB,IAAMm2B,EAAkB,CACtB+/B,iBAAkB,SAACM,EAAYyB,GAC7B,IAAMh5E,EAAQ,IAAI+tE,YAAYsL,EAA2BC,WAAY,CACnEx1D,OAAQ,CAAEyzD,aAAYyB,kBAExB55E,SAAS4uE,cAAchuE,IAEzBk3E,mBAAoB,SAAAK,GAClB,IAAMv3E,EAAQ,IAAI+tE,YAAYsL,EAA2BC,WAAY,CACnEx1D,OAAQ,CAAEyzD,aAAYqB,gBAAiB,KAEzCx5E,SAAS4uE,cAAchuE,KAU3B,OANK47E,EAAqBrkB,YACxBqkB,EAAqBrkB,UAAY,IAAIqkB,EACnC76D,GAAWm2B,IAIR0kC,EAAqBrkB,c,OAjH1BqkB,E,SACYvC,G,2LCzblB,IAAMmD,EAAiBh6E,OAAO,iBACxBi6E,EAAsBj6E,OAAO,sBAQdk6E,E,WACnB,c,4FAAc,SACZpwE,KAAKkwE,GAAkB,GACvBlwE,KAAKmwE,GAAuB,E,yDAUpBE,EAAWlqE,GACnB,QAAkB9Q,IAAdg7E,EACF,MAAM,IAAIt8E,MAAM,0BAGlB,GAAwB,mBAAboS,EACT,MAAM,IAAIpS,MAAM,+BAGbiM,KAAKkwE,GAAgBr/E,eAAew/E,KACvCrwE,KAAKkwE,GAAgBG,GAAa,IAGpC,IAAMC,EAAiB,MAAH,OAAStwE,KAAKmwE,MAClCnwE,KAAKkwE,GAAgBG,GAAWC,GAAkBnqE,I,kCAUxCkqE,EAAWlqE,GACrB,IAAMoqE,EAAYvwE,KAAKkwE,GAAgBG,IAAc,GACrD,IAAK,IAAIC,KAAkBC,EACpBpqE,EAEMoqE,EAAUD,KAAoBnqE,UAChCoqE,EAAUD,UAFVC,EAAUD,K,8BAcfD,GACN,QAAkBh7E,IAAdg7E,EACF,MAAM,IAAIt8E,MAAM,0BAFW,IAK7B,IAAMw8E,EAAYvwE,KAAKkwE,GAAgBG,IAAc,GALxB,mBAATG,EAAS,iCAATA,EAAS,kBAM7B,IAAK,IAAIF,KAAkBC,EACzBA,EAAUD,GAAV,MAAAC,EAA6BC,Q,6lBCpE5B,IAAMC,EAAY9/E,OAAO6kC,OAAO,CACrC8X,MAAO,UAaM,M,6UAJJmjC,G,0VADcL,I,01BCLlB,IAAMM,GAAb,gC,4FAAA,8C,UAAA,O,mOAAA,M,EAAA,E,EAAA,+CAyDiCj0C,GAC7B,IAAMk0C,EAAYl0C,EAAckW,UAGhCg+B,EAAUjoD,UAAW,EACrBioD,EAAUziB,YAAczxB,EAAc8sC,iBACtC5I,IAAqBnmB,IAAI/d,O,EA/D7B,wCAOmBod,EAAQmG,GACvB,OAAOmc,YAAsBtiB,EAAQmG,KARzC,gCAeY9pC,GAAO,WACf,KAAMA,aAAiBqjB,KACrB,MAAM,IAAItF,IACR,gFAIJ,OAAO,IAAI1hC,SAAQ,SAACC,EAASC,GAC3B,IAAMutD,EAAmB9pC,EAAMunB,sBAE/B,GAAIvnB,aAAiBqjB,IAUnB,OATsB/J,KAAKoV,OAAOgsC,QAAQnmB,OAAO,CAC/Cn1C,iBAAkB0qC,KAIlB0wB,EAAwBG,wBAAwB36D,QAGlD1jB,EAAQ0jB,GAIV,EAAK46D,iBAAiB9wB,GACnB5rD,MAAK,SAAAu8E,GAEJ,IAAMl0C,EAAgB,IAAIlD,IACxBo3C,EACAA,EAAUr7D,kBAIQmnB,EAAcs0C,oBAElCL,EAAwBG,wBAAwBp0C,GAChDjqC,EAAQiqC,MAETlR,MAAM94B,W,6BApDf,GAA6ConC,K,UC4BvCze,GAAU,CACds1D,2BACAM,qBACA5sC,oBACAE,mBACAqI,aACA6iB,aACA4gB,SACAjJ,kBACAmI,uBACAjC,uBACA9B,2BACAhyC,kBACA8a,mBACAzgB,qBACA22B,wBACAt2B,cACA4F,yBAGaze,Q,6BCvDf,8CAEM61D,EAAc,CAClBr5E,IAAmBC,gCACnBD,IAAmBE,uCACnBF,IAAmBG,qCACnBH,IAAmBI,kDACnBJ,IAAmBK,gDACnBL,IAAmBM,gDACnBN,IAAmBO,8CACnBP,IAAmBQ,eACnBR,IAAmBS,uBACnBT,IAAmBU,sCACnBV,IAAmBW,iCACnBX,IAAmBY,eACnBZ,IAAmBa,uBACnBb,IAAmBe,4BACnBf,IAAmBgB,sCACnBhB,IAAmBiB,uBACnBjB,IAAmBmB,6BACnBnB,IAAmBoB,gDACnBpB,IAAmBqB,oDACnBrB,IAAmBsB,oDACnBtB,IAAmBuB,gDACnBvB,IAAmBsC,6BACnBtC,IAAmBuC,uBACnBvC,IAAmBwC,kCACnBxC,IAAmByC,wBACnBzC,IAAmB0C,+BACnB1C,IAAmB2C,+BACnB3C,IAAmB4C,gCACnB5C,IAAmB6C,gDACnB7C,IAAmB8C,8CACnB9C,IAAmB+C,mEACnB/C,IAAmBgD,iEACnBhD,IAAmBiD,4BACnBjD,IAAmB2D,yBACnB3D,IAAmB4D,4BACnB5D,IAAmB6D,0BACnB7D,IAAmB8D,6BACnB9D,IAAmB+D,0CACnB/D,IAAmBgE,2BACnBhE,IAAmBiE,8BACnBjE,IAAmBkE,sCACnBlE,IAAmBmE,uCACnBnE,IAAmBqE,iCACnBrE,IAAmBsE,mCACnBtE,IAAmBiG,uCACnBjG,IAAmBkG,wBACnBlG,IAAmBmG,uCACnBnG,IAAmBqG,gBAQRg/B,EAAU,SAAA+jB,GACrB,QAAKA,IACwC,IAAtCiwB,EAAYp3D,QAAQmnC,K,sCC5D7B,sCAAMkwB,EAA0BvgF,OAAO6kC,OAAO,CAC5C,MACA,MACA,WACA,KACA,KACA,OAGa,SAAS08B,EAAsBhlC,GAC5C,OAAOgkD,EAAwBpjE,SAASof,K,4CCT3B,SAASqR,IACtB,IAAI4yC,EAAS,GAAG/5E,MAAMtG,KAAK2X,WACzB2oE,EAAWD,EAAOzgF,OAEpB,OAAO,SAAS2gF,EAAGvhD,GACjB,IAAIa,EAAGC,EAAGnR,EAAO/oB,EAAK8nC,EAASjtC,EAAQf,EAEvC,IAAKA,EAAI,EAAGA,EAAI4gF,IACd7/E,EAAS,EAKTo/B,EAAI0gD,EAFJ36E,EAAuB,iBAFvB+oB,EAAQ0xD,EAAO3gF,IAEmBivB,EAAQA,EAAMrqB,MAGhDw7B,EAAId,EAAEp5B,QAEsB,IAAjB+oB,EAAM6xD,SACf3gD,EAAIlR,EAAM6xD,OAAO3gD,GACjBC,EAAInR,EAAM6xD,OAAO1gD,IAGnB4N,EAAU/e,EAAM+e,SAAW,EAAI,EAE3B7N,EAAIC,IACNr/B,GAAoB,EAAXitC,GAGP7N,EAAIC,IACNr/B,EAAmB,EAAVitC,GAGI,IAAXjtC,GAxBoBf,KA6B1B,OAAOe,GArCX,mC,6BCAA,6BAIIggF,EAAW,GACXC,EAAgB,GACdC,EAAwB,GAoF9BD,EAAgB,CACdE,kBA1EF,SAA2BH,EAAUr7D,EAAO8nB,EAAYyzC,GACtD,IAAMvzC,EAASF,EAAWE,OAC1B,GAAKA,EAAL,CAIA,IAEIE,EAFEuzC,EAAYzzC,EAAOxtC,OACnB03E,EAAW,GAGjBpqC,EAAWE,OAAOrwB,SAAQ,SAACmvB,EAAU40C,GACnC,IAAMtiD,EAAQ0N,EAAS2V,UACjBk2B,EAAW,CACf7rC,SAAU1N,EACVuN,OAAQmB,EACR9nB,QACAy7D,YACAC,WAAYA,EAAa,GAGrBC,EAAsB70C,EAAS2V,UAAU9e,SACzCg4B,EAAiBgmB,EAAoBhmB,eAE3C,GAAIA,EAAiB,EACnB,IAAK,IAAIr7D,EAAI,EAAGA,EAAIq7D,EAAgBr7D,IAAK,CACvCq4E,EAASiJ,YAActhF,EACvB4tC,EAAUC,YAAW/O,EAAO9+B,GAC5B43E,EAASp3E,KAAKotC,GAHyB,MASnCpB,EAAS2V,UAAU9e,SAHrBve,EANqC,EAMrCA,iBACAooB,EAPqC,EAOrCA,kBACAE,EARqC,EAQrCA,eAGFlQ,IAAiBqkD,iBAAiB3zC,EAAS,CACzC9oB,mBACAooB,oBACAE,uBAGC,CACLirC,EAASiJ,YAAc,EACvB1zC,EAAUC,YAAW/O,GACrB84C,EAASp3E,KAAKotC,GAHT,IAMH9oB,EAGEu8D,EAHFv8D,iBACAooB,EAEEm0C,EAFFn0C,kBACAE,EACEi0C,EADFj0C,eAGFlQ,IAAiBqkD,iBAAiB3zC,EAAS,CACzC9oB,mBACAooB,oBACAE,uBAKN,IAAMliB,EAAQ,CACZpG,iBAAkBY,EAAMZ,iBACxBO,sBAAuBmoB,EAAWnoB,sBAClCuyD,WACAlX,UAAWlzB,EAAWkzB,UACtBJ,OAAQ9yB,EAAW8yB,QAKrB,OAFAygB,EAASvzC,EAAWnoB,uBAAyB6F,EAEtCA,KAYT,IAAM8qD,EAAe,CAInBwL,YAJmB,WAKjBT,EAAW,IAQbU,gBAbmB,SAaH/7D,EAAO8nB,GACrB,OAAOwzC,EAAcE,kBACnBH,EACAr7D,EACA8nB,EACAyzC,IAQJS,UA1BmB,SA0BTr8D,GACR,OAAO07D,EAAS17D,IAQlB85D,kBAnCmB,SAmCDz5D,EAAO8nB,GACvB,IAAItiB,EAAQ1b,KAAKkyE,UAAUl0C,EAAWnoB,uBAMtC,OAJK6F,GAAUA,EAAM0sD,WACnB1sD,EAAQ1b,KAAKiyE,gBAAgB/7D,EAAO8nB,IAG/BtiB,GAOTy2D,aAjDmB,WAkDjB,OAAOZ,GAOTa,wBAzDmB,SAyDKjsE,GACtB,GAAwB,mBAAbA,EACT,MAAM,IAAI8tB,IAAU,2CAEtBw9C,EAAsBzgF,KAAKmV,IAK7BksE,iBAlEmB,WAmEjB,OAAOb,GASTc,iBA5EmB,SA4EFljD,GACfoiD,EAAgBpiD,IAKLo3C,O,sdChLf,IAAM+L,EAAqB,IACrBC,EAAY,MACZC,EAAa,OACbC,EAAY,EAMLnoB,EAAb,WACE,c,4FAAc,SACZvqD,KAAK2yE,gBAAkBD,EACvB1yE,KAAK4yE,aAAe,GACpB5yE,KAAK6yE,UAAYliF,OAAO8F,OAAO,M,UAJnC,O,EAAA,G,EAAA,qCAYI,IAAIs2C,EAAQ/sC,KAAK2yE,gBACjB3yE,KAAK2yE,gBAAkB5lC,EAlBT,WAkB6BA,EAAQ,EAAI2lC,IAb3D,gCAgBYI,GAER,OADW,IAAXA,GAAmB9yE,KAAK2yE,gBACjB3yE,KAAK4yE,eAlBhB,0CAqBsBpC,EAASsC,GAC3B,OAAO9yE,KAAK+yE,UAAUD,GAAQ78D,MAAK,SAAApK,GAAI,OAAIA,EAAK2kE,UAAYA,OAtBhE,qCAyBiBhuE,EAAIswE,GACjB,OAAO9yE,KAAK+yE,UAAUD,GAAQ78D,MAAK,SAAApK,GAAI,OAAIA,EAAKrJ,KAAOA,OA1B3D,+BA6BW9O,EAAOxD,GACd,IAAI8iF,EAAWhzE,KAAK6yE,UACpB,GAAIn/E,KAASs/E,EAAU,CAErB,MADAA,EAAWA,EAASt/E,cACM6R,OACxB,OAEF,IAAK,IAAI/U,EAAI,EAAGmW,EAAQqsE,EAAStiF,OAAQF,EAAImW,IAASnW,EAAG,CACvD,IAAIg4B,EAAUwqD,EAASxiF,GACnByiF,EAAYzqD,IACdA,EAAQ13B,KAAK,KAAMZ,OAvC7B,+BAiDWiW,GACP,GAAI8sE,EAAY9sE,GAAW,CACzB,IAAI6sE,EAAWhzE,KAAK6yE,UAAUroB,OACxBwoB,aAAoBztE,QACxBytE,EAAW,GACXhzE,KAAK6yE,UAAUroB,OAASwoB,GAE1BA,EAAShiF,KAAKmV,MAxDpB,iCAkEa3D,EAAIguE,GACb,IAAIj/E,GAAS,EACXmjD,EAAQ10C,KAAKkzE,oBAAoB1C,GAAS,GAgB5C,OAfI97B,EAEEA,EAAMlyC,KAAOA,IAEfjR,GAAS,EACTyO,KAAKmzE,gBAGPz+B,EAAQ10C,KAAKozE,eAAe5wE,GAAI,MAE9BkyC,EAAM87B,QAAUA,EAChBj/E,GAAS,EACTyO,KAAKmzE,eAGF5hF,IApFX,6BA6FSi/E,GACL,IAAIj/E,GAAS,EAOb,OANUyO,KAAKkzE,oBAAoB1C,GAAS,KAG1Cj/E,GAAS,EACTyO,KAAKmzE,eAEA5hF,IArGX,6BA8GSi/E,GACL,IAAIhuE,EAAK,KAQT,OAPUxC,KAAKkzE,oBAAoB1C,GAAS,KAE1ChuE,EAAKmzB,cACL31B,KAAK+yE,WAAU,GAAM/hF,KAAK,CAAEwR,KAAIguE,YAChCxwE,KAAKmzE,cACLnzE,KAAKqzE,SAAS,SAAU,CAAE7wE,KAAItS,KAAMsgF,KAE/BhuE,IAvHX,kCAiII,IAFA,IAAIhN,EAAMwK,KAAK+yE,WAAU,GACvBriF,EAAS8E,EAAI9E,OACNF,EAAIE,EAAS,EAAGF,GAAK,EAAGA,IAAK,CACpC,IAAIqb,EAAOrW,EAAIhF,UACRqb,EAAKrJ,UACLqJ,EAAK2kE,QACZh7E,EAAIhF,GAAK,KAEXgF,EAAI5D,OAAO,EAAGlB,GACdsP,KAAKmzE,gBAxIT,6BAgJSG,GACL,IAAI5+B,EAAQ10C,KAAKuzE,iBAAiBD,GAChCE,EAAa9+B,EAAMhkD,OACnB+iF,EAAU,GACZ,GAAID,EAAa,EAAG,CAElB,IADA,IAAMh+E,EAAMwK,KAAK+yE,WAAU,GAClBviF,EAAIgjF,EAAa,EAAGhjF,GAAK,EAAGA,IAAK,CACxC,IAAIqb,EAAO6oC,EAAMlkD,GACjBgF,EAAI5D,OAAOia,EAAK,GAAI,GACpB4nE,EAAQziF,KAAK6a,EAAK,IAEpB7L,KAAKmzE,cAEP,OAAOM,IA7JX,mCAqKejD,GACX,IAAI97B,EAAQ10C,KAAKkzE,oBAAoB1C,GACrC,OAAO97B,GAASA,EAAMlyC,KAvK1B,+BA+KWA,GACP,IAAIkyC,EAAQ10C,KAAKozE,eAAe5wE,GAChC,OAAOkyC,GAASA,EAAM87B,UAjL1B,qCAyLiBA,GACb,OAAOxwE,KAAK+yE,YAAYl5D,QAAQ7Z,KAAKkzE,oBAAoB1C,GAAS,MA1LtE,gCAkMYhuE,GACR,OAAOxC,KAAK+yE,YAAYl5D,QAAQ7Z,KAAKozE,eAAe5wE,GAAI,MAnM5D,wCA2MoB4C,GAChB,IAAIsvC,EAAQ10C,KAAK+yE,YAAY3tE,GAAS,EAAIA,GAAS,GACnD,OAAOsvC,GAASA,EAAM87B,UA7M1B,2BAwNOrqE,GAAU,IACTuuC,EADS,OAOb,OALIu+B,EAAY9sE,KACduuC,EAAQ10C,KAAK+yE,YAAY98D,MAAK,SAACpK,EAAMzG,GACnC,OAAOe,EAASrV,KAAK,EAAM+a,EAAK2kE,QAAS3kE,EAAKrJ,GAAI4C,OAG/CsvC,GAASA,EAAM87B,UA/N1B,6BA0OS8C,EAAa7+D,GAClB,IAAIigC,EACJ,GAAIg/B,EAAUj/D,GAAU,CAGtB,IAAMjf,EAAMwK,KAAKxK,IAAIif,GACjBjf,EAAI9E,OAAS,IAEbgkD,EADEg/B,EAAUJ,GACJ99E,EAAIygB,MAAK,SAAApK,GAAI,OACnB8nE,EAA4BL,EAAaznE,MAGnCrW,EAAI,SAGPk+E,EAAUJ,KACnB5+B,EAAQ10C,KAAK+yE,YAAY98D,MAAK,SAAApK,GAAI,OAChC8nE,EAA4BL,EAAaznE,EAAK2kE,eAG9C97B,EAAQA,EAAM87B,SAGlB,OAAO97B,IAjQX,uCA2QmB4+B,GACf,IAAM5+B,EAAQ,GASd,OARIg/B,EAAUJ,IACZtzE,KAAK+yE,YAAYllE,SAAQ,SAAChC,EAAMzG,GAC1BuuE,EAA4BL,EAAaznE,EAAK2kE,UAEhD97B,EAAM1jD,KAAK,CAAC6a,EAAK2kE,QAAS3kE,EAAKrJ,GAAI4C,OAIlCsvC,IArRX,gCAiSY4+B,EAAa7+D,GACrB,IAAMigC,EAAQ10C,KAAKuzE,iBAAiBD,GAAa3yE,KAAI,SAAAkL,GAAI,OAAIA,EAAK,MAMlE,OALI6nE,EAAUj/D,IACR,SAAUA,GACZm/D,EAAYl/B,EAAOjgC,EAAQ0M,MAGxBuzB,IAxSX,8BAkTUvuC,GAAU,WACZ8sE,EAAY9sE,IACdnG,KAAK+yE,YAAYllE,SAAQ,SAAChC,EAAMzG,GAC9Be,EAASrV,KAAK,EAAM+a,EAAK2kE,QAAS3kE,EAAKrJ,GAAI4C,QArTnD,8BA+TI,OAAOpF,KAAK+yE,YAAYriF,SA/T5B,0BAyUM+jB,GACF,IAAI4U,EAAOrpB,KAAK+yE,YAAYpyE,KAAI,SAAAkL,GAAI,OAAIA,EAAK2kE,WAM7C,OALIkD,EAAUj/D,IACR,SAAUA,GACZm/D,EAAYvqD,EAAM5U,EAAQ0M,MAGvBkI,O,2BAhVX,KA4VA,SAASqqD,EAAU7wC,GACjB,OACEA,aAAmBlyC,QACC,WAAnB,EAAOkyC,IAAoC,OAAZA,EAQpC,SAASgxC,EAAUhxC,GACjB,MAA0B,iBAAZA,EAOhB,SAASowC,EAAYpwC,GACnB,MAA0B,mBAAZA,EAMhB,IAAMixC,EAAkBnjF,OAAOC,UAAUC,eASzC,SAASkjF,EAAkBC,EAAc9gC,GACvC,IAAIC,EACJ,GAAIugC,EAAUM,IAAiBH,EAAU3gC,GAAe,CACtD,IAAM+gC,EAAY/gC,EAAajnC,MAAMsmE,GAC/B2B,EAAgBD,EAAUvjF,OAChC,GAAIwjF,EAAgB,EAAG,CACrB,IAAMC,EAAgBF,EAAU,GAC1BG,EACJF,EAAgB,EAAID,EAAU78E,MAAM,GAAG8U,KAAKqmE,GAAsB,KACpEp/B,EAAgB6gC,EAAaG,GACF,OAAvBC,IACFjhC,EAAgB4gC,EAAkB5gC,EAAeihC,KAIvD,OAAOjhC,EAUT,SAASwgC,EAA4BL,EAAaU,GAChD,IAAIziF,GAAS,EAEb,IAAK,IAAI2hD,KAAgBogC,EACvB,GAAIQ,EAAgBhjF,KAAKwiF,EAAapgC,GAAe,CACnD,GACEogC,EAAYpgC,KACZ6gC,EAAkBC,EAAc9gC,GAChC,CACA3hD,GAAS,EACT,OACoB,IAAXA,IACTA,GAAS,GAIf,OAAOA,EAwCT,SAASqiF,EAAYvqD,EAAMgrD,GACzB,KAAIhrD,aAAgB9jB,OA7BtB,SAAkC8uE,GAChC,IAAI9iF,GAAS,EACb,GAAI8iF,aAAsB9uE,OAAS8uE,EAAW3jF,OAAS,EACrD,IAAK,IAAIF,EAAI6jF,EAAW3jF,OAAS,EAAGF,GAAK,EAAGA,IAAK,CAC/C,IAAMqb,EAAOwoE,EAAW7jF,GACxB,GAAIqb,aAAgBtG,MAAO,CACzB,IAAMzO,EAAW+U,EAAK,GAChBwpD,EAAQxpD,EAAK,GACnB,GACEgoE,EAAU/8E,KACTu+D,IAAUmd,GAAand,IAAUod,GAElC,SAGJlhF,GAAS,EACT,MAGJ,OAAOA,EAUsB+iF,CAAyBD,IA0BpD,MAAM,IAAItgF,MAAM,qBAzBhB,IAAMwgF,EAAiBF,EAAW3jF,OAClC24B,EAAKlI,MAAK,SAA6BwP,EAAGC,GAGxC,IADA,IAAIxrB,EAAQ,EACLA,EAAQmvE,GAAgB,CAC7B,IAAMC,EAAYH,EAAWjvE,GACvBtO,EAAW09E,EAAU,GACrBnf,EAAQmf,EAAU,KAAO/B,GAAc,EAAI,EAC3CgC,EAASV,EAAkBpjD,EAAG75B,GAC9B49E,EAASX,EAAkBnjD,EAAG95B,GAIpC,GAAI29E,EAASC,EACX,OAAgB,EAATrf,EAET,GAAIof,EAASC,EACX,OAAe,EAARrf,EAET,KAAMjwD,GAASmvE,EACb,OAAO,Q,k6CCpfjB,IAIaI,EAAgB,CAC3BnyE,GAAI,gBACJpN,KAAM,gBACNw/E,UAAW,WACXC,oBAAqB,gBACrBpgE,QAAS,CACPqgE,iBAAkB,CAChBC,gBAXkB,SAAA7kF,GACtB,OAAOA,EAAKqsB,MAAQ,KAYlBy4D,aAAc,CACZC,SAAS,EACTC,UAAU,KCNHC,EAAgB,CAC3B3yE,GAAI,gBACJpN,KAAM,SACNw/E,UAAW,WACXC,oBAAqB,gBACrBpgE,QAAS,CACPqgE,iBAAkB,CAChBC,gBAhBkB,SAAA7kF,GACtB,OAAIA,EAAKklF,iBAEAllF,EAAKmlF,gBAAkB,MAAQnlF,EAAKklF,iBAGtCllF,EAAKmlF,kBAYVL,aAAc,CACZC,SAAS,EACTC,UAAU,KCXHI,EAAgB,CAC3B9yE,GAAI,gBACJpN,KAAM,UACNw/E,UAAW,WACXC,oBAAqB,gBACrBpgE,QAAS,CACPqgE,iBAAkB,CAChBC,gBAhBkB,SAAA7kF,GACtB,IAAIqlF,EAAY,GACRC,EAAgBtlF,EAAhBslF,YAIR,OAHIA,GAAeA,EAAYC,OAASC,MAAMF,EAAYC,QACxDF,EAAYC,EAAYC,KAAKnlE,QAAQ,GAAK,OAErCilE,IAYLP,aAAc,CACZC,SAAS,EACTC,UAAU,KCXHS,EAAY,CACvBnzE,GAAI,YACJpN,KAAM,SACNw/E,UAAW,WACXC,oBAAqB,YACrBpgE,QAAS,CACPqgE,iBAAkB,CAChBC,gBAhBkB,SAAA7kF,GACtB,IAAIqlF,EAAY,GACRC,EAAgBtlF,EAAhBslF,YAIR,OAHIA,GAAeA,EAAYC,OAASC,MAAMF,EAAYC,QACxDF,EAAYC,EAAYC,KAAKnlE,QAAQ,GAAK,OAErCilE,IAYLP,aAAc,CACZC,SAAS,EACTC,UAAU,KCZHU,EAAgB,CAC3BpzE,GAAI,gBACJpN,KAAM,WACNw/E,UAAW,WACXC,oBAAqB,gBACrBpgE,QAAS,CACPqgE,iBAAkB,CAChBC,gBAfkB,SAAA7kF,GACtB,IAAIqlF,EAAY,GAIhB,OAHIrlF,EAAK2lF,YAAc3lF,EAAK2lF,WAAWJ,OAASC,MAAMxlF,EAAK2lF,WAAWJ,QACpEF,EAAYrlF,EAAK2lF,WAAWJ,KAAKnlE,QAAQ,GAAK,OAEzCilE,IAYLP,aAAc,CACZC,SAAS,EACTC,UAAU,KCXHxkF,EAAS,CACpB8R,GAAI,SACJpN,KAAM,SACNw/E,UAAW,WACXC,oBAAqB,SACrBpgE,QAAS,CACPqgE,iBAAkB,CAChBC,gBAfkB,SAAA7kF,GACtB,IAAI4lF,EAAc,GAIlB,OAHI5lF,EAAKQ,SAAWglF,MAAMxlF,EAAKQ,UAC7BolF,EAAc5lF,EAAKQ,OAAO4f,QAAQ,GAAK,OAElCwlE,IAYLd,aAAc,CACZC,SAAS,EACTC,UAAU,KCnBHa,EAAY,CACvBvzE,GAAI,YACJpN,KAAM,aACNw/E,UAAW,WACXC,oBAAqB,YACrBpgE,QAAS,CACPqgE,iBAAkB,CAChBC,gBAAiB,SAAA7kF,GAAI,OAAIA,EAAKuuE,WAEhCuW,aAAc,CACZC,SAAS,EACTC,UAAU,KCFHc,EAAe,CAC1BxzE,GAAI,eACJpN,KAAM,YACNw/E,UAAW,WACXC,oBAAqB,eACrBpgE,QAAS,CACPqgE,iBAAkB,CAChBC,gBAhBkB,SAAA7kF,GACtB,IAAIqlF,EAAY,GACRC,EAAgBtlF,EAAhBslF,YAIR,OAHIA,GAAeA,EAAYC,OAASC,MAAMF,EAAYC,QACxDF,EAAYC,EAAYC,KAAKnlE,QAAQ,GAAK,OAErCilE,IAYLP,aAAc,CACZC,SAAS,EACTC,UAAU,KCZHe,EAAQ,CACnBzzE,GAAI,QACJpN,KAAM,QACNw/E,UAAW,WACXC,oBAAqB,QACrBpgE,QAAS,CACPqgE,iBAAkB,CAChBC,gBAfkB,SAAA7kF,GACtB,IAAIqsB,EAAO,GAIX,OAHIrsB,EAAKgmF,SAAWR,MAAMxlF,EAAKgmF,UAC7B35D,EAAOrsB,EAAKgmF,OAAO5lE,QAAQ,GAAK6H,OAAOg+D,aAAa/xD,SAAS,OAAQ,MAEhE7H,IAYLy4D,aAAc,CACZC,SAAS,EACTC,UAAU,KCnBHkB,EAAW,CACtB5zE,GAAI,WACJpN,KAAM,YACNw/E,UAAW,WACXC,oBAAqB,WACrBpgE,QAAS,CACPqgE,iBAAkB,CAChBC,gBAAiB,SAAA7kF,GAAI,OAAIA,EAAKuuE,WAEhCuW,aAAc,CACZC,SAAS,EACTC,UAAU,KCXHmB,EAAW,CACtB7zE,GAAI,WACJpN,KAAM,YACNw/E,UAAW,WACXC,oBAAqB,WACrBpgE,QAAS,CACPqgE,iBAAkB,CAChBC,gBAAiB,SAAA7kF,GAAI,OAAIA,EAAKuuE,WAEhCuW,aAAc,CACZC,SAAS,EACTC,UAAU,KCXHoB,EAAW,CACtB9zE,GAAI,WACJpN,KAAM,YACNw/E,UAAW,WACXC,oBAAqB,WACrBpgE,QAAS,CACPqgE,iBAAkB,CAChBC,gBAAiB,SAAA7kF,GAAI,OAAIA,EAAKuuE,WAEhCuW,aAAc,CACZC,SAAS,EACTC,UAAU,KCUDqB,EArBmB,CAChC/zE,GAAI,qBACJpN,KAAM,qBACNw/E,UAAW,WACXC,oBAAqB,qBACrBpgE,QAAS,CACPqgE,iBAAkB,CAChBC,gBAAiB,SAAA7kF,GACf,qBAAeA,EAAKsmF,oBAClBtmF,EAAK8U,mBACL9U,EAAKqsB,MACL,MAGNy4D,aAAc,CACZC,SAAS,EACTC,UAAU,K,OCdVuB,EAAa,GACnB9lF,OAAO4c,KAAKmpE,GAAO7oE,SAAQ,SAAAnX,GAAG,OAAI+/E,EAAWzlF,KAAK0lF,EAAMhgF,OAEjD,ICMDigF,EAA8B,CAClCC,iBAAkB,CDPI,CACtBp0E,GAAI,WACJpN,KAAM,UACNqhF,WAAYA,EACZhiE,QAAS,CACPugE,aAAc,CACZC,SAAS,EACTC,UAAU,MCCd2B,WAAY,CACV,CACEr0E,GAAI,aACJpN,KAAM,cACN0hF,YAAa,WAEf,CACEt0E,GAAI,gBACJpN,KAAM,kBACN0hF,YAAa,eAGjBC,aAAc,CACZC,SCxBgC,SAACt0D,EAAWu0D,GAE9C,OADA5/E,IAAIvC,MAAM,wBACHvC,QAAQC,WDuBbqrE,MCpB6B,SAAC35D,EAAiB+yE,GAEjD,OADA5/E,IAAIvC,MAAM,qBACHvC,QAAQC,a,qjBCNjB,IAAMg/E,E,+UAAgB,CAAH,GF4Be,CAChCuF,aAAc,CACZC,SCrB8B,SAAAvpC,GAEhC,OADAp2C,IAAIvC,MAAM,sBACHvC,QAAQC,WDoBbqrE,MCjB2B,SAAAqZ,GAE7B,OADA7/E,IAAIvC,MAAM,mBACHvC,QAAQC,WDgBbk4D,OCR2B,SAAAysB,GAE7B,OADA9/E,IAAIvC,MAAM,mBACHvC,QAAQC,WDOb8yE,OCd2B,SAAC4R,EAAen0C,GAE7C,OADA1rC,IAAIvC,MAAM,mBACHvC,QAAQC,WDab4kF,aCL6B,SAACH,EAAc3hE,GAE9C,OADAje,IAAIvC,MAAM,qBACHvC,QAAQC,cC3BX6kF,EAAuB,CAC3BC,YAAa,eACbC,SAAU,WACVC,SAAU,aAGSC,E,WAWnB,WAAYC,GAAkC,IAAdjjE,EAAc,uDAAJ,GACxC,G,4FAD4C,SACxCgjE,EAAaE,SAEf,OADAF,EAAaE,SAASC,WAAWF,EAAoBjjE,GAC9CgjE,EAAaE,SAGtB33E,KAAK43E,WAAWF,EAAoBjjE,GACpCgjE,EAAaE,SAAW33E,K,wDAfFovB,GACtBz+B,OAAOqhC,OAAOw/C,EAAepiD,K,yCAI7B,OAAOoiD,M,sCAaEkG,GAAkC,IAAdjjE,EAAc,uDAAJ,GACvCzU,KAAK03E,mBAAqBA,EAC1B13E,KAAK63E,uBAAyBpjE,EAAQojE,wBAA0B,WAChE73E,KAAKyU,QAAUA,EACfzU,KAAK4K,WAAa,K,4CAI8B,mBAArC5K,KAAKyU,QAAQqjE,oBAKxB93E,KAAKyU,QAAQqjE,oBAAoBnnF,OAAOqhC,OAAO,GAAIhyB,KAAK4K,aAJtDvT,IAAIC,KAAK,+C,2CAOQuT,GAEnB,IAiBMktE,EAjBmB/3E,KAAK4K,WAAWuW,MAAK,SAAC62D,EAAKC,GAClD,OAAOD,EAAIE,UAAYD,EAAIC,UAAY,GAAK,KAEFjiE,MAC1C,SAAAkiE,GAAE,OACAA,EAAGz1D,YAAc7X,EAAU6X,WAC3By1D,EAAGC,gBAAkBvtE,EAAUutE,iBAKKz3E,KACtC,SAAAkK,GAAS,OAAIA,EAAUssE,eAKQt9D,QAAQhP,EAAUssE,aAAe,EAGlE,IAAKY,EACH,MAAM,IAAIhkF,MACR,iEAIJ,OAAOgkF,I,yCAGUtqC,GAAQ,WACnB4qC,EAAc7G,EAAcuF,aAAaC,SAC/C,GAA2B,mBAAhBqB,EAKX,OAAO,IAAI9lF,SAAQ,SAACC,EAASC,GAC3B4lF,EAAY5qC,GACTr5C,MAAK,SAAA8iF,GACJ7/E,IAAIE,KAAK,4BAET2/E,EAAcrpE,SAAQ,SAAAhD,GACpB,IAAMytE,EAAiB,EAAK1tE,WAAW2M,WACrC,SAAA4gE,GAAE,OAAIA,EAAGhB,cAAgBtsE,EAAUssE,eAEjCmB,EAAiB,EACnB,EAAK1tE,WAAW5Z,KAAK6Z,GAErB,EAAKD,WAAW0tE,GAAkBztE,KAKtC,EAAKitE,sBAELtlF,OAED+4B,OAAM,SAAA6hD,GACL/1E,IAAIvC,MAAJ,+CAAkDs4E,IAClD36E,EAAO26E,SA3BX/1E,IAAIvC,MAAM,2D,wCAiCZ,IAAMyjF,EAAU/G,EAAcuF,aAAalZ,MACpB,mBAAZ0a,GAKXlhF,IAAIE,KAAK,iCACTF,IAAIE,KAAKihF,KAAKC,UAAUz4E,KAAK4K,WAAY,KAAM,IAE/C2tE,EAAQv4E,KAAK4K,YAAYxW,MAAK,kBAC5BiD,IAAIE,KAAK,mCARTF,IAAIvC,MAAM,uD,wCAYImiF,EAAc3hE,GAAkB,WAC1CojE,EAAiBlH,EAAcuF,aAAaK,aACpB,mBAAnBsB,EAKXA,EAAezB,EAAc3hE,GAAkBlhB,MAAK,WAClDiD,IAAIE,KAAK,4BAET,EAAKqT,WAAa,GAClB,EAAK+tE,mBAAmB,OARxBthF,IAAIvC,MAAM,0D,sCAYEqiF,GAAa,WACrByB,EAAWpH,EAAcuF,aAAarsB,OAC5C,GAAwB,mBAAbkuB,EAAX,CAKA,IAAM1B,EAAgB,CACpBC,eAGF9/E,IAAIE,KAAK,iCACTF,IAAIE,KAAKihF,KAAKC,UAAUvB,EAAe,KAAM,IAE7C0B,EAAS1B,GAAe9iF,MAAK,WAC3BiD,IAAIE,KAAK,+BAET,IAAMshF,EAAU,EAAKjuE,WAAW2M,WAC9B,SAAA4gE,GAAE,OAAIA,EAAGhB,cAAgBA,KAEvB0B,GAAW,GACb,EAAKjuE,WAAWhZ,OAAOinF,EAAS,GAIlC,EAAKf,8BAtBLzgF,IAAIvC,MAAM,wD,sCA0BEqiF,EAAap0C,GAAO,WAC5B+1C,EAAWtH,EAAcuF,aAAazR,OAC5C,GAAwB,mBAAbwT,EAAX,CAKA,IAAM5B,EAAgB,CACpBC,eAGF9/E,IAAIE,KAAK,iCACTF,IAAIE,KAAKihF,KAAKC,UAAUvB,EAAe,KAAM,IAC7C7/E,IAAIE,KAAKihF,KAAKC,UAAU11C,EAAO,KAAM,IAErC+1C,EAAS5B,EAAen0C,GAAO3uC,MAAK,WAClCiD,IAAIE,KAAK,+BAET,IAAMshF,EAAU,EAAKjuE,WAAW2M,WAC9B,SAAA4gE,GAAE,OAAIA,EAAGhB,cAAgBA,KAEvB0B,GAAW,IACb,EAAKjuE,WAAWiuE,GAAWloF,OAAOqhC,OAChC,GACA,EAAKpnB,WAAWiuE,GAChB91C,IAKJ,EAAK+0C,8BA3BLzgF,IAAIvC,MAAM,wD,0BAgCV24C,GAQF,OANIA,EACmBztC,KAAK4K,WAAW6iC,OAAOA,GAEvBztC,KAAK4K,YAGFuW,MAAK,SAAC62D,EAAKC,GACnC,OAAOD,EAAIE,UAAYD,EAAIC,UAAY,GAAK,O,gCAKtC,WACR,OAAOl4E,KAAK4K,WAAWqL,MACrB,SAAAkiE,GAAE,OAAIA,EAAGhB,cAAgB,EAAKO,wB,6BAI3B,WACCmB,EAAU74E,KAAK4K,WAAW2M,WAC9B,SAAA4gE,GAAE,OAAIA,EAAGhB,cAAgB,EAAKO,sBAE5BmB,EAAU,IAId74E,KAAK4K,WAAWiuE,GAAWloF,OAAOqhC,OAAO,GAAIhyB,KAAK4K,WAAWiuE,GAAU,CACrE5gD,QAAQ,O,8BAMV,IAAMhkB,EAAUjU,KAAKiU,UACrB,GAAKA,EAIL,OAAOjU,KAAKxK,MAAMygB,MAAK,SAAAkiE,GAAE,OAAIA,EAAGD,UAAYjkE,EAAQikE,e,wCAKpD,IAAMttE,EAAa,GAEbqJ,EAAUjU,KAAKiU,UACjBA,GACFrJ,EAAW5Z,KAAKijB,GAGlB,IAAM8kE,EAAQ/4E,KAAK+4E,QAKnB,OAJI9kE,GAAW8kE,GAASA,EAAM5B,cAAgBljE,EAAQkjE,aACpDvsE,EAAW5Z,KAAK+nF,GAGXnuE,I,6CAIkE,IAAtDitE,EAAsD,uDAA7B73E,KAAK63E,uBAC3C5jE,EAAUjU,KAAKiU,UACf+kE,EAAsBh5E,KAAKi5E,WAAWpB,GACtCjtE,EAAa,CAACqJ,GASpB,OANE+kE,IACCpuE,EAAWqL,MAAK,SAAAkiE,GAAE,OAAIA,EAAGhB,cAAgB6B,EAAoB7B,gBAE9DvsE,EAAW5Z,KAAKgoF,GAGXpuE,I,mCAOIusE,GACX,IAAMljE,EAAUkjE,EACZn3E,KAAK4K,WAAWqL,MAAK,SAAAkiE,GAAE,OAAIA,EAAGhB,cAAgBA,KAC9Cn3E,KAAKiU,UACT,QAAKA,GAIajU,KAAK4K,WAAW6iC,QAChC,SAAA0qC,GAAE,MAAyB,aAArBA,EAAGC,eAAgCD,EAAGD,WAAajkE,EAAQikE,aAElDxnF,OAAS,I,iDAQ1B,IAAIujB,EAAUjU,KAAKiU,UAMnB,OAHyBjU,KAAK4K,WAAWuW,MAAK,SAAC62D,EAAKC,GAClD,OAAOD,EAAIE,UAAYD,EAAIC,UAAY,GAAK,KAEtBjiE,MACtB,SAAAkiE,GAAE,OAAIA,EAAGD,UAAYjkE,EAAQikE,WAAkC,aAArBC,EAAGC,mB,4CAQ3BjB,GACpBn3E,KAAK03E,mBAAqBP,I,wCAOVtsE,GAChB7K,KAAKk5E,eAAiBruE,I,mCAQyC,IAAtDgtE,EAAsD,uDAA7B73E,KAAK63E,uBAEvC,GAAI73E,KAAKk5E,eACP,OAAOl5E,KAAKk5E,eAGd,IAAMjlE,EAAUjU,KAAKiU,UACrB,GAAKA,EAAL,CAKA,GAA8B,gBAA1BA,EAAQmkE,cAAiC,CAC3C,IAAMe,EAA2Bn5E,KAAKm5E,2BAEtC,GAAIA,EACF,OAAOA,EAKX,GAA8B,aAA1BllE,EAAQmkE,cAA8B,CACxC,IAAMW,EAAQ/4E,KAAK+4E,QACnB,GAAIA,EACF,OAAOA,EAIX,IAAME,EAAaj5E,KAAK63E,KAIxB,IAAIoB,GAAcA,EAAW9B,cAAgBljE,EAAQkjE,YAIrD,OAAO8B,K,2DAQP,IAAIG,EAAmBp5E,KAAKiU,UAG5B,GAAuC,aAAnCmlE,EAAiBhB,cAArB,CAKA,IAGMiB,EAHmBr5E,KAAK4K,WAAWuW,MAAK,SAAC62D,EAAKC,GAClD,OAAOD,EAAIE,UAAYD,EAAIC,UAAY,GAAK,KAEHzqC,QACzC,SAAA0qC,GAAE,OAAIA,EAAGD,UAAYkB,EAAiBlB,aAMlCoB,EAHoBD,EAAkB9hE,WAC1C,SAAA4gE,GAAE,MAAyB,aAArBA,EAAGC,iBAEgD,EAE3D,OAAIkB,EAAiC,EAE5BD,EAAkBA,EAAkB3oF,OAAS,GAI/C2oF,EAAkBC,M,4CAQzB,IAAIC,EAAmBv5E,KAAKiU,UAKS,gBAAnCslE,EAAiBnB,eACkB,aAAnCmB,EAAiBnB,gBAEjBmB,EACEv5E,KAAKw5E,sCAAwCD,GAGjD,IAAME,EAAmBF,EAAiBrB,UAOpCwB,GAJJ15E,KAAK4K,WAAW6iC,QACd,SAAA0qC,GAAE,MACqB,gBAArBA,EAAGC,eAAmCD,EAAGD,WAAauB,MACrD,IAC+C94E,KACpD,SAAAkK,GAAS,OAAIA,EAAUssE,eAQnBwC,GAJJ35E,KAAK4K,WAAW6iC,QACd,SAAA0qC,GAAE,MACqB,aAArBA,EAAGC,eAAgCD,EAAGD,WAAauB,MAClD,IACyC94E,KAC9C,SAAAkK,GAAS,OAAIA,EAAUssE,eAGzB,OAAOuC,EAAwBt8C,OAAOu8C,K,iCAKtC,IAAMC,EAAmB55E,KAAKiU,UAAUikE,UACxC,OAAOl4E,KAAKxK,MAAMygB,MAChB,SAAAkiE,GAAE,MAAyB,aAArBA,EAAGC,eAAgCD,EAAGD,WAAa0B,O,8BAS3D,IAAM3lE,EAAUjU,KAAKiU,UACf4lE,EAAQ75E,KAAKxK,MAAMygB,MACvB,SAAAkiE,GAAE,OACAA,EAAGhB,cAAgBljE,EAAQkjE,aACP,UAApBgB,EAAG2B,cACH3B,EAAGD,WAAajkE,EAAQikE,aAI5B,OAAI2B,GAOG75E,KAAKu3E,a,4BAKZ,IAAMhmF,EAAS,CAACyO,KAAKiU,WACf8kE,EAAQ/4E,KAAK+4E,QACbc,EAAQ75E,KAAK65E,QACbtC,EAAWv3E,KAAKu3E,WAEhBwC,EAAiB,SAAAlvE,GAAS,QAC5BtZ,EAAO0kB,MAAK,SAAAlP,GAAC,OAAIA,EAAEowE,cAAgBtsE,EAAUssE,gBAcjD,OAZI4B,IAAmC,IAA1BgB,EAAehB,IAC1BxnF,EAAOP,KAAK+nF,GAGVc,IAAmC,IAA1BE,EAAeF,IAC1BtoF,EAAOP,KAAK6oF,GAGVtC,IAAyC,IAA7BwC,EAAexC,IAC7BhmF,EAAOP,KAAKumF,GAGPhmF,I,4BAIH+jB,GACJ,OAAOtV,KAAKxK,MAAMi4C,QAAO,SAAA5iC,GAAS,OAChCA,EAAUmvE,kBAAkBlsE,SAASwH,Q,2BAKpCzK,GACH,IAAMovE,EAAoB5C,EAAqBxsE,EAAUutE,eAGzD,GAAgC,aAA5BvtE,EAAUutE,cACZ,MAAO,WACF,GAAIvtE,EAAUktE,YACnB,gBAAUkC,EAAV,YAA+BpvE,EAAUktE,aAG3C,IAAMA,EAAc/3E,KAAKk6E,qBAAqBrvE,GAG9C,gBAAUovE,EAAV,YAA+BlC,K,4BAI3BltE,GAMJ,IALA,IAAMsvE,EAAgBn6E,KAAK5K,KAAKyV,GAE1BrV,EAAMwK,KAAKxK,MACb4P,GAAS,EACTg1E,EAAe,KACV5pF,EAAI,EAAGA,EAAIgF,EAAI9E,OAAQF,IAAK,CACnC,IAAM4oF,EAAmB5jF,EAAIhF,GAY7B,GATIwP,KAAK03E,qBAAuB0B,EAAiBjC,cAC/CiD,EAAe,GAGI,OAAjBA,IACFh1E,EAAQg1E,KAINhB,EAAiBjC,cAAgBtsE,EAAUssE,YAC7C,MAIJ,IAIMkD,EAJS,CACbC,EAAG,CAAC,WACJC,EAAG,CAAC,UAEqBn1E,IAAU,GAC/By0E,EAAQ75E,KAAK65E,QAEfA,GAASA,EAAM1C,cAAgBtsE,EAAUssE,aAC3CkD,EAAYrpF,KAAK,SAGnB,IAAIwpF,EAAkB,GAKtB,OAJIH,EAAY3pF,SACd8pF,EAAkB,IAAH,OAAOH,EAAYnuE,KAAK,MAAxB,MAGjB,UAAUiuE,EAAV,YAA2BK,O,OAnjBV/C,E,uDCbN,WAASltE,GACtB,GAAKA,EAIL,OAAQA,EAAYkwE,UAClB,IAAK,gBACL,IAAK,WACL,IAAK,WACL,IAAK,WACH,uBAAiBlwE,EAAYisE,oBAC/B,IAAK,YACH,2BAAqBjsE,EAAYisE,sBCZxB,WAASjsE,GACtB,OAAOA,EAAYiR,a,8fCCN,eAASk/D,GAA8B,IAAnBpvB,EAAmB,0DAMhDovB,EAAUzuE,MAAM,KANgC,SAElDqJ,EAFkD,KAGlDooB,EAHkD,KAIlDE,EAJkD,KAKlD+8C,EALkD,KAO9Cl+C,EAAgBkkC,IAAqB3qE,IAAIsf,GACzCunB,EAASJ,EAAc81B,eAAe70B,GACtCV,EAAWH,EAAO4X,iBAAiB7W,GACzC,OAAOZ,EAASqB,WAAWs8C,EAAYrvB,I,unCCFzC,IAAMkmB,E,+UAAgB,IACjBmF,GAGgBiE,E,WA0KnB,WAAYC,GAA4B,IAAdpmE,EAAc,uDAAJ,GAClC,G,4FADsC,SAClCmmE,EAAejD,SAEjB,OADAiD,EAAejD,SAASC,WAAWiD,EAAcpmE,GAC1CmmE,EAAejD,SAGxB33E,KAAK43E,WAAWiD,EAAcpmE,GAC9BmmE,EAAejD,SAAW33E,K,wDA5JJovB,GACtBz+B,OAAOqhC,OAAOw/C,EAAepiD,K,yCAI7B,OAAOoiD,I,0CAIP,IAAMsJ,EAAiB,GAOvB,OANAtJ,EAAcoF,iBAAiB/oE,SAAQ,SAAA+mE,GACrCA,EAAU6B,WAAW5oE,SACnB,SAAAqiB,GAAI,OAAK4qD,EAAe5qD,EAAK1tB,IAAMoyE,EAAUpyE,SAI1Cs4E,I,wCAGgBA,GACvB,IAAMvpF,EAAS,GAUf,OATAZ,OAAO4c,KAAKutE,GAAgBjtE,SAAQ,SAAA4sE,GAClC,IAAM3D,EAAcgE,EAAeL,GAC9BlpF,EAAOulF,KACVvlF,EAAOulF,GAAe,IAGxBvlF,EAAOulF,GAAa9lF,KAAKypF,MAGpBlpF,I,2CAGmBkpF,GAC1B,IAQIvqD,EAREshD,EAAgBoJ,EAAevI,mBAG/ByE,EAFiB8D,EAAeG,oBAEHN,GAC7B7F,EAAYpD,EAAcoF,iBAAiB3gE,MAC/C,SAAA2+D,GAAS,OAAIA,EAAUpyE,KAAOs0E,KAQhC,OAJIlC,IACF1kD,EAAO0kD,EAAU6B,WAAWxgE,MAAK,SAAAia,GAAI,OAAIA,EAAK1tB,KAAOi4E,MAGhD,CACL3D,cACAlC,YACA1kD,U,iDAI8B3lB,GAChClT,IAAIE,KAAK,8BAET,IAAMyjF,EAAmBC,EAAS1wE,GAC9BywE,IACFzwE,EAAY2wE,OAAS,CAACF,IAGxB,IAAMG,EAAYrtD,IAAiBstD,sCAAsCC,gBAGjE/lE,EAAqB/K,EAArB+K,iBAER,GADiBqrD,IAAqB3qE,IAAIsf,GAC1C,CAGA,IAAMmlE,EAAWlwE,EAAYkwE,SACrBvqD,EAAS0qD,EAAeU,qBAAqBb,GAA7CvqD,KACR,GAAI3qB,MAAMC,QAAQ0qB,EAAKumD,YACrBvmD,EAAKumD,WAAW5oE,SAAQ,SAAA0tE,GACtB,IAAMC,EAAmBjxE,EAAYgxE,GAChCC,IACLA,EAAiBC,IAAMlxE,EAAYkxE,IACnCD,EAAiBx2E,kBAAoBuF,EAAYvF,kBACjDw2E,EAAiBhF,mBAAqBjsE,EAAYisE,mBAElDoE,EAAec,2BAA2BF,WAR9C,CAcA,IAAMp9C,EAAUu9C,EAAuBpxE,EAAYmwE,WAG9CS,EAAU/8C,KACb+8C,EAAU/8C,GAAW,IAGvB,IAAMw9C,EAAmBT,EAAU/8C,GAASq8C,GACtCoB,EAAWD,GAAoBA,EAAiB1rF,KAGtD,GAAI2rF,GAAYA,EAASnrF,OAAQ,CAE/B,IAAMmrF,EAAWV,EAAU/8C,GAASq8C,GAAUvqF,KAG1C4rF,GAAgB,EAkBpB,GAfAD,EAAShuE,SAAQ,SAAAqiB,GAEf,GAAIA,EAAKurD,MAAQlxE,EAAYkxE,IAS7B,OAJAK,GAAgB,EAGhBnrF,OAAOqhC,OAAO9B,EAAM3lB,IACb,MAIa,IAAlBuxE,EACF,YAIFX,EAAU/8C,GAASq8C,GAAY,CAC7BvqF,KAAM,IAQVirF,EAAU/8C,GAASq8C,GAAUvqF,KAAKc,KAAKuZ,GAEvCujB,IAAiBstD,sCAAsCW,iBACrDZ,O,qCAIkBjrD,GACpB,OACEA,EAAKzb,SACLyb,EAAKzb,QAAQugE,cACb9kD,EAAKzb,QAAQugE,aAAaC,Y,sCAcnB4F,GAA4B,WAAdpmE,EAAc,uDAAJ,GACjCzU,KAAK66E,aAAeA,EACpB76E,KAAKyU,QAAUA,EACfzU,KAAKg8E,WAAa,GAClBh8E,KAAK02E,MAAQ,GACb12E,KAAK86E,eAAiBF,EAAeG,oBACrC/6E,KAAKi8E,eAAiBrB,EAAesB,kBAAkBl8E,KAAK86E,gBAG5DtJ,EAAcoF,iBAAiB/oE,SAAQ,SAAA+mE,GACrC,EAAKoH,WAAWpH,EAAUpyE,IAAM,GAGhCoyE,EAAU6B,WAAW5oE,SAAQ,SAAAqiB,GAC3B,EAAKwmD,MAAMxmD,EAAK1tB,IAAM,W,8CAMwB,mBAAvCxC,KAAKyU,QAAQ0nE,sBAKxBn8E,KAAKyU,QAAQ0nE,sBAAsBxrF,OAAOqhC,OAAO,GAAIhyB,KAAK02E,QAJxDr/E,IAAIC,KAAK,iD,2CAOQorB,EAAWu0D,GAAc,WACtCoB,EAAc7G,EAAcuF,aAAaC,SACvCn9B,EAAW23B,EAAX33B,OACR,GAA2B,mBAAhBw+B,EAKX,OAAO,IAAI9lF,SAAQ,SAACC,EAASC,GAC3B4lF,EAAYx+B,GAAQzlD,MAAK,SAAA8P,GACnBA,IACF7M,IAAIE,KAAK,8BACTF,IAAIE,KAAK2M,GAETvT,OAAO4c,KAAKrJ,GAAiB2J,SAAQ,SAAAuuE,GACdl4E,EAAgBk4E,GAExBvuE,SAAQ,SAAAtD,GAAe,IAC1BkwE,EAAalwE,EAAbkwE,SAER,EAAK4B,eAAe5B,EAAUlwE,UAKpC/X,IAGA,EAAK8pF,8BAEL7uD,IAAY8uD,qBAAqB1uE,SAAQ,SAAA6gB,GACnCA,EAAeY,OACjB7B,IAAY+uD,YAAY9tD,EAAe7lB,YAK3C,EAAKszE,0BACJ1pF,MAlCH4E,IAAIvC,MAAM,6D,wCAsCIqiF,GAAa,WACrBt9B,EAAW23B,EAAX33B,OACF0+B,EAAU/G,EAAcuF,aAAalZ,MAC3C,GAAuB,mBAAZ0a,EAAX,CAKA,IAAIr0E,EAAkB,GACtBstE,EAAcoF,iBAAiB/oE,SAAQ,SAAA+mE,GAEhCgG,EAAe6B,eAAe7H,IAInCA,EAAU6B,WAAW5oE,SAAQ,SAAAqiB,GAEtB0qD,EAAe6B,eAAevsD,KAI9BhsB,EAAgB0wE,EAAUpyE,MAC7B0B,EAAgB0wE,EAAUpyE,IAAM,IAGlC0B,EAAgB0wE,EAAUpyE,IAAM0B,EAAgB0wE,EAAUpyE,IAAI46B,OAC5D,EAAKs5C,MAAMxmD,EAAK1tB,YAKtB,IAAMk6E,EAAkBvF,EACpB,SAAAgB,GAAE,OAAIA,EAAGhB,cAAgBA,GACzB,KACEvsE,EAAa5K,KAAK66E,aAAarlF,IAAIknF,GACnCzF,EAAersE,EAAWjK,KAAI,SAAAtK,GAAC,OAAIA,EAAE8gF,eAErC1pC,EAAS,CACb/qB,UAFgB9X,EAAW,GAAG8X,UAG9Bu0D,gBAIF,OADA5/E,IAAIE,KAAK,sCAAuCqT,GACzC2tE,EAAQr0E,EAAiBupC,EAAQoM,GAAQzlD,MAAK,SAAA7C,GAEnD,OADA8F,IAAIE,KAAK,iCACFhG,KAzCP8F,IAAIvC,MAAM,yD,kDA6CcwV,GAC1B,IAYI9Z,EAZEmsF,EAAqBryE,EAAa6W,MAAK,SAACwP,EAAGC,GAC/C,OAAID,EAAE6lD,mBAAqB5lD,EAAE4lD,mBACpB,EACE7lD,EAAE6lD,mBAAqB5lD,EAAE4lD,oBAC1B,EAGH,KAMT,IAAKhmF,EAAI,EAAGA,EAAImsF,EAAmBjsF,OAAS,KACtCF,EAAImsF,EAAmBnsF,EAAI,GAAGgmF,oBADWhmF,KAM/C,OAAOA,I,4BAGHsmF,EAAarpC,GAAQ,WACzB,IAAKztC,KAAKg8E,WAAWlF,GACnB,MAAM,IAAI/iF,MAAJ,qDAC0C+iF,IAWlD,OANIrpC,EACMztC,KAAKg8E,WAAWlF,GAAarpC,OAAOA,GAEpCztC,KAAKg8E,WAAWlF,IAGbn2E,KAAI,SAAAkL,GACf,OAAIA,EAAK+wE,OACA,EAAKlG,MAAM7qE,EAAK+wE,QAAQ3mE,MAC7B,SAAAia,GAAI,OAAIA,EAAKurD,MAAQ5vE,EAAKgxE,cAIvB,CAAErG,mBAAoB3qE,EAAK2qE,yB,0CAIlBW,GAAa,WAE3BV,EAAa,GACjBjF,EAAcoF,iBAAiB/oE,SAAQ,SAAA+mE,GAErC,IAAKgG,EAAe6B,eAAe7H,GACjC,OAAO,EAGT6B,EAAaA,EAAWr5C,OAAOw3C,EAAU6B,eAI3C,IAAMqG,EAAqBrG,EAAWhpC,QAAO,SAAAvd,GAAI,OAC/C0qD,EAAe6B,eAAevsD,MAI5B3lB,OAAclV,EAUlB,OATAynF,EAAmBhjD,OAAM,SAAA5J,GAKvB,QAJA3lB,EAAc,EAAKmsE,MAAMxmD,EAAK1tB,IAAIyT,MAChC,SAAA5f,GAAC,OAAIA,EAAE8gF,cAAgBA,GAAuC,IAAxB9gF,EAAE2O,yBAOrCuF,I,+CAGgBisE,EAAoBM,EAAaG,GAOxD,QALgCj3E,KAAKw+D,MAAMsY,GAAa,SAAA5mD,GAAI,OAC1D+mD,EAAanpE,SAASoiB,EAAKinD,gBAIIlhE,MAC/B,SAAAxgB,GAAC,OAAIA,EAAE+gF,qBAAuBA,O,8CAIVtyE,GACtB,GAAKA,EAAL,CAIA,IAAM64E,EAAanC,EAAeU,qBAChCp3E,EAAgBu2E,UAEZA,EAAWsC,EAAW7sD,KAAK8sD,YAAc94E,EAAgBu2E,SACvDI,EAAiB76E,KAAjB66E,aACFoC,EACJj9E,KAAK02E,MAAM+D,GAAUxkE,MAAK,SAAAia,GAAI,OAAIA,EAAKurD,MAAQv3E,EAAgBu3E,QAAQ,GACnEtE,EACJ8F,EAAmB9F,aAAejzE,EAAgBizE,YAC9CX,EACJyG,EAAmBzG,oBACnBtyE,EAAgBsyE,mBAGlB,GAAKqE,GAAiB1D,GAAgB4F,EAAtC,CAnBuC,IAuB/BjG,EAAgBiG,EAAhBjG,YACF7iE,EAAU4mE,EAAajwE,WAAWqL,MACtC,SAAAkiE,GAAE,OAAIA,EAAGhB,cAAgBA,KAErB+F,EAAsBrC,EAAaqC,sBAGzC,SACGA,GACDA,EAAoBxsF,OAAS,GAC7BwsF,EAAoB5qB,MAClB,SAAA6qB,GAAW,OAAIA,IAAgBlpE,EAAQkjE,kBAWnC,IAJNn3E,KAAKo9E,yBACH5G,EACAM,EACAoG,O,0DAK8BG,EAAS5vC,GAiB3C,IAjBmD,WAa7CkvC,GAXFU,EAEar9E,KAAKg8E,WAAWqB,IAAY,GAG5B1sF,OAAO4c,KAAKvN,KAAKg8E,YAAY95D,QAAO,SAACo0B,EAAKpC,GAEvD,OADAoC,EAAItlD,KAAJ,MAAAslD,EAAG,EAAS,EAAK0lC,WAAW9nC,KACrBoC,IACN,KAGmC7I,OAAOA,GAAQtsB,MAAK,SAAC62D,EAAKC,GAChE,OAAOD,EAAIhzE,kBAAoBizE,EAAIjzE,kBAAoB,GAAK,KAdX,WAiB1CxU,GACP,IAAM8sF,EAAuBX,EAAmBnsF,GAC1C+Z,EAAc,EAAKmsE,MAAM4G,EAAqBV,QAAQ3mE,MAC1D,SAAAia,GAAI,OAAIA,EAAKurD,MAAQ6B,EAAqBT,cAG5C,IADc,EAAKU,wBAAwBhzE,GAEzC,SAAOA,EAAYvF,oBAPdxU,EAAI,EAAGA,EAAImsF,EAAmBjsF,OAAQF,IAAK,SAA3CA,GAA2C,8BAWpD,OAAO,I,6DAG8B6sF,EAAS5vC,GAO9C,IAPsD,WAChDkvC,EAAqB38E,KAAKg8E,WAAWqB,GACxC5vC,OAAOA,GACPtsB,MAAK,SAAC62D,EAAKC,GACV,OAAOD,EAAIhzE,kBAAoBizE,EAAIjzE,kBAAoB,GAAK,KAJV,WAO7CxU,GACP,IAAM8sF,EAAuBX,EAAmBnsF,GAC1C+Z,EAAc,EAAKmsE,MAAM4G,EAAqBV,QAAQ3mE,MAC1D,SAAAia,GAAI,OAAIA,EAAKurD,MAAQ6B,EAAqBT,cAG5C,GADc,EAAKU,wBAAwBhzE,GAEzC,SAAOA,EAAYvF,oBAPdxU,EAAI,EAAGA,EAAImsF,EAAmBjsF,OAAQF,IAAK,SAA3CA,GAA2C,8BAWpD,OAAO,I,iDAGkB+Z,GACzB,IAAMusE,EAAc92E,KAAK86E,eAAevwE,EAAYkwE,UAE9ChtC,EAAS,SAAAvd,GAAI,OAAIA,EAAKurD,MAAQlxE,EAAYkxE,KAIhD,IAFcz7E,KAAKu9E,wBAAwBhzE,GAiCpC,CACL,IAAMizE,EAA6Bx9E,KAAKy9E,oCACtC,UACAhwC,GAEF,GAAoB,YAAhBqpC,EACF,OAAO0G,EACF,GAAoB,eAAhB1G,EAA8B,CACvC,IAAM4G,EAAgC19E,KAAKy9E,oCACzC,aACAhwC,GAEF,OAAOl6B,KAAKtD,IACVutE,EACAE,GAGF,OAAO19E,KAAKy9E,oCAAoC,KAAMhwC,GA/CxD,IAAM+vC,EAA6Bx9E,KAAKy9E,oCACtC,UACAhwC,GAEIiwC,EAAgC19E,KAAKy9E,oCACzC,aACAhwC,GAEIkwC,EAAgC39E,KAAK49E,uCACzC,UACAnwC,GAEF,GAAoB,YAAhBqpC,EACF,OAAOvjE,KAAKtD,IACVutE,EACAE,EACAC,GAEG,GAAoB,eAAhB7G,EAA8B,CACvC,IAAM+G,EAAmC79E,KAAK49E,uCAC5C,aACAnwC,GAEF,OAAOl6B,KAAKtD,IACVutE,EACAE,EACAC,EACAE,GAwBN,OAAO,I,6CAGc35E,GACrB,GAAKA,EAAL,CADsC,IAK9BizE,EAA8CjzE,EAA9CizE,YAAasD,EAAiCv2E,EAAjCu2E,SAAUjE,EAAuBtyE,EAAvBsyE,mBAC/B,GAAKW,GAAgBsD,GAAajE,EAAlC,CAIA,IAII/oC,EAJEqpC,EAAc92E,KAAK86E,eAAe52E,EAAgBu2E,UAKlD3nC,EACJ5uC,EAAgB45E,gBAChB55E,EAAgB45E,eAAeC,wBAE/BtwC,EADEqF,EACO,SAAA5iB,GAAI,OACXA,EAAKurD,MAAQv3E,EAAgBu3E,KAC7BvrD,EAAK4tD,gBACL5tD,EAAK4tD,eAAeC,0BAA4BjrC,GAEzC,SAAA5iB,GAAI,OACXA,EAAKurD,MAAQv3E,EAAgBu3E,KAC7BvrD,EAAKsmD,qBAAuBA,GAIhC,IADA,IAAMwH,EAAiBh+E,KAAKi8E,eAAenF,GAClCtmF,EAAI,EAAGA,EAAIwtF,EAAettF,OAAQF,IAAK,CAC9C,IAAMytF,EAAgBD,EAAextF,GAE/Bqb,EADiB7L,KAAK02E,MAAMuH,GACNhoE,KAAKw3B,GAEjC,GAAI5hC,EACF,OAAOA,O,oDAKiB3H,GAAiB,WAC7C,GAAKA,EAAL,CAD6C,IAKrCu2E,EAAgCv2E,EAAhCu2E,SAAUz1E,EAAsBd,EAAtBc,kBAClB,GAAKy1E,GAAaz1E,EAAlB,CAIA,IAAMyoC,EAAS,SAAAvd,GAAI,OACjBA,EAAKurD,MAAQv3E,EAAgBu3E,KAC7BvrD,EAAKlrB,oBAAsBd,EAAgBc,mBAE7C,OAAOwsE,EAAcoF,iBAClBnpC,QAAO,SAAAmnC,GAAS,MAAqB,SAAjBA,EAAUpyE,MAC9B8vD,MAAK,SAAAsiB,GACJ,QAAI,EAAKoH,WAAWpH,EAAUpyE,IAAIyT,KAAKw3B,IAGhCmnC,EAAU6B,WAAWnkB,MAAK,SAAApiC,GAC/B,GAAI,EAAKwmD,MAAMxmD,EAAK1tB,IAAIyT,KAAKw3B,GAC3B,OAAO,Y,sCAMDywC,EAAoBC,EAAgBjrC,EAAckrC,GAChEF,EAAmBzwC,OAAO0wC,GAAgBtwE,SAAQ,SAAAhC,GAChDA,EAAKqnC,IAAiBkrC,O,gEAIgB7zE,EAAa6zE,GAAW,WAC1D3wC,EAAS,SAAAvd,GAAI,OACjBA,EAAKurD,MAAQlxE,EAAYkxE,KACzBvrD,EAAKlrB,mBAAqBuF,EAAYvF,mBAExCwsE,EAAcoF,iBACXnpC,QAAO,SAAAmnC,GAAS,MAAqB,SAAjBA,EAAUpyE,MAC9BqL,SAAQ,SAAA+mE,GACP,EAAKyJ,gBACH,EAAKrC,WAAWpH,EAAUpyE,IAC1BirC,EACA,oBACA2wC,GAGFxJ,EAAU6B,WAAW5oE,SAAQ,SAAAqiB,GAC3B,EAAKmuD,gBACH,EAAK3H,MAAMxmD,EAAK1tB,IAChBirC,EACA,oBACA2wC,W,qCAMK3D,EAAUlwE,GACvB,IAwBIM,EAxBE+pE,EAAY50E,KAAK86E,eAAeL,GAChC6D,EAAkBt+E,KAAKg8E,WAAWpH,GAClC2J,EAAav+E,KAAK02E,MAAM+D,GAGxB+D,EAAqBD,EAAWtoE,MACpC,SAAA5f,GAAC,OACCA,EAAEmgF,qBAAuBjsE,EAAYisE,oBACrCngF,EAAEokF,WAAalwE,EAAYkwE,YAiB/B,GAbI+D,GAAsBA,EAAmB7iE,WAC3CpR,EAAYoR,SAAW6iE,EAAmB7iE,UAIxC6iE,GAAsBA,EAAmBhjE,cAC3CjR,EAAYiR,YAAcgjE,EAAmBhjE,aAG/CjR,EAAYkxE,IAAM9lD,cAIdprB,EAAY+K,iBACdzK,EAAY7K,KAAK66E,aAAa3kE,MAAM3L,EAAY+K,kBAAkB,OAC7D,KACG6hE,EAAgB5sE,EAAhB4sE,YACRtsE,EAAY7K,KAAK66E,aAAajwE,WAAWqL,MACvC,SAAA5f,GAAC,OAAIA,EAAE8gF,cAAgBA,KAM3B,GAAKtsE,EAAL,CAGA,IAAM4zE,EAAYH,EAAgBroE,MAChC,SAAAyoE,GAAS,OACNA,EAAU9B,QAAU8B,EAAUvH,cAAgBtsE,EAAUssE,eAO7D,GAHA5sE,EAAY4sE,YAActsE,EAAUssE,YAGhCsH,EAEFl0E,EAAYisE,mBAAqBiI,EAAUjI,mBAC3CjsE,EAAYvF,kBAAoBy5E,EAAUz5E,kBAE1Cs5E,EACG7wC,QACC,SAAAixC,GAAS,OACPA,EAAUvH,cAAgBtsE,EAAUssE,aACpCuH,EAAUlI,qBAAuBjsE,EAAYisE,sBAEhD3oE,SAAQ,SAAA6wE,GACPA,EAAU9B,OAAS1sD,KAAK1tB,GACxBk8E,EAAU7B,WAAatyE,EAAYkxE,IACnCiD,EAAUC,UAAYp0E,EAAYo0E,UAClCD,EAAU15E,kBAAoBuF,EAAYvF,yBAEzC,CAEL,IAAM45E,EAA0BN,EAAgB7wC,QAC9C,SAAAixC,GAAS,OAAIA,EAAUvH,cAAgBtsE,EAAUssE,eAEnD5sE,EAAYisE,mBAAqBx2E,KAAK6+E,4BACpCD,GAEFr0E,EAAYvF,kBACVuF,EAAYvF,mBACZhF,KAAK8+E,2BAA2Bv0E,GAAe,EAInD,IA0CIw0E,EA1CEC,EAAe,CACnB7H,YAAatsE,EAAUssE,YACvBX,mBAAoBjsE,EAAYisE,mBAChCxxE,kBAAmBuF,EAAYvF,mBAI3B0vC,EAAQ10C,KAAKi/E,uBAAuB10E,GAG1C,GAAImqC,EAAO,CAETnqC,EAAYisE,mBAAqB9hC,EAAM8hC,mBACvCjsE,EAAYvF,kBAAoB0vC,EAAM1vC,kBAOtCg6E,EAAaxI,mBAAqB9hC,EAAM8hC,mBACxCwI,EAAah6E,kBAAoB0vC,EAAM1vC,kBACvCg6E,EAAalB,eAAiBvzE,EAAYuzE,gBAAkB,GAC5DkB,EAAalB,eAAeC,wBAC1BrpC,EAAMopC,gBAAkBppC,EAAMopC,eAAeC,wBAC/CiB,EAAarjE,SAAW+4B,EAAM/4B,SAC9BqjE,EAAal9E,MAAQ4yC,EAAM5yC,MAC3Bk9E,EAAaxjE,YAAck5B,EAAMl5B,YACjCwjE,EAAaE,cAAgBxqC,EAAMwqC,cACnCF,EAAaG,QAAUzqC,EAAMyqC,QAE7B,IAAM3jE,EAAc4jE,EAAe1qC,GAC/Bl5B,IACFwjE,EAAaxjE,YAAcA,QAEpBxb,KAAKq/E,8BAA8B90E,IAI5CvK,KAAKs/E,0CAA0C/0E,EAAa,GAM9D,IAAMg1E,EAAYhB,EAAWhnE,WAC3B,SAAA2Y,GAAI,OAAIA,EAAKurD,MAAQlxE,EAAYkxE,OAiCnC,OA/BI8D,GAAa,GACfR,EAAmBpuF,OAAOqhC,OAAO,GAAIusD,EAAWgB,GAAYP,GAC5DT,EAAWgB,GAAaR,IAExBA,EAAmBpuF,OAAOqhC,OAAO,GAAIznB,EAAay0E,GAClDT,EAAWvtF,KAAK+tF,IAGdx0E,EAAYnG,aACd26E,EAAiB36E,WAAamG,EAAYnG,YAGvCq6E,GAEHH,EAAgBttF,KAAK,CACnB4rF,OAAQnC,EACRoC,WAAYkC,EAAiBtD,IAC7BtE,YAAatsE,EAAUssE,YACvB7hE,iBAAkBypE,EAAiBzpE,iBACnCqpE,UAAWI,EAAiBJ,UAC5BnI,mBAAoBuI,EAAiBvI,mBACrCxxE,kBAAmB+5E,EAAiB/5E,oBAKxChF,KAAKm8E,wBAKE4C,K,wCAGStE,EAAUlwE,GAC1B,IAAMg0E,EAAav+E,KAAK02E,MAAM+D,GAExB8E,EAAYhB,EAAWhnE,WAC3B,SAAA2Y,GAAI,OAAIA,EAAKurD,MAAQlxE,EAAYkxE,OAE/B8D,EAAY,IAIhBhB,EAAWgB,GAAa5uF,OAAOqhC,OAAO,GAAIznB,GAG1CvK,KAAKm8E,2B,2CAMc1B,EAAUlwE,GAAa,WAClCisE,EAA0CjsE,EAA1CisE,mBAAoBxxE,EAAsBuF,EAAtBvF,kBAEtB8xE,EAAc92E,KAAK86E,eAAeL,GAClC6D,EAAkBt+E,KAAKg8E,WAAWlF,GAElC0I,EAAalB,EAAgB/mE,WACjC,SAAAkoE,GAAK,OAAIA,EAAM5C,aAAetyE,EAAYkxE,OAE5C,KAAI+D,EAAa,GAAjB,CAaA,GARAlB,EAAgB1sF,OAAO4tF,EAAY,GAGMlB,EACtC7wC,QAAO,SAAAvd,GAAI,OAAIA,EAAKlrB,oBAAsBA,KAC1CrE,KAAI,SAAAuvB,GAAI,OAAIA,EAAKinD,eAGiBzmF,OAAS,EAAG,CAE/C,IAAMgvF,EAA2B,SAAAxvD,GAAI,OACnCA,EAAKsmD,oBAAsBA,GAC7Bx2E,KAAKq+E,gBACHC,EACAoB,EACA,sBACC,GAGH,IAAM9K,EAAYpD,EAAcoF,iBAAiB3gE,MAC/C,SAAA0pE,GAAM,OAAIA,EAAOn9E,KAAOs0E,KAEtBlC,GAAaA,EAAU6B,YACzB7B,EAAU6B,WAAW5oE,SAAQ,SAAA+xE,GAC3B,IAAMrB,EAAa,EAAK7H,MAAMkJ,EAAUp9E,IACxC,EAAK67E,gBACHE,EACAmB,EACA,sBACC,MAMP1/E,KAAKs/E,0CAA0C/0E,GAAc,GAI/DvK,KAAKs8E,8BAGLt8E,KAAKm8E,2B,oDAMuB,WAC5B3K,EAAcoF,iBAAiB/oE,SAAQ,SAAA+mE,GAEhCgG,EAAe6B,eAAe7H,IAGnCA,EAAU6B,WAAW5oE,SAAQ,SAAAqiB,GAEtB0qD,EAAe6B,eAAevsD,IAGd,EAAKwmD,MAAMxmD,EAAK1tB,IACxBqL,SAAQ,SAAAtD,GACnBqwE,EAAec,2BAA2BnxE,c,yCAM/BkwE,EAAU2B,EAAmB3uC,GAAQ,WAChDoyC,EAAalvF,OAAO4c,KAAKkgC,GACzB6wC,EAAkBt+E,KAAKg8E,WAAWI,GAGxC,GAAKkC,EAAL,CAGA,IAAMwB,EAAaxB,EAAgB7wC,QAAO,SAAAmnC,GACxC,OAAOiL,EAAW/lD,OAChB,SAAAimD,GAAS,OAAInL,EAAUmL,KAAetyC,EAAOsyC,SAG3CrlC,EAAU,GAiBhB,GAhBAolC,EAAWjyE,SAAQ,SAAAmyE,GACjB,GAAKA,EAAUpD,OAAf,CAIA,IAAM2B,EAAa,EAAK7H,MAAMsJ,EAAUpD,QAClC2C,EAAYhB,EAAWhnE,WAC3B,SAAA2Y,GAAI,OAAIA,EAAKurD,MAAQuE,EAAUnD,cAE7B0C,GAAa,IACf7kC,EAAQ1pD,KAAKutF,EAAWgB,IACxBhB,EAAW3sF,OAAO2tF,EAAW,QAK5B7kC,EAAQhqD,OAAb,CAKA,IAAM8lF,EACJ/oC,EAAO+oC,oBAAsB97B,EAAQ,GAAG87B,mBAGpC2E,EAAYrtD,IAAiBstD,sCAAsCC,gBAEzE3gC,EAAQ7sC,SAAQ,SAAAwsC,GACd,IAAM4lC,EAAmB,GACjB/vD,EAAS0qD,EAAeU,qBAAqBjhC,EAAMogC,UAAnDvqD,KACJ3qB,MAAMC,QAAQ0qB,EAAKumD,YACrBvmD,EAAKumD,WAAW5oE,SAAQ,SAAAnX,GACtB,IAAM8kF,EAAmBnhC,EAAM3jD,GAC1B8kF,GACLyE,EAAiBjvF,KAAKwqF,MAGxByE,EAAiBjvF,KAAKqpD,GAGxB4lC,EAAiBpyE,SAAQ,SAAA3J,GAAmB,IAClCw2E,EAAwBx2E,EAAxBw2E,UAAWD,EAAav2E,EAAbu2E,SACbr8C,EAAUu9C,EAAuBjB,GACvC,GAAIt8C,GAAW+8C,EAAU/8C,GAAU,CACjC,IAAMy9C,EAAWV,EAAU/8C,GAASq8C,GAC9ByF,EAAqBrE,GAAYA,EAAS3rF,KAC1CiwF,EAAmBD,EAAmBjqE,MAC1C,SAAAmqE,GAAM,OAAIA,EAAO3E,MAAQphC,EAAMohC,OAEjC,GAAI0E,EAAkB,CACpB,IAAM/6E,EAAQ86E,EAAmBrmE,QAAQsmE,GACzCD,EAAmBtuF,OAAOwT,EAAO,QAKvC,EAAKi7E,qBAAqB5F,EAAUpgC,MAGtCvsB,IAAiBstD,sCAAsCW,iBACrDZ,GAKF,IAAMmF,EAAa3vF,OAAOqhC,OAAO,GAAIyb,UAC9B6yC,EAAWnJ,mBACXmJ,EAAW9J,mBAElB,IAAM+J,EAAiB5vF,OAAO4c,KAAK+yE,GAEjB,EAAI,IAAI7nD,IAAIiiB,EAAQ/5C,KAAI,SAAA05C,GAAK,OAAIA,EAAMogC,cAC/C5sE,SAAQ,SAAA4sE,GACG,EAAK/D,MAAM+D,GAE3BhtC,QAAO,SAAAvd,GACN,OACEA,EAAKsmD,mBAAqBA,EAAqB,GAC/C+J,EAAezmD,OACb,SAAA0mD,GAAa,OAAItwD,EAAKswD,KAAmB/yC,EAAO+yC,SAIrD3yE,SAAQ,SAAAtD,GACPqwE,EAAec,2BAA2BnxE,e,6KAt/B/BqwE,E,mBCdd,IAAM6F,EAAb,WACE,WAAYhsE,EAASisE,I,4FAAe,SAClC1gF,KAAKyU,QAAUA,EACfzU,KAAK0gF,cAAgBA,E,UAHzB,O,EAAA,G,EAAA,wCAMmBvrF,EAASmV,GAIxB,MAAO,CACL8pB,QAJcj/B,EAKdwrF,UAJgBr2E,IAAiBA,EAAa5Z,OAK9CyE,UACAmV,eACAo2E,cAAe1gF,KAAK0gF,iBAf1B,0CAmBsBxwF,GAAM,IAChBukB,EAAYzU,KAAZyU,QACFmsE,EAA6B,GAC7BC,EAAmB,IAAIpoD,IAmB7B,OAjBIhkB,EAAQqsE,YACV5wF,EAAK6wF,QAAQlzE,SAAQ,SAAAja,GAAU,IACrBoR,EAAsBpR,EAAO2W,YAA7BvF,kBAC+B,aAAnCpR,EAAOiX,UAAUutE,eACnBwI,EAA2B5vF,KAAKgU,MAGpC9U,EAAK6wF,QAAQlzE,SAAQ,SAAAja,GAAU,IACrBoR,EAAsBpR,EAAO2W,YAA7BvF,kBAC+B,aAAnCpR,EAAOiX,UAAUutE,gBACdwI,EAA2B9yE,SAAS9I,IACvC67E,EAAiBrmC,IAAIx1C,QAMtB67E,O,2BAzCX,K,uyBCEO,IAAMG,GAAiB,CAC5BztF,KAAM,UAMK0tF,GAAb,YACE,aAAsB,O,4FAAA,oCAAPliF,EAAO,yBAAPA,EAAO,kEACXA,K,UAFb,O,kOAAA,M,EAAA,G,EAAA,gCAKW7O,GACP,IAEIiF,EAFEyjB,EAAQ1oB,EAAK6wF,QAAQ3jD,OAAOltC,EAAKgxF,YACjC52E,EAAe,GAerB,OAZAsO,EAAM/K,SAAQ,SAAAhC,GACZ,IAAMtB,EAAcsB,EAAKtB,YAEpBA,EAAYoR,UACfrR,EAAatZ,KAAKuZ,MAIlBD,EAAa5Z,SACfyE,EAAU,2CAGL6K,KAAKmhF,iBAAiBhsF,EAASmV,Q,2BAtB1C,GAAuCm2E,G,gzBCPhC,IAAMW,GAA2B,CACtC7tF,KAAM,SACNyjC,WAAY,CACVrwB,MAAO,CACL7E,MAAO,gCACPvO,KAAM,UACN8tF,QAAS,GAEXP,UAAW,CACTh/E,MAAO,oCACPvO,KAAM,WAER4rF,QAAS,CACPr9E,MAAO,2DACPvO,KAAM,WAER4B,QAAS,CACP2M,MAAO,mDACPvO,KAAM,WAGVmqB,SAAU,CAAC,UAYA4jE,GAAb,YACE,aAAsB,O,4FAAA,oCAAPviF,EAAO,yBAAPA,EAAO,oEACXA,K,UAFb,O,mOAAA,M,EAAA,G,EAAA,gCAKW7O,GAAM,IA6BTiF,EA5BIsf,EAAYzU,KAAZyU,QACF8sE,EAAkB,GACpBj3E,EAAe,GAEbu2E,EAAmB7gF,KAAKwhF,oBAAoBtxF,GAyBlD,GAxBAA,EAAK6wF,QAAQlzE,SAAQ,SAAAja,GAAU,IACrB2W,EAAgB3W,EAAhB2W,YACAoR,EAAwDpR,EAAxDoR,SAAU3W,EAA8CuF,EAA9CvF,kBAAmBk6E,EAA2B30E,EAA3B20E,cAAeC,EAAY50E,EAAZ40E,QAEhDD,GAGmB,kBAAZC,GAAoD,kBAApB1qE,EAAQ0qE,SAAyB1qE,EAAQ0qE,UAAYA,IAG3FoC,EAAgB5lE,KACnB4lE,EAAgB5lE,GAAY,IAAI8c,KAG7BhkB,EAAQqsE,YAAaD,EAAiB5lD,IAAIj2B,IAC7Cu8E,EAAgB5lE,GAAU6+B,IAAIx1C,GAG5Bu8E,EAAgB5lE,GAAU+E,KAAOjM,EAAQ9N,OAC3C2D,EAAatZ,KAAKuZ,OAKlBD,EAAa5Z,OAAQ,CACvB,IAAM0tF,EAAY3pE,EAAQqsE,UAAY,OAAS,GAC/C3rF,EACEsf,EAAQtf,SAAR,+CAEAsf,EAAQ9N,MAFR,YAGIy3E,EAHJ,YAMJ,OAAOp+E,KAAKmhF,iBAAiBhsF,EAASmV,Q,6BA5C1C,GAAiDm2E,G,gzBCjC1C,IAAMgB,GAAmB,CAC9BluF,KAAM,SACNyjC,WAAY,CACVrwB,MAAO,CACL7E,MAAO,+BACPvO,KAAM,UACN8tF,QAAS,GAEXP,UAAW,CACTh/E,MAAO,oCACPvO,KAAM,WAERmuF,WAAY,CACV5/E,MACE,oEACFvO,KAAM,QACNqlB,MAAO,CACLrlB,KAAM,UAERouF,SAAU,EACVC,aAAa,GAEfC,cAAe,CACb//E,MACE,uEACFvO,KAAM,QACNqlB,MAAO,CACLrlB,KAAM,UAERouF,SAAU,EACVC,aAAa,GAEfzC,QAAS,CACPr9E,MAAO,2DACPvO,KAAM,WAER4B,QAAS,CACP2M,MAAO,mDACPvO,KAAM,WAGVmqB,SAAU,CAAC,UAaAokE,GAAb,YACE,aAAsB,O,4FAAA,oCAAP/iF,EAAO,yBAAPA,EAAO,oEACXA,K,UAFb,O,mOAAA,M,EAAA,G,EAAA,gCAKW7O,GAAM,IACLukB,EAAYzU,KAAZyU,QAEFosE,EAAmB7gF,KAAKwhF,oBAAoBtxF,GAC5C6xF,EAAqB,GAC3B7xF,EAAK6wF,QAAQlzE,SAAQ,SAAAja,GAAU,MACmCA,EAAO2W,YAA/DoR,EADqB,EACrBA,SAAU3W,EADW,EACXA,kBAAmBk6E,EADR,EACQA,cAAeC,EADvB,EACuBA,QAEhDD,GAGmB,kBAAZC,GAAoD,kBAApB1qE,EAAQ0qE,SAAyB1qE,EAAQ0qE,UAAYA,GAG5F1qE,EAAQqsE,YAAcD,EAAiB5lD,IAAIj2B,IAG3CyP,EAAQitE,aAAwD,IAA1CjtE,EAAQitE,WAAW7nE,QAAQ8B,IAGjDlH,EAAQotE,eAAiBptE,EAAQotE,cAAchoE,QAAQ8B,IAAa,GAGxEomE,EAAmB/wF,KAAKgU,MAG1B,IAKI7P,EALA6sF,EAAa,GAMjB,GAL+B,kBAApBvtE,EAAQ0qE,UACjB6C,EAAavtE,EAAQ0qE,QAAU,SAAW,eAIxC4C,EAAmBrxF,OAAS+jB,EAAQ9N,MAAO,CAC7C,IAAMy3E,EAAY3pE,EAAQqsE,UAAY,OAAS,GACzCmB,EAA2B,IAAlBxtE,EAAQ9N,MAAc,GAAK,IACpCu7E,EAA2B,IAAlBztE,EAAQ9N,MAAc,GAAtB,oBAAwC8N,EAAQ9N,OAC/DxR,EACEsf,EAAQtf,SAAR,oCAC6B+sF,EAD7B,YACuC9D,GADvC,OACmD4D,EADnD,iBACsEC,EADtE,KAIJ,OAAOjiF,KAAKmhF,iBAAiBhsF,Q,6BA9CjC,GAAyCsrF,G,gzBCtDlC,IAAM0B,GAA2B,CACtC5uF,KAAM,SACNyjC,WAAY,CACVorD,SAAU,CACRtgF,MAAO,8BACPvO,KAAM,SACN8tF,QAAS,GAEXgB,UAAW,CACTvgF,MAAO,+BACPvO,KAAM,SACN8tF,QAAS,GAEXiB,iCAAkC,CAChCxgF,MAAO,iCACPvO,KAAM,SACN8tF,QAAS,GAEXkB,kCAAmC,CACjCzgF,MAAO,kCACPvO,KAAM,SACN8tF,QAAS,GAEXmB,WAAY,CACV1gF,MACE,qEACFvO,KAAM,QACNqlB,MAAO,CACLrlB,KAAM,UAERouF,SAAU,EACVC,aAAa,GAEfa,cAAe,CACb3gF,MACE,wEACFvO,KAAM,QACNqlB,MAAO,CACLrlB,KAAM,UAERouF,SAAU,EACVC,aAAa,GAEfF,WAAY,CACV5/E,MACE,oEACFvO,KAAM,QACNqlB,MAAO,CACLrlB,KAAM,UAERouF,SAAU,EACVC,aAAa,GAEfC,cAAe,CACb//E,MACE,uEACFvO,KAAM,QACNqlB,MAAO,CACLrlB,KAAM,UAERouF,SAAU,EACVC,aAAa,GAEfzC,QAAS,CACPr9E,MAAO,2DACPvO,KAAM,WAER4B,QAAS,CACP2M,MAAO,mDACPvO,KAAM,WAGVmvF,MAAO,CACL,CAAEhlE,SAAU,CAAC,UAAW,aACxB,CAAEA,SAAU,CAAC,UAAW,cACxB,CAAEA,SAAU,CAAC,UAAW,qCACxB,CAAEA,SAAU,CAAC,UAAW,wCAoBfilE,GAAb,YACE,aAAsB,O,4FAAA,oCAAP5jF,EAAO,yBAAPA,EAAO,oEACXA,K,UAFb,O,mOAAA,M,EAAA,G,EAAA,gCAKW7O,GACP,IAAIiF,EACAmV,EAAe,GACXmK,EAAYzU,KAAZyU,QACFmuE,EAAiBnuE,EAAQ6tE,iCACzBO,EAAkBpuE,EAAQ8tE,kCAuDhC,OArDAryF,EAAK6wF,QAAQlzE,SAAQ,SAAAhC,GAAQ,IACnBgoB,EAA0BhoB,EAA1BgoB,SAAUtpB,EAAgBsB,EAAhBtB,YACVoR,EAAapR,EAAboR,SAEF05D,EAA+C9qE,EAA/C8qE,gBAAiBD,EAA8B7qE,EAA9B6qE,iBAAkB+J,EAAY50E,EAAZ40E,QACzC,GAAI50E,EAAYu4E,gBAAiB,CAC/B,IAAM7sC,EAAQ1rC,EAAY4qE,cAC1BE,EAAmBp/B,GAASA,EAAMo/B,iBAAoB,EACtDD,EAAoBn/B,GAASA,EAAMm/B,kBAAqB,EAR/B,IAWnBhzB,EAAmBvuB,EAAnBuuB,eAEFl1B,EAAW2G,EAASqB,YAAY,aAAe,GAIhC,kBAAZiqD,GACoB,kBAApB1qE,EAAQ0qE,SACf1qE,EAAQ0qE,UAAYA,GAGlB1qE,EAAQitE,aAAwD,IAA1CjtE,EAAQitE,WAAW7nE,QAAQ8B,IAEjDlH,EAAQ+tE,aAAwD,IAA1C/tE,EAAQ+tE,WAAW3oE,QAAQqT,IAEjDzY,EAAQotE,eAAiBptE,EAAQotE,cAAchoE,QAAQ8B,IAAa,GAEpElH,EAAQguE,eAAiBhuE,EAAQguE,cAAc5oE,QAAQqT,IAAa,IAKrEzY,EAAQ2tE,UAAY/M,EAAkB5gE,EAAQ2tE,UAC9C3tE,EAAQ4tE,WAAajN,EAAmB3gE,EAAQ4tE,WAChDO,IACElN,MAAMtzB,IACPizB,EAAkBuN,EAAiBxgC,GACpCygC,IACEnN,MAAMtzB,IACPgzB,EAAmByN,EAAkBzgC,IAIvC93C,EAAatZ,KAAKuZ,MAKlBD,EAAa5Z,SACfyE,EAAUsf,EAAQtf,SAGb6K,KAAKmhF,iBAAiBhsF,EAASmV,Q,6BAjE1C,GAAiDm2E,G,gzBChG1C,IAAMsC,GAAiB,CAC5BxvF,KAAM,SACNyjC,WAAY,CACV6a,OAAQ,CACN/vC,MAAO,8DACPvO,KAAM,SACNyvF,KAAM,CAAC,QAAS,SAElBC,iBAAkB,CAChBnhF,MAAO,mDACPvO,KAAM,QACNqlB,MAAO,CACLrlB,KAAM,UAERouF,SAAU,EACVC,aAAa,GAEf7sE,WAAY,CACVjT,MAAO,oCACPvO,KAAM,QACNqlB,MAAO,CACLrlB,KAAM,UAERouF,SAAU,EACVC,aAAa,IAGjBlkE,SAAU,CAAC,SAAU,eAWVwlE,GAAb,YACE,aAAsB,O,4FAAA,oCAAPnkF,EAAO,yBAAPA,EAAO,oEACXA,K,UAFb,O,mOAAA,M,EAAA,G,EAAA,gCAKW7O,GACP,IAKIiF,EALE8tF,EAAmBjjF,KAAKyU,QAAQwuE,kBAAoB,CAAC,WACrDE,EAAgB,IAAI1qD,IAAIz4B,KAAKyU,QAAQM,YACrCquE,EAAmBpjF,KAAKyU,QAAQo9B,OAChCvnC,EAAe,GACf+4E,EAAoB,IAAI5qD,IAoB9B,GAjBAwqD,EAAiBp1E,SAAQ,SAAAy1E,GACTpzF,EAAKozF,GAEbz1E,SAAQ,SAAAhC,GAAQ,IACZtB,EAA0BsB,EAA1BtB,YACF2iB,EAD4BrhB,EAAbgoB,SACKqB,YAAY,aAAe,IAG7B,UAArBkuD,IAAiCD,EAAcloD,IAAI/N,IAC9B,SAArBk2D,GAA+BD,EAAcloD,IAAI/N,MAElD5iB,EAAatZ,KAAKuZ,GAClB84E,EAAkB7oC,IAAIttB,UAKxB5iB,EAAa5Z,OAAQ,CACvB,IAAM6yF,EAAmBh+E,MAAMg8B,KAAK8hD,GAC9BG,EAAuBD,EAAiBr3E,KAAK,MAC7Cu3E,EACJF,EAAiB7yF,OAAS,EAAI,aAAe,WAE/CyE,EAAU,OAAH,OAAUsuF,EAAV,YAA0BD,EAA1B,kDAGT,OAAOxjF,KAAKmhF,iBAAiBhsF,EAASmV,Q,6BAvC1C,GAAuCm2E,G,gzBCtChC,IAAMiD,GAA0B,CACrCnwF,KAAM,UAMKowF,GAAb,YACE,aAAsB,O,4FAAA,oCAAP5kF,EAAO,yBAAPA,EAAO,oEACXA,K,UAFb,O,mOAAA,M,EAAA,G,EAAA,gCAKW7O,GACP,IAEIiF,EAFEyjB,EAAQ1oB,EAAKgxF,WACb52E,EAAe,GAgBrB,OAbAsO,EAAM/K,SAAQ,SAAAhC,GACZ,IAAMtB,EAAcsB,EAAKtB,YAGR,aAFCA,EAAYk0D,UAAY,IAAIp8D,eAG5CiI,EAAatZ,KAAKuZ,MAIlBD,EAAa5Z,SACfyE,EAAU,iDAGL6K,KAAKmhF,iBAAiBhsF,EAASmV,Q,6BAvB1C,GAAgDm2E,G,gzBCPzC,IAAMmD,GAAmB,CAC9BrwF,KAAM,UAMKswF,GAAb,YACE,aAAsB,O,4FAAA,oCAAP9kF,EAAO,yBAAPA,EAAO,oEACXA,K,UAFb,O,mOAAA,M,EAAA,G,EAAA,gCAKW7O,GACP,IAEIiF,EAFEyjB,EAAQ1oB,EAAK6wF,QACbz2E,EAAe,GAmBrB,OAhBAsO,EAAM/K,SAAQ,SAAAhC,GACZ,IAAMtB,EAAcsB,EAAKtB,YAGE,kBAAzBA,EAAYkwE,UACXlwE,EAAY4qE,eAEb7qE,EAAatZ,KAAKuZ,MAIlBD,EAAa5Z,SACfyE,EACE,+EAGG6K,KAAKmhF,iBAAiBhsF,EAASmV,Q,6BA1B1C,GAAyCm2E,G,4LCLzC,IAAMqD,GAAWnzF,OAAOqhC,OAAO,GAAI+xD,GAEtBC,GAAb,WACE,WAAYC,GAAgB,Y,4FAAA,SAC1B,IAAMC,EAAoBlkF,KAAKmkF,uBAG/B,GAFAnkF,KAAKokF,SAAW,IAEXF,EAAkBD,GAAiB,CACtC,IAAI9uF,EAAU,GAId,MAHA+uF,EAAkBzzC,OAAO5iC,SAAQ,SAAA/Y,GAC/BK,GAAW,YAAJ,OAAgBL,EAAMuvF,SAAtB,YAAkCvvF,EAAMK,YAE3C,IAAIpB,MAAMoB,GAGlBxE,OAAO4c,KAAK02E,GAAgBp2E,SAAQ,SAAAy2E,GAClC,IAAMC,EAAgBN,EAAeK,GAC/BE,EAAYV,GAAS,GAAD,OAAIQ,EAAJ,eAExBC,aAAyBh/E,MAAQg/E,EAAgB,CAACA,IACvC12E,SAAQ,SAAA4G,GAAO,OAC1B,EAAK2vE,SAASpzF,KAAK,IAAIwzF,EAAU/vE,EAAS6vE,U,UAnBlD,O,EAAA,E,EAAA,oCAoFsBG,EAAcC,GAChCZ,GAASW,GAAgBC,M,EArF7B,uCAwBmC,IAAnB5D,EAAmB,wDAC3BvvF,EAAS,EAUb,OATAyO,KAAKokF,SAASv2E,SAAQ,SAAA82E,GACpB,IAAMC,EAAiB9D,MAAgB6D,EAAUlwE,QAAQqsE,UACzD,GAAI6D,aAAqBb,GAAShC,qBAAuB8C,EAAgB,KAC/Dj+E,EAAUg+E,EAAUlwE,QAApB9N,MACJA,EAAQpV,IACVA,EAASoV,OAIRpV,IAnCX,6CAuCI,GAAIyyF,EAAkBE,kBACpB,OAAOF,EAAkBE,kBAG3B,IAAMW,EAAS,CACb7tD,WAAY,GACZ8tD,YAAa,IAyBf,OAtBAn0F,OAAO4c,KAAKu2E,IAAUj2E,SAAQ,SAAAnX,GAE5B,GADkBotF,GAASptF,GACb9F,qBAAqB6vF,EAAe,CAChD,IAAM6D,EAAe5tF,EAAIyc,QAAQ,aAAc,IACzC4xE,EAAsB,iBAAH,OAAoBT,GAE7CO,EAAOC,YAAYR,GAAgBR,GAAS,GAAD,OAAIQ,EAAJ,WAC3CO,EAAO7tD,WAAWstD,GAAgB,CAChC7jE,MAAO,CACL,CAAEukE,KAAMD,GACR,CACExxF,KAAM,QACNqlB,MAAO,CACLosE,KAAMD,UAQlBf,EAAkBE,mBAAoB,IAAIe,MAAMC,QAAQL,GACjDb,EAAkBE,oBAtE7B,+BAyEWh0F,GACP,IAAMi1F,EAAkB,GAOxB,OANAnlF,KAAKokF,SAASv2E,SAAQ,SAAA82E,GACpB,IAAMS,EAAkBT,EAAUzP,SAAShlF,GACtCk1F,EAAgBhxD,QACnB+wD,EAAgBn0F,KAAKo0F,MAGlBD,O,6BAjFX,K,UCJaE,G,w+BCEb,IAAMC,GAAc30F,OAAOqhC,OAAO,GAAIuzD,GA+NvBC,G,WAtNb,WAAYC,EAAgB5K,GAA4B,IAAdpmE,EAAc,uDAAJ,I,4FAAI,SACtDzU,KAAKylF,eAAiBA,EACtBzlF,KAAK66E,aAAeA,EACpB76E,KAAKmlF,gBAAkB,GACvBnlF,KAAK0lF,uBAAyB,GAC9B1lF,KAAK2lF,WAAa,KAClB3lF,KAAK4lF,cAAgB,KACrB5lF,KAAKyU,QAAUA,E,4DAGPa,GACR,GAAsC,mBAA3BtV,KAAKyU,QAAQ+nB,UACtB,MAAM,IAAIzoC,MAAM,qCAGlB,OAAOiM,KAAKyU,QAAQ+nB,UAAU,KAAMlnB,K,gEAGvBuwE,G,mHACPC,EAAkB9lF,KAAK2yC,QA1BhB,YA2BPozC,EAAkB/lF,KAAK2yC,QA1BhB,Y,SA2B8BpgD,QAAQiD,IAAI,CACrDswF,EACAC,I,iCAFKC,E,KAAcC,E,MAIfC,EAAa,CACjBnF,QAAS,GACTG,WAAY,KAGHH,QAAUmF,EAAWnF,QAAQ3jD,OAAO4oD,EAAajF,SAC5DmF,EAAWnF,QAAUmF,EAAWnF,QAAQ3jD,OAAO6oD,EAAalF,SAC5DmF,EAAWhF,WAAagF,EAAWhF,WAAW9jD,OAC5C4oD,EAAa9E,YAEfgF,EAAWhF,WAAagF,EAAWhF,WAAW9jD,OAC5C6oD,EAAa/E,YAGflhF,KAAK2lF,WAAa,KAClB3lF,KAAK4lF,cAAgB,KACfO,EAAanmF,KAAKomF,kBA9Cf,OAgDPP,EACAK,GAEIG,EAAiBrmF,KAAKomF,kBArDf,WAuDXP,EACAG,GAEIM,EAAiBtmF,KAAKomF,kBAzDf,WA2DXP,EACAI,GAEId,EAAkBkB,EACrBjpD,OAAOkpD,GACPlpD,OAAO+oD,GACJT,EAAyB1lF,KAAKumF,qBAAqBpB,GAIzDnlF,KAAKmlF,gBAAkBA,EACvBnlF,KAAK0lF,uBAAyBA,EAE9B1uF,QAAQM,KAAK,mBACbN,QAAQM,KAAK6tF,GACbnuF,QAAQM,KAAK,0BACbN,QAAQM,KAAKouF,G,kBAENP,G,0IAGYA,GACnB,IAAMqB,EAAS,GACT1L,EAAiB96E,KAAKylF,eAAe3K,eA8B3C,OA5BAqK,EAAgBt3E,SAAQ,SAAA44E,GACtB,GAAIA,EAAc9F,SAIhB,OAHA6F,EAAOE,QAAUF,EAAOE,SAAW,CAAEC,SAAU,SAC/CH,EAAOE,QAAQC,SAAS31F,KAAKy1F,EAActxF,SAK7CsxF,EAAcn8E,aAAauD,SAAQ,SAAAtD,GACjC,IAAMG,EAAYowE,EAAevwE,EAAYkwE,UAC7C+L,EAAO97E,GAAa87E,EAAO97E,IAAc,CAAEq3E,mBAAoB,IAE/D,IAAMtC,EAAQ+G,EAAO97E,GACfk8E,EAAgBr8E,EAAYvF,kBAC9B+8E,EAAqBtC,EAAMsC,mBAAmB6E,GAE7C7E,IACHA,EAAqBtC,EAAMsC,mBAAmB6E,GAAiB,CAC7DD,SAAU,GACVr8E,aAAc,KAIlBy3E,EAAmB4E,SAAS31F,KAAKy1F,EAActxF,SAC/C4sF,EAAmBz3E,aAAatZ,KAAKuZ,SAIlCi8E,I,wCAGSpO,EAAeyN,EAAmB31F,GAAM,WAClD22F,EAAa7mF,KAAK8mF,cAAc1O,EAAeyN,GACjDV,EAAkB,GAwBtB,OAtBA0B,EAAWh5E,SAAQ,SAAAk5E,GACjB,IAAMpB,EAAaoB,EAAUC,eAAc,GACrCpB,EAAgBmB,EAAUC,eAAc,GAC1CrB,IACF,EAAKA,WAAaA,GAGhBC,IACF,EAAKA,cAAgBA,GAGvB,IAAMr0F,EAASw1F,EAAU7R,SAAShlF,GAE9BqB,EAAOb,OAAS,GAClBa,EAAOsc,SAAQ,SAAAo5E,GACbA,EAAW7O,cAAgBA,KAI/B+M,EAAkBA,EAAgB/nD,OAAO7rC,MAGpC4zF,I,oCAGK/M,EAAeyN,GAC3B,IAAMgB,EAAa,GACnB7vF,QAAQM,KAAKguF,IACb,IAAM4B,EAAsBrB,EAAkBrjF,GAAGH,cAC3C8kF,EAAa7B,GAAY4B,GAE/B,GAAIC,EAAY,CACd,IAAMC,EAAsBD,EAAW/O,GAEnCgP,GACFP,EAAW71F,KAAK,IAAIgzF,GAAkBoD,IAI1C,OAAOP,I,+DAMKzO,G,wGACNloF,EAAO,CACX6wF,QAAS,GACTG,WAAY,IAGRmG,EAAgB,IAEhBC,EAAW,SAAAhE,GACM,EAAKmC,eAAejnB,MAAM8kB,GAElCz1E,SAAQ,SAAAtD,GAAe,IAC1B+K,EAAqB/K,EAArB+K,iBAEF6hE,EAAc5sE,EAAY4sE,YAC1BtsE,EACJssE,GACA,EAAK0D,aAAajwE,WAAWqL,MAAK,SAAA0a,GAAC,OAAIA,EAAEwmD,cAAgBA,KAE3D,GACGtsE,IAvLE,SAwLFutE,GAA0BvtE,EAAUutE,gBAAkBA,GAFzD,CAOA,IAAM9jF,EAAU,EAAKkoC,UAAUlnB,GAC/BhhB,EAAQF,MACN,SAAAqoC,GACEvsC,EAAKozF,GAAiBtyF,KAAK,CACzBuZ,cACAspB,SAAU4I,EAAcnC,mBACxBzvB,iBAGJ,SAAA/V,GACE,MAAM,IAAIf,MAAMe,MAGpBuyF,EAAcr2F,KAAKsD,SAzMX,WA8MZgzF,EA7Me,c,SA+MT/0F,QAAQiD,IAAI6xF,G,gCAEXn3F,G,4IAGuBq3F,EAAeC,GAC7ClC,GAAYiC,GAAiBC,K,8CC7NlB,YAAS3+E,EAASu1B,GAC1BA,IAGHA,EADuB3Q,IAAYkB,kBAAkB9lB,GAC5BymB,MAAM8O,SAJO,MAapC3Q,IAAYo7C,SAAS7yE,IAAI,WAAYooC,GAJvC9oB,EATsC,EAStCA,iBACAoN,EAVsC,EAUtCA,UACAgb,EAXsC,EAWtCA,kBACAE,EAZsC,EAYtCA,eAGIqqB,EAAe7pB,EAAQnyB,MAAM,UAC7B0uE,OACgBtlF,IAApB4yD,EAAa,GAAmB7K,OAAO6K,EAAa,IAAM,EAEtDyyB,EAAY,CAChBplE,EACAooB,EACAE,EACA+8C,GACAzuE,KAAK,KAEP,MAAO,CACLwW,YACApN,mBACAooB,oBACAE,iBACA+8C,aACAD,cChCW,SAAS+M,KACtBh6D,IAAY8uD,qBAAqB1uE,SAAQ,SAAA6gB,GACnCA,EAAeY,OACjB7B,IAAY+uD,YAAY9tD,EAAe7lB,YCG9B,SAAS6+E,GAAT,GAA2D,IAAnBv4D,EAAmB,EAAnBA,UAAWe,EAAQ,EAARA,KAC1Du1D,EAAiB7K,EAAejD,SACjC8N,GACHpuF,IAAIC,KAAK,sCAH6D,IAMhE4M,EAA8BirB,EAA9BjrB,gBAAiBu2E,EAAatrD,EAAbsrD,SAKzB,GAHmBgL,EAAe/O,MAAM+D,IAMnCv2E,IAAmBA,EAAgByjF,UAAxC,CAEAtwF,IAAIE,KAAK,oCAET,IAAMqwF,EAAkBC,GAAmB14D,EAAUtmB,SAC/C0B,EAAc5Z,OAAOqhC,OAAO,GAAI9tB,EAAiB0jF,EAAiB,CACtEpR,mBAAoBtyE,EAAgBsyE,mBACpCsR,OAAQl7D,KAAK0L,YACbmiD,aAGIsE,EAAmB0G,EAAepJ,eAAe5B,EAAUlwE,GACjE5Z,OAAOqhC,OAAO9tB,EAAiB66E,GAE/B,IAAM/D,EAAmBC,EAAS/2E,GAC9B82E,IACF92E,EAAgBg3E,OAAS,CAACF,IAI5ByM,KAII7M,EAAe6B,eAAevsD,ICtCrB,mBAAsD,IAA3Cf,EAA2C,EAA3CA,UAAWe,EAAgC,EAAhCA,KAC7Bu1D,GAD6D,EAA1B3O,YAA0B,EAAblC,UAC/BgG,EAAejD,UACjC8N,GACHpuF,IAAIC,KAAK,sCAHwD,IAM3D4M,EAAoBirB,EAApBjrB,gBAEFq6E,EAAakH,EAAe/O,MAAMxmD,EAAK8sD,YAG7C,GAAKuB,GAGAr6E,IAAmBA,EAAgByjF,UAAxC,CAEAtwF,IAAIE,KAAK,oCAET,IAAMqwF,EAAkBC,GAAmB14D,EAAUtmB,SAE/Ck/E,EAAuBp3F,OAAOqhC,OAAO41D,EAAiB,CAC1DE,OAAQl7D,KAAK0L,cAGTkjD,EAAmB7qF,OAAOqhC,OAC9B,GACA9tB,EACA6jF,GAGIC,EAAoBzJ,EAAWtoE,MACnC,SAAA5f,GAAC,OACCA,EAAEokF,WAAavqD,EAAK8sD,YACpB3mF,EAAEqsB,YAAcklE,EAAgBllE,WACV,OAAtBrsB,EAAE65B,EAAKuE,cAIX,GAAIuzD,EAAmB,CACrB,IAAMtxF,EAAMw5B,EAAKuE,UAGjB+mD,EAAiBmD,UAAY,IAAI/gE,KAGjCoqE,EAAkBtxF,GAAO8kF,EACzBwM,EAAkBlF,iBACfkF,EAAkBlF,iBAAmB,GAAK,EAC7C2C,EAAewC,kBAAkB/3D,EAAK8sD,WAAYgL,GAGlD9jF,EAAgBu3E,IAAMuM,EAAkBvM,IACxCv3E,EAAgBsyE,mBAAqBwR,EAAkBxR,uBAClD,CACL,IAAMjsE,EAAc,CAClBkwE,SAAUvqD,EAAK8sD,WACfxG,mBAAoBtyE,EAAgBsyE,mBACpCsR,OAAQl7D,KAAK0L,YACb5V,UAAWklE,EAAgBllE,UAC3BpN,iBAAkBsyE,EAAgBtyE,kBAGpC/K,EAAY2lB,EAAKuE,WAAa9jC,OAAOqhC,OACnC,GACA9tB,EACA6jF,GAGF,IAAMhJ,EAAmB0G,EAAepJ,eACtCnsD,EAAK8sD,WACLzyE,GAEF5Z,OAAOqhC,OAAO9tB,EAAiB66E,GAGjC,IAAM/D,EAAmBC,EAAS/2E,GAC9B82E,IACF92E,EAAgBg3E,OAAS,CAACF,IAI5ByM,KAII7M,EAAe6B,eAAevsD,KCzFrB,eAAsD,IAA3Cf,EAA2C,EAA3CA,UAAWe,EAAgC,EAAhCA,KAC7Bu1D,GAD6D,EAA1B3O,YAA0B,EAAblC,UAC/BgG,EAAejD,UACjC8N,GACHpuF,IAAIC,KAAK,sCAHwD,IAM3D4M,EAA8BirB,EAA9BjrB,gBAAiBu2E,EAAatrD,EAAbsrD,SAEnB8D,EAAakH,EAAe/O,MAAM+D,GAGxC,GAAK8D,EAAL,CAEAlnF,IAAIE,KAAK,uCACT,IAAIgT,EAAcg0E,EAAWtoE,MAAK,SAAA5f,GAAC,OAAIA,EAAEolF,MAAQv3E,EAAgBu3E,OAG5DlxE,KAELA,EAAc5Z,OAAOqhC,OAAOznB,EAAarG,IAC7B6zB,SAAWtK,IAAYy6D,YAAY/4D,EAAUtmB,SAEzD48E,EAAewC,kBAAkBxN,EAAUlwE,GAIvCqwE,EAAe6B,eAAevsD,MC1BrB,eAAsD,IAA3Cf,EAA2C,EAA3CA,UAAWe,EAAgC,EAAhCA,KAC7Bu1D,GAD6D,EAA1B3O,YAA0B,EAAblC,UAC/BgG,EAAejD,UACjC8N,GACHpuF,IAAIC,KAAK,sCAHwD,IAM3D4M,EAAoBirB,EAApBjrB,gBAEFq6E,EAAakH,EAAe/O,MAAMxmD,EAAK8sD,YAG7C,GAAKuB,EAAL,CAEAlnF,IAAIE,KAAK,uCAET,IAAMgT,EAAcg0E,EAAWtoE,MAAK,SAAA5f,GAAC,OAAIA,EAAEolF,MAAQv3E,EAAgBu3E,OAC/DD,EAAmBjxE,GAAeA,EAAY2lB,EAAKuE,WAGlD+mD,KAELA,EAAmB7qF,OAAOqhC,OAAOwpD,EAAkBt3E,IAClC6zB,SAAWtK,IAAYy6D,YAAY/4D,EAAUtmB,SAG9D0B,EAAY2lB,EAAKuE,WAAa+mD,EAC9BiK,EAAewC,kBAAkB/3D,EAAK8sD,WAAYzyE,GAI9CqwE,EAAe6B,eAAevsD,MC7BrB,SAASi4D,GAAT,GAKZ,IAJDh5D,EAIC,EAJDA,UACAe,EAGC,EAHDA,KAGC,EAFD4mD,YAEC,EADDlC,UAEAv9E,IAAIE,KAAK,sCADR,IAEO2M,EAA8BirB,EAA9BjrB,gBAAiBu2E,EAAatrD,EAAbsrD,SAEnBgL,EAAiB7K,EAAejD,SACjC8N,GACHpuF,IAAIC,KAAK,sCAGX,IAAMinF,EAAakH,EAAe/O,MAAM+D,GAGxC,GAAK8D,EAAL,CAEA,IAAMnC,EAAoBqJ,EAAe3K,eAAeL,GAClDlwE,EAAcg0E,EAAWtoE,MAAK,SAAA5f,GAAC,OAAIA,EAAEolF,MAAQv3E,EAAgBu3E,OAGnE,GAAKlxE,EAAL,CAlBC,IAqBOisE,EAAoCjsE,EAApCisE,mBAAoBW,EAAgB5sE,EAAhB4sE,YAC5BsO,EAAe2C,mBAAmB3N,EAAU2B,EAAmB,CAC7D5F,qBACAW,gBAIFsQ,KAEI7M,EAAe6B,eAAevsD,KCnCrB,mBAAsD,IAA3Cf,EAA2C,EAA3CA,UAAWe,EAAgC,EAAhCA,KAAgC,EAA1B4mD,YAA0B,EAAblC,UACtDv9E,IAAIE,KAAK,sCAD0D,IAE3D2M,EAAoBirB,EAApBjrB,gBAEFuhF,EAAiB7K,EAAejD,SACjC8N,GACHpuF,IAAIC,KAAK,sCAGX,IAAMinF,EAAakH,EAAe/O,MAAMxmD,EAAK8sD,YAG7C,GAAKuB,EAAL,CAEA,IAAM8J,EAAmB9J,EAAWhnE,WAClC,SAAAlhB,GAAC,OAAIA,EAAEolF,MAAQv3E,EAAgBu3E,OAE3BlxE,EACJ89E,GAAoB,EAAI9J,EAAW8J,GAAoB,KAGpD99E,IAE+B,IAAhCA,EAAYu4E,iBAEdvE,EAAW3sF,OAAOy2F,EAAkB,GACpC5C,EAAepF,qBAAqBnwD,EAAK8sD,WAAYzyE,KAGrDA,EAAY2lB,EAAKuE,WAAa,KAC9BlqB,EAAYu4E,iBAAmBv4E,EAAYu4E,iBAAmB,GAAK,EACnE2C,EAAewC,kBAAkB/3D,EAAK8sD,WAAYzyE,IAIpDk9E,KAEI7M,EAAe6B,eAAevsD,MClC9Bo4D,GAAe,SAAA50F,GACnB,IAAMy7B,EAAYz7B,EAAM8jB,OAKxB,OAJI2X,EAAUo5D,WACZp5D,EAAUsrD,SAAWtrD,EAAUo5D,UAG1Bp5D,GAoFMq5D,GAjFa,CAC1Bd,gCACAe,+BACAC,mCACAC,kCACAR,kCACAS,iCAEAC,QAR0B,SAQlBn1F,GACN,IAAMy7B,EAAYm5D,GAAa50F,GACvB+mF,EAAatrD,EAAbsrD,SAFK,EAOTG,EAAeU,qBAAqBb,GAHtC3D,EAJW,EAIXA,YACAlC,EALW,EAKXA,UACA1kD,EANW,EAMXA,KAEI44D,EAAS,CACb35D,YACAe,OACA4mD,cACAlC,aAGG1kD,IAEDA,EAAK8sD,WACPyL,GAA4BK,GAE5BpB,GAA6BoB,KAIjCC,WAhC0B,SAgCfr1F,GACT,IAAMy7B,EAAYm5D,GAAa50F,GACvB+mF,EAAatrD,EAAbsrD,SAFQ,EAOZG,EAAeU,qBAAqBb,GAHtC3D,EAJc,EAIdA,YACAlC,EALc,EAKdA,UACA1kD,EANc,EAMdA,KAEI44D,EAAS,CACb35D,YACAe,OACA4mD,cACAlC,aAGG1kD,IAEDA,EAAK8sD,WACP2L,GAA+BG,GAE/BJ,GAAgCI,KAIpCE,UAxD0B,SAwDhBt1F,GACR,IAAMy7B,EAAYm5D,GAAa50F,GACvB+mF,EAAatrD,EAAbsrD,SAFO,EAOXG,EAAeU,qBAAqBb,GAHtC3D,EAJa,EAIbA,YACAlC,EALa,EAKbA,UACA1kD,EANa,EAMbA,KAEI44D,EAAS,CACb35D,YACAe,OACA4mD,cACAlC,aAGG1kD,IAEDA,EAAK8sD,WACP4L,GAA8BE,GAE9BX,GAA+BW,MC3FxB/H,GAAU,CACrBv+E,GAAI,UACJpN,KAAM,UACNqhF,WAAY,CAACtB,EAAeiB,EAAUE,EAAUD,GAChD5hE,QAAS,CACPugE,aAAc,CACZC,SAAS,EACTC,UAAU,KCPHgM,GAAa,CACxB1+E,GAAI,aACJpN,KAAM,cACNqhF,WAAY,CAACV,GACbthE,QAAS,CACPugE,aAAc,CACZC,SAAS,EACTC,UAAU,K,oBCNVuB,GAAa78D,KAAU,CAAClpB,EAAQ4kF,IAGtCmB,GAAW5oE,SAAQ,SAAA+xE,GACjBA,EAAUnrE,QAAU9jB,OAAOqhC,OAAO,GAAI4tD,EAAUnrE,QAAS,CACvDugE,aAAc,CACZC,SAAS,EACTC,UAAU,QAKT,IAAM+T,GAAO,CAClBzmF,GAAI,OACJpN,KAAM,YACNqhF,cACAhiE,QAAS,CACPugE,aAAc,CACZC,SAAS,EACTC,UAAU,KCjBVgU,GAAUtvE,KAAU,CAACmnE,GAASG,GAAY+H,KAEhDC,GAAQr7E,SAAQ,SAAA+mE,GACdA,EAAU6B,WAAW5oE,SAAQ,SAAAqiB,GAC3BA,EAAK0kD,UAAYA,EAAUpyE,SAIhB0mF,ICFT5+E,GAAe,CACnBmtE,eACAmD,iBACA4K,uBACAgD,uBACAU,QDHaA,GCIbxS,QACAuE,WACAmE,iBACAyI,sBACAlM,0BAGarxE,Q,yDCVf,SAAS6+E,EAA0BtvC,EAAQvkC,EAAkB8zE,GAC3D,IAAMC,EAAY,GAoDlB,OAjDAD,EAAWv7E,SAAQ,SAASmvB,GAI1B,IAAIU,EAAoBzR,IAASuB,UAAUwP,EAAS,aAChDH,EAASwsD,EAAU3rD,GAIlBb,IACHA,EAAS,CACPa,kBAAmBA,EACnBqiB,aAAc9zB,IAASuB,UAAUwP,EAAS,aAC1CwhB,UAAW,IAIb6qC,EAAU3rD,GAAqBb,EAC/BA,EAAO7rC,KAAK6rC,IAYd,IAAIe,EAAiB3R,IAASuB,UAAUwP,EAAS,aAC7Cue,EACF1B,EAAOyvC,YACP,8BACAh0E,EACA,cACAooB,EACA,cACAE,EACA,mCAGFf,EAAO2hB,UAAUxtD,KAAK,CACpBgwD,YAAa/0B,IAASuB,UAAUwP,EAAS,aACzCY,eAAgBA,EAChB2d,IAAKA,EACL0L,eAAgBh7B,IAASuB,UAAUwP,EAAS,kBAhDjC,G,2WCFjB,SAASusD,EAAaz+E,GACpB,IAAKA,EAAM,MAAO,GAClB,IAAIqS,EAAOrS,EAAK0+E,cAAcz9D,WAC1BlP,GAAS/R,EAAK2+E,WAAa,GAAG19D,WAC9BxL,EAAMzV,EAAK4+E,UAAU39D,WAIzB,OAHA5O,EAAO,IAAIonD,OAAO,EAAIpnD,EAAKzsB,QAAQ0sC,OAAOjgB,GAC1CN,EAAQ,IAAI0nD,OAAO,EAAI1nD,EAAMnsB,QAAQ0sC,OAAOvgB,GAC5C0D,EAAM,IAAIgkD,OAAO,EAAIhkD,EAAI7vB,QAAQ0sC,OAAO7c,GACjC,GAAG6c,OAAOjgB,EAAMN,EAAO0D,GA8DhC,SAASopE,EAAoBP,GAC3B,IAAMloE,EAAU,GAEhB,GAAKkoE,GAAeA,EAAW14F,OA2B/B,OAzBA04F,EAAWv7E,SAAQ,SAAAqI,GAAK,OACtBgL,EAAQlwB,KAAK,CACXskB,iBAAkB2W,IAASuB,UAAUtX,EAAM,aAE3CrB,UAAWoX,IAASuB,UAAUtX,EAAM,aACpC0xC,UAAW37B,IAASuB,UAAUtX,EAAM,aACpCuM,gBAAiBwJ,IAASuB,UAAUtX,EAAM,aAC1C0zE,uBAAwB39D,IAASuB,UAAUtX,EAAM,aAEjDyM,YAAasJ,IAASoB,QAAQnX,EAAM,aACpCwM,UAAWuJ,IAASuB,UAAUtX,EAAM,aACpC2zE,iBAAkB59D,IAASuB,UAAUtX,EAAM,aAC3C4zE,WAAY79D,IAASuB,UAAUtX,EAAM,aACrC6zE,QAAS99D,IAASuB,UAAUtX,EAAM,aAClC8zE,2BAA4B/9D,IAASuB,UAAUtX,EAAM,aACrD+zE,8BAA+Bh+D,IAASuB,UAAUtX,EAAM,aACxDpB,iBAAkBmX,IAASuB,UAAUtX,EAAM,aAG3CnB,WAAYkX,IAASuB,UACnBvB,IAASgB,cAAc/W,EAAM,YAAaA,EAAM,mBAK/CgL,EAGM,SAAS0vD,EAAQ/2B,EAAQpM,GAAQ,IACtCy8C,EAAerwC,EAAfqwC,WACF96D,E,+UAAS,CAAH,GACPyqB,EADO,CAEVjI,IAAKiI,EAAOswC,SACZz9D,QAAST,IAASO,uBAAuBqtB,GACzC4B,iBAAkB/W,IAAauM,sBAC/ByK,aAAc,CAAClJ,iBAGXyK,EAAWitC,EACb,IAAIE,IAAiBh7D,GACrB,IAAIusB,IAAIC,eAAexsB,GAC3ByqB,EAAOwwC,8BAC+Bh1F,IAApCwkD,EAAOwwC,0BAEHxwC,EAAOwwC,yBACb,IAIM51E,EAAU,CACd61E,YA1GJ,SAA4B78C,EAAQ88C,GAClC,IAAMC,EAAuB,CAC3B,WACA,YAEAt+E,KAAK,KAEDu+E,EAAa,CACjB9nE,YAAa8qB,EAAO9qB,YACpBD,UAAW+qB,EAAO/qB,UAClBD,gBAAiBgrB,EAAOhrB,gBACxB3N,iBAAkB24B,EAAO34B,iBACzBqY,kBAAmBsgB,EAAOtgB,kBAC1BxmB,MAAO8mC,EAAO9mC,MACdooB,OAAQ0e,EAAO1e,OACf27D,cAAej9C,EAAOi9C,cACtBC,aAAcJ,EAAiCC,EAAuB,OAIxE,GAAI/8C,EAAO5uB,eAAiB4uB,EAAO7uB,YAAa,CAC9C,IAAMgsE,EAAWrB,EAAa,IAAI3rE,KAAK6vB,EAAO5uB,gBACxCgsE,EAAStB,EAAa,IAAI3rE,KAAK6vB,EAAO7uB,cAC5C6rE,EAAW51E,UAAX,UAA0B+1E,EAA1B,YAAsCC,GAIxC,GAAIp9C,EAAOn4B,iBAAkB,CAC3B,IAAIw1E,EAAYr9C,EAAOn4B,iBAEvBw1E,GADAA,EAAYvlF,MAAMC,QAAQslF,GAAaA,EAAU5+E,OAAS4+E,GACpC33E,QAAQ,YAAa,MAC3Cs3E,EAAWn1E,iBAAmBw1E,EAIhC,IAAMhC,EAAS,GAOf,OANAn4F,OAAO4c,KAAKk9E,GAAY58E,SAAQ,SAAAnX,QACNrB,IAApBo1F,EAAW/zF,IAA0C,KAApB+zF,EAAW/zF,KAC9CoyF,EAAOpyF,GAAO+zF,EAAW/zF,OAItBoyF,EA2DaiC,CAClBt9C,EACAoM,EAAOwwC,2BAMT,OAAOptC,EAAS+tC,iBAAiBv2E,GAASrgB,KAAKu1F,G,ICzI3CsB,EAAO,CACXzuB,iB,OAAAA,GAGI0uB,EAAO,CACXta,UACAua,UFkEa,SAAmBtxC,EAAQvkC,GAGxC,IAAM8Z,EAAS,CACbwiB,IAAKiI,EAAOswC,SACZz9D,QAAST,IAASO,uBAAuBqtB,GACzC4B,iBAAkB/W,IAAauM,uBAE3BgM,EAAW,IAAItB,IAAIC,eAAexsB,GAKlC3a,GAJcs2E,mBAClBt9C,OACAoM,EAAOwwC,0BAEO,CACdrqC,iBAAkB1qC,IAGpB,OAAO2nC,EAASmuC,mBAAmB32E,GAASrgB,MAAK,SAAA7C,GAC/C,MAAO,CACL+3F,YAAazvC,EAAOyvC,YACpBh0E,iBAAkBA,EAClBunB,OAAQssD,EAA0BtvC,EAAQvkC,EAAkB/jB,EAAOrB,Y,gBGhGzE,IAAMm7F,EAAsB,IAAIzxD,I,aCS1B1Y,EAAU,CACdoqE,SAAU,CACRJ,OACAD,QAEFM,YAAa,GACbpvB,0BACAO,+BACA8uB,wBCFa,SACb3xC,EACAmgC,EACA5d,GAEA,IADAC,EACA,wDAEM/pE,EAAW,GAGjB0nF,EAAkBnsE,SAAQ,SAASyH,GAEjC,IAAMhhB,EAAU6nE,YACdtiB,EACAvkC,EACA8mD,EACAC,GAIF/pE,EAAStB,KAAKsD,MAIhB,IAAMA,EAAU/B,QAAQiD,IAAIlD,GAK5B,OAFAgC,EAAQi3B,OAAM,SAAAz2B,GAAK,OAAIuC,IAAIC,KAAKxC,MAEzBR,GD1BPm3F,iBEPsB,EFQtBC,cDXa,SAAuB7xC,EAAQpM,GAC5C,IAAMk+C,EAAgB,CACpBxB,SAAUtwC,EAAOswC,SACjB18C,UAEIm+C,EAAapT,KAAKC,UAAUkT,GAClC,GAAIN,EAAoBpwD,IAAI2wD,GAC1B,OAAOP,EAAoBr1F,IAAI41F,GAE/B,IAAMt3F,EAAUs8E,EAAQ/2B,EAAQpM,GAIhC,OAFA49C,EAAoBnwD,IAAI0wD,EAAYt3F,GAE7BA,GCDTu3F,eAGa3qE,O,8BGGA,SAAS+zC,EAAiBj4B,EAAUoX,GACjD,IAAMmH,EA7BR,SAA2Bve,EAAUoX,GACnC,IAAI4gB,EAAYh4B,EAASg4B,UAEzB,GAAKA,EAeL,OAVc,OAAV5gB,EACF4gB,EAAYA,EAAU7hD,QAAQ,gBAAiB,KAG/CihC,EAAQA,EAAQhwB,SAASgwB,GAAS,EAAI,EAGtC4gB,EAAYA,EAAU7hD,QAAQ,gBAAlB,iBAA6CihC,KAGpD4gB,EAWK82B,CAAkB9uD,EAAUoX,GAExC,GAAKmH,EAIL,uBAAiBA,GAnCnB,mC,6BCAA,uDAGMwwC,EAAO71F,OAAO,QAQL,SAAS81F,EAAcnvD,GACpC,IAAItlC,EAAOslC,EAAOkvD,GAClB,IAAKx0F,EAAM,CACT,IAAM21B,EAAWjB,IAASuB,UAAUqP,EAAO,YAAa,IAAIjxB,cAC5DrU,EAAO5G,OAAO6kC,OAAO,CACnBtI,WACA++D,cAAe/5B,YAAsBhlC,GACrCwQ,kBAAmBzR,IAASuB,UAAUqP,EAAO,aAC7CkjB,aAAc9zB,IAASsB,UAAUsP,EAAO,YAAa,IAAM,IAE7DA,EAAOkvD,GAAQx0F,EAEjB,OAAOA,I,6BCvBT,mHAoBA,IAAM20F,EAAqB,CACzBrgE,QAAS,SAAC8E,EAAGC,GAAJ,OAAUD,EAAEovB,aAAenvB,EAAEmvB,cACtCosC,0BAdF,SAAmCz5B,EAAa05B,GAC9C,IAAMz7D,EAAIq7D,YAAct5B,GAClB9hC,EAAIo7D,YAAcI,GACxB,OAAKz7D,EAAEs7D,eAAiBr7D,EAAEq7D,eAChB,EAENt7D,EAAEs7D,gBAAkBr7D,EAAEq7D,cACjB,EAEFt7D,EAAEovB,aAAenvB,EAAEmvB,eAQtBssC,EAAwB,CAC5BxgE,QAAS,SAAC8E,EAAGC,GAAJ,OAAUD,EAAEs2B,eAAiBr2B,EAAEq2B,iBAGpCqlC,EAAkB,CACtBJ,qBACAG,yBAWIE,EAAkB,SACtB1vD,GAEG,IADH2vD,EACG,uDADqBN,EAAmBrgE,QAE3C,OAAOgR,EAAO1b,KAAKqrE,IAWfC,EAAqB,SACzBC,GAEG,IADHC,EACG,uDADwBN,EAAsBxgE,QAEjD,OAAO6gE,EAAcvrE,KAAKwrE,IAab,SAASd,EACtB31E,GAIA,IAHA02E,IAGA,yDAFAJ,EAEA,uDAFwBN,EAAmBrgE,QAC3C8gE,EACA,uDAD2BN,EAAsBxgE,QAEjD,IAAK3V,IAAUA,EAAM2mB,OACnB,MAAM,IAAI9oC,MAAM,qDAWlB,OARAw4F,EAAgBr2E,EAAM2mB,OAAQ2vD,GAE1BI,GACF12E,EAAM2mB,OAAOhvB,SAAQ,SAAAgvB,GACnB4vD,EAAmB5vD,EAAO2hB,UAAWmuC,MAIlCz2E,I,8BC5FT,oJAGiB22E,EAHjB,MAG6Br9D,EAAKgV,MAA1BkiC,QAGFomB,EAAwBphE,aAAe,kBAC3CP,aAAY,kBACV,kEAGE4hE,EAAgBrhE,aAAe,kBACnCP,aAAY,kBAAM,kEAGd6hE,EAAmBthE,aAAe,kBACtCP,aAAY,kBAAM,2DAId8hE,EAAoBvhE,aAAe,kBACvCP,aAAY,kBAAM,kEAId+hE,EAAsBxhE,aAAe,kBACzCP,aAAY,kBAAM,yEAKdvP,EAAS,kBAAM1kB,OAAOykB,SAASC,UAE/BuxE,EAAa,CACjBthE,QAAS,CACP+Y,OAAQ,CACNo4B,KAAM,6BACNvxC,UAAWshE,GAEbK,iBAAkB,CAChBpwB,KAAM,UACNvxC,UAAWwhE,GAEb5jE,KAAM,CACJ2zC,KAAM,CAAC,aAAc,KACrBvxC,UAAWuhE,EACXK,UAAW,SAAAl0C,GACT,OAAOA,EAAUm0C,gBAGrBC,MAAO,CACLvwB,KAAM,SACNvxC,UAAWyhE,GAEbJ,sBAAuB,CACrB9vB,KAAM,yBACNvxC,UAAWqhE,IAGfU,OAAQ,CACN5oD,OAAQ,CACNo4B,KACE,4GACFvxC,UAAWshE,EACXM,UAAW,SAAAl0C,GACT,QAASA,EAAUs0C,2BAGvBpkE,KAAM,CACJ2zC,KACE,mFACFvxC,UAAWuhE,EACXK,UAAW,SAAAl0C,GAGT,OAFiBA,EAAUm0C,iBAENn0C,EAAUs0C,6BAMjCC,EAAY,SAAAv0C,GAChB,IAAMw0C,EAAS,GACf,IAAK,IAAIC,KAAaT,EAAY,CAChC,IAAMU,EAAeV,EAAWS,GAEhC,IAAK,IAAIE,KAAYD,EAAc,CACjC,IAAME,EAAQF,EAAaC,IAEE,mBAApBC,EAAMV,WACTU,EAAMV,UAAUl0C,KAIpBw0C,EAAO38F,KAAK,CACVgsE,KAAM+wB,EAAM/wB,KACZr5D,UAAWoqF,EAAMtiE,aAMzB,OAAOkiE,GAGHK,EAAY,SAAChxB,EAAMnjB,EAAQivC,GAC/B,IAAImF,EAAQjxB,EACNkxB,EAAcv9F,OAAOqhC,OAAO,GAAI6nB,EAAQivC,GAE9C,IAAK,IAAIpyF,KAAOw3F,EACdD,EAAQpB,EAAQ1qB,YAAYS,aAAaqrB,EAAOv3F,EAAKw3F,EAAYx3F,IAGnE,OAAOu3F,GAGHE,EAAkB,WAAyC,IAAxCh1C,EAAwC,uDAA5B,GAAIU,EAAwB,uDAAf,GAAIivC,EAAW,uCAC3DsF,EAAajB,EAAWthE,QAAQ+Y,OAAOo4B,KAK3C,OAJI7jB,EAAUs0C,2BACZW,EAAajB,EAAWK,OAAO5oD,OAAOo4B,MAGjCgxB,EAAUI,EAAYv0C,EAAQivC,IAGjCuF,EAAqB,WAAyC,IAAxCl1C,EAAwC,uDAA5B,GAAIU,EAAwB,uDAAf,GAAIivC,EAAW,uCAC9DwF,EAAgBnB,EAAWthE,QAAQxC,KAAK2zC,KAK5C,OAJI7jB,EAAUs0C,2BACZa,EAAgBnB,EAAWK,OAAOnkE,KAAK2zC,MAAQsxB,GAG1CN,EAAUM,EAAez0C,EAAQivC,K,sFCvF3ByF,EAnCqB,SAAAvxD,GAClC,IAAMwxD,EAA8BxxD,EAAS,YAEvCyxD,EAA2B,GA6BjC,OA3BID,GAA+BA,EAA4BtiE,OAC7DsiE,EAA4BtiE,MAAMre,SAAQ,SAAA6gF,GACxC,IAAMp9B,EAA8BrlC,IAASuB,UAC3CkhE,EAAiB,aAGbC,EAAgCD,EAAiB,YACjDE,EAA6B,GAEnCD,EAA8BziE,MAAMre,SAAQ,SAAAghF,GAC1CD,EAA2B59F,KAAK,CAC9B89F,sBAAuB7iE,IAASuB,UAC9BqhE,EAAmB,aAErBE,yBAA0B9iE,IAASuB,UACjCqhE,EAAmB,kBAKzBJ,EAAyBz9F,KAAK,CAC5BsgE,8BACAs9B,kCAKCH,G,4TC9BT,SAASO,EAAYn1C,EAAQo1C,GAE3B,MAAO,CACLpyD,OAAQ,GACRwsD,UAAW14F,OAAO8F,OAAO,MACzBy4F,aAAc,KACd5F,YAAazvC,EAAOyvC,YACpB9tC,SAAU3B,EAAO2B,SACjB2uC,SAAUtwC,EAAOswC,SACjBxnE,YAAasJ,IAASoB,QAAQ4hE,EAAa,aAC3CvsE,UAAWuJ,IAASuB,UAAUyhE,EAAa,aAC3C9uC,WAAYl0B,IAASsB,UAAU0hE,EAAa,aAC5C5uC,YAAap0B,IAASsB,UAAU0hE,EAAa,aAC7C1uC,cAAet0B,IAASsB,UAAU0hE,EAAa,aAC/CxsE,gBAAiBwJ,IAASuB,UAAUyhE,EAAa,aACjDrnC,UAAW37B,IAASuB,UAAUyhE,EAAa,aAC3Cp6E,UAAWoX,IAASuB,UAAUyhE,EAAa,aAC3CptC,oBAAqB51B,IAASuB,UAAUyhE,EAAa,aACrDjgC,yBAA0Bu/B,EAA4BU,GACtDl6E,WAAYkX,IAASuB,UAAUyhE,EAAa,aAC5Cn6E,iBAAkBmX,IAASuB,UAAUyhE,EAAa,aAClDE,8BAA+BljE,IAASuB,UAAUyhE,EAAa,aAC/D35E,iBAAkB2W,IAASuB,UAAUyhE,EAAa,aAClDG,gBAAiBnjE,IAASuB,UAAUyhE,EAAa,cAWrD,SAASI,EACPx1C,EACAvkC,EACAooB,EACAE,GAGA,IAAMkrD,EAAS,GAEfA,EAAO93F,KAAK,oBACZ83F,EAAO93F,KAAP,mBAAwBskB,IACxBwzE,EAAO93F,KAAP,oBAAyB0sC,IACzBorD,EAAO93F,KAAP,oBAAyB4sC,IACzBkrD,EAAO93F,KAAK,iCACZ83F,EAAO93F,KAAK,oBAEZ,IAAMmxE,EAAc2mB,EAAO58E,KAAK,KAEhC,gBAAU2tC,EAAOyvC,YAAjB,YAAgCnnB,GAGlC,SAASmtB,EACPz1C,EACAvkC,EACAooB,EACAE,GAEA,gBAAUic,EAAO2B,SAAjB,oBAAqClmC,EAArC,mBAAgEooB,EAAhE,sBAA+FE,GAGjG,SAAS2xD,EACP11C,EACAvkC,EACAooB,EACAE,EACAwW,GAEA,IAAMo7C,EAAgBF,EACpBz1C,EACAvkC,EACAooB,EACAE,GAIF,OAFAwW,EAAiB,MAATA,GAAiB,EAEzB,UAAUo7C,EAAV,mBAAkCp7C,G,SAGrBq7C,E,uFAAf,WAA+B51C,EAAQ3jC,EAAO8mB,GAA9C,gIACoCtP,IAAiB89B,YAAYxuB,EAAU,CACvE6c,WAFJ,OA+DE,GA9DMg4B,EADR,OAMIv8D,EAGEu8D,EAHFv8D,iBACAooB,EAEEm0C,EAFFn0C,kBACAE,EACEi0C,EADFj0C,gBAGEf,EAAS3mB,EAAMmzE,UAAU3rD,UAeDroC,IAAtBwnC,EAAO0iB,aACT1iB,EAAO0iB,WAAasyB,EAAoBtyB,iBAChBlqD,IAAtBwnC,EAAO2iB,aACT3iB,EAAO2iB,WAAaqyB,EAAoBryB,cAf1C3iB,EAAS,CACPa,oBACAgyB,kBAAmBmiB,EAAoBniB,kBACvCxiC,SAAU2kD,EAAoB3kD,SAC9B6yB,aAAc8xB,EAAoB9xB,aAClCR,WAAYsyB,EAAoBtyB,WAChCC,WAAYqyB,EAAoBryB,WAChChB,UAAW,IAEbtoC,EAAMmzE,UAAU3rD,GAAqBb,EACrC3mB,EAAM2mB,OAAO7rC,KAAK6rC,IAQdq4B,EAAUm6B,EACdx1C,EACAvkC,EACAooB,EACAE,GAEI4xD,EAAgBF,EACpBz1C,EACAvkC,EACAooB,EACAE,GAEIo3B,EAAYu6B,EAChB11C,EACAvkC,EACAooB,EACAE,GAGI8xD,EAAc,CAClB77D,SAAUg+C,EACV2d,gBACAt6B,UACAF,YACAxZ,SAAU3B,EAAO2B,SACjBm0C,eAAgB91C,EAAO81C,eACvBC,mBAAoB/1C,EAAO+1C,oBAG7B/yD,EAAO2hB,UAAUxtD,KAAK0+F,GAGe,WAAnCA,EAAYE,oBACmB,WAA/BF,EAAYC,eAWZ,GAJME,EAAiBl/F,OAAOqhC,OAAOgL,GAE7B6uB,EAAmB6jC,EAAY77D,SAA/Bg4B,eAGN,IAASr7D,EAAI,EAAGA,EAAIq7D,EAAgBr7D,IAC5Bs/F,EAAgB76B,YAAiBy6B,EAAal/F,GAEpDyuE,IAA2B8wB,OAAOC,gBAAgBx1C,IAChDs1C,EACAD,QAIEC,EAAgB76B,YAAiBy6B,GAEvCzwB,IAA2B8wB,OAAOC,gBAAgBx1C,IAChDs1C,EACAD,GA1FR,yBA+FSH,GA/FT,6C,+BAwGeO,E,uFAAf,WAAmCp2C,EAAQ3jC,EAAOg6E,GAAlD,yGACS39F,QAAQiD,IACb06F,EAAgBvvF,KAAI,SAAS+uF,GAC3B,OAAOD,EAAgB51C,EAAQ3jC,EAAOw5E,QAH5C,4C,sBAQA,IAAMS,EAA8B,4CAAG,WAAOt2C,EAAQq2C,GAAf,6FACjC3qF,MAAMC,QAAQ0qF,IAAoBA,EAAgBx/F,OAAS,GAD1B,uBAE7B0/F,EAAmBF,EAAgB,GACnCh6E,EAAQ84E,EAAYn1C,EAAQu2C,GAHC,SAI7BH,EAAoBp2C,EAAQ3jC,EAAOg6E,GAJN,gCAK5Bh6E,GAL4B,aAO/B,IAAIniB,MAAM,4DAPqB,2CAAH,wD,seCtMfs8F,E,WAQnB,WAAYx2C,EAAQmG,GAAgC,IAAdoc,EAAc,uDAAJ,I,4FAAI,SAClDp8D,KAAK65C,OAASA,EACd75C,KAAKggD,iBAAmBA,EACxBhgD,KAAKo8D,QAAUA,E,gNAITp8D,KAAKswF,a,uBACetwF,KAAKuwF,U,cAAzBC,E,gBACiBxwF,KAAK4hE,KAAK4uB,G,cAA3BC,E,iBACqBzwF,KAAK0wF,QAAQD,G,eAAlCE,E,yBAECA,G,+JAOQC,G,gIAEMA,E,yEAAV5wB,E,2BAEQA,I,aAAfzuE,E,UACcA,EAAOb,O,mYAQrBkgG,EAAQxuE,OAAOyuE,MAASt/F,E,uBACpB,IAAIwC,MAAM,iC,iCAGXxC,G,ioBAMEi/F,G,gOACGC,G,4zCC3CKK,E,gdACN,IAGLr8E,EAAU,CACdurC,iBAHoChgD,KAA9BggD,kBAMAH,EAN8B7/C,KAAZo8D,QAMlBvc,kBAKR,OAJIA,IACFprC,EAAO,kBAAwBorC,GAG1BprC,I,4JA2BP,OApBMm8E,EAAU,GAEd5wC,EAGEhgD,KAHFggD,iB,EAGEhgD,KAFFo8D,QAAWvc,G,aAAsB,G,GAAtBA,kBACXkxC,EACE/wF,KADF+wF,OAGElxC,GACF+wC,EAAQ5/F,KACN+/F,EAAOC,uBAAuBr6F,KAAKo6F,EAAQ,CACzC/wC,mBACAH,uBAKN+wC,EAAQ5/F,KACN+/F,EAAO50B,sBAAsBxlE,KAAKo6F,EAAQ,CAAE/wC,sBAG9C,gBAAO4wC,EAAP,Q,mFAGW,IACH/2C,EAAW75C,KAAX65C,OACFk3C,EAAS,IAAIp1C,IAAIC,eAAe,CACpChK,IAAKiI,EAAO2B,SACZ9uB,QAAST,IAASO,uBAAuBqtB,GACzC4B,iBAAkB/W,IAAauM,sBAC/ByK,aAAc,CAAClJ,iBAGjBxyC,KAAK+wF,OAASA,I,2DAGLP,G,+FACHI,EAAU5wF,KAAKixF,aACf1/F,EAASyO,KAAKkxF,WAAWN,G,kBACxBr/F,G,4JAGKk/F,G,6FACJ52C,EAAW75C,KAAX65C,O,kBACDs2C,EAA+Bt2C,EAAQ42C,I,+HA/DMJ,G,g+CCDhDtyC,EAAsBF,IAAM3tD,KAAK4tD,oBAAjCC,kBAWR,SAASozC,EAAmBt3C,EAAQ3jC,EAAOg5E,GACN,MAAnCh5E,EAAMg5E,aAAev+F,OAAO6kC,OAAO,CACjC47D,QADiC,WAE/B,OAAOlC,EAAakC,WAEhBhvE,MAJ2B,gJAKV8sE,EAAa9sE,OALH,cAKzBya,EALyB,gBAMzBozD,EAAoBp2C,EAAQ3jC,EAAO2mB,EAAOw0D,cANjB,gCAOxBn7E,EAAMmzE,UAAUxsD,EAAOgjB,oBAPC,yFAmBrC,SAASyxC,EACPnhC,EACAnQ,EACAuxC,GAEA,OAAO5gG,OAAO6kC,OAAO,CACnB47D,QADmB,WAEjB,OAAOG,EAAsB7gG,OAAS,GAElC0xB,MAJa,yIAKXy9B,EAAoB0xC,EAAsBpgG,QAL/B,SAMUg/D,EAAe6gC,uBAAuB,CAC/DhxC,mBACAH,sBARe,cAMXwxC,EANW,yBAUV,CAAErxC,mBAAkBH,oBAAmBwxC,iBAV7B,+F,IAqBFG,E,kdACN,IACH33C,EAAW75C,KAAX65C,OAEFk3C,EAAS,IAAI3G,I,+UAAJ,IACVvwC,EADU,CAEbjI,IAAKiI,EAAOswC,SACZz9D,QAAST,IAASO,uBAAuBqtB,GACzC4B,iBAAkB/W,IAAauM,sBAC/ByK,aAAc,CAAClJ,kBAGjBxyC,KAAK+wF,OAASA,I,iKAwBd,OAjBMU,EAAa,GAEjBzxC,EAGEhgD,KAHFggD,iB,EAGEhgD,KAFFo8D,QAAWvc,G,aAAsB,G,GAAtBA,kBACXkxC,EACE/wF,KADF+wF,OAGElxC,IACIprC,EAAU,CACdurC,mBACAsqC,YAAa,CAAE5sD,kBAAmBmiB,IAEpC4xC,EAAWzgG,KAAK+/F,EAAOW,gBAAgB/6F,KAAKo6F,EAAQt8E,KAGtDg9E,EAAWzgG,KAAK+/F,EAAOW,gBAAgB/6F,KAAKo6F,EAAQ,CAAE/wC,sBAEtD,gBAAOyxC,EAAP,Q,mNAIMA,EAAazxF,KAAK2xF,gB,SAIC3xF,KAAKkxF,WAAWO,G,cAAnC97E,E,OAEAi8E,EAAerF,YACnB52E,EACA22E,IAAgBJ,mBAAmBC,2BAE/B0F,EAAuCD,EAnGjCjxF,KAAI,SAAAk8B,GAAM,OAAImvD,YAAcnvD,GAAQa,qB,kBAqGzC,CACLm0D,wBACAl8E,e,wJAIO66E,G,mGACDO,EAA6B/wF,KAA7B+wF,OAAQ/wC,EAAqBhgD,KAArBggD,iBAEV8xC,EAAoBR,EACxBP,EACA/wC,EACAwwC,EAAYqB,uB,SAGYC,EAAkB1vE,O,cAAtCswC,E,yBAEC,CACL2+B,aAAc3+B,EAAY2+B,aAC1BU,YAAaD,EACbn8E,WAAY66E,EAAY76E,a,4JAId86E,G,qGACJ52C,EAAW75C,KAAX65C,OAEAw3C,EAA0CZ,EAA1CY,aAAcU,EAA4BtB,EAA5BsB,YAAap8E,EAAe86E,EAAf96E,W,SAEfw6E,EAA+Bt2C,EAAQw3C,G,cAArDn7E,E,OAGwBP,EAAWhV,IAAIo9C,GAEvBlwC,SAAQ,SAACgvB,EAAQsX,GACrC,IAAM69C,EAAqB,CACzBt0D,kBAAmBb,EAAOa,kBAC1BgyB,kBAAmB7yB,EAAO6yB,kBAC1B3P,aAAcljB,EAAOkjB,aACrB7yB,SAAU2P,EAAO3P,SACjBsxB,UAAW,IAGTtoC,EAAM2mB,OAAOsX,GACfj+B,EAAM2mB,OAAOsX,GAAOxjD,OAAOqhC,OACzBggE,EACA97E,EAAM2mB,OAAOsX,IAGfj+B,EAAM2mB,OAAOsX,GAAO69C,EAGtB97E,EAAMmzE,UAAUxsD,EAAOa,mBAAqBxnB,EAAM2mB,OAAOsX,MAGvD49C,EAAYX,WACdD,EAAmBt3C,EAAQ3jC,EAAO67E,G,kBAG7B77E,G,+HA/G8Cm6E,G,8KC1DzD,WAAgCx2C,EAAQvkC,GAAxC,+GAA0D8mD,EAA1D,+BAAoE,GAC5Di0B,EAC0B,GAA9Bx2C,EAAOo4C,oBACHT,EACAV,EAEAoB,EAAyB,IAAI7B,EACjCx2C,EACAvkC,EACA8mD,GAEI3/B,EAAgBy1D,EAAuBC,WAX/C,kBAaS11D,GAbT,2C,uMAgBe+/B,I,2MC1BR,SAAS41B,EAAuBrzF,GACrC,OACE,yBACEW,UAAU,mBACVU,MAAO,CACLkH,SAAU,WACVC,IAAK,EACLC,KAAM,EACNuiE,MAAO,EACPsoB,OAAQ,EACRp1E,OAAQ,OACRsG,UAAW,SACX+uE,cAAe,SAGjB,oCACA,uBAAG5yF,UAAU,eAAb,0BACA,uBAAGA,UAAU,WAAWX,EAAMo1B,UAKpCi+D,EAAuB7vF,UAAY,CACjC4xB,QAASjzB,IAAUuB,QAGN2vF,QC1BR,SAASG,EAAyBxzF,GACvC,OACE,yBACEW,UAAU,oBACVU,MAAO,CACLkH,SAAU,WACVC,IAAK,EACLC,KAAM,EACNuiE,MAAO,EACPsoB,OAAQ,EACRp1E,OAAQ,OACRsG,UAAW,SACX+uE,cAAe,SAVnB,WAaWvzF,EAAMutE,iBAKrBimB,EAAyBhwF,UAAY,CACnC+pE,gBAAiBprE,IAAUC,QAGdoxF,Q,sfCXf,SAASC,EAAezzF,GAAO,IAiBzB0zF,EACAC,EAhBF9wF,EAQE7C,EARF6C,OACAhB,EAOE7B,EAPF6B,MACAC,EAME9B,EANF8B,OACA8xF,EAKE5zF,EALF4zF,SACAv0D,EAIEr/B,EAJFq/B,QACAw0D,EAGE7zF,EAHF6zF,qBACOC,EAEL9zF,EAFFjK,MACAg+F,EACE/zF,EADF+zF,gBAT2B,IAYGxmF,oBAAS,GAZZ,GAYtB2U,EAZsB,KAYX8xE,EAZW,SAaHzmF,oBAAS,GAbN,GAatBxX,EAbsB,eAcHwX,mBAAS,IAdN,IActBgjB,EAdsB,KAcf0jE,EAde,KAevBC,EAAY5gF,sBAKdwgF,GAAc/9F,EAChB29F,EAAiB,kBAAC,EAAD,MACRxxE,IACTwxE,EAAiB,kBAAC,EAAD,OAGnB,IAAMS,EACJJ,QAA4Cz9F,IAAzBu9F,EAEfO,EAAuB,WAC3B,OAAO/0D,IAAYu0D,GAGfS,EAAoB,WACnBV,IAILK,GAAW,GACXL,EACGt+F,MAAK,SAAAqqE,GACJu0B,EAASv0B,MAEVlzC,OAAM,SAAAz2B,GACDA,EAAM8xE,gBAOVysB,EAAkB,WAClBF,MACFT,EAAoBluD,IAAMmiC,eACxBl5C,YAAYkxC,kBAAkBvgC,MAK9Bk1D,EAAyBz/E,uBAAY,WACrC6+E,GACFA,EAAkB7rB,YA+BtB,OA3BAxyD,qBAAU,WACR,OAAO,WACLi/E,OAED,CAACA,IAEJj/E,qBAAU,WACJib,EAAM8O,UACR3Q,YAAY8lE,eAAeN,EAAUh/E,QAASqb,GAC9CyjE,GAAW,MAEZ,CAACE,EAAW3jE,EAAOA,EAAM8O,UAE5B/pB,qBAAU,WACHib,EAAM8O,SAAW9O,EAAM8O,UAAYA,IACtCk1D,IACAD,IACAD,OAED,CACDA,EACA9jE,EAAM8O,QACNA,EACAk1D,EACAD,IAIA,yBAAK3zF,UAAWuO,IAAW,iBAAkB,CAAErM,OAAQA,KACrD,yBAAKlC,UAAU,0BACZyzF,IACC,4BAAQvqF,IAAKqqF,EAAWryF,MAAOA,EAAOC,OAAQA,IAE9C,yBACEnB,UAAU,eACV7L,IAAK8+F,EAEL9xF,OAAQA,EACR0T,IAAK,MAIVk+E,EACAS,GACC,yBAAKxzF,UAAU,gCACb,yBACEA,UAAU,qCACVU,MAAO,CAAEQ,MAAO,GAAF,OAAKgyF,EAAL,SAInB3xE,GAAa,yBAAKvhB,UAAU,uCAKnC8yF,EAAejwF,UAAY,CACzBX,OAAQV,IAAUG,KAClBsxF,SAAUzxF,IAAUuB,OACpB27B,QAASl9B,IAAUuB,OACnB3N,MAAOoM,IAAUG,KACjBT,MAAOM,IAAUC,OACjBN,OAAQK,IAAUC,OAClByxF,qBAAsB1xF,IAAUC,OAAOC,WACvC0xF,gBAAiB5xF,IAAUG,MAG7BmxF,EAAe5vF,aAAe,CAC5BhB,QAAQ,EACR9M,OAAO,EACP89F,qBAAsB,EACtBhyF,MAAO,IACPC,OAAQ,IACRiyF,iBAAiB,GAGJN,Q,ujBCjJf,IAAMljB,EAAuBl0D,IAAQk0D,qBAErC,SAASkkB,EAAT,GAMG,IALD9jC,EAKC,EALDA,kBACA3P,EAIC,EAJDA,aACAgR,EAGC,EAHDA,eACA5sD,EAEC,EAFDA,YACAsvF,EACC,EADDA,sBACC,IACyDnnF,mBAAS,IADlE,GACMonF,EADN,KAC6BC,EAD7B,SAE+DrnF,mBAAS,IAFxE,GAEMsnF,EAFN,KAEgCC,EAFhC,KAIDx/E,qBAAU,WACR,IAAIy/E,GAAY,EAWhB,OAVA3vF,EAAY/P,MAAK,SAAAqqE,GACVq1B,GACHH,EAAyBl1B,MAG7Bg1B,EAAsBr/F,MAAK,SAAAqqE,GACpBq1B,GACHD,EAA4Bp1B,MAGzB,WACLq1B,GAAY,KAEb,CAAC3vF,EAAasvF,IAEjB,IAAMM,GAAYrkC,EAEZskC,EAAU,SAAC59F,EAAOqL,GAAyB,IAAnB/B,EAAmB,uDAAP,GACxC,OACE,yBAAKA,UAAWuO,IAAW,mBAAoBvO,IAC7C,yBAAKA,UAAU,QAAQ+B,GACvB,yBAAK/B,UAAU,SAAStJ,KAKxB0P,EAAoB,SAAA4tF,GACxB,GAAInuF,MAAMC,QAAQkuF,GAAwB,CACxC,IAAMjuF,EAAiBiuF,EAAsB/yF,KAAI,SAACrJ,EAAM8N,GACtD,OAAO,wBAAI1O,IAAK0O,GAAQ9N,MAG1B,OAAO,4BAAKmO,GAEZ,OAAO,kBAAC,IAAMC,SAAP,KAAiBguF,IAoF5B,OACE,yBAAKh0F,UAAWuO,IAAW,iBAAkB,CAAE,YAAa8lF,KAC1D,yBAAKr0F,UAAU,sBAAsBgwD,GAnCZ,SAC3B3P,EACAgR,EACA2iC,EACAE,GAEA,GAAK7zC,GAAiBgR,EAwBtB,OApBE,yBAAKrxD,UAAU,sBACb,kBAAC,IAAMgG,SAAP,UACoBrQ,IAAjB0qD,EACCi0C,EAAQj0C,EAAc,MAEtB,kBAAC,IAAMr6C,SAAP,OAGJ,kBAAC,IAAMA,SAAP,UACsBrQ,IAAnB07D,EACCijC,EAAQjjC,EAAgB,GAAI,gBAE5B,kBAAC,IAAMrrD,SAAP,OApCa,SAAAkuF,GACrB,OACE,kBAAC,IAAMluF,SAAP,KACGkuF,EACC,yBAAKl0F,UAAU,WACb,kBAACyC,EAAA,EAAD,CAAM/M,KAAK,UAGb,kBAAC,IAAMsQ,SAAP,OA+BDuuF,CAAeL,GAxEC,SAAC7zC,EAAc2zC,GACpC,OACE,kBAAC,IAAMhuF,SAAP,KACGguF,GAAyD,GAAhCA,EAAsBhjG,OAC9C,kBAAC,IAAD,CACEgG,IAAKqpD,EACLn6C,UAAU,OACVC,QACE,kBAAC,IAAD,CACED,UAAU,OACVlG,UAAU,qBACV8C,GAAG,gBAEH,yBAAK9C,UAAU,gBAAf,0BACA,yBAAKA,UAAU,kBACZoG,EAAkB4tF,MAKzB,yBAAKh0F,UAAWuO,IAAW,YACzB,0BAAMvO,UAAU,gBACd,kBAACyC,EAAA,EAAD,CAAM/M,KAAK,4BAKjB,kBAAC,IAAMsQ,SAAP,OA8CDwuF,CAAen0C,EAAc2zC,IAU/BS,CACCp0C,EACAgR,EACA2iC,EACAE,IAMR,SAASh+E,EAAU7W,GAAO,IAEtB6C,EAYE7C,EAZF6C,OACAwyF,EAWEr1F,EAXFq1F,aACAt/F,EAUEiK,EAVFjK,MACA+gB,EASE9W,EATF8W,sBACAuoB,EAQEr/B,EARFq/B,QACAu0D,EAOE5zF,EAPF4zF,SACAr9E,EAMEvW,EANFuW,iBACApV,EAKEnB,EALFmB,QACAm0F,EAIEt1F,EAJFs1F,cACAC,EAGEv1F,EAHFu1F,YACAC,EAEEx1F,EAFFw1F,aACAzB,EACE/zF,EADF+zF,gBAbsB,IAgBgCxmF,mBAAS,GAhBzC,GAgBjBsmF,EAhBiB,KAgBK4B,EAhBL,KAiBxBngF,qBAAU,WACR,IAAMogF,EAAmBC,KAAS,YAAgB,IAAbl9E,EAAa,EAAbA,OAC3ByzD,EAA6BzzD,EAA7ByzD,WAAYyB,EAAiBl1D,EAAjBk1D,aACpB,GAAI,wBAAiB72D,KAA4Bo1D,EAAY,CAC3D,IAAM0pB,EAAUjoB,EAAeA,EAAaJ,gBAAkB,EAC1DqoB,EAAU/B,GACZ4B,EAAwBG,MAG3B,KAOH,OALA7hG,SAASqW,iBACPmmE,EAAqB1H,OAAOoF,WAC5BynB,GAGK,WACL3hG,SAASsW,oBACPkmE,EAAqB1H,OAAOoF,WAC5BynB,MAGH,CAAC5+E,IAvCoB,QAyCoB++E,YAAQ,CAGlD/oF,KAAM,CACJyJ,mBACAO,wBACAtiB,KAAM,aAERshG,QAAS,SAASC,GAChB,OAAOP,KAlDa,GAyCDQ,GAzCC,WAsDlBC,GAtDkB,KAsDPrC,GAAYv0D,GACvB62D,OAA8B5/F,IAAjB++F,EAEnB,OACE,yBACExrF,IAAKmsF,EACLr1F,UAAWuO,IAAW,YAAa,CAAErM,OAAQA,IAC7C1B,QAASA,EACTm0F,cAAeA,EACfC,YAAaA,GAGZU,GACC,kBAAC,EAAD,CACEpzF,OAAQA,EACR+wF,SAAUA,EACVv0D,QAASA,EACTtpC,MAAOA,EACP89F,qBAAsBA,EACtBE,gBAAiBA,KAInBkC,GAAYC,GACZ,yBAAKv1F,UAAW,wBACd,4BAAK00F,IAGRZ,EAAgBz0F,IAKvB,IAAMmoE,EAAO,aAEbtxD,EAAUrT,UAAY,CACpBgyF,aAAcrzF,IAAUG,KACxBmB,GAAItB,IAAUuB,OAAOrB,WACrByU,sBAAuB3U,IAAUuB,OAAOrB,WACxCkU,iBAAkBpU,IAAUuB,OAAOrB,WACnCuxF,SAAUzxF,IAAUuB,OACpB27B,QAASl9B,IAAUuB,OACnB3N,MAAOoM,IAAUG,KACjBO,OAAQV,IAAUG,KAClBuxF,qBAAsB1xF,IAAUC,OAMhCizF,aAAclzF,IAAUuB,OACxBitD,kBAAmBxuD,IAAUuB,OAC7Bs9C,aAAc7+C,IAAUwB,UAAU,CAACxB,IAAUuB,OAAQvB,IAAUC,SAC/DgD,YAAajD,IAAUyc,WAAWprB,SAClCkhG,sBAAuBvyF,IAAUyc,WAAWprB,SAC5Cw+D,eAAgB7vD,IAAUC,OAC1BkzF,cAAenzF,IAAUI,KACzBpB,QAASgB,IAAUI,KACnBgzF,YAAapzF,IAAUI,KACvBwxF,gBAAiB5xF,IAAUG,MAG7BuU,EAAUhT,aAAe,CACvB2xF,cAAc,EACd3yF,QAAQ,EACR9M,OAAO,EACP89F,qBAAsB,EACtByB,cAAentB,EACfhnE,QAASgnE,EACTotB,YAAaptB,I,ixCC/QMkjB,E,YAYnB,WAAY8K,GAAY,a,4FAAA,UACtB,wBAAMA,KACDhL,WAAagL,EAAWhL,WAFP,E,0UAWDz1E,G,oGAChBzU,KAAKkqF,W,6FAA0Cz1E,I,2EAEJA,G,UAA5C0gF,E,OACI7K,EAAgB71E,EAAhB61E,Y,yCACiB6K,G,cACnBC,EAAWD,EAAa1nD,QAAO,SAAAv3B,GACnC,cAAkBvlB,OAAO4c,KAAK68E,EAAiBvK,YAA/C,eAA4D,CAAvD,IAAMnpF,EAAG,KACZ,IAAK,EAAK2+F,WAAW3+F,EAAK4zF,EAAap0E,GAAQ,OAAO,EAExD,OAAO,K,kBAEFk/E,G,kTAeKE,EAASC,GAAQ,WAC7B,GAAIhwF,MAAMC,QAAQ8vF,GAChB,OAAOA,EAAQr/E,MAAK,SAAApK,GAAI,OAAI,EAAK2pF,cAAc3pF,EAAM0pF,MAEvD,GAAIhwF,MAAMC,QAAQ+vF,GAChB,OAAOA,EAAOt/E,MAAK,SAAAw/E,GAAU,OAAI,EAAKD,cAAcF,EAASG,MAK/D,GAHIF,GAAUA,EAAOjoE,aACnBioE,EAASA,EAAOjoE,YAEK,iBAAXioE,EAAqB,CAC/B,GAAsB,IAAlBA,EAAO7kG,OAAc,OAAO,EAChC,GAAuB,IAAnB4kG,EAAQ5kG,QAA4B,MAAZ4kG,EAAiB,OAAO,EACpD,GAAmB,MAAfA,EAAQ,IAA8C,MAAhCA,EAAQA,EAAQ5kG,OAAS,GAEjD,OADAsG,QAAQK,IAAR,oBAAyBk+F,EAAzB,eAAsCD,EAAQtkD,UAAU,EAAGskD,EAAQ5kG,OAAS,MACR,GAA7D6kG,EAAO17E,QAAQy7E,EAAQtkD,UAAU,EAAGskD,EAAQ5kG,OAAS,IACvD,GAAoC,MAAhC4kG,EAAQA,EAAQ5kG,OAAS,GAClC,OAAoE,GAA7D6kG,EAAO17E,QAAQy7E,EAAQtkD,UAAU,EAAGskD,EAAQ5kG,OAAS,IACvD,GAAmB,MAAf4kG,EAAQ,GACjB,OAAOC,EAAO17E,QAAQy7E,EAAQtkD,UAAU,MAAQukD,EAAO7kG,OAAS4kG,EAAQ5kG,OAAS,EAGrF,OAAO4kG,IAAYC,I,uCAIJG,EAAOt/F,GACtB,IAAKA,EAAO,OAAO,EACnB,IAAMu/F,EAAOD,EAAM77E,QAAQ,KAC3B,IAAc,IAAV87E,EAAa,OAAO31F,KAAKw1F,cAAcE,EAAOt/F,GAClD,IAAMomB,EAAQk5E,EAAM1kD,UAAU,EAAG2kD,GAC3Bl5E,EAAMi5E,EAAM1kD,UAAU2kD,EAAO,GACnC,QAASn5E,GAASpmB,GAASomB,MACvBC,GAAOrmB,GAASqmB,K,iCAWX/lB,EAAK4zF,EAAap0E,GAC3B,IAAM4tB,EAASsmD,EAAiBvK,WAAWnpF,IAAQA,EACnD,IAAK4zF,EAAa,OAAO,EACzB,IAAMsL,EAAYtL,EAAY5zF,IAAQ4zF,EAAYxmD,GAClD,IAAK8xD,EAAW,OAAO,EACvB,IAAMC,EAAY3/E,EAAMxf,IAAQwf,EAAM4tB,GACtC,IAAK+xD,EAAW,OAAO,EACvB,GAAoB,MAAhBA,EAAUzoE,GAAY,OAAOptB,KAAK81F,iBAAiBF,EAAWC,EAAU3pE,MAAM,IAClF,IAAM91B,EAAQy/F,EAAU3pE,MACxB,OAAOlsB,KAAKw1F,cAAcI,EAAWx/F,KAAU,O,oCAvGLulD,EAAIC,gB,EAC5B,CAClB,iBAAoB,WACpB,YAAe,WACf,WAAY,MACZ,UAAa,WACb,iBAAoB,WACpB,UAAa,WACb,kBAAqB,WACrBn5B,gBAAiB,a,oBATA2nE,G,qHCTrB,+CAUalxC,EAAoB68C,yBAC/B,CAT6B,SAAAn2F,GAAK,OAAIA,EAAM83B,UAAUs+D,qBAC7B,SAAAp2F,GAAK,OAAIA,EAAM83B,UAAUu+D,OAAOv+D,WAC3B,SAAA93B,GAAK,OAAIA,EAAM83B,UAAUoI,wBAQvD,SAACk2D,EAAqBE,EAAiBp2D,GACrC,IAAMkZ,EAAiB,CAAC,UAClBm9C,EAAuBD,EAAgBF,IAAwB,GAC/DI,EACJt2D,EAAqBk2D,IAAwB,GACzCK,EACJF,EAAqBjmC,QAAUkmC,EAA2BlmC,OAE5D,GAAImmC,EAA0B,CAC5B,IAAMC,EAA0B,oBAAH,OAAuBD,EAAyBzqF,eAC7EotC,EAAehoD,KAAKslG,GAGtB,OAAOt9C,M,qECzBX,oBAGMu9C,EAAuB,CAC3BC,sBAAuB,SAAAzwE,GAAK,OAAI0wE,gBAG5BC,EAPN,OAO6B3wE,EAAMwkB,cAAcgsD,GAElCG,O,mbCWR,IAAMtyD,EAAb,WACE,aAAqD,6DAAJ,GAAnCuyD,EAAuC,EAAvCA,YAAaz9C,EAA0B,EAA1BA,mB,4FAA0B,SACnDl5C,KAAK42F,SAAW,GAEXD,GAAgBz9C,GACnB7hD,IAAIC,KACF,iFAIJ0I,KAAK62F,aAAeF,EACpB32F,KAAK82F,mBAAqB59C,E,UAX9B,O,EAAA,G,EAAA,qCAwBgB69C,GACZ,GAAKA,EAIL,OAAI/2F,KAAK42F,SAASG,GACT/2F,KAAKg3F,aAAaD,QAG3B/2F,KAAK42F,SAASG,GAAe,MAjCjC,iCA2CaA,GACT,IAAM1wF,EAAUrG,KAAK42F,SAASG,GAE9B,GAAK1wF,EAIL,OAAOA,IAlDX,mCA2De0wF,GACNA,IAIL/2F,KAAK42F,SAASG,GAAe,MAhEjC,sCA4EkBA,EAAaE,EAAaC,GACxC,GAA0B,WAAtB,EAAOA,GAAX,CAIA,IAAM7wF,EAAUrG,KAAKm3F,WAAWJ,GAC3B1wF,IAILA,EAAQ4wF,GAAeC,MAtF3B,iCAiGaD,EAAaF,GAAa,IAsB/BK,EAtB+B,OAC/BR,EAAW,GAEf,GAAIG,EAAa,CACf,IAAM1wF,EAAUrG,KAAKm3F,WAAWJ,GAC5B1wF,GACFuwF,EAAS5lG,KAAKqV,QAGOrG,KAAK82F,qBACbjpF,SAAQ,SAAAwpF,GACrB,IAAMhxF,EAAU,EAAK8wF,WAAWE,GAC5BhxF,GACFuwF,EAAS5lG,KAAKqV,MAKpB,GAAwB,IAApBuwF,EAASlmG,OAWb,OANAkmG,EAAS/oF,SAAQ,SAAAxH,GACXA,EAAQ4wF,KACVG,EAAe/wF,EAAQ4wF,OAIpBG,IA9HX,iCAwIaH,GAAwC,IAA3BxiF,EAA2B,uDAAjB,GAAIsiF,EAAa,uCAC3CG,EAAal3F,KAAKs3F,WAAWL,EAAaF,GAChD,GAAKG,EAAL,CAFiD,IAOzCK,EAAkCL,EAAlCK,UAPyC,EAOPL,EAAvBM,qBAP8B,MAOd,GAPc,EAQ3CC,EAAoBP,EAAWziF,QAEjCijF,EAAgB,GACdC,EAAW33F,KAAK62F,eAYtB,OAXAW,EAAc3pF,SAAQ,SAAAxH,GACpBqxF,EAAcrxF,GAAWsxF,EAAStxF,MAGpCqxF,EAAgB/mG,OAAOqhC,OACrB,GACA0lE,EACAD,EACAhjF,GAGuB,mBAAd8iF,OACTlgG,IAAIC,KAAJ,gDAAkD2/F,EAAlD,MAGOM,EAAUG,GAxBjBrgG,IAAIC,KAAJ,mBAAqB2/F,EAArB,wC,2BA3IN,KAwKe7yD,O,ktCChLR,IAAME,EAAb,WACE,WAAYszD,EAAiBC,I,4FAAiB,SAC5C73F,KAAK83F,kBAAoB,GACzB93F,KAAK+3F,eAAiB,GACtB/3F,KAAKg4F,WAAY,EAEZJ,GACHvgG,IAAIC,KACF,2GAIJ0I,KAAKi4F,iBAAmBJ,EACxB73F,KAAKk4F,iBAAmBN,E,UAb5B,O,EAAA,G,EAAA,8BAqBSlkG,GACL,OAAO0a,IAAQC,OAAO3a,KAtB1B,gCA8BIsM,KAAKg4F,WAAY,EACjB5pF,IAAQI,UA/BZ,+BAsCIxO,KAAKg4F,WAAY,EACjB5pF,IAAQE,YAvCZ,mCA+CqC,WAAxBwpF,EAAwB,uDAAJ,GAC7B,IACE,IAAMhT,EAAc9kF,KAAKm4F,qBAAqBL,GAE9ChT,EAAYj3E,SAAQ,SAAAqpF,GAAU,OAAI,EAAKkB,gBAAgBlB,MACvD,MAAOpiG,GAAO,MAIVkL,KAAKi4F,iBAAiB3M,SAFxBzmD,EAFY,EAEZA,sBACAI,EAHY,EAGZA,cAEI9vC,EAAU,6BAChB8vC,EAAcnwC,MAAM,CAAEA,QAAOK,YAC7B0vC,EAAsBqG,KAAK,CACzBlhC,MAAO,kBACP7U,UACA5B,KAAM,aA9Dd,0CAyE4C,IAAxBukG,EAAwB,uDAAJ,GAC9BhT,EAAc9kF,KAAKm4F,qBAAqBL,GAE9C93F,KAAK+3F,eAAiBjT,IA5E1B,2CAqFuBgT,GAKnB,OAJoBvyF,MAAMC,QAAQsyF,GAAd,EACZA,GACJ93F,KAAKq4F,kBAAkBP,KAxF/B,0CAoG+C,WAA3BQ,EAA2B,uDAAJ,GACjCC,EAAO,EAAH,GAAQD,GAClB,OAAO3nG,OAAO+pD,QAAQ69C,GAAM53F,KAAI,SAAA63F,GAAU,OACxC,EAAKC,kBAAkBD,EAAW,GAAIA,EAAW,SAvGvD,wCA4HoBtlD,EAAcC,GAC9B,UACE8jD,YAAa/jD,GACVC,KA/HT,wCA4IgE,6DAAf,GAA7B8jD,EAA4C,EAA5CA,YAAa1pF,EAA+B,EAA/BA,KAAMzL,EAAyB,EAAzBA,MACnC,GAD4D,iCACvDm1F,EAAL,CAKA,IAAMyB,EAAiC14F,KAAK83F,kBAAkBb,GAE9D,GAAIyB,EAAgC,CAClC,IAAMC,EAA2BD,EAA+BnrF,KAChEvN,KAAK44F,eAAe3B,EAAa0B,GACjCthG,IAAIE,KAAJ,oBAAsB0/F,EAAtB,iBAA0C0B,IAI5C34F,KAAK83F,kBAAkBb,GAAe,CAAE1pF,OAAMzL,SAC9C9B,KAAK64F,aAAa5B,EAAa1pF,GAC/BlW,IAAIE,KAAJ,kBAAoB0/F,EAApB,eAAsC1pF,SAfpClW,IAAIC,KAAJ,6CAA+CiW,EAA/C,QA9IN,+CAsKIvN,KAAK84F,WAAW94F,KAAK+3F,kBAtKzB,gCA6KI/3F,KAAK+3F,eAAiB,GACtB/3F,KAAK83F,kBAAoB,GACzB1pF,IAAQ2rB,UA/KZ,mCA0Lek9D,EAAa1pF,GAAM,WAE9B,GAD8B,KAATA,QAAwBlY,IAATkY,EACpC,CAIA,IACMwrF,EADaxrF,aAAgBhI,MACDgI,EAAKrB,KAAK,KAAOqB,EAEnDa,IAAQzX,KAAKoiG,GAAc,SAAAzkF,GACzBA,EAAInR,iBACJmR,EAAIlR,kBACJ,EAAK80F,iBAAiBc,WAAW/B,EAAa,CAAE3iF,cAtMtD,qCAkNiB2iF,EAAa1pF,GAE1B,GAD8B,KAATA,QAAwBlY,IAATkY,EAMpC,GADmBA,aAAgBhI,MACnC,CACE,IAAMwzF,EAAexrF,EAAKrB,KAAK,KAC/BlM,KAAK44F,eAAe3B,EAAa8B,QAInC3qF,IAAQ6qF,OAAO1rF,Q,2BA/NnB,KAmOe+2B,O,qGC/OF40D,EAA6B,CACxCC,yBAA0B,SAC1BC,aAAc,SACdC,oBAAqB,SACrBC,iBAAkB,SAClBC,kBAAmB,SACnBC,yBAA0B,SAC1BC,mBAAoB,SACpBC,QAAS,SACTC,YAAa,SACbC,oBAAqB,sBACrBC,MAAO,aAGIC,EAAoB,CAC/BC,cAAe,gBACfC,cAAe,iBAGJC,EAA0B,CACrCC,IAAK,MACLC,kBAAmB,QClBNC,EAHY,SAAA3sF,GAAQ,OACjClI,MAAMC,QAAQiI,GAAYA,EAAW,CAACA,I,qVCExC,IAkDe4sF,EAlD8C,SAAAC,GAC3D,IAAMC,EAAoD,GA8C1D,OA5CAD,EAAkBzsF,SAAQ,SAAAyrF,GACxB,IAAMkB,EAAkBJ,EACtBd,EAAiBkB,iBAGbC,EAA+BD,EAAgBvkF,MACnD,SAAApK,GAAI,OACFA,EAAK6uF,wBAAwBC,YAC7BzB,EAA2BM,4BAG1BiB,GACHzjG,QAAQM,KACN,kEAIJ,IAAMsjG,EAA2BH,EAA6BI,SAKtDxlG,IAFNklG,EACEK,GAIFL,EACEK,GADF,EAEQJ,GAIRA,EAAgB3sF,SAAQ,SAAAhC,GAEpBA,EAAK6uF,wBAAwBC,YAC7BzB,EAA2BM,0BAE3Be,EACEK,GACA5pG,KAAK6a,SAMR0uF,GChCMO,EAlB2B,SACxCJ,EACAK,GACG,IACKC,EAAgBN,EAAhBM,YACAC,EAA+CF,EAA/CE,aACAN,EAD+CI,EAAjCG,6BACdP,UAEFQ,EAAuBF,EACzB79C,OAAO69C,GAAc3qF,QAAQ,GAC7B,GAEJ,MAAO,CACLxO,MAAOk5F,EACP5kG,MAAO,GAAF,OAAK+kG,EAAL,YAA6BR,KCgBvBS,EA9BuB,SAACC,EAAar9D,GAAe,IACzDs9D,EAA0DD,EAA1DC,UASFC,GAT4DF,EAA/CG,iBASJ,CAAEF,YAAWG,YATsCJ,EAA7BI,YASIC,YATyBL,EAAhBK,cAYlD,GAAkB,WAAdJ,EAAwB,KAClBK,EAA0BN,EAAYb,gBAAtCmB,sBACRJ,EAAOI,sBAAwBA,OAC1B,GAAkB,aAAdL,EACT,GAAID,EAAYO,8BACdL,EAAOM,mCAAqCR,EAAYO,mCACnD,GAAIP,EAAYb,gBAAiB,KAEpCqB,EACER,EAAYb,gBADdqB,mCAEFN,EAAOM,mCAAqCA,EAIhD,OAAON,GC4DMO,EA7EmB,SAACC,EAAuB/9D,GAIxD,IAAMq9D,EAAcU,EAAsB9lF,MACxC,SAAAwpE,GAAK,MAAwB,WAApBA,EAAM6b,WAA8C,aAApB7b,EAAM6b,aAGjD,GAAKD,EAAL,CAOA,IAAMW,EAAoBD,EAAsB9lF,MAC9C,SAAAwpE,GAAK,MAAwB,WAApBA,EAAM6b,aAGXW,EAAgCF,EAAsB9lF,MAC1D,SAAApK,GAAI,OACFA,EAAK6uF,wBAAwBC,YAC7BzB,EAA2BO,sBAGzByC,EAAkBH,EAAsBtuD,QAC5C,SAAAgyC,GAAK,MAAwB,QAApBA,EAAM6b,aAGX/wF,EAAc,CAClBohE,QAAQ,EACRuP,OAAQ,GACRqgB,OAAQ,CAACH,EAA8BC,EAAar9D,IACpDw7D,yBAA0BwC,EAAkBnB,IAC5CpB,mBAAoBwC,EAA8BE,WAwCpD,OArCAD,EAAgBruF,SAAQ,SAAAhC,GAAQ,IAE5B6uF,EAGE7uF,EAHF6uF,wBACAF,EAEE3uF,EAFF2uF,gBACAO,EACElvF,EADFkvF,sBAIAlvF,EAAK6uF,wBAAwBC,YAC7BzB,EAA2BW,OAE3BW,EAAgB3sF,SAAQ,SAAAhC,GAEpB,CACEiuF,EAAkBE,cAClBF,EAAkBC,eAClBjsF,SAASjC,EAAK2vF,mBAEZ3vF,EAAK8vF,uBACPpxF,EAAYgxF,OAAO1tF,SAAQ,SAAAuuF,GACzBA,EAAMT,sBAAwB9vF,EAAK8vF,4BAOzCZ,GACFxwF,EAAY2wE,OAAOlqF,KACjB8pG,EACEJ,EACAK,OAMDxwF,EAjELvT,QAAQM,KAAR,4BACuB+jG,EAAYC,UADnC,oDCiGWe,EA9GmC,SAAAN,GAChD,IAAMG,EAAkBH,EAAsBtuD,QAC5C,SAAAgyC,GAAK,MAAwB,QAApBA,EAAM6b,aAGXU,EAAoBD,EAAsB9lF,MAC9C,SAAAwpE,GAAK,MAAwB,WAApBA,EAAM6b,aAGXW,EAAgCF,EAAsB9lF,MAC1D,SAAApK,GAAI,OACFA,EAAK6uF,wBAAwBC,YAC7BzB,EAA2BO,sBAGzBC,EAAUqC,EAAsB9lF,MACpC,SAAApK,GAAI,OACFA,EAAK6uF,wBAAwBC,YAC7BzB,EAA2BQ,WAGzB4C,EAAeP,EAAsBtuD,QACzC,SAAA5hC,GAAI,OACFA,EAAK6uF,wBAAwB6B,yBAC3BtC,EAAwBC,KAC1BruF,EAAK6uF,wBAAwBC,YAC3BzB,EAA2BS,eAG3BpvF,EAAc,CAClBohE,QAAQ,EACRuP,OAAQ,GACRqgB,OAAQ,GACR/B,yBAA0BwC,EAAkBnB,IAC5CpB,mBAAoBwC,EAA8BE,WAiBpD,GAbEzC,GACAA,EAAQ8C,oBAAoBD,yBAC1BtC,EAAwBE,mBAC1BT,EAAQ8C,oBAAoB7B,YAC1BzB,EAA2BU,qBAE7BrvF,EAAY2wE,OAAOlqF,KAAK,CACtB8Q,MA/CkC,sBAgDlC1L,MAAOsjG,EAAQ8C,oBAAoBxB,cAKnCsB,EAAa5rG,OAAQ,CACvB,IAAM+rG,EAAiCH,EAAarmF,MAClD,SAAA0jF,GAAW,OACTA,EAAY6C,oBAAoBD,yBAC9BtC,EAAwBE,mBAC1BR,EAAY6C,oBAAoB7B,YAC9BzB,EAA2BU,uBAG7B6C,GACFlyF,EAAY2wE,OAAOlqF,KAAK,CACtB8Q,MAhEgC,sBAiEhC1L,MAAOqmG,EAA+BD,oBAAoBxB,cA4ChE,OAvCAkB,EAAgBruF,SAAQ,SAAAhC,GAAQ,IAE5B6uF,EAGE7uF,EAHF6uF,wBACAF,EAEE3uF,EAFF2uF,gBACAO,EACElvF,EADFkvF,sBAGF,GAAKP,EAAL,CAP8B,IAatBc,EAAcd,EAAdc,UAER,GAAmB,YAAdA,GAAyC,cAAdA,EAAhC,CAQA,IAAMC,EAASH,EAA8BZ,GAEzCe,GACFhxF,EAAYgxF,OAAOvqG,KAAKuqG,GAGtBR,GACFxwF,EAAY2wE,OAAOlqF,KACjB8pG,EACEJ,EACAK,SAjBJ/jG,QAAQM,KAAR,kBACagkG,EADb,wDARAtkG,QAAQM,KAAR,kBAAwBkjG,EAAxB,sCA+BGjwF,GClGMmyF,EAZY,SAACX,EAAuB/9D,GACjD,OACE+9D,EAAsBzpC,MACpB,SAAAmtB,GAAK,MAAwB,WAApBA,EAAM6b,WAA8C,aAApB7b,EAAM6b,aAG1CQ,EAA0BC,EAAuB/9D,GAGnDq+D,EAA0CN,ICkCpC3xF,EAzCS,SACtBuyF,EACA3+D,GAEA,IAAMq7D,EAAsBsD,EAAwC1mF,MAClE,SAAApK,GAAI,OACFA,EAAK6uF,wBAAwBC,YAC7BzB,EAA2BG,uBAGzBiB,EAAoBF,EACxBf,EAAoBmB,iBACpB/sD,QACA,SAAA5hC,GAAI,OACFA,EAAK6uF,wBAAwBC,YAC7BzB,EAA2BI,oBAGzBiB,EAAoDF,EACxDC,GAGEhwF,EAAe,GAgBnB,OAdA3Z,OAAO4c,KAAKgtF,GAAmD1sF,SAC7D,SAAA+sF,GACE,IAAMmB,EACJxB,EACEK,GAGErwF,EAAcmyF,EAAmBX,EAAuB/9D,GAC1DzzB,GACFD,EAAatZ,KAAKuZ,MAKjBD,GCDMsyF,EAvCiB,SAAAD,GAC9B,IAAME,EAAmB,GAEnBzD,EAAeuD,EAAwC1mF,MAC3D,SAAApK,GAAI,OACFA,EAAK6uF,wBAAwBC,YAC7BzB,EAA2BE,gBAG/B,IAAKA,EAAaoB,gBAChB,OAAOqC,EAGT,IAAMtD,EAAoBa,EACxBhB,EAAaoB,iBACbvkF,MACA,SAAApK,GAAI,OACFA,EAAK6uF,wBAAwBC,YAC7BzB,EAA2BK,qBAkB/B,OAfAa,EAAmBb,EAAkBiB,iBAAiB3sF,SAAQ,SAAAhC,GAAQ,IAC5D8vF,EAA0B9vF,EAA1B8vF,sBACR,GAAIA,EAAuB,KAEvBmB,EAEEnB,EAFFmB,sBACAluC,EACE+sC,EADF/sC,yBAGFiuC,EAAiB7rG,KAAK,CACpB8rG,wBACAluC,iCAKCiuC,G,qOCrCT,IAAME,EAAsBC,IAASC,Y,4BCEtBC,EAJI,CACjBC,sBAAuB,sB,iBCDV,EACN,QADM,EAED,aAFC,EAGH,WAHG,EAIL,SAJK,EAKJ,UALI,EAMJ,U,UCyLIC,EA3LW,SACxB3B,EACAC,EACAJ,EACA+B,GAEA,IAAIC,EAEEC,EAAcF,EAAcx8C,wBAC5Bv5C,EAAW+1F,EAAcn7C,qBACzBV,EAAe67C,EAAcv8C,aAC7B08C,EAAeH,EAAcj7C,eAC/Bi7C,EAAcj7C,eACd,EAEEq7C,EAAI,CACR,CACEF,EAAY,GAAK/7C,EAAa,GAC9B+7C,EAAY,GAAK/7C,EAAa,GAC9Bg8C,EACAl2F,EAAS,IAEX,CACEi2F,EAAY,GAAK/7C,EAAa,GAC9B+7C,EAAY,GAAK/7C,EAAa,GAC9Bg8C,EACAl2F,EAAS,IAEX,CACEi2F,EAAY,GAAK/7C,EAAa,GAC9B+7C,EAAY,GAAK/7C,EAAa,GAC9Bg8C,EACAl2F,EAAS,IAEX,CAAC,EAAG,EAAG,EAAG,IAKNo2F,EAAKC,YAAIF,GAETG,EAAa,SAACC,EAAOH,GASzB,MARmB,CACjB32F,EACE22F,EAAG,GAAG,GAAKG,EAAM92F,EAAI22F,EAAG,GAAG,GAAKG,EAAM52F,EAAIy2F,EAAG,GAAG,GAAKG,EAAMC,EAAIJ,EAAG,GAAG,GACvEz2F,EACEy2F,EAAG,GAAG,GAAKG,EAAM92F,EAAI22F,EAAG,GAAG,GAAKG,EAAM52F,EAAIy2F,EAAG,GAAG,GAAKG,EAAMC,EAAIJ,EAAG,GAAG,GACvEI,EACEJ,EAAG,GAAG,GAAKG,EAAM92F,EAAI22F,EAAG,GAAG,GAAKG,EAAM52F,EAAIy2F,EAAG,GAAG,GAAKG,EAAMC,EAAIJ,EAAG,GAAG,KAM3E,OAAQjC,GACN,KAAKsC,EAGH,GAFAT,EAAiB,GAEC,aAAdhC,EACF,IAAK,IAAI9qG,EAAI,EAAGA,EAAIkrG,EAAYhrG,OAAQF,GAAK,EAAG,CAC9C,IAAMqtG,EAAQ,CACZ92F,EAAG20F,EAAYlrG,GACfyW,EAAGy0F,EAAYlrG,EAAI,GACnBstG,EAAGpC,EAAYlrG,EAAI,IAGrB8sG,EAAetsG,KAAK4sG,EAAWC,EAAOH,SAGxC,IAAK,IAAIltG,EAAI,EAAGA,EAAIkrG,EAAYhrG,OAAQF,GAAK,EAC3C8sG,EAAetsG,KAAK,CAAE+V,EAAG20F,EAAYlrG,GAAIyW,EAAGy0F,EAAYlrG,EAAI,KAIhE,MACF,KAAKutG,EAGH,GAFAT,EAAiB,GAEC,aAAdhC,EACF,IAAK,IAAI9qG,EAAI,EAAGA,EAAIkrG,EAAYhrG,OAAQF,GAAK,EAAG,CAC9C,IAAMqtG,EAAQ,CACZ92F,EAAG20F,EAAYlrG,GACfyW,EAAGy0F,EAAYlrG,EAAI,GACnBstG,EAAGpC,EAAYlrG,EAAI,IAGrB8sG,EAAetsG,KAAK4sG,EAAWC,EAAOH,SAGxC,IAAK,IAAIltG,EAAI,EAAGA,EAAIkrG,EAAYhrG,OAAQF,GAAK,EAC3C8sG,EAAetsG,KAAK,CAAE+V,EAAG20F,EAAYlrG,GAAIyW,EAAGy0F,EAAYlrG,EAAI,KAIhE,MACF,KAAKutG,EAGH,GAFAT,EAAiB,GAEC,aAAdhC,EACF,IAAK,IAAI9qG,EAAI,EAAGA,EAAIkrG,EAAYhrG,OAAQF,GAAK,EAAG,CAC9C,IAAMqtG,EAAQ,CACZ92F,EAAG20F,EAAYlrG,GACfyW,EAAGy0F,EAAYlrG,EAAI,GACnBstG,EAAGpC,EAAYlrG,EAAI,IAGrB8sG,EAAetsG,KAAK4sG,EAAWC,EAAOH,SAGxC,IAAK,IAAIltG,EAAI,EAAGA,EAAIkrG,EAAYhrG,OAAQF,GAAK,EAC3C8sG,EAAetsG,KAAK,CAAE+V,EAAG20F,EAAYlrG,GAAIyW,EAAGy0F,EAAYlrG,EAAI,KAIhE,MACF,KAAKutG,EAEHT,EAAiB,GACjB,IAAK,IAAI9sG,EAAI,EAAGA,EAAIkrG,EAAYhrG,OAAQF,GAAK,EAAG,CAC9C,IAAMqtG,EAAQ,CACZ92F,EAAG20F,EAAYlrG,GACfyW,EAAGy0F,EAAYlrG,EAAI,GACnBstG,EAAGpC,EAAYlrG,EAAI,IAGrB8sG,EAAetsG,KAAK4sG,EAAWC,EAAOH,IAExC,MACF,KAAKK,EAEH,IAAMC,EAAS,CAAEj3F,EAAG20F,EAAY,GAAIz0F,EAAGy0F,EAAY,IAC7CuC,EAAc,CAAEl3F,EAAG20F,EAAY,GAAIz0F,EAAGy0F,EAAY,IAIxD4B,EAAiB,CACfU,SACAE,OAJaC,IAAON,MAAMrpC,SAASwpC,EAAQC,IAM7C,MAEF,KAAKF,EACH/mG,QAAQM,KAAK,sCAEb,IAAM8mG,EAAY,CAChB,CAAEr3F,EAAG20F,EAAY,GAAIz0F,EAAGy0F,EAAY,IACpC,CAAE30F,EAAG20F,EAAY,GAAIz0F,EAAGy0F,EAAY,KAEhC2C,EAAY,CAChB,CAAEt3F,EAAG20F,EAAY,GAAIz0F,EAAGy0F,EAAY,IACpC,CAAE30F,EAAG20F,EAAY,GAAIz0F,EAAGy0F,EAAY,KAKhC4C,EAAkBH,IAAON,MAAMrpC,SAAS6pC,EAAU,GAAIA,EAAU,IAEhEE,EAAqB,CACzBx3F,GAAIs3F,EAAU,GAAGt3F,EAAIs3F,EAAU,GAAGt3F,GAAKu3F,EACvCr3F,GAAIo3F,EAAU,GAAGp3F,EAAIo3F,EAAU,GAAGp3F,GAAKq3F,GAGnCE,EAAsBF,EAAkB,EAc9ChB,EAAiB,CACfmB,QAZc,CACd13F,EAAGq3F,EAAU,GAAGr3F,EAAIw3F,EAAmBx3F,EAAIy3F,EAC3Cv3F,EAAGm3F,EAAU,GAAGn3F,EAAIs3F,EAAmBt3F,EAAIu3F,GAW3CE,QAPc,CACd33F,EAAGq3F,EAAU,GAAGr3F,EAAIw3F,EAAmBx3F,EAAIy3F,EAC3Cv3F,EAAGm3F,EAAU,GAAGn3F,EAAIs3F,EAAmBt3F,EAAIu3F,IAWjD,OAAOlB,GCrLHliB,EACJujB,IAAQvjB,sCAuEV,IAAMwjB,EAAsB,SAAC,GAA2C,IAAzC16F,EAAyC,EAAzCA,gBAAiBqkF,EAAwB,EAAxBA,SAAUnqD,EAAc,EAAdA,QAClDqnD,EAAiBj2D,IAAKllB,aAAaswE,eAAejD,SAElD8C,EAAW8N,EAEjB,GADmB9C,EAAe/O,MAAM+D,IAEnCv2E,IAAmBA,EAAgByjF,UAAxC,CAEA,IAAMC,EAAkBp4D,IAAKllB,aAAau9E,mBAAmB,KAAMzpD,GAC7D7zB,EAAc5Z,OAAOqhC,OAAO,GAAI9tB,EAAiB0jF,EAAiB,CACtEpR,mBAAoBtyE,EAAgBsyE,mBACpCsR,OAAQt4D,IAAK5C,KAAK0L,YAClBmiD,aAGIsE,EAAmB0G,EAAepJ,eAAe5B,EAAUlwE,GACjE5Z,OAAOqhC,OAAO9tB,EAAiB66E,GAE/B,IAAM/D,EAAmBxrD,IAAKllB,aAAa2wE,SAAS/2E,GAChD82E,IACF92E,EAAgBg3E,OAAS,CAACF,MCvDxB6jB,EAAwC,SAC5CC,EACAC,GAEA,IAAIz0F,EAAew0F,EAAax0F,aAMhC,GAAMy0F,aAA2BvvC,IAAjC,CAPG,IAWKG,EAAyBovC,EAAzBpvC,aAAczxB,EAAW6gE,EAAX7gE,OAiEtB,GAA4B,KA5D5B5zB,EAAeA,EAAamjC,QAAO,SAAAljC,GACjC,OAAOA,EAAYgxF,OAAOjpC,MAAK,SAAA8pC,GAC7B,QAAoC/mG,IAAhC+mG,EAAMT,sBAAqC,CAO7C,IAAK,IAAInrG,EAAI,EAAGA,EAAI0tC,EAAOxtC,SAAUF,EAAG,CACtC,IAAM6sG,EAAgBn/D,EAAO1tC,GAAGmiD,UAAU9e,SAC1C,GACEwpE,EAAcx7C,sBACdu6C,EAAMP,mCAFR,CAOA,IAAImD,EAAc,CAAC,EAAG,EAAG,GACnBzB,EAAcF,EAAcx8C,wBAClCm+C,EAAY,GACVzB,EAAY,GAAKA,EAAY,GAAKA,EAAY,GAAKA,EAAY,GACjEyB,EAAY,GACVzB,EAAY,GAAKA,EAAY,GAAKA,EAAY,GAAKA,EAAY,GACjEyB,EAAY,GACVzB,EAAY,GAAKA,EAAY,GAAKA,EAAY,GAAKA,EAAY,GAGjE,IADA,IAAI0B,EAAsB,EACjBvtG,EAAI,EAAGA,EAAI,IAAKA,EACvButG,GACED,EAAYttG,GAAK2rG,EAAcn7C,qBAAqBxwD,GAIxD,KAAI6hB,KAAKw5C,IAAIkyC,EAAsB7C,EAAMV,YAAY,IAAM,GAA3D,CAIAU,EAAMT,sBAAwB,CAC5BmB,sBAAuBO,EAAcr8C,YACrC4N,yBAA0ByuC,EAAcz/D,gBAG1C,QAGF,QAAoCvoC,IAAhC+mG,EAAMT,sBACR,OAAO,EAIX,OAAOhsC,EAAa7hD,SAClBsuF,EAAMT,sBAAsBmB,8BAQjBpsG,OAAjB,CAIA,IAAM03E,EAAWlqC,EAAOv9B,KAAI,SAAAnQ,GAAC,OAAIA,EAAE6tC,gBAC7B6gE,EAAkBhhE,EAAOv9B,KAAI,SAAAnQ,GAAC,OAAIA,EAAEotC,kBAC1CtzB,EAAauD,SAAQ,SAAAtD,GACAA,EAAXgxF,OAED1tF,SAAQ,SAAAuuF,GACb,QAAoC/mG,IAAhC+mG,EAAMT,sBAAqC,CAC7C,IAAM/pB,EAAastB,EAAgB3nF,WACjC,SAAAqmB,GAAc,OACZA,IACAw+D,EAAMT,sBAAsB/sC,4BAEhC,GAAIgjB,GAAc,EAAG,CACnB,IAAMxzC,EAAUgqC,EAASwJ,GACnByrB,EAAgBn/D,EAAO0zC,GAAYj/B,UAAU9e,UD5H9C,SACbtpB,EACA6zB,EACAi/D,EACAxnF,GAGA,IAAM0yE,EAAW2U,EAAWC,sBAEtBj5F,EAAkB,CACtBs1F,yBAA0BjvF,EAAYivF,yBACtC8D,eAAgB,GAChBpiB,OAAQ3wE,EAAY2wE,QAGtB3wE,EAAYgxF,OAAO1tF,SAAQ,SAAAuuF,GAAS,IAC1BX,EAAwCW,EAAxCX,YAAaC,EAA2BU,EAA3BV,YAAaJ,EAAcc,EAAdd,eAEkBjmG,IAAhD6O,EAAgBo5F,eAAe7B,KACjCv3F,EAAgBo5F,eAAe7B,GAAe,IAEhDv3F,EAAgBo5F,eAAe7B,GAAazqG,KAC1CosG,EAAkB3B,EAAaC,EAAaJ,EAAW+B,OAI3D,IAAMliB,EAAYC,EAAsCC,qBAE7BhmF,IAAvB8lF,EAAU/8C,KACZ+8C,EAAU/8C,GAAW,IAGvB,IAAM+gE,EAAmBhkB,EAAU/8C,QAGA/oC,IAA/B8pG,EAAiB5W,KACnB4W,EAAiB5W,GAAY,CAC3Br4F,KAAM,KAIV,IAAM2rF,EAAWsjB,EAAiB5W,GAElCrkF,EAAgBsX,YAAhB,uBACAtX,EAAgBE,YAAa,EAC7By3E,EAAS3rF,KAAKc,KAAKkT,GAEnB06F,EAAoB,CAAE16F,kBAAiBqkF,WAAUnqD,YAEjD7zB,EAAYohE,QAAS,EACrBphE,EAAY6zB,QAAUA,EACtB7zB,EAAYsL,sBAAwBA,EAKpCtL,EAAYqkD,yBACVrkD,EAAYgxF,OAAO,GAAGI,sBAAsB/sC,yBCoEtCytB,CACE9xE,EACA6zB,EACAi/D,EACA0B,EAAgBlpF,kCAQbupF,EApJO,SAAC,GAAqC,IAAnCvH,EAAmC,EAAnCA,gBAAiB3pC,EAAkB,EAAlBA,YAChClpB,EAAuB6yD,EAAgBvM,SAAvCtmD,mBAEckpB,EAAYzgB,QAAO,SAAA2gB,GAAE,MAAoB,OAAhBA,EAAGlhC,YAEpCrf,SAAQ,SAAAixF,GACpB,IAAM9iE,EAAgB8iE,EAAajrE,SACnC,GAAKmI,EAAL,CAFoC,IAM5Bw+D,EAAoBx+D,EAApBw+D,gBAERsE,EAAajC,iBAAmBD,EAAwBpC,GACxDsE,EAAax0F,aAAeF,EAAgBowF,EAAiBsE,GAC7D,IAAMO,EAAWr6D,EAAmBs6D,kBAClC,mBACA,KAGFR,EAAaS,YAAa,EAC1BT,EAAaU,eLhBF,SAAwBxhE,EAAYqhE,GACjD,IAAKA,IAAaA,EAAS3uG,OACzB,OAAO,EAGT,IAAM+uG,EAAqBJ,EAAS1+F,KAAI,SAAAlL,GAAC,OAAIA,EAAEyhG,cACvC5sF,EAAiB0zB,EAAjB1zB,aAEFo1F,EAAc/uG,OAAO4c,KAAKwvF,GAAqBtvD,QACnD,SAAAkyD,GAAU,MAEoC,mBADrC5C,EAAoB4C,GACxBC,wCAGD5C,EAAW,GAEjB0C,EAAY7xF,SAAQ,SAAAnX,GACd+oG,EAAmB3xF,SAASpX,IAG9BsmG,EAAShsG,KAAK+rG,EAAoBrmG,OAItC,IAxB2D,eAwBlDlG,GACP,IAAMipG,EAAqBnvF,EAAa9Z,GAAGipG,mBAK3C,GAJmBuD,EAAS1qC,MAAK,SAAAutC,GAAO,OACtCA,EAAQD,qCAAqCnG,MAI7C,UAAO,IAPFjpG,EAAI,EAAGA,EAAI8Z,EAAa5Z,OAAQF,IAAK,SAArCA,GAAqC,8BAW9C,OAAO,EKnByBgvG,CAAeV,EAAcO,GAC3DP,EAAa/9B,UAAW,EAEC7S,EAAYzgB,QACnC,SAAA2gB,GAAE,MACgB,OAAhBA,EAAGlhC,UACa,QAAhBkhC,EAAGlhC,UACa,aAAhBkhC,EAAGlhC,UACa,WAAhBkhC,EAAGlhC,YAEUrf,SAAQ,SAAAkxF,GAEvBF,EAAsCC,EAAcC,WCf3Ce,EAjB8B,SAAC5xC,EAAatwB,GACzD,IAAImiE,EAaJ,OAXA7xC,EAAYj4C,MAAK,SAAA+nB,GACf,QAAKA,EAAWE,WAEhB6hE,EAAgB/hE,EAAWE,OAAOjoB,MAChC,SAAAy2C,GAAgB,OACdA,EAAiBnvB,sBAAwBK,SAMxCmiE,GCfDpzD,EAAevxB,IAAfuxB,WAuGFqzD,EAAe,SACnB1qF,EACAooB,EACAE,EACA+8C,GAEA,MAAO,CAACrlE,EAAkBooB,EAAmBE,EAAgB+8C,GAAYzuE,KACvE,MAIW+zF,EAtGoB,SACjCC,EACAhyC,EACAiyC,GAEIA,GAAYA,EAAStI,iBACvBuH,EAAc,CAAEvH,gBAAiBsI,EAAStI,gBAAiB3pC,gBAI7D,IAOIkyC,EAPE7iD,EAAYM,IAAM3tD,KAAKstD,aAAaC,SAASyiD,GAC7C3hD,EAAUV,IAAM3tD,KAAK4tD,oBAAoBC,kBAC7CR,EAAUI,MAGJ0iD,EAAsBxiD,IAAMm/C,SAASC,YAArCoD,kBAGR,IACED,EAA8BC,EAAkBC,kBAAkB/hD,GAClE,MAAOzpD,GACP,IAAMyrG,EAAoBhiD,EAAQmR,mBAAqB,GAOvD,YANA/iB,EAAW6zD,QAAQ7zD,EAAWU,OAAOC,MAAO,CAC1CtjC,MAAO,mBAAF,OAAqBu2F,EAArB,uBACLhtG,KAAM,UACN4B,QAASL,EAAMK,SAAW,GAC1Bg4C,QAAQ,IAKZ,IAAMjpC,EAAkB,GACpBc,EAAoB,EAgDxB,OA9CArU,OAAO4c,KAAK6yF,GAA6BvyF,SAAQ,SAAA06E,GAC/C,IAAMj+E,EAAe81F,EAA4B7X,GACjDrkF,EAAgBqkF,GAAY,GAE5Bj+E,EAAauD,SAAQ,SAAAtD,GACnB,IAAMmiD,EAAmBozC,EACvB5xC,EACA3jD,EAAYw8C,gBAGE7wC,EAA2Bw2C,EAAnC3B,OAAwBluB,EAAW6vB,EAApB1B,QACf11C,EAAgCY,EAAhCZ,iBAAkBoN,EAAcxM,EAAdwM,UAClBgb,EAAsBb,EAAtBa,kBACAqpB,EAA+Bx8C,EAA/Bw8C,eAAgB4zB,EAAepwE,EAAfowE,WAClBD,EAAYslB,EAChB1qF,EACAooB,EACAqpB,EACA4zB,GAGIv8C,EAAUsuB,EAAiBruB,aACjC,GAAKD,EAAL,CAKA,IAEMy9C,EAAWlrF,OAAOqhC,OAAO,GAAIznB,EAAa,CAC9C6zB,UACAs8C,YACA98C,eAAgBmpB,EAChBrpB,oBACApoB,mBACAoN,YACA1d,oBAAqBA,EACrBmyE,YAVyB,cAWzBsD,SAAU8N,EACV9M,IAAKr9C,EAAUp5B,IAGjBd,EAAgBqkF,GAAUv3F,KAAK6qF,UAI5B33E,G,yBCrFMu8F,EALS,SAAAlY,GAEtB,QADgB1qC,IAAMm/C,SAASC,YACd1U,IC8CJmY,EA3Ce,SAAAzgB,GAAoB,IACxCogB,EAAsBxiD,IAAMm/C,SAASC,YAArCoD,kBACA1kB,EAA2BrxE,IAA3BqxE,uBAEFR,EAAY,GACZwlB,EAAmB,GAiCzB,OA/BAhwG,OAAO4c,KAAK0yE,GAAkBpyE,SAAQ,SAAAy1E,GAChBrD,EAAiBqD,GAEzBz1E,SAAQ,SAAA+yF,GAAc,IACxBnmB,EAAwBmmB,EAAxBnmB,SAAUC,EAAckmB,EAAdlmB,UAElB,GAAI+lB,EAAgBhmB,GAAW,CAC7B,IAAMr8C,EAAUu9C,EAAuBjB,GACvCS,EAAU/8C,GAAW+8C,EAAU/8C,IAAY,GAC3C+8C,EAAU/8C,GAASq8C,GAAYU,EAAU/8C,GAASq8C,IAAa,CAC7DvqF,KAAM,IAGRirF,EAAU/8C,GAASq8C,GAAUvqF,KAAKc,KAAK4vG,QAEvCD,EAAiB3vG,KAAKypF,SAKxBkmB,EAAiBjwG,OAAS,GAC5B2G,IAAIC,KAAJ,6CACwCqpG,EAAiBz0F,KAAK,QASzD,CACLqyC,QANa8hD,EAAkBQ,eAC/B1lB,EACA1tD,IAAYo7C,UAIItqB,UClCLuiD,EAZW,SAAA5/E,GACxB,IAAI+sC,EAAiB,GAQrB,OANA/sC,EAAQrT,SAAQ,SAAAqI,GACVA,EAAMqzD,iBACRtb,EAAiBA,EAAe7wB,OAAOlnB,EAAMqzD,sBAI1Ctb,G,kVCLT,IAYM8yC,GAAyB,6CAAG,WAChClkE,EACA3b,EACA8/E,EACAb,GAJgC,yGAM1B/wE,EAAS,CACbwiB,IAAKovD,EACLt0E,QAAST,IAASO,yBAClBivB,iBAAkB/W,KAAauM,sBAC/ByK,aAAc,CAAClJ,iBAGXyK,EAAW,IAAItB,IAAIC,eAAexsB,GAElC4N,EAAWH,EAAOvC,mBAClB7lB,EAAU,CACdurC,iBAAkBhjB,EAASS,sBAC3BoiB,kBAAmB7iB,EAASW,uBAC5BonB,eAAgB/nB,EAASO,qBAnBK,SAsBE0f,EAAS4hB,iBAAiBpqD,GAtB5B,cAsB1ByrF,EAtB0B,OAuB1BhyC,EAAc4yC,EAAkB5/E,GAChC++D,EAAmBggB,EACvBC,EACAhyC,EACAiyC,GA3B8B,kBA8BzBlgB,GA9ByB,4CAAH,4DAwCzBghB,GAAsB,6CAAG,WAAO32F,EAAc02F,GAArB,qHACTN,EAAsBp2F,GAAlCi0C,EADqB,EACrBA,QADqB,EAEcV,IAAM3tD,KAAzC4tD,EAFqB,EAErBA,oBAAqBojD,EAFA,EAEAA,UACvB5iF,EAAO,CACX6iF,2BAA4B5iD,EAAQ6iD,MAAMD,2BAA2Bj1E,MACrEm1E,wBAAyB9iD,EAAQyC,YACjCsgD,2BAA4B/iD,EAAQ3gB,eACpC2jE,kBA1DwB,sBA2DxBC,uBAAwB1jD,EAAoBhL,MAC5C2uD,0BA7DiB,aAgEbC,EAAgB5jD,EAAoB6jD,oBAAoBrjF,IACxDsjF,EAAY,IAAIV,EAAUQ,IAEtB/jD,KAAOG,EAAoB6jD,oBAAoBpjD,GAEnDsjD,EAAeD,EAAUE,QAEzB1yE,EAAS,CACbwiB,IAAKovD,EACLt0E,QAAST,IAASO,yBAClBivB,iBAAkB/W,KAAauM,sBAC/ByK,aAAc,CAAClJ,iBAGXyK,EAAW,IAAItB,IAAIC,eAAexsB,GAClC3a,EAAU,CACd4oC,SAAU,CAACwkD,IA5BgB,UA+BvB5kD,EAAS8kD,eAAettF,GA/BD,4CAAH,wDCvBtButF,GAA2B,SAAAnlE,GAC/B,IAOMmkB,EADgBnkB,EAAOvC,mBACKqY,UAAU9e,SAASmtB,YAErD,MAT8B,CAC5B,gCACA,+BACA,iCAM2BlzC,SAASkzC,IAUlCihD,GAAoB,SAACC,EAASC,GAClC,OACED,EAAQjvD,MAAMsM,WAAa4iD,EAAQlvD,MAAMsM,YACxC2iD,EAAQjvD,MAAMsM,aAAe4iD,EAAQlvD,MAAMsM,YAC1C2iD,EAAQjvD,MAAMuM,WAAa2iD,EAAQlvD,MAAMuM,YAIhC4iD,GA7DwB,SAAAlhF,GACrC,IAAImhF,EAuBJ,OArBAnhF,EAAQrT,SAAQ,SAAAqI,IACIA,EAAM+yD,UAAY/yD,EAAM+yD,YAAc,IAC9Cp7D,SAAQ,SAAAgvB,GAIXA,GAAwC,IAA9BA,EAAO0yB,oBAIlByyC,GAAyBnlE,KAExBwlE,IACDJ,GAAkBplE,EAAQwlE,KAE1BA,EAA6BxlE,UAM9BwlE,G,0HCNT,ICrBM19D,GAAU,CACd29D,qBDoB2B,SAACzoD,GAA0B,IAAlBsmD,EAAkB,uDAAP,GAG/C,GAFA9oG,IAAIE,KAAK,mCAEJsiD,GAA0B,aAAhBA,EAAOtmD,KAEpB,OADA8D,IAAIvC,MAAM,0CACHvC,QAAQE,OAAO,IAGxB,IAAMuuG,EAAYnnD,EAAO2B,SACnBt6B,EAAUsjB,IAAMm8B,qBAAqBnrE,MAErC+sG,EAAeH,GAA+BlhF,GAEpD,OAAKqhF,EAEExB,GAA0BwB,EAAcrhF,EAAS8/E,EAAWb,GAFzC5tG,QAAQC,QAAQ,KChC1CgwG,kBD6CqB,e,EAAA,G,EAAA,yBAAG,WAAOt+F,EAAiBupC,EAAQoM,GAAhC,+FACxBxiD,IAAIE,KAAK,+BAEJsiD,GAA0B,aAAhBA,EAAOtmD,KAHE,uBAItB8D,IAAIvC,MAAM,0CAJY,kBAKfvC,QAAQE,OAAO,KALA,cAQlBuuG,EAAYnnD,EAAO2B,SACnBinD,EAAsB9xG,OAAO4c,KAAKrJ,GAAiB,GACnDw+F,EAAmBx+F,EAAgBu+F,GAAqB,GACxDntF,EACJotF,GAAoBA,EAAiBptF,iBAZf,mBAehB2rF,GAAuB/8F,EAAiB88F,GAfxB,eAgBlB1rF,GACF4L,IAAQw7C,2BAA2BpnD,GAjBf,kBAoBf,CACLngB,QAAS,oCArBW,wCAwBtBkC,IAAIvC,MAAJ,yDACoD,KAAMK,UAEpD,IAAIpB,MAAM,wCA3BM,yD,iLAAH,0DC5CrB0sG,mBAGa97D,Q,6BCNR,ICkIQg+D,EArBC,CAIdC,kBAhF+B,SAAAhnE,GAAa,MAAK,CACjDroC,KDjCiC,uBCkCjCqoC,kBA+EAiE,wBA1FqC,SACrCjE,EACAkE,GAFqC,MAGjC,CACJvsC,KD5B0B,gBC6B1BqoC,gBACAkE,yBAqFA+iE,yBA9DsC,SAAC,EAEvC/iE,GAFsC,MAGlC,CACJvsC,KDrDA,yCCsDAkrC,QALsC,EACpCA,QAKFC,WANsC,EAC3BA,WAMXhH,UAPsC,EACfA,UAOvBoI,yBAuDAnB,UA3EuB,SAAC,GAAD,MAAyC,CAChEprC,KDxCiC,uBCyCjCkrC,QAFuB,EAAGA,QAG1BC,WAHuB,EAAYA,WAInChH,UAJuB,EAAwBA,YA4E/CorE,0BArDuC,SAAAlnE,GAAa,MAAK,CACzDroC,KD5D4B,kBC6D5BqoC,kBAoDAmnE,8BAjD2C,SAAAjjE,GAAoB,MAAK,CACpEvsC,KD/DsC,qCCgEtCusC,yBAmDAkjE,mBA7CgC,SAAApjG,GAAK,MAAK,CAC1CrM,KDvDkC,uBCwDlCqM,UA4CAqjG,iBAzC8B,SAAChzC,EAAW//D,GAAZ,MAAsB,CACpDqD,KAAM,qBACN08D,YACA//D,SAuCAgzG,cApC2B,SAAAtjG,GAAK,MAAK,CACrCrM,KAAM,iBACNqM,UAmCAujG,gBAhC6B,SAAAvjG,GAAK,MAAK,CACvCrM,KAAM,mBACNqM,UA+BAwjG,aA5B0B,SAAC9tF,EAAkBplB,GAAnB,MAA6B,CACvDqD,KAAM,iBACN+hB,mBACAplB,SA0BAmzG,WAvBwB,SAAAzlC,GAAO,MAAK,CACpCrqE,KD5FyB,cC6FzBqqE,a,uqBC7GK,IAAM0lC,EAAe,GAwBbC,EAtBI,WAAkC,IAAjC3jG,EAAiC,uDAAzB0jG,EAAcv3D,EAAW,uCACnD,OAAQA,EAAOx4C,MACb,IAAK,qBACH,IAAMiwG,EAAgBz3D,EAAOkkB,UACvBwzC,EAAc7jG,EAAM4jG,IAAkB,GAEtCE,EAAe33D,EAAO77C,KAEtB+/D,EAAY,EAAH,GACZuzC,EADY,KAERC,EAFQ,GAGRC,IAIP,YAAY9jG,EAAZ,GAAsBqwD,GAExB,QACE,OAAOrwD,ICpBP0jG,EAAe,CACnBK,gBAAiB,CACfppB,EAAG,CAAE/+D,YAAa,cAAetkB,OAAQ,MAAOswC,MAAO,MACvDo8D,EAAG,CAAEpoF,YAAa,OAAQtkB,OAAQ,MAAOswC,MAAO,QAChDq8D,EAAG,CAAEroF,YAAa,QAAStkB,OAAQ,MAAOswC,MAAO,MACjDs8D,EAAG,CAAEtoF,YAAa,OAAQtkB,OAAQ,OAAQswC,MAAO,OACjDu8D,EAAG,CAAEvoF,YAAa,QAAStkB,OAAQ,KAAMswC,MAAO,MAChDw8D,EAAG,CAAExoF,YAAa,QAAStkB,OAAQ,IAAKswC,MAAO,KAC/Cy8D,EAAG,CAAEzoF,YAAa,GAAItkB,OAAQ,GAAIswC,MAAO,IACzCv1C,EAAG,CAAEupB,YAAa,GAAItkB,OAAQ,GAAIswC,MAAO,IACzC08D,EAAG,CAAE1oF,YAAa,GAAItkB,OAAQ,GAAIswC,MAAO,IACzC28D,GAAI,CAAE3oF,YAAa,GAAItkB,OAAQ,GAAIswC,MAAO,KAE5C48D,mBAAoB,IAgBPC,EAXK,WAAkC,IAAjCzkG,EAAiC,uDAAzB0jG,EAAcv3D,EAAW,uCACpD,OAAQA,EAAOx4C,MACb,IAAK,uBACH,OAAO5C,OAAOqhC,OAAO,GAAIpyB,EAAOmsC,EAAOnsC,OAEzC,QACE,OAAOA,I,8gCCtBN,IAAM0jG,EAAe,CAC1B1lC,QAAS,IA4BIA,EAzBC,WAAkC,IAAjCh+D,EAAiC,uDAAzB0jG,EAAcv3D,EAAW,uCAChD,OAAQA,EAAOx4C,MACb,IAAK,aACH,IAAIqqE,EAAU0mC,IAAO,GAAD,SAAK1kG,EAAMg+D,SAAX,CAAoB7xB,EAAO8N,SAAS,MAExD,OADA+jB,EAAQ/vD,SAAQ,SAAA/b,GAAC,OAAKA,EAAE8P,QAAS,KACjC,KAAYhC,EAAZ,CAAmBg+D,YAErB,IAAK,kBACH,IAAM2mC,EAAY,KAAKx4D,EAAO8N,OAAf,CAAuBj4C,QAAQ,IACxC4iG,EAAa5kG,EAAMg+D,QAEzB,OADA4mC,EAAW32F,SAAQ,SAAA/b,GAAC,OAAKA,EAAE8P,QAAS,KACpC,KACKhC,EADL,CAEEg+D,QAAS0mC,IAAO,GAAD,SAAKE,GAAL,CAAiBD,IAAY,cAIhD,IAAK,cACH,YAAY3kG,EAAZ,CAAmBg+D,QAAS7xB,EAAO6xB,UAErC,QACE,OAAOh+D,I,iBCzBP0jG,EAAe,CACnB1uF,UAAW,IAgBEgpD,EAbC,WAAkC,IAAjCh+D,EAAiC,uDAAzB0jG,EAAcv3D,EAAW,uCAChD,OAAQA,EAAOx4C,MACb,IAAK,iBACH,IAAMkxG,EAAmB7qF,IAAUha,EAAMgV,WAGzC,OAFA6vF,EAAiB14D,EAAOz2B,kBAAoBsE,IAAUmyB,EAAO77C,MAEtDS,OAAOqhC,OAAO,GAAIpyB,EAAO,CAAEgV,UAAW6vF,IAE/C,QACE,OAAO7kG,ICfP0jG,EAAe,CACnB14F,WAAY,GACZN,aAAc,IAcDo6F,EAXU,WAAkC,IAAjC9kG,EAAiC,uDAAzB0jG,EAAcv3D,EAAW,uCACzD,OAAQA,EAAOx4C,MACb,IAAK,iBACH,OAAO5C,OAAOqhC,OAAO,GAAIpyB,EAAO,CAAEgL,WAAYmhC,EAAOnsC,QACvD,IAAK,mBACH,OAAOjP,OAAOqhC,OAAO,GAAIpyB,EAAO,CAAE0K,aAAcyhC,EAAOnsC,QACzD,QACE,OAAOA,I,qgCCCb+kG,aAAc,GAEP,IAAMC,EAAgB,CAC3BnmE,QAAS,EACTC,WAAY,EACZs3D,oBAAqB,EACrBC,OAAQ,CACNv+D,UAAW,CAAC,KAEdoI,qBAAsB,IAYlB+kE,EAAiC,SACrCpmE,EACAC,GAEG,IADHomE,EACG,uDAD2B,GAExBC,EAAoBtmE,EAAUC,EAC9BoB,EAAuBlmB,IAAUkrF,GAUvC,OARIC,EAAoBp0G,OAAO4c,KAAKuyB,GAAsBpvC,QACxDC,OAAO4c,KAAKuyB,GAAsBjyB,SAAQ,SAAAnX,GACpCA,EAAMquG,EAAoB,UACrBjlE,EAAqBppC,MAK3BopC,GAUHklE,EAAyB,SAC7BvmE,EACAC,EACAumE,GAIA,OAAOA,EAFmBxmE,EAAUC,EAEoB,EACpDkmE,EAAc5O,oBACdiP,GCrDSC,EATE,CACf3B,aACAc,cACAzmC,UACA18C,UACAwjF,mBACAhtE,UD0EgB,WAAmC,IAAlC93B,EAAkC,uDAA1BglG,EAAe74D,EAAW,uCAC/Co5D,GAAoB,EAExB,OAAQp5D,EAAOx4C,MAMb,IP5F+B,uBO6F7B,OAAO6xG,YAAQxlG,GAAO,SAAAylG,GACpBA,EAAWrP,oBAAsBgP,EAC/BK,EAAW5mE,QACX4mE,EAAW3mE,WACXqN,EAAOnQ,kBAUb,IP1G+B,uBO0GL,IAChB6C,EAAwBsN,EAAxBtN,QAASC,EAAeqN,EAAfrN,WACXoB,EAAuB+kE,EAC3BpmE,EACAC,EACA9+B,EAAMkgC,sBAEFk2D,EAAsBgP,EAC1BvmE,EACAC,EACA9+B,EAAMo2F,qBAGR,YACKp2F,EADL,CAEE6+B,QAASsN,EAAOtN,QAChBC,WAAYqN,EAAOrN,WACnBu3D,OAAQ,CAAEv+D,UAAW,EAAIqU,EAAOrU,YAChCoI,uBACAk2D,wBASJ,IPpIF,yCOoIqC,IACzBv3D,EAAwBsN,EAAxBtN,QAASC,EAAeqN,EAAfrN,WACXoB,EAAuB+kE,EAC3BpmE,EACAC,EACAqN,EAAOjM,sBAEHk2D,EAAsBgP,EAC1BvmE,EACAC,EACA9+B,EAAMo2F,qBAGR,YACKp2F,EADL,CAEE6+B,QAASsN,EAAOtN,QAChBC,WAAYqN,EAAOrN,WACnBu3D,OAAQ,CAAEv+D,UAAW,EAAIqU,EAAOrU,YAChCoI,uBACAk2D,wBASJ,IPpKwB,gBOqKtB,OAAOoP,YAAQxlG,GAAO,SAAAylG,GACpBA,EAAWvlE,qBAAqBiM,EAAOnQ,eACrCypE,EAAWvlE,qBAAqBiM,EAAOnQ,gBAAkB,GAE3DjrC,OAAO4c,KAAKw+B,EAAOjM,sBAAsBjyB,SAAQ,SAAAnX,GAC/C2uG,EAAWvlE,qBAAqBiM,EAAOnQ,eAAellC,GACpDq1C,EAAOjM,qBAAqBppC,MAG5Bq1C,EAAOjM,sBAAwBiM,EAAOjM,qBAAqBowB,SAC7Dm1C,EAAWpP,OAAOv+D,UAAUqU,EAAOnQ,eAAes0B,OAChDnkB,EAAOjM,qBAAqBowB,WAUpC,IPnLoC,qCOoLlCi1C,GAAoB,EAGtB,IPxL6B,8BOyL3B,IAAMlP,EAASr8E,IAAUha,EAAMq2F,QACzBr6D,EAAgBupE,EAClBvlG,EAAMo2F,oBACNjqD,EAAOnQ,cAEPkE,EAAuBlmB,IAAUha,EAAMkgC,sBAU3C,OATAA,EAAqBlE,GAArB,KACKmQ,EAAOjM,sBAGRiM,EAAOjM,sBAAwBiM,EAAOjM,qBAAqBowB,SAC7D+lC,EAAOv+D,UAAUkE,GAAes0B,OAC9BnkB,EAAOjM,qBAAqBowB,QAGhC,KAAYtwD,EAAZ,CAAmBq2F,SAAQn2D,yBAQ7B,IPjN0B,kBOkNxB,IAAIA,EAAuBlmB,IAAUha,EAAMkgC,sBAE3C,OAAIiM,EAAOnQ,eACTkE,EAAqBiM,EAAOnQ,eAAiB,GAC7C,KAAYh8B,EAAZ,CAAmBkgC,0BAEZ8kE,EASX,QACE,OAAOhlG,KE1OP0lG,EAAkBpuG,OAAOquG,aA2BhBA,EALM,CACnBC,UARuB,SAAA5lG,GACvB,IACE,IAAM6lG,EAAkBjtB,KAAKC,UAAU74E,GACvC0lG,EAAgBI,QAjBI,QAiBqBD,GACzC,MAAOpzG,MAKTszG,UAtBuB,WACvB,IACE,IAAMF,EAAkBH,EAAgBphC,QAHpB,SAIpB,IAAKuhC,EACH,OAGF,OAAOjtB,KAAKpwB,MAAMq9C,GAClB,MAAOpzG,GACP,UCXEuzG,EAAoB1uG,OAAO2uG,eCK3BphE,EAAQ,CACZygE,WACAvC,UACA4C,eACAM,eDaqB,CACrBL,UARuB,SAAA5lG,GACvB,IACE,IAAM6lG,EAAkBjtB,KAAKC,UAAU74E,GACvCgmG,EAAkBF,QAjBI,QAiBuBD,GAC7C,MAAOpzG,MAKTszG,UAtBuB,WACvB,IACE,IAAMF,EAAkBG,EAAkB1hC,QAHpB,SAItB,IAAKuhC,EACH,OAGF,OAAOjtB,KAAKpwB,MAAMq9C,GAClB,MAAOpzG,GACP,WCCWoyC,O,iNCNPptC,EAAQm4B,IAARn4B,IAEO,aAA6B,IAApBm6E,EAAoB,uDAAJ,GAEtCt6E,OAAO42B,iBAAmBA,IAE1BA,IAAiBqyE,SAAS1yE,YAAcA,IACxCK,IAAiBqyE,SAAS2F,OAASA,IACnCh4E,IAAiBqyE,SAAS4F,gBAAkBA,IAC5Cj4E,IAAiB27B,KAAK+nB,GAEtB1jD,IAAiBk4E,mBAAmBC,wBAClC,SAACp9F,EAASu1B,EAAStpC,GAEjB,MADAuC,EAAIvC,MAAMspC,GACJtpC,KAMV,IAAMoxG,EACJ,2HACFp4E,IAAiBC,UAAUo4E,QAA3B,eAA2CD,IAG3Cp4E,IAAiBs4E,UAAUC,aAAa,GACxCv4E,IAAiBw4E,WAAWC,aAAa,oBACzCz4E,IAAiBw4E,WAAWE,eAAe,kBAE3C14E,IAAiB+vC,MAAMj+D,MAAM6mG,eAAiB,GAG9C34E,IAAiB44E,cAAcp0B,iBAAiB,CAC9Cq0B,oBAAqBn1B,EAAcm1B,oBACnCC,qBAAsBp1B,EAAco1B,qBACpCC,wBAAyBr1B,EAAcq1B,2B,sVCvC3C,IAAMC,EAAkB,CACtB,SACA,gBACA,eACA,iBAsIaC,EAnI2B,SAAAC,GAQxC,IAwEMC,EAAiB,SAAAp+F,GACrB,IACMu1B,EADiB3Q,IAAYkB,kBAAkB9lB,GACtBymB,MAAM8O,QAC/BpB,EAAWvP,IAAYo7C,SAAS7yE,IAAI,WAAYooC,GAEtD,MAAO,CACLR,eAAgBZ,EAASY,eACzBikB,oBAAqB7kB,EAAS6kB,oBAC9BnkB,kBAAmBV,EAASU,oBAI1BwpE,EAA4B,SAAAzsB,GAAY,MACPusB,EAAmBG,YAAhDC,EADoC,EACpCA,SAUR,MAPgC,CAC9BC,OAAQD,EACRE,cAN0C,EAC1BC,QAMhBC,aAAcJ,EACdK,cAR0C,EACjBC,OAUIjtB,IAG3BktB,EAAwB,SAAA72E,GAC5B,IAAI82E,EAAS,GASb,OARAj3G,OAAO4c,KAAKujB,GAASnwB,KAAI,SAAAknG,GACvB,GAAI,CAAC,QAAS,OAAO/5F,SAAS+5F,GAAS,CACrC,IAAIhK,EAAQ,GACR/sE,EAAQ+2E,GAAQ9gG,IAAG82F,EAAM92F,EAAI+pB,EAAQ+2E,GAAQ9gG,GAC7C+pB,EAAQ+2E,GAAQ5gG,IAAG42F,EAAM52F,EAAI6pB,EAAQ+2E,GAAQ5gG,GACjD2gG,EAAO52G,KAAK6sG,OAGT+J,GAGHE,EAAwB,SAAAF,GAC5B,OAAOA,EACJjnG,KAAI,SAAC/N,EAAGpC,GAAJ,OAAWA,EAAI,IAAO,EAAI,CAAEgsB,MAAO5pB,GAAM,CAAE6pB,IAAK7pB,MACpDsvB,QAAO,SAACiZ,EAAKtvB,GAAN,OAAelb,OAAOqhC,OAAOmJ,E,+UAAd,IAAwBtvB,MAAS,KAG5D,MAAO,CACLk8F,aAtHmB,SAACx9F,EAAa2sF,GAAe,IAE9C10F,EAQE+H,EARF/H,GACAV,EAOEyI,EAPFzI,MACA0Z,EAMEjR,EANFiR,YACAosF,EAKEr9F,EALFq9F,OACAI,EAIEz9F,EAJFy9F,KAMF,MAAO,CACLzf,SAAU2O,EACVhzF,gBAAiB,CACf6iD,eALAx8C,EAHFqzB,eASEgkB,oBANAr3C,EAFFs3C,oBASEnkB,kBAPAnzB,EADF09F,mBASED,OACAzrF,KAAMza,EACN0Z,cACAsV,QAASg3E,EAAsBF,GAC/BM,sBAAuB1lG,KAiG3B2lG,cAtFoB,SAAAC,GAAqB,IAOnB7f,EANd1/E,EAA6Bu/F,EAA7Bv/F,QAAS3E,EAAoBkkG,EAApBlkG,gBACXgsB,EACJk4E,EAAkB3tB,UAClB2tB,EAAkB7f,UAClBrkF,EAAgBu2E,SAIlB,GAFsB8N,EAEHr4D,GAFe42E,EAAgBh5F,SAASy6E,GAGzD,MAAM,IAAIx0F,MAAM,sBAVuB,MAiBrCkzG,EAAep+F,GAHjB+0B,EAduC,EAcvCA,eACAikB,EAfuC,EAevCA,oBACAnkB,EAhBuC,EAgBvCA,kBAMF,MAHe,GACR1sC,KAAKkT,EAAgB4sB,SAErB,CACLtuB,GAAI0B,EAAgBgkG,sBACpBtqE,eAAgBA,EAChBikB,sBACAomD,mBAAoBvqE,EACpB57B,MAAOoC,EAAgBqY,KACvBf,YAAatX,EAAgBsX,YAC7BwsF,KAAM9jG,EAAgB8jG,KACtBK,KACEnkG,EAAgBsxE,aAChBtxE,EAAgBsxE,YACb6yB,KACL90G,KAAM2zG,EAA0Bh3E,GAChC03E,OAAQD,EAAsBzjG,EAAgB4sB,aCnF9ClxB,EAAQ,CACZ45F,yBAA0B,KAC1B8O,wCAAyC,IA+C5B,OACb1oG,QACA2oG,QAAS,CACPC,oCAdJ,SAAgD3/F,GAC9C,IACQ4/F,EADeh7E,IAAYkB,kBAAkB9lB,GAC7C4/F,KAER,OAAI7oG,EAAM0oG,wCAAwCG,GACzC7oG,EAAM0oG,wCAAwCG,GAGhD,CAAEC,0BAA2B,MAQpCC,QAAS,CACPH,oCAlDJ,SACE3/F,EACA6/F,GAEA,IADAE,EACA,uDADc,EAGNH,EADeh7E,IAAYkB,kBAAkB9lB,GAC7C4/F,KAER7oG,EAAM0oG,wCAAwCG,GAAQ,CACpDC,4BACAE,gBAyCAC,yCArCJ,SACEhgG,EACA2wF,GAEA,IACQiP,EADeh7E,IAAYkB,kBAAkB9lB,GAC7C4/F,KAEFK,EACJlpG,EAAM0oG,wCAAwCG,GAEhD,GAAIK,EAA+B,CACjC,IAAMF,EAAcE,EAA8BJ,0BAA0BnxF,WAC1E,SAAAwxF,GAAI,OAAIA,IAASvP,KAGnBsP,EAA8BF,YAAcA,M,qgCCpBjC,SAASn/C,EAAT,GAAkD,IAAlCouC,EAAkC,EAAlCA,gBAAiBrmB,EAAiB,EAAjBA,cAAiB,EACfqmB,EAAgBvM,SAAxDvmD,EADuD,EACvDA,gBAAiBC,EADsC,EACtCA,mBAEzB25D,IAAQqK,SAAS,SAAUC,IAAYC,GAEvC,IAAMC,EAAkB,SAACj5G,EAAMwD,EAAOyS,GACpC,GAAI4+B,EACF,IAAIkK,EAAWlK,EAAgBtuC,OAAO,CACpCk5C,YAAY,EACZE,aAAa,EACbhF,QAAS7wB,IAAaovF,YACtBC,iBAAiB,EACjBp5D,aAAa,EACbnF,aAAc,CACZ9gC,MAAO,wBACPlI,MAAO,YACPoC,gBAAiBhU,EAAO,CAAEsrB,YAAatrB,EAAKqsB,MAAS,GACrD7L,QAAS,kBAAMq0B,EAAgBmK,QAAQ,CAAE1sC,GAAIysC,KAC7C30B,SAAU,SAAAlkB,GACR+P,EAAS/P,GACT2uC,EAAgBmK,QAAQ,CAAE1sC,GAAIysC,SAQtCq6D,EAME93B,EANF83B,cA5B6D,EAkC3D93B,EALFk1B,qBA7B6D,MA6B7C,CACdC,oBAAqB4C,IACrB3C,sBAAsB,EACtBC,wBAAyB,IAhCkC,EAmCzDn5E,EAAmB8B,IAAK/B,YAAYC,iBAE1CD,IAAYo7C,SAAS2gC,YACnB97E,EAAiB13B,IAAIW,KAAK+2B,GAC1B,MAUF+7E,EAAqB,KANQH,GAAiB,CAC5CI,uBAAuB,EACvBC,gBAAgB,EAChBC,qBAAqB,GAGH,GAA+BlD,IAEnD,IAAMmD,EAAqB,CACzBC,MAAO,CAACnL,IAAQoL,kBAAmBpL,IAAQqL,oBAC3CC,YAAa,CACXtL,IAAQuL,kBACRvL,IAAQwL,kBACRxL,IAAQyL,WACRzL,IAAQ0L,UACR1L,IAAQ2L,gBACR3L,IAAQ4L,kBACR5L,IAAQ6L,cACR7L,IAAQ8L,kBAEVC,MAAO,CACL/L,IAAQgM,QACRhM,IAAQiM,SACRjM,IAAQkM,SACRlM,IAAQmM,eACRnM,IAAQoM,YACRpM,IAAQqM,gBACRrM,IAAQsM,0BACRtM,IAAQuM,cAIRx0B,EAAQ,GACZ/lF,OAAO4c,KAAKs8F,GAAoBh8F,SAAQ,SAAAs9F,GAAU,OAChDz0B,EAAM1lF,KAAN,MAAA0lF,EAAK,EAASmzB,EAAmBsB,QAInCC,EAAkCpmE,GAGlC,IAAMqmE,EAAsB,CAC1B5D,cAAe,CACbj2B,cAAe,CACb85B,gBAAiB,SAACnlG,EAAUolG,GAAX,OACfpC,EAAgB,KAAMoC,EAAcplG,IACtCqlG,mBAAoB,SAACt7G,EAAMq7G,EAAcplG,GAArB,OAClBgjG,EAAgBj5G,EAAMq7G,EAAcplG,OAsC5CuwE,EAAM7oE,SAAQ,SAAAqiB,GACZ,IAAMq4D,EAAWr4D,EAAK96B,KAAK+d,QAAQ,OAAQ,IAErCs4F,GADsBj6B,EAAckF,OAAS,IACL6R,IAAa,GACrDmjB,EAAoBL,EAAoB9iB,IAAa,GACrDxpF,EAAQ4sG,IACZD,EAtCmB,SAAC3sG,EAAOmxB,GAAS,IAIhC07E,EAHkB/B,EAAhBI,YAGqCx8D,QAC3C,SAAAvd,GAAI,OAAK,CAAC,mBAAoB,qBAAqBpiB,SAASoiB,EAAK96B,SAG/Dy2G,EAAc,KAAK9sG,GAoBvB,OAVgC,IAA9ByyE,EAAcs6B,aACdF,EAAyB99F,SAASoiB,KAE9BnxB,EAAMyyE,cACRq6B,EAAYr6B,cAAcu6B,oBAAqB,EAE/CF,EAAYr6B,cAAgB,CAAEu6B,oBAAoB,IAI/CF,EAWLG,CAAeP,EAAmBv7E,IAEpCyuE,IAAQsN,QAAQ/7E,EAAMnxB,MAIxB,IAAMmtG,EAAqBvN,IAAQwN,eAAe,2BAClDz1B,EAAM7oE,SAAQ,SAAAqiB,GACZ,GAAIA,EAAKt/B,qBAAqBs7G,EAAoB,CAEhD,IAAM3jB,GAAW,IAAIr4D,GAAO96B,KAC5BupG,IAAQyN,eAAe7jB,OAI3BoW,IAAQ0N,cAAc,MAAO,CAAEC,gBAAiB,IAChD3N,IAAQ0N,cAAc,OAAQ,CAAEC,gBAAiB,IACjD3N,IAAQ0N,cAAc,OAAQ,CAAEC,gBAAiB,IACjD3N,IAAQ0N,cAAc,wBAAyB,IAC/C1N,IAAQ0N,cAAc,gBAAiB,CAAEE,SAAU,IACnD5N,IAAQ0N,cAAc,iBAAkB,IACxC1N,IAAQ6N,eAAe,UAAW,IAGpC,IA4BMpB,EAAoC,SAAApE,GACxC,IAAMyF,EA7BwB,SAAAzF,GAAsB,MAEZD,EACtCC,GADMe,EAF4C,EAE5CA,aAAcI,EAF8B,EAE9BA,cAGhBsE,EAA+BzF,EAAmB0F,aACtD,mBACA,KAIIC,EAAmB,CACvBC,UAAW5F,EAAmBG,YAAYC,SAC1CQ,OAAQ,GAYV,OARAZ,EAAmB6F,WACjBJ,EACA,SACAE,EACA5E,EACAI,GAGKsE,EAI8BK,CACnC9F,GAGI+F,EAGFN,EAHFjqG,GACAwqG,EAEEP,EAFFO,YACAC,EACER,EADFQ,cAIFx/E,IAAYm6C,OAAOz+D,iBACjBskB,IAAY4f,OAAO6/D,iBACnB,SAAAx5G,GAAS,MAIHszG,EAAmB35D,OAFrB8/D,EAFK,EAELA,kBACAC,EAHK,EAGLA,oBAGFpG,EAAmB55D,UACjB+/D,GACA,YAA6B,IAA1BE,EAA0B,EAA1BA,OAAQ9iG,EAAkB,EAAlBA,YACT,IAAK,CAACwiG,GAAUj/F,SAASu/F,EAAO7qG,IAAK,CACnC,IAAMo+F,EAAaqM,EAAc,SAAU1iG,EAAY/H,IAEvDxL,QAAQK,IACN,uDACAkT,GAEFvT,QAAQK,IAAI,qBAAsBupG,OAKxCoG,EAAmB55D,UACjBggE,GACA,YAA6B,IAA1BC,EAA0B,EAA1BA,OAAQ9iG,EAAkB,EAAlBA,YACT,IAAK,CAACwiG,GAAUj/F,SAASu/F,EAAO7qG,IAAK,CACnC,IAAMo+F,EAAaqM,EAAc,SAAU1iG,EAAY/H,IAEvDxL,QAAQK,IACN,yDACAkT,GAEFvT,QAAQK,IAAI,qBAAsBupG,OAKxC,IAeM0M,EAA0B,SAAC9qG,EAAI4lG,GAAsB,IACjDlkG,EAAoBkkG,EAApBlkG,gBACRvT,OAAOqhC,OAAO9tB,EAAiB,CAAEgkG,sBAAuB1lG,KAG1D,CACEm8F,IAAQtxD,OAAO8/D,kBACfxO,IAAQtxD,OAAOkgE,sBACf1/F,SAAQ,SAAA2/F,GACR95G,EAAM8jB,OAAO3O,QAAQM,iBACnBqkG,GACA,YAAmC,IAAxBpF,EAAwB,EAAhC5wF,OACDxgB,QAAQK,IAAR,qCAA0Cm2G,IA3BjB,SAAApF,GAC7B,IAAI,IACM7f,EAAwC6f,EAAxC7f,SAAU9N,EAA8B2tB,EAA9B3tB,SAAUv2E,EAAoBkkG,EAApBlkG,gBACtBupG,EAASllB,GAAYrkF,EAAgBu2E,UAAYA,EACvD2tB,EAAkB5lG,GAAK0B,EAAgBgkG,sBACvC,IAAMwF,EAAuBV,EAAYS,EAAQrF,GAE5ClkG,EAAgBgkG,uBACnBoF,EAAwBI,EAAsBtF,GAEhD,MAAOtzG,GACPkC,QAAQM,KAAK,uCAAwCxC,IAiBnD64G,CAAuBvF,a,SCtR3BzpE,EAAc8F,IAAMk+D,QAApBhkE,UAmBOivE,EAZc,WAC3B,IAMM7hE,EAASpN,EANA,CACbF,QAAS,EACTC,WAAY,EACZhH,UAAW,CAAC,CAAEw4B,OAAQ,kBAKxBh5D,OAAO2mE,MAAMG,SAASjyB,I,iBCJlB8hE,EAAkC,SAAC,GAAqC,IAAnCn9F,EAAmC,EAAnCA,QAASslF,EAA0B,EAA1BA,oBAC5C8X,EAAuBn/E,YAAkBqnE,GA6G/C,OACE,kBAAC,IAAD,CACEtlF,QAASA,EACTQ,YArHe,IAsHfC,YApHmB,IAqHnBF,YAtHe,IAuHfG,YAAa,qBACbX,eAAgBq9F,EAChBl9F,eAnHmB,SAAAqB,GACjBA,GACFwb,IAAYsgF,OAAO97F,IAkHnBpB,gBA9GoB,SAAAoB,GAClBA,GACFwb,IAAYugF,QAAQ/7F,IA6GpBtB,sBAzG0B,SAACsB,EAAiBK,EAAgBf,GAAlC,OAC5B,IAAIhf,SAAQ,SAAAC,GACVi7B,IAAYwgF,YAAYh8F,GAExBA,EAAgB9I,iBACd,4BACA,SAAS+kG,EAAex6G,GACtB,IAAMg7B,EAAiBjB,IAAYkB,kBAAkBj7B,EAAME,QACxDiV,QACGtV,EAAO,SAAWge,EAClB2C,EAAU5B,EAAe67F,UAAU56G,EAAM,GAE3C66G,EAAW1/E,EAAehoB,aAC1B2nG,EAAY3/E,EAAe7mB,YAE/B,GAAIumG,EAjCO,KAiCoBC,EAjCpB,IAiC8C,CACvD,IAAMC,EAlCG,IAkCyB/6F,KAAKtD,IAAIm+F,EAAUC,GACrDA,GAAaC,EACbF,GAAYE,EAGd97G,EAAQ,CAAE0hB,UAAStT,MAAOwtG,EAAUvtG,OAAQwtG,IAE5Cp8F,EAAgB7I,oBACd,2BACA8kG,UAiFNn9F,UA3Ec,SAACN,EAAgBwB,EAAiBrR,EAAOC,GAAzC,OAChB,IAAItO,SAAQ,SAAAC,GACV,GAAIie,GAAkBwB,EAAiB,CACrC,IAAMyc,EAAiBjB,IAAYkB,kBAAkBle,GAC/CsnB,EAAWpnC,OAAOqhC,OAAO,GAAItD,EAAeqJ,iBAC3CA,EAASw2E,MAChBx2E,EAASy2E,YAAc,CACrBznG,EAAG,EACHE,EAAG,GAGLwmB,IAAY1c,UAAU2d,EAAeY,MAAM8O,SAAShqC,MAAK,SAAAk7B,GACvD7B,IAAYghF,aAAax8F,EAAiBqd,GAC1C7B,IAAYihF,YAAYz8F,EAAiB8lB,GACzCtK,IAAYkhF,OAAO18F,GAAiB,GAEpC,IAAMm8F,EAAW76F,KAAKxD,IAAInP,GAAS0uB,EAAM1uB,MAhE1B,KAiETytG,EAAY96F,KAAKxD,IAAIlP,GAAUyuB,EAAMzuB,OAjE5B,KAmEfrO,EAAQ,CAAE88B,QAAO1uB,MAAOwtG,EAAUvtG,OAAQwtG,YAyD9Cv9F,kBApDsB,SAAC89F,EAAQ38F,GACjC6b,IAAiB+vC,MAAMj+D,MAAM82E,MAAM7oE,SAAQ,YAAc,IAAXzY,EAAW,EAAXA,KACxCw5G,EACF9gF,IAAiB+gF,yBAAyB58F,EAAiB7c,GAE3D04B,IAAiBghF,0BAA0B78F,EAAiB7c,OAgD9D4b,aA3CiB,SACnBK,EACAE,EACAU,EACAK,GAEA,IAAMy8F,EAAO,GAAH,OAAM19F,EAAN,YAAkBE,GACtBy9F,EAAW,SAAH,OAAYz9F,GAG1B,GAAIe,EAAe28F,UAAyB,SAAb19F,EAAqB,CAClD,IAAM+d,EAAQhd,EAAe67F,UAAUa,EAAU,GAC3CxuC,EAAOh8B,IAAMy7B,UACjB3wC,EAAMnc,QAAQ,0BAA2B,IACzC67F,GAEF,OAAO93G,OAAOwzB,UAAUwkF,WAAW1uC,EAAMuuC,GAG3C98F,EAAgB68B,cAAc,UAAUqgE,QAAO,SAAA3uC,GAC7C,IAAM4uC,EAASl4G,OAAOm4G,KAAOn4G,OAAOo4G,UAC9B3+E,EAAI79B,SAASQ,cAAc,KACjCq9B,EAAEj+B,KAAO08G,EAAOG,gBAAgB/uC,GAChC7vC,EAAE6+E,SAAWT,EACbj8G,SAAS6U,KAAKxT,YAAYw8B,GAC1BA,EAAE8+E,QACF38G,SAAS6U,KAAKzT,YAAYy8B,UAsBhCk9E,EAAgCtrG,UAAY,CAC1CmO,QAASxP,IAAUI,KACnB00F,oBAAqB90F,IAAUC,OAAOC,YAGzBysG,QC5IT6B,EAAS5hF,IAAiB6hF,OAAO,eAE/BhvC,EAAyBnxC,IAAKgV,MAA9Bm8B,qBACA9gC,EAA4BrQ,IAAKiV,MAAMk+D,QAAvC9iE,wBAEF4nD,EAA8B,WAClCh6D,IAAY8uD,qBAAqB1uE,SAAQ,SAAA6gB,GACnCA,EAAeY,OACjB7B,IAAY+uD,YAAY9tD,EAAe7lB,aAqZ9B+mG,EAhZQ,SAAC,GAAwB,IAAtB/X,EAAsB,EAAtBA,gBAClB8K,EAAU,CACdkN,eAAgB,YAA6B,IAA1Bn4E,EAA0B,EAA1BA,UAAWo4E,EAAe,EAAfA,SACtBphF,EAAiBC,YAAkB+I,EAAUs+D,qBAEnD,GAAItnE,EAAgB,CAClB,IAAIqJ,EAAWtK,IAAYy6D,YAAYx5D,GACvCqJ,EAAS+3E,UAAYA,EACrBriF,IAAYihF,YAAYhgF,EAAgBqJ,KAG5Cg4E,uBAAwB,YAAmB,IAAhBr4E,EAAgB,EAAhBA,UACnBhJ,EAAiBC,YAAkB+I,EAAUs+D,qBAEnD,GAAItnE,EAAgB,CAClB,IAAIqJ,EAAWtK,IAAYy6D,YAAYx5D,GACvCqJ,EAASi4E,OAASj4E,EAASi4E,MAC3BviF,IAAYihF,YAAYhgF,EAAgBqJ,KAG5Ck4E,qBAAsB,YAAmB,IAAhBv4E,EAAgB,EAAhBA,UACjBhJ,EAAiBC,YAAkB+I,EAAUs+D,qBAEnD,GAAItnE,EAAgB,CAClB,IAAIqJ,EAAWtK,IAAYy6D,YAAYx5D,GACvCqJ,EAASm4E,OAASn4E,EAASm4E,MAC3BziF,IAAYihF,YAAYhgF,EAAgBqJ,KAG5Co4E,cAAe,YAA8B,IAA3B7tF,EAA2B,EAA3BA,UAAWoV,EAAgB,EAAhBA,UACrBhJ,EAAiBC,YAAkB+I,EAAUs+D,qBAC7C7lF,EAAmB,IAAZmS,EAEb,GAAIoM,EACF,GAAIve,EAAM,CACR,IAAI4nB,EAAWtK,IAAYy6D,YAAYx5D,GACvCqJ,EAASw2E,OAASp+F,EAClBsd,IAAYihF,YAAYhgF,EAAgBqJ,QAExCtK,IAAYwgF,YAAYv/E,IAI9B0hF,cAAe,YAAmB,IAAhB14E,EAAgB,EAAhBA,UACVhJ,EAAiBC,YAAkB+I,EAAUs+D,qBAE/CtnE,GACFjB,IAAYsM,MAAMrL,IAGtB2hF,eAAgB,YAAmB,IAAhB34E,EAAgB,EAAhBA,UACXhJ,EAAiBC,YAAkB+I,EAAUs+D,qBAEnD,GAAItnE,EAAgB,CAClB,IAAIqJ,EAAWtK,IAAYy6D,YAAYx5D,GACvCqJ,EAASu4E,QAAUv4E,EAASu4E,OAC5B7iF,IAAYihF,YAAYhgF,EAAgBqJ,KAK5Cs0E,cAAe,YAAkB,IAAf9jB,EAAe,EAAfA,SACXA,GACHvxF,QAAQM,KAAK,iDAEfw2B,IAAiBu+E,cAAc9jB,EAAU,CAAE+jB,gBAAiB,KAE9DiE,iBAAkB,YAAmB,IAAhB74E,EAAgB,EAAhBA,UACb7uB,EAAU8lB,YAAkB+I,EAAUs+D,qBAC5C,GAAKntF,EAAL,CAIA,IAAM6lB,EAAiBjB,IAAYkB,kBAAkB9lB,GACrD,GAAK6lB,GAAmBA,EAAeY,MAAvC,CAPmC,IAYjC6rD,EACErtD,IAAiBstD,sCADnBD,UAEF,GACGA,IAC0D,IAA3DA,EAAUtqF,eAAe69B,EAAeY,MAAM8O,SAFhD,CAOA,IAAM+gE,EAAmBhkB,EAAUzsD,EAAeY,MAAM8O,SAElDoyE,EAAuB,GAE7B7/G,OAAO4c,KAAK4xF,GAAkBtxF,SAAQ,SAAA4sE,GACnB0kB,EAAiB1kB,GAA1BvqF,KAEH2d,SAAQ,SAAA3J,GAAmB,IAE5Bu3E,EAGEv3E,EAHFu3E,IACAjF,EAEEtyE,EAFFsyE,mBACAxxE,EACEd,EADFc,kBAEGy2E,GAIL+0B,EAAqBx/G,KAAK,CACxBypF,WACAgB,MACAjF,qBACAxxE,4BAKNwrG,EAAqB3iG,SAAQ,SAAA3J,GAC3BsrB,IAAKllB,aAAak+E,oBAAoBQ,UAAU,CAC9CxxE,OAAQ,CACNijE,SAAUv2E,EAAgBu2E,SAC1Bv2E,4BAKRusG,UAAW,YAAmB,IAAhB/4E,EAAgB,EAAhBA,UACNhJ,EAAiBC,YAAkB+I,EAAUs+D,qBACnD0Z,EAAOhhF,EAAgB,IAEzBgiF,cAAe,YAAmB,IAAhBh5E,EAAgB,EAAhBA,UACVhJ,EAAiBC,YAAkB+I,EAAUs+D,qBACnD0Z,EAAOhhF,GAAiB,IAE1BiiF,gCAAiC,YAAmB,IAAhBj5E,EAAgB,EAAhBA,UAElC,OADuB/I,YAAkB+I,EAAUs+D,sBAGrD4a,0BAA2B,YAA0B,IAAvB5mG,EAAuB,EAAvBA,MACtBgsF,EAD6C,EAAhBt+D,UACGs+D,oBAC9BlxD,EAAmB+yD,EAAgBvM,SAAnCxmD,eACJA,GACFA,EAAeoG,KAAK,CAClBL,QAASgjE,EACT7jG,QACA8gC,aAAc,CACZkrD,sBACAtlF,QAASo0B,EAAeqG,SAKhC0lE,kCApJc,YAyJX,IAJDp2B,EAIC,EAJDA,SACAz1E,EAGC,EAHDA,kBACA2W,EAEC,EAFDA,SACAH,EACC,EADDA,YAGMiqE,EAAiBj2D,IAAKllB,aAAaswE,eAAejD,SACnC8N,EAAe/O,MAAM+D,GAAUhtC,QAClD,SAAAh4C,GAAC,OAAIA,EAAEuP,oBAAsBA,KAGlB6I,SAAQ,SAAAtD,GACnBA,EAAYoR,SAAWA,EACvBpR,EAAYiR,YAAcA,EAE1BiqE,EAAewC,kBAAkB19E,EAAYkwE,SAAUlwE,MAGzDk7E,EAAenJ,8BAEfmL,KAEFqpB,kBA3Kc,YA2KwD,IAAlDjoG,EAAkD,EAAlDA,QAASkoG,EAAyC,EAAzCA,kBAAmBC,EAAsB,EAAtBA,mBACxCC,EAAa,GACfC,GAAgB,EAiDpB,OA/CAF,EAAmBnjG,SAAQ,SAAA4sE,GACzB,IAAM02B,EAAkBrjF,IAAiBsjF,aACvCvoG,EACA4xE,GAGF,GAAK02B,EAoCL,OAhCAA,EAAgBjhH,KAAK2d,SAAQ,SAACguE,EAAUz2E,GACtC,IAAIisG,EAAsBvjF,IAAiBwjF,kBACzCzoG,EACA4xE,GAGG42B,IACHA,EAAsBvjF,IAAiBwjF,kBACrCzoG,EADoB,UAEjB4xE,EAFiB,UAMnB42B,EAMHA,EAAoBH,cAClBroG,EACAgzE,EACAk1B,KAGFG,GAAgB,EAChBD,EAAW/gF,KAAO2rD,EAClBo1B,EAAW7rG,MAAQA,EACnB6rG,EAAWx2B,SAAWA,GAdtBzjF,QAAQM,KAAK,uBAkBb45G,QAAJ,KAKKA,EAAgBD,OAAa57G,GAEtCk8G,gBAAiB,YAAiC,IAA9B1oG,EAA8B,EAA9BA,QAAS4xE,EAAqB,EAArBA,SAAUvqD,EAAW,EAAXA,KACrCpC,IAAiByjF,gBAAgB1oG,EAAS4xE,EAAUvqD,GACpDzC,IAAY+uD,YAAY3zE,IAE1B+kG,qBAAsB,WACpBA,KAEF4D,eAAgB,YAAkC,IAA/B95E,EAA+B,EAA/BA,UAAWxgC,EAAoB,EAApBA,OAAQswC,EAAY,EAAZA,MAC9B9Y,EAAiBC,YAAkB+I,EAAUs+D,qBAEnD,GAAItnE,EAAgB,CAClB,IAAIqJ,EAAWtK,IAAYy6D,YAAYx5D,GAEvCqJ,EAAS05E,IAAM,CACbptD,YAAajH,OAAOlmD,GACpBktD,aAAchH,OAAO5V,IAEvB/Z,IAAYihF,YAAYhgF,EAAgBqJ,KAG5C25E,YAAa,YAMP,IALJp8F,EAKI,EALJA,iBACAsoB,EAII,EAJJA,eACA+8C,EAGI,EAHJA,WACAqb,EAEI,EAFJA,oBAEI,IADJ2b,wBACI,SAGE3zE,EAFQ2iC,EAAqB3qE,IAAIsf,GAEd2oB,gBAAe,SAAAmwB,GACtC,OACEA,EAAGlwB,QACHkwB,EAAGlwB,OAAOjoB,MAAK,SAAAzlB,GAAC,OAAIA,EAAE+sC,sBAAwBK,QAI7CI,IAILA,EAAWJ,eAAiBA,EAC5BI,EAAW28C,WAAaA,EAExBzjF,OAAO2mE,MAAMG,SACXn+B,EAAwBm2D,EAAqBh4D,IAG3C2zE,GACFlqB,OAwHN,MAAO,CACLkb,UACA7d,YArHkB,CAClB4sB,YAAa,CACXna,UAAWoL,EAAQ+O,YACnBla,cAAe,GACf/iF,QAAS,IAEXq8F,kBAAmB,CACjBvZ,UAAWoL,EAAQmO,kBACnBtZ,cAAe,GACf/iF,QAAS,IAEX88F,gBAAiB,CACfha,UAAWoL,EAAQ4O,gBACnB/Z,cAAe,GACf/iF,QAAS,IAEXo8F,kCAAmC,CACjCtZ,UAAWoL,EAAQkO,kCACnBrZ,cAAe,GACf/iF,QAAS,IAEXm8F,0BAA2B,CACzBrZ,UAAWoL,EAAQiO,0BACnBpZ,cAAe,CAAC,aAChB/iF,QAAS,IAEXk8F,gCAAiC,CAC/BpZ,UAAWoL,EAAQgO,gCACnBnZ,cAAe,CAAC,aAChB/iF,QAAS,IAEXm9F,iBAAkB,CAChBra,UAAWoL,EAAQkN,eACnBrY,cAAe,CAAC,aAChB/iF,QAAS,CAAEq7F,SAAU,KAEvB+B,kBAAmB,CACjBta,UAAWoL,EAAQkN,eACnBrY,cAAe,CAAC,aAChB/iF,QAAS,CAAEq7F,UAAW,KAExBO,eAAgB,CACd9Y,UAAWoL,EAAQ0N,eACnB7Y,cAAe,CAAC,aAChB/iF,QAAS,IAEXw7F,qBAAsB,CACpB1Y,UAAWoL,EAAQsN,qBACnBzY,cAAe,CAAC,aAChB/iF,QAAS,IAEXs7F,uBAAwB,CACtBxY,UAAWoL,EAAQoN,uBACnBvY,cAAe,CAAC,aAChB/iF,QAAS,IAEXq9F,gBAAiB,CACfva,UAAWoL,EAAQwN,cACnB3Y,cAAe,CAAC,aAChB/iF,QAAS,CAAE6N,UAAW,IAExByvF,kBAAmB,CACjBxa,UAAWoL,EAAQwN,cACnB3Y,cAAe,CAAC,aAChB/iF,QAAS,CAAE6N,WAAY,IAEzB0vF,oBAAqB,CACnBza,UAAWoL,EAAQwN,cACnB3Y,cAAe,CAAC,aAChB/iF,QAAS,CAAE6N,UAAW,IAExB8tF,cAAe,CACb7Y,UAAWoL,EAAQyN,cACnB5Y,cAAe,CAAC,aAChB/iF,QAAS,IAEX87F,iBAAkB,CAChBhZ,UAAWoL,EAAQ4N,iBACnB/Y,cAAe,CAAC,aAChB/iF,QAAS,IAEXg8F,UAAW,CACTlZ,UAAWoL,EAAQ8N,UACnBjZ,cAAe,CAAC,aAChB/iF,QAAS,IAEXi8F,cAAe,CACbnZ,UAAWoL,EAAQ+N,cACnBlZ,cAAe,CAAC,aAChB/iF,QAAS,IAGX43F,cAAe,CACb9U,UAAWoL,EAAQ0J,cACnB7U,cAAe,GACf/iF,QAAS,IAEXw9F,YAAa,CACX1a,UAAWoL,EAAQ0J,cACnB7U,cAAe,GACf/iF,QAAS,CAAE8zE,SAAU,SAEvBqlB,qBAAsB,CACpBrW,UAAWoL,EAAQiL,qBACnBpW,cAAe,GACf/iF,QAAS,GACTpO,QAAS,UAEXmrG,eAAgB,CACdja,UAAWoL,EAAQ6O,eACnBha,cAAe,CAAC,aAChB/iF,QAAS,KAOXy9F,eAAgB,iCC7YdC,EAAuB,CAC3BC,QAAS,UACTC,gBAAiB,gBACjBC,SAAU,WAGNC,EAA2B,CAC/BC,KAAM,OACNC,qBAAsB,wBAsNT,GACb3tB,YA9MkB,CAClB,CACEtiF,GAAI,cACJV,MAAO,eACPL,KAAM,OAENlO,KAAM4+G,EAAqBE,gBAC3Bpb,YAAa,gBACbyb,eAAgB,CAAEnqB,SAAU,gBAE9B,CACE/lF,GAAI,OACJV,MAAO,OACPL,KAAM,cAENlO,KAAM4+G,EAAqBE,gBAC3Bpb,YAAa,gBACbyb,eAAgB,CAAEnqB,SAAU,SAE9B,CACE/lF,GAAI,OACJV,MAAO,SACPL,KAAM,QAENlO,KAAM4+G,EAAqBE,gBAC3Bpb,YAAa,gBACbyb,eAAgB,CAAEnqB,SAAU,SAE9B,CACE/lF,GAAI,MACJV,MAAO,MACPL,KAAM,SAENlO,KAAM4+G,EAAqBE,gBAC3Bpb,YAAa,gBACbyb,eAAgB,CAAEnqB,SAAU,QAE9B,CACE/lF,GAAI,SACJV,MAAO,SACPL,KAAM,eAENlO,KAAM4+G,EAAqBE,gBAC3Bpb,YAAa,gBACbyb,eAAgB,CAAEnqB,SAAU,WAE9B,CACE/lF,GAAI,gBACJV,MAAO,WACPL,KAAM,qBAENlO,KAAM4+G,EAAqBE,gBAC3Bpb,YAAa,gBACbyb,eAAgB,CAAEnqB,SAAU,kBAE9B,CACE/lF,GAAI,QACJV,MAAO,QACPL,KAAM,aAENlO,KAAM4+G,EAAqBE,gBAC3Bpb,YAAa,gBACbyb,eAAgB,CAAEnqB,SAAU,UAE9B,CACE/lF,GAAI,QACJV,MAAO,QACPL,KAAM,QAENlO,KAAM4+G,EAAqBC,QAC3Bnb,YAAa,iBAEf,CACEz0F,GAAI,OACJV,MAAO,OACPL,KAAM,UAENlO,KAAM4+G,EAAqBG,SAC3B79F,QAAS,CACPk+F,SAAUJ,EAAyBC,OAGvC,CACEhwG,GAAI,OACJV,MAAO,OACPL,KAAM,iBACNoW,QAAS,CACP,CACErV,GAAI,UACJV,MAAO,UACPL,KAAM,SAENlO,KAAM4+G,EAAqBE,gBAC3Bpb,YAAa,gBACbyb,eAAgB,CAAEnqB,SAAU,YAE9B,CACE/lF,GAAI,aACJV,MAAO,aACPL,KAAM,OAENlO,KAAM4+G,EAAqBE,gBAC3Bpb,YAAa,gBACbyb,eAAgB,CAAEnqB,SAAU,eAE9B,CACE/lF,GAAI,YACJV,MAAO,QACPL,KAAM,aAENlO,KAAM4+G,EAAqBE,gBAC3Bpb,YAAa,gBACbyb,eAAgB,CAAEnqB,SAAU,cAE9B,CACE/lF,GAAI,gBACJV,MAAO,UACPL,KAAM,WAENlO,KAAM4+G,EAAqBE,gBAC3Bpb,YAAa,gBACbyb,eAAgB,CAAEnqB,SAAU,kBAE9B,CACE/lF,GAAI,eACJV,MAAO,YACPL,KAAM,WAENlO,KAAM4+G,EAAqBE,gBAC3Bpb,YAAa,gBACbyb,eAAgB,CAAEnqB,SAAU,iBAE9B,CACE/lF,GAAI,SACJV,MAAO,SACPL,KAAM,SAENlO,KAAM4+G,EAAqBC,QAC3Bnb,YAAa,kBAEf,CACEz0F,GAAI,cACJV,MAAO,eACPL,KAAM,eAENlO,KAAM4+G,EAAqBC,QAC3Bnb,YAAa,oBAEf,CACEz0F,GAAI,QACJV,MAAO,SACPL,KAAM,YAENlO,KAAM4+G,EAAqBC,QAC3Bnb,YAAa,0BAEf,CACEz0F,GAAI,QACJV,MAAO,SACPL,KAAM,YAENlO,KAAM4+G,EAAqBC,QAC3Bnb,YAAa,wBAEf,CACEz0F,GAAI,QACJV,MAAO,QACPL,KAAM,QAENlO,KAAM4+G,EAAqBC,QAC3Bnb,YAAa,oBAEf,CACEz0F,GAAI,gBACJV,MAAO,gBACPL,KAAM,iBAENlO,KAAM4+G,EAAqBE,gBAC3Bpb,YAAa,gBACbyb,eAAgB,CAAEnqB,SAAU,kBAE9B,CACE/lF,GAAI,WACJV,MAAO,WACPL,KAAM,wBAENlO,KAAM4+G,EAAqBG,SAC3B79F,QAAS,CACPk+F,SAAUJ,EAAyBE,qBACnCG,WAAW,MAKnB,CACEpwG,GAAI,YACJV,MAAO,cACPL,KAAM,QAENlO,KAAM4+G,EAAqBC,QAC3Bnb,YAAa,uBACb5wF,QAAS,yBAMX6rG,eAAgB,gC,0NC5OlB,IAAMvuG,GAAYoiB,IAAM8sF,MAAK,WAC3B,OAAO,0DAGHC,GAA0B,SAAA/zG,GAC9B,OACE,kBAAC,IAAMg0G,SAAP,CAAgBn0D,SAAU,4CACxB,kBAAC,GAAc7/C,KAQN,IAIbyD,GAAI,cACJgJ,YAQAwnG,gBAba,YAa4C,IAAvCnb,EAAuC,EAAvCA,gBAAuC,IAAtBrmB,cACjC/nB,EAAK,CAAEouC,kBAAiBrmB,mBAD+B,MAAN,GAAM,KAGzDyhC,kBAhBa,YAgBqC,IAA9Brb,EAA8B,EAA9BA,gBAAiBz+C,EAAa,EAAbA,UA0BnC,OAzBwC,SAAAp6C,GAMtC,IAMQkvE,EAAoB90B,EAApB80B,gBACFilC,EACJjlC,IAAoBA,EAAgBklC,QAEtC,OACE,kBAAC,GAAD,MACMp0G,EADN,CAEEq0G,WAbsB,SAAAC,GAExBA,EAAS1B,kBAAmB,EAC5B/Z,EAAgBoB,WAAW,cAAeqa,IAWxCH,uBAAwBA,OAOhCI,iBA5Ca,WA6CX,OAAOC,GAETC,kBA/Ca,YA+C0B,IAAnB3b,EAAmB,EAAnBA,gBAClB,OAAO+X,EAAe,CAAE/X,sB,oJCtEb,Y,iWCiBA,gBAASh6B,EAAO41C,GAC7B,GAAK51C,GAAU41C,EAAf,CAIA,IAAMC,E,kVAAW,IACZD,EADS,CAEZE,sBAAsB,EACtBC,4BAA4B,EAC5BC,sBAAsB,IAGlBC,EAAcC,4BAAkBL,GAItC,OAFAM,mBAASn2C,EAAOi2C,GAETA,IC/BLj6C,IAAc,EAEZo6C,GAAkB,E,mXCUhB/O,GAA2CzgE,IAA3CygE,SAAUK,GAAiC9gE,IAAjC8gE,aAAcM,GAAmBphE,IAAnBohE,eAC1BqO,GAAa,CAACC,MACdC,GAAmBl9G,OAAOm9G,sCAAwCC,KAExEpP,GAASqP,KAAOC,UAEhB,IAAMC,GAAcC,aAAgBxP,IAC9ByP,G,kVAAiB,IAClBpP,GAAaI,YADE,GAEfE,GAAeF,aAGhBzuG,OAAOk4B,SAAgD,IAAtCl4B,OAAOk4B,OAAOwlF,4BAC1BD,GAAe/2C,QAGxB,IAAMC,GAAQg3C,aACZJ,GACAE,GACAP,GAAiBU,KAAe,WAAf,EAAmBZ,MAKtCr2C,GAAMzwB,WAAU,WACdm4D,GAAaC,UAAU,CACrBnB,YAAaxmC,GAAMk3C,WAAW1Q,cAEhCwB,GAAeL,UAAU,CACvB5nC,QAASC,GAAMk3C,WAAWn3C,aAIfC,U,wVC5Cf,IAwIe+xC,GAxIQ,SAAC,GAAwB,IAAtBhY,EAAsB,EAAtBA,gBAAsB,EACenzD,IAAMk+D,QAA3DC,EADsC,EACtCA,kBAAmBG,EADmB,EACnBA,8BAErBJ,EAAU,CACdqS,qBAAsB,YAA8B,IAA3Bt9E,EAA2B,EAA3BA,UAAWpV,EAAgB,EAAhBA,UAC1Bwd,EAA8CpI,EAA9CoI,qBAAsBk2D,EAAwBt+D,EAAxBs+D,oBACxBif,EAAWtkH,OAAO4c,KAAKuyB,GAAsBpvC,OAAS,EAExDwkH,EAAWlf,EAAsB1zE,EAErC4yF,GADAA,EAAWA,EAAWD,EAAW,EAAIC,GACf,EAAID,EAAWC,EAErCr3C,GAAMG,SAAS4kC,EAAkBsS,KAEnCC,qBAAsB,YAA2B,IAAxBz9E,EAAwB,EAAxBA,UAAW/a,EAAa,EAAbA,OAAa,EACjCkhD,GAAMk3C,WACZ1Q,mBAFuC,MAEzB,GAFyB,IAI7CA,EAAYV,iBAAmBU,EAAYV,gBAAgBhnF,GADrDzlB,EAHuC,EAGvCA,OAAQswC,EAH+B,EAG/BA,MAGZtwC,GAAUswC,GACZowD,EAAgBoB,WAAW,iBAAkB,CAC3CthE,YACAxgC,SACAswC,WAIN4tE,yBAA0B,YAA8B,IAA3B19E,EAA2B,EAA3BA,UAAWpV,EAAgB,EAAhBA,UAEhC7R,E,kVADuB,IAAKinB,EAAUoI,sBAErBpI,EAAUs+D,qBAC3Bv5D,EAAgB+H,MAAMm8B,qBAAqB3qE,IAC/Cya,EAAe6E,kBAGjB,GAAKmnB,EAAL,CAIA,IAAMwxB,EAAiBxxB,EAAc8sC,iBAC/B8rC,EAAyBpnD,EAAe12C,WAC5C,SAAAymB,GAAU,OACRA,EAAWnoB,wBACXpF,EAAeoF,yBAEnB,KAAIw/F,EAAyB,GAA7B,CAIA,IACMC,EAAoBrnD,EADConD,EAAyB/yF,GAE/CgzF,GAILz3C,GAAMG,SAAS+kC,EAA8BuS,QA0EjD,MAAO,CACLxwB,YAvEkB,CAElBywB,wBAAyB,CACvBhe,UAAWoL,EAAQqS,qBACnBxd,cAAe,CAAC,aAChB/iF,QAAS,CAAE6N,UAAW,IAExBkzF,wBAAyB,CACvBje,UAAWoL,EAAQqS,qBACnBxd,cAAe,CAAC,aAChB/iF,QAAS,CAAE6N,WAAY,IAGzBmzF,mBAAoB,CAClBle,UAAWoL,EAAQwS,qBACnB3d,cAAe,CAAC,aAChB/iF,QAAS,CAAEkI,OAAQ,IAErB+4F,mBAAoB,CAClBne,UAAWoL,EAAQwS,qBACnB3d,cAAe,CAAC,aAChB/iF,QAAS,CAAEkI,OAAQ,IAErBg5F,mBAAoB,CAClBpe,UAAWoL,EAAQwS,qBACnB3d,cAAe,CAAC,aAChB/iF,QAAS,CAAEkI,OAAQ,IAErBi5F,mBAAoB,CAClBre,UAAWoL,EAAQwS,qBACnB3d,cAAe,CAAC,aAChB/iF,QAAS,CAAEkI,OAAQ,IAErBk5F,mBAAoB,CAClBte,UAAWoL,EAAQwS,qBACnB3d,cAAe,CAAC,aAChB/iF,QAAS,CAAEkI,OAAQ,IAErBm5F,mBAAoB,CAClBve,UAAWoL,EAAQwS,qBACnB3d,cAAe,CAAC,aAChB/iF,QAAS,CAAEkI,OAAQ,IAErBo5F,mBAAoB,CAClBxe,UAAWoL,EAAQwS,qBACnB3d,cAAe,CAAC,aAChB/iF,QAAS,CAAEkI,OAAQ,IAErBq5F,mBAAoB,CAClBze,UAAWoL,EAAQwS,qBACnB3d,cAAe,CAAC,aAChB/iF,QAAS,CAAEkI,OAAQ,IAErBs5F,mBAAoB,CAClB1e,UAAWoL,EAAQwS,qBACnB3d,cAAe,CAAC,aAChB/iF,QAAS,CAAEkI,OAAQ,IAErBu5F,uBAAwB,CACtB3e,UAAWoL,EAAQyS,yBACnB5d,cAAe,CAAC,aAChB/iF,QAAS,CAAE6N,UAAW,IAExB6zF,2BAA4B,CAC1B5e,UAAWoL,EAAQyS,yBACnB5d,cAAe,CAAC,aAChB/iF,QAAS,CAAE6N,WAAY,KAMzB4vF,eAAgB,WCrIL,IACb1vG,GAAI,0BACJ,cACE,OAAOtL,OAAOsU,SAEhBgoG,kBALa,YAK0B,IAAnB5b,EAAmB,EAAnBA,gBAClB,OAAOgY,GAAe,CAAEhY,sB,6BCNpBhd,G,OAAmBtwE,EAAnBswE,eACAja,GAAyBn8B,IAAzBm8B,qB,4VCKA9gC,GAA4BrQ,IAAKiV,MAAMk+D,QAAvC9iE,wBACA+6C,GAAmBprD,IAAKllB,aAAxBswE,eAqCR,SAASw7B,KAAyC,IAAtBlyG,EAAsB,uDAAJ,GAAI,EAEJA,EAApCyX,gBAFwC,MAE7B,GAF6B,IAEJzX,EAArBsX,mBAFyB,MAEX,GAFW,EAKhD,OAFeG,GAAYH,EAAc,KAAH,OAAQA,EAAR,KAAyB,KAF3C,MAetB,SAAS66F,GACPC,EACA1rG,EACAmqE,GAEA,IAAM7kF,EAAO,GAcb,OAZAomH,EAAsBzoG,SAAQ,SAAAtD,GAC5BK,EAAWiD,SAAQ,SAAAhD,GACjB,IAAM0rG,EAAW,CACflxG,YAAa,OAEXkF,EAAY4sE,cAAgBtsE,EAAUssE,cACxCo/B,EAASlxG,YAAc0vE,EAAgBxqE,IAEzCra,EAAKc,KAAKulH,SAIPrmH,EA4BT,SAASsmH,GAA+BC,EAAiB7rG,GACvD,IACMoxE,EADSxsD,IAAKllB,aAAaswE,eAAevI,mBACtBuE,iBACpBF,EAjFR,WAAsC,IAAjBsF,EAAiB,uDAAJ,GAC5BtF,EAAQ,GAGZ,OAFAsF,EAAWnuE,SAAQ,SAAA+mE,GAAS,OAAK8B,EAAQA,EAAMt5C,OAAOw3C,EAAU6B,eAEzDC,EA6EOggC,CAAY16B,GAEpB26B,EAAoB36B,EAAWr7E,KAAI,SAAAi0E,GACvC,MAAO,CACLlqE,UAAWkqE,EAAUx/E,KACrBioF,QAASzI,EAAUpyE,GACnB8H,aAAc,OAkElB,OA9DA3Z,OAAO4c,KAAKkpG,GAAiB5oG,SAAQ,SAAA+uE,GACnC,IAzGmB79E,EAyGb63G,EAAmBH,EAAgB75B,GACnC1sD,EAAOwmD,EAAMzgE,MAAK,SAAAia,GAAI,OAAIA,EAAK1tB,KAAOo6E,KACpC7H,EAAoB7kD,EAAKzb,QAAQqgE,iBAAjCC,gBAGF8hC,GA9Ga93G,EA8GmC,oBAAlB63G,EA7G1B10F,QAAO,SAACyO,EAAGC,GAErB,OADCD,EAAEC,EAAE7xB,IAAU4xB,EAAEC,EAAE7xB,KAAW,IAAI/N,KAAK4/B,GAChCD,IACN,KA4GDhgC,OAAO4c,KAAKspG,GAAqBhpG,SAAQ,SAAAipG,GACvC,IAzC6BvuB,EAC3BkY,EAwCI6V,EACJO,EAAoBC,GAChB5yG,EAAkBoyG,EAAsB,GAE5CtxG,EAIEd,EAJFc,kBACAwxE,EAGEtyE,EAHFsyE,mBACAiE,EAEEv2E,EAFFu2E,SACAr2E,EACEF,EADFE,WAEI2yG,EAAgB7yG,EAAgBu3E,IAV6B,GAxCtC8M,EAwDC9N,EArD3B,CACLt2E,cAHIs8F,EAAkB97D,KAAQ87D,gBAAgBlY,IAI9C5iF,aAAc86F,EAAkB,GAAK,mBACrCn7F,YAAam7F,EACT,GACA,CAAC,GAAD,OAAIlY,EAAJ,wCA6CApkF,EAbiE,EAajEA,YACAwB,EAdiE,EAcjEA,aACAL,EAfiE,EAejEA,YAII0xG,EAAmB,CACvBxsG,WAAYgsE,EACZ10E,MAAOs0G,GAAmBlyG,GAC1B6yG,gBACA/xG,oBACAwxE,qBACAiE,WACAt2E,cACAC,aACAuB,eACAL,cACA45E,eAAe,EACfhvF,KAAMmmH,GACJC,EACA1rG,EACAmqE,IAK0B4hC,EAAkB1gG,MAAK,SAAAwpE,GACnD,OAAOA,EAAMpC,UAAYntD,EAAK0kD,aAGVtqE,aAAatZ,KAAKgmH,SAK5CL,EAAkB9oG,SAAQ,SAAAopG,GACxBA,EAAG3sG,aAAa6W,MAAK,SAAC+1F,EAAIC,GAAL,OACnBD,EAAG1gC,mBAAqB2gC,EAAG3gC,mBAAqB,GAAK,QAIlDmgC,EAUT,SAASS,GAA6BxsG,GACpC,OAAKA,GAAeA,EAAWla,OAIxB,CACL,CACEoR,MAAO,cACPpL,IAAK,YACLoU,KAAMgR,KAAOlR,EAAW,GAAGysG,YAAYnjF,OAAO,eAPzC,GA4BX,IAuMeojF,GANmBC,aAjMV,SAAA33G,GAAS,IACvB8kG,EAA8B9kG,EAA9B8kG,iBAAkB9mC,EAAYh+D,EAAZg+D,QAClBhzD,EAA6B85F,EAA7B95F,WAAYN,EAAiBo6F,EAAjBp6F,aAEdR,EAdR,SAAyBg0D,GACvB,GAAmB,aAAfA,EACF,OAAO,WAGL,OAFuBtuC,IAAKllB,aAAaswE,eAAejD,SACzB6qB,qBAUdgV,CADA55C,EAAQA,QAAQ3nD,MAAK,SAAA0a,GAAC,OAAiB,IAAbA,EAAE/uB,UACCrO,MAElD,MAAO,CACLqX,WAAYwsG,GAA6BxsG,GACzCX,sBAAuBusG,GACrBlsG,EACAM,GAEF85F,iBAAkB9kG,EAAM8kG,iBACxBhtE,UAAW93B,EAAM83B,UACjB5tB,mBAIuB,SAACk0D,EAAUy5C,GACpC,MAAO,CACLC,gBAAiB,SAAChkH,EAAOwQ,EAAiByzG,GACxCjkH,EAAMkkH,UAEN,IAAM5hB,EACH2hB,GAAkBA,EAAe3hB,qBAAwB,EAEtDziD,EAAkB9lB,IAAY8uD,qBACpC,IAAKhpC,GAAmBA,EAAgB7iD,QAAUslG,EAChDxmE,IAAKn4B,IAAIvC,MAAM,0CADjB,CAP2D,IAYnD2lF,EAA4Bv2E,EAA5Bu2E,SAAUs8B,EAAkB7yG,EAAlB6yG,cACZ7mF,EAAO0qD,GAAejD,SAASjB,MAAM+D,GAAUxkE,MAAK,SAAA1L,GACxD,OAAOA,EAAYkxE,MAAQs7B,KAIvBc,EAAkBlnH,OAAOqhC,OAAO,GAAI9B,EAAM,CAAEvU,SAAU,OAExD87F,EAASnzG,WACXmzG,EAASnzG,UAAUuzG,KAGvBC,wBAAyB,SAACpkH,EAAOwQ,EAAiByzG,GAChDjkH,EAAMkkH,UAEN,IAAM5hB,EACH2hB,GAAkBA,EAAe3hB,qBAAwB,EAEtDziD,EAAkB9lB,IAAY8uD,qBACpC,IAAKhpC,GAAmBA,EAAgB7iD,QAAUslG,EAChDxmE,IAAKn4B,IAAIvC,MAAM,0CADjB,CAPmE,IAY3D2lF,EAA4Bv2E,EAA5Bu2E,SAAUs8B,EAAkB7yG,EAAlB6yG,cACZ7mF,EAAO0qD,GAAejD,SAASjB,MAAM+D,GAAUxkE,MAAK,SAAA1L,GACxD,OAAOA,EAAYkxE,MAAQs7B,KAGzBU,EAAS/yG,mBACX+yG,EAAS/yG,kBAAkBwrB,KAG/B6nF,sBAAuB,SACrB7zG,EACAyzG,EACAK,EACAvjG,IDtRS,SACbvQ,EACAyzG,EACAK,GAEA,IADAvjG,EACA,uDADU,CAAEwjG,+BAA+B,EAAO18B,aAAc,MAE1D38C,EAAe+4E,EAAe1hB,OAAOv+D,UAAUhnC,OAC/CwnH,EAAgBF,EAAsBptG,WAAWla,OAC/C4Z,EAA6B0tG,EAA7B1tG,aAAcM,EAAeotG,EAAfptG,WAChButG,EAAuB5kG,KAAKxD,IAAImoG,EAAet5E,GAC7C67C,EAAgCv2E,EAAhCu2E,SAAUz1E,EAAsBd,EAAtBc,kBAEdyP,EAAQwjG,+BACVrtG,EAAW4zB,UAOb,IAJA,IAAM45E,EAA2B9tG,EAAamwE,GAGxC49B,EAAuB,GAd7B,WAeS7nH,GAfT,IAgBU2mF,EAAgBvsE,EAAWpa,GAA3B2mF,YAEFmhC,EAAsBF,EAAyBniG,MAAK,SAAAokC,GACxD,OACEA,EAAM88B,cAAgBA,GACtB98B,EAAMr1C,oBAAsBA,KAIhC,IAAKszG,EAEH,OADAD,EAAqBrnH,KAAK,MAC1B,WAGF,IAAIuZ,EAAc+tG,EAEVpoF,EAAS0qD,GAAeU,qBAAqBb,GAA7CvqD,KACR,GAAIzb,EAAQ8mE,aACVhxE,EAAc+tG,EAAoB7jG,EAAQ8mE,mBACrC,GAAIh2E,MAAMC,QAAQ0qB,EAAKumD,YAAa,CACzC,IAAM//E,EAAMw5B,EAAKumD,WAAWxgE,MAAK,SAAAvf,GAAG,QAAM4hH,EAAoB5hH,MAC9D6T,EAAc+tG,EAAoB5hH,GAGpC2hH,EAAqBrnH,KAAKuZ,IAzBnB/Z,EAAI,EAAGA,EAAI2nH,EAAsB3nH,IAAK,EAAtCA,GAmCT,IAUMsvC,EAAuB,GAiC7B,OAhCAu4E,EAAqBxqG,SAAQ,SAAC3d,EAAM0rC,GAElC,GAAK1rC,EAAL,CAIA,IAAMgmB,EAAQyqD,GAAqB3qE,IAAI9F,EAAKolB,kBAC5C,IAAKY,EACH,MAAM,IAAIniB,MAAM,oBAGlB,IAAMiqC,EAAa9nB,EAAM+nB,gBAAe,SAAAD,GACtC,OAvBkC,SAACA,EAAYJ,GACjD,GAAKI,EAAWE,QAAWF,EAAWE,OAAOxtC,OAI7C,OAAOstC,EAAWE,OAAOjoB,MACvB,SAAAqZ,GAAK,OAAIA,EAAMiO,sBAAwBK,KAiBhC26E,CAA8Bv6E,EAAY9tC,EAAK0tC,mBAGxD,IAAKI,EACH,MAAM,IAAIjqC,MAAM,0BAGlBiqC,EAAWJ,eAAiB1tC,EAAK0tC,eAC7B1tC,EAAKyqF,aACP38C,EAAW28C,WAAazqF,EAAKyqF,YAG/B/+C,GACGA,EAAgB+7E,EAAe3hB,qBAAuBp3D,EACzDkB,EAAqB9uC,KAAK,CACxB4qC,gBACAoC,mBAIG,CACL8B,uBACAm2D,OAAQ,KCoLauiB,CACjBt0G,EACAyzG,EACAK,EACAh6C,EACAvpD,GAGSqrB,qBAAqBjyB,SAAQ,SAAAiyB,GAAwB,IACtDlE,EAA8BkE,EAA9BlE,cAAeoC,EAAe8B,EAAf9B,WAEvBggC,EAASn+B,GAAwBjE,EAAeoC,OAZ/C,IAeKy8C,EAAgCv2E,EAAhCu2E,SAAUz1E,EAAsBd,EAAtBc,kBACZygF,EAAiB7K,GAAejD,SAEtChnF,OAAO4c,KAAKk4E,EAAe/O,OAAO7oE,SAAQ,SAAA4sE,GACnBgL,EAAe/O,MAAM+D,GAE7B5sE,SAAQ,SAAAtD,GACnBA,EAAY3I,QAAS,QAII6jF,EAAe/O,MAAM+D,GAAUhtC,QAC1D,SAAAljC,GACE,OAAOA,EAAYvF,oBAAsBA,KAIxB6I,SAAQ,SAAA4qG,GAC3BA,EAAoB72G,QAAS,KAG/B6jF,EAAenJ,8BAEf7uD,IAAY8uD,qBAAqB1uE,SAAQ,SAAA6gB,GACnCA,EAAeY,OACjB7B,IAAY+uD,YAAY9tD,EAAe7lB,iBAqB9B,SAAC6vG,EAAgBC,EAAmBlB,GAIrD,O,kVAAA,EACE7sG,WAJ0D8tG,EAApD9tG,WAKNd,aAL0D4uG,EAAxC5uG,aAMlBG,sBAN0DyuG,EAA1BzuG,sBAOhCF,eANoD0tG,EAA9C1tG,eAONM,0BAPoDotG,EAA9BptG,2BAQnBsuG,EANL,CAOEz1G,YAAa,SAACxP,EAAOwQ,GAKnB,IAAMyzG,EAAiBe,EAAehhF,UAChCsgF,EAAwBU,EAAehU,iBAS7CiU,EAAkBZ,sBAChB7zG,EACAyzG,EACAK,EARc,CACdC,+BAA+B,EAC/B18B,aAAc,QAUlB92E,eAAgB,SAAC/Q,EAAOwQ,GACtB,IAAMyzG,EAAiBe,EAAehhF,UACtCihF,EAAkBjB,gBAAgBhkH,EAAOwQ,EAAiByzG,IAE5D/yG,uBAAwB,SAAClR,EAAOwQ,GAC9B,IAAMyzG,EAAiBe,EAAehhF,UACtCihF,EAAkBb,wBAChBpkH,EACAwQ,EACAyzG,IAGJ5yG,cAAe,SAACrR,EAAOwQ,GACWsrB,IAAKllB,aAA7Bk+E,oBAEYQ,UAAU,CAC5BxxE,OAAQ,CACNijE,SAAUv2E,EAAgBu2E,SAC1Bv2E,gBAAiB,CACfu3E,IAAKv3E,EAAgB6yG,cACrBvgC,mBAAoBtyE,EAAgBsyE,mBACpCxxE,kBAAmBd,EAAgBc,2BAQbuyG,CAIhC3tG,K,02BC9ZF,I,SAIqBgvG,G,2cAOjB,OACE,kBAAC,iBAAD,CACE9jE,GAAI90C,KAAKjB,MAAM85G,iBACf5jE,QAZmB,EAanBvgD,QAfmB,IAgBnBuZ,WAfoB,YAgBpBsnC,SAAUv1C,KAAKjB,MAAM+5G,kBAEpB94G,KAAKjB,MAAM2E,e,gCAf6BC,a,GAA5Bi1G,G,kBACA,CACjBl1G,SAAUxC,IAAU0C,KAAKxC,WACzBy3G,iBAAkB33G,IAAUG,KAAKD,WACjC03G,iBAAkB53G,IAAUI,KAAKF,Y,qGCfrC,IAsCe23G,GAtCD,CACZ,qBACA,UACA,UACA,OACA,QACA,SACA,QACA,YACA,cACA,cACA,SACA,QACA,OACA,aACA,oBACA,SACA,OACA,oBACA,QACA,WACA,SACA,qBACA,WACA,kBACA,cACA,SACA,UACA,gBAG8Bp4G,KAAI,SAAAkL,GAClC,MAAO,CACL/J,MAAO+J,EACPzV,MAAOyV,M,2zBC5BLmO,G,2cAOF,OACE,yBACEta,UAAS,uBAAkBM,KAAKjB,MAAMob,WACtCvR,IAAK5I,KAAKjB,MAAMqb,aAChBha,MAAOJ,KAAKjB,MAAMsb,gBAElB,0BAAMC,SAAUta,KAAKjB,MAAMkb,WACzB,yBAAKva,UAAU,UACb,0BAAMA,UAAU,WAAWQ,QAASF,KAAKjB,MAAM2R,SAC7C,0BAAMhR,UAAU,aAAhB,MAEF,wBAAIA,UAAU,SAASM,KAAKjB,MAAMwK,cAEpC,yBAAK7J,UAAU,WAAWM,KAAKjB,MAAM2E,UACrC,yBAAKhE,UAAU,UACb,4BACEnM,KAAK,SACLmM,UAAU,iBACVQ,QAASF,KAAKjB,MAAM2R,SAHtB,UAOA,4BACEnd,KAAK,SACLmM,UAAU,kBACVQ,QAASF,KAAKjB,MAAMkb,WAHtB,mB,gCA7BetW,c,8GAArBqW,G,eACkB,CACpBK,eAAgB,GAChBF,UAAW,KAwCfH,GAAazX,UAAY,CACvBgH,YAAarI,IAAUuB,OAAOrB,WAC9BsP,QAASxP,IAAUI,KAAKF,WACxB6Y,UAAW/Y,IAAUI,KAAKF,YAGb4Y,U,+2BChDMg/F,G,YAQnB,WAAYj6G,GAAO,M,IAAA,O,4FAAA,S,EACjB,K,EAAA,gBAAMA,GAAN,G,kDADiB,oBAoCT,WACR,EAAKA,MAAMoO,cArCM,sBAwCP,SAAA9a,GACVA,EAAE8Q,iBACF,EAAKpE,MAAMk6G,SAAS,EAAKr5G,MAAM4b,gBA1Cd,yBA6CJ,SAAA9nB,GACb,EAAKoM,SAAS,CAAE0b,YAAa9nB,EAAME,OAAOwC,WA3C1C,EAAKwJ,MAAQ,CACX4b,YAAazc,EAAMmF,gBAAgBsX,aAAe,IAJnC,E,2SAQAxY,GACbhD,KAAKjB,MAAMyc,cAAgBxY,EAAUwY,aACvCxb,KAAKF,SAAS,CACZ0b,YAAaxb,KAAKjB,MAAMyc,gB,+BAM5B,OACE,kBAAC,GAAD,CACEjS,YAAY,mBACZmH,QAAS1Q,KAAK0Q,QACduJ,UAAWja,KAAKia,UAChBE,UAAU,yBAEV,2BACE/jB,MAAO4J,KAAKJ,MAAM4b,YAClB9b,UAAU,oBACV8C,GAAG,cACH02G,aAAa,MACb//F,WAAS,EACThZ,SAAUH,KAAKgO,qB,gCAtC0BrK,a,GAA9Bq1G,G,YACA,CACjBx9F,YAAata,IAAUuB,OACvByB,gBAAiBhD,IAAUrK,OAAOuK,WAClC+L,SAAUjM,IAAUI,KAAKF,WACzB63G,SAAU/3G,IAAUI,KAAKF,a,2qCCF7B,IAAM+3G,GAAgB,SAAC,GAQjB,IAPJj1G,EAOI,EAPJA,gBACAk1G,EAMI,EANJA,aACAC,EAKI,EALJA,gBACAC,EAII,EAJJA,mBACAC,EAGI,EAHJA,gBACAC,EAEI,EAFJA,sBACAC,EACI,EADJA,wBACI,KACoCntG,qBADpC,GACGotG,EADH,KACiBC,EADjB,UAEsCrtG,oBAAS,GAF/C,GAEGstG,EAFH,KAEkBC,EAFlB,KAGEC,EAAmBhnG,mBAHrB,KAIsBxG,mBAAS,CACjCpI,kBACAk1G,eACAC,kBACAC,uBARE,GAIG15G,EAJH,KAIUE,EAJV,KAWJuU,qBAAU,WACR,IAAM0lG,EAAqBngG,KAAU1V,GAEjCm1G,IACFU,EAAmBv+F,iBAAcnmB,GAG/B+jH,IACFW,EAAmBp+F,cAAWtmB,GAGhC,IAAI2kH,EAAkBZ,EACjBC,GAAoBD,IACvBY,GAAkB,GAGpBl6G,GAAS,SAAAF,GAAK,aACTA,EADS,CAEZw5G,aAAcY,EACd91G,gBAAiB61G,SAElB,CAACV,EAAiBD,EAAcl1G,IAEnCmQ,qBAAU,WACJylG,EAAiB7lG,SACnB6lG,EAAiB7lG,QAAQgmG,UAE1B,CAACr6G,IAEJ,IAAMs6G,EAAU,SAAAxmH,GAAK,OACnBoM,GAAS,SAAAF,GAAK,aAAUA,EAAV,CAAiBw5G,cAAc,QAEzCe,EAA2B,WAC/BL,EAAiB7lG,QAAQgmG,QACzBn6G,GAAS,SAAAF,GAAK,aAAUA,EAAV,CAAiBy5G,iBAAiB,QAG5Ce,EAAoB,WAAM,MACDxgG,KAAUha,GAA/B4b,mBADsB,MACR,GADQ,EAE9Bs+F,EAAiB7lG,QAAQ7d,MAAQolB,EACjC1b,GAAS,SAAAF,GAAK,aAAUA,EAAV,CAAiBy5G,iBAAiB,QAG5CgB,EAAiB,SAAA3mH,GACH,UAAdA,EAAMgD,KACR4jH,KAIEA,EAAkB,WACtB,IAAM9+F,EAAcs+F,EAAiB7lG,QAAQ7d,MAC7CmjH,EAAgB,CAAE/9F,gBAElB1b,GAAS,SAAAF,GAAK,aACTA,EADS,CAEZ4b,cACA69F,iBAAiB,QAIfkB,EAA2B,SAAC7mH,EAAO8mH,GACvC,IAAM7+F,EAAW6+F,EAAapkH,MACxBqkH,EAAgBD,EAAa14G,MACnCy3G,EAAgB,CAAE59F,aAElB7b,GAAS,SAAAF,GAAK,aACTA,EADS,CAEZw5G,cAAc,EACdl1G,gBAAiB,MACZtE,EAAMsE,gBADI,CAEbyX,WACA8+F,wBAKAC,EAAgB,WACpB56G,GAAS,SAAAF,GAAK,aACTA,EADS,CAEZ05G,oBAAoB,EACpBF,cAAc,QAWZuB,EAAsB,kBAAMd,GAAiB,IA+FnD,OAAIJ,EAEA,kBAAC,GAAD,CACEtsG,SAAUqsG,EACVP,SA1F0B,SAAAz9F,GAC9B+9F,EAAgB,CAAE/9F,gBAClBg+F,KAyFIt1G,gBAAiBtE,EAAMsE,kBAM3B,kBAAC,GAAD,CACE20G,iBAAkBe,EAClBd,iBAAkBU,GAElB,oCACE,yBACE95G,UAAS,6BAAwBE,EAAMy5G,iBACrC,mBACFr4G,aArHgB,kBACtB24G,EAAgBrkH,WAAWqlH,EAAqB,OAqH1C55G,aAjHkB,WACpB24G,IACF3kH,aAAa2kH,GACbC,EAAgB,SASW,WAAM,IAC3BL,EAAsD15G,EAAtD05G,mBAAoBF,EAAkCx5G,EAAlCw5G,aAAcl1G,EAAoBtE,EAApBsE,gBAClCsX,EAAyCtX,EAAzCsX,YAAai/F,EAA4Bv2G,EAA5Bu2G,cAAe9+F,EAAazX,EAAbyX,SAEpC,OAAK29F,EAWCF,EAEA,kBAAC,IAAD,CACExgG,MAAOmgG,GACPh3D,QAAS,EACTzpC,WAAYiiG,EACZzhG,qBAAqB,iBAKvB,oCACE,yBAAKpZ,UAAU,mBAAmBQ,QAASy6G,GACzC,kBAAC,IAAD,CAAMvlH,KAAK,QAAQsK,UAAU,eAE/B,yBAAKA,UAAU,8BACb,yBAAKA,UAAU,YAAY+6G,GAC3B,yBAAK/6G,UAAU,eACb,2BACE8C,GAAG,mBACHoG,IAAKkxG,EACLv/F,aAAciB,GAAe,GAC7B09F,aAAa,MACb0B,WAAYP,MAIlB,yBAAK36G,UAAU,iBACb,4BACEnM,KAAK,SACLmM,UAAU,oBACVQ,QAASg6G,GAHX,WAOA,4BACE3mH,KAAK,SACLmM,UAAU,qBACVQ,QAASi6G,GAER3+F,EAAc,QAAU,OAL3B,gBASF,yBAAK9b,UAAU,0BACb,4BACEnM,KAAK,SACLmM,UAAU,oBACVQ,QAASk6G,GAHX,UAOA,4BACE7mH,KAAK,SACLmM,UAAU,qBACVQ,QAASo6G,GAHX,UA7DN,4BACE/mH,KAAK,SACLmM,UAAU,iBACVQ,QAASw6G,GAER/+F,EAAW,OAAS,MALvB,UAiGGk/F,OAOX1B,GAAc52G,UAAY,CACxB2B,gBAAiBhD,IAAUrK,OAAOuK,WAClCo4G,sBAAuBt4G,IAAUI,KAAKF,WACtCm4G,gBAAiBr4G,IAAUI,KAAKF,WAChC05G,mBAAoB55G,IAAUC,OAC9Bm4G,mBAAoBp4G,IAAUG,KAC9B+3G,aAAcl4G,IAAUG,KACxBg4G,gBAAiBn4G,IAAUG,KAC3Bo4G,wBAAyBv4G,IAAUG,MAGrC83G,GAAcv2G,aAAe,CAC3B02G,oBAAoB,EACpBF,cAAc,EACdC,iBAAiB,EACjBI,yBAAyB,GAGZN,UCjQT4B,GAAY,CAChB,QACA,gBACA,SACA,gBACA,gBACA,YACA,gBAGIC,GAAkB,SAAC,GAOnB,IANJC,EAMI,EANJA,WACAC,EAKI,EALJA,iBACAC,EAII,EAJJA,aACAhsF,EAGI,EAHJA,UACAze,EAEI,EAFJA,QACA7L,EACI,EADJA,SAEMu2G,EAAuB,CAC3B,CACEt5G,MAAO,qBACPu5G,WAAY,SACZtvE,OAAQ,gBAAGuvE,EAAH,EAAGA,eAAgBnsF,EAAnB,EAAmBA,UAAnB,OACNtqB,EAASy2G,EAAgBnsF,KAE7B,CACErtB,MAAO,UACPu5G,WAAY,WACZtvE,OAAQ,YAAmC,IAAhCuvE,EAAgC,EAAhCA,eAAgBnsF,EAAgB,EAAhBA,UACXjrB,EAAoBo3G,EAA1BprF,KACR+qF,EAAW9rF,EAAWjrB,KAG1B,CACEm3G,WAAY,iBACZtvE,OAAQ,YAAmC,IAAhCuvE,EAAgC,EAAhCA,eAAgBnsF,EAAgB,EAAhBA,UACXjrB,EAAoBo3G,EAA1BprF,KACRgrF,EAAiB/rF,EAAWjrB,MAiD5Bq3G,EA5CmB,SAACpsF,GAAoC,IAAzBgsF,EAAyB,wDACtDG,EAAiB1jB,GAAgBoB,WAAW,oBAAqB,CACrEnwF,QAASsmB,EAAUtmB,QACnBkoG,kBAAmB5hF,EAAUqsF,cAAc5sF,OAC3CoiF,mBAAoB+J,KAOtB,IACEI,IACAG,GAC4B,kBAA5BA,EAAe7gC,SAHjB,CAQA,IAAI8gC,EAAgB,GAepB,OAdID,GACFF,EAAqBvtG,SAAQ,SAAAhC,GAC3BA,EAAKi9E,OAAS,CAAE35D,YAAWmsF,kBAEH,mBAApBzvG,EAAKwvG,aACPxvG,EAAK/J,MAAL,UACEw5G,EAAeprF,KAAK1U,YAAc,OAAS,MAD7C,iBAKF+/F,EAAcvqH,KAAK6a,MAIhB0vG,GAUaE,CAAiBtsF,EAAWgsF,GAElD,OACE,yBAAKz7G,UAAU,mBACb,kBAAC,IAAD,CAAakZ,MAAO2iG,EAAer7G,QAXhB,SAAC,IACtB6rC,EAD6C,EAArBA,QAAqB,EAAb+8C,QAE5Bp4E,GACFA,SAaNsqG,GAAgBz4G,UAAY,CAC1B44G,aAAcj6G,IAAUG,KAAKD,WAC7B+tB,UAAWjuB,IAAUrK,OACrB6Z,QAASxP,IAAUI,KACnB45G,iBAAkBh6G,IAAUI,KAC5B25G,WAAY/5G,IAAUI,KACtBuD,SAAU3D,IAAUI,MAGtB05G,GAAgBp4G,aAAe,CAC7Bu4G,cAAc,GAGDH,U,orBCrGXxrF,IAAKllB,aAAak+E,oBAHpBK,G,GAAAA,QACAG,G,GAAAA,UACAD,G,GAAAA,WAGI2yB,GAAyB,CAC7BC,MAAO9yB,GACPpV,QAASuV,GACT4yB,SAAUlnB,MAAS,SAAAhhG,GACjB,OAAOq1F,GAAWr1F,KACjB,MAUU,SAAS+1D,GAAT,GAIZ,IAHDouC,EAGC,EAHDA,gBACAD,EAEC,EAFDA,gBAGQ7yD,GADP,EADDysC,cAE4BqmB,EAAgBvM,SAApCvmD,iBAGF82E,EAAwB,SAAC9vE,EAAQr4C,GACrC,OAAOgoH,GAAuB3vE,GAAQr4C,IAElCooH,EAAqBD,EAAsBllH,KAAKqJ,KAAM,SACtDqgF,EAAuBw7B,EAAsBllH,KAAKqJ,KAAM,WACxD+7G,EAAwBF,EAAsBllH,KAAKqJ,KAAM,YACzDg8G,EAAqBH,EAAsBllH,KAC/CqJ,KACA,oBAGIi8G,EAAsB,SAAAvoH,GAAK,MAAK,CACpCqT,EAAIrT,GAASA,EAAM8nH,cAAczqB,OAAOhqF,GAAM,EAC9CE,EAAIvT,GAASA,EAAM8nH,cAAczqB,OAAO9pF,GAAM,IAsB1Ci1G,EAAsB,SAACn9G,EAAO+rC,EAAc5mC,GAC3C6gC,EAKLA,EAAgBtuC,OAAhB,IACE+L,GAAI,YACJqtC,aAAa,EACbI,aAAa,EACbN,YAAY,EACZ9E,QAASsuE,GACTruE,aAAc,IACZ5mC,kBACAs1G,sBAAuB,kBACrBz0E,EAAgBmK,QAAQ,CAAE1sC,GAAI,eAChC+2G,gBAAiB,SAAA4C,GAAa,OAnCJ,SAACA,EAAej4G,GAAoB,IAC1DyX,EAAoCwgG,EAApCxgG,SAAUH,EAA0B2gG,EAA1B3gG,YAAaijD,EAAa09C,EAAb19C,SAE3B9iD,IACFzX,EAAgByX,SAAWA,GAG7BzX,EAAgBsX,YAAcA,GAAe,GAEzCijD,IACFv6D,EAAgBu6D,SAAWA,GAG7Bm5B,EAAgBoB,WACd,oCACA90F,GAqBIk4G,CAAwBD,EAAej4G,KACtC4mC,IAEF/rC,IAlBH/H,QAAQM,KAAK,2DAgEX+kH,EAAe,SAAA3oH,GACdqxC,EAKLA,EAAgBtuC,OAAO,CACrB04B,UAAWz7B,EAAM8jB,OACjBqzB,QAASmwE,GACTlwE,aAAc,CACZqwE,cAAc,KARhBnkH,QAAQM,KAAK,2DAaXglH,EAAe,kBAAMC,KAIrBA,EAA8B,WAC7Bx3E,GAKLA,EAAgBmK,QAAQ,CAAE1sC,GAAI,iBAC9BuiC,EAAgBmK,QAAQ,CAAE1sC,GAAI,eAL5BxL,QAAQM,KAAK,2DAgBXurB,EAAc,SAAA25F,GAE0B,IADvBA,EAA2BhlG,OAAO9jB,MACrBiwC,MAjFf,SAAAjwC,GACdqxC,GAKLA,EAAgBmK,QAAQ,CAAE1sC,GAAI,iBAC9BuiC,EAAgBtuC,OAAO,CACrB+L,GAAI,eACJqtC,aAAa,EACbD,kBAAkB,EAClBF,gBAAiBusE,EAAoBvoH,EAAM8jB,QAC3CqzB,QAASmwE,GACTlwE,aAAc,CACZ3b,UAAWz7B,EAAM8jB,OACjB3S,SAAU,SAACy2G,EAAgBnsF,GACzB,IAAMtmB,EAAUsmB,EAAUtmB,QAC1B+uF,EAAgBoB,WAAW,kBAAmB,CAC5CnwF,UACA4xE,SAAU6gC,EAAe7gC,SACzBvqD,KAAMorF,EAAeprF,QAGzBxf,QAAS,kBAAMq0B,EAAgBmK,QAAQ,CAAE1sC,GAAI,kBAC7Cy4G,WAAY,SAAC9rF,EAAWjrB,GACtBg4G,EACE,CAAEvsE,YAAY,EAAME,aAAa,GACjC,CAAEypE,oBAAoB,EAAMF,cAAc,GAC1Cl1G,IAGJg3G,iBAAkB,SAAC/rF,EAAWjrB,GAC5Bg4G,EACE,CAAExsE,gBAAiBusE,EAAoB9sF,IACvC,CAAEsqF,yBAAyB,GAC3Bv1G,QAjCNlN,QAAQM,KAAK,0DAkFbmlH,CAAaD,GAzBUD,KAuF3B9uF,IAAYm6C,OAAOz+D,iBACjBskB,IAAY4f,OAAO6/D,iBAzDrB,SAA+B54F,GAC7B,IAAMzL,EAAUyL,EAAIkD,OAAO3O,QAE3BA,EAAQM,iBACNw1F,IAAQtxD,OAAO8/D,kBACf2O,GAEFjzG,EAAQM,iBACNw1F,IAAQtxD,OAAOqvE,oBACfr8B,GAEFx3E,EAAQM,iBACNw1F,IAAQtxD,OAAOkgE,qBACfwO,GAEFlzG,EAAQM,iBACNw1F,IAAQtxD,OAAOsvE,kBACfX,GAGFnzG,EAAQM,iBAAiBw1F,IAAQtxD,OAAOuvE,YAAaP,GACrDxzG,EAAQM,iBAAiBw1F,IAAQtxD,OAAOwvE,YAAah6F,GACrDha,EAAQM,iBAAiBw1F,IAAQtxD,OAAOyvE,YAAaR,MAsCvD7uF,IAAYm6C,OAAOz+D,iBACjBskB,IAAY4f,OAAO0vE,kBAjCrB,SAAgCzoG,GAC9B,IAAMzL,EAAUyL,EAAIkD,OAAO3O,QAE3BA,EAAQO,oBACNu1F,IAAQtxD,OAAO8/D,kBACf2O,GAEFjzG,EAAQO,oBACNu1F,IAAQtxD,OAAOqvE,oBACfr8B,GAEFx3E,EAAQO,oBACNu1F,IAAQtxD,OAAOkgE,qBACfwO,GAEFlzG,EAAQO,oBACNu1F,IAAQtxD,OAAOsvE,kBACfX,GAGFnzG,EAAQO,oBAAoBu1F,IAAQtxD,OAAOuvE,YAAaP,GACxDxzG,EAAQO,oBAAoBu1F,IAAQtxD,OAAOwvE,YAAah6F,GACxDha,EAAQO,oBAAoBu1F,IAAQtxD,OAAOyvE,YAAaR,M,6qBCtO7C,QAIb95G,GAAI,qBACJ,cACE,OAAOtL,OAAOsU,SAGhBwnG,gBATa,YAS6D,IAAxDnb,EAAwD,EAAxDA,gBAAiBD,EAAuC,EAAvCA,gBAAuC,IAAtBpmB,cAClD/nB,GAAK,CAAEouC,kBAAiBD,kBAAiBpmB,mBAD+B,MAAN,GAAM,KAI1EwrC,eAba,YAawC,IAApCnlB,EAAoC,EAApCA,gBAAiBD,EAAmB,EAAnBA,gBAAmB,EACAC,EAAgBvM,SAA3DzmD,EAD2C,EAC3CA,sBAAuBE,EADoB,EACpBA,gBAEzBm3E,EAAsB,SAACn9G,EAAOmF,GAC7B6gC,GAKLA,EAAgBmK,QAAQ,CAAE1sC,GAAI,cAC9BuiC,EAAgBtuC,OAAO,CACrB+L,GAAI,YACJmtC,YAAY,EACZE,aAAa,EACbI,aAAa,EACbpF,QAASsuE,GACTruE,aAAc,IACZ5mC,kBACAs1G,sBAAuB,kBACrBz0E,EAAgBmK,QAAQ,CAAE1sC,GAAI,eAChC+2G,gBAAiB,YAAyC,IAAtC59F,EAAsC,EAAtCA,SAAUH,EAA4B,EAA5BA,YAAaijD,EAAe,EAAfA,SACzCv6D,EAAgByX,SAAWA,GAAYzX,EAAgByX,SACvDzX,EAAgBsX,YAAcA,GAAe,GAC7CtX,EAAgBu6D,SAAWA,GAAYv6D,EAAgBu6D,SAEvDm5B,EAAgBoB,WACd,oCACA90F,KAGDnF,MAzBL/H,QAAQM,KAAK,2DAgDjB,MAAO,CACL2lH,YAAa,CACX,CACEx7G,KAAM,OACNK,MAAO,UACPlO,OAAQ,sBAGZqpE,WAAY,CACV,CACEz6D,GAAI,oBACJipB,UA7BoC,kBACxC,kBAAC,GAAD,CACEnnB,UAAW,SAAA4rB,GAAI,OACbgsF,EACE,CAAE9C,cAAc,EAAME,oBAAoB,GAC1CppF,IAGJxrB,kBAAmB,SAAAwrB,GAAI,OACrBgsF,EAAoB,CAAEzC,yBAAyB,GAAQvpF,IAEzDnmB,eAAgB,SAAA5U,GACV0vC,GACFA,EAAsBqG,KAAK/1C,SAmBjC+8G,eAAgB,CAAC,a,uCCvDRgL,GA7BH,SAAC,GAAD,IAAG/3C,EAAH,EAAGA,SAAUg4C,EAAb,EAAaA,kBAAb,OACV,yBACE/8G,MAAO,CACLg9G,WAAY,OACZv8G,OAAQ,EACR2G,KAAM,EACN61G,WAAY,GAAF,OAAuB,MAAhB,EAAIl4C,GAAX,KACV79D,SAAU,QACVC,IAAK,EACL2uC,WAAY,eAAF,OAAiBinE,EAAjB,aACVv8G,MAAO,OACP8Z,OAAQ,OAGV,yBACEta,MAAO,CACLk9G,UAAW,8BACXj9G,QAAS,QACTQ,OAAQ,OACR08G,QAAS,EACTj2G,SAAU,WACVyiE,MAAO,EACPyzC,UAAW,oCACX58G,MAAO,SCXA68G,GAZG,SAAC,GAAD,IAAG/5G,EAAH,EAAGA,SAAUg6G,EAAb,EAAaA,WAAYP,EAAzB,EAAyBA,kBAAzB,OAChB,yBACE/8G,MAAO,CACLm9G,QAASG,EAAa,EAAI,EAC1BprB,cAAe,OACfp8C,WAAY,WAAF,OAAainE,EAAb,eAGXz5G,I,y3BCQL,IAAMi6G,GAAejyF,aAAe,kBAClCP,aAAY,kBAAM,qCAGdyyF,G,kVAEI,CACN38F,WAAW,I,8SAWO,WAClBjhB,KAAK69G,SAAW79G,KAAKjB,MAAM++G,QAAQC,QAAO,SAACpiG,EAAUowB,GAC/C,EAAKhtC,MAAMi/G,YACb,EAAKj/G,MAAMi/G,WAAW9mH,OAAOykB,SAASsiG,e,6CAM1Cj+G,KAAK69G,a,+BAGE,aACuB79G,KAAKjB,MAA3B6tB,EADD,EACCA,KAAMknF,EADP,EACOA,YADP,EAEoB9zG,KAAKqG,QAAxB8yC,iBAFD,MAEa,GAFb,EAIP,GADwB26D,KAAiBlnF,GAAQA,EAAKsxF,SACjC,OACUl+G,KAAKjB,MAAM4c,SAAhCsiG,EADW,EACXA,SAAUn7E,EADC,EACDA,OASlB,MAPiB,cAAbm7E,GACFpY,eAAeH,QACb,mBACAltB,KAAKC,UAAU,CAAEwlC,WAAUn7E,YAK7B,kBAAC,KAAD,KACE,kBAAC,KAAD,CACEq7E,OAAK,EACLnhD,KAAK,uBACL9nB,QAASkpE,OAEX,kBAAC,KAAD,CACED,OAAK,EACLnhD,KAAK,mBACLqhD,OAAQ,kBACN,kBAAC,2BAAD,CACEvK,YAAaA,EACbwK,gBAAiB,kBAAMtnH,QAAQK,IAAI,uBACnCknH,cAAe,SAAAzpH,GACbkC,QAAQM,KAAKxC,GACbkC,QAAQM,KAAK,wBAKrB,kBAAC,KAAD,CACE0lE,KAAK,YACLqhD,OAAQ,kBAAM,kBAACV,GAAD,CAAc7J,YAAaA,OAE3C,kBAAC,KAAD,CACE92C,KAAK,SACLvxC,UAAW,WACT,IAAM6+D,EAAc,IAAIk0B,gBACtB,EAAKz/G,MAAM4c,SAASmnB,QAEhB27E,EAAMn0B,EAAYt0F,IAAI,OACtB0oH,EAAYp0B,EAAYt0F,IAAI,cAC5B2oH,EAAgBr0B,EAAYt0F,IAAI,mBAGtC,OAAIyoH,KADiB,OAAnBtlE,EAAUo7D,MAAiBp7D,EAAUo7D,KAAK,GAAGqK,YAE7C5nH,QAAQlC,MACN,mDAEK,OAGTg/G,EAAY+K,aAAazqH,MAAK,WAC5B,GAAsB,OAAlBuqH,EAAwB,CAC1B,IAAMG,EAAiB,CACrBb,SAAU,IAAI5O,IAAIsP,GAAeV,UAEnCpY,eAAeH,QACb,mBACAltB,KAAKC,UAAUqmC,SAMjBjZ,eAAeH,QACb,mBACAltB,KAAKC,UALgB,CACrBwlC,SAAU,OAQI,OAAdS,EACF5K,EAAYiL,eAAe,CAAEC,WAAYN,IAEzC5K,EAAYiL,oBAIT,SAGX,kBAAC,KAAD,CACEtzF,UAAW,WAST,OARAqoF,EAAYmL,UAAU7qH,MAAK,SAAAw4B,GACrBA,EACFknF,EAAYoL,eAEZpL,EAAYiL,oBAIT,SAajB,IAAMpxB,EAASywB,KAAqBjlE,GAE9BgmE,EAAcn/G,KAAKjB,MAAM4c,SAASsiG,SAClCmB,GAAoBzxB,EAAO13E,MAAK,SAAAhgB,GAAC,OACrCopH,aAAUF,EAAa,CACrBniD,KAAM/mE,EAAE+mE,KACRmhD,OAAO,OAIX,OACE,oCACE,kBAAC,KAAD,CAAWmB,YAAat/G,KAAKJ,MAAMqhB,YAChC,gBAAGy8F,EAAH,EAAGA,WAAYv4C,EAAf,EAAeA,SAAUg4C,EAAzB,EAAyBA,kBAAzB,OACC,kBAAC,GAAD,CACEO,WAAYA,EACZP,kBAAmBA,GAEnB,kBAAC,GAAD,CAAKh4C,SAAUA,EAAUg4C,kBAAmBA,QAIlD,kBAAC,KAAD,CAAOgB,OAAK,EAACnhD,KAAK,uBAAuB9nB,QAASkpE,OAClD,kBAAC,KAAD,CAAOD,OAAK,EAACnhD,KAAK,wBAAwB9nB,QAASkpE,QACjDgB,GACAzxB,EAAOhtF,KAAI,gBAAGq8D,EAAH,EAAGA,KAAMr5D,EAAT,EAASA,UAAT,OACT,kBAAC,KAAD,CAAOjN,IAAKsmE,EAAMmhD,OAAK,EAACnhD,KAAMA,IAC3B,gBAAG55B,EAAH,EAAGA,MAAH,OACC,kBAAC,iBAAD,CACE0R,GAAc,OAAV1R,EACJ1uC,QAAS,IACTuZ,WAAW,OACX+mC,eAAa,EACbE,QAAS,WACP,EAAKp1C,SAAS,CACZmhB,WAAW,KAGfm0B,UAAW,WACT,EAAKt1C,SAAS,CACZmhB,WAAW,MAIJ,OAAVmiB,EACC,qCAEE,kBAAC,IAAD,CAAe/8B,QAAS+8B,EAAMwO,KAC5B,kBAACjuC,EAAD,CAAWy/B,MAAOA,EAAOznB,SAAU,EAAK5c,MAAM4c,mBAO7DyjG,GAAoB,kBAACG,GAAA,EAAD,Y,gCA9LM57G,a,GAA7Bi6G,G,cACiBllE,M,GADjBklE,G,YAMe,CACjBE,QAAS58G,IAAUrK,OAAOuK,WAC1BwrB,KAAM1rB,IAAUrK,OAChBmnH,WAAY98G,IAAUI,KACtBwyG,YAAa5yG,IAAUrK,OACvB8kB,SAAUza,IAAUrK,SAyLxB,IAMM2oH,GAAgCjI,aANd,SAAA33G,GACtB,MAAO,CACLgtB,KAAMhtB,EAAM20G,KAAK3nF,QAMnB,KAFoC2qF,CAGpCqG,IAEa6B,eACbC,aAAWF,K,mkDCzKb,IASIG,GATEC,GAAwB,CAC5BjpB,YAAa,kBAAM94B,GAAMk3C,YACzB77D,kBAAmB,kBAAMA,aAAkB2kB,GAAMk3C,cAI7Cnd,GAAkB,IAAIxzD,KAAgBw7E,IACtC/nB,GAAkB,IAAItzD,KACtBs7E,GAAiB,IAAIv7E,KAAeszD,GAAiBC,IAK3D3gG,OAAO2mE,MAAQA,GAEf3mE,OAAO4oH,KAAO5oH,OAAO4oH,MAAQ,GAC7B5oH,OAAO4oH,KAAKC,IAAM,CAChBnoB,mBACAioB,kBACAhoB,mBACA8nB,qB,IAGIK,G,YA4BJ,WAAYjhH,GAAO,M,iGAAA,S,EACjB,S,EAAA,gBAAMA,K,+CADW,kEAGTqwB,EAA8BrwB,EAA9BqwB,OAAQ6wF,EAAsBlhH,EAAtBkhH,kBAShB,EAAKC,W,kVAAL,IAPyB,CACvB5yB,eAAe,EACf6yB,2BAA4B,GAC5B5c,WAAY,GACZ6c,eAAgB,KAGlB,GAEwB,mBAAXhxF,EAAwBA,EAAO,CAAEyoE,qBAAqBzoE,GAdlD,ICzGY+pB,EAC3BknE,EACI30G,EDoQa4/E,EA7JF,EAuBb,EAAK40B,WALPtiD,EAlBe,EAkBfA,QACS0iD,EAnBM,EAmBflyG,QACA+xG,EApBe,EAoBfA,2BACA5c,EArBe,EAqBfA,WACAgR,EAtBe,EAsBfA,KAtBe,OCzGYp7D,EDkIZ,EAAK+mE,YChIhBx0G,EAAYxU,OAAZwU,UACOA,EAAQ60G,KAAO70G,EAAQ60G,IAAIC,aACxCH,EAAW30G,EAAQ60G,IAAIC,YAGzBtpH,OAAOK,KAAO,CACZiU,WACA60G,YAKFnpH,OAAOu2B,YAAcA,IACrBv2B,OAAO+nE,2BAA6BA,KAGpCA,KAA2BkhC,SAAS1yE,YAAcA,IAClDwxC,KAA2BkhC,SAAS1gD,YAAcA,KAElDjwB,IAAK5C,KAAKC,eAAiB,WAEzB,IAAMjtB,EAAQ1I,OAAO2mE,MAAMk3C,WAC3B,GAAKn1G,EAAM20G,MAAS30G,EAAM20G,KAAK3nF,KAI/B,OAAOhtB,EAAM20G,KAAK3nF,KAAK6zF,cAGzBjxF,IAAKkV,aAAauM,oBAAsB,WAGtC,OAAOkI,EAAUunE,kBAGnBzhD,KAA2B0hD,UAAU,CACnCC,WAAY,SAASC,GACnB,IAAMn0F,EAAU8C,IAAKvD,SAASO,yBAE1BE,EAAQK,eACV8zF,EAAIC,iBAAiB,gBAAiBp0F,EAAQK,gBAGlD0uB,iBAAkB,SAAA3mD,GAG0B,mBAA/BqkD,EAAUunE,kBACnBvnE,EAAUunE,iBAAiB5rH,MDmF/B,EAAKisH,gBAAgBxM,GAkIFjpB,EAjIL,CACZzmD,KACAC,KACAC,KACAC,KACAC,MA6HJ4yD,GAAgBmpB,iBAAiB11B,GAMnC,SAAyBiY,EAAY4c,EAA4BhnE,GAC/DwmE,GAAmB,IAAIt7E,KAAiB,CACtCuzD,mBACAC,mBACA1+C,YACAwC,IAAK,CACHi7C,SAAUj+C,KACVsoE,MAAO,CACLnoE,uBAKN,IAAMooE,EAAqB,CACzBC,GACA,CAACC,GAA0BjB,KAGa,IAAtChnE,EAAUkoE,yBAEZH,EAAmBlwH,KAAKswH,IAG1B,IAAMC,EAAmBL,EAAmB9jF,OAAOmmE,GACnDoc,GAAiB6B,mBAAmBD,GAzJlCE,CAAgB,GAAD,UACTxB,GADS,GACa1c,IAC1B4c,EACA,EAAKD,YA6JX,SAAsBI,GAGpB,IAAMoB,EAAuBlpC,KAAKpwB,MAChCm9C,aAAarhC,QAAQ,uBAAyB,MAK9Cw9C,GAAwB/wH,OAAO4c,KAAKm0G,GAAsBhxH,OAAS,EAEnEmvH,GAAe/mB,WAAW4oB,GAE1B7B,GAAe/mB,WAAWwnB,GAG5BT,GAAe8B,kBAAkBrB,GAtK/BsB,CAAatB,GAyKjB,SAAsB1iD,GAChBA,GACFp5B,IAAMm5B,WAAWC,EAASC,IA1K1BgkD,CAAajkD,GjBxJF,WACb,IAAMxuC,EAAS,CACb0yF,cAAevuG,KAAKtD,IAAIsD,KAAKxD,IAAI2a,UAAUq3F,oBAAsB,EAAG9N,IAAkB,GACtF+N,yBAAyB,EACzBC,kBAAmB,CACjBC,WAAY,CACVC,2BAA2B,EAC3BC,UAAU,EACVC,QAAQ,KAKTxoD,KACHoF,KAA2BqjD,iBAAiB1qC,WAAWxoD,GACvDyqC,IAAc,GiB0Id0oD,GA/CiB,E,iSAkDV,MACmCviH,KAAKkgH,WAAvCsC,EADD,EACCA,cAAepC,EADhB,EACgBA,eADhB,EAQHvoB,GAAgBvM,SALlBzmD,EAHK,EAGLA,sBACAE,EAJK,EAILA,gBACAD,EALK,EAKLA,eAEAG,GAPK,EAMLD,mBANK,EAOLC,eAGF,OAAIjlC,KAAKyiH,aAEL,kBAAC,IAAD,CAAep8G,QAAQ,OACrB,kBAAC,IAAD,CAAUw3D,MAAOA,IACf,kBAAC,KAAD,CAAazuC,OAAQpvB,KAAKkgH,YACxB,kBAAC,IAAD,CAAiBlkG,KAAMA,MACrB,kBAAC,eAAD,CAAc6hD,MAAOA,GAAOi2C,YAAa9zG,KAAKyiH,cAC5C,kBAACC,GAAA,EAAmBl4E,SAApB,CAA6Bp0C,MAAO4J,KAAKyiH,cACvC,kBAAC,IAAD,CAAQE,SAAUvC,GAChB,kBAAC1pB,GAAA,EAAqBlsD,SAAtB,CAA+Bp0C,MAAOosH,GACpC,kBAAC,IAAD,CAAgB73E,QAAS1F,GACvB,kBAAC,IAAD,CAAkB0F,QAAS9F,GACzB,kBAAC,IAAD,CAAgB8F,QAAS5F,GACvB,kBAAC,IAAD,CACE2F,MAAO1vB,IACP2vB,QAAS7F,GAET,kBAAC,GAAD,CACEgvE,YAAa9zG,KAAKyiH,2BAkB9C,kBAAC,IAAD,CAAep8G,QAAQ,OACrB,kBAAC,IAAD,CAAUw3D,MAAOA,IACf,kBAAC,KAAD,CAAazuC,OAAQpvB,KAAKkgH,YACxB,kBAAC,IAAD,CAAiBlkG,KAAMA,MACrB,kBAAC,IAAD,CAAQ2mG,SAAUvC,GAChB,kBAAC1pB,GAAA,EAAqBlsD,SAAtB,CAA+Bp0C,MAAOosH,GACpC,kBAAC,IAAD,CAAgB73E,QAAS1F,GACvB,kBAAC,IAAD,CAAkB0F,QAAS9F,GACzB,kBAAC,IAAD,CAAgB8F,QAAS5F,GACvB,kBAAC,IAAD,CACE2F,MAAO1vB,IACP2vB,QAAS7F,GAET,kBAAC,GAAD,kB,sCAcRyvE,GACd,GAAIA,GAAUA,EAAK7jH,OAAQ,CACzB,IAAMkyH,EAAoB5iH,KAAKkgH,WAAW3L,KAAK,GADtB,EAGEr9G,OAAOykB,SAA1Bse,EAHiB,EAGjBA,SAAU4oF,EAHO,EAGPA,KACVzC,EAAmBpgH,KAAKkgH,WAAxBE,eACF0C,EAAU,GAAH,OAAM7oF,EAAN,aAAmB4oF,GAAnB,OAA0BzC,GAEjC2C,EAAeH,EAAkBG,cAAgB,YACjDC,EACJJ,EAAkBI,qBAAuB,uBACrCC,EACJL,EAAkBK,0BAA4B,IAE1CC,EAA6BvyH,OAAOqhC,OAAO,GAAI4wF,EAAmB,CACtEG,aAAcI,GAAyBJ,EAAcD,GACrDE,oBAAqBG,GACnBH,EACAF,GAEFG,yBAA0BE,GACxBF,EACAH,KAIJ9iH,KAAKyiH,aAAeW,GAClBvlD,GACAqlD,S,gCAnLUv/G,aA4PlB,SAASw/G,GAAyBvxE,EAAKyxE,GACrC,OALF,SAAwBzxE,GACtB,OAAOA,EAAI9jC,SAAS,YAAc8jC,EAAI9jC,SAAS,YAI3Cw1G,CAAe1xE,GACVA,GAM6B,MAAlCyxE,EAASA,EAAS3yH,OAAS,KAC7B2yH,EAAWA,EAASjsH,MAAM,EAAGisH,EAAS3yH,OAAS,IAG1C2yH,EAAWzxE,G,GAxQdouE,G,YACe,CACjB5wF,OAAQluB,IAAUwB,UAAU,CAC1BxB,IAAUI,KACVJ,IAAUyB,MAAM,CACdy9G,eAAgBl/G,IAAUuB,OAAOrB,WACjCmzG,KAAMrzG,IAAUiK,MAChBq3G,cAAethH,IAAUyB,MAAM,CAC7B6zF,sBAAuBt1F,IAAUI,OAEnCiiG,WAAYriG,IAAUiK,UAEvB/J,WACH6+G,kBAAmB/+G,IAAUiK,Q,GAb3B60G,G,eAgBkB,CACpB5wF,OAAQ,CACNk+D,eAAe,EACfinB,KAAM,GACNhR,WAAY,IAEd0c,kBAAmB,KAwPvB,IAAMsD,GAAkEvD,GAEzDuD,Q,8BEpWf,gFAKe,SAAShE,EAAT,GAA6F,QAAzEpqH,eAAyE,MAA/D,mCAA+D,MAA3BquH,wBAA2B,SAEpGn9G,EAAUyyC,cAEhB,OACE,yBAAKp5C,UAAW,aACd,6BACE,4BAAKvK,GACJquH,GAAoBn9G,EAAQ8yC,UAAUm0C,eACrC,4BACE,kBAAC,IAAD,CAAMm2B,GAAI,KAAV,kC,6BCfZ,sFAKA,SAASC,EAAa3kH,GAAO,IAEzBmiB,EAKEniB,EALFmiB,QACAyiG,EAIE5kH,EAJF4kH,iBACAC,EAGE7kH,EAHF6kH,uBACArvB,EAEEx1F,EAFFw1F,aACAsvB,EACE9kH,EADF8kH,yBAGF,OACE,yBAAKnkH,UAAU,iBACb,yBAAKA,UAAU,+BACZwhB,EACEvgB,KAAI,SAACuV,EAAOomB,GAAe,IAClBhnB,EAAqBY,EAArBZ,iBACR,OAAOY,EAAMC,WAAWxV,KAAI,SAACmjH,EAAOC,GAAe,IAG/CniH,EAUEkiH,EAVFliH,OACAwyF,EASE0vB,EATF1vB,aACAv+E,EAQEiuG,EARFjuG,sBACAuoB,EAOE0lF,EAPF1lF,QACA4lF,EAMEF,EANFE,yBACAjzD,EAKE+yD,EALF/yD,eACArB,EAIEo0D,EAJFp0D,kBACA3P,EAGE+jE,EAHF/jE,aACA57C,EAEE2/G,EAFF3/G,YACAsvF,EACEqwB,EADFrwB,sBAGF,OACE,yBACE/8F,IAAKotH,EAAMjuG,sBACXnW,UAAU,sBACV4C,UAAQ,kBAER,kBAAC,IAAD,CACEV,OAAQA,EACR2yF,aAAcA,EACd79F,IAAG,UAAK4lC,EAAL,YAAmBynF,GACtBvhH,GAAE,UAAK85B,EAAL,YAAmBynF,GAErBzuG,iBAAkBA,EAElB8+E,aAAcA,EACdh2D,QAASA,EACT4lF,yBAA0BA,EAC1BnuG,sBAAuBA,EACvBk7C,eAAgBA,EAChBrB,kBAAmBA,EACnB3P,aAAcA,EACd57C,YAAaA,EACbsvF,sBAAuBA,EAEvBvzF,QAASyjH,EAAiBhtH,UACxBtB,EACAwgB,GAEFw+E,cAAeuvB,EACf9wB,gBAAiB+wB,WAM1BI,SAMX,IAAM/8C,EAAO,aAEbw8C,EAAanhH,UAAY,CACvB2e,QAAShgB,IAAU0L,QACjB1L,IAAUyB,MAAM,CACd2S,iBAAkBpU,IAAUuB,OAAOrB,WACnC+U,WAAYjV,IAAU0L,QACpB1L,IAAUyB,MAAM,CACdyxF,aAAclzF,IAAUuB,OACxBoT,sBAAuB3U,IAAUuB,OAAOrB,WACxCg9B,QAASl9B,IAAUuB,OACnBuhH,yBAA0B9iH,IAAUC,OACpC4vD,eAAgB7vD,IAAUC,OAC1BuuD,kBAAmBxuD,IAAUuB,OAC7Bs9C,aAAc7+C,IAAUC,OACxByxF,qBAAsB1xF,IAAUC,aAItCC,WACFmzF,aAAcrzF,IAAUG,KACxBsiH,iBAAkBziH,IAAUI,KAC5BsiH,uBAAwB1iH,IAAUI,KAClCuiH,yBAA0B3iH,IAAUG,MAGtCqiH,EAAa9gH,aAAe,CAC1Bse,QAAS,GACTqzE,cAAc,EACdovB,iBAAkBz8C,EAClB08C,uBAAwB18C,EACxB28C,0BAA0B,I,6BC3G5B,IAAMrhH,EAAK,oBAEIA,MAGW,GAAH,OAAMA,EAAN,kCADK,a,6BCJ5B,WAEMkgH,EAFN,OAE2B38F,EAAMwkB,gBAElBm4E,O,yRCJf,mCA0BejsB,IArBf,WACE,OACE,uBACE7iG,OAAO,SACPT,IAAI,sBACJuM,UAAU,eACVhN,KAAK,mBAEL,kBAAC,IAAD,CAAM0C,KAAK,YAAYsK,UAAU,sBAQjC,kBAAC,IAAD,CAAMtK,KAAK,iBAAiBsK,UAAU,wB,q01BCrB7B,KACbwkH,SAAU,iBACVC,MAAO,cACPC,kBAAmB,wBACnBC,QAAS,gBACTC,SAAU,mB,41CCCNC,G,QAAc,SAAAxlH,GAClB,IAEMylH,EAA2B3wG,uBAAY,WAAM,IACzC+uF,EAA0D7jG,EAA1D6jG,kBAA0D7jG,EAAvC68B,gBAAuC78B,EAAxBi3F,qBAIxC4M,OAoBJ,OAhBAvuF,qBAAU,WACR,IAAMowG,EAAoB,SAAAnwG,IACQvV,EAAM+J,SAAS/J,EAAM68B,gBAAkB,IAC3BkX,MACAx+B,EAAIkD,OAAOs7B,KAGrD0xE,KAKJ,OADAttH,OAAOiS,iBAAiB,iBAAkBs7G,GACnC,kBACLvtH,OAAOkS,oBAAoB,iBAAkBq7G,MAC9C,CAAC1lH,EAAOA,EAAM+J,SAAU/J,EAAM68B,cAAe4oF,IAG9C,yBACE9kH,UAAU,uBACVU,MA9BU,CAAEQ,MAAO,OAAQC,OAAQ,OAAQyG,SAAU,YA+BrDpH,QAASskH,GAET,kBAAC,SAAWzlH,MAKlBwlH,EAAYhiH,UAAY,CACtBqgG,kBAAmB1hG,IAAUI,KAAKF,WAClCw6B,cAAe16B,IAAUC,OAAOC,WAChC40F,oBAAqB90F,IAAUC,OAAOC,WAEtC0H,SAAU5H,IAAUI,MAGtBijH,EAAY3hH,aAAe,CACzBkG,SAAU,cAGGy7G,Q,6qBCrDwC/0F,IAAKiV,MAAMk+D,QAA1DC,E,EAAAA,kBAAmB/iE,E,EAAAA,wBA4EZ6kF,EANcnN,aApEL,SAAC33G,EAAO63G,GAC9B,IAAIkN,EAEA/kH,EAAM2jG,YAAc3jG,EAAM2jG,WAAWqhB,MACvCD,EAAgB/kH,EAAM2jG,WAAWqhB,KAJQ,IAQnChpF,EAAkB67E,EAAlB77E,cACFp6B,EAAWo6B,IAAkBh8B,EAAM83B,UAAUs+D,oBAE7C6uB,EADiBjlH,EAAM83B,UAAUu+D,OAAOv+D,UAAUkE,GACnBgpF,KAAO,GAE5C,UACE5uB,oBAAqBp2F,EAAM83B,UAAUs+D,oBACrCC,OAAQr2F,EAAM83B,UAAUu+D,OACxBz0F,YACGqjH,EAJL,GAOKF,EAPL,CAQEG,oBAAqBtjH,OAIE,SAACw8D,EAAUy5C,GAAa,IACzC77E,EAAkB67E,EAAlB77E,cAER,MAAO,CACLgnE,kBAAmB,WACjB5kC,EAAS4kC,EAAkBhnE,KAG7BiE,wBAAyB,SAAA3vC,GACvB8tE,EAASn+B,EAAwBjE,EAAe1rC,SAKnC,SAACwoH,EAAgBC,EAAmBlB,GAAa,IAC1DsN,EAAkBrM,EAAlBqM,cAyBR,OAvBc,EAAH,GACNrM,EADM,GAENC,EAFM,GAGNlB,EAHM,CAcTuN,UAAW,SAAArpE,GAILopE,GAA0C,mBAAlBA,GAC1BA,EAAcppE,QAOO47D,CAI3BgN,G,q7BCxEIU,E,wcAYF,IAAIC,EAKJ,OAJIllH,KAAKjB,MAAMutE,iBAAkD,MAA/BtsE,KAAKjB,MAAMutE,kBAC3C44C,EAAe,GAAH,OAAMllH,KAAKjB,MAAMutE,gBAAjB,MAIZ,kBAAC,IAAM5mE,SAAP,KACG1F,KAAKjB,MAAMjK,MACV,yBAAK4K,UAAU,qDACb,yBAAKA,UAAU,qBACb,mDACA,uBAAGA,UAAU,eAAb,0BACA,uBAAGA,UAAU,WAAWM,KAAKjB,MAAMjK,MAAMK,WAI7C,yBAAKuK,UAAU,gDACb,yBAAKA,UAAU,qBACb,2BACGM,KAAKjB,MAAM1I,EAAE,cACd,uBAAGqJ,UAAU,uCACZwlH,W,8BAjCcjkH,iB,EAAzBgkH,E,YACe,CACjB34C,gBAAiBprE,IAAUC,OAAOC,WAClCtM,MAAOoM,IAAUrK,S,EAHfouH,E,eAMkB,CACpB34C,gBAAiB,EACjBx3E,MAAO,OAmCI+N,kBAAgB,SAAhBA,CAA0BoiH,G,mvCCpCzC,IAAME,EAAqBr3F,IAAiBs3F,UAAU,gBAE9C5+C,EAAiBh3C,IAAKgV,MAAtBgiC,aAGF6+C,EAAc,GACdC,EAAgB,GA4BhBC,E,6UACI,CACNC,QAAS,KACTC,6BAA8B,KAC9BC,+BAAgC,KAChCp5C,gBAAiB,EACjBvL,UAAU,I,0BA+EM,SAChB7/C,EACA5L,EACAO,EACAmrC,EACApjB,EACA+8C,GACG,IAaCgrC,EACAC,EAbI/gF,EAA0B,EAAK9lC,MAAM84F,gBAAgBvM,SAArDzmD,sBAEFnpB,EAAQ6pG,EAAgBM,oBAC5B3kG,EACA5L,EACAO,EACAmrC,EACApjB,EACA+8C,GAGImrC,EAAkBC,uBAAarqG,EAAM0sD,SAAUvyD,GAI/CmwG,EAAetqG,EAAM0sD,SAAS,GAC5BxoE,EAAUulH,EAAVvlH,MACFqmH,EAAkBrmH,EAAMi9B,OAAOmpF,GAErC,GAAIC,EAAiB,KACXC,EAAwBD,EAAxBC,oBACFC,EAAaF,EAAgBG,YAAYF,GAG7CD,EAAgBG,YAAY11H,OAAS,GACR,IAA7B,EAAKqO,MAAM68B,eAEXiJ,EAAsBqG,KAAK,CACzBlhC,MAAO,iCACP7U,QACE,iEACF5B,KAAM,SAIV,EAAK8yH,0BAA4BF,EAAWG,eAAe3lH,KACzD,SAAA4lH,GACE,MAAO,CAAEjmH,SAAUimH,MAIvB,IAAMC,EAAgB,GAAH,OAAMR,EAAN,YAAsBE,GAEzC,GAAIZ,EAAckB,GAChBb,EAAqBL,EAAckB,OAC9B,aAECC,EAAiBN,EAAWrpD,OAGlC6oD,EAAqBe,UAAaC,cAElC,IAAMC,EAAYC,UAAaF,YAAY,CACzCG,mBAAoB,EACpBl0G,OAAQ,IAAIuoC,YAAYsrE,KAG1Bd,EAAmBoB,eAAeC,WAAWJ,IAC7C,EAAAjB,GAAmBj0G,cAAnB,UAAoCo0G,EAAgBr0G,cACpD,EAAAk0G,GAAmBsB,WAAnB,UACKnB,EAAgBY,aAAaQ,gBAElC,EAAAvB,GAAmBwB,UAAnB,UACKrB,EAAgBY,aAAaU,eAElC,EAAAzB,GAAmB0B,aAAnB,UACKvB,EAAgBY,aAAaY,iBAIlChC,EAAckB,GAAiBb,EAGjCC,EAAmBhmH,EAAM2nH,eAAepB,EAAWqB,eAGrD,MAAO,CACL1B,kBACAH,qBACAC,uB,+RA3IF5uH,QAAQK,IAAI,4B,gCAIZL,QAAQK,IAAI,6BACZmvE,EAAawL,gB,0CAIb9wD,EACA5L,EACAO,EACA+nB,EACA+8C,GAGA,IAAMzkE,EAAQgL,EAAQjL,MACpB,SAAAC,GAAK,OAAIA,EAAMZ,mBAAqBA,KAGhC0oB,EAAa9nB,EAAMg4C,YAAYj4C,MAAK,SAAAilB,GACxC,OAAOA,EAAIrlB,wBAA0BA,KAIjC4xG,EAAcjhD,EAAamJ,kBAAkBz5D,EAAO8nB,GAGpDtiB,EAAQ/qB,OAAOqhC,OAAO,GAAIy1F,GAEhC,QAAmBpyH,IAAfslF,EACFj/D,EAAMmiB,oBAAsB88C,OACvB,GAAI/8C,EAAgB,CACzB,IAAMx4B,EAAQsW,EAAM0sD,SAAS7wD,WAAU,SAAA6mB,GAMrC,OAL8B3Q,IAAYo7C,SAAS7yE,IACjD,iBACAooC,KAG+BR,KAG/Bx4B,GAAS,IACXsW,EAAMmiB,oBAAsBz4B,QAG9BsW,EAAMmiB,oBAAsB,EAG9B,OAAOniB,M,2CA2GSoqG,EAAiBjwG,GACjC,GAAIwvG,EAAYxvG,GACd,OAAOwvG,EAAYxvG,GAFmC,IAKhD6wG,EAAiCZ,EAAjCY,aAAcgB,EAAmB5B,EAAnB4B,eALkC,EAyS5D,SAAmC9mH,EAAOo9F,GAExC,MAAiB,QAFqD,4DAAX3oG,GAGlD,CAAEsyH,MAAO,EAAGC,MAAO,GAGAlyC,MAAMsoB,IAAWtoB,MAAM90E,GAG1C,CAAE+mH,MAAO,EAAGC,MAAO,KAGrB,CACLD,MAAO3pB,EAASp9F,EAAQ,EACxBgnH,MAAO5pB,EAASp9F,EAAQ,GAzSCinH,CAFrBH,EAHFrjE,YAGEqjE,EAFFtjE,aAEEsjE,EADF9nE,UAGM+nE,EAdgD,EAchDA,MAAOC,EAdyC,EAczCA,MAKTE,EAAcC,UAAUpB,cACxBqB,EAAeC,UAAgBtB,cAErCmB,EAAYI,UAAUF,GACtBA,EAAaG,aAAazB,GAE1BoB,EACGM,cACAC,uBAAuB,GACvBC,SAASX,EAAOC,GAEnB,IAAMz6D,EAAUu5D,EAAaQ,aAGvBqB,GAAkBp7D,EAAQ,GAAKA,EAAQ,GAAKA,EAAQ,IAAM,EAUhE,OARA66D,EAAaQ,kBAAkBD,GAI/BP,EAAaS,wBAAwB,KAErCpD,EAAYxvG,GAAyBiyG,EAE9BA,I,0CAGW,aACc9nH,KAAKjB,MAAMmgC,aAAnChe,EADU,EACVA,QAAS8c,EADC,EACDA,WAEf1oB,EAKE0oB,EALF1oB,iBACAO,EAIEmoB,EAJFnoB,sBACA85C,EAGE3xB,EAHF2xB,aACA/xB,EAEEI,EAFFJ,eACA+8C,EACE38C,EADF28C,WAGEhrB,EAAaj/D,OAAS,GACxBsG,QAAQM,KACN,sEAIJ,IAAM4e,EAAQgL,EAAQjL,MACpB,SAAAC,GAAK,OAAIA,EAAMZ,mBAAqBA,KAGhCozG,EAAc,CAClBhhE,UAAWxxC,EAAMwxC,UACjBC,UAAWzxC,EAAMyxC,UACjBF,iBAAkBvxC,EAAMuxC,iBACxBb,YAAa1wC,EAAM0wC,YACnBC,UAAW3wC,EAAM2wC,UACjB/G,aAAc3nC,OAAO6lB,EAAW8hB,cAChCygD,kBAAmBviE,EAAWuiE,mBAGhC,IAAI,MAKEvgG,KAAK2oH,gBACPznG,EACA5L,EACAO,EACA+nB,EACA+8C,GARAmrC,EAFA,EAEAA,gBACAH,EAHA,EAGAA,mBACAC,EAJA,EAIAA,iBASF5lH,KAAK8lH,gBAAkBA,EAOvB,IAAMgC,EAAc9nH,KAAK4oH,kBACvB9C,EACAjwG,GAGF7V,KAAKF,SACH,CACEwsE,gBAAiB,EACjBo8C,gBAEF,WACE,EAAKG,kBAAkB/C,GAMvBxwH,YAAW,WACT,EAAKwK,SAAS,CACZ0lH,QAAS,CAACsC,GACVrC,6BAA8BE,EAC9BD,+BAAgCI,EAAgBY,aAChDd,uBAED,QAGP,MAAO9wH,GAEPkC,QAAQlC,MADW,wBACOA,GAFZ,MAMVkL,KAAKjB,MAAM84F,gBAAgBvM,SAF7BzmD,EAJY,EAIZA,sBACAI,EALY,EAKZA,cAEF,GAAiC,IAA7BjlC,KAAKjB,MAAM68B,cAAqB,CAClC,IAAMzmC,EAAUL,EAAMK,QAAQ2Y,SAAS,UACnC,uCACAhZ,EAAMK,QACV8vC,EAAcnwC,MAAM,CAAEA,QAAOK,YAC7B0vC,EAAsBqG,KAAK,CACzBlhC,MAZe,wBAaf7U,UACA5B,KAAM,QACNs4C,WAAW,EACXE,OAAQ,CACNjqC,MAAO,cACP5B,QAAS,aAEP8rC,EAFsB,EAAZA,SAGV,EAAKjtC,MAAM64F,gBAAgBoB,WAAW,4BAK9Ch5F,KAAKF,SAAS,CAAEihE,UAAU,O,0CAK5B/gE,KAAK8oH,sB,yCAGY9lH,EAAW4U,GAAW,IAC/BomB,EAAeh+B,KAAKjB,MAAMmgC,aAA1BlB,WACF+qF,EAAiB/lH,EAAUk8B,aAAalB,WAG5CA,EAAWnoB,wBACXkzG,EAAelzG,uBACfmoB,EAAWJ,iBAAmBmrF,EAAenrF,gBAC7CI,EAAW28C,aAAeouC,EAAepuC,YAEzC36E,KAAK8oH,sB,wCAIShD,GAAiB,WACjCkD,wBAAclD,GADmB,IAGzB7kG,EAAwB6kG,EAAxB7kG,UAAWmnD,EAAa09C,EAAb19C,SAEnB,GAAKnnD,EAAL,CAKA,IAAM4qC,EAAiBuc,EAAS13E,OA0ChCo1H,EAAgBmD,qBAxCoB,SAAAC,GAClC,IAAM58C,EAAkB/4D,KAAKw9B,MACR,IAAlBm4E,EAAyBr9D,GAGxBygB,IAAoB,EAAK1sE,MAAM0sE,iBACjC,EAAKxsE,SAAS,CACZwsE,uBAkCNw5C,EAAgBqD,wBAPuB,WACrC,EAAKrpH,SAAS,CACZihE,UAAU,OAMd+kD,EAAgBsD,0BA9ByB,SAAAt0H,GAAS,MAI5C,EAAKiK,MAAM84F,gBAAgBvM,SAF7BzmD,EAF8C,EAE9CA,sBACAI,EAH8C,EAG9CA,cAGG,EAAKtyB,WACyB,IAA7B,EAAK5T,MAAM68B,gBAEbqJ,EAAcnwC,MAAM,CAAEA,QAAOK,QAASL,EAAMK,UAC5C0vC,EAAsBqG,KAAK,CACzBlhC,MAAO,iBACP7U,QAASL,EAAMK,QACf5B,KAAM,QACNs4C,WAAW,KAIf,EAAKl5B,UAAW,WApClB3S,KAAKF,SAAS,CAAEihE,UAAU,M,+BAmDrB,WACHsoD,EAAoB,KAChB73C,EAAkB2zC,EAAlB3zC,cAiBR,OAdIxxE,KAAKjB,MAAM2E,UAAY1D,KAAKjB,MAAM2E,SAAShT,SAC7C24H,EAAoBrpH,KAAKjB,MAAM2E,SAAS/C,KAAI,SAACs1C,EAAO7wC,GAClD,OACE6wC,GACAlwB,IAAM8vB,aAAaI,EAAO,CACxBra,cAAe,EAAK78B,MAAM68B,cAC1BllC,IAAK0O,QASX,oCACE,yBAAKhF,MAJK,CAAEQ,MAAO,OAAQC,OAAQ,OAAQyG,SAAU,cAKjDtH,KAAKJ,MAAMmhE,UACX,kBAAC,EAAD,CAAkBuL,gBAAiBtsE,KAAKJ,MAAM0sE,kBAE/CtsE,KAAKJ,MAAM4lH,SACV,kBAAC,EAAD,CACEA,QAASxlH,KAAKJ,MAAM4lH,QACpBC,6BACEzlH,KAAKJ,MAAM6lH,6BAEbC,+BACE1lH,KAAKJ,MAAM8lH,+BAEb9pF,cAAe57B,KAAKjB,MAAM68B,cAC1B8sF,YAAa1oH,KAAKJ,MAAM8oH,YACxBY,yBAA0B,CACxBC,SAAUvpH,KAAKJ,MAAMgmH,iBACrB4D,cAAeh4C,EAAci4C,UAC7BnpH,QAASkxE,EAAck4C,WACvBC,iBAAkBn4C,EAAco4C,aAChCC,cAAer4C,EAAcq4C,cAC7BxD,0BAA2BrmH,KAAKqmH,0BAChCyD,2BAA4B,WAC1B,EAAKhB,sBAGThgH,SAAU9I,KAAKjB,MAAM+J,YA3B7B,KAgCGugH,Q,8BAtdqB1lH,a,EAAxB4hH,E,YASe,CACjBrmF,aAAch+B,IAAUyB,MAAM,CAC5Bue,QAAShgB,IAAUiK,MAAM/J,WACzB48B,WAAY98B,IAAUyB,MAAM,CAC1B2S,iBAAkBpU,IAAUuB,OAAOrB,WACnCyU,sBAAuB3U,IAAUuB,OAAOrB,WACxCuuD,aAAczuD,IAAU0L,QAAQ1L,IAAUuB,QAC1Cm7B,eAAgB18B,IAAUuB,OAC1Bk4E,WAAYz5E,IAAUC,WAG1By6B,cAAe16B,IAAUC,OAAOC,WAChCsC,SAAUxC,IAAU0C,KACpBkF,SAAU5H,IAAUI,KACpBu2F,gBAAiB32F,IAAUrK,OAAOuK,a,EAvBhCmkH,E,eA0BkB,CACpBz8G,SAAU,e,EA3BRy8G,E,KA8BQ,mBA0dCA,a,2qBCviBf,IAAI5kH,EAAM,CACT,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,aAAc,IACd,UAAW,IACX,aAAc,IACd,UAAW,IACX,aAAc,IACd,UAAW,IACX,aAAc,IACd,UAAW,IACX,aAAc,IACd,UAAW,IACX,aAAc,IACd,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,aAAc,IACd,UAAW,IACX,aAAc,IACd,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,UAAW,IACX,aAAc,IACd,UAAW,IACX,aAAc,IACd,UAAW,IACX,aAAc,IACd,UAAW,IACX,aAAc,IACd,UAAW,IACX,aAAc,IACd,UAAW,IACX,aAAc,IACd,UAAW,IACX,aAAc,IACd,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,aAAc,IACd,UAAW,IACX,aAAc,IACd,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,aAAc,IACd,UAAW,IACX,aAAc,IACd,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,aAAc,IACd,gBAAiB,IACjB,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,UAAW,IACX,aAAc,IACd,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,aAAc,IACd,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR,UAAW,IACX,aAAc,IACd,UAAW,IACX,OAAQ,IACR,UAAW,IACX,OAAQ,IACR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","file":"app.bundle.e0d8a9a2b3e06de7adc1.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded CSS chunks\n \tvar installedCssChunks = {\n \t\t8: 0\n \t}\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t8: 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// script path function\n \tfunction jsonpScriptSrc(chunkId) {\n \t\treturn __webpack_require__.p + \"\" + ({\"0\":\"ConnectedStandaloneRouting~IHEInvokeImageDisplay~StudyListRouting~ViewerLocalFileData~ViewerRouting\",\"1\":\"ConnectedStandaloneRouting~IHEInvokeImageDisplay~ViewerLocalFileData~ViewerRouting\",\"2\":\"CallbackPage\",\"3\":\"ConnectedStandaloneRouting\",\"4\":\"IHEInvokeImageDisplay\",\"5\":\"StudyListRouting\",\"6\":\"ViewerLocalFileData\",\"7\":\"ViewerRouting\",\"9\":\"vendors~ViewerLocalFileData\",\"11\":\"vendors~dicom-microscopy-viewer\"}[chunkId]||chunkId) + \".bundle.\" + {\"0\":\"789919e5b106d4165b70\",\"1\":\"1bd534b47b718a551682\",\"2\":\"846428649ae447fca9d6\",\"3\":\"802d813a62f9caec3431\",\"4\":\"c081924f4c0d21f5ac64\",\"5\":\"07549daa66faadef6b6b\",\"6\":\"d6fb3e58917d8ac13249\",\"7\":\"143baf7c6cf58e150fbf\",\"9\":\"e552bfe8b81016df95a3\",\"11\":\"a7b221b7ff55f42ac881\",\"12\":\"340d4a6b6f5a77e1d56b\",\"13\":\"ee18290a1eb7f5fc84a3\",\"14\":\"df200af38c75c5eda904\",\"15\":\"807ff2a12bc86f93b42b\",\"16\":\"b6db09222e580b2e1b90\",\"17\":\"f1e5afe6cf3f6997a2b0\",\"18\":\"2a9a3c31cf8d7f664e24\"}[chunkId] + \".js\"\n \t}\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tvar promises = [];\n\n\n \t\t// extract-css-chunks-webpack-plugin CSS loading\n \t\tvar cssChunks = {\"0\":1,\"1\":1,\"5\":1,\"6\":1,\"13\":1,\"14\":1,\"15\":1};\n \t\tif(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);\n \t\telse if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {\n \t\t\tpromises.push(installedCssChunks[chunkId] = new Promise(function(resolve, reject) {\n \t\t\t\tvar href = \"\" + chunkId + \".\" + \"e75f63d3bdc28344a6cc\" + \".css\";\n \t\t\t\tvar fullhref = __webpack_require__.p + href;\n \t\t\t\tvar existingLinkTags = document.getElementsByTagName(\"link\");\n \t\t\t\tfor(var i = 0; i < existingLinkTags.length; i++) {\n \t\t\t\t\tvar tag = existingLinkTags[i];\n \t\t\t\t\tvar dataHref = tag.getAttribute(\"data-href\") || tag.getAttribute(\"href\");\n \t\t\t\t\tif(tag.rel === \"stylesheet\" && (dataHref === href || dataHref === fullhref)) return resolve();\n \t\t\t\t}\n \t\t\t\tvar existingStyleTags = document.getElementsByTagName(\"style\");\n \t\t\t\tfor(var i = 0; i < existingStyleTags.length; i++) {\n \t\t\t\t\tvar tag = existingStyleTags[i];\n \t\t\t\t\tvar dataHref = tag.getAttribute(\"data-href\");\n \t\t\t\t\tif(dataHref === href || dataHref === fullhref) return resolve();\n \t\t\t\t}\n \t\t\t\tvar linkTag = document.createElement(\"link\");\n \t\t\t\tlinkTag.rel = \"stylesheet\";\n \t\t\t\tlinkTag.type = \"text/css\";\n \t\t\t\tlinkTag.onload = resolve;\n \t\t\t\tlinkTag.onerror = function(event) {\n \t\t\t\t\tvar request = event && event.target && event.target.src || fullhref;\n \t\t\t\t\tvar err = new Error(\"Loading CSS chunk \" + chunkId + \" failed.\\n(\" + request + \")\");\n \t\t\t\t\terr.code = \"CSS_CHUNK_LOAD_FAILED\";\n \t\t\t\t\terr.request = request;\n \t\t\t\t\tdelete installedCssChunks[chunkId]\n \t\t\t\t\tlinkTag.parentNode.removeChild(linkTag)\n \t\t\t\t\treject(err);\n \t\t\t\t};\n \t\t\t\tlinkTag.href = fullhref;\n\n \t\t\t\tvar head = document.getElementsByTagName(\"head\")[0];\n \t\t\t\thead.appendChild(linkTag);\n \t\t\t}).then(function() {\n \t\t\t\tinstalledCssChunks[chunkId] = 0;\n \t\t\t}));\n \t\t}\n\n \t\t// JSONP chunk loading for javascript\n\n \t\tvar installedChunkData = installedChunks[chunkId];\n \t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n \t\t\t// a Promise means \"currently loading\".\n \t\t\tif(installedChunkData) {\n \t\t\t\tpromises.push(installedChunkData[2]);\n \t\t\t} else {\n \t\t\t\t// setup Promise in chunk cache\n \t\t\t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\t\t\tinstalledChunkData = installedChunks[chunkId] = [resolve, reject];\n \t\t\t\t});\n \t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n \t\t\t\t// start chunk loading\n \t\t\t\tvar script = document.createElement('script');\n \t\t\t\tvar onScriptComplete;\n\n \t\t\t\tscript.charset = 'utf-8';\n \t\t\t\tscript.timeout = 120;\n \t\t\t\tif (__webpack_require__.nc) {\n \t\t\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t\t\t}\n \t\t\t\tscript.src = jsonpScriptSrc(chunkId);\n\n \t\t\t\t// create error before stack unwound to get useful stacktrace later\n \t\t\t\tvar error = new Error();\n \t\t\t\tonScriptComplete = function (event) {\n \t\t\t\t\t// avoid mem leaks in IE.\n \t\t\t\t\tscript.onerror = script.onload = null;\n \t\t\t\t\tclearTimeout(timeout);\n \t\t\t\t\tvar chunk = installedChunks[chunkId];\n \t\t\t\t\tif(chunk !== 0) {\n \t\t\t\t\t\tif(chunk) {\n \t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n \t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n \t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n \t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n \t\t\t\t\t\t\terror.type = errorType;\n \t\t\t\t\t\t\terror.request = realSrc;\n \t\t\t\t\t\t\tchunk[1](error);\n \t\t\t\t\t\t}\n \t\t\t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t\t\t}\n \t\t\t\t};\n \t\t\t\tvar timeout = setTimeout(function(){\n \t\t\t\t\tonScriptComplete({ type: 'timeout', target: script });\n \t\t\t\t}, 120000);\n \t\t\t\tscript.onerror = script.onload = onScriptComplete;\n \t\t\t\tdocument.head.appendChild(script);\n \t\t\t}\n \t\t}\n \t\treturn Promise.all(promises);\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// add entry module to deferred list\n \tdeferredModules.push([1023,10]);\n \t// run deferred modules when ready\n \treturn checkDeferredModules();\n","const log = {\n error: console.error,\n warn: console.warn,\n info: console.log,\n trace: console.trace,\n debug: console.debug,\n time: console.time,\n timeEnd: console.timeEnd,\n};\n\nexport default log;\n","// TODO: Deprecate since we have the same thing in dcmjs?\nexport const sopClassDictionary = {\n ComputedRadiographyImageStorage: '1.2.840.10008.5.1.4.1.1.1',\n DigitalXRayImageStorageForPresentation: '1.2.840.10008.5.1.4.1.1.1.1',\n DigitalXRayImageStorageForProcessing: '1.2.840.10008.5.1.4.1.1.1.1.1',\n DigitalMammographyXRayImageStorageForPresentation:\n '1.2.840.10008.5.1.4.1.1.1.2',\n DigitalMammographyXRayImageStorageForProcessing:\n '1.2.840.10008.5.1.4.1.1.1.2.1',\n DigitalIntraOralXRayImageStorageForPresentation:\n '1.2.840.10008.5.1.4.1.1.1.3',\n DigitalIntraOralXRayImageStorageForProcessing:\n '1.2.840.10008.5.1.4.1.1.1.3.1',\n CTImageStorage: '1.2.840.10008.5.1.4.1.1.2',\n EnhancedCTImageStorage: '1.2.840.10008.5.1.4.1.1.2.1',\n LegacyConvertedEnhancedCTImageStorage: '1.2.840.10008.5.1.4.1.1.2.2',\n UltrasoundMultiframeImageStorage: '1.2.840.10008.5.1.4.1.1.3.1',\n MRImageStorage: '1.2.840.10008.5.1.4.1.1.4',\n EnhancedMRImageStorage: '1.2.840.10008.5.1.4.1.1.4.1',\n MRSpectroscopyStorage: '1.2.840.10008.5.1.4.1.1.4.2',\n EnhancedMRColorImageStorage: '1.2.840.10008.5.1.4.1.1.4.3',\n LegacyConvertedEnhancedMRImageStorage: '1.2.840.10008.5.1.4.1.1.4.4',\n UltrasoundImageStorage: '1.2.840.10008.5.1.4.1.1.6.1',\n EnhancedUSVolumeStorage: '1.2.840.10008.5.1.4.1.1.6.2',\n SecondaryCaptureImageStorage: '1.2.840.10008.5.1.4.1.1.7',\n MultiframeSingleBitSecondaryCaptureImageStorage:\n '1.2.840.10008.5.1.4.1.1.7.1',\n MultiframeGrayscaleByteSecondaryCaptureImageStorage:\n '1.2.840.10008.5.1.4.1.1.7.2',\n MultiframeGrayscaleWordSecondaryCaptureImageStorage:\n '1.2.840.10008.5.1.4.1.1.7.3',\n MultiframeTrueColorSecondaryCaptureImageStorage:\n '1.2.840.10008.5.1.4.1.1.7.4',\n Sop12LeadECGWaveformStorage: '1.2.840.10008.5.1.4.1.1.9.1.1',\n GeneralECGWaveformStorage: '1.2.840.10008.5.1.4.1.1.9.1.2',\n AmbulatoryECGWaveformStorage: '1.2.840.10008.5.1.4.1.1.9.1.3',\n HemodynamicWaveformStorage: '1.2.840.10008.5.1.4.1.1.9.2.1',\n CardiacElectrophysiologyWaveformStorage: '1.2.840.10008.5.1.4.1.1.9.3.1',\n BasicVoiceAudioWaveformStorage: '1.2.840.10008.5.1.4.1.1.9.4.1',\n GeneralAudioWaveformStorage: '1.2.840.10008.5.1.4.1.1.9.4.2',\n ArterialPulseWaveformStorage: '1.2.840.10008.5.1.4.1.1.9.5.1',\n RespiratoryWaveformStorage: '1.2.840.10008.5.1.4.1.1.9.6.1',\n GrayscaleSoftcopyPresentationStateStorage: '1.2.840.10008.5.1.4.1.1.11.1',\n ColorSoftcopyPresentationStateStorage: '1.2.840.10008.5.1.4.1.1.11.2',\n PseudoColorSoftcopyPresentationStateStorage: '1.2.840.10008.5.1.4.1.1.11.3',\n BlendingSoftcopyPresentationStateStorage: '1.2.840.10008.5.1.4.1.1.11.4',\n XAXRFGrayscaleSoftcopyPresentationStateStorage:\n '1.2.840.10008.5.1.4.1.1.11.5',\n XRayAngiographicImageStorage: '1.2.840.10008.5.1.4.1.1.12.1',\n EnhancedXAImageStorage: '1.2.840.10008.5.1.4.1.1.12.1.1',\n XRayRadiofluoroscopicImageStorage: '1.2.840.10008.5.1.4.1.1.12.2',\n EnhancedXRFImageStorage: '1.2.840.10008.5.1.4.1.1.12.2.1',\n XRay3DAngiographicImageStorage: '1.2.840.10008.5.1.4.1.1.13.1.1',\n XRay3DCraniofacialImageStorage: '1.2.840.10008.5.1.4.1.1.13.1.2',\n BreastTomosynthesisImageStorage: '1.2.840.10008.5.1.4.1.1.13.1.3',\n BreastProjectionXRayImageStorageForPresentation:\n '1.2.840.10008.5.1.4.1.1.13.1.4',\n BreastProjectionXRayImageStorageForProcessing:\n '1.2.840.10008.5.1.4.1.1.13.1.5',\n IntravascularOpticalCoherenceTomographyImageStorageForPresentation:\n '1.2.840.10008.5.1.4.1.1.14.1',\n IntravascularOpticalCoherenceTomographyImageStorageForProcessing:\n '1.2.840.10008.5.1.4.1.1.14.2',\n NuclearMedicineImageStorage: '1.2.840.10008.5.1.4.1.1.20',\n RawDataStorage: '1.2.840.10008.5.1.4.1.1.66',\n SpatialRegistrationStorage: '1.2.840.10008.5.1.4.1.1.66.1',\n SpatialFiducialsStorage: '1.2.840.10008.5.1.4.1.1.66.2',\n DeformableSpatialRegistrationStorage: '1.2.840.10008.5.1.4.1.1.66.3',\n SegmentationStorage: '1.2.840.10008.5.1.4.1.1.66.4',\n SurfaceSegmentationStorage: '1.2.840.10008.5.1.4.1.1.66.5',\n RealWorldValueMappingStorage: '1.2.840.10008.5.1.4.1.1.67',\n SurfaceScanMeshStorage: '1.2.840.10008.5.1.4.1.1.68.1',\n SurfaceScanPointCloudStorage: '1.2.840.10008.5.1.4.1.1.68.2',\n VLEndoscopicImageStorage: '1.2.840.10008.5.1.4.1.1.77.1.1',\n VideoEndoscopicImageStorage: '1.2.840.10008.5.1.4.1.1.77.1.1.1',\n VLMicroscopicImageStorage: '1.2.840.10008.5.1.4.1.1.77.1.2',\n VideoMicroscopicImageStorage: '1.2.840.10008.5.1.4.1.1.77.1.2.1',\n VLSlideCoordinatesMicroscopicImageStorage: '1.2.840.10008.5.1.4.1.1.77.1.3',\n VLPhotographicImageStorage: '1.2.840.10008.5.1.4.1.1.77.1.4',\n VideoPhotographicImageStorage: '1.2.840.10008.5.1.4.1.1.77.1.4.1',\n OphthalmicPhotography8BitImageStorage: '1.2.840.10008.5.1.4.1.1.77.1.5.1',\n OphthalmicPhotography16BitImageStorage: '1.2.840.10008.5.1.4.1.1.77.1.5.2',\n StereometricRelationshipStorage: '1.2.840.10008.5.1.4.1.1.77.1.5.3',\n OphthalmicTomographyImageStorage: '1.2.840.10008.5.1.4.1.1.77.1.5.4',\n VLWholeSlideMicroscopyImageStorage: '1.2.840.10008.5.1.4.1.1.77.1.6',\n LensometryMeasurementsStorage: '1.2.840.10008.5.1.4.1.1.78.1',\n AutorefractionMeasurementsStorage: '1.2.840.10008.5.1.4.1.1.78.2',\n KeratometryMeasurementsStorage: '1.2.840.10008.5.1.4.1.1.78.3',\n SubjectiveRefractionMeasurementsStorage: '1.2.840.10008.5.1.4.1.1.78.4',\n VisualAcuityMeasurementsStorage: '1.2.840.10008.5.1.4.1.1.78.5',\n SpectaclePrescriptionReportStorage: '1.2.840.10008.5.1.4.1.1.78.6',\n OphthalmicAxialMeasurementsStorage: '1.2.840.10008.5.1.4.1.1.78.7',\n IntraocularLensCalculationsStorage: '1.2.840.10008.5.1.4.1.1.78.8',\n MacularGridThicknessandVolumeReport: '1.2.840.10008.5.1.4.1.1.79.1',\n OphthalmicVisualFieldStaticPerimetryMeasurementsStorage:\n '1.2.840.10008.5.1.4.1.1.80.1',\n OphthalmicThicknessMapStorage: '1.2.840.10008.5.1.4.1.1.81.1',\n CornealTopographyMapStorage: '1.2.840.10008.5.1.4.1.1.82.1',\n BasicTextSR: '1.2.840.10008.5.1.4.1.1.88.11',\n EnhancedSR: '1.2.840.10008.5.1.4.1.1.88.22',\n ComprehensiveSR: '1.2.840.10008.5.1.4.1.1.88.33',\n Comprehensive3DSR: '1.2.840.10008.5.1.4.1.1.88.34',\n ProcedureLog: '1.2.840.10008.5.1.4.1.1.88.40',\n MammographyCADSR: '1.2.840.10008.5.1.4.1.1.88.50',\n KeyObjectSelection: '1.2.840.10008.5.1.4.1.1.88.59',\n ChestCADSR: '1.2.840.10008.5.1.4.1.1.88.65',\n XRayRadiationDoseSR: '1.2.840.10008.5.1.4.1.1.88.67',\n RadiopharmaceuticalRadiationDoseSR: '1.2.840.10008.5.1.4.1.1.88.68',\n ColonCADSR: '1.2.840.10008.5.1.4.1.1.88.69',\n ImplantationPlanSRDocumentStorage: '1.2.840.10008.5.1.4.1.1.88.70',\n EncapsulatedPDFStorage: '1.2.840.10008.5.1.4.1.1.104.1',\n EncapsulatedCDAStorage: '1.2.840.10008.5.1.4.1.1.104.2',\n PositronEmissionTomographyImageStorage: '1.2.840.10008.5.1.4.1.1.128',\n EnhancedPETImageStorage: '1.2.840.10008.5.1.4.1.1.130',\n LegacyConvertedEnhancedPETImageStorage: '1.2.840.10008.5.1.4.1.1.128.1',\n BasicStructuredDisplayStorage: '1.2.840.10008.5.1.4.1.1.131',\n RTImageStorage: '1.2.840.10008.5.1.4.1.1.481.1',\n RTDoseStorage: '1.2.840.10008.5.1.4.1.1.481.2',\n RTStructureSetStorage: '1.2.840.10008.5.1.4.1.1.481.3',\n RTBeamsTreatmentRecordStorage: '1.2.840.10008.5.1.4.1.1.481.4',\n RTPlanStorage: '1.2.840.10008.5.1.4.1.1.481.5',\n RTBrachyTreatmentRecordStorage: '1.2.840.10008.5.1.4.1.1.481.6',\n RTTreatmentSummaryRecordStorage: '1.2.840.10008.5.1.4.1.1.481.7',\n RTIonPlanStorage: '1.2.840.10008.5.1.4.1.1.481.8',\n RTIonBeamsTreatmentRecordStorage: '1.2.840.10008.5.1.4.1.1.481.9',\n RTBeamsDeliveryInstructionStorage: '1.2.840.10008.5.1.4.34.7',\n GenericImplantTemplateStorage: '1.2.840.10008.5.1.4.43.1',\n ImplantAssemblyTemplateStorage: '1.2.840.10008.5.1.4.44.1',\n ImplantTemplateGroupStorage: '1.2.840.10008.5.1.4.45.1',\n};\n","import React, { PureComponent } from 'react';\nimport PropTypes from 'prop-types';\nimport './LayoutChooser.styl';\n\n/**\n * Adds the 'hover' class to cells above and to the left of the current cell\n * This is used to \"fill in\" the grid that the user will change the layout to,\n * if they click on a specific table cell.\n **/\n\nclass LayoutChooser extends PureComponent {\n static propTypes = {\n Rows: PropTypes.number.isRequired,\n Columns: PropTypes.number.isRequired,\n visible: PropTypes.bool.isRequired,\n selectedCell: PropTypes.object,\n boxSize: PropTypes.number.isRequired,\n cellBorder: PropTypes.number.isRequired,\n onClick: PropTypes.func,\n onChange: PropTypes.func,\n };\n\n static defaultProps = {\n Rows: 3,\n Columns: 3,\n visible: true,\n boxSize: 20,\n cellBorder: 1,\n selectedCell: {\n row: -1,\n col: -1,\n },\n };\n\n constructor(props) {\n super(props);\n this.emptyCell = {\n row: -1,\n column: -1,\n };\n this.state = {\n table: [[]],\n selectedCell: this.props.selectedCell,\n };\n }\n componentDidMount() {\n this.highlightCells(this.emptyCell);\n }\n onClick(currentCell) {\n this.setState({\n selectedCell: currentCell,\n });\n this.highlightCells(currentCell);\n if (this.props.onClick) {\n this.props.onClick(currentCell);\n }\n if (this.props.onChange) {\n this.props.onChange(currentCell);\n }\n }\n isRange = (cell, parentCell) => {\n return cell.row <= parentCell.row && cell.col <= parentCell.col;\n };\n highlightCells = currentCell => {\n let table = [];\n for (let row = 0; row < this.props.Rows; row++) {\n let newRow = [];\n for (let col = 0; col < this.props.Columns; col++) {\n let cell = { row: row, col: col };\n if (this.isRange(cell, currentCell)) {\n cell.className = 'hover';\n } else if (\n this.isRange(currentCell, this.emptyCell) &&\n this.isRange(cell, this.state.selectedCell)\n ) {\n cell.className = 'selectedBefore';\n }\n newRow.push(cell);\n }\n table.push(newRow);\n }\n this.setState({ table: table });\n };\n\n render() {\n let Columns = this.props.Columns;\n const style = {\n display: this.props.visible ? 'block' : 'none',\n minWidth:\n Columns * this.props.boxSize + (Columns + 5) * this.props.cellBorder,\n };\n return (\n \n \n \n {this.state.table.map((row, i) => {\n return (\n \n {row.map((cell, j) => {\n return (\n this.highlightCells(cell)}\n onMouseLeave={() => this.highlightCells(this.emptyCell)}\n onClick={() => this.onClick(cell)}\n />\n );\n })}\n \n );\n })}\n \n
\n \n );\n }\n}\n\nexport { LayoutChooser };\n","import './toolbar-button.styl';\n\nimport { Icon } from './../elements/Icon';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport classnames from 'classnames';\nimport { withTranslation } from '../contextProviders';\n\nexport function ToolbarButton(props) {\n const { isActive, icon, labelWhenActive, onClick, t } = props;\n const className = classnames(props.className, { active: isActive });\n const iconProps = typeof icon === 'string' ? { name: icon } : icon;\n const label = isActive && labelWhenActive ? labelWhenActive : props.label;\n\n const arrowIconName = props.isExpanded ? 'caret-up' : 'caret-down';\n const arrowIcon = props.isExpandable && (\n \n );\n\n const handleClick = event => {\n if (onClick) {\n onClick(event, props);\n }\n };\n\n const cypressSelectorId = props.label.toLowerCase();\n\n return (\n \n {iconProps && }\n
\n {t(label)}\n {arrowIcon}\n
\n \n );\n}\n\nToolbarButton.propTypes = {\n id: PropTypes.string,\n isActive: PropTypes.bool,\n /** Display label for button */\n label: PropTypes.string.isRequired,\n /** Alternative text to show when button is active */\n labelWhenActive: PropTypes.string,\n className: PropTypes.string.isRequired,\n icon: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.shape({\n name: PropTypes.string.isRequired,\n }),\n ]),\n onClick: PropTypes.func,\n /** Determines if we show expandable 'caret' symbol */\n isExpandable: PropTypes.bool,\n /** Direction of expandable 'caret' symbol */\n isExpanded: PropTypes.bool,\n t: PropTypes.func.isRequired,\n};\n\nToolbarButton.defaultProps = {\n isActive: false,\n className: 'toolbar-button',\n};\n\nexport default withTranslation('Buttons')(ToolbarButton);\n","import React, { PureComponent } from 'react';\n\nimport { LayoutChooser } from './LayoutChooser.js';\nimport PropTypes from 'prop-types';\nimport ToolbarButton from '../../viewer/ToolbarButton';\n\nexport class LayoutButton extends PureComponent {\n static defaultProps = {\n dropdownVisible: false,\n };\n\n static propTypes = {\n dropdownVisible: PropTypes.bool.isRequired,\n /** Called with the selectedCell number when grid sell is selected */\n onChange: PropTypes.func,\n /** The cell to show as selected */\n selectedCell: PropTypes.object,\n };\n\n state = {\n dropdownVisible: this.props.dropdownVisible,\n };\n\n componentDidUpdate(prevProps) {\n if (this.props.dropdownVisible !== prevProps.dropdownVisible) {\n this.setState({\n dropdownVisible: this.props.dropdownVisible,\n });\n }\n }\n\n onClick = () => {\n this.setState({\n dropdownVisible: !this.state.dropdownVisible,\n });\n };\n\n onChange = selectedCell => {\n if (this.props.onChange) {\n this.props.onChange(selectedCell);\n }\n };\n\n render() {\n return (\n
\n \n \n
\n );\n }\n}\n\nexport default LayoutButton;\n","import './TableListItem.styl';\n\nimport { Component } from 'react';\nimport { Icon } from './../../elements/Icon';\nimport PropTypes from 'prop-types';\nimport React from 'react';\n\nexport class TableListItem extends Component {\n static propTypes = {\n children: PropTypes.node,\n itemClass: PropTypes.string,\n itemIndex: PropTypes.number,\n itemMeta: PropTypes.node,\n itemMetaClass: PropTypes.string,\n itemKey: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.number,\n ]),\n onItemClick: PropTypes.func.isRequired,\n };\n\n static defaultProps = {\n itemMeta: null,\n itemMetaClass: ''\n };\n\n render() {\n return (\n \n
\n {this.props.itemIndex}\n {this.props.itemMeta}\n \n \n \n
\n
{this.props.children}
\n \n );\n }\n\n onItemClick = event => {\n if (this.props.onItemClick) {\n event.preventDefault();\n event.stopPropagation();\n\n this.props.onItemClick(event, this.props.itemKey);\n }\n };\n}\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport { withTranslation } from '../../contextProviders';\n\nimport { Icon } from './../../elements/Icon';\nimport { OverlayTrigger } from './../overlayTrigger';\nimport { Tooltip } from './../tooltip';\nimport { TableListItem } from './../tableList/TableListItem.js';\n\nimport './MeasurementTableItem.styl';\n\nclass MeasurementTableItem extends Component {\n static propTypes = {\n measurementData: PropTypes.object.isRequired,\n onItemClick: PropTypes.func.isRequired,\n onRelabel: PropTypes.func,\n onDelete: PropTypes.func,\n onEditDescription: PropTypes.func,\n itemClass: PropTypes.string,\n itemIndex: PropTypes.number,\n t: PropTypes.func,\n };\n\n render() {\n const {\n warningTitle = '',\n hasWarnings,\n isReadOnly,\n } = this.props.measurementData;\n\n return (\n \n {hasWarnings && !isReadOnly ? (\n \n
{this.props.t(warningTitle)}
\n
{this.getWarningContent()}
\n \n }\n >\n
{this.getTableListItem()}
\n \n ) : (\n {this.getTableListItem()}\n )}\n
\n );\n }\n\n getActionButton = (btnLabel, onClickCallback) => {\n return (\n \n );\n };\n\n getTableListItem = () => {\n const hasWarningClass =\n this.props.measurementData.hasWarnings &&\n !this.props.measurementData.isReadOnly\n ? 'hasWarnings'\n : '';\n\n const actionButtons = [];\n\n if (typeof this.props.onRelabel === 'function') {\n const relabelButton = this.getActionButton(\n 'Relabel',\n this.onRelabelClick\n );\n actionButtons.push(relabelButton);\n }\n if (typeof this.props.onEditDescription === 'function') {\n const descriptionButton = this.getActionButton(\n 'Description',\n this.onEditDescriptionClick\n );\n actionButtons.push(descriptionButton);\n }\n if (typeof this.props.onDelete === 'function') {\n const deleteButton = this.getActionButton('Delete', this.onDeleteClick);\n actionButtons.push(deleteButton);\n }\n\n return (\n \n
\n
\n {this.props.t(this.props.measurementData.label, {\n keySeparator: '>',\n nsSeparator: '|',\n })}\n
\n
{this.getDataDisplayText()}
\n {!this.props.measurementData.isReadOnly && (\n
{actionButtons}
\n )}\n
\n \n );\n };\n\n onItemClick = event => {\n this.props.onItemClick(event, this.props.measurementData);\n };\n\n onRelabelClick = event => {\n // Prevent onItemClick from firing\n event.stopPropagation();\n\n this.props.onRelabel(event, this.props.measurementData);\n };\n\n onEditDescriptionClick = event => {\n // Prevent onItemClick from firing\n event.stopPropagation();\n\n this.props.onEditDescription(event, this.props.measurementData);\n };\n\n onDeleteClick = event => {\n // Prevent onItemClick from firing\n event.stopPropagation();\n\n this.props.onDelete(event, this.props.measurementData);\n };\n\n getDataDisplayText = () => {\n return this.props.measurementData.data.map((data, index) => {\n return (\n
\n {data.displayText ? data.displayText : '...'}\n
\n );\n });\n };\n\n getWarningContent = () => {\n const { warningList = '' } = this.props.measurementData;\n\n if (Array.isArray(warningList)) {\n const listedWarnings = warningList.map((warn, index) => {\n return
  • {warn}
  • ;\n });\n\n return
      {listedWarnings}
    ;\n } else {\n return {warningList};\n }\n };\n}\n\nconst connectedComponent = withTranslation('MeasurementTable')(\n MeasurementTableItem\n);\nexport { connectedComponent as MeasurementTableItem };\nexport default connectedComponent;\n","import './ScrollableArea.styl';\n\nimport React, { Component } from 'react';\n\nimport { Icon } from './../elements/Icon';\nimport PropTypes from 'prop-types';\nimport getScrollbarSize from '../utils/getScrollbarSize.js';\nimport throttled from '../utils/throttled.js';\n\nexport class ScrollableArea extends Component {\n static propTypes = {\n children: PropTypes.node.isRequired,\n class: PropTypes.string,\n scrollableClass: PropTypes.string,\n scrollX: PropTypes.bool,\n scrollY: PropTypes.bool,\n hideScrollbar: PropTypes.bool,\n scrollStep: PropTypes.number,\n };\n\n static defaultProps = {\n hideScrollbar: true,\n class: 'flex-grow fit',\n scrollY: true,\n scrollX: false,\n scrollStep: 100,\n };\n\n constructor(props) {\n super(props);\n\n this.state = {\n scrollAreaClasses: '',\n };\n\n this.scrollHandlerThrottled = throttled(150, this.scrollHandler);\n }\n\n render() {\n let scrollableClass = 'scrollable';\n if (this.props.scrollableClass) {\n scrollableClass += ` ${this.props.scrollableClass}`;\n }\n if (this.props.scrollX) {\n scrollableClass += ` scrollX`;\n }\n if (this.props.scrollY) {\n scrollableClass += ` scrollY`;\n }\n\n return (\n \n {\n this.scrollableElement = element;\n }}\n onScroll={this.scrollHandlerThrottled}\n onMouseEnter={this.scrollHandlerThrottled}\n onTransitionEnd={this.scrollHandlerThrottled}\n >\n {this.props.children}\n \n
    \n {/* */}\n \n
    \n
    \n \n
    \n \n );\n }\n\n componentDidMount() {\n this.adjustMargins();\n this.scrollHandler();\n window.addEventListener('resize', this.adjustMargins);\n }\n\n componentDidUpdate() {\n this.adjustMargins();\n this.scrollHandler();\n }\n\n componentWillUnmount() {\n window.removeEventListener('resize', this.adjustMargins);\n }\n\n scrollNavDown = event => {\n const {\n scrollTop: currentTop,\n offsetHeight: height,\n scrollHeight,\n } = this.scrollableElement;\n\n const limit = scrollHeight - height;\n let scrollTop = currentTop + this.props.scrollStep;\n scrollTop = scrollTop > limit ? limit : scrollTop;\n this.scrollableElement.scrollTop = scrollTop;\n };\n\n scrollNavUp = event => {\n const { scrollTop: currentTop } = this.scrollableElement;\n\n let scrollTop = currentTop - this.props.scrollStep;\n scrollTop = scrollTop < 0 ? 0 : scrollTop;\n\n this.scrollableElement.scrollTop = scrollTop;\n };\n\n adjustMargins = () => {\n if (this.props.hideScrollbar) {\n const x = this.props.scrollX ? 1 : 0;\n const y = this.props.scrollY ? 1 : 0;\n const scrollbarSize = getScrollbarSize();\n this.scrollableElement.style.marginRight = `${0 -\n scrollbarSize[0] * y}px`;\n this.scrollableElement.style.marginBottom = `${0 -\n scrollbarSize[1] * x}px`;\n }\n };\n\n scrollHandler = () => {\n const {\n offsetHeight: height,\n scrollTop: scrollTop,\n scrollHeight,\n } = this.scrollableElement;\n let scrollAreaClasses = '';\n\n // Check if can scroll up\n if (scrollTop) {\n scrollAreaClasses += 'canScrollUp';\n }\n\n // Check if can scroll down\n if (scrollTop + height < scrollHeight) {\n scrollAreaClasses += ' canScrollDown';\n }\n\n if (this.state.scrollAreaClasses !== scrollAreaClasses) {\n this.setState({\n scrollAreaClasses,\n });\n }\n };\n}\n","export default function throttled(delay, callback) {\n let isThrottled = false,\n args,\n context;\n\n function wrapper() {\n if (isThrottled) {\n args = arguments;\n context = this;\n return;\n }\n\n isThrottled = true;\n callback.apply(this, arguments);\n\n setTimeout(() => {\n isThrottled = false;\n if (args) {\n wrapper.apply(context, args);\n args = context = null;\n }\n }, delay);\n }\n\n return wrapper;\n}\n","/**\n * Get the vertical and horizontal scrollbar sizes\n * Got from https://stackoverflow.com/questions/986937/how-can-i-get-the-browsers-scrollbar-sizes\n *\n * @returns {Array} Array containing the scrollbar horizontal and vertical sizes\n */\nexport default function getScrollbarSize() {\n const inner = document.createElement('p');\n inner.style.width = '100%';\n inner.style.height = '100%';\n\n const outer = document.createElement('div');\n outer.style.position = 'absolute';\n outer.style.top = '0px';\n outer.style.left = '0px';\n outer.style.visibility = 'hidden';\n outer.style.width = '100px';\n outer.style.height = '100px';\n outer.style.overflow = 'hidden';\n outer.appendChild(inner);\n\n document.body.appendChild(outer);\n\n const w1 = inner.offsetWidth;\n const h1 = inner.offsetHeight;\n outer.style.overflow = 'scroll';\n let w2 = inner.offsetWidth;\n let h2 = inner.offsetHeight;\n\n if (w1 === w2) {\n w2 = outer.clientWidth;\n }\n\n if (h1 === h2) {\n h2 = outer.clientHeight;\n }\n\n document.body.removeChild(outer);\n\n return [w1 - w2, h1 - h2];\n}\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nimport './TableList.styl';\n\nexport class TableList extends Component {\n static propTypes = {\n customHeader: PropTypes.node,\n defaultItems: PropTypes.object,\n children: PropTypes.node.isRequired,\n headerTitle: PropTypes.string,\n headless: PropTypes.bool,\n };\n\n static defaultProps = {\n headless: false,\n };\n\n render() {\n return (\n
    \n {!this.props.headless && (\n
    \n {this.getHeader()}\n
    \n )}\n
    {this.props.children}
    \n
    \n );\n }\n\n getHeader = () => {\n if (this.props.customHeader) {\n return this.props.customHeader;\n } else {\n return (\n \n
    {this.props.headerTitle}
    \n
    {this.props.children.length}
    \n
    \n );\n }\n };\n}\n","import './MeasurementTable.styl';\n\nimport React, { Component } from 'react';\nimport { withTranslation } from '../../contextProviders';\n\nimport { Icon } from './../../elements/Icon';\nimport { MeasurementTableItem } from './MeasurementTableItem.js';\nimport { OverlayTrigger } from './../overlayTrigger';\nimport PropTypes from 'prop-types';\nimport { ScrollableArea } from './../../ScrollableArea/ScrollableArea.js';\nimport { TableList } from './../tableList';\nimport { Tooltip } from './../tooltip';\n\nclass MeasurementTable extends Component {\n static propTypes = {\n measurementCollection: PropTypes.array.isRequired,\n timepoints: PropTypes.array.isRequired,\n overallWarnings: PropTypes.object.isRequired,\n readOnly: PropTypes.bool,\n onItemClick: PropTypes.func,\n onRelabelClick: PropTypes.func,\n onDeleteClick: PropTypes.func,\n onEditDescriptionClick: PropTypes.func,\n selectedMeasurementNumber: PropTypes.number,\n t: PropTypes.func,\n saveFunction: PropTypes.func,\n onSaveComplete: PropTypes.func,\n };\n\n static defaultProps = {\n overallWarnings: {\n warningList: [],\n },\n readOnly: false,\n };\n\n state = {\n selectedKey: null,\n };\n\n render() {\n const { overallWarnings, saveFunction, t } = this.props;\n const hasOverallWarnings = overallWarnings.warningList.length > 0;\n\n return (\n
    \n
    \n {hasOverallWarnings && (\n \n
    \n {t('Criteria nonconformities')}\n
    \n
    \n {this.getWarningContent()}\n
    \n \n }\n >\n \n \n \n \n \n \n )}\n {this.getTimepointsHeader()}\n
    \n \n
    {this.getMeasurementsGroups()}
    \n
    \n
    \n {saveFunction && (\n \n \n Salvar medidas\n \n )}\n
    \n
    \n );\n }\n\n saveFunction = async event => {\n const { saveFunction, onSaveComplete } = this.props;\n if (saveFunction) {\n try {\n const result = await saveFunction();\n if (onSaveComplete) {\n onSaveComplete({\n title: 'STOW SR',\n message: result.message,\n type: 'success',\n });\n }\n } catch (error) {\n if (onSaveComplete) {\n onSaveComplete({\n title: 'STOW SR',\n message: error.message,\n type: 'error',\n });\n }\n }\n }\n };\n\n getMeasurementsGroups = () => {\n return this.props.measurementCollection.map((measureGroup, index) => {\n return (\n \n {this.getMeasurements(measureGroup)}\n \n );\n });\n };\n\n getMeasurements = measureGroup => {\n const selectedKey = this.props.selectedMeasurementNumber\n ? this.props.selectedMeasurementNumber\n : this.state.selectedKey;\n return measureGroup.measurements.map((measurement, index) => {\n const key = measurement.measurementNumber;\n const itemIndex = measurement.itemNumber || index + 1;\n const itemClass =\n selectedKey === key && !this.props.readOnly ? 'selected' : '';\n return (\n \n );\n });\n };\n\n onItemClick = (event, measurementData) => {\n if (this.props.readOnly) return;\n\n this.setState({\n selectedKey: measurementData.measurementNumber,\n });\n\n if (this.props.onItemClick) {\n this.props.onItemClick(event, measurementData);\n }\n };\n\n getCustomHeader = measureGroup => {\n return (\n \n
    \n {this.props.t(measureGroup.groupName)}\n
    \n {measureGroup.maxMeasurements && (\n
    \n {this.props.t('MAX')} {measureGroup.maxMeasurements}\n
    \n )}\n
    {measureGroup.measurements.length}
    \n
    \n );\n };\n\n getTimepointsHeader = () => {\n const { timepoints, t } = this.props;\n\n return timepoints.map((timepoint, index) => {\n return (\n
    \n
    {t(timepoint.key)}
    \n
    {timepoint.date}
    \n
    \n );\n });\n };\n\n getWarningContent = () => {\n const { warningList = '' } = this.props.overallWarnings;\n\n if (Array.isArray(warningList)) {\n const listedWarnings = warningList.map((warn, index) => {\n return
  • {warn}
  • ;\n });\n\n return
      {listedWarnings}
    ;\n } else {\n return {warningList};\n }\n };\n}\n\nconst connectedComponent = withTranslation(['MeasurementTable', 'Common'])(\n MeasurementTable\n);\nexport { connectedComponent as MeasurementTable };\nexport default connectedComponent;\n","import React from 'react';\nimport detect from 'browser-detect';\nimport { useTranslation } from 'react-i18next';\n\nimport './AboutContent.styl';\n\nconst AboutContent = () => {\n const { t } = useTranslation('AboutContent');\n\n const { os, version, name } = detect();\n const capitalize = s =>\n s.substr(0, 1).toUpperCase() + s.substr(1).toLowerCase();\n\n const itemsPreset = () => {\n return [\n {\n name: t('Repository URL'),\n value: 'https://github.com/OHIF/Viewers/',\n link: 'https://github.com/OHIF/Viewers/',\n },\n {\n name: t('Latest Master Commits'),\n value: 'https://github.com/OHIF/Viewers/commits/master',\n link: 'https://github.com/OHIF/Viewers/commits/master',\n },\n {\n name: 'Version Number',\n value: process.env.VERSION_NUMBER,\n },\n {\n name: t('Build Number'),\n value: process.env.BUILD_NUM,\n },\n {\n name: t('Browser'),\n value: `${capitalize(name)} ${version}`,\n },\n {\n name: t('OS'),\n value: os,\n },\n ];\n };\n\n const renderTableRow = ({ name, value, link }) => (\n \n {name}\n \n {link ? (\n \n {value}\n \n ) : (\n value\n )}\n \n \n );\n\n return (\n
    \n
    \n \n {t('Visit the forum')}\n \n {` `}\n \n {t('Report an issue')}\n \n {` `}\n \n {t('More details')}\n \n
    \n
    \n

    {t('Version Information')}

    \n \n \n \n \n \n \n \n {itemsPreset().map(item => renderTableRow(item))}\n
    {t('Name')}{t('Value')}
    \n
    \n
    \n );\n};\n\nexport { AboutContent };\nexport default AboutContent;\n","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport classnames from 'classnames';\n\n// Style\nimport './TabComponents.styl';\n\n/**\n * Take name of the tab and create the data-cy value for it\n *\n * @param {string} [name=''] tab name\n * @returns {string} data-cy value\n */\nconst getDataCy = (name = '') => {\n return name\n .split(' ')\n .join('-')\n .toLowerCase();\n};\n\n/**\n * Single tab data information\n *\n * @typedef {Object} tabData\n * @property {string} name - name of the tab\n * @property {Object} Component - tab component to be rendered\n * @property {Object} customProps - tab custom properties\n * @property {bool} hidden - bool to define if tab is hidden of not\n */\n\n/**\n * Take a list of components data and render then into tabs\n *\n * @param {Object} props\n * @param {[tabData]} props.tabs array of tab data\n * @param {Object} props.customProps common custom properties\n */\nfunction TabComponents({ tabs, customProps = {} }) {\n const [currentTabIndex, setCurrentTabIndex] = useState(0);\n\n return (\n tabs.length > 0 && (\n
    \n
    \n
    \n
    \n
      \n {tabs.map((tab, index) => {\n const { name, hidden = false } = tab;\n return (\n !hidden && (\n {\n setCurrentTabIndex(index);\n }}\n className={classnames(\n 'nav-link',\n index === currentTabIndex && 'active'\n )}\n data-cy={getDataCy(name)}\n >\n \n \n )\n );\n })}\n
    \n
    \n
    \n
    \n {tabs.map((tab, index) => {\n const {\n Component,\n customProps: tabCustomProps,\n hidden = false,\n } = tab;\n return (\n !hidden && (\n \n \n
    \n )\n );\n })}\n \n )\n );\n}\n\nTabComponents.propTypes = {\n tabs: PropTypes.arrayOf(\n PropTypes.shape({\n name: PropTypes.string,\n Component: PropTypes.any,\n customProps: PropTypes.object,\n hidden: PropTypes.bool,\n })\n ),\n customProps: PropTypes.object,\n};\n\nexport { TabComponents };\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport './TabFooter.styl';\n\n// In case translate is not passed\nconst translate = word => word;\n\nfunction TabFooter({\n onResetPreferences,\n onSave,\n onCancel,\n hasErrors,\n t = translate,\n}) {\n return (\n
    \n \n {t('Reset to Defaults')}\n \n
    \n \n {t('Cancel')}\n
    \n \n {t('Save')}\n \n
    \n \n );\n}\n\nTabFooter.propTypes = {\n onResetPreferences: PropTypes.func,\n onSave: PropTypes.func,\n onCancel: PropTypes.func,\n hasErrors: PropTypes.bool,\n t: PropTypes.func,\n};\n\nexport { TabFooter };\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { hotkeys } from '@ohif/core';\n\n/**\n * Take the pressed key array and return the readable string for the keys\n *\n * @param {Array} [keys=[]]\n * @returns {string} string representation of an array of keys\n */\nconst formatKeysForInput = (keys = []) => keys.join('+');\n\n/**\n * formats given keys sequence to insert the modifier keys in the first index of the array\n * @param {string} sequence keys sequence from MouseTrap Record -> \"shift+left\"\n * @returns {Array} keys in array-format -> ['shift','left']\n */\nconst getKeys = ({ sequence, modifier_keys }) => {\n const keysArray = sequence.join(' ').split('+');\n let keys = [];\n let modifiers = [];\n keysArray.forEach(key => {\n if (modifier_keys && modifier_keys.includes(key)) {\n modifiers.push(key);\n } else {\n keys.push(key);\n }\n });\n return [...modifiers, ...keys];\n};\n\n/**\n * HotkeyField\n * Renders a hotkey input\n *\n * @param {object} props component props\n * @param {Array[]} props.keys array of keys to be controlled by this field\n * @param {function} props.handleChange Callback function to communicate parent once value is changed\n * @param {string} props.classNames string caontaining classes to be added in the input field\n * @param {Array[]} props.modifier_keys\n */\nfunction HotkeyField({ keys, handleChange, classNames, modifier_keys }) {\n const inputValue = formatKeysForInput(keys);\n\n const onInputKeyDown = event => {\n event.stopPropagation();\n event.preventDefault();\n\n hotkeys.record(sequence => {\n const keys = getKeys({ sequence, modifier_keys });\n hotkeys.unpause();\n handleChange(keys);\n });\n };\n\n const onFocus = () => {\n hotkeys.pause();\n hotkeys.startRecording();\n };\n\n return (\n \n );\n}\n\nHotkeyField.propTypes = {\n keys: PropTypes.array.isRequired,\n handleChange: PropTypes.func.isRequired,\n classNames: PropTypes.string,\n modifier_keys: PropTypes.array,\n allowed_keys: PropTypes.array,\n};\n\nexport { HotkeyField };\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport './LanguageSwitcher.styl';\n\nconst LanguageSwitcher = ({ language, onLanguageChange, languages }) => {\n const onChange = event => {\n const { value } = event.target;\n onLanguageChange(value);\n };\n\n return (\n \n {languages.map(lng => (\n \n ))}\n \n );\n};\n\nLanguageSwitcher.propTypes = {\n language: PropTypes.string.isRequired,\n languages: PropTypes.array.isRequired,\n onLanguageChange: PropTypes.func.isRequired,\n};\n\nexport { LanguageSwitcher };\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport './checkbox.css';\n\nexport class Checkbox extends Component {\n static propTypes = {\n label: PropTypes.string.isRequired,\n checked: PropTypes.bool,\n onChange: PropTypes.func,\n };\n\n constructor(props) {\n super(props);\n this.state = { checked: !!props.checked, label: props.label };\n }\n\n handleChange(e) {\n const checked = e.target.checked;\n this.setState({ checked });\n if (this.props.onChange) this.props.onChange(checked);\n }\n\n componentDidUpdate(props) {\n const { checked = false, label } = props;\n\n if (this.state.checked !== checked || this.state.label !== label) {\n this.setState({\n checked,\n label,\n });\n }\n }\n\n render() {\n let checkbox;\n if (this.state.checked) {\n checkbox = ;\n } else {\n checkbox = ;\n }\n\n return (\n
    \n
    \n \n
    \n
    \n );\n }\n}\n","import './CineDialog.styl';\n\nimport React, { PureComponent } from 'react';\nimport { withTranslation } from '../../contextProviders';\nimport { Icon } from './../../elements/Icon';\nimport PropTypes from 'prop-types';\n\nclass CineDialog extends PureComponent {\n constructor(props) {\n super(props);\n\n this.state = {\n cineFrameRate: props.cineFrameRate,\n isPlaying: props.isPlaying,\n };\n }\n\n static propTypes = {\n /** Minimum value for range slider */\n cineMinFrameRate: PropTypes.number.isRequired,\n /** Maximum value for range slider */\n cineMaxFrameRate: PropTypes.number.isRequired,\n /** Increment range slider can \"step\" in either direction. */\n cineStepFrameRate: PropTypes.number.isRequired,\n cineFrameRate: PropTypes.number.isRequired,\n /** 'True' if playing, 'False' if paused. */\n isPlaying: PropTypes.bool.isRequired,\n onPlayPauseChanged: PropTypes.func,\n onFrameRateChanged: PropTypes.func,\n onClickNextButton: PropTypes.func,\n onClickBackButton: PropTypes.func,\n onClickSkipToStart: PropTypes.func,\n onClickSkipToEnd: PropTypes.func,\n /** i18next translation function */\n t: PropTypes.func.isRequired,\n };\n\n static defaultProps = {\n cineMinFrameRate: 1,\n cineMaxFrameRate: 90,\n cineStepFrameRate: 1,\n cineFrameRate: 24,\n isPlaying: false,\n };\n\n componentDidUpdate(prevProps) {\n // TODO: Not sure if we should just switch this to a stateless\n // fully-controlled component instead\n if (\n this.props.isPlaying !== prevProps.isPlaying ||\n this.props.isPlaying !== this.state.isPlaying\n ) {\n this.setState({\n isPlaying: this.props.isPlaying,\n });\n }\n\n if (\n this.props.cineFrameRate !== prevProps.cineFrameRate ||\n this.props.cineFrameRate !== this.state.cineFrameRate\n ) {\n this.setState({\n cineFrameRate: this.props.cineFrameRate,\n });\n }\n }\n\n handleInputChange = event => {\n const target = event.target;\n\n let value = target.value;\n\n if (target.type === 'range') {\n value = parseFloat(target.value);\n }\n\n const name = target.name;\n\n this.setState({\n [name]: value,\n });\n\n if (name === 'cineFrameRate' && this.props.onFrameRateChanged) {\n this.props.onFrameRateChanged(parseFloat(value));\n }\n };\n\n onClickPlayPause = () => {\n const value = !this.state.isPlaying;\n\n this.setState({\n isPlaying: value,\n });\n\n if (this.props.onPlayPauseChanged) {\n this.props.onPlayPauseChanged(value);\n }\n };\n\n onClickNextButton = event => {\n if (this.props.onClickNextButton) {\n this.props.onClickNextButton(event);\n }\n };\n\n onClickBackButton = event => {\n if (this.props.onClickBackButton) {\n this.props.onClickBackButton(event);\n }\n };\n\n onClickSkipToStart = event => {\n if (this.props.onClickSkipToStart) {\n this.props.onClickSkipToStart(event);\n }\n };\n\n onClickSkipToEnd = event => {\n if (this.props.onClickSkipToEnd) {\n this.props.onClickSkipToEnd(event);\n }\n };\n\n render() {\n const { t } = this.props;\n return (\n
    \n
    \n
    \n
    \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
    \n
    \n
    \n
    \n \n
    \n \n {this.state.cineFrameRate.toFixed(1)} {t('fps')}\n \n
    \n
    \n
    \n );\n }\n}\n\nconst connectedComponent = withTranslation('CineDialog')(CineDialog);\nexport { connectedComponent as CineDialog };\nexport default connectedComponent;\n","import React, {\n useRef,\n useCallback,\n useEffect,\n useState,\n createRef,\n} from 'react';\nimport PropTypes from 'prop-types';\nimport { useTranslation } from 'react-i18next';\n\nimport './ViewportDownloadForm.styl';\nimport { TextInput, Select, Icon } from '@ohif/ui';\nimport classnames from 'classnames';\n\nconst FILE_TYPE_OPTIONS = [\n {\n key: 'jpg',\n value: 'jpg',\n },\n {\n key: 'png',\n value: 'png',\n },\n];\n\nconst DEFAULT_FILENAME = 'image';\nconst REFRESH_VIEWPORT_TIMEOUT = 1000;\n\nconst ViewportDownloadForm = ({\n activeViewport,\n onClose,\n updateViewportPreview,\n enableViewport,\n disableViewport,\n toggleAnnotations,\n loadImage,\n downloadBlob,\n defaultSize,\n minimumSize,\n maximumSize,\n canvasClass,\n}) => {\n const [t] = useTranslation('ViewportDownloadForm');\n\n const [filename, setFilename] = useState(DEFAULT_FILENAME);\n const [fileType, setFileType] = useState('jpg');\n\n const [dimensions, setDimensions] = useState({\n width: defaultSize,\n height: defaultSize,\n });\n\n const [showAnnotations, setShowAnnotations] = useState(true);\n\n const [keepAspect, setKeepAspect] = useState(true);\n const [aspectMultiplier, setAspectMultiplier] = useState({\n width: 1,\n height: 1,\n });\n\n const [viewportElement, setViewportElement] = useState();\n const [viewportElementDimensions, setViewportElementDimensions] = useState({\n width: defaultSize,\n height: defaultSize,\n });\n\n const [downloadCanvas, setDownloadCanvas] = useState({\n ref: createRef(),\n width: defaultSize,\n height: defaultSize,\n });\n\n const [viewportPreview, setViewportPreview] = useState({\n src: null,\n width: defaultSize,\n height: defaultSize,\n });\n\n const [error, setError] = useState({\n width: false,\n height: false,\n filename: false,\n });\n\n const hasError = Object.values(error).includes(true);\n\n const refreshViewport = useRef(null);\n\n const downloadImage = () => {\n downloadBlob(\n filename || DEFAULT_FILENAME,\n fileType,\n viewportElement,\n downloadCanvas.ref.current\n );\n };\n\n /**\n * @param {object} event - Input change event\n * @param {string} dimension - \"height\" | \"width\"\n */\n const onDimensionsChange = (event, dimension) => {\n const oppositeDimension = dimension === 'height' ? 'width' : 'height';\n const sanitizedTargetValue = event.target.value.replace(/\\D/, '');\n const isEmpty = sanitizedTargetValue === '';\n const newDimensions = { ...dimensions };\n const updatedDimension = isEmpty\n ? ''\n : Math.min(sanitizedTargetValue, maximumSize);\n\n if (updatedDimension === dimensions[dimension]) {\n return;\n }\n\n newDimensions[dimension] = updatedDimension;\n\n if (keepAspect && newDimensions[oppositeDimension] !== '') {\n newDimensions[oppositeDimension] = Math.round(\n newDimensions[dimension] * aspectMultiplier[oppositeDimension]\n );\n }\n\n // In current code, keepAspect is always `true`\n // And we always start w/ a square width/height\n setDimensions(newDimensions);\n\n // Only update if value is non-empty\n if (!isEmpty) {\n setViewportElementDimensions(newDimensions);\n setDownloadCanvas(state => ({\n ...state,\n ...newDimensions,\n }));\n }\n };\n\n const error_messages = {\n width: t('minWidthError'),\n height: t('minHeightError'),\n filename: t('emptyFilenameError'),\n };\n\n const renderErrorHandler = errorType => {\n if (!error[errorType]) {\n return null;\n }\n\n return
    {error_messages[errorType]}
    ;\n };\n\n const onKeepAspectToggle = () => {\n const { width, height } = dimensions;\n const aspectMultiplier = { ...aspectMultiplier };\n if (!keepAspect) {\n const base = Math.min(width, height);\n aspectMultiplier.width = width / base;\n aspectMultiplier.height = height / base;\n setAspectMultiplier(aspectMultiplier);\n }\n\n setKeepAspect(!keepAspect);\n };\n\n const validSize = value => (value >= minimumSize ? value : minimumSize);\n const loadAndUpdateViewports = useCallback(async () => {\n const { width: scaledWidth, height: scaledHeight } = await loadImage(\n activeViewport,\n viewportElement,\n dimensions.width,\n dimensions.height\n );\n\n toggleAnnotations(showAnnotations, viewportElement);\n\n const scaledDimensions = {\n height: validSize(scaledHeight),\n width: validSize(scaledWidth),\n };\n\n setViewportElementDimensions(scaledDimensions);\n setDownloadCanvas(state => ({\n ...state,\n ...scaledDimensions,\n }));\n\n const {\n dataUrl,\n width: viewportElementWidth,\n height: viewportElementHeight,\n } = await updateViewportPreview(\n viewportElement,\n downloadCanvas.ref.current,\n fileType\n );\n\n setViewportPreview(state => ({\n ...state,\n src: dataUrl,\n width: validSize(viewportElementWidth),\n height: validSize(viewportElementHeight),\n }));\n }, [\n activeViewport,\n viewportElement,\n showAnnotations,\n loadImage,\n toggleAnnotations,\n updateViewportPreview,\n fileType,\n downloadCanvas.ref,\n minimumSize,\n maximumSize,\n viewportElementDimensions,\n ]);\n\n useEffect(() => {\n enableViewport(viewportElement);\n\n return () => {\n disableViewport(viewportElement);\n };\n }, [disableViewport, enableViewport, viewportElement]);\n\n useEffect(() => {\n if (refreshViewport.current !== null) {\n clearTimeout(refreshViewport.current);\n }\n\n refreshViewport.current = setTimeout(() => {\n refreshViewport.current = null;\n loadAndUpdateViewports();\n }, REFRESH_VIEWPORT_TIMEOUT);\n }, [\n activeViewport,\n viewportElement,\n showAnnotations,\n dimensions,\n loadImage,\n toggleAnnotations,\n updateViewportPreview,\n fileType,\n downloadCanvas.ref,\n minimumSize,\n maximumSize,\n ]);\n\n useEffect(() => {\n const { width, height } = dimensions;\n const hasError = {\n width: width < minimumSize,\n height: height < minimumSize,\n filename: !filename,\n };\n\n setError({ ...hasError });\n }, [dimensions, filename, minimumSize]);\n\n return (\n
    \n
    {t('formTitle')}
    \n\n
    \n
    \n
    \n
    \n onDimensionsChange(evt, 'width')}\n data-cy=\"image-width\"\n />\n {renderErrorHandler('width')}\n
    \n
    \n onDimensionsChange(evt, 'height')}\n data-cy=\"image-height\"\n />\n {renderErrorHandler('height')}\n
    \n
    \n
    \n \n \n \n
    \n
    \n\n
    \n
    \n setFilename(event.target.value)}\n label={t('filename')}\n id=\"file-name\"\n />\n {renderErrorHandler('filename')}\n
    \n
    \n setFileType(event.target.value)}\n options={FILE_TYPE_OPTIONS}\n label={t('fileType')}\n />\n
    \n
    \n\n
    \n
    \n \n
    \n
    \n
    \n\n setViewportElement(ref)}\n >\n \n
    \n\n {viewportPreview.src ? (\n
    \n
    {t('imagePreview')}
    \n \n
    \n ) : (\n
    \n \n {t('loadingPreview')}\n
    \n )}\n\n
    \n
    \n \n {t('Buttons:Cancel')}\n \n
    \n
    \n \n {t('Buttons:Download')}\n \n
    \n
    \n \n );\n};\n\nViewportDownloadForm.propTypes = {\n onClose: PropTypes.func.isRequired,\n activeViewport: PropTypes.object,\n updateViewportPreview: PropTypes.func.isRequired,\n enableViewport: PropTypes.func.isRequired,\n disableViewport: PropTypes.func.isRequired,\n toggleAnnotations: PropTypes.func.isRequired,\n loadImage: PropTypes.func.isRequired,\n downloadBlob: PropTypes.func.isRequired,\n /** A default width & height, between the minimum and maximum size */\n defaultSize: PropTypes.number.isRequired,\n minimumSize: PropTypes.number.isRequired,\n maximumSize: PropTypes.number.isRequired,\n canvasClass: PropTypes.string.isRequired,\n};\n\nexport default ViewportDownloadForm;\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nimport './StudiesItem.styl';\n\nexport class StudiesItem extends Component {\n static propTypes = {\n onClick: PropTypes.func.isRequired,\n studyData: PropTypes.object.isRequired,\n active: PropTypes.bool,\n };\n\n render() {\n const {\n StudyDate,\n StudyDescription,\n modalities,\n studyAvailable,\n } = this.props.studyData;\n const activeClass = this.props.active ? ' active' : '';\n const hasDescriptionAndDate = StudyDate && StudyDescription;\n return (\n \n
    \n
    \n \n {modalities}\n
    \n
    \n
    \n {hasDescriptionAndDate ? (\n \n
    {StudyDate}
    \n
    {StudyDescription}
    \n
    \n ) : (\n
    \n {studyAvailable ? (\n N/A\n ) : (\n Click to load\n )}\n
    \n )}\n
    \n \n \n );\n }\n\n getModalitiesStyle = () => {\n return {};\n };\n}\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nimport { StudiesItem } from './StudiesItem.js';\nimport './StudiesList.styl';\n\nexport class StudiesList extends Component {\n static propTypes = {\n class: PropTypes.string,\n studyListData: PropTypes.array.isRequired,\n onClick: PropTypes.func.isRequired,\n activeStudyInstanceUID: PropTypes.string,\n };\n\n render() {\n return (\n
    \n {this.getBrowserItems()}\n
    \n );\n }\n\n getBrowserItems = () => {\n return this.props.studyListData.map((studyData, index) => {\n return (\n this.props.onClick(studyData)}\n />\n );\n });\n };\n}\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nimport { Thumbnail } from './../studyBrowser';\nimport './SeriesList.styl';\n\nexport class SeriesList extends Component {\n static propTypes = {\n seriesItems: PropTypes.array.isRequired,\n onClick: PropTypes.func.isRequired,\n activeDisplaySetInstanceUID: PropTypes.string,\n };\n\n render() {\n return (\n \n
    \n
    {this.getSeriesItems()}
    \n
    \n
    \n );\n }\n\n getSeriesItems = () => {\n return this.props.seriesItems.map((seriesData, index) => {\n return (\n this.props.onClick(seriesData)}\n />\n );\n });\n };\n}\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nimport { StudiesList } from './StudiesList.js';\nimport { ScrollableArea } from './../../ScrollableArea/ScrollableArea.js';\nimport { SeriesList } from './SeriesList.js';\n\nimport './QuickSwitch.styl';\n\nexport class QuickSwitch extends Component {\n static propTypes = {\n side: PropTypes.string,\n studyListData: PropTypes.array.isRequired,\n onSeriesSelected: PropTypes.func.isRequired,\n seriesData: PropTypes.array,\n onStudySelected: PropTypes.func,\n activeStudyInstanceUID: PropTypes.string,\n activeDisplaySetInstanceUID: PropTypes.string,\n };\n\n constructor(props) {\n super(props);\n\n this.state = {\n seriesQuickSwitchOpen: false,\n sideClass: this.props.side || '',\n activeStudyInstanceUID: this.props.activeStudyInstanceUID,\n activeDisplaySetInstanceUID: this.props.activeDisplaySetInstanceUID,\n };\n }\n\n componentDidUpdate(prevProps) {\n const props = this.props;\n\n if (props.activeStudyInstanceUID !== prevProps.activeStudyInstanceUID) {\n this.setState({\n activeStudyInstanceUID: props.activeStudyInstanceUID,\n });\n }\n\n if (\n props.activeDisplaySetInstanceUID !==\n prevProps.activeDisplaySetInstanceUID\n ) {\n this.setState({\n activeDisplaySetInstanceUID: props.activeDisplaySetInstanceUID,\n });\n }\n }\n\n render() {\n const quickSwitchClass = this.state.seriesQuickSwitchOpen\n ? 'series-triggered'\n : '';\n\n return (\n \n
    \n
    Series
    \n
    \n {this.getSmallListItems()}\n \n \n \n
    \n
    \n
    \n
    Study
    \n
    \n \n \n \n
    \n
    \n \n );\n }\n\n getSeriesItems = () => {\n let seriesData;\n\n if (this.props.seriesData) {\n seriesData = this.props.seriesData;\n } else if (this.state.activeStudyInstanceUID) {\n const study = this.props.studyListData.find(\n study => study.StudyInstanceUID === this.state.activeStudyInstanceUID\n );\n\n seriesData = study.thumbnails;\n } else {\n seriesData = this.props.studyListData[0].thumbnails;\n }\n\n return seriesData || [];\n };\n\n getSmallListItems = () => {\n const seriesItems = this.getSeriesItems() || [];\n return seriesItems.map((seriesData, index) => {\n const active =\n seriesData.displaySetInstanceUID ===\n this.state.activeDisplaySetInstanceUID;\n return (\n
    \n );\n });\n };\n\n onStudyClick = studyDataSelected => {\n if (this.props.onStudySelected) {\n this.props.onStudySelected(studyDataSelected);\n }\n this.setState({\n activeStudyInstanceUID: studyDataSelected.StudyInstanceUID,\n seriesQuickSwitchOpen: true,\n });\n };\n\n onSeriesClick = seriesDataSelected => {\n this.setState({\n activeDisplaySetInstanceUID: seriesDataSelected.displaySetInstanceUID,\n });\n\n this.props.onSeriesSelected(seriesDataSelected);\n };\n\n showSeriesSwitch = () => {\n this.setState({\n seriesQuickSwitchOpen: true,\n });\n };\n\n hideSeriesSwitch = () => {\n this.setState({\n seriesQuickSwitchOpen: false,\n });\n };\n}\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport classnames from 'classnames';\nimport { Icon } from './../../elements/Icon';\nimport './RoundedButtonGroup.css';\n\n// TODO: Rename to Toggle?\nclass RoundedButtonGroup extends Component {\n static className = 'RoundedButtonGroup';\n\n static propTypes = {\n options: PropTypes.arrayOf(\n PropTypes.shape({\n value: PropTypes.any,\n label: PropTypes.string,\n stateEvent: PropTypes.string,\n icon: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.shape({\n name: PropTypes.string.isRequired,\n }),\n ]),\n })\n ),\n value: PropTypes.string,\n onValueChanged: PropTypes.func,\n };\n\n static defaultProps = {\n options: [],\n value: null,\n };\n\n state = {\n badgeNumbers: [],\n };\n\n constructor() {\n super();\n this.onStateEvent = this.onStateEvent.bind(this);\n }\n\n onClickOption = value => {\n let newValue = value;\n if (this.props.value === value) {\n newValue = null;\n }\n\n if (this.props.onValueChanged) {\n this.props.onValueChanged(newValue);\n }\n };\n\n onStateEvent(event) {\n const optionIndex = this.props.options.findIndex(\n o => o.value === event.detail.target\n );\n if (optionIndex > -1) {\n const badgeNumbers = this.state.badgeNumbers;\n badgeNumbers[optionIndex] = event.detail.badgeNumber;\n this.setState({ badgeNumbers });\n }\n }\n\n componentDidMount() {\n this.props.options.forEach(option => {\n if (option.stateEvent) {\n document.addEventListener(option.stateEvent, this.onStateEvent);\n }\n });\n }\n\n componentDidUpdate(prevProps, prevState) {\n this.props.options.forEach((option, index) => {\n if (\n option.stateEvent &&\n option.stateEvent !==\n (prevProps.options[index]\n ? prevProps.options[index].stateEvent\n : null)\n ) {\n document.removeEventListener(option.stateEvent, this.onStateEvent);\n document.addEventListener(option.stateEvent, this.onStateEvent);\n }\n });\n }\n\n componentWillUnmount() {\n this.props.options.forEach(option => {\n if (option.stateEvent) {\n document.removeEventListener(option.stateEvent, this.onStateEvent);\n }\n });\n }\n\n render() {\n let className = classnames(\n RoundedButtonGroup.className,\n 'clearfix center-table'\n );\n\n const buttons = this.props.options.map((option, index) => {\n const className = classnames({\n roundedButtonWrapper: true,\n noselect: true,\n active: this.props.value === option.value,\n });\n\n const optionText = option.label && {option.label};\n const iconProps =\n typeof option.icon === 'string' ? { name: option.icon } : option.icon;\n\n const bottomLabel = option.bottomLabel && (\n
    {option.bottomLabel}
    \n );\n\n let badgeNumber = this.state.badgeNumbers[index];\n const badgeNumberOverflow = String(badgeNumber).length > 2;\n badgeNumber = badgeNumber\n ? badgeNumberOverflow\n ? 99\n : badgeNumber\n : null;\n\n return (\n this.onClickOption(option.value)}\n >\n
    \n {optionText}\n {badgeNumber && (\n
    \n \n {badgeNumber}\n {badgeNumberOverflow && '+'}\n \n
    \n )}\n {iconProps && }\n
    \n {bottomLabel}\n
    \n );\n });\n\n return
    {buttons}
    ;\n }\n}\n\nexport { RoundedButtonGroup };\n","import { Component } from 'react';\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nexport default class InputRadio extends Component {\n static propTypes = {\n value: PropTypes.string,\n label: PropTypes.string.isRequired,\n itemData: PropTypes.object.isRequired,\n labelClass: PropTypes.string,\n id: PropTypes.string.isRequired,\n onSelected: PropTypes.func.isRequired,\n };\n\n render() {\n const labelClass = this.props.labelClass ? this.props.labelClass : '';\n return (\n \n \n {this.props.label}\n \n );\n }\n\n onSelected = evt => {\n this.props.onSelected(evt, this.props.itemData);\n };\n}\n","import { Component } from 'react';\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport { Icon } from './../../elements/Icon';\n\nexport default class SelectTreeBreadcrumb extends Component {\n static propTypes = {\n label: PropTypes.string.isRequired,\n value: PropTypes.string.isRequired,\n onSelected: PropTypes.func.isRequired,\n };\n\n render() {\n return (\n
    \n \n \n \n \n \n \n {this.props.label}\n \n \n
    \n );\n }\n}\n","import './SelectTree.styl';\n\nimport React, { Component } from 'react';\n\nimport { Icon } from './../../elements/Icon';\nimport InputRadio from './InputRadio.js';\nimport PropTypes from 'prop-types';\nimport SelectTreeBreadcrumb from './SelectTreeBreadcrumb.js';\nimport cloneDeep from 'lodash.clonedeep';\n\nexport class SelectTree extends Component {\n static propTypes = {\n autoFocus: PropTypes.bool,\n searchEnabled: PropTypes.bool,\n selectTreeFirstTitle: PropTypes.string,\n selectTreeSecondTitle: PropTypes.string,\n /** Called when 'componentDidUpdate' is triggered */\n onComponentChange: PropTypes.func,\n /** [{ label, value, items[]}] - An array of items than can be expanded to show child items */\n items: PropTypes.array.isRequired,\n /** fn(evt, item) - Called when a child item is selected; receives event and selected item */\n onSelected: PropTypes.func.isRequired,\n };\n\n static defaultProps = {\n searchEnabled: true,\n autoFocus: true,\n selectTreeFirstTitle: 'First Level itens',\n items: [],\n };\n\n constructor(props) {\n super(props);\n\n this.state = {\n searchTerm: null,\n currentNode: null,\n value: null,\n };\n }\n\n render() {\n const treeItems = this.getTreeItems();\n\n return (\n
    \n
    \n {this.headerItem()}\n
    \n {this.state.currentNode && (\n \n )}\n
    \n
    {treeItems}
    \n
    \n
    \n
    \n
    \n );\n }\n\n componentDidUpdate = () => {\n if (this.props.onComponentChange) {\n this.props.onComponentChange();\n }\n };\n\n isLeafSelected = item => item && !Array.isArray(item.items);\n\n getLabelClass = item => {\n let labelClass = 'treeLeaf';\n if (this.state.searchTerm || Array.isArray(item.items)) {\n labelClass = 'treeNode';\n }\n return labelClass;\n };\n\n filterItems() {\n const filteredItems = [];\n const rawItems = cloneDeep(this.props.items);\n rawItems.forEach(item => {\n if (Array.isArray(item.items)) {\n item.items.forEach(item => {\n const label = item.label.toLowerCase();\n const searchTerm = this.state.searchTerm.toLowerCase();\n if (label.indexOf(searchTerm) !== -1) {\n filteredItems.push(item);\n }\n });\n } else {\n const label = item.label.toLowerCase();\n const searchTerm = this.state.searchTerm.toLowerCase();\n if (label.indexOf(searchTerm) !== -1) {\n filteredItems.push(item);\n }\n }\n });\n return filteredItems;\n }\n\n getTreeItems() {\n const storageKey = 'SelectTree';\n let treeItems;\n\n if (this.state.searchTerm) {\n treeItems = this.filterItems();\n } else if (this.state.currentNode) {\n treeItems = cloneDeep(this.state.currentNode.items);\n } else {\n treeItems = cloneDeep(this.props.items);\n }\n\n return treeItems.map((item, index) => {\n let itemKey = index;\n if (this.state.currentNode) {\n itemKey += `_${this.state.currentNode.value}`;\n }\n return (\n \n );\n });\n }\n\n headerItem = () => {\n let title = this.props.selectTreeFirstTitle;\n if (this.state.currentNode && this.props.selectTreeSecondTitle) {\n title = this.props.selectTreeSecondTitle;\n }\n\n return (\n
    \n
    {title}
    \n {this.props.searchEnabled && (\n
    \n
    \n \n
    \n \n
    \n )}\n
    \n );\n };\n\n searchLocations = evt => {\n this.setState({\n currentNode: null,\n searchTerm: evt.currentTarget.value,\n });\n };\n\n onSelected = (event, item) => {\n if (this.isLeafSelected(item)) {\n this.setState({\n searchTerm: null,\n currentNode: null,\n value: null,\n });\n } else {\n this.setState({\n currentNode: item,\n });\n }\n return this.props.onSelected(event, item);\n };\n\n onBreadcrumbSelected = () => {\n this.setState({\n currentNode: null,\n });\n };\n}\n","import React, { Component, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { TextInput } from '@ohif/ui';\n\nimport './SimpleDialog.styl';\n\nclass SimpleDialog extends Component {\n static propTypes = {\n children: PropTypes.node,\n componentRef: PropTypes.any,\n componentStyle: PropTypes.object,\n rootClass: PropTypes.string,\n isOpen: PropTypes.bool,\n headerTitle: PropTypes.string.isRequired,\n onClose: PropTypes.func.isRequired,\n onConfirm: PropTypes.func.isRequired,\n };\n\n static defaultProps = {\n isOpen: true,\n componentStyle: {},\n rootClass: '',\n };\n\n static InputDialog = ({ onSubmit, defaultValue, title, label, onClose }) => {\n const [value, setValue] = useState(defaultValue);\n\n const onSubmitHandler = () => {\n onSubmit(value);\n };\n\n return (\n
    \n \n setValue(event.target.value)}\n label={label}\n />\n \n
    \n );\n };\n\n render() {\n return (\n \n {this.props.isOpen && (\n \n
    \n
    \n \n x\n \n

    {this.props.headerTitle}

    \n
    \n
    {this.props.children}
    \n
    \n \n \n
    \n
    \n \n )}\n
    \n );\n }\n\n onClose = event => {\n event.preventDefault();\n event.stopPropagation();\n this.props.onClose();\n };\n\n onConfirm = event => {\n event.preventDefault();\n event.stopPropagation();\n this.props.onConfirm();\n };\n}\n\nexport { SimpleDialog };\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Modal from 'react-modal';\nimport classNames from 'classnames';\n\nimport './OHIFModal.styl';\n\nconst customStyle = {\n overlay: {\n zIndex: 1071,\n backgroundColor: 'rgb(0, 0, 0, 0.5)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n};\n\nModal.setAppElement(document.getElementById('root'));\n\nconst OHIFModal = ({\n className,\n closeButton,\n shouldCloseOnEsc,\n isOpen,\n fullscreen,\n title,\n onClose,\n children,\n}) => {\n const renderHeader = () => {\n return (\n title && (\n
    \n

    {title}

    \n {closeButton && (\n \n )}\n
    \n )\n );\n };\n\n const classes = fullscreen\n ? classNames('OHIFModal', className, 'OHIFModal-fullscreen')\n : classNames('OHIFModal', className);\n\n return (\n \n <>\n {renderHeader()}\n
    \n {children}\n
    \n \n \n );\n};\n\nOHIFModal.propTypes = {\n className: PropTypes.string,\n closeButton: PropTypes.bool,\n shouldCloseOnEsc: PropTypes.bool,\n isOpen: PropTypes.bool,\n title: PropTypes.string,\n onClose: PropTypes.func,\n children: PropTypes.oneOfType([\n PropTypes.arrayOf(PropTypes.node),\n PropTypes.node,\n ]).isRequired,\n};\n\nexport default OHIFModal;\n","import PropTypes from 'prop-types';\nimport React from 'react';\nimport './ContextMenu.css';\n\nconst ContextMenu = ({ items, onClick }) => {\n return (\n
    e.preventDefault()}>\n
      \n {items.map((item, index) => (\n
    • \n \n
    • \n ))}\n
    \n
    \n );\n};\n\nContextMenu.propTypes = {\n items: PropTypes.array.isRequired,\n onClick: PropTypes.func.isRequired,\n};\n\nexport default ContextMenu;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Icon } from '@ohif/ui';\n\nimport './ErrorPage.css';\n\nconst ErrorPage = ({ error, title, description, onRetry }) => {\n return (\n
    \n {title &&

    {title}

    }\n

    {description}

    \n \n {error && (\n
    \n
    {error.message}
    \n
    {error.stack}
    \n
    \n )}\n
    \n );\n};\n\nErrorPage.propTypes = {\n error: PropTypes.object,\n title: PropTypes.string,\n description: PropTypes.string,\n onRetry: PropTypes.func\n};\n\nErrorPage.defaultProps = {\n description: 'Oh snap, something went wrong, please try reloading',\n onRetry: () => window.location.reload()\n};\n\nexport default ErrorPage;\n","import ErrorPage from './ErrorPage';\nexport default ErrorPage;\n","// If you want to continue using CSS stylesheets and classes...\n// https://github.com/airbnb/react-dates#initialize\nimport 'react-dates/initialize';\nimport 'react-dates/lib/css/_datepicker.css';\nimport './CustomDateRangePicker.css';\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport { DateRangePicker } from 'react-dates';\nimport moment from 'moment';\nimport i18n from '@ohif/i18n';\nimport { useTranslation } from 'react-i18next';\n\nfunction CustomDateRangePicker(props) {\n moment.locale(i18n.language); // using i18n in the date picker\n\n const { t } = useTranslation('DatePicker');\n\n const {\n onDatesChange,\n startDate,\n endDate,\n presets,\n ...dateRangePickerProps\n } = props;\n\n const renderDatePresets = () => {\n const { presets } = props;\n\n return (\n
    \n {presets.map(({ text, start, end }) => {\n const isSelected = startDate === start && endDate === end;\n\n return (\n \n onDatesChange({\n startDate: start,\n endDate: end,\n preset: true,\n })\n }\n >\n {text}\n \n );\n })}\n
    \n );\n };\n const renderMonthElement = ({ month, onMonthSelect, onYearSelect }) => {\n const containerStyle = {\n margin: '0 5px',\n };\n\n const renderYearsOptions = () => {\n const yearsRange = 20;\n const options = [];\n\n for (let i = 0; i < yearsRange; i++) {\n const year = moment().year() - i;\n options.push();\n }\n\n return options;\n };\n\n renderMonthElement.propTypes = {\n onMonthSelect: PropTypes.func,\n onYearSelect: PropTypes.func,\n };\n\n return (\n
    \n
    \n onMonthSelect(month, e.target.value)}\n >\n {moment.months().map((label, value) => (\n \n ))}\n \n
    \n
    \n {}\n onYearSelect(month, e.target.value)}\n >\n {renderYearsOptions()}\n \n
    \n
    \n );\n };\n\n return (\n \n );\n}\n\nCustomDateRangePicker.propTypes = {\n presets: PropTypes.arrayOf(\n PropTypes.shape({\n text: PropTypes.string,\n start: PropTypes.required,\n end: PropTypes.required,\n })\n ),\n onDatesChange: PropTypes.func.isRequired,\n startDate: PropTypes.instanceOf(Date),\n endDate: PropTypes.instanceOf(Date),\n month: PropTypes.instanceOf(Date),\n};\n\nexport default CustomDateRangePicker;\n","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport moment from 'moment';\nimport { isInclusivelyBeforeDay } from 'react-dates';\nimport CustomDateRangePicker from './CustomDateRangePicker.js';\nimport { Icon } from './../../elements/Icon';\nimport { useTranslation } from 'react-i18next';\n\nconst getDateEntry = (datePicked, rangeDatePicked) => {\n return rangeDatePicked || datePicked || null;\n};\n\nconst getDateEntryFromRange = (today, numOfDays, edge = 'start') => {\n if (typeof numOfDays !== 'number') {\n return;\n }\n\n if (edge === 'end') {\n return today;\n } else {\n today.subtract(numOfDays, 'days');\n }\n};\n\nfunction TableSearchFilter(props) {\n const {\n meta,\n values,\n onSort,\n onValueChange,\n sortFieldName,\n sortDirection,\n // TODO: Rename\n studyListDateFilterNumDays,\n } = props;\n\n const { studyDateTo, studyDateFrom } = values || {};\n const [focusedInput, setFocusedInput] = useState(null);\n const { t, ready: translationsAreReady } = useTranslation('Common');\n\n const sortIcons = ['sort', 'sort-up', 'sort-down'];\n const sortIconForSortField =\n sortDirection === 'asc' ? sortIcons[1] : sortIcons[2];\n\n const today = moment();\n const lastWeek = moment().subtract(7, 'day');\n const lastMonth = moment().subtract(1, 'month');\n\n const defaultStartDate = getDateEntryFromRange(\n today,\n studyListDateFilterNumDays,\n 'start'\n );\n const defaultEndDate = getDateEntryFromRange(\n today,\n studyListDateFilterNumDays,\n 'end'\n );\n\n const studyDatePresets = [\n {\n text: t('Today'),\n start: today,\n end: today,\n },\n {\n text: t('Last 7 days'),\n start: lastWeek,\n end: today,\n },\n {\n text: t('Last 30 days'),\n start: lastMonth,\n end: today,\n },\n ];\n\n return translationsAreReady\n ? meta.map((field, i) => {\n const { displayText, fieldName, inputType } = field;\n const isSortField = sortFieldName === fieldName;\n const sortIcon = isSortField ? sortIconForSortField : sortIcons[0];\n\n return (\n \n onSort(fieldName)}\n >\n {`${displayText}`}\n \n \n {inputType === 'text' && (\n onValueChange(fieldName, e.target.value)}\n />\n )}\n {inputType === 'date-range' && (\n // https://github.com/airbnb/react-dates\n {\n onValueChange('studyDateFrom', startDate);\n onValueChange('studyDateTo', endDate);\n }}\n focusedInput={focusedInput}\n onFocusChange={updatedVal => setFocusedInput(updatedVal)}\n // Optional\n numberOfMonths={1} // For med and small screens? 2 for large?\n showClearDates={true}\n anchorDirection=\"left\"\n presets={studyDatePresets}\n hideKeyboardShortcutsPanel={true}\n isOutsideRange={day => !isInclusivelyBeforeDay(day, moment())}\n />\n )}\n \n );\n })\n : null;\n}\n\nTableSearchFilter.propTypes = {\n meta: PropTypes.arrayOf(\n PropTypes.shape({\n displayText: PropTypes.string.isRequired,\n fieldName: PropTypes.string.isRequired,\n inputType: PropTypes.oneOf(['text', 'date-range']).isRequired,\n size: PropTypes.number.isRequired,\n })\n ).isRequired,\n values: PropTypes.object.isRequired,\n onSort: PropTypes.func.isRequired,\n sortFieldName: PropTypes.string,\n sortDirection: PropTypes.oneOf([null, 'asc', 'desc']),\n};\n\nTableSearchFilter.defaultProps = {};\n\nexport { TableSearchFilter };\nexport default TableSearchFilter;\n","import React from 'react';\nimport { Icon } from './../../elements/Icon';\n// TODO: useTranslation\nimport { withTranslation } from '../../contextProviders';\n\nfunction StudyListLoadingText({ t: translate }) {\n return (\n
    \n {translate('Loading')}... \n
    \n );\n}\n\nconst connectedComponent = withTranslation('StudyListLoadingText')(\n StudyListLoadingText\n);\n\nexport { connectedComponent as StudyListLoadingText };\n","import './StudyList.styl';\n\nimport React from 'react';\nimport classNames from 'classnames';\nimport TableSearchFilter from './TableSearchFilter.js';\nimport PropTypes from 'prop-types';\nimport { StudyListLoadingText } from './StudyListLoadingText.js';\nimport { useTranslation } from 'react-i18next';\n\nconst getContentFromUseMediaValue = (\n displaySize,\n contentArrayMap,\n defaultContent\n) => {\n const content =\n displaySize in contentArrayMap\n ? contentArrayMap[displaySize]\n : defaultContent;\n\n return content;\n};\n/**\n *\n *\n * @param {*} props\n * @returns\n */\nfunction StudyList(props) {\n const {\n isLoading,\n hasError,\n studies,\n sort,\n onSort: handleSort,\n filterValues,\n onFilterChange: handleFilterChange,\n onSelectItem: handleSelectItem,\n studyListDateFilterNumDays,\n displaySize,\n } = props;\n const { t, ready: translationsAreReady } = useTranslation('StudyList');\n\n const largeTableMeta = [\n {\n displayText: t('PatientName'),\n fieldName: 'PatientName',\n inputType: 'text',\n size: 330,\n },\n {\n displayText: t('MRN'),\n fieldName: 'PatientID',\n inputType: 'text',\n size: 378,\n },\n {\n displayText: t('AccessionNumber'),\n fieldName: 'AccessionNumber',\n inputType: 'text',\n size: 180,\n },\n {\n displayText: t('StudyDate'),\n fieldName: 'StudyDate',\n inputType: 'date-range',\n size: 300,\n },\n {\n displayText: t('Modality'),\n fieldName: 'modalities',\n inputType: 'text',\n size: 114,\n },\n {\n displayText: t('StudyDescription'),\n fieldName: 'StudyDescription',\n inputType: 'text',\n size: 335,\n },\n ];\n\n const mediumTableMeta = [\n {\n displayText: `${t('PatientName')} / ${t('MRN')}`,\n fieldName: 'patientNameOrId',\n inputType: 'text',\n size: 250,\n },\n {\n displayText: t('Description'),\n fieldName: 'accessionOrModalityOrDescription',\n inputType: 'text',\n size: 350,\n },\n {\n displayText: t('StudyDate'),\n fieldName: 'StudyDate',\n inputType: 'date-range',\n size: 300,\n },\n ];\n\n const smallTableMeta = [\n {\n displayText: t('Search'),\n fieldName: 'allFields',\n inputType: 'text',\n size: 100,\n },\n ];\n\n const tableMeta = getContentFromUseMediaValue(\n displaySize,\n { large: largeTableMeta, medium: mediumTableMeta, small: smallTableMeta },\n smallTableMeta\n );\n\n const totalSize = tableMeta\n .map(field => field.size)\n .reduce((prev, next) => prev + next);\n\n return translationsAreReady ? (\n \n \n {tableMeta.map((field, i) => {\n const size = field.size;\n const percentWidth = (size / totalSize) * 100.0;\n\n return ;\n })}\n \n \n \n \n \n \n \n {/* I'm not in love with this approach, but it's the quickest way for now\n *\n * - Display different content based on loading, empty, results state\n *\n * This is not ideal because it create a jump in focus. For loading especially,\n * We should keep our current results visible while we load the new ones.\n */}\n {/* LOADING */}\n {isLoading && (\n \n \n \n )}\n {!isLoading && hasError && (\n \n \n \n )}\n {/* EMPTY */}\n {!isLoading && !studies.length && (\n \n \n \n )}\n {!isLoading &&\n studies.map((study, index) => (\n handleSelectItem(StudyInstanceUID)}\n AccessionNumber={study.AccessionNumber || ''}\n modalities={study.modalities}\n PatientID={study.PatientID || ''}\n PatientName={study.PatientName || ''}\n StudyDate={study.StudyDate}\n StudyDescription={study.StudyDescription || ''}\n StudyInstanceUID={study.StudyInstanceUID}\n displaySize={displaySize}\n />\n ))}\n \n
    \n \n
    \n
    \n {t('There was an error fetching studies')}\n
    \n
    \n
    {t('No matching results')}
    \n
    \n ) : null;\n}\n\nStudyList.propTypes = {\n isLoading: PropTypes.bool.isRequired,\n hasError: PropTypes.bool.isRequired,\n studies: PropTypes.array.isRequired,\n onSelectItem: PropTypes.func.isRequired,\n // ~~ SORT\n sort: PropTypes.shape({\n fieldName: PropTypes.string,\n direction: PropTypes.oneOf(['desc', 'asc', null]),\n }).isRequired,\n onSort: PropTypes.func.isRequired,\n // ~~ FILTERS\n filterValues: PropTypes.shape({\n PatientName: PropTypes.string.isRequired,\n PatientID: PropTypes.string.isRequired,\n AccessionNumber: PropTypes.string.isRequired,\n StudyDate: PropTypes.string.isRequired,\n modalities: PropTypes.string.isRequired,\n StudyDescription: PropTypes.string.isRequired,\n patientNameOrId: PropTypes.string.isRequired,\n accessionOrModalityOrDescription: PropTypes.string.isRequired,\n allFields: PropTypes.string.isRequired,\n studyDateTo: PropTypes.any,\n studyDateFrom: PropTypes.any,\n }).isRequired,\n onFilterChange: PropTypes.func.isRequired,\n studyListDateFilterNumDays: PropTypes.number,\n displaySize: PropTypes.string,\n};\n\nStudyList.defaultProps = {};\n\nfunction TableRow(props) {\n const {\n AccessionNumber,\n isHighlighted,\n modalities,\n PatientID,\n PatientName,\n StudyDate,\n StudyDescription,\n StudyInstanceUID,\n onClick: handleClick,\n displaySize,\n } = props;\n\n const { t } = useTranslation('StudyList');\n\n const largeRowTemplate = (\n handleClick(StudyInstanceUID)}\n className={classNames({ active: isHighlighted })}\n >\n \n {PatientName || `(${t('Empty')})`}\n \n {PatientID}\n {AccessionNumber}\n {StudyDate}\n \n {modalities || `(${t('Empty')})`}\n \n {StudyDescription}\n \n );\n\n const mediumRowTemplate = (\n handleClick(StudyInstanceUID)}\n className={classNames({ active: isHighlighted })}\n >\n \n {PatientName || `(${t('Empty')})`}\n
    {PatientID}
    \n \n \n
    \n {/* DESCRIPTION */}\n \n {StudyDescription}\n
    \n\n {/* MODALITY & ACCESSION */}\n \n \n {modalities || `(${t('Empty')})`}\n \n \n {AccessionNumber}\n \n \n \n \n {/* DATE */}\n {StudyDate}\n \n );\n\n const smallRowTemplate = (\n handleClick(StudyInstanceUID)}\n className={classNames({ active: isHighlighted })}\n >\n \n
    \n {/* NAME AND ID */}\n \n
    \n {PatientName || `(${t('Empty')})`}\n
    \n
    {PatientID}
    \n
    \n\n {/* DESCRIPTION */}\n \n {StudyDescription}\n \n\n {/* MODALITY & DATE */}\n \n \n {modalities || `(${t('Empty')})`}\n \n
    {StudyDate}
    \n \n \n \n \n );\n\n const rowTemplate = getContentFromUseMediaValue(\n displaySize,\n {\n large: largeRowTemplate,\n medium: mediumRowTemplate,\n small: smallRowTemplate,\n },\n smallRowTemplate\n );\n\n return rowTemplate;\n}\n\nTableRow.propTypes = {\n AccessionNumber: PropTypes.string.isRequired,\n isHighlighted: PropTypes.bool,\n modalities: PropTypes.string,\n PatientID: PropTypes.string.isRequired,\n PatientName: PropTypes.string.isRequired,\n StudyDate: PropTypes.string.isRequired,\n StudyDescription: PropTypes.string.isRequired,\n StudyInstanceUID: PropTypes.string.isRequired,\n displaySize: PropTypes.string,\n};\n\nTableRow.defaultProps = {\n isHighlighted: false,\n};\n\nexport { StudyList };\n","import React, { PureComponent } from 'react';\nimport PropTypes from 'prop-types';\nimport './PaginationArea.styl';\nimport { withTranslation } from '../../contextProviders';\n\nclass TablePagination extends PureComponent {\n static defaultProps = {\n pageOptions: [5, 10, 25, 50, 100],\n rowsPerPage: 25,\n currentPage: 0,\n };\n\n static propTypes = {\n /* Values to show in \"Rows per page\" select dropdown */\n pageOptions: PropTypes.array,\n rowsPerPage: PropTypes.number.isRequired,\n currentPage: PropTypes.number.isRequired,\n nextPageFunc: PropTypes.func,\n prevPageFunc: PropTypes.func,\n onRowsPerPageChange: PropTypes.func,\n recordCount: PropTypes.number.isRequired,\n };\n\n nextPage = () => {\n this.props.nextPageFunc(this.props.currentPage);\n };\n\n prevPage = () => {\n this.props.prevPageFunc(this.props.currentPage);\n };\n\n onRowsPerPageChange = event => {\n this.props.onRowsPerPageChange(parseInt(event.target.value));\n };\n\n renderPaginationButtons() {\n return (\n
    \n
    \n \n
      \n
    • \n \n {this.props.t('Previous')}\n \n
    • \n
    • \n this.props.recordCount\n }\n className=\"btn page-link\"\n >\n {this.props.t('Next')}\n \n
    • \n
    \n
    \n
    \n
    \n );\n }\n\n renderRowsPerPageDropdown() {\n return (\n
    \n {this.props.t('Show')}\n \n {this.props.pageOptions.map(pageNumber => {\n return (\n \n );\n })}\n \n {this.props.t('RowsPerPage')}\n
    \n );\n }\n\n render() {\n return (\n
    \n
    {this.renderRowsPerPageDropdown()}
    \n
    \n
    \n {this.renderPaginationButtons()}\n
    \n
    \n
    \n );\n }\n}\n\nconst connectedComponent = withTranslation('Common')(TablePagination);\nexport { connectedComponent as TablePagination };\n","import React, { PureComponent } from 'react';\n\nimport { Icon } from './../../elements/Icon';\nimport PropTypes from 'prop-types';\n\nclass PageToolbar extends PureComponent {\n static propTypes = {\n onImport: PropTypes.func,\n };\n\n onImport = event => {\n if (this.props.onImport) {\n this.props.onImport(event);\n }\n };\n\n getImportTool() {\n if (this.props.onImport) {\n return (\n
    \n \n \n \n
    \n );\n }\n }\n\n render() {\n return
    {this.getImportTool()}
    ;\n }\n}\n\nexport { PageToolbar };\n","import './ExpandableToolMenu.styl';\n\nimport { OverlayTrigger } from '../components/overlayTrigger';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport ToolbarButton from './ToolbarButton.js';\nimport { Tooltip } from '../components/tooltip';\n\nclass ExpandableToolMenu extends React.Component {\n static propTypes = {\n /** Button label */\n label: PropTypes.string.isRequired,\n /** Array of buttons to render when expanded */\n buttons: PropTypes.arrayOf(\n PropTypes.shape({\n id: PropTypes.string,\n label: PropTypes.string.isRequired,\n icon: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.shape({\n name: PropTypes.string.isRequired,\n }),\n ]),\n })\n ).isRequired,\n icon: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.shape({\n name: PropTypes.string.isRequired,\n }),\n ]),\n onGroupMenuClick: PropTypes.func,\n activeCommand: PropTypes.string,\n };\n\n static defaultProps = {\n buttons: [],\n icon: 'ellipse-circle',\n label: 'More',\n };\n\n constructor(props) {\n super(props);\n this.state = {\n isExpanded: false,\n };\n }\n\n toolbarMenuOverlay = () => (\n \n {this.getButtons()}\n \n );\n\n getButtons = () => {\n return this.props.buttons.map((button, index) => {\n return (\n \n );\n });\n };\n\n isActive = () => {\n let isActive = false;\n if (this.props.activeCommand) {\n this.props.buttons.forEach(button => {\n if (this.props.activeCommand === button.id) {\n isActive = true;\n }\n });\n }\n\n return isActive;\n };\n\n activeIcon = () => {\n if (this.props.activeCommand) {\n return (\n this.props.buttons.find(btn => this.props.activeCommand === btn.id)\n .icon || this.props.icon\n );\n }\n\n return this.props.icon;\n };\n\n onExpandableToolClick = () => {\n if (this.props.onGroupMenuClick) {\n this.props.onGroupMenuClick();\n }\n this.setState({\n isExpanded: !this.state.isExpanded,\n });\n };\n\n onOverlayHide = () => {\n this.setState({\n isExpanded: false,\n });\n };\n\n render() {\n const getToolBarButtonComponent = () => {\n return (\n \n );\n };\n\n const toolbarComponent = getToolBarButtonComponent();\n\n return (\n \n {toolbarComponent}\n \n );\n }\n}\n\nexport default ExpandableToolMenu;\n","import './ToolbarSection.styl';\n\nimport React, { PureComponent } from 'react';\n\nimport ExpandableToolMenu from '../../viewer/ExpandableToolMenu';\nimport PropTypes from 'prop-types';\nimport ToolbarButton from '../../viewer/ToolbarButton';\nimport classnames from 'classnames';\n\nclass ToolbarSection extends PureComponent {\n static defaultProps = {\n className: '',\n };\n\n static propTypes = {\n buttons: PropTypes.arrayOf(\n PropTypes.shape({\n id: PropTypes.string,\n label: PropTypes.string.isRequired,\n icon: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.shape({\n name: PropTypes.string.isRequired,\n }),\n ]),\n /** Optional: Expandable Tool Menu */\n buttons: PropTypes.arrayOf(PropTypes.shape({})),\n })\n ).isRequired,\n /** Array of string button ids that should show as active */\n activeButtons: PropTypes.arrayOf(PropTypes.string).isRequired,\n /** Class for toolbar section container */\n className: PropTypes.string,\n };\n\n render() {\n const items = this.props.buttons.map((button, index) => {\n if (button.buttons && Array.isArray(button.buttons)) {\n return (\n \n );\n } else {\n return (\n \n );\n }\n });\n\n return (\n
    \n {items}\n
    \n );\n }\n}\n\nexport { ToolbarSection };\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { ErrorBoundary } from 'react-error-boundary';\nimport './ErrorFallback.css';\n\nconst ErrorFallback = ({ error, componentStack, resetErrorBoundary }) => {\n return (\n
    \n

    Something went wrong.

    \n
    {error.message}
    \n
    {componentStack}
    \n
    \n );\n};\n\nconst OHIFErrorBoundary = ({\n context = 'OHIF',\n onReset = () => { },\n onError = () => { },\n fallbackComponent,\n children,\n}) => {\n const onErrorHandler = (error, componentStack) => {\n console.error(`${context} Error Boundary`, error, componentStack);\n onError(error, componentStack);\n };\n\n const onResetHandler = () => {\n onReset();\n };\n\n return (\n \n {children}\n \n );\n};\n\nOHIFErrorBoundary.propTypes = {\n context: PropTypes.string,\n onReset: PropTypes.func,\n onError: PropTypes.func,\n children: PropTypes.node.isRequired,\n fallbackComponent: PropTypes.oneOfType([PropTypes.node, PropTypes.func, PropTypes.element]),\n};\n\nexport default OHIFErrorBoundary;\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport isEqual from 'lodash.isequal';\n/**\n * Get display size value for matched mediaQueryList\n * @param {MediaQueryList[]} mediaQueryMap - Array of mappings, containing MediaQueryLists\n * @param {Array} mediaTypesAliases - Array of strings representing each mediaQueryAlias.\n * @param {string} defaultDisplaySize - default display size value. Fallback value.\n */\nconst getDisplaySize = (\n mediaQueryMap,\n mediaTypesAliases,\n defaultDisplaySize\n) => {\n if ((!mediaTypesAliases && !defaultDisplaySize) || !mediaQueryMap) {\n return;\n }\n\n // Get index of first media query that matches\n const index = mediaQueryMap.findIndex(mql => mql.matches);\n\n // Return related value or defaultDisplaySize if none\n return index >= 0 && typeof mediaTypesAliases[index] !== 'undefined'\n ? mediaTypesAliases[index]\n : defaultDisplaySize;\n};\n/**\n * Map each window MediaQueryLists\n * @param {Array} mediaQueriesStringList - array of string media queries to be parsed\n */\nconst getMediaQueryMap = mediaQueriesStringList => {\n return (\n mediaQueriesStringList &&\n mediaQueriesStringList.map(q => window.matchMedia(q))\n );\n};\n\nconst getMediaTypeAlias = (mediaQuery, state) => {\n const { media } = mediaQuery;\n const { mediaQueriesStringList, mediaTypesAliases } = state;\n\n const index = mediaQueriesStringList.findIndex(originalMediaQuery => {\n const { media: toCompareMedia } = window.matchMedia(originalMediaQuery);\n return toCompareMedia === media;\n });\n\n return mediaTypesAliases[index];\n};\n\n/**\n * Hook to get current displaySize value.\n *\n * Its state changes and also displaySize value changes in case viewport is resized.\n * Its state changes in case mediaQueriesStringList or mediaTypesAliases changes.\n *\n * Current hook only offers displayMedia size, it wont expose method to change its state.\n * @param {Array} mediaQueriesStringList - array of string media queries to be parsed\n * @param {Array} mediaTypesAliases - array of aliases. Each value represents one mediaQueryList from array mediaQueriesStringList\n * @param {String} defaultMediaType - default mediaTypeAlias\n * @returns {String} current displayMedia size based on viewport size.\n *\n * @example Example to getDisplayMedia Size based on viewport size\n *\n * const displaySize = useMedia(\n * ['(min-width: 1500px)', '(min-width: 1000px)', '(min-width: 600px)'],\n * // Value to return for matched media query\n * ['large', 'medium', 'small'],\n * // Default value\n * 'medium');\n *\n * const currentDisplaySize = useMedia();\n *\n */\nconst useMedia = (\n mediaQueriesStringList,\n mediaTypesAliases,\n defaultMediaType\n) => {\n // MediaQuery.state is the source of truth. This hook will be dependent on it.\n const [state, setState] = useState(() => {\n const _mediaQueryMap = getMediaQueryMap(mediaQueriesStringList);\n const _displaySize = getDisplaySize(\n _mediaQueryMap,\n mediaTypesAliases,\n defaultMediaType\n );\n\n return {\n mediaQueryMap: _mediaQueryMap,\n displaySize: _displaySize,\n mediaQueriesStringList,\n mediaTypesAliases,\n defaultMediaType,\n };\n });\n let mount = useRef(false);\n\n const updateDisplaySize = displaySize => {\n if (mount.current) {\n setState({ ...state, displaySize });\n }\n };\n\n const updateState = value => {\n const {\n mediaQueriesStringList,\n mediaTypesAliases,\n defaultMediaType,\n } = value;\n\n const mediaQueryMap = getMediaQueryMap(mediaQueriesStringList);\n const displaySize = getDisplaySize(\n mediaQueryMap,\n mediaTypesAliases,\n defaultMediaType\n );\n // immutable state\n // last chance to avoid setState of unmount component\n if (mount.current) {\n setState({\n ...state,\n mediaQueriesStringList,\n mediaTypesAliases,\n displaySize,\n mediaQueryMap,\n });\n }\n };\n\n const onMediaQueryChange = useCallback(mediaQuery => {\n if (mediaQuery.matches) {\n const nextDisplaySize = getMediaTypeAlias(mediaQuery, state);\n updateDisplaySize(nextDisplaySize);\n }\n }, []);\n\n // update state of MediaQuery in case mediaQueriesStringList or mediaTypesAliases has changed\n useEffect(() => {\n const {\n mediaQueriesStringList: _mediaQueriesStringList,\n mediaTypesAliases: _mediaTypesAliases,\n } = state;\n if (\n (mediaQueriesStringList &&\n !isEqual(mediaQueriesStringList, _mediaQueriesStringList)) ||\n (mediaTypesAliases && !isEqual(mediaTypesAliases, _mediaTypesAliases))\n ) {\n updateState({\n mediaQueriesStringList,\n mediaTypesAliases,\n });\n }\n }, [mediaQueriesStringList, mediaTypesAliases]);\n\n // re-assign window resizing listeners\n useEffect(() => {\n const { mediaQueryMap } = state;\n mediaQueryMap.forEach(mql => {\n mql.removeListener(onMediaQueryChange);\n mql.addListener(onMediaQueryChange);\n });\n }, [state.mediaQueryMap]);\n\n useEffect(() => {\n mount.current = true;\n\n return () => {\n mount.current = false;\n const { mediaQueryMap } = state;\n mediaQueryMap.forEach(mql => {\n mql.removeListener(onMediaQueryChange);\n });\n };\n }, []);\n\n return state.displaySize;\n};\n\nexport { useMedia };\n","import React, { useState, useEffect } from 'react';\n\n/**\n * A hook to set a value\n *\n * @param {*} value - A value to \"set\"\n * @param {number} delay - The debounce delay for setting the value\n * @returns\n */\nexport default function useDebounce(value, delay) {\n const [debouncedValue, setDebouncedValue] = useState(value);\n\n useEffect(\n () => {\n // Set debouncedValue to value (passed in) after the specified delay\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n // Return a cleanup function that will be called every time useEffect is\n // re-called. useEffect will only be re-called if value changes (see the\n // inputs array below).\n //\n // This is how we prevent debouncedValue from changing if value is changed\n // within the delay period. Timeout gets cleared and restarted.\n //\n // To put it in context, if the user is typing within our app's search\n // box, we don't want the debouncedValue to update until they've stopped\n // typing for more than 500ms.\n return () => {\n clearTimeout(handler);\n };\n },\n // Only re-call effect if value changes\n // You could also add the \"delay\" var to inputs array if you need to be\n // able to change that dynamically.\n [value]\n );\n\n return debouncedValue;\n}\n","import './Select.css';\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nclass Select extends Component {\n constructor(props) {\n super(props);\n this.state = {\n value: this.props.value,\n };\n }\n\n handleChange = event => {\n const value = event.target.value;\n this.setState({ value });\n if (this.props.onChange) this.props.onChange(value);\n };\n\n render() {\n return (\n \n {this.props.options.map(({ key, value }) => {\n return (\n \n );\n })}\n \n );\n }\n}\n\nSelect.propTypes = {\n options: PropTypes.arrayOf(\n PropTypes.shape({\n key: PropTypes.string.isRequired,\n value: PropTypes.string.isRequired,\n })\n ),\n value: PropTypes.string,\n onChange: PropTypes.func,\n};\n\nexport default Select;\n","import './Select.css';\n\nimport React, { Component } from 'react';\n\nimport PropTypes from 'prop-types';\n\nclass Select extends Component {\n constructor(props) {\n super(props);\n }\n\n static propTypes = {\n options: PropTypes.arrayOf(\n PropTypes.shape({\n key: PropTypes.string.isRequired,\n value: PropTypes.string.isRequired,\n })\n ),\n value: PropTypes.string,\n onChange: PropTypes.func,\n };\n\n handleChange = event => {\n const value = event.target.value;\n this.setState({ value });\n if (this.props.onChange) this.props.onChange(value);\n };\n\n render() {\n return (\n
    \n {this.props.label && (\n \n )}\n \n
    \n );\n }\n}\n\nexport { Select };\n","import './Label.css';\n\nimport React from 'react';\n\nimport PropTypes from 'prop-types';\n\nclass Label extends React.Component {\n constructor(props) {\n super(props);\n this.state = { value: this.props.text };\n }\n\n render() {\n return (\n \n );\n }\n}\n\nLabel.propTypes = {\n text: PropTypes.string.isRequired,\n for: PropTypes.string,\n};\n\nexport { Label };\n","import './Range.css';\n\nimport React, { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nclass Range extends Component {\n constructor(props) {\n super(props);\n this.state = { value: props.value || 0 };\n }\n\n handleChange = event => {\n this.setState({ value: event.target.value });\n if (this.props.onChange) this.props.onChange(event);\n };\n\n render() {\n return (\n <>\n \n {this.props.showPercentage && {`${this.state.value}%`}}\n {this.props.showValue && (\n \n {this.props.valueRenderer\n ? this.props.valueRenderer(this.state.value)\n : this.state.value}\n \n )}\n \n );\n }\n}\n\nRange.propTypes = {\n value: PropTypes.number,\n min: PropTypes.number.isRequired,\n max: PropTypes.number.isRequired,\n step: PropTypes.number,\n id: PropTypes.string,\n valueRenderer: PropTypes.func,\n onChange: PropTypes.func,\n showPercentage: PropTypes.bool,\n showValue: PropTypes.bool,\n};\n\nRange.defaultProps = {\n showPercentage: false,\n showValue: false,\n};\n\nexport { Range };\n","import './TextArea.css';\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nclass TextArea extends React.Component {\n constructor(props) {\n super(props);\n this.state = { value: this.props.value };\n }\n\n handleChange = event => {\n this.setState({ value: event.target.value });\n if (this.props.onChange) this.props.onChange();\n };\n\n render() {\n return (\n \n );\n }\n}\n\nTextArea.propTypes = {\n value: PropTypes.string,\n Rows: PropTypes.number,\n cols: PropTypes.number,\n id: PropTypes.string,\n onChange: PropTypes.func,\n};\n\nexport { TextArea };\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport './TextInput.css';\n\nclass TextInput extends React.Component {\n constructor(props) {\n super(props);\n }\n\n static propTypes = {\n value: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.number\n ]),\n id: PropTypes.string,\n label: PropTypes.string,\n type: PropTypes.string,\n };\n\n static defaultProps = {\n value: '',\n id: `TextInput-${new Date().toTimeString()}`,\n label: undefined,\n type: 'text',\n };\n\n render() {\n return (\n
    \n {this.props.label && (\n \n )}\n \n
    \n );\n }\n}\n\nexport { TextInput };\n","import './DropdownMenu.css';\n\nimport React, { Component } from 'react';\n\nimport { Icon } from '../Icon';\nimport PropTypes from 'prop-types';\n\nclass DropdownMenu extends Component {\n state = {\n open: false,\n };\n\n static propTypes = {\n titleElement: PropTypes.node,\n title: PropTypes.string,\n align: PropTypes.oneOf(['left', 'center', 'right']),\n /** Items to render in the select's drop down */\n list: PropTypes.arrayOf(\n PropTypes.shape({\n title: PropTypes.string.isRequired,\n icon: PropTypes.object,\n onClick: PropTypes.func,\n link: PropTypes.string,\n })\n ),\n };\n\n getListItems = () => {\n const { list, align } = this.props;\n\n return list.map(({ icon, title, link, onClick }, key) => {\n if (link) {\n return (\n this.handleOnClick(onClick)}\n >\n {icon && }\n {title}\n \n );\n } else {\n return (\n this.handleOnClick(onClick)}\n >\n {icon && }\n {title}\n \n );\n }\n });\n };\n\n renderList = () => {\n const { align } = this.props;\n\n if (!this.state.open) {\n return null;\n }\n\n return (\n
    \n {this.getListItems()}\n
    \n );\n };\n\n handleOnClick = onClick => {\n this.toggleList();\n\n if (onClick) {\n onClick();\n }\n };\n\n handleMouseClick = e => {\n if (this.node.contains(e.target)) {\n return;\n }\n\n this.toggleList();\n };\n\n renderTitleElement = () => {\n const { titleElement, title } = this.props;\n\n if (titleElement) {\n return titleElement;\n }\n\n return (\n \n {title}\n \n \n );\n };\n\n toggleList = () => {\n const { open } = this.state;\n let state = true;\n\n document.addEventListener('mousedown', this.handleMouseClick, false);\n\n if (open) {\n document.removeEventListener('mousedown', this.handleMouseClick, false);\n state = false;\n }\n\n this.setState({\n open: state,\n });\n };\n\n render() {\n return (\n (this.node = node)}\n >\n
    \n {this.renderTitleElement()}\n
    \n\n {this.renderList()}\n \n );\n }\n}\n\nexport { DropdownMenu };\n","import React, { Component } from 'react';\n\nimport { Icon } from './../elements/Icon';\nimport PropTypes from 'prop-types';\n\nexport default class PlayClipButton extends Component {\n static propTypes = {\n isPlaying: PropTypes.bool.isRequired,\n };\n\n static defaultProps = {\n isPlaying: false,\n };\n\n render() {\n const iconName = this.props.isPlaying ? 'stop' : 'play';\n\n return (\n
    \n \n \n \n \n \n \n
    \n );\n }\n}\n","import { Icon } from './../elements/Icon';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport classnames from 'classnames';\n\nexport function SimpleToolbarButton(props) {\n const className = classnames(props.className, 'btn btn-sm btn-default');\n\n return (\n \n {props.icon && }\n \n );\n}\n\nSimpleToolbarButton.propTypes = {\n icon: PropTypes.string,\n title: PropTypes.string,\n className: PropTypes.string,\n id: PropTypes.string,\n onClick: PropTypes.func,\n};\nexport default SimpleToolbarButton;\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport SimpleToolbarButton from './SimpleToolbarButton';\nimport PlayClipButton from './PlayClipButton';\nimport { LayoutButton } from './../components/layoutButton';\n\n// TODO: This should not be built in the `@ohif/ui` component\nfunction getDefaultButtonData() {\n var buttonData = [\n {\n id: 'wwwc',\n title: 'WW/WC',\n className: 'imageViewerTool',\n icon: 'sun',\n },\n {\n id: 'wwwcRegion',\n title: 'Window by Region',\n className: 'imageViewerTool',\n icon: 'stop',\n },\n {\n id: 'magnify',\n title: 'Magnify',\n className: 'imageViewerTool',\n icon: 'circle',\n },\n {\n id: 'annotate',\n title: 'Annotation',\n className: 'imageViewerTool',\n icon: 'arrows-alt-h',\n },\n {\n id: 'invert',\n title: 'Invert',\n className: 'imageViewerCommand',\n icon: 'adjust',\n },\n {\n id: 'zoom',\n title: 'Zoom',\n className: 'imageViewerTool',\n icon: 'search-plus',\n },\n {\n id: 'pan',\n title: 'Pan',\n className: 'imageViewerTool',\n icon: 'arrows',\n },\n {\n id: 'stackScroll',\n title: 'Stack Scroll',\n className: 'imageViewerTool',\n icon: 'bars',\n },\n {\n id: 'length',\n title: 'Length Measurement',\n className: 'imageViewerTool',\n icon: 'arrows-alt-v',\n },\n {\n id: 'angle',\n title: 'Angle Measurement',\n className: 'imageViewerTool',\n icon: 'fa fa-angle-left',\n },\n {\n id: 'dragProbe',\n title: 'Pixel Probe',\n className: 'imageViewerTool',\n icon: 'fa fa-dot-circle-o',\n },\n {\n id: 'ellipticalRoi',\n title: 'Elliptical ROI',\n className: 'imageViewerTool',\n icon: 'circle-o',\n },\n {\n id: 'rectangleRoi',\n title: 'Rectangle ROI',\n className: 'imageViewerTool',\n icon: 'square-o',\n },\n {\n id: 'resetViewport',\n title: 'Reset Viewport',\n className: 'imageViewerCommand',\n icon: 'reset',\n },\n {\n id: 'clearTools',\n title: 'Clear tools',\n className: 'imageViewerCommand',\n icon: 'trash',\n },\n ];\n return buttonData;\n}\n\nexport default class Toolbar extends Component {\n static propTypes = {\n buttons: PropTypes.arrayOf(\n PropTypes.shape({\n id: PropTypes.string.isRequired,\n title: PropTypes.string.isRequired,\n icon: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.shape({\n name: PropTypes.string.isRequired,\n }),\n ]),\n })\n ).isRequired,\n includeLayoutButton: PropTypes.bool.isRequired,\n includePlayClipButton: PropTypes.bool.isRequired,\n };\n\n static defaultProps = {\n buttons: getDefaultButtonData(),\n includeLayoutButton: true,\n includePlayClipButton: true,\n };\n\n render() {\n var maybePlayClipButton;\n if (this.props.includePlayClipButton) {\n maybePlayClipButton = ;\n }\n\n var maybeLayoutButton;\n if (this.props.includeLayoutButton) {\n maybeLayoutButton = ;\n }\n\n return (\n
    \n
    \n {this.props.buttons.map((button, i) => {\n return ;\n })}\n {maybePlayClipButton}\n {maybeLayoutButton}\n
    \n
    \n );\n }\n}\n","import React from 'react';\nimport { DndProvider } from \"react-dnd\";\nimport HTML5Backend from 'react-dnd-html5-backend';\nimport TouchBackend from 'react-dnd-touch-backend';\n\nconst isTouchDevice = !!('ontouchstart' in window || navigator.maxTouchPoints);\n\n// See https://github.com/react-dnd/react-dnd/issues/186#issuecomment-335429067\n// https://github.com/react-dnd/react-dnd/issues/186#issuecomment-282789420\n//\n// http://react-dnd.github.io/react-dnd/docs/api/drag-drop-context\nexport default function viewerbaseDragDropContext(DecoratedClass) {\n const backend = isTouchDevice ? TouchBackend : HTML5Backend;\n const opts = isTouchDevice ? { enableMouseEvents: true } : {};\n\n return (props) => (\n \n \n \n );\n}\n","import React, { useState, useEffect } from 'react';\nimport { ErrorPage } from '@ohif/ui';\n\nexport const retryImport = (fn, retriesLeft = 5, interval = 1000) =>\n new Promise((resolve, reject) => {\n fn().then(resolve).catch((error) => {\n setTimeout(() => {\n if (retriesLeft === 1) {\n /* reject('maximum retries exceeded'); */\n reject(error);\n return;\n }\n\n /* Passing on \"reject\" is the important part */\n retry(fn, retriesLeft - 1, interval).then(resolve, reject);\n }, interval);\n });\n });\n\nconst onError = (error, setState) => setState({ component: ErrorPage });\n\n/**\n * We use this function to lazy load the import of a component to leverage 'Code Splitting'\n * Link: https://serverless-stack.com/chapters/code-splitting-in-create-react-app.html\n */\nconst asyncComponent = (importComponent, options = { onError }) => props => {\n const [state, setState] = useState({ component: null });\n\n const isFunction = item => typeof item === 'function';\n const isChunkError = error => error.toString().indexOf('ChunkLoadError') > -1;\n\n useEffect(() => {\n const addDynamicallyLoadedComponentToState = async () => {\n try {\n const { default: component } = await importComponent();\n setState({ component });\n if (options.onLoaded && isFunction(options.onLoaded)) {\n options.onLoaded(component);\n }\n } catch (error) {\n console.error('[AsyncComponent] Failed to import chunk:', error);\n\n if (options.onError && isFunction(options.onError)) {\n options.onError(error, setState);\n return;\n }\n\n if (isChunkError(error)) {\n console.error('[AsyncComponent] Reloading due to chunk error');\n window.location.reload();\n }\n }\n };\n\n addDynamicallyLoadedComponentToState();\n }, []);\n\n const Component = state.component;\n return Component ? : null;\n};\n\nexport default asyncComponent;\n","import {\n ContextMenu,\n Checkbox,\n CineDialog,\n ViewportDownloadForm,\n LayoutButton,\n LayoutChooser,\n MeasurementTable,\n MeasurementTableItem,\n Overlay,\n OverlayTrigger,\n PageToolbar,\n QuickSwitch,\n RoundedButtonGroup,\n SelectTree,\n SimpleDialog,\n StudyBrowser,\n StudyList,\n TableList,\n TableListItem,\n Thumbnail,\n TabComponents,\n TabFooter,\n HotkeyField,\n LanguageSwitcher,\n TableSearchFilter,\n TablePagination,\n ToolbarSection,\n Tooltip,\n AboutContent,\n OHIFModal,\n ErrorBoundary,\n ErrorPage,\n} from './components';\nimport { useDebounce, useMedia } from './hooks';\n\n// Elements\nimport {\n ICONS,\n Icon,\n DropdownMenu as Dropdown,\n Select,\n OldSelect,\n Label,\n Range,\n TextArea,\n TextInput,\n} from './elements';\n\n// Alias this for now as not all dependents are using strict versioning\nimport ExpandableToolMenu from './viewer/ExpandableToolMenu.js';\nimport PlayClipButton from './viewer/PlayClipButton.js';\nimport { ScrollableArea } from './ScrollableArea/ScrollableArea.js';\nimport Toolbar from './viewer/Toolbar.js';\nimport ToolbarButton from './viewer/ToolbarButton.js';\nimport ViewerbaseDragDropContext from './utils/viewerbaseDragDropContext.js';\nimport { asyncComponent, retryImport } from './utils/asyncComponent';\nimport {\n SnackbarProvider,\n useSnackbarContext,\n withSnackbar,\n DialogProvider,\n useDialog,\n withDialog,\n ModalProvider,\n ModalConsumer,\n useModal,\n withModal,\n LoggerProvider,\n withLogger,\n useLogger,\n} from './contextProviders';\n\nexport {\n // Elements\n ICONS,\n //\n Checkbox,\n Dropdown,\n Label,\n TextArea,\n TextInput,\n CineDialog,\n ContextMenu,\n ViewportDownloadForm,\n ExpandableToolMenu,\n Icon,\n LayoutButton,\n LayoutChooser,\n MeasurementTable,\n MeasurementTableItem,\n Overlay,\n OverlayTrigger,\n PlayClipButton,\n PageToolbar,\n QuickSwitch,\n Range,\n RoundedButtonGroup,\n ScrollableArea,\n Select,\n OldSelect,\n SelectTree,\n SimpleDialog,\n StudyBrowser,\n StudyList,\n TableList,\n TableListItem,\n Thumbnail,\n TabComponents,\n TabFooter,\n HotkeyField,\n LanguageSwitcher,\n TableSearchFilter,\n TablePagination,\n Toolbar,\n ToolbarButton,\n ToolbarSection,\n Tooltip,\n AboutContent,\n SnackbarProvider,\n useSnackbarContext,\n withSnackbar,\n ModalProvider,\n useModal,\n ModalConsumer,\n withModal,\n OHIFModal,\n DialogProvider,\n withDialog,\n useDialog,\n ErrorBoundary,\n ErrorPage,\n LoggerProvider,\n withLogger,\n useLogger,\n // Hooks\n useDebounce,\n useMedia,\n // Utils\n ViewerbaseDragDropContext,\n asyncComponent,\n retryImport,\n};\n","import getAttribute from './getAttribute.js';\nimport getAuthorizationHeader from './getAuthorizationHeader.js';\nimport getModalities from './getModalities.js';\nimport getName from './getName.js';\nimport getNumber from './getNumber.js';\nimport getString from './getString.js';\n\nconst DICOMWeb = {\n getAttribute,\n getAuthorizationHeader,\n getModalities,\n getName,\n getNumber,\n getString,\n};\n\nexport default DICOMWeb;\n","/**\n * Returns the specified element as a dicom attribute group/element.\n *\n * @param element - The group/element of the element (e.g. '00280009')\n * @param [defaultValue] - The value to return if the element is not present\n * @returns {*}\n */\nexport default function getAttribute(element, defaultValue) {\n if (!element) {\n return defaultValue;\n }\n // Value is not present if the attribute has a zero length value\n if (!element.Value) {\n return defaultValue;\n }\n // Sanity check to make sure we have at least one entry in the array.\n if (!element.Value.length) {\n return defaultValue;\n }\n\n return convertToInt(element.Value);\n}\n\nfunction convertToInt(input) {\n function padFour(input) {\n const l = input.length;\n\n if (l == 0) return '0000';\n if (l == 1) return '000' + input;\n if (l == 2) return '00' + input;\n if (l == 3) return '0' + input;\n\n return input;\n }\n\n let output = '';\n for (let i = 0; i < input.length; i++) {\n for (let j = 0; j < input[i].length; j++) {\n output += padFour(input[i].charCodeAt(j).toString(16));\n }\n }\n\n return parseInt(output, 16);\n}\n","import user from '../user';\n\n/**\n * Returns the Authorization header as part of an Object.\n *\n * @export\n * @param {Object} [server={}]\n * @param {Object} [server.requestOptions]\n * @param {string|function} [server.requestOptions.auth]\n * @returns {Object} { Authorization }\n */\nexport default function getAuthorizationHeader({ requestOptions } = {}) {\n const headers = {};\n\n // Check for OHIF.user since this can also be run on the server\n const accessToken = user && user.getAccessToken && user.getAccessToken();\n\n // Auth for a specific server\n if (requestOptions && requestOptions.auth) {\n if (typeof requestOptions.auth === 'function') {\n // Custom Auth Header\n headers.Authorization = requestOptions.auth(requestOptions);\n } else {\n // HTTP Basic Auth (user:password)\n headers.Authorization = `Basic ${btoa(requestOptions.auth)}`;\n }\n }\n // Auth for the user's default\n else if (accessToken) {\n headers.Authorization = `Bearer ${accessToken}`;\n }\n\n return headers;\n}\n","export default function getModalities(Modality, ModalitiesInStudy) {\n if (!Modality && !ModalitiesInStudy) {\n return {};\n }\n\n const modalities = Modality || {\n vr: 'CS',\n Value: [],\n };\n\n if (ModalitiesInStudy) {\n if (modalities.vr && modalities.vr === ModalitiesInStudy.vr) {\n for (let i = 0; i < ModalitiesInStudy.Value.length; i++) {\n const value = ModalitiesInStudy.Value[i];\n if (modalities.Value.indexOf(value) === -1) {\n modalities.Value.push(value);\n }\n }\n } else {\n return ModalitiesInStudy;\n }\n }\n\n return modalities;\n}\n","/**\n * Returns the Alphabetic version of a PN\n *\n * @param element - The group/element of the element (e.g. '00200013')\n * @param [defaultValue] - The default value to return if the element is not found\n * @returns {*}\n */\nexport default function getName(element, defaultValue) {\n if (!element) {\n return defaultValue;\n }\n // Value is not present if the attribute has a zero length value\n if (!element.Value) {\n return defaultValue;\n }\n // Sanity check to make sure we have at least one entry in the array.\n if (!element.Value.length) {\n return defaultValue;\n }\n // Return the Alphabetic component group\n if (element.Value[0].Alphabetic) {\n return element.Value[0].Alphabetic;\n }\n // Orthanc does not return PN properly so this is a temporary workaround\n return element.Value[0];\n}\n","/**\n * Returns the first string value as a Javascript Number\n * @param element - The group/element of the element (e.g. '00200013')\n * @param [defaultValue] - The default value to return if the element does not exist\n * @returns {*}\n */\nexport default function getNumber(element, defaultValue) {\n if (!element) {\n return defaultValue;\n }\n // Value is not present if the attribute has a zero length value\n if (!element.Value) {\n return defaultValue;\n }\n // Sanity check to make sure we have at least one entry in the array.\n if (!element.Value.length) {\n return defaultValue;\n }\n\n return parseFloat(element.Value[0]);\n}\n","/**\n * Returns the specified element as a string. Multi-valued elements will be separated by a backslash\n *\n * @param element - The group/element of the element (e.g. '00200013')\n * @param [defaultValue] - The value to return if the element is not present\n * @returns {*}\n */\nexport default function getString(element, defaultValue) {\n if (!element) {\n return defaultValue;\n }\n // Value is not present if the attribute has a zero length value\n if (!element.Value) {\n return defaultValue;\n }\n // Sanity check to make sure we have at least one entry in the array.\n if (!element.Value.length) {\n return defaultValue;\n }\n // Join the array together separated by backslash\n // NOTE: Orthanc does not correctly split values into an array so the join is a no-op\n return element.Value.join('\\\\');\n}\n","import metadataProvider from './classes/MetadataProvider';\nimport {\n getBoundingBox,\n pixelToPage,\n repositionTextBox,\n} from './lib/cornerstone.js';\n\nconst cornerstone = {\n metadataProvider,\n getBoundingBox,\n pixelToPage,\n repositionTextBox,\n};\n\nexport default cornerstone;\n","import cornerstone from 'cornerstone-core';\nimport cornerstoneTools from 'cornerstone-tools';\n\nfunction getBoundingBox(context, textLines, x, y, options) {\n if (Object.prototype.toString.call(textLines) !== '[object Array]') {\n textLines = [textLines];\n }\n\n const padding = 5;\n const font = cornerstoneTools.textStyle.getFont();\n const fontSize = cornerstoneTools.textStyle.getFontSize();\n\n context.save();\n context.font = font;\n context.textBaseline = 'top';\n\n // Find the longest text width in the array of text data\n let maxWidth = 0;\n\n textLines.forEach(text => {\n // Get the text width in the current font\n const width = context.measureText(text).width;\n\n // Find the maximum with for all the text Rows;\n maxWidth = Math.max(maxWidth, width);\n });\n\n // Calculate the bounding box for this text box\n const boundingBox = {\n width: maxWidth + padding * 2,\n height: padding + textLines.length * (fontSize + padding),\n };\n\n if (options && options.centering && options.centering.x === true) {\n x -= boundingBox.width / 2;\n }\n\n if (options && options.centering && options.centering.y === true) {\n y -= boundingBox.height / 2;\n }\n\n boundingBox.left = x;\n boundingBox.top = y;\n\n context.restore();\n\n // Return the bounding box so it can be used for pointNearHandle\n return boundingBox;\n}\n\nfunction pixelToPage(element, position) {\n const enabledElement = cornerstone.getEnabledElement(element);\n const result = {\n x: 0,\n y: 0,\n };\n\n // Stop here if the cornerstone element is not enabled or position is not an object\n if (!enabledElement || typeof position !== 'object') {\n return result;\n }\n\n const canvas = enabledElement.canvas;\n\n const canvasOffset = $(canvas).offset();\n result.x += canvasOffset.left;\n result.y += canvasOffset.top;\n\n const canvasPosition = cornerstone.pixelToCanvas(element, position);\n result.x += canvasPosition.x;\n result.y += canvasPosition.y;\n\n return result;\n}\n\nfunction repositionTextBox(eventData, measurementData, config) {\n // Stop here if it's not a measurement creating\n if (!measurementData.isCreating) {\n return;\n }\n\n const element = eventData.element;\n const enabledElement = cornerstone.getEnabledElement(element);\n const image = enabledElement.image;\n\n const allowedBorders = OHIF.uiSettings.autoPositionMeasurementsTextCallOuts;\n const allow = {\n T: !allowedBorders || allowedBorders.includes('T'),\n R: !allowedBorders || allowedBorders.includes('R'),\n B: !allowedBorders || allowedBorders.includes('B'),\n L: !allowedBorders || allowedBorders.includes('L'),\n };\n\n const getAvailableBlankAreas = (enabledElement, labelWidth, labelHeight) => {\n const { element, canvas, image } = enabledElement;\n\n const topLeft = cornerstone.pixelToCanvas(element, {\n x: 0,\n y: 0,\n });\n\n const bottomRight = cornerstone.pixelToCanvas(element, {\n x: image.width,\n y: image.height,\n });\n\n const $canvas = $(canvas);\n const canvasWidth = $canvas.outerWidth();\n const canvasHeight = $canvas.outerHeight();\n\n const result = {};\n result['x-1'] = allow.L && topLeft.x > labelWidth;\n result['y-1'] = allow.T && topLeft.y > labelHeight;\n result.x1 = allow.R && canvasWidth - bottomRight.x > labelWidth;\n result.y1 = allow.B && canvasHeight - bottomRight.y > labelHeight;\n\n return result;\n };\n\n const getRenderingInformation = (limits, tool) => {\n const mid = {};\n mid.x = limits.x / 2;\n mid.y = limits.y / 2;\n\n const directions = {};\n directions.x = tool.x < mid.x ? -1 : 1;\n directions.y = tool.y < mid.y ? -1 : 1;\n\n const diffX = directions.x < 0 ? tool.x : limits.x - tool.x;\n const diffY = directions.y < 0 ? tool.y : limits.y - tool.y;\n let cornerAxis = diffY < diffX ? 'y' : 'x';\n\n const map = {\n 'x-1': 'L',\n 'y-1': 'T',\n x1: 'R',\n y1: 'B',\n };\n\n let current = 0;\n while (current < 4 && !allow[map[cornerAxis + directions[cornerAxis]]]) {\n // Invert the direction for the next iteration\n directions[cornerAxis] *= -1;\n\n // Invert the tempCornerAxis\n cornerAxis = cornerAxis === 'x' ? 'y' : 'x';\n\n current++;\n }\n\n return {\n directions,\n cornerAxis,\n };\n };\n\n const calculateAxisCenter = (axis, start, end) => {\n const a = start[axis];\n const b = end[axis];\n const lowest = Math.min(a, b);\n const highest = Math.max(a, b);\n return lowest + (highest - lowest) / 2;\n };\n\n const getTextBoxSizeInPixels = (element, bounds) => {\n const topLeft = cornerstone.pageToPixel(element, 0, 0);\n const bottomRight = cornerstone.pageToPixel(element, bounds.x, bounds.y);\n return {\n x: bottomRight.x - topLeft.x,\n y: bottomRight.y - topLeft.y,\n };\n };\n\n function getTextBoxOffset(config, cornerAxis, toolAxis, boxSize) {\n config = config || {};\n const centering = config.centering || {};\n const centerX = !!centering.x;\n const centerY = !!centering.y;\n const halfBoxSizeX = boxSize.x / 2;\n const halfBoxSizeY = boxSize.y / 2;\n const offset = {\n x: [],\n y: [],\n };\n\n if (cornerAxis === 'x') {\n const offsetY = centerY ? 0 : halfBoxSizeY;\n\n offset.x[-1] = centerX ? halfBoxSizeX : 0;\n offset.x[1] = centerX ? -halfBoxSizeX : -boxSize.x;\n offset.y[-1] = offsetY;\n offset.y[1] = offsetY;\n } else {\n const offsetX = centerX ? 0 : halfBoxSizeX;\n\n offset.x[-1] = offsetX;\n offset.x[1] = offsetX;\n offset.y[-1] = centerY ? halfBoxSizeY : 0;\n offset.y[1] = centerY ? -halfBoxSizeY : -boxSize.y;\n }\n\n return offset;\n }\n\n const handles = measurementData.handles;\n const textBox = handles.textBox;\n\n const $canvas = $(enabledElement.canvas);\n const canvasWidth = $canvas.outerWidth();\n const canvasHeight = $canvas.outerHeight();\n const offset = $canvas.offset();\n const canvasDimensions = {\n x: canvasWidth,\n y: canvasHeight,\n };\n\n const bounds = {};\n bounds.x = textBox.boundingBox.width;\n bounds.y = textBox.boundingBox.height;\n\n const getHandlePosition = key => {\n const { x, y } = handles[key];\n\n return { x, y };\n };\n const start = getHandlePosition('start');\n const end = getHandlePosition('end');\n\n const tool = {};\n tool.x = calculateAxisCenter('x', start, end);\n tool.y = calculateAxisCenter('y', start, end);\n\n let limits = {};\n limits.x = image.width;\n limits.y = image.height;\n\n let { directions, cornerAxis } = getRenderingInformation(limits, tool);\n\n const availableAreas = getAvailableBlankAreas(\n enabledElement,\n bounds.x,\n bounds.y\n );\n const tempDirections = Object.assign({}, directions);\n let tempCornerAxis = cornerAxis;\n let foundPlace = false;\n let current = 0;\n while (current < 4) {\n if (availableAreas[tempCornerAxis + tempDirections[tempCornerAxis]]) {\n foundPlace = true;\n break;\n }\n\n // Invert the direction for the next iteration\n tempDirections[tempCornerAxis] *= -1;\n\n // Invert the tempCornerAxis\n tempCornerAxis = tempCornerAxis === 'x' ? 'y' : 'x';\n\n current++;\n }\n\n let cornerAxisPosition;\n if (foundPlace) {\n directions = Object.assign({}, directions, tempDirections);\n cornerAxis = tempCornerAxis;\n cornerAxisPosition = directions[cornerAxis] < 0 ? 0 : limits[cornerAxis];\n } else {\n limits = Object.assign({}, limits, canvasDimensions);\n\n const toolPositionOnCanvas = cornerstone.pixelToCanvas(element, tool);\n const renderingInformation = getRenderingInformation(\n limits,\n toolPositionOnCanvas\n );\n directions = renderingInformation.directions;\n cornerAxis = renderingInformation.cornerAxis;\n\n const position = {\n x: directions.x < 0 ? offset.left : offset.left + canvasWidth,\n y: directions.y < 0 ? offset.top : offset.top + canvasHeight,\n };\n\n const pixelPosition = cornerstone.pageToPixel(\n element,\n position.x,\n position.y\n );\n cornerAxisPosition = pixelPosition[cornerAxis];\n }\n\n const toolAxis = cornerAxis === 'x' ? 'y' : 'x';\n const boxSize = getTextBoxSizeInPixels(element, bounds);\n\n textBox[cornerAxis] = cornerAxisPosition;\n textBox[toolAxis] = tool[toolAxis];\n\n // Adjust the text box position reducing its size from the corner axis\n const textBoxOffset = getTextBoxOffset(config, cornerAxis, toolAxis, boxSize);\n textBox[cornerAxis] += textBoxOffset[cornerAxis][directions[cornerAxis]];\n\n // Preventing the text box from partially going outside the canvas area\n const topLeft = cornerstone.pixelToCanvas(element, textBox);\n const bottomRight = {\n x: topLeft.x + bounds.x,\n y: topLeft.y + bounds.y,\n };\n const canvasBorders = {\n x0: offset.left,\n y0: offset.top,\n x1: offset.left + canvasWidth,\n y1: offset.top + canvasHeight,\n };\n if (topLeft[toolAxis] < 0) {\n const x = canvasBorders.x0;\n const y = canvasBorders.y0;\n const pixelPosition = cornerstone.pageToPixel(element, x, y);\n textBox[toolAxis] = pixelPosition[toolAxis];\n } else if (bottomRight[toolAxis] > canvasDimensions[toolAxis]) {\n const x = canvasBorders.x1 - bounds.x;\n const y = canvasBorders.y1 - bounds.y;\n const pixelPosition = cornerstone.pageToPixel(element, x, y);\n textBox[toolAxis] = pixelPosition[toolAxis];\n }\n}\n\nexport { getBoundingBox, pixelToPage, repositionTextBox };\n","import validate from 'validate.js';\n\nvalidate.validators.equals = function(value, options, key, attributes) {\n if (options && value !== options.value) {\n return key + 'must equal ' + options.value;\n }\n};\n\nvalidate.validators.doesNotEqual = function(value, options, key) {\n if (options && value === options.value) {\n return key + 'cannot equal ' + options.value;\n }\n};\n\nvalidate.validators.contains = function(value, options, key) {\n if (options && value.indexOf && value.indexOf(options.value) === -1) {\n return key + 'must contain ' + options.value;\n }\n};\n\nvalidate.validators.doesNotContain = function(value, options, key) {\n if (options && value.indexOf && value.indexOf(options.value) !== -1) {\n return key + 'cannot contain ' + options.value;\n }\n};\n\nvalidate.validators.startsWith = function(value, options, key) {\n if (options && value.startsWith && !value.startsWith(options.value)) {\n return key + 'must start with ' + options.value;\n }\n};\n\nvalidate.validators.endsWith = function(value, options, key) {\n if (options && value.endsWith && !value.endsWith(options.value)) {\n return key + 'must end with ' + options.value;\n }\n};\n\nexport { validate };\n","// Define an empty object to store callbacks that are used to retrieve custom attributes\n// The simplest example for a custom attribute is the Timepoint type (i.e. baseline or follow-up)\n// used in the LesionTracker application.\n//\n// Timepoint type can be obtained given a studyId, and this is done through a custom callback.\n// Developers can define attributes (i.e. attributeId = timepointType) with a name ('Timepoint Type')\n// and a callback function that is used to calculate them.\n//\n// The input to the callback, which is called during viewport-image matching rule evaluation\n// is the set of attributes that contains the specified attribute. In our example, timepointType is\n// linked to the study attributes, and so the inputs to the callback is an object containing\n// the study attributes.\nconst CustomAttributeRetrievalCallbacks = {};\n\n/**\n * Adds a custom attribute to be used in the HangingProtocol UI and matching rules, including a\n * callback that will be used to calculate the attribute value.\n *\n * @param attributeId The ID used to refer to the attribute (e.g. 'timepointType')\n * @param attributeName The name of the attribute to be displayed (e.g. 'Timepoint Type')\n * @param callback The function used to calculate the attribute value from the other attributes at its level (e.g. study/series/image)\n */\nfunction addCustomAttribute(attributeId, attributeName, callback) {\n CustomAttributeRetrievalCallbacks[attributeId] = {\n name: attributeName,\n callback: callback,\n };\n}\n\nexport { CustomAttributeRetrievalCallbacks, addCustomAttribute };\n","import OHIFError from '../classes/OHIFError.js';\nimport metadata from '../classes/metadata/';\nimport { validate } from './lib/validate.js';\nimport { CustomAttributeRetrievalCallbacks } from './customAttributes';\n\n/**\n * Import Constants\n */\nconst { InstanceMetadata } = metadata;\n\n/**\n * Match a Metadata instance against rules using Validate.js for validation.\n * @param {InstanceMetadata} metadataInstance Metadata instance object\n * @param {Array} rules Array of MatchingRules instances (StudyMatchingRule|SeriesMatchingRule|ImageMatchingRule) for the match\n * @return {Object} Matching Object with score and details (which rule passed or failed)\n */\nconst match = (metadataInstance, rules) => {\n // Make sure the supplied data is valid.\n if (!(metadataInstance instanceof InstanceMetadata)) {\n throw new OHIFError(\n 'HPMatcher::match metadataInstance must be an instance of InstanceMetadata'\n );\n }\n\n const options = {\n format: 'grouped',\n };\n\n const details = {\n passed: [],\n failed: [],\n };\n\n let requiredFailed = false;\n let score = 0;\n\n rules.forEach(rule => {\n const attribute = rule.attribute;\n\n // Do not use the custom attribute from the metadataInstance since it is subject to change\n if (CustomAttributeRetrievalCallbacks.hasOwnProperty(attribute)) {\n const customAttribute = CustomAttributeRetrievalCallbacks[attribute];\n metadataInstance.setCustomAttribute(\n attribute,\n customAttribute.callback(metadataInstance)\n );\n }\n\n // Format the constraint as required by Validate.js\n const testConstraint = {\n [attribute]: rule.constraint,\n };\n\n // Create a single attribute object to be validated, since metadataInstance is an\n // instance of Metadata (StudyMetadata, SeriesMetadata or InstanceMetadata)\n const attributeValue = metadataInstance.customAttributeExists(attribute)\n ? metadataInstance.getCustomAttribute(attribute)\n : metadataInstance.getTagValue(attribute);\n const attributeMap = {\n [attribute]: attributeValue,\n };\n\n // Use Validate.js to evaluate the constraints on the specified metadataInstance\n let errorMessages;\n try {\n errorMessages = validate(attributeMap, testConstraint, [options]);\n } catch (e) {\n errorMessages = ['Something went wrong during validation.', e];\n }\n\n if (!errorMessages) {\n // If no errorMessages were returned, then validation passed.\n\n // Add the rule's weight to the total score\n score += parseInt(rule.weight, 10);\n\n // Log that this rule passed in the matching details object\n details.passed.push({\n rule,\n });\n } else {\n // If errorMessages were present, then validation failed\n\n // If the rule that failed validation was Required, then\n // mark that a required Rule has failed\n if (rule.required) {\n requiredFailed = true;\n }\n\n // Log that this rule failed in the matching details object\n // and include any error messages\n details.failed.push({\n rule,\n errorMessages,\n });\n }\n });\n\n // If a required Rule has failed Validation, set the matching score to zero\n if (requiredFailed) {\n score = 0;\n }\n\n return {\n score,\n details,\n requiredFailed,\n };\n};\n\nconst HPMatcher = {\n match,\n};\n\nexport { HPMatcher };\n","// Define an empty object to store callbacks that are used to apply custom viewport settings\n// after a viewport is rendered.\nconst CustomViewportSettings = {};\n\n/**\n * Adds a custom setting that can be chosen in the HangingProtocol UI and applied to a Viewport\n *\n * @param settingId The ID used to refer to the setting (e.g. 'displayCADMarkers')\n * @param settingName The name of the setting to be displayed (e.g. 'Display CAD Markers')\n * @param options\n * @param callback A function to be run after a viewport is rendered with a series\n */\nfunction addCustomViewportSetting(settingId, settingName, options, callback) {\n CustomViewportSettings[settingId] = {\n id: settingId,\n text: settingName,\n options: options,\n callback: callback,\n };\n}\n\nexport { CustomViewportSettings, addCustomViewportSetting };\n","const comparators = [\n {\n id: 'equals',\n name: '= (Equals)',\n validator: 'equals',\n validatorOption: 'value',\n description: 'The attribute must equal this value.',\n },\n {\n id: 'doesNotEqual',\n name: '!= (Does not equal)',\n validator: 'doesNotEqual',\n validatorOption: 'value',\n description: 'The attribute must not equal this value.',\n },\n {\n id: 'contains',\n name: 'Contains',\n validator: 'contains',\n validatorOption: 'value',\n description: 'The attribute must contain this value.',\n },\n {\n id: 'doesNotContain',\n name: 'Does not contain',\n validator: 'doesNotContain',\n validatorOption: 'value',\n description: 'The attribute must not contain this value.',\n },\n {\n id: 'startsWith',\n name: 'Starts with',\n validator: 'startsWith',\n validatorOption: 'value',\n description: 'The attribute must start with this value.',\n },\n {\n id: 'endsWith',\n name: 'Ends with',\n validator: 'endsWith',\n validatorOption: 'value',\n description: 'The attribute must end with this value.',\n },\n {\n id: 'onlyInteger',\n name: 'Only Integers',\n validator: 'numericality',\n validatorOption: 'onlyInteger',\n description: \"Real numbers won't be allowed.\",\n },\n {\n id: 'greaterThan',\n name: '> (Greater than)',\n validator: 'numericality',\n validatorOption: 'greaterThan',\n description: 'The attribute has to be greater than this value.',\n },\n {\n id: 'greaterThanOrEqualTo',\n name: '>= (Greater than or equal to)',\n validator: 'numericality',\n validatorOption: 'greaterThanOrEqualTo',\n description: 'The attribute has to be at least this value.',\n },\n {\n id: 'lessThanOrEqualTo',\n name: '<= (Less than or equal to)',\n validator: 'numericality',\n validatorOption: 'lessThanOrEqualTo',\n description: 'The attribute can be this value at the most.',\n },\n {\n id: 'lessThan',\n name: '< (Less than)',\n validator: 'numericality',\n validatorOption: 'lessThan',\n description: 'The attribute has to be less than this value.',\n },\n {\n id: 'odd',\n name: 'Odd',\n validator: 'numericality',\n validatorOption: 'odd',\n description: 'The attribute has to be odd.',\n },\n {\n id: 'even',\n name: 'Even',\n validator: 'numericality',\n validatorOption: 'even',\n description: 'The attribute has to be even.',\n },\n];\n\n// Immutable object\nObject.freeze(comparators);\n\nexport { comparators };\n","import { comparators } from '../lib/comparators';\nimport guid from '../../utils/guid';\n\nconst EQUALS_REGEXP = /^equals$/;\n\n/**\n * This Class represents a Rule to be evaluated given a set of attributes\n * Rules have:\n * - An attribute (e.g. 'SeriesDescription')\n * - A constraint Object, in the form required by Validate.js:\n *\n * rule.constraint = {\n * contains: {\n * value: 'T-1'\n * }\n * };\n *\n * Note: In this example we use the 'contains' Validator, which is a custom Validator defined in Viewerbase\n *\n * - A value for whether or not they are Required to be matched (default: False)\n * - A value for their relative weighting during Protocol or Image matching (default: 1)\n */\nexport default class Rule {\n /**\n * The Constructor for the Class to create a Rule with the bare\n * minimum information\n *\n * @param name The desired name for the Rule\n */\n constructor(attribute, constraint, required, weight) {\n // Create a new UUID for this Rule\n this.id = guid();\n\n // Set the Rule's weight (defaults to 1)\n this.weight = weight || 1;\n\n // If an attribute is specified, assign it\n if (attribute) {\n this.attribute = attribute;\n }\n\n // If a constraint is specified, assign it\n if (constraint) {\n this.constraint = constraint;\n }\n\n // If a value for 'required' is specified, assign it\n if (required === undefined) {\n // If no value was specified, default to False\n this.required = false;\n } else {\n this.required = required;\n }\n\n // Cache for constraint info object\n this._constraintInfo = void 0;\n\n // Cache for validator and value object\n this._validatorAndValue = void 0;\n }\n\n /**\n * Occasionally the Rule class needs to be instantiated from a JavaScript Object.\n * This function fills in a Protocol with the Object data.\n *\n * @param input A Rule as a JavaScript Object, e.g. retrieved from JSON\n */\n fromObject(input) {\n // Check if the input already has an ID\n // If so, keep it. It not, create a new UUID\n this.id = input.id || guid();\n\n // Assign the specified input data to the Rule\n this.required = input.required;\n this.weight = input.weight;\n this.attribute = input.attribute;\n this.constraint = input.constraint;\n }\n\n /**\n * Get the constraint info object for the current constraint\n * @return {Object\\undefined} Constraint object or undefined if current constraint\n * is not valid or not found in comparators list\n */\n getConstraintInfo() {\n let constraintInfo = this._constraintInfo;\n // Check if info is cached already\n if (constraintInfo !== void 0) {\n return constraintInfo;\n }\n\n const ruleConstraint = Object.keys(this.constraint)[0];\n\n if (ruleConstraint !== void 0) {\n constraintInfo = comparators.find(\n comparator => ruleConstraint === comparator.id\n );\n }\n\n // Cache this information for later use\n this._constraintInfo = constraintInfo;\n\n return constraintInfo;\n }\n\n /**\n * Check if current rule is related to priors\n * @return {Boolean} True if a rule is related to priors or false otherwise\n */\n isRuleForPrior() {\n // @TODO: Should we check this too? this.attribute === 'relativeTime'\n return this.attribute === 'abstractPriorValue';\n }\n\n /**\n * If the current rule is a rule for priors, returns the number of referenced priors. Otherwise, returns -1.\n * @return {Number} The number of referenced priors or -1 if not applicable. Returns zero if the actual value could not be determined.\n */\n getNumberOfPriorsReferenced() {\n if (!this.isRuleForPrior()) {\n return -1;\n }\n\n // Get rule's validator and value\n const ruleValidatorAndValue = this.getConstraintValidatorAndValue();\n const { value, validator } = ruleValidatorAndValue;\n const intValue = parseInt(value, 10) || 0; // avoid possible NaN\n\n // \"Equal to\" validators\n if (EQUALS_REGEXP.test(validator)) {\n // In this case, -1 (the oldest prior) indicates that at least one study is used\n return intValue < 0 ? 1 : intValue;\n }\n\n // Default cases return value\n return 0;\n }\n\n /**\n * Get the constraint validator and value\n * @return {Object|undefined} Returns an object containing the validator and it's value or undefined\n */\n getConstraintValidatorAndValue() {\n let validatorAndValue = this._validatorAndValue;\n\n // Check if validator and value are cached already\n if (validatorAndValue !== void 0) {\n return validatorAndValue;\n }\n\n // Get the constraint info object\n const constraintInfo = this.getConstraintInfo();\n\n // Constraint info object exists and is valid\n if (constraintInfo !== void 0) {\n const validator = constraintInfo.validator;\n const currentValidator = this.constraint[validator];\n\n if (currentValidator) {\n const constraintValidator = constraintInfo.validatorOption;\n const constraintValue = currentValidator[constraintValidator];\n\n validatorAndValue = {\n value: constraintValue,\n validator: constraintInfo.id,\n };\n\n this._validatorAndValue = validatorAndValue;\n }\n }\n\n return validatorAndValue;\n }\n}\n","import Rule from './Rule';\n\n/**\n * The ProtocolMatchingRule Class extends the Rule Class.\n *\n * At present it does not add any new methods or attributes\n * @type {ProtocolMatchingRule}\n */\nclass ProtocolMatchingRule extends Rule {}\n\n/**\n * The StudyMatchingRule Class extends the Rule Class.\n *\n * At present it does not add any new methods or attributes\n * @type {StudyMatchingRule}\n */\nclass StudyMatchingRule extends Rule {}\n\n/**\n * The SeriesMatchingRule Class extends the Rule Class.\n *\n * At present it does not add any new methods or attributes\n * @type {SeriesMatchingRule}\n */\nclass SeriesMatchingRule extends Rule {}\n\n/**\n * The ImageMatchingRule class extends the Rule Class.\n *\n * At present it does not add any new methods or attributes\n * @type {ImageMatchingRule}\n */\nclass ImageMatchingRule extends Rule {}\n\nexport {\n ProtocolMatchingRule,\n StudyMatchingRule,\n SeriesMatchingRule,\n ImageMatchingRule,\n};\n","/**\n * Removes the first instance of an element from an array, if an equal value exists\n *\n * @param array\n * @param input\n *\n * @returns {boolean} Whether or not the element was found and removed\n */\nconst removeFromArray = (array, input) => {\n // If the array is empty, stop here\n if (!array || !array.length) {\n return false;\n }\n\n array.forEach((value, index) => {\n // TODO: Double check whether or not this deep equality check is necessary\n //if (_.isEqual(value, input)) {\n if (value === input) {\n indexToRemove = index;\n return false;\n }\n });\n\n if (indexToRemove === void 0) {\n return false;\n }\n\n array.splice(indexToRemove, 1);\n return true;\n};\n\nexport { removeFromArray };\n","/**\n * The ViewportStructure class represents the layout and layout properties that\n * Viewports are displayed in. ViewportStructure has a type, which corresponds to\n * a layout template, and a set of properties, which depend on the type.\n *\n * @type {ViewportStructure}\n */\nexport default class ViewportStructure {\n constructor(type, properties) {\n this.type = type;\n this.properties = properties;\n }\n\n /**\n * Occasionally the ViewportStructure class needs to be instantiated from a JavaScript Object.\n * This function fills in a ViewportStructure with the Object data.\n *\n * @param input The ViewportStructure as a JavaScript Object, e.g. retrieved from JSON\n */\n fromObject(input) {\n this.type = input.type;\n this.properties = input.properties;\n }\n\n /**\n * Retrieve the layout template name based on the layout type\n *\n * @returns {string}\n */\n getLayoutTemplateName() {\n // Viewport structure can be updated later when we build more complex display layouts\n switch (this.type) {\n case 'grid':\n return 'gridLayout';\n }\n }\n\n /**\n * Retrieve the number of Viewports required for this layout\n * given the layout type and properties\n *\n * @returns {string}\n */\n getNumViewports() {\n // Viewport structure can be updated later when we build more complex display layouts\n switch (this.type) {\n case 'grid':\n // For the typical grid layout, we only need to multiply Rows by Columns to\n // obtain the number of viewports\n return this.properties.Rows * this.properties.Columns;\n }\n }\n}\n","import {\n StudyMatchingRule,\n SeriesMatchingRule,\n ImageMatchingRule,\n} from './rules';\nimport { removeFromArray } from '../lib/removeFromArray';\n\n/**\n * This Class defines a Viewport in the Hanging Protocol Stage. A Viewport contains\n * arrays of Rules that are matched in the ProtocolEngine in order to determine which\n * images should be hung.\n *\n * @type {Viewport}\n */\nexport default class Viewport {\n constructor() {\n this.viewportSettings = {};\n this.imageMatchingRules = [];\n this.seriesMatchingRules = [];\n this.studyMatchingRules = [];\n }\n\n /**\n * Occasionally the Viewport class needs to be instantiated from a JavaScript Object.\n * This function fills in a Viewport with the Object data.\n *\n * @param input The Viewport as a JavaScript Object, e.g. retrieved from JSON\n */\n fromObject(input) {\n // If ImageMatchingRules exist, create them from the Object data\n // and add them to the Viewport's imageMatchingRules array\n if (input.imageMatchingRules) {\n input.imageMatchingRules.forEach(ruleObject => {\n var rule = new ImageMatchingRule();\n rule.fromObject(ruleObject);\n this.imageMatchingRules.push(rule);\n });\n }\n\n // If SeriesMatchingRules exist, create them from the Object data\n // and add them to the Viewport's seriesMatchingRules array\n if (input.seriesMatchingRules) {\n input.seriesMatchingRules.forEach(ruleObject => {\n var rule = new SeriesMatchingRule();\n rule.fromObject(ruleObject);\n this.seriesMatchingRules.push(rule);\n });\n }\n\n // If StudyMatchingRules exist, create them from the Object data\n // and add them to the Viewport's studyMatchingRules array\n if (input.studyMatchingRules) {\n input.studyMatchingRules.forEach(ruleObject => {\n var rule = new StudyMatchingRule();\n rule.fromObject(ruleObject);\n this.studyMatchingRules.push(rule);\n });\n }\n\n // If ViewportSettings exist, add them to the current protocol\n if (input.viewportSettings) {\n this.viewportSettings = input.viewportSettings;\n }\n }\n\n /**\n * Finds and removes a rule from whichever array it exists in.\n * It is not required to specify if it exists in studyMatchingRules,\n * seriesMatchingRules, or imageMatchingRules\n *\n * @param rule\n */\n removeRule(rule) {\n var array;\n if (rule instanceof StudyMatchingRule) {\n array = this.studyMatchingRules;\n } else if (rule instanceof SeriesMatchingRule) {\n array = this.seriesMatchingRules;\n } else if (rule instanceof ImageMatchingRule) {\n array = this.imageMatchingRules;\n }\n\n removeFromArray(array, rule);\n }\n}\n","import ViewportStructure from './ViewportStructure';\nimport Viewport from './Viewport';\nimport guid from '../../utils/guid';\n\n/**\n * A Stage is one step in the Display Set Sequence for a Hanging Protocol\n *\n * Stages are defined as a ViewportStructure and an array of Viewports\n *\n * @type {Stage}\n */\nexport default class Stage {\n constructor(ViewportStructure, name) {\n // Create a new UUID for this Stage\n this.id = guid();\n\n // Assign the name and ViewportStructure provided\n this.name = name;\n this.viewportStructure = ViewportStructure;\n\n // Create an empty array for the Viewports\n this.viewports = [];\n\n // Set the created date to Now\n this.createdDate = new Date();\n }\n\n /**\n * Creates a clone of the current Stage with a new name\n *\n * @param name\n * @returns {Stage|*}\n */\n createClone(name) {\n // Create a new JavaScript independent of the current Protocol\n var currentStage = Object.assign({}, this);\n\n // Create a new Stage to return\n var clonedStage = new Stage();\n\n // Assign the desired properties\n currentStage.id = clonedStage.id;\n clonedStage.fromObject(currentStage);\n\n // If we have specified a name, assign it\n if (name) {\n clonedStage.name = name;\n }\n\n // Return the cloned Stage\n return clonedStage;\n }\n\n /**\n * Occasionally the Stage class needs to be instantiated from a JavaScript Object.\n * This function fills in a Protocol with the Object data.\n *\n * @param input A Stage as a JavaScript Object, e.g. retrieved from JSON\n */\n fromObject(input) {\n // Check if the input already has an ID\n // If so, keep it. It not, create a new UUID\n this.id = input.id || guid();\n\n // Assign the input name to the Stage\n this.name = input.name;\n\n // If a ViewportStructure is present in the input, add it from the\n // input data\n this.viewportStructure = new ViewportStructure();\n this.viewportStructure.fromObject(input.viewportStructure);\n\n // If any viewports are present in the input object\n if (input.viewports) {\n input.viewports.forEach(viewportObject => {\n // Create a new Viewport with their data\n var viewport = new Viewport();\n viewport.fromObject(viewportObject);\n\n // Add it to the viewports array\n this.viewports.push(viewport);\n });\n }\n }\n}\n","import { ProtocolMatchingRule } from './rules';\nimport { removeFromArray } from '../lib/removeFromArray';\nimport Stage from './Stage';\nimport guid from '../../utils/guid';\nimport user from '../../user';\n\n/**\n * This class represents a Hanging Protocol at the highest level\n *\n * @type {Protocol}\n */\nexport default class Protocol {\n /**\n * The Constructor for the Class to create a Protocol with the bare\n * minimum information\n *\n * @param name The desired name for the Protocol\n */\n constructor(name) {\n // Create a new UUID for this Protocol\n this.id = guid();\n\n // Store a value which determines whether or not a Protocol is locked\n // This is probably temporary, since we will eventually have role / user\n // checks for editing. For now we just need it to prevent changes to the\n // default protocols.\n this.locked = false;\n\n // Boolean value to indicate if the protocol has updated priors information\n // it's set in \"updateNumberOfPriorsReferenced\" function\n this.hasUpdatedPriorsInformation = false;\n\n // Apply the desired name\n this.name = name;\n\n // Set the created and modified dates to Now\n this.createdDate = new Date();\n this.modifiedDate = new Date();\n\n // If we are logged in while creating this Protocol,\n // store this information as well\n if (user.userLoggedIn && user.userLoggedIn()) {\n this.createdBy = user.getUserId();\n this.modifiedBy = user.getUserId();\n }\n\n // Create two empty Sets specifying which roles\n // have read and write access to this Protocol\n this.availableTo = new Set();\n this.editableBy = new Set();\n\n // Define empty arrays for the Protocol matching rules\n // and Stages\n this.protocolMatchingRules = [];\n this.stages = [];\n\n // Define auxiliary values for priors\n this.numberOfPriorsReferenced = -1;\n }\n\n getNumberOfPriorsReferenced(skipCache = false) {\n let numberOfPriorsReferenced =\n skipCache !== true ? this.numberOfPriorsReferenced : -1;\n\n // Check if information is cached already\n if (numberOfPriorsReferenced > -1) {\n return numberOfPriorsReferenced;\n }\n\n numberOfPriorsReferenced = 0;\n\n // Search each study matching rule for prior rules\n // Each stage can have many viewports that can have\n // multiple study matching rules.\n this.stages.forEach(stage => {\n if (!stage.viewports) {\n return;\n }\n\n stage.viewports.forEach(viewport => {\n if (!viewport.studyMatchingRules) {\n return;\n }\n\n viewport.studyMatchingRules.forEach(rule => {\n // If the current rule is not a priors rule, it will return -1 then numberOfPriorsReferenced will continue to be 0\n const priorsReferenced = rule.getNumberOfPriorsReferenced();\n if (priorsReferenced > numberOfPriorsReferenced) {\n numberOfPriorsReferenced = priorsReferenced;\n }\n });\n });\n });\n\n this.numberOfPriorsReferenced = numberOfPriorsReferenced;\n\n return numberOfPriorsReferenced;\n }\n\n updateNumberOfPriorsReferenced() {\n this.getNumberOfPriorsReferenced(true);\n }\n\n /**\n * Method to update the modifiedDate when the Protocol\n * has been changed\n */\n protocolWasModified() {\n // If we are logged in while modifying this Protocol,\n // store this information as well\n if (user.userLoggedIn && user.userLoggedIn()) {\n this.modifiedBy = user.getUserId();\n }\n\n // Protocol has been modified, so mark priors information\n // as \"outdated\"\n this.hasUpdatedPriorsInformation = false;\n\n // Update number of priors referenced info\n this.updateNumberOfPriorsReferenced();\n\n // Update the modifiedDate with the current Date/Time\n this.modifiedDate = new Date();\n }\n\n /**\n * Occasionally the Protocol class needs to be instantiated from a JavaScript Object\n * containing the Protocol data. This function fills in a Protocol with the Object\n * data.\n *\n * @param input A Protocol as a JavaScript Object, e.g. retrieved from JSON\n */\n fromObject(input) {\n // Check if the input already has an ID\n // If so, keep it. It not, create a new UUID\n this.id = input.id || guid();\n\n // Assign the input name to the Protocol\n this.name = input.name;\n\n // Retrieve locked status, use !! to make it truthy\n // so that undefined values will be set to false\n this.locked = !!input.locked;\n\n // TODO: Check how to regenerate Set from Object\n //this.availableTo = new Set(input.availableTo);\n //this.editableBy = new Set(input.editableBy);\n\n // If the input contains Protocol matching rules\n if (input.protocolMatchingRules) {\n input.protocolMatchingRules.forEach(ruleObject => {\n // Create new Rules from the stored data\n var rule = new ProtocolMatchingRule();\n rule.fromObject(ruleObject);\n\n // Add them to the Protocol\n this.protocolMatchingRules.push(rule);\n });\n }\n\n // If the input contains data for various Stages in the\n // display set sequence\n if (input.stages) {\n input.stages.forEach(stageObject => {\n // Create Stages from the stored data\n var stage = new Stage();\n stage.fromObject(stageObject);\n\n // Add them to the Protocol\n this.stages.push(stage);\n });\n }\n }\n\n /**\n * Creates a clone of the current Protocol with a new name\n *\n * @param name\n * @returns {Protocol|*}\n */\n createClone(name) {\n // Create a new JavaScript independent of the current Protocol\n var currentProtocol = Object.assign({}, this);\n\n // Create a new Protocol to return\n var clonedProtocol = new Protocol();\n\n // Apply the desired properties\n currentProtocol.id = clonedProtocol.id;\n clonedProtocol.fromObject(currentProtocol);\n\n // If we have specified a name, assign it\n if (name) {\n clonedProtocol.name = name;\n }\n\n // Unlock the clone\n clonedProtocol.locked = false;\n\n // Return the cloned Protocol\n return clonedProtocol;\n }\n\n /**\n * Adds a Stage to this Protocol's display set sequence\n *\n * @param stage\n */\n addStage(stage) {\n this.stages.push(stage);\n\n // Update the modifiedDate and User that last\n // modified this Protocol\n this.protocolWasModified();\n }\n\n /**\n * Adds a Rule to this Protocol's array of matching rules\n *\n * @param rule\n */\n addProtocolMatchingRule(rule) {\n this.protocolMatchingRules.push(rule);\n\n // Update the modifiedDate and User that last\n // modified this Protocol\n this.protocolWasModified();\n }\n\n /**\n * Removes a Rule from this Protocol's array of matching rules\n *\n * @param rule\n */\n removeProtocolMatchingRule(rule) {\n var wasRemoved = removeFromArray(this.protocolMatchingRules, rule);\n\n // Update the modifiedDate and User that last\n // modified this Protocol\n if (wasRemoved) {\n this.protocolWasModified();\n }\n }\n}\n","import OHIFError from '../classes/OHIFError.js';\nimport metadata from '../classes/metadata/';\nimport { StudyMetadataSource } from '../classes/StudyMetadataSource.js';\nimport { isImage } from '../utils/isImage.js';\nimport { HPMatcher } from './HPMatcher.js';\nimport { sortByScore } from './lib/sortByScore';\nimport log from '../log.js';\nimport sortBy from '../utils/sortBy.js';\nimport { CustomViewportSettings } from './customViewportSettings';\nimport Protocol from './classes/Protocol';\nimport { ProtocolStore } from './protocolStore/classes';\n\n/**\n * Import Constants\n */\nconst { StudyMetadata, InstanceMetadata } = metadata;\n\n// Useful constants\nconst ABSTRACT_PRIOR_VALUE = 'abstractPriorValue';\n\nexport default class ProtocolEngine {\n matchedProtocols = new Map();\n matchedProtocolScores = {};\n\n /**\n * Constructor\n * @param {ProtocolStore} protocolStore Protocol Store used to keep track of all hanging protocols\n * @param {Array} studies Array of study metadata\n * @param {Map} priorStudies Map of prior studies\n * @param {Object} studyMetadataSource Instance of StudyMetadataSource (ohif-viewerbase) Object to get study metadata\n * @param {Object} options\n */\n constructor(\n protocolStore,\n studies,\n priorStudies,\n studyMetadataSource,\n options = {}\n ) {\n // -----------\n // Type Validations\n if (!(studyMetadataSource instanceof StudyMetadataSource)) {\n throw new OHIFError(\n 'ProtocolEngine::constructor studyMetadataSource is not an instance of StudyMetadataSource'\n );\n }\n\n if (\n !(studies instanceof Array) &&\n !studies.every(study => study instanceof StudyMetadata)\n ) {\n throw new OHIFError(\n \"ProtocolEngine::constructor studies is not an array or it's items are not instances of StudyMetadata\"\n );\n }\n\n // --------------\n // Initialization\n this.protocolStore = protocolStore;\n this.studies = studies;\n this.priorStudies = priorStudies instanceof Map ? priorStudies : new Map();\n this.studyMetadataSource = studyMetadataSource;\n this.options = options;\n\n // Put protocol engine in a known state\n this.reset();\n\n // Create an array for new stage ids to be stored\n // while editing a stage\n this.newStageIds = [];\n }\n\n /**\n * Resets the ProtocolEngine to the best match\n */\n reset() {\n const protocol = this.getBestProtocolMatch();\n\n this.setHangingProtocol(protocol);\n }\n\n /**\n * Retrieves the current Stage from the current Protocol and stage index\n *\n * @returns {*} The Stage model for the currently displayed Stage\n */\n getCurrentStageModel() {\n return this.protocol.stages[this.stage];\n }\n\n /**\n * Finds the best protocols from Protocol Store, matching each protocol matching rules\n * with the given study. The best protocol are orded by score and returned in an array\n * @param {Object} study StudyMetadata instance object\n * @return {Array} Array of match objects or an empty array if no match was found\n * Each match object has the score of the matching and the matched\n * protocol\n */\n findMatchByStudy(study) {\n log.trace('ProtocolEngine::findMatchByStudy');\n\n const matched = [];\n const studyInstance = study.getFirstInstance();\n\n // Set custom attribute for study metadata\n const numberOfAvailablePriors = this.getNumberOfAvailablePriors(\n study.getObjectID()\n );\n\n this.protocolStore.getProtocol().forEach(protocol => {\n // Clone the protocol's protocolMatchingRules array\n // We clone it so that we don't accidentally add the\n // numberOfPriorsReferenced rule to the Protocol itself.\n let rules = protocol.protocolMatchingRules.slice();\n if (!rules) {\n return;\n }\n\n // Check if the study has the minimun number of priors used by the protocol.\n const numberOfPriorsReferenced = protocol.getNumberOfPriorsReferenced();\n if (numberOfPriorsReferenced > numberOfAvailablePriors) {\n return;\n }\n\n // Run the matcher and get matching details\n const matchedDetails = HPMatcher.match(studyInstance, rules);\n const score = matchedDetails.score;\n\n // The protocol matched some rule, add it to the matched list\n if (score > 0) {\n matched.push({\n score,\n protocol,\n });\n }\n });\n\n // If no matches were found, select the default protocol\n if (!matched.length) {\n const defaultProtocol = this.protocolStore.getProtocol('defaultProtocol');\n\n return [\n {\n score: 1,\n protocol: defaultProtocol,\n },\n ];\n }\n\n // Sort the matched list by score\n sortByScore(matched);\n\n log.trace('ProtocolEngine::findMatchByStudy matched', matched);\n\n return matched;\n }\n\n _clearMatchedProtocols() {\n this.matchedProtocols.clear();\n this.matchedProtocolScores = {};\n }\n /**\n * Populates the MatchedProtocols Collection by running the matching procedure\n */\n updateProtocolMatches() {\n log.trace('ProtocolEngine::updateProtocolMatches');\n\n // Clear all data currently in matchedProtocols\n this._clearMatchedProtocols();\n\n // For each study, find the matching protocols\n this.studies.forEach(study => {\n const matched = this.findMatchByStudy(study);\n\n // For each matched protocol, check if it is already in MatchedProtocols\n matched.forEach(matchedDetail => {\n const protocol = matchedDetail.protocol;\n if (!protocol) {\n return;\n }\n\n // If it is not already in the MatchedProtocols Collection, insert it with its score\n if (!this.matchedProtocols.has(protocol.id)) {\n log.trace(\n 'ProtocolEngine::updateProtocolMatches inserting protocol match',\n matchedDetail\n );\n this.matchedProtocols.set(protocol.id, protocol);\n this.matchedProtocolScores[protocol.id] = matchedDetail.score;\n }\n });\n });\n }\n\n _largestKeyByValue(obj) {\n return Object.keys(obj).reduce((a, b) => (obj[a] > obj[b] ? a : b));\n }\n\n _getHighestScoringProtocol() {\n if (!Object.keys(this.matchedProtocolScores).length) {\n return this.protocolStore.getProtocol('defaultProtocol');\n }\n const highestScoringProtocolId = this._largestKeyByValue(\n this.matchedProtocolScores\n );\n return this.matchedProtocols.get(highestScoringProtocolId);\n }\n\n /**\n * Return the best matched Protocol to the current study or set of studies\n * @returns {*}\n */\n getBestProtocolMatch() {\n // Run the matching to populate matchedProtocols Set and Map\n this.updateProtocolMatches();\n\n // Retrieve the highest scoring Protocol\n const bestMatch = this._getHighestScoringProtocol();\n\n log.trace('ProtocolEngine::getBestProtocolMatch bestMatch', bestMatch);\n\n return bestMatch;\n }\n\n /**\n * Get the number of prior studies supplied in the priorStudies map property.\n *\n * @param {String} studyObjectID The study object ID of the study whose priors are needed\n * @returns {number} The number of available prior studies with the same PatientID\n */\n getNumberOfAvailablePriors(studyObjectID) {\n return this.getAvailableStudyPriors(studyObjectID).length;\n }\n\n /**\n * Get the array of prior studies from a specific study.\n *\n * @param {String} studyObjectID The study object ID of the study whose priors are needed\n * @returns {Array} The array of available priors or an empty array\n */\n getAvailableStudyPriors(studyObjectID) {\n const priors = this.priorStudies.get(studyObjectID);\n\n return priors instanceof Array ? priors : [];\n }\n\n // Match images given a list of Studies and a Viewport's image matching reqs\n matchImages(viewport, viewportIndex) {\n log.trace('ProtocolEngine::matchImages');\n\n const {\n studyMatchingRules,\n seriesMatchingRules,\n imageMatchingRules: instanceMatchingRules,\n } = viewport;\n\n const matchingScores = [];\n const currentStudy = this.studies[0]; // @TODO: Should this be: this.studies[this.currentStudy] ???\n const firstInstance = currentStudy.getFirstInstance();\n\n let highestStudyMatchingScore = 0;\n let highestSeriesMatchingScore = 0;\n\n // Set custom attribute for study metadata and it's first instance\n currentStudy.setCustomAttribute(ABSTRACT_PRIOR_VALUE, 0);\n if (firstInstance instanceof InstanceMetadata) {\n firstInstance.setCustomAttribute(ABSTRACT_PRIOR_VALUE, 0);\n }\n\n // Only used if study matching rules has abstract prior values defined...\n let priorStudies;\n\n studyMatchingRules.forEach(rule => {\n if (rule.attribute === ABSTRACT_PRIOR_VALUE) {\n const validatorType = Object.keys(rule.constraint)[0];\n const validator = Object.keys(rule.constraint[validatorType])[0];\n\n let abstractPriorValue = rule.constraint[validatorType][validator];\n abstractPriorValue = parseInt(abstractPriorValue, 10);\n // TODO: Restrict or clarify validators for abstractPriorValue?\n\n // No need to call it more than once...\n if (!priorStudies) {\n priorStudies = this.getAvailableStudyPriors(\n currentStudy.getObjectID()\n );\n }\n\n // TODO: Revisit this later: What about two studies with the same\n // study date?\n\n let priorStudy;\n if (abstractPriorValue === -1) {\n priorStudy = priorStudies[priorStudies.length - 1];\n } else {\n const studyIndex = Math.max(abstractPriorValue - 1, 0);\n priorStudy = priorStudies[studyIndex];\n }\n\n // Invalid data\n if (!priorStudy instanceof StudyMetadata) {\n return;\n }\n\n const priorStudyObjectID = priorStudy.getObjectID();\n\n // Check if study metadata is already in studies list\n if (\n this.studies.find(study => study.getObjectID() === priorStudyObjectID)\n ) {\n return;\n }\n\n // Get study metadata if necessary and load study in the viewer (each viewer should provide it's own load study method)\n this.studyMetadataSource.loadStudy(priorStudy).then(\n studyMetadata => {\n // Set the custom attribute abstractPriorValue for the study metadata\n studyMetadata.setCustomAttribute(\n ABSTRACT_PRIOR_VALUE,\n abstractPriorValue\n );\n\n // Also add custom attribute\n const firstInstance = studyMetadata.getFirstInstance();\n if (firstInstance instanceof InstanceMetadata) {\n firstInstance.setCustomAttribute(\n ABSTRACT_PRIOR_VALUE,\n abstractPriorValue\n );\n }\n\n // Insert the new study metadata\n this.studies.push(studyMetadata);\n\n // Update the viewport to refresh layout manager with new study\n this.updateViewports(viewportIndex);\n },\n error => {\n log.warn(error);\n throw new OHIFError(\n `ProtocolEngine::matchImages could not get study metadata for the Study with the following ObjectID: ${priorStudyObjectID}`\n );\n }\n );\n }\n // TODO: Add relative Date / time\n });\n\n this.studies.forEach(study => {\n const studyMatchDetails = HPMatcher.match(\n study.getFirstInstance(),\n studyMatchingRules\n );\n\n // Prevent bestMatch from being updated if the matchDetails' required attribute check has failed\n if (\n studyMatchDetails.requiredFailed === true ||\n studyMatchDetails.score < highestStudyMatchingScore\n ) {\n return;\n }\n\n highestStudyMatchingScore = studyMatchDetails.score;\n\n study.forEachSeries(series => {\n const seriesMatchDetails = HPMatcher.match(\n series.getFirstInstance(),\n seriesMatchingRules\n );\n\n // Prevent bestMatch from being updated if the matchDetails' required attribute check has failed\n if (\n seriesMatchDetails.requiredFailed === true ||\n seriesMatchDetails.score < highestSeriesMatchingScore\n ) {\n return;\n }\n\n highestSeriesMatchingScore = seriesMatchDetails.score;\n\n series.forEachInstance((instance, index) => {\n // This tests to make sure there is actually image data in this instance\n // TODO: Change this when we add PDF and MPEG support\n // See https://ohiforg.atlassian.net/browse/LT-227\n if (\n !isImage(instance.getTagValue('SOPClassUID')) &&\n !instance.getTagValue('Rows')\n ) {\n return;\n }\n\n const instanceMatchDetails = HPMatcher.match(\n instance,\n instanceMatchingRules\n );\n\n // Prevent bestMatch from being updated if the matchDetails' required attribute check has failed\n if (instanceMatchDetails.requiredFailed === true) {\n return;\n }\n\n const matchDetails = {\n passed: [],\n failed: [],\n };\n\n matchDetails.passed = matchDetails.passed.concat(\n instanceMatchDetails.details.passed\n );\n matchDetails.passed = matchDetails.passed.concat(\n seriesMatchDetails.details.passed\n );\n matchDetails.passed = matchDetails.passed.concat(\n studyMatchDetails.details.passed\n );\n\n matchDetails.failed = matchDetails.failed.concat(\n instanceMatchDetails.details.failed\n );\n matchDetails.failed = matchDetails.failed.concat(\n seriesMatchDetails.details.failed\n );\n matchDetails.failed = matchDetails.failed.concat(\n studyMatchDetails.details.failed\n );\n\n const totalMatchScore =\n instanceMatchDetails.score +\n seriesMatchDetails.score +\n studyMatchDetails.score;\n const currentSOPInstanceUID = instance.getSOPInstanceUID();\n\n const imageDetails = {\n StudyInstanceUID: study.getStudyInstanceUID(),\n SeriesInstanceUID: series.getSeriesInstanceUID(),\n SOPInstanceUID: currentSOPInstanceUID,\n currentImageIdIndex: index,\n matchingScore: totalMatchScore,\n matchDetails: matchDetails,\n sortingInfo: {\n score: totalMatchScore,\n study:\n instance.getTagValue('StudyDate') +\n instance.getTagValue('StudyTime'),\n series: parseInt(instance.getTagValue('SeriesNumber')), // TODO: change for seriesDateTime\n instance: parseInt(instance.getTagValue('InstanceNumber')), // TODO: change for acquisitionTime\n },\n };\n\n // Find the displaySet\n const displaySet = study.findDisplaySet(displaySet =>\n displaySet.images.find(\n image => image.getSOPInstanceUID() === currentSOPInstanceUID\n )\n );\n\n // If the instance was found, set the displaySet ID\n if (displaySet) {\n imageDetails.displaySetInstanceUID = displaySet.getUID();\n imageDetails.imageId = instance.getImageId();\n }\n\n matchingScores.push(imageDetails);\n });\n });\n });\n\n // Sort the matchingScores\n const sortingFunction = sortBy(\n {\n name: 'score',\n reverse: true,\n },\n {\n name: 'study',\n reverse: true,\n },\n {\n name: 'instance',\n },\n {\n name: 'series',\n }\n );\n matchingScores.sort((a, b) =>\n sortingFunction(a.sortingInfo, b.sortingInfo)\n );\n\n const bestMatch = matchingScores[0];\n\n log.trace('ProtocolEngine::matchImages bestMatch', bestMatch);\n\n return {\n bestMatch,\n matchingScores,\n };\n }\n\n /**\n * Sets the current layout\n *\n * @param {number} numRows\n * @param {number} numColumns\n */\n setLayout(numRows, numColumns) {\n if (numRows < 1 && numColumns < 1) {\n log.error(`Invalid layout ${numRows} x ${numColumns}`);\n return;\n }\n\n if (typeof this.options.setLayout !== 'function') {\n log.error('Hanging Protocol Engine setLayout callback is not defined');\n return;\n }\n\n let viewports = [];\n const numViewports = numRows * numColumns;\n\n for (let i = 0; i < numViewports; i++) {\n viewports.push({});\n }\n\n this.options.setLayout({ numRows, numColumns, viewports });\n }\n\n /**\n * Rerenders viewports that are part of the current layout manager\n * using the matching rules internal to each viewport.\n *\n * If this function is provided the index of a viewport, only the specified viewport\n * is rerendered.\n *\n * @param viewportIndex\n */\n updateViewports(viewportIndex) {\n log.trace(\n `ProtocolEngine::updateViewports viewportIndex: ${viewportIndex}`\n );\n\n // Make sure we have an active protocol with a non-empty array of display sets\n if (!this.getNumProtocolStages()) {\n return;\n }\n\n // Retrieve the current stage\n const stageModel = this.getCurrentStageModel();\n\n // If the current stage does not fulfill the requirements to be displayed,\n // stop here.\n if (\n !stageModel ||\n !stageModel.viewportStructure ||\n !stageModel.viewports ||\n !stageModel.viewports.length\n ) {\n return;\n }\n\n // Retrieve the layoutTemplate associated with the current display set's viewport structure\n // If no such template name exists, stop here.\n const layoutTemplateName = stageModel.viewportStructure.getLayoutTemplateName();\n if (!layoutTemplateName) {\n return;\n }\n\n // Retrieve the properties associated with the current display set's viewport structure template\n // If no such layout properties exist, stop here.\n const layoutProps = stageModel.viewportStructure.properties;\n if (!layoutProps) {\n return;\n }\n\n // Create an empty array to store the output viewportData\n const viewportData = [];\n\n // Empty the matchDetails associated with the ProtocolEngine.\n // This will be used to store the pass/fail details and score\n // for each of the viewport matching procedures\n this.matchDetails = [];\n\n // Loop through each viewport\n stageModel.viewports.forEach((viewport, viewportIndex) => {\n const details = this.matchImages(viewport, viewportIndex);\n\n this.matchDetails[viewportIndex] = details;\n\n // Convert any YES/NO values into true/false for Cornerstone\n const cornerstoneViewportParams = {};\n\n // Cache viewportSettings keys\n const viewportSettingsKeys = Object.keys(viewport.viewportSettings);\n\n viewportSettingsKeys.forEach(key => {\n let value = viewport.viewportSettings[key];\n if (value === 'YES') {\n value = true;\n } else if (value === 'NO') {\n value = false;\n }\n\n cornerstoneViewportParams[key] = value;\n });\n\n // imageViewerViewports occasionally needs relevant layout data in order to set\n // the element style of the viewport in question\n const currentViewportData = {\n viewportIndex,\n viewport: cornerstoneViewportParams,\n ...layoutProps,\n };\n\n const customSettings = [];\n viewportSettingsKeys.forEach(id => {\n const setting = CustomViewportSettings[id];\n if (!setting) {\n return;\n }\n\n customSettings.push({\n id: id,\n value: viewport.viewportSettings[id],\n });\n });\n\n currentViewportData.renderedCallback = element => {\n //console.log('renderedCallback for ' + element.id);\n customSettings.forEach(customSetting => {\n log.trace(\n `ProtocolEngine::currentViewportData.renderedCallback Applying custom setting: ${customSetting.id}`\n );\n log.trace(\n `ProtocolEngine::currentViewportData.renderedCallback with value: ${customSetting.value}`\n );\n\n const setting = CustomViewportSettings[customSetting.id];\n setting.callback(element, customSetting.value);\n });\n };\n\n let currentMatch = details.bestMatch;\n let currentPosition = 1;\n const scoresLength = details.matchingScores.length;\n while (\n currentPosition < scoresLength &&\n viewportData.find(a => a.imageId === currentMatch.imageId)\n ) {\n currentMatch = details.matchingScores[currentPosition];\n currentPosition++;\n }\n\n if (currentMatch && currentMatch.imageId) {\n currentViewportData.StudyInstanceUID = currentMatch.StudyInstanceUID;\n currentViewportData.SeriesInstanceUID = currentMatch.SeriesInstanceUID;\n currentViewportData.SOPInstanceUID = currentMatch.SOPInstanceUID;\n currentViewportData.currentImageIdIndex =\n currentMatch.currentImageIdIndex;\n currentViewportData.displaySetInstanceUID =\n currentMatch.displaySetInstanceUID;\n currentViewportData.imageId = currentMatch.imageId;\n }\n\n // @TODO Why should we throw an exception when a best match is not found? This was aborting the whole process.\n // if (!currentViewportData.displaySetInstanceUID) {\n // throw new OHIFError('ProtocolEngine::updateViewports No matching display set found?');\n // }\n\n viewportData.push(currentViewportData);\n });\n\n this.setLayout(layoutProps.Rows, layoutProps.Columns);\n\n if (typeof this.options.setViewportSpecificData !== 'function') {\n log.error(\n 'Hanging Protocol Engine setViewportSpecificData callback is not defined'\n );\n return;\n }\n\n // If viewportIndex is defined, then update only that viewport\n if (viewportIndex !== undefined && viewportData[viewportIndex]) {\n this.options.setViewportSpecificData(\n viewportIndex,\n viewportData[viewportIndex]\n );\n return;\n }\n\n // Update all viewports\n viewportData.forEach(viewportSpecificData => {\n this.options.setViewportSpecificData(\n viewportSpecificData.viewportIndex,\n viewportSpecificData\n );\n });\n }\n\n /**\n * Sets the current Hanging Protocol to the specified Protocol\n * An optional argument can also be used to prevent the updating of the Viewports\n *\n * @param newProtocol\n * @param updateViewports\n */\n setHangingProtocol(newProtocol, updateViewports = true) {\n log.trace('ProtocolEngine::setHangingProtocol newProtocol', newProtocol);\n log.trace(\n `ProtocolEngine::setHangingProtocol updateViewports = ${updateViewports}`\n );\n\n // Reset the array of newStageIds\n this.newStageIds = [];\n\n if (Protocol.prototype.isPrototypeOf(newProtocol)) {\n this.protocol = newProtocol;\n } else {\n this.protocol = new Protocol();\n this.protocol.fromObject(newProtocol);\n }\n\n this.stage = 0;\n\n // Update viewports by default\n if (updateViewports) {\n this.updateViewports();\n }\n }\n\n /**\n * Check if the next stage is available\n * @return {Boolean} True if next stage is available or false otherwise\n */\n isNextStageAvailable() {\n const numberOfStages = this.getNumProtocolStages();\n\n return this.stage + 1 < numberOfStages;\n }\n\n /**\n * Check if the previous stage is available\n * @return {Boolean} True if previous stage is available or false otherwise\n */\n isPreviousStageAvailable() {\n return this.stage - 1 >= 0;\n }\n\n /**\n * Changes the current stage to a new stage index in the display set sequence.\n * It checks if the next stage exists.\n *\n * @param {Integer} stageAction An integer value specifying wheater next (1) or previous (-1) stage\n * @return {Boolean} True if new stage has set or false, otherwise\n */\n setCurrentProtocolStage(stageAction) {\n // Check if previous or next stage is available\n if (stageAction === -1 && !this.isPreviousStageAvailable()) {\n return false;\n } else if (stageAction === 1 && !this.isNextStageAvailable()) {\n return false;\n }\n\n // Sets the new stage\n this.stage += stageAction;\n\n // Log the new stage\n log.trace(`ProtocolEngine::setCurrentProtocolStage stage = ${this.stage}`);\n\n // Since stage has changed, we need to update the viewports\n // and redo matchings\n this.updateViewports();\n\n // Everything went well\n return true;\n }\n\n /**\n * Retrieves the number of Stages in the current Protocol or\n * undefined if no protocol or stages are set\n */\n getNumProtocolStages() {\n if (\n !this.protocol ||\n !this.protocol.stages ||\n !this.protocol.stages.length\n ) {\n return;\n }\n\n return this.protocol.stages.length;\n }\n\n /**\n * Switches to the next protocol stage in the display set sequence\n */\n nextProtocolStage() {\n log.trace('ProtocolEngine::nextProtocolStage');\n\n if (!this.setCurrentProtocolStage(1)) {\n log.trace('ProtocolEngine::nextProtocolStage failed');\n }\n }\n\n /**\n * Switches to the previous protocol stage in the display set sequence\n */\n previousProtocolStage() {\n log.trace('ProtocolEngine::previousProtocolStage');\n\n if (!this.setCurrentProtocolStage(-1)) {\n log.trace('ProtocolEngine::previousProtocolStage failed');\n }\n }\n}\n","// Sorts an array by score\nconst sortByScore = arr => {\n arr.sort((a, b) => {\n return b.score - a.score;\n });\n};\n\nexport { sortByScore };\n","import Protocol from '../../classes/Protocol';\n\n// The ProtocolStore class allows persisting hanging protocols using different strategies.\n// For example, one strategy stores hanging protocols in the application server while\n// another strategy stores them in a remote machine, but only one strategy can be used at a time.\n\nexport default class ProtocolStore {\n constructor(strategy) {\n this.strategy = strategy;\n }\n\n /**\n * Get a Protocol instance or array of Protocol instances for the given protocol object or array\n * @param {Object|array} protocolObject Protocol plain object or array of Protocol plain objects\n * @return {Protocol|array} Protocol instance or array of Protocol intances for the given protocol object or array\n */\n static getProtocolInstance(protocolObject) {\n let result = protocolObject;\n\n // If result is an array of protocols objects\n if (result instanceof Array) {\n result.forEach((protocol, index) => {\n // Check if protocol is an instance of Protocol\n if (!(protocol instanceof Protocol)) {\n const protocolInstance = new Protocol();\n protocolInstance.fromObject(protocol);\n result[index] = protocolInstance;\n }\n });\n } else if (result !== void 0 && !(result instanceof Protocol)) {\n // Check if result exists and is not an instance of Protocol\n const protocolInstance = new Protocol();\n protocolInstance.fromObject(result);\n result = protocolInstance;\n }\n\n return result;\n }\n\n /**\n * Registers a function to be called when the protocol store is ready to persist hanging protocols\n *\n * NOTE: Strategies should implement this function\n *\n * @param callback The function to be called as a callback\n */\n onReady(callback) {\n this.strategy.onReady(callback);\n }\n\n /**\n * Gets the hanging protocol by protocolId if defined, otherwise all stored hanging protocols\n *\n * NOTE: Strategies should implement this function\n *\n * @param protocolId The protocol ID used to find the hanging protocol\n * @returns {object|array} The hanging protocol by protocolId or array of the stored hanging protocols\n */\n getProtocol(protocolId) {\n let result = this.strategy.getProtocol(protocolId);\n return ProtocolStore.getProtocolInstance(result);\n }\n\n /**\n * Stores the hanging protocol\n *\n * NOTE: Strategies should implement this function\n *\n * @param protocol The hanging protocol to be stored\n */\n addProtocol(protocol) {\n this.strategy.addProtocol(protocol);\n }\n\n /**\n * Updates the hanging protocol by protocolId\n *\n * NOTE: Strategies should implement this function\n *\n * @param protocolId The protocol ID used to find the hanging protocol to update\n * @param protocol The updated hanging protocol\n */\n updateProtocol(protocolId, protocol) {\n this.strategy.updateProtocol(protocolId, protocol);\n }\n\n /**\n * Removes the hanging protocol\n *\n * NOTE: Strategies should implement this function\n *\n * @param protocolId The protocol ID used to remove the hanging protocol\n */\n removeProtocol(protocolId) {\n this.strategy.removeProtocol(protocolId);\n }\n}\n","import Protocol from '../classes/Protocol';\nimport ViewportStructure from '../classes/ViewportStructure';\nimport Viewport from '../classes/Viewport';\nimport Stage from '../classes/Stage';\n\nfunction getDefaultProtocol() {\n const protocol = new Protocol('Default');\n protocol.id = 'defaultProtocol';\n protocol.locked = true;\n\n const oneByOne = new ViewportStructure('grid', {\n Rows: 1,\n Columns: 1,\n });\n\n const viewport = new Viewport();\n const first = new Stage(oneByOne, 'oneByOne');\n first.viewports.push(viewport);\n\n protocol.stages.push(first);\n\n return protocol;\n}\n\nconst defaultProtocol = getDefaultProtocol();\n\nexport default defaultProtocol;\n","import ProtocolEngine from './ProtocolEngine.js';\nimport { ProtocolStore, ProtocolStrategy } from './protocolStore';\nimport { addCustomAttribute } from './customAttributes';\nimport { addCustomViewportSetting } from './customViewportSettings';\n\nconst hangingProtocols = {\n ProtocolEngine,\n ProtocolStore,\n ProtocolStrategy,\n addCustomAttribute,\n addCustomViewportSetting,\n};\n\nexport default hangingProtocols;\n","import log from '../../../log';\nimport defaultProtocol from '../defaultProtocol';\n\nexport default class ProtocolStrategy {\n constructor() {\n this.hangingProtocols = new Map();\n this.defaultsAdded = false;\n }\n\n /**\n * Registers a function to be called when the hangingProtocols collection is subscribed\n * The callback is called only one time when the subscription is ready\n *\n * @param callback The function to be called as a callback\n */\n onReady(callback) {\n if (!this.defaultsAdded) {\n log.info('Inserting the default hanging protocol...');\n this.addProtocol(defaultProtocol);\n this.defaultsAdded = true;\n }\n\n callback();\n }\n\n /**\n * Gets the hanging protocol by protocolId if defined, otherwise all stored hanging protocols\n *\n * @param protocolId The protocol ID used to find the hanging protocol\n * @returns {object|array} The hanging protocol by protocolId or array of the stored hanging protocols\n */\n getProtocol(protocolId) {\n // Return the hanging protocol by protocolId if defined\n if (protocolId) {\n return this.hangingProtocols.get(protocolId);\n }\n\n // Otherwise, return all protocols\n return Array.from(this.hangingProtocols.values());\n }\n\n /**\n * Stores the hanging protocol\n *\n * @param protocol The hanging protocol to be stored\n */\n addProtocol(protocol) {\n this.hangingProtocols.set(protocol.id, protocol);\n }\n\n /**\n * Updates the hanging protocol by protocolId\n *\n * @param protocolId The protocol ID used to find the hanging protocol to update\n * @param protocol The updated hanging protocol\n */\n updateProtocol(protocolId, protocol) {\n if (!this.hangingProtocols.has(protocolId)) {\n return;\n }\n\n this.hangingProtocols.set(protocolId, protocol);\n }\n\n /**\n * Removes the hanging protocol\n *\n * @param protocolId The protocol ID used to remove the hanging protocol\n */\n removeProtocol(protocolId) {\n if (!this.hangingProtocols.has(protocolId)) {\n return;\n }\n\n this.hangingProtocols.delete(protocolId);\n }\n}\n","//import Dropdown from './ui/dropdown/class.js';\n\n/*\n * Defines the base OHIF header object\n */\n//const dropdown = new OHIF.ui.Dropdown();\nconst header = {};\n\nexport default header;\n","// Transforms a shallow object with keys separated by \".\" into a nested object\nfunction getNestedObject(shallowObject) {\n const nestedObject = {};\n for (let key in shallowObject) {\n if (!shallowObject.hasOwnProperty(key)) continue;\n const value = shallowObject[key];\n const propertyArray = key.split('.');\n let currentObject = nestedObject;\n while (propertyArray.length) {\n const currentProperty = propertyArray.shift();\n if (!propertyArray.length) {\n currentObject[currentProperty] = value;\n } else {\n if (!currentObject[currentProperty]) {\n currentObject[currentProperty] = {};\n }\n\n currentObject = currentObject[currentProperty];\n }\n }\n }\n\n return nestedObject;\n}\n\n// Transforms a nested object into a shallowObject merging its keys with \".\" character\nfunction getShallowObject(nestedObject) {\n const shallowObject = {};\n const putValues = (baseKey, nestedObject, resultObject) => {\n for (let key in nestedObject) {\n if (!nestedObject.hasOwnProperty(key)) continue;\n let currentKey = baseKey ? `${baseKey}.${key}` : key;\n const currentValue = nestedObject[key];\n if (typeof currentValue === 'object') {\n if (currentValue instanceof Array) {\n currentKey += '[]';\n }\n\n putValues(currentKey, currentValue, resultObject);\n } else {\n resultObject[currentKey] = currentValue;\n }\n }\n };\n\n putValues('', nestedObject, shallowObject);\n return shallowObject;\n}\n\nconst object = {\n getNestedObject,\n getShallowObject,\n};\n\nexport default object;\n","// TODO: This is duplicated in TypeSafeCollection\nfunction isObject(subject) {\n return (\n subject instanceof Object ||\n (typeof subject === 'object' && subject !== null)\n );\n}\n\n// TODO: This is duplicated in TypeSafeCollection\nfunction isString(subject) {\n return typeof subject === 'string';\n}\n\n// Search for some string inside any object or array\nfunction search(object, query, property = null, result = []) {\n // Create the search pattern\n const pattern = new RegExp(query.trim(), 'i');\n\n Object.keys(object).forEach(key => {\n const item = object[key];\n\n // Stop here if item is empty\n if (!item) {\n return;\n }\n\n // Get the value to be compared\n const value = isString(property) ? item[property] : item;\n\n // Check if the value match the pattern\n if (isString(value) && pattern.test(value)) {\n // Add the current item to the result\n result.push(item);\n }\n\n if (isObject(item)) {\n // Search recursively the item if the current item is an object\n search(item, query, property, result);\n }\n });\n\n // Return the found items\n return result;\n}\n\n// Encode any string into a safe format for HTML id attribute\nfunction encodeId(input) {\n const string = input && input.toString ? input.toString() : input;\n\n // Return an underscore if the given string is empty or if it's not a string\n if (string === '' || typeof string !== 'string') {\n return '_';\n }\n\n // Create a converter to replace non accepted chars\n const converter = match => '_' + match[0].charCodeAt(0).toString(16) + '_';\n\n // Encode the given string and return it\n return string.replace(/[^a-zA-Z0-9-]/g, converter);\n}\n\nconst string = {\n search,\n encodeId,\n};\n\nexport default string;\n","import unsavedChanges from './unsavedChanges.js';\nimport handleError from './handleError.js';\nimport isCharacterKeyPress from './isCharacterKeyPress.js';\nimport getOffset from './getOffset.js';\nimport getScrollbarSize from './getScrollbarSize.js';\n\nconst ui = {\n getScrollbarSize,\n getOffset,\n isCharacterKeyPress,\n handleError,\n};\n\nexport default ui;\n","/**\n * Get the vertical and horizontal scrollbar sizes\n * Got from https://stackoverflow.com/questions/986937/how-can-i-get-the-browsers-scrollbar-sizes\n *\n * @returns {Array} Array containing the scrollbar horizontal and vertical sizes\n */\nexport default function getScrollbarSize() {\n const inner = document.createElement('p');\n inner.style.width = '100%';\n inner.style.height = '100%';\n\n const outer = document.createElement('div');\n outer.style.position = 'absolute';\n outer.style.top = '0px';\n outer.style.left = '0px';\n outer.style.visibility = 'hidden';\n outer.style.width = '100px';\n outer.style.height = '100px';\n outer.style.overflow = 'hidden';\n outer.appendChild(inner);\n\n document.body.appendChild(outer);\n\n const w1 = inner.offsetWidth;\n const h1 = inner.offsetHeight;\n outer.style.overflow = 'scroll';\n let w2 = inner.offsetWidth;\n let h2 = inner.offsetHeight;\n\n if (w1 === w2) {\n w2 = outer.clientWidth;\n }\n\n if (h1 === h2) {\n h2 = outer.clientHeight;\n }\n\n document.body.removeChild(outer);\n\n return [w1 - w2, h1 - h2];\n}\n","/**\n * Get the offset for the given element\n *\n * @param {Object} element DOM element which will have the offser calculated\n * @returns {Object} Object containing the top and left offset\n */\nexport default function getOffset(element) {\n let top = 0;\n let left = 0;\n if (element.offsetParent) {\n do {\n left += element.offsetLeft;\n top += element.offsetTop;\n } while ((element = element.offsetParent));\n }\n\n return {\n left,\n top,\n };\n}\n","/**\n * Check if the pressed key combination will result in a character input\n * Got from https://stackoverflow.com/questions/4179708/how-to-detect-if-the-pressed-key-will-produce-a-character-inside-an-input-text\n *\n * @returns {Boolean} Whether the pressed key combination will input a character or not\n */\nexport default function isCharacterKeyPress(event) {\n if (typeof event.which === 'undefined') {\n // This is IE, which only fires keypress events for printable keys\n return true;\n } else if (typeof event.which === 'number' && event.which > 0) {\n // In other browsers except old versions of WebKit, event.which is\n // only greater than zero if the keypress is a printable key.\n // We need to filter out backspace and ctrl/alt/meta key combinations\n return (\n !event.ctrlKey && !event.metaKey && !event.altKey && event.which !== 8\n );\n }\n\n return false;\n}\n","import log from '../log.js';\n\nexport default function handleError(error) {\n let { title, message } = error;\n\n if (!title) {\n if (error instanceof Error) {\n title = error.name;\n }\n }\n\n if (!message) {\n if (error instanceof Error) {\n message = error.message;\n }\n }\n\n const data = Object.assign(\n {\n title,\n message,\n class: 'themed',\n hideConfirm: true,\n cancelLabel: 'Dismiss',\n cancelClass: 'btn-secondary',\n },\n error || {}\n );\n\n log.error(error);\n // TODO: Find a better way to handle errors instead of displaying a dialog for all of them.\n // OHIF.ui.showDialog('dialogForm', data);\n}\n","import './lib';\n\nimport { ExtensionManager, MODULE_TYPES } from './extensions';\nimport { ServicesManager } from './services';\nimport classes, { CommandsManager, HotkeysManager } from './classes/';\n\nimport DICOMWeb from './DICOMWeb';\nimport DICOMSR from './DICOMSR';\nimport cornerstone from './cornerstone.js';\nimport hangingProtocols from './hanging-protocols';\nimport header from './header.js';\nimport log from './log.js';\nimport measurements from './measurements';\nimport metadata from './classes/metadata/';\nimport object from './object.js';\nimport redux from './redux/';\nimport string from './string.js';\nimport studies from './studies/';\nimport ui from './ui';\nimport user from './user.js';\nimport errorHandler from './errorHandler.js';\nimport utils, { hotkeys } from './utils/';\nimport str2ab from './utils/str2ab';\n\nimport {\n UINotificationService,\n UIModalService,\n UIDialogService,\n MeasurementService,\n LoggerService,\n} from './services';\n\nconst OHIF = {\n MODULE_TYPES,\n //\n CommandsManager,\n ExtensionManager,\n HotkeysManager,\n ServicesManager,\n //\n utils,\n hotkeys,\n studies,\n redux,\n classes,\n metadata,\n header,\n cornerstone,\n string,\n ui,\n user,\n errorHandler,\n object,\n log,\n DICOMWeb,\n DICOMSR,\n viewer: {},\n measurements,\n hangingProtocols,\n //\n UINotificationService,\n UIModalService,\n UIDialogService,\n MeasurementService,\n LoggerService,\n};\n\nexport {\n MODULE_TYPES,\n //\n CommandsManager,\n ExtensionManager,\n HotkeysManager,\n ServicesManager,\n //\n utils,\n hotkeys,\n studies,\n redux,\n classes,\n metadata,\n header,\n cornerstone,\n string,\n ui,\n user,\n errorHandler,\n object,\n log,\n DICOMWeb,\n DICOMSR,\n measurements,\n hangingProtocols,\n //\n UINotificationService,\n UIModalService,\n UIDialogService,\n MeasurementService,\n LoggerService,\n\n str2ab,\n};\n\nexport { OHIF };\n\nexport default OHIF;\n","import React from 'react';\nimport adjust from './icons/adjust.svg';\n// Icons\nimport angleDoubleDown from './icons/angle-double-down.svg';\nimport angleDoubleUp from './icons/angle-double-up.svg';\nimport angleLeft from './icons/angle-left.svg';\nimport arrows from './icons/arrows.svg';\nimport arrowsAltH from './icons/arrows-alt-h.svg';\nimport arrowsAltV from './icons/arrows-alt-v.svg';\nimport bars from './icons/bars.svg';\nimport brain from './icons/brain.svg';\nimport brush from './icons/brush.svg';\nimport caretDown from './icons/caret-down.svg';\nimport caretUp from './icons/caret-up.svg';\nimport check from './icons/check.svg';\nimport checkCircle from './icons/check-circle.svg';\nimport checkCircleO from './icons/check-circle-o.svg';\nimport chevronDown from './icons/chevron-down.svg';\nimport circle from './icons/circle.svg';\nimport circleNotch from './icons/circle-notch.svg';\nimport circleO from './icons/circle-o.svg';\nimport clipboard from './icons/clipboard.svg';\nimport cog from './icons/cog.svg';\nimport createComment from './icons/create-comment.svg';\nimport createScreenCapture from './icons/create-screen-capture.svg';\nimport crosshairs from './icons/crosshairs.svg';\nimport cube from './icons/cube.svg';\nimport d3Rotate from './icons/3d-rotate.svg';\nimport database from './icons/database.svg';\nimport dotCircle from './icons/dot-circle.svg';\nimport edit from './icons/edit.svg';\nimport ellipseCircle from './icons/ellipse-circle.svg';\nimport ellipseH from './icons/ellipse-h.svg';\nimport ellipseV from './icons/ellipse-v.svg';\nimport exclamationCircle from './icons/exclamation-circle.svg';\nimport exclamationTriangle from './icons/exclamation-triangle.svg';\nimport fastBackward from './icons/fast-backward.svg';\nimport fastForward from './icons/fast-forward.svg';\nimport stop from './icons/stop.svg';\nimport info from './icons/info.svg';\nimport inlineEdit from './icons/inline-edit.svg';\nimport level from './icons/level.svg';\nimport link from './icons/link.svg';\nimport linkCircles from './icons/link-circles.svg';\nimport list from './icons/list.svg';\nimport liver from './icons/liver.svg';\nimport lock from './icons/lock.svg';\nimport lockAlt from './icons/lock-alt.svg';\nimport lung from './icons/lung.svg';\nimport measureNonTarget from './icons/measure-non-target.svg';\nimport measureTarget from './icons/measure-target.svg';\nimport measureTargetCr from './icons/measure-target-cr.svg';\nimport measureTargetNe from './icons/measure-target-ne.svg';\nimport measureTargetUn from './icons/measure-target-un.svg';\nimport measureTemp from './icons/measure-temp.svg';\nimport objectGroup from './icons/object-group.svg';\nimport ohifLogo from './icons/ohif-logo.svg';\nimport ohifTextLogo from './icons/ohif-text-logo.svg';\nimport oval from './icons/oval.svg';\nimport palette from './icons/palette.svg';\nimport play from './icons/play.svg';\nimport plus from './icons/plus.svg';\nimport powerOff from './icons/power-off.svg';\nimport reset from './icons/reset.svg';\nimport rotate from './icons/rotate.svg';\nimport rotateRight from './icons/rotate-right.svg';\nimport saveRegular from './icons/save-regular.svg';\nimport scissors from './icons/scissors.svg';\nimport search from './icons/search.svg';\nimport searchPlus from './icons/search-plus.svg';\nimport softTissue from './icons/soft-tissue.svg';\nimport sort from './icons/sort.svg';\nimport sortDown from './icons/sort-down.svg';\nimport sortUp from './icons/sort-up.svg';\nimport sphere from './icons/sphere.svg';\nimport squareO from './icons/square-o.svg';\nimport star from './icons/star.svg';\nimport stepBackward from './icons/step-backward.svg';\nimport stepForward from './icons/step-forward.svg';\nimport sun from './icons/sun.svg';\nimport th from './icons/th.svg';\nimport thLarge from './icons/th-large.svg';\nimport thList from './icons/th-list.svg';\nimport times from './icons/times.svg';\nimport trash from './icons/trash.svg';\nimport unlink from './icons/unlink.svg';\nimport user from './icons/user.svg';\nimport youtube from './icons/youtube.svg';\nimport eye from './icons/eye.svg';\nimport eyeClosed from './icons/eye-closed.svg';\nimport envelopeSquare from './icons/envelope-square.svg';\n\nconst ICONS = {\n eye,\n 'eye-closed': eyeClosed,\n brush,\n scissors,\n user,\n sort,\n th,\n star,\n 'sort-up': sortUp,\n sphere,\n 'sort-down': sortDown,\n info,\n cube,\n crosshairs,\n 'dot-circle': dotCircle,\n 'angle-left': angleLeft,\n '3d-rotate': d3Rotate,\n plus,\n 'chevron-down': chevronDown,\n 'angle-double-down': angleDoubleDown,\n 'angle-double-up': angleDoubleUp,\n 'arrows-alt-h': arrowsAltH,\n 'arrows-alt-v': arrowsAltV,\n bars,\n 'caret-down': caretDown,\n 'caret-up': caretUp,\n 'check-circle-o': checkCircleO,\n check,\n circle,\n 'circle-o': circleO,\n times,\n 'create-comment': createComment,\n 'create-screen-capture': createScreenCapture,\n edit,\n 'fast-backward': fastBackward,\n 'fast-forward': fastForward,\n 'object-group': objectGroup,\n search,\n 'power-off': powerOff,\n 'inline-edit': inlineEdit,\n list,\n 'ohif-logo': ohifLogo,\n 'ohif-text-logo': ohifTextLogo,\n lock,\n play,\n database,\n cog,\n 'circle-notch': circleNotch,\n 'square-o': squareO,\n 'check-circle': checkCircle,\n 'lock-alt': lockAlt,\n 'step-backward': stepBackward,\n 'step-forward': stepForward,\n clipboard: clipboard,\n stop,\n 'th-large': thLarge,\n 'th-list': thList,\n sun,\n palette,\n youtube,\n oval,\n 'ellipse-h': ellipseH,\n 'ellipse-v': ellipseV,\n adjust,\n level,\n 'link-circles': linkCircles,\n 'search-plus': searchPlus,\n 'measure-non-target': measureNonTarget,\n 'measure-target': measureTarget,\n 'measure-target-cr': measureTargetCr,\n 'measure-target-un': measureTargetUn,\n 'measure-target-ne': measureTargetNe,\n 'measure-temp': measureTemp,\n 'ellipse-circle': ellipseCircle,\n arrows,\n reset,\n rotate,\n 'rotate-right': rotateRight,\n trash,\n unlink,\n 'exclamation-circle': exclamationCircle,\n link,\n 'exclamation-triangle': exclamationTriangle,\n brain,\n 'soft-tissue': softTissue,\n lung,\n liver,\n save: saveRegular,\n 'envelope-square': envelopeSquare,\n};\n\n/**\n * Return the matching SVG Icon as a React Component.\n * Results in an inlined SVG Element. If there's no match,\n * return `null`\n */\nexport default function getIcon(key, props) {\n if (!key || !ICONS[key]) {\n return React.createElement('div', null, 'Missing Icon');\n }\n\n return React.createElement(ICONS[key], props);\n}\n\nexport { ICONS };\n","import './Icon.styl';\n\nimport PropTypes from 'prop-types';\nimport getIcon from './getIcon.js';\n\nconst Icon = props => {\n return getIcon(props.name, props);\n};\n\nIcon.propTypes = {\n /** The string name of the icon to display */\n name: PropTypes.string.isRequired,\n};\n\nexport default Icon;\n","import { ICONS } from './getIcon.js';\nimport Icon from './Icon.js';\n\nexport { Icon, ICONS };\n","import React, {\n useState,\n createContext,\n useContext,\n useEffect,\n useCallback,\n} from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\n\nconst ModalContext = createContext(null);\nconst { Provider } = ModalContext;\n\nexport const useModal = () => useContext(ModalContext);\n\n/**\n * UI Modal\n *\n * @typedef {Object} ModalProps\n * @property {ReactElement|HTMLElement} [content=null] Modal content.\n * @property {Object} [contentProps=null] Modal content props.\n * @property {boolean} [shouldCloseOnEsc=false] Modal is dismissible via the esc key.\n * @property {boolean} [isOpen=true] Make the Modal visible or hidden.\n * @property {boolean} [closeButton=true] Should the modal body render the close button.\n * @property {string} [title=null] Should the modal render the title independently of the body content.\n * @property {string} [customClassName=null] The custom class to style the modal.\n */\n\nconst ModalProvider = ({ children, modal: Modal, service }) => {\n const DEFAULT_OPTIONS = {\n content: null,\n contentProps: null,\n shouldCloseOnEsc: false,\n isOpen: true,\n onClose: null,\n closeButton: true,\n showScrollbar: false,\n title: null,\n customClassName: '',\n fullscreen: false,\n };\n\n const [options, setOptions] = useState(DEFAULT_OPTIONS);\n\n /**\n * Show the modal and override its configuration props.\n *\n * @param {ModalProps} props { content, contentProps, shouldCloseOnEsc, isOpen, closeButton, title, customClassName }\n * @returns void\n */\n const show = useCallback(props => setOptions({ ...options, ...props }), [\n options,\n ]);\n\n /**\n * Hide the modal and set its properties to default.\n *\n * @returns void\n */\n const hide = useCallback(() => setOptions(DEFAULT_OPTIONS), [\n DEFAULT_OPTIONS,\n ]);\n\n /**\n * Sets the implementation of a modal service that can be used by extensions.\n *\n * @returns void\n */\n useEffect(() => {\n if (service) {\n service.setServiceImplementation({ hide, show });\n }\n }, [hide, service, show]);\n\n const {\n content: ModalContent,\n contentProps,\n isOpen,\n onClose,\n title,\n customClassName,\n shouldCloseOnEsc,\n fullscreen,\n closeButton,\n showScrollbar,\n noScroll,\n } = options;\n\n return (\n \n {ModalContent && (\n {\n if (onClose) {\n onClose();\n }\n\n hide();\n }}\n >\n \n \n )}\n {children}\n \n );\n};\n\n/**\n * Higher Order Component to use the modal methods through a Class Component.\n *\n * @returns\n */\nexport const withModal = Component => {\n return function WrappedComponent(props) {\n const { show, hide } = useModal();\n return ;\n };\n};\n\nModalProvider.defaultProps = {\n service: null,\n};\n\nModalProvider.propTypes = {\n children: PropTypes.oneOfType([\n PropTypes.arrayOf(PropTypes.node),\n PropTypes.node,\n ]).isRequired,\n modal: PropTypes.oneOfType([\n PropTypes.arrayOf(PropTypes.node),\n PropTypes.node,\n PropTypes.func,\n ]).isRequired,\n service: PropTypes.shape({\n setServiceImplementation: PropTypes.func,\n }),\n};\n\nexport default ModalProvider;\n\nexport const ModalConsumer = ModalContext.Consumer;\n","import React, { useEffect } from 'react';\n\nconst SnackbarItem = ({ options, onClose }) => {\n const handleClose = () => {\n onClose(options.id);\n };\n\n const handleClick = () => {\n options.action.onClick({ ...options, close: handleClose });\n };\n\n useEffect(() => {\n if (options.autoClose) {\n setTimeout(() => {\n handleClose();\n }, options.duration);\n }\n }, []);\n\n return (\n \n \n x\n \n {options.title &&
    {options.title}
    }\n {options.message &&
    {options.message}
    }\n {options.action && (\n \n )}\n \n );\n};\n\nexport default SnackbarItem;\n","import React from 'react';\nimport SnackbarItem from './SnackbarItem';\nimport './Snackbar.css';\nimport { useSnackbarContext } from '../../contextProviders';\n\nconst SnackbarContainer = () => {\n const { snackbarItems, hide } = useSnackbarContext();\n\n const renderItem = item => {\n return ;\n };\n\n if (!snackbarItems) {\n return null;\n }\n\n const renderItems = () => {\n const items = {\n topLeft: [],\n topCenter: [],\n topRight: [],\n bottomLeft: [],\n bottomCenter: [],\n bottomRight: [],\n };\n\n snackbarItems.map(item => {\n items[item.position].push(item);\n });\n\n return (\n
    \n {Object.keys(items).map(pos => {\n if (!items[pos].length) {\n return null;\n }\n\n return (\n
    \n {items[pos].map((item, index) => (\n
    {renderItem(item)}
    \n ))}\n
    \n );\n })}\n
    \n );\n };\n\n return <>{renderItems()};\n};\n\nexport default SnackbarContainer;\n","export default {\n INFO: 'info',\n WARNING: 'warning',\n SUCCESS: 'success',\n ERROR: 'error',\n};\n","import React, {\n useState,\n createContext,\n useContext,\n useCallback,\n useEffect,\n} from 'react';\nimport PropTypes from 'prop-types';\nimport { classes } from '@ohif/core';\n\nimport SnackbarContainer from '../components/snackbar/SnackbarContainer';\nimport SnackbarTypes from '../components/snackbar/SnackbarTypes';\n\nconst { LogManager } = classes;\n\nconst SnackbarContext = createContext(null);\n\nexport const useSnackbarContext = () => useContext(SnackbarContext);\n\nconst SnackbarProvider = ({ children, service }) => {\n const DEFAULT_OPTIONS = {\n title: '',\n message: '',\n duration: 5000,\n autoClose: true,\n position: 'bottomRight',\n type: SnackbarTypes.INFO,\n action: null,\n };\n\n const [count, setCount] = useState(1);\n const [snackbarItems, setSnackbarItems] = useState([]);\n\n useEffect(() => {\n const onLogHandler = ({ type, notify, title, message }) => {\n if (notify) {\n show({ type, title, message });\n }\n };\n\n LogManager.subscribe(LogManager.EVENTS.OnLog, onLogHandler);\n\n return () => {\n LogManager.unsubscribe(LogManager.EVENTS.OnLog, onLogHandler);\n };\n }, [show]);\n\n const show = useCallback(\n options => {\n if (!options || (!options.title && !options.message)) {\n console.warn(\n 'Snackbar cannot be rendered without required parameters: title | message'\n );\n\n return null;\n }\n\n if (options.type === 'error') {\n console.error(options.error);\n }\n\n const newItem = {\n ...DEFAULT_OPTIONS,\n ...options,\n id: count,\n visible: true,\n };\n\n setSnackbarItems(state => [...state, newItem]);\n setCount(count + 1);\n },\n [count, DEFAULT_OPTIONS]\n );\n\n const hide = useCallback(\n id => {\n const hideItem = items => {\n const newItems = items.map(item => {\n if (item.id === id) {\n item.visible = false;\n }\n\n return item;\n });\n\n return newItems;\n };\n\n setSnackbarItems(state => hideItem(state));\n\n setTimeout(() => {\n setSnackbarItems(state => [...state.filter(item => item.id !== id)]);\n }, 1000);\n },\n [setSnackbarItems]\n );\n\n const hideAll = () => {\n // reset count\n setCount(1);\n\n // remove all items from array\n setSnackbarItems(() => []);\n };\n\n /**\n * Sets the implementation of a notification service that can be used by extensions.\n *\n * @returns void\n */\n useEffect(() => {\n if (service) {\n service.setServiceImplementation({ hide, show });\n }\n }, [service, hide, show]);\n\n /**\n * expose snackbar methods to window for debug purposes\n * TODO: Check if it's really necessary\n */\n window.snackbar = {\n show,\n hide,\n hideAll,\n };\n\n return (\n \n {!!snackbarItems && }\n {children}\n \n );\n};\n\nSnackbarProvider.defaultProps = {\n service: null,\n};\n\nSnackbarProvider.propTypes = {\n children: PropTypes.oneOfType([\n PropTypes.arrayOf(PropTypes.node),\n PropTypes.node,\n PropTypes.func,\n ]).isRequired,\n service: PropTypes.shape({\n setServiceImplementation: PropTypes.func,\n }),\n};\n\n/**\n *\n * High Order Component to use the snackbar methods through a Class Component\n *\n */\nexport const withSnackbar = Component => {\n return function WrappedComponent(props) {\n const snackbarContext = {\n ...useSnackbarContext(),\n };\n return ;\n };\n};\n\nexport default SnackbarProvider;\n","// Reference > https://reactjs.org/docs/context.html\nimport React from 'react';\nimport {\n withTranslation as I18NextWithTranslation,\n I18nextProvider,\n} from 'react-i18next';\nimport i18n from '@ohif/i18n';\n\nconst WrapperI18n = Component => {\n const WrapperComponent = props => (\n \n \n \n );\n\n return WrapperComponent;\n};\n\nconst withTranslation = namespace => Component => {\n const TranslatedComponent = props => {\n return ;\n };\n\n return WrapperI18n(I18NextWithTranslation(namespace)(TranslatedComponent));\n};\n\nexport { withTranslation };\nexport default withTranslation;\n","import React, {\n useState,\n createContext,\n useContext,\n useCallback,\n useEffect,\n} from 'react';\nimport PropTypes from 'prop-types';\nimport Draggable from 'react-draggable';\nimport classNames from 'classnames';\n\nimport { utils } from '@ohif/core';\n\nimport './DialogProvider.styl';\n\nconst DialogContext = createContext(null);\n\nexport const useDialog = () => useContext(DialogContext);\n\nconst DialogProvider = ({ children, service }) => {\n const [isDragging, setIsDragging] = useState(false);\n const [dialogs, setDialogs] = useState([]);\n const [lastDialogId, setLastDialogId] = useState(null);\n const [lastDialogPosition, setLastDialogPosition] = useState(null);\n const [centerPositions, setCenterPositions] = useState([]);\n\n useEffect(() => {\n setCenterPositions(\n dialogs.map(dialog => ({\n id: dialog.id,\n ...getCenterPosition(dialog.id),\n }))\n );\n }, [dialogs]);\n\n const getCenterPosition = id => {\n const root = document.querySelector('#root');\n const centerX = root.offsetLeft + root.offsetWidth / 2;\n const centerY = root.offsetTop + root.offsetHeight / 2;\n const item = document.querySelector(`#draggableItem-${id}`);\n const itemBounds = item.getBoundingClientRect();\n return {\n x: centerX - itemBounds.width / 2,\n y: centerY - itemBounds.height / 2,\n };\n };\n\n /**\n * Creates a new dialog and return its id.\n *\n * @param {DialogProps} props The dialog props.\n * @returns The new dialog id.\n */\n const create = useCallback(props => {\n const { id } = props;\n\n let dialogId = id;\n if (!dialogId) {\n dialogId = utils.guid();\n }\n\n setDialogs(dialogs => [...dialogs, { ...props, id: dialogId }]);\n setLastDialogId(dialogId);\n\n return dialogId;\n }, []);\n\n /**\n * Dismisses the dialog with a given id.\n *\n * @param {Object} props -\n * @property {string} props.id The dialog id.\n * @returns void\n */\n const dismiss = useCallback(\n ({ id }) =>\n setDialogs(dialogs => dialogs.filter(dialog => dialog.id !== id)),\n []\n );\n\n /**\n * Sets the implementation of a dialog service that can be used by extensions.\n *\n * @returns void\n */\n useEffect(() => {\n if (service) {\n service.setServiceImplementation({ create, dismiss, dismissAll });\n }\n }, [create, dismiss, service]);\n\n /**\n * Moves the dialog to the foreground if clicked.\n *\n * @param {string} id The dialog id.\n * @returns void\n */\n const _bringToFront = useCallback(id => {\n setDialogs(dialogs => {\n const topDialog = dialogs.find(dialog => dialog.id === id);\n return topDialog\n ? [...dialogs.filter(dialog => dialog.id !== id), topDialog]\n : dialogs;\n });\n }, []);\n\n /**\n * UI Dialog\n *\n * @typedef {Object} DialogProps\n * @property {string} id The dialog id.\n * @property {DialogContent} content The dialog content.\n * @property {Object} contentProps The dialog content props.\n * @property {boolean} isDraggable Controls if dialog content is draggable or not.\n * @property {boolean} showOverlay Controls dialog overlay.\n * @property {boolean} centralize Center the dialog on the screen.\n * @property {boolean} preservePosition Use last position instead of default.\n * @property {ElementPosition} defaultPosition Specifies the `x` and `y` that the dragged item should start at.\n * @property {Function} onStart Called when dragging starts. If `false` is returned any handler, the action will cancel.\n * @property {Function} onStop Called when dragging stops.\n * @property {Function} onDrag Called while dragging.\n */\n\n useEffect(() => _bringToFront(lastDialogId), [_bringToFront, lastDialogId]);\n\n /**\n * Dismisses all dialogs.\n *\n * @returns void\n */\n const dismissAll = () => {\n setDialogs([]);\n };\n\n /**\n * Indicate if there are no dialogs present.\n *\n * @returns True if no dialogs are present.\n */\n const isEmpty = () => dialogs && dialogs.length < 1;\n\n const renderDialogs = () =>\n dialogs.map(dialog => {\n const {\n id,\n content: DialogContent,\n contentProps,\n defaultPosition,\n centralize = false,\n preservePosition = true,\n isDraggable = true,\n onStart,\n onStop,\n onDrag,\n showOverlay,\n } = dialog;\n\n let position =\n (preservePosition && lastDialogPosition) || defaultPosition;\n if (centralize) {\n position = centerPositions.find(position => position.id === id);\n }\n\n const dragableItem = () => (\n {\n const e = event || window.event;\n const target = e.target || e.srcElement;\n const BLACKLIST = [\n 'SVG',\n 'BUTTON',\n 'PATH',\n 'INPUT',\n 'SPAN',\n 'LABEL',\n ];\n if (BLACKLIST.includes(target.tagName.toUpperCase())) {\n return false;\n }\n\n if (validCallback(onStart)) {\n return onStart(event);\n }\n }}\n onStop={event => {\n setIsDragging(false);\n\n if (validCallback(onStop)) {\n return onStop(event);\n }\n }}\n onDrag={event => {\n setIsDragging(true);\n _bringToFront(id);\n _updateLastDialogPosition(id);\n\n if (validCallback(onDrag)) {\n return onDrag(event);\n }\n }}\n >\n _bringToFront(id)}\n >\n \n \n \n );\n\n return showOverlay ? (\n
    \n {dragableItem()}\n
    \n ) : (\n dragableItem()\n );\n });\n\n /**\n * Update the last dialog position to be used as the new default position.\n *\n * @returns void\n */\n const _updateLastDialogPosition = dialogId => {\n const draggableItemBounds = document\n .querySelector(`#draggableItem-${dialogId}`)\n .getBoundingClientRect();\n setLastDialogPosition({\n x: draggableItemBounds.x,\n y: draggableItemBounds.y,\n });\n };\n\n const validCallback = callback => callback && typeof callback === 'function';\n\n return (\n \n {!isEmpty() &&
    {renderDialogs()}
    }\n {children}\n
    \n );\n};\n\n/**\n *\n * High Order Component to use the dialog methods through a Class Component\n *\n */\nexport const withDialog = Component => {\n return function WrappedComponent(props) {\n const { create, dismiss, dismissAll, isEmpty } = useDialog();\n return (\n \n );\n };\n};\n\nDialogProvider.defaultProps = {\n service: null,\n};\n\nDialogProvider.propTypes = {\n children: PropTypes.oneOfType([\n PropTypes.arrayOf(PropTypes.node),\n PropTypes.node,\n PropTypes.func,\n ]).isRequired,\n service: PropTypes.shape({\n setServiceImplementation: PropTypes.func,\n }),\n};\n\nexport default DialogProvider;\n","import React, { useState, createContext, useContext, useEffect } from 'react';\nimport PropTypes from 'prop-types';\n\nconst LoggerContext = createContext(null);\nconst { Provider } = LoggerContext;\n\nexport const useLogger = () => useContext(LoggerContext);\n\nconst LoggerProvider = ({ children, service }) => {\n const [state, setState] = useState({\n errors: [],\n infos: [],\n });\n\n useEffect(() => {\n const onErrorHandler = ({ error: errorObject, message }) => {\n error({ error: errorObject, message });\n };\n window.addEventListener('error', onErrorHandler);\n return () => {\n window.removeEventListener('error', onErrorHandler);\n };\n }, []);\n\n /**\n * Logs an error\n *\n * @param {object} props { error, stack, message, displayOnConsole }\n * @returns void\n */\n const error = ({\n error = {},\n stack = '',\n message = '',\n displayOnConsole = true,\n }) => {\n const errorObject = { error, stack, message, displayOnConsole };\n setState(state => ({ ...state, errors: [...state.errors, errorObject] }));\n\n if (displayOnConsole) {\n console.error(error);\n }\n };\n\n /**\n * Logs an info\n *\n * @param {object} props { message, displayOnConsole }\n * @returns void\n */\n const info = ({ message = '', displayOnConsole = true }) => {\n setState(state => ({\n ...state,\n infos: state.infos.push({ message, displayOnConsole }),\n }));\n\n if (displayOnConsole) {\n console.info(message);\n }\n };\n\n /**\n * Sets the implementation of a log service that can be used by extensions\n *\n * @returns void\n */\n useEffect(() => {\n if (service) {\n service.setServiceImplementation({ error, info });\n }\n }, [error, service, info]);\n\n return {children};\n};\n\n/**\n * Higher Order Component to use the log methods through a Class Component\n *\n * @returns\n */\nexport const withLogger = Component => {\n return function WrappedComponent(props) {\n const { error, info, state } = useLogger();\n return ;\n };\n};\n\nLoggerProvider.defaultProps = {\n service: null,\n};\n\nLoggerProvider.propTypes = {\n children: PropTypes.oneOfType([\n PropTypes.arrayOf(PropTypes.node),\n PropTypes.node,\n ]).isRequired,\n service: PropTypes.shape({\n setServiceImplementation: PropTypes.func,\n }),\n};\n\nexport default LoggerProvider;\n\nexport const LogConsumer = LoggerContext.Consumer;\n","export {\n default as ModalProvider,\n useModal,\n withModal,\n ModalConsumer,\n} from './ModalProvider.js';\nexport {\n default as SnackbarProvider,\n useSnackbarContext,\n withSnackbar,\n} from './SnackbarProvider.js';\nexport {\n default as LanguageProvider,\n withTranslation,\n} from './LanguageProvider.js';\nexport {\n default as DialogProvider,\n withDialog,\n useDialog,\n} from './DialogProvider.js';\nexport {\n default as LoggerProvider,\n withLogger,\n useLogger,\n} from './LoggerProvider.js';\n","/**\n * Create a random GUID\n *\n * @return {string}\n */\nconst guid = () => {\n const getFourRandomValues = () => {\n return Math.floor((1 + Math.random()) * 0x10000)\n .toString(16)\n .substring(1);\n };\n return (\n getFourRandomValues() +\n getFourRandomValues() +\n '-' +\n getFourRandomValues() +\n '-' +\n getFourRandomValues() +\n '-' +\n getFourRandomValues() +\n '-' +\n getFourRandomValues() +\n getFourRandomValues() +\n getFourRandomValues()\n );\n};\n\nexport default guid;\n","// These should be overridden by the implementation\nconst errorHandler = {\n getHTTPErrorHandler: () => null,\n};\n\nexport default errorHandler;\n","// @TODO: improve this object\n/**\n * Objects to be used to throw errors\n */\nclass OHIFError extends Error {\n constructor(message) {\n super();\n this.message = message;\n this.stack = new Error().stack;\n this.name = this.constructor.name;\n }\n}\n\nexport default OHIFError;\n","import retry from 'retry';\n\nconst defaultRetryOptions = {\n retries: 5,\n factor: 3,\n minTimeout: 1 * 1000,\n maxTimeout: 60 * 1000,\n randomize: true,\n retryableStatusCodes: [429, 500],\n};\n\nlet retryOptions = { ...defaultRetryOptions };\n\n/**\n * Request hook used to add retry functionality to XHR requests.\n *\n * @param {XMLHttpRequest} request XHR request instance\n * @param {object} metadata Metadata about the request\n * @param {object} metadata.url URL\n * @param {object} metadata.method HTTP method\n * @returns {XMLHttpRequest} request instance optionally modified\n */\nconst xhrRetryRequestHook = (request, metadata) => {\n const { url, method } = metadata;\n\n function faultTolerantRequestSend(...args) {\n const operation = retry.operation(retryOptions);\n\n operation.attempt(function operationAttempt(currentAttempt) {\n const originalOnReadyStateChange = request.onreadystatechange;\n\n /** Overriding/extending XHR function */\n request.onreadystatechange = function onReadyStateChange(...args) {\n originalOnReadyStateChange.apply(request, args);\n\n if (retryOptions.retryableStatusCodes.includes(request.status)) {\n const errorMessage = `Attempt to request ${url} failed.`;\n const attemptFailedError = new Error(errorMessage);\n operation.retry(attemptFailedError);\n }\n };\n\n /** Call open only on retry (after headers and other things were set in the xhr instance) */\n if (currentAttempt > 1) {\n console.warn(`Requesting ${url}... (attempt: ${currentAttempt})`);\n request.open(method, url, true);\n }\n });\n\n originalRequestSend.apply(request, args);\n }\n\n /** Overriding/extending XHR function */\n const originalRequestSend = request.send;\n request.send = faultTolerantRequestSend;\n\n return request;\n};\n\n/**\n * Returns a configured retry request hook function\n * that can be used to add retry functionality to XHR request.\n *\n * Default options:\n * retries: 5\n * factor: 3\n * minTimeout: 1 * 1000\n * maxTimeout: 60 * 1000\n * randomize: true\n *\n * @param {object} options\n * @param {number} options.retires number of retries\n * @param {number} options.factor factor\n * @param {number} options.minTimeout the min timeout\n * @param {number} options.maxTimeout the max timeout\n * @param {boolean} options.randomize randomize\n * @param {array} options.retryableStatusCodes status codes that can trigger retry\n * @returns {function} the configured retry request function\n */\nexport const getXHRRetryRequestHook = (options = {}) => {\n retryOptions = { ...defaultRetryOptions };\n if ('retries' in options) {\n retryOptions.retries = options.retries;\n }\n if ('factor' in options) {\n retryOptions.factor = options.factor;\n }\n if ('minTimeout' in options) {\n retryOptions.minTimeout = options.minTimeout;\n }\n if ('maxTimeout' in options) {\n retryOptions.maxTimeout = options.maxTimeout;\n }\n if ('randomize' in options) {\n retryOptions.randomize = options.randomize;\n }\n if ('retryableStatusCodes' in options) {\n retryOptions.retryableStatusCodes = options.retryableStatusCodes;\n }\n return xhrRetryRequestHook;\n};\n\nexport default getXHRRetryRequestHook;\n","// These should be overridden by the implementation\nlet user = {\n userLoggedIn: () => false,\n getUserId: () => null,\n getName: () => null,\n getAccessToken: () => null,\n login: () => new Promise((resolve, reject) => reject()),\n logout: () => new Promise((resolve, reject) => reject()),\n getData: key => null,\n setData: (key, value) => null,\n};\n\nexport default user;\n","/**\n * Constants\n */\n\nconst STRING = 'string';\nconst NUMBER = 'number';\nconst FUNCTION = 'function';\nconst OBJECT = 'object';\n\n/**\n * Class Definition\n */\n\nexport class Metadata {\n /**\n * Constructor and Instance Methods\n */\n\n constructor(data, uid) {\n // Define the main \"_data\" private property as an immutable property.\n // IMPORTANT: This property can only be set during instance construction.\n Object.defineProperty(this, '_data', {\n configurable: false,\n enumerable: false,\n writable: false,\n value: data,\n });\n\n // Define the main \"_uid\" private property as an immutable property.\n // IMPORTANT: This property can only be set during instance construction.\n Object.defineProperty(this, '_uid', {\n configurable: false,\n enumerable: false,\n writable: false,\n value: uid,\n });\n\n // Define \"_custom\" properties as an immutable property.\n // IMPORTANT: This property can only be set during instance construction.\n Object.defineProperty(this, '_custom', {\n configurable: false,\n enumerable: false,\n writable: false,\n value: Object.create(null),\n });\n }\n\n getData() {\n return this._data;\n }\n\n getDataProperty(propertyName) {\n let propertyValue;\n const _data = this._data;\n if (\n _data instanceof Object ||\n (typeof _data === OBJECT && _data !== null)\n ) {\n propertyValue = _data[propertyName];\n }\n return propertyValue;\n }\n\n /**\n * Get unique object ID\n */\n getObjectID() {\n return this._uid;\n }\n\n /**\n * Set custom attribute value\n * @param {String} attribute Custom attribute name\n * @param {Any} value Custom attribute value\n */\n setCustomAttribute(attribute, value) {\n this._custom[attribute] = value;\n }\n\n /**\n * Get custom attribute value\n * @param {String} attribute Custom attribute name\n * @return {Any} Custom attribute value\n */\n getCustomAttribute(attribute) {\n return this._custom[attribute];\n }\n\n /**\n * Check if a custom attribute exists\n * @param {String} attribute Custom attribute name\n * @return {Boolean} True if custom attribute exists or false if not\n */\n customAttributeExists(attribute) {\n return attribute in this._custom;\n }\n\n /**\n * Set custom attributes in batch mode.\n * @param {Object} attributeMap An object whose own properties will be used as custom attributes.\n */\n setCustomAttributes(attributeMap) {\n const _hasOwn = Object.prototype.hasOwnProperty;\n const _custom = this._custom;\n for (let attribute in attributeMap) {\n if (_hasOwn.call(attributeMap, attribute)) {\n _custom[attribute] = attributeMap[attribute];\n }\n }\n }\n\n /**\n * Static Methods\n */\n\n static isValidUID(uid) {\n return typeof uid === STRING && uid.length > 0;\n }\n\n static isValidIndex(index) {\n return typeof index === NUMBER && index >= 0 && (index | 0) === index;\n }\n\n static isValidCallback(callback) {\n return typeof callback === FUNCTION;\n }\n}\n","const state = {\n enabledElements: {},\n};\n\n/**\n * Sets the enabled element `dom` reference for an active viewport.\n * @param {HTMLElement} dom Active viewport element.\n * @return void\n */\nconst setEnabledElement = (viewportIndex, element) =>\n (state.enabledElements[viewportIndex] = element);\n\n/**\n * Grabs the enabled element `dom` reference of an active viewport.\n *\n * @return {HTMLElement} Active viewport element.\n */\nconst getEnabledElement = viewportIndex => state.enabledElements[viewportIndex];\n\nexport { setEnabledElement, getEnabledElement };\n","import { Metadata } from './Metadata';\nimport OHIFError from '../OHIFError.js';\n\n/**\n * ATTENTION! This class should never depend on StudyMetadata or SeriesMetadata classes as this could\n * possibly cause circular dependency issues.\n */\n\nconst UNDEFINED = 'undefined';\nconst STRING = 'string';\n\nexport class InstanceMetadata extends Metadata {\n constructor(data, uid) {\n super(data, uid);\n // Initialize Private Properties\n Object.defineProperties(this, {\n _imageId: {\n configurable: true, // configurable so that it can be redefined in sub-classes...\n enumerable: false,\n writable: true,\n value: null,\n },\n });\n // Initialize Public Properties\n this._definePublicProperties();\n }\n\n /**\n * Private Methods\n */\n\n /**\n * Define Public Properties\n * This method should only be called during initialization (inside the class constructor)\n */\n _definePublicProperties() {\n /**\n * Property: this.SOPInstanceUID\n * Same as this.getSOPInstanceUID()\n * It's specially useful in contexts where a method call is not suitable like in search criteria. For example:\n * sopInstanceCollection.findBy({\n * SOPInstanceUID: '1.2.3.4.5.6.77777.8888888.99999999999.0'\n * });\n */\n Object.defineProperty(this, 'SOPInstanceUID', {\n configurable: false,\n enumerable: false,\n get: function() {\n return this.getSOPInstanceUID();\n },\n });\n }\n\n /**\n * Public Methods\n */\n\n /**\n * Returns the StudyInstanceUID of the current instance. This method is basically a shorthand the full \"getTagValue\" method call.\n */\n getStudyInstanceUID() {\n return this.getTagValue('StudyInstanceUID', null);\n }\n\n /**\n * Returns the SeriesInstanceUID of the current instance. This method is basically a shorthand the full \"getTagValue\" method call.\n */\n getSeriesInstanceUID() {\n return this.getTagValue('SeriesInstanceUID', null);\n }\n\n /**\n * Returns the SOPInstanceUID of the current instance.\n */\n getSOPInstanceUID() {\n return this.getTagValue('SOPInstanceUID', null);\n }\n\n // @TODO: Improve this... (E.g.: blob data)\n getStringValue(tagOrProperty, index, defaultValue) {\n let value = this.getTagValue(tagOrProperty, defaultValue);\n\n if (typeof value !== STRING && typeof value !== UNDEFINED) {\n value = value.toString();\n }\n\n return InstanceMetadata.getIndexedValue(value, index, defaultValue);\n }\n\n // @TODO: Improve this... (E.g.: blob data)\n getFloatValue(tagOrProperty, index, defaultValue) {\n let value = this.getTagValue(tagOrProperty, defaultValue);\n value = InstanceMetadata.getIndexedValue(value, index, defaultValue);\n\n if (value instanceof Array) {\n value.forEach((val, idx) => {\n value[idx] = parseFloat(val);\n });\n\n return value;\n }\n\n return typeof value === STRING ? parseFloat(value) : value;\n }\n\n // @TODO: Improve this... (E.g.: blob data)\n getIntValue(tagOrProperty, index, defaultValue) {\n let value = this.getTagValue(tagOrProperty, defaultValue);\n value = InstanceMetadata.getIndexedValue(value, index, defaultValue);\n\n if (value instanceof Array) {\n value.forEach((val, idx) => {\n value[idx] = parseFloat(val);\n });\n\n return value;\n }\n\n return typeof value === STRING ? parseInt(value) : value;\n }\n\n /**\n * This function should be overriden by specialized classes in order to allow client libraries or viewers to take advantage of the Study Metadata API.\n */\n getTagValue(tagOrProperty, defaultValue) {\n /**\n * Please override this method on a specialized class.\n */\n throw new OHIFError(\n 'InstanceMetadata::getTagValue is not overriden. Please, override it in a specialized class. See OHIFInstanceMetadata for example'\n );\n }\n\n /**\n * Compares the current instance with another one.\n * @param {InstanceMetadata} instance An instance of the InstanceMetadata class.\n * @returns {boolean} Returns true if both instances refer to the same instance.\n */\n equals(instance) {\n const self = this;\n return (\n instance === self ||\n (instance instanceof InstanceMetadata &&\n instance.getSOPInstanceUID() === self.getSOPInstanceUID())\n );\n }\n\n /**\n * Check if the tagOrProperty exists\n * @param {String} tagOrProperty tag or property be checked\n * @return {Boolean} True if the tag or property exists or false if doesn't\n */\n tagExists(tagOrProperty) {\n /**\n * Please override this method\n */\n throw new OHIFError(\n 'InstanceMetadata::tagExists is not overriden. Please, override it in a specialized class. See OHIFInstanceMetadata for example'\n );\n }\n\n /**\n * Get custom image id of a sop instance\n * @return {Any} sop instance image id\n */\n getImageId(frame) {\n /**\n * Please override this method\n */\n throw new OHIFError(\n 'InstanceMetadata::getImageId is not overriden. Please, override it in a specialized class. See OHIFInstanceMetadata for example'\n );\n }\n\n /**\n * Static Methods\n */\n\n /**\n * Get an value based that can be index based. This function is called by all getters. See above functions.\n * - If value is a String and has indexes:\n * - If undefined index: returns an array of the split values.\n * - If defined index:\n * - If invalid: returns defaultValue\n * - If valid: returns the indexed value\n * - If value is not a String, returns default value.\n */\n static getIndexedValue(value, index, defaultValue) {\n let result = defaultValue;\n\n if (typeof value === STRING) {\n const hasIndexValues = value.indexOf('\\\\') !== -1;\n\n result = value;\n\n if (hasIndexValues) {\n const splitValues = value.split('\\\\');\n if (Metadata.isValidIndex(index)) {\n const indexedValue = splitValues[index];\n\n result = typeof indexedValue !== STRING ? defaultValue : indexedValue;\n } else {\n result = splitValues;\n }\n }\n }\n\n return result;\n }\n}\n","import { Metadata } from './Metadata';\nimport { InstanceMetadata } from './InstanceMetadata';\n\nexport class SeriesMetadata extends Metadata {\n constructor(data, uid) {\n super(data, uid);\n // Initialize Private Properties\n Object.defineProperties(this, {\n _seriesInstanceUID: {\n configurable: true, // configurable so that it can be redefined in sub-classes...\n enumerable: false,\n writable: true,\n value: null,\n },\n _instances: {\n configurable: false,\n enumerable: false,\n writable: false,\n value: [],\n },\n _firstInstance: {\n configurable: false,\n enumerable: false,\n writable: true,\n value: null,\n },\n });\n // Initialize Public Properties\n this._definePublicProperties();\n }\n\n /**\n * Private Methods\n */\n\n /**\n * Define Public Properties\n * This method should only be called during initialization (inside the class constructor)\n */\n _definePublicProperties() {\n /**\n * Property: this.seriesInstanceUID\n * Same as this.getSeriesInstanceUID()\n * It's specially useful in contexts where a method call is not suitable like in search criteria. For example:\n * seriesCollection.findBy({\n * seriesInstanceUID: '1.2.3.4.5.6.77777.8888888.99999999999.0'\n * });\n */\n Object.defineProperty(this, 'seriesInstanceUID', {\n configurable: false,\n enumerable: false,\n get: function() {\n return this.getSeriesInstanceUID();\n },\n });\n }\n\n /**\n * Public Methods\n */\n\n /**\n * Returns the SeriesInstanceUID of the current series.\n */\n getSeriesInstanceUID() {\n return this._seriesInstanceUID;\n }\n\n /**\n * Append an instance to the current series.\n * @param {InstanceMetadata} instance The instance to be added to the current series.\n * @returns {boolean} Returns true on success, false otherwise.\n */\n addInstance(instance) {\n let result = false;\n if (\n instance instanceof InstanceMetadata &&\n this.getInstanceByUID(instance.getSOPInstanceUID()) === void 0\n ) {\n this._instances.push(instance);\n result = true;\n }\n return result;\n }\n\n /**\n * Get the first instance of the current series retaining a consistent result across multiple calls.\n * @return {InstanceMetadata} An instance of the InstanceMetadata class or null if it does not exist.\n */\n getFirstInstance() {\n let instance = this._firstInstance;\n if (!(instance instanceof InstanceMetadata)) {\n instance = null;\n const found = this.getInstanceByIndex(0);\n if (found instanceof InstanceMetadata) {\n this._firstInstance = found;\n instance = found;\n }\n }\n return instance;\n }\n\n /**\n * Find an instance by index.\n * @param {number} index An integer representing a list index.\n * @returns {InstanceMetadata} Returns a InstanceMetadata instance when found or undefined otherwise.\n */\n getInstanceByIndex(index) {\n let found; // undefined by default...\n if (Metadata.isValidIndex(index)) {\n found = this._instances[index];\n }\n return found;\n }\n\n /**\n * Find an instance by SOPInstanceUID.\n * @param {string} uid An UID string.\n * @returns {InstanceMetadata} Returns a InstanceMetadata instance when found or undefined otherwise.\n */\n getInstanceByUID(uid) {\n let found; // undefined by default...\n if (Metadata.isValidUID(uid)) {\n found = this._instances.find(instance => {\n return instance.getSOPInstanceUID() === uid;\n });\n }\n return found;\n }\n\n /**\n * Retrieve the number of instances within the current series.\n * @returns {number} The number of instances in the current series.\n */\n getInstanceCount() {\n return this._instances.length;\n }\n\n /**\n * Invokes the supplied callback for each instance in the current series passing\n * two arguments: instance (an InstanceMetadata instance) and index (the integer\n * index of the instance within the current series)\n * @param {function} callback The callback function which will be invoked for each instance in the series.\n * @returns {undefined} Nothing is returned.\n */\n forEachInstance(callback) {\n if (Metadata.isValidCallback(callback)) {\n this._instances.forEach((instance, index) => {\n callback.call(null, instance, index);\n });\n }\n }\n\n /**\n * Find the index of an instance inside the series.\n * @param {InstanceMetadata} instance An instance of the SeriesMetadata class.\n * @returns {number} The index of the instance inside the series or -1 if not found.\n */\n indexOfInstance(instance) {\n return this._instances.indexOf(instance);\n }\n\n /**\n * Search the associated instances using the supplied callback as criteria. The callback is passed\n * two arguments: instance (a InstanceMetadata instance) and index (the integer\n * index of the instance within its series)\n * @param {function} callback The callback function which will be invoked for each instance.\n * @returns {InstanceMetadata|undefined} If an instance is found based on callback criteria it\n * returns a InstanceMetadata. \"undefined\" is returned otherwise\n */\n findInstance(callback) {\n if (Metadata.isValidCallback(callback)) {\n return this._instances.find((instance, index) => {\n return callback.call(null, instance, index);\n });\n }\n }\n\n /**\n * Compares the current series with another one.\n * @param {SeriesMetadata} series An instance of the SeriesMetadata class.\n * @returns {boolean} Returns true if both instances refer to the same series.\n */\n equals(series) {\n const self = this;\n return (\n series === self ||\n (series instanceof SeriesMetadata &&\n series.getSeriesInstanceUID() === self.getSeriesInstanceUID())\n );\n }\n}\n","import classNames from 'classnames';\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport Transition, {\n ENTERED,\n ENTERING,\n} from 'react-transition-group/Transition';\n\nconst propTypes = {\n /**\n * Show the component; triggers the fade in or fade out animation\n */\n in: PropTypes.bool,\n\n /**\n * Wait until the first \"enter\" transition to mount the component (add it to the DOM)\n */\n mountOnEnter: PropTypes.bool,\n\n /**\n * Unmount the component (remove it from the DOM) when it is faded out\n */\n unmountOnExit: PropTypes.bool,\n\n /**\n * Run the fade in animation when the component mounts, if it is initially\n * shown\n */\n appear: PropTypes.bool,\n\n /**\n * Duration of the fade animation in milliseconds, to ensure that finishing\n * callbacks are fired even if the original browser transition end events are\n * canceled\n */\n timeout: PropTypes.number,\n\n /**\n * Callback fired before the component fades in\n */\n onEnter: PropTypes.func,\n /**\n * Callback fired after the component starts to fade in\n */\n onEntering: PropTypes.func,\n /**\n * Callback fired after the has component faded in\n */\n onEntered: PropTypes.func,\n /**\n * Callback fired before the component fades out\n */\n onExit: PropTypes.func,\n /**\n * Callback fired after the component starts to fade out\n */\n onExiting: PropTypes.func,\n /**\n * Callback fired after the component has faded out\n */\n onExited: PropTypes.func,\n};\n\nconst defaultProps = {\n in: false,\n timeout: 300,\n mountOnEnter: false,\n unmountOnExit: false,\n appear: false,\n};\n\nconst fadeStyles = {\n [ENTERING]: 'in',\n [ENTERED]: 'in',\n};\n\nclass Fade extends React.Component {\n render() {\n const { className, children, ...props } = this.props;\n\n return (\n \n {(status, innerProps) =>\n React.cloneElement(children, {\n ...innerProps,\n className: classNames(\n 'fade',\n className,\n children.props.className,\n fadeStyles[status]\n ),\n })\n }\n \n );\n }\n}\n\nFade.propTypes = propTypes;\nFade.defaultProps = defaultProps;\n\nexport default Fade;\n","import classNames from 'classnames';\nimport React, { cloneElement } from 'react';\nimport PropTypes from 'prop-types';\nimport { Overlay as BaseOverlay } from 'react-overlays';\nimport elementType from 'prop-types-extra/lib/elementType';\nimport { withTranslation } from '../../contextProviders';\n\nimport Fade from './Fade';\n\nconst propTypes = {\n /**\n * Set the visibility of the Overlay\n */\n show: PropTypes.bool,\n /**\n * Specify whether the overlay should trigger onHide when the user clicks outside the overlay\n */\n rootClose: PropTypes.bool,\n /**\n * A callback invoked by the overlay when it wishes to be hidden. Required if\n * `rootClose` is specified.\n */\n onHide: PropTypes.func,\n\n /**\n * Use animation\n */\n animation: PropTypes.oneOfType([PropTypes.bool, elementType]),\n\n /**\n * Callback fired before the Overlay transitions in\n */\n onEnter: PropTypes.func,\n\n /**\n * Callback fired as the Overlay begins to transition in\n */\n onEntering: PropTypes.func,\n\n /**\n * Callback fired after the Overlay finishes transitioning in\n */\n onEntered: PropTypes.func,\n\n /**\n * Callback fired right before the Overlay transitions out\n */\n onExit: PropTypes.func,\n\n /**\n * Callback fired as the Overlay begins to transition out\n */\n onExiting: PropTypes.func,\n\n /**\n * Callback fired after the Overlay finishes transitioning out\n */\n onExited: PropTypes.func,\n\n /**\n * Sets the direction of the Overlay.\n */\n placement: PropTypes.oneOf(['top', 'right', 'bottom', 'left']),\n};\n\nconst defaultProps = {\n animation: Fade,\n rootClose: false,\n show: false,\n placement: 'right',\n};\n\nclass Overlay extends React.Component {\n render() {\n const { animation, children, ...props } = this.props;\n\n const transition = animation === true ? Fade : animation || null;\n\n let child;\n\n if (!transition) {\n child = cloneElement(children, {\n className: classNames(children.props.className, 'in'),\n });\n } else {\n child = children;\n }\n\n return (\n \n {child}\n \n );\n }\n}\n\nOverlay.propTypes = propTypes;\nOverlay.defaultProps = defaultProps;\n\nconst connectedComponent = withTranslation()(Overlay);\nexport { connectedComponent as Overlay };\nexport default connectedComponent;\n","/**\n * Safe chained function\n *\n * Will only create a new function if needed,\n * otherwise will pass back existing functions or null.\n *\n * @param {function} functions to chain\n * @returns {function|null}\n */\nfunction createChainedFunction(...funcs) {\n return funcs\n .filter(f => f != null)\n .reduce((acc, f) => {\n if (typeof f !== 'function') {\n throw new Error(\n 'Invalid Argument Type, must only provide functions, undefined, or null.'\n );\n }\n\n if (acc === null) {\n return f;\n }\n\n return function chainedFunction(...args) {\n acc.apply(this, args);\n f.apply(this, args);\n };\n }, null);\n}\n\nexport default createChainedFunction;\n","import contains from 'dom-helpers/query/contains';\nimport React, { cloneElement } from 'react';\nimport PropTypes from 'prop-types';\nimport ReactDOM from 'react-dom';\nimport warning from 'warning';\n\nimport { Overlay } from './Overlay';\n\nimport createChainedFunction from './createChainedFunction';\n\n/**\n * Check if value one is inside or equal to the of value\n *\n * @param {string} one\n * @param {string|array} of\n * @returns {boolean}\n */\nfunction isOneOf(one, of) {\n if (Array.isArray(of)) {\n return of.indexOf(one) >= 0;\n }\n return one === of;\n}\n\nconst triggerType = PropTypes.oneOf(['click', 'hover', 'focus']);\n\nconst propTypes = {\n /**\n * Specify which action or actions trigger Overlay visibility\n */\n trigger: PropTypes.oneOfType([triggerType, PropTypes.arrayOf(triggerType)]),\n\n /**\n * A millisecond delay amount to show and hide the Overlay once triggered\n */\n delay: PropTypes.number,\n /**\n * A millisecond delay amount before showing the Overlay once triggered.\n */\n delayShow: PropTypes.number,\n /**\n * A millisecond delay amount before hiding the Overlay once triggered.\n */\n delayHide: PropTypes.number,\n\n // FIXME: This should be `defaultShow`.\n /**\n * The initial visibility state of the Overlay. For more nuanced visibility\n * control, consider using the Overlay component directly.\n */\n defaultOverlayShown: PropTypes.bool,\n\n /**\n * An element or text to overlay next to the target.\n */\n overlay: PropTypes.node.isRequired,\n\n /**\n * A function to be called once the hide is triggered\n */\n handleHide: PropTypes.func,\n\n /**\n * @private\n */\n onBlur: PropTypes.func,\n /**\n * @private\n */\n onClick: PropTypes.func,\n /**\n * @private\n */\n onFocus: PropTypes.func,\n /**\n * @private\n */\n onMouseOut: PropTypes.func,\n /**\n * @private\n */\n onMouseOver: PropTypes.func,\n\n // Overridden props from ``.\n /**\n * @private\n */\n target: PropTypes.oneOf([null]),\n /**\n * @private\n */\n onHide: PropTypes.oneOf([null]),\n /**\n * @private\n */\n show: PropTypes.oneOf([null]),\n};\n\nconst defaultProps = {\n defaultOverlayShown: false,\n trigger: ['hover', 'focus'],\n};\n\nclass OverlayTrigger extends React.Component {\n constructor(props, context) {\n super(props, context);\n\n this.handleToggle = this.handleToggle.bind(this);\n this.handleDelayedShow = this.handleDelayedShow.bind(this);\n this.handleDelayedHide = this.handleDelayedHide.bind(this);\n this.handleHide = createChainedFunction(\n this.handleHide.bind(this),\n props.handleHide\n );\n\n this.handleMouseOver = e =>\n this.handleMouseOverOut(this.handleDelayedShow, e, 'fromElement');\n this.handleMouseOut = e =>\n this.handleMouseOverOut(this.handleDelayedHide, e, 'toElement');\n\n this._mountNode = null;\n\n this.state = {\n show: props.defaultOverlayShown,\n };\n }\n\n componentDidMount() {\n this._mountNode = document.createElement('div');\n this.renderOverlay();\n }\n\n componentDidUpdate() {\n this.renderOverlay();\n }\n\n componentWillUnmount() {\n ReactDOM.unmountComponentAtNode(this._mountNode);\n this._mountNode = null;\n\n clearTimeout(this._hoverShowDelay);\n clearTimeout(this._hoverHideDelay);\n }\n\n handleDelayedHide() {\n if (this._hoverShowDelay != null) {\n clearTimeout(this._hoverShowDelay);\n this._hoverShowDelay = null;\n return;\n }\n\n if (!this.state.show || this._hoverHideDelay != null) {\n return;\n }\n\n const delay =\n this.props.delayHide != null ? this.props.delayHide : this.props.delay;\n\n if (!delay) {\n this.hide();\n return;\n }\n\n this._hoverHideDelay = setTimeout(() => {\n this._hoverHideDelay = null;\n this.hide();\n }, delay);\n }\n\n handleDelayedShow() {\n if (this._hoverHideDelay != null) {\n clearTimeout(this._hoverHideDelay);\n this._hoverHideDelay = null;\n return;\n }\n\n if (this.state.show || this._hoverShowDelay != null) {\n return;\n }\n\n const delay =\n this.props.delayShow != null ? this.props.delayShow : this.props.delay;\n\n if (!delay) {\n this.show();\n return;\n }\n\n this._hoverShowDelay = setTimeout(() => {\n this._hoverShowDelay = null;\n this.show();\n }, delay);\n }\n\n handleHide() {\n this.hide();\n }\n\n // Simple implementation of mouseEnter and mouseLeave.\n // React's built version is broken: https://github.com/facebook/react/issues/4251\n // for cases when the trigger is disabled and mouseOut/Over can cause flicker\n // moving from one child element to another.\n handleMouseOverOut(handler, e, relatedNative) {\n const target = e.currentTarget;\n const related = e.relatedTarget || e.nativeEvent[relatedNative];\n\n if ((!related || related !== target) && !contains(target, related)) {\n handler(e);\n }\n }\n\n handleToggle() {\n if (this.state.show) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n hide() {\n this.setState({ show: false });\n }\n\n makeOverlay(overlay, props) {\n return (\n \n {overlay}\n \n );\n }\n\n show() {\n this.setState({ show: true });\n }\n\n renderOverlay() {\n ReactDOM.unstable_renderSubtreeIntoContainer(\n this,\n this._overlay,\n this._mountNode\n );\n }\n\n render() {\n const {\n trigger,\n overlay,\n children,\n onBlur,\n onClick,\n onFocus,\n onMouseOut,\n onMouseOver,\n ...props\n } = this.props;\n\n delete props.delay;\n delete props.delayShow;\n delete props.delayHide;\n delete props.defaultOverlayShown;\n\n const child = React.Children.only(children);\n const childProps = child.props;\n const triggerProps = {};\n\n if (this.state.show) {\n triggerProps['aria-describedby'] = overlay.props.id;\n }\n\n // FIXME: The logic here for passing through handlers on this component is\n // inconsistent. We shouldn't be passing any of these props through.\n\n triggerProps.onClick = createChainedFunction(childProps.onClick, onClick);\n\n if (isOneOf('click', trigger)) {\n triggerProps.onClick = createChainedFunction(\n triggerProps.onClick,\n this.handleToggle\n );\n }\n\n if (isOneOf('hover', trigger)) {\n warning(\n !(trigger === 'hover'),\n '[react-bootstrap] Specifying only the `\"hover\"` trigger limits the ' +\n 'visibility of the overlay to just mouse users. Consider also ' +\n 'including the `\"focus\"` trigger so that touch and keyboard only ' +\n 'users can see the overlay as well.'\n );\n\n triggerProps.onMouseOver = createChainedFunction(\n childProps.onMouseOver,\n onMouseOver,\n this.handleMouseOver\n );\n triggerProps.onMouseOut = createChainedFunction(\n childProps.onMouseOut,\n onMouseOut,\n this.handleMouseOut\n );\n }\n\n if (isOneOf('focus', trigger)) {\n triggerProps.onFocus = createChainedFunction(\n childProps.onFocus,\n onFocus,\n this.handleDelayedShow\n );\n triggerProps.onBlur = createChainedFunction(\n childProps.onBlur,\n onBlur,\n this.handleDelayedHide\n );\n }\n\n this._overlay = this.makeOverlay(overlay, props);\n\n return cloneElement(child, triggerProps);\n }\n}\n\nOverlayTrigger.propTypes = propTypes;\nOverlayTrigger.defaultProps = defaultProps;\n\nexport { OverlayTrigger };\n","export { Overlay } from './Overlay.js';\nexport { OverlayTrigger } from './OverlayTrigger.js';\n","import React, { useContext } from 'react';\nimport { useSelector } from 'react-redux';\nimport { getActiveContexts } from '../store/layout/selectors.js';\n\nlet AppContext = React.createContext({});\n\nexport const CONTEXTS = {\n CORNERSTONE: 'ACTIVE_VIEWPORT::CORNERSTONE',\n VTK: 'ACTIVE_VIEWPORT::VTK'\n};\n\nexport const useAppContext = () => useContext(AppContext);\n\nexport const AppProvider = ({ children, config }) => {\n const activeContexts = useSelector(state => getActiveContexts(state));\n\n return (\n \n {children}\n \n );\n};\n\nexport const withAppContext = Component => {\n return function WrappedComponent(props) {\n const { appConfig, activeContexts } = useAppContext();\n return (\n \n );\n };\n};\n\nexport default AppContext;\n","import './Tooltip.styl';\n\nimport classNames from 'classnames';\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nconst propTypes = {\n /** Sets the direction the Tooltip is positioned towards. */\n placement: PropTypes.oneOf(['top', 'right', 'bottom', 'left']),\n\n /** The \"top\" position value for the Tooltip. */\n positionTop: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n /** The \"left\" position value for the Tooltip. */\n positionLeft: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n\n /** The \"top\" position value for the Tooltip arrow. */\n arrowOffsetTop: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n /** The \"left\" position value for the Tooltip arrow. */\n arrowOffsetLeft: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n};\n\nconst defaultProps = {\n placement: 'right',\n};\n\nclass Tooltip extends React.Component {\n render() {\n const {\n placement,\n positionTop,\n positionLeft,\n arrowOffsetTop,\n arrowOffsetLeft,\n className,\n style,\n children,\n } = this.props;\n\n const outerStyle = {\n top: positionTop,\n left: positionLeft,\n ...style,\n };\n\n const arrowStyle = {\n top: arrowOffsetTop,\n left: arrowOffsetLeft,\n };\n\n return (\n \n
    \n
    {children}
    \n
    \n );\n }\n}\n\nTooltip.propTypes = propTypes;\nTooltip.defaultProps = defaultProps;\n\nexport { Tooltip };\n","export { Tooltip } from './Tooltip.js';\n","import { api } from 'dicomweb-client';\nimport DICOMWeb from '../../DICOMWeb';\nimport str2ab from '../str2ab';\n\nimport errorHandler from '../../errorHandler';\nimport getXHRRetryRequestHook from '../xhrRetryRequestHook';\n\nexport default async function fetchPaletteColorLookupTableData(\n instance,\n server\n) {\n const {\n PaletteColorLookupTableUID,\n RedPaletteColorLookupTableDescriptor,\n GreenPaletteColorLookupTableDescriptor,\n BluePaletteColorLookupTableDescriptor,\n RedPaletteColorLookupTableData,\n GreenPaletteColorLookupTableData,\n BluePaletteColorLookupTableData,\n } = instance;\n\n return new Promise((resolve, reject) => {\n let entry;\n if (_paletteColorCache.isValidUID(PaletteColorLookupTableUID)) {\n entry = _paletteColorCache.get(PaletteColorLookupTableUID);\n\n if (entry) {\n return resolve(entry);\n }\n }\n\n // no entry in cache... Fetch remote data.\n const promises = [\n _getPaletteColor(\n server,\n RedPaletteColorLookupTableData,\n RedPaletteColorLookupTableDescriptor\n ),\n _getPaletteColor(\n server,\n GreenPaletteColorLookupTableData,\n GreenPaletteColorLookupTableDescriptor\n ),\n _getPaletteColor(\n server,\n BluePaletteColorLookupTableData,\n BluePaletteColorLookupTableDescriptor\n ),\n ];\n\n Promise.all(promises).then(\n ([\n RedPaletteColorLookupTableData,\n GreenPaletteColorLookupTableData,\n BluePaletteColorLookupTableData,\n ]) => {\n // when PaletteColorLookupTableUID is present, the entry can be cached...\n _paletteColorCache.add({\n RedPaletteColorLookupTableData,\n GreenPaletteColorLookupTableData,\n BluePaletteColorLookupTableData,\n PaletteColorLookupTableUID,\n });\n\n instance.RedPaletteColorLookupTableData = RedPaletteColorLookupTableData;\n instance.GreenPaletteColorLookupTableData = GreenPaletteColorLookupTableData;\n instance.BluePaletteColorLookupTableData = BluePaletteColorLookupTableData;\n\n resolve();\n }\n );\n });\n}\n\n/**\n * Simple cache schema for retrieved color palettes.\n */\nconst _paletteColorCache = {\n count: 0,\n maxAge: 24 * 60 * 60 * 1000, // 24h cache?\n entries: {},\n isValidUID: function(PaletteColorLookupTableUID) {\n return (\n typeof PaletteColorLookupTableUID === 'string' &&\n PaletteColorLookupTableUID.length > 0\n );\n },\n get: function(PaletteColorLookupTableUID) {\n let entry = null;\n if (this.entries.hasOwnProperty(PaletteColorLookupTableUID)) {\n entry = this.entries[PaletteColorLookupTableUID];\n // check how the entry is...\n if (Date.now() - entry.time > this.maxAge) {\n // entry is too old... remove entry.\n delete this.entries[PaletteColorLookupTableUID];\n this.count--;\n entry = null;\n }\n }\n return entry;\n },\n add: function(entry) {\n if (this.isValidUID(entry.uid)) {\n let PaletteColorLookupTableUID = entry.uid;\n if (this.entries.hasOwnProperty(PaletteColorLookupTableUID) !== true) {\n this.count++; // increment cache entry count...\n }\n entry.time = Date.now();\n this.entries[PaletteColorLookupTableUID] = entry;\n // @TODO: Add logic to get rid of old entries and reduce memory usage...\n }\n },\n};\n\nfunction _getPaletteColor(server, paletteColorLookupTableData, lutDescriptor) {\n const numLutEntries = lutDescriptor[0] ? lutDescriptor[0] : 65536;\n const bits = lutDescriptor[2];\n\n const arrayBufferToPaletteColorLUT = arraybuffer => {\n const byteArray = bits === 16 ?\n new Uint16Array(arraybuffer) :\n new Uint8Array(arraybuffer);\n const lut = [];\n\n for (let i = 0; i < numLutEntries; i++) {\n lut[i] = byteArray[i];\n }\n\n return lut;\n };\n\n if (paletteColorLookupTableData.BulkDataURI) {\n let uri = paletteColorLookupTableData.BulkDataURI;\n\n // TODO: Workaround for dcm4chee behind SSL-terminating proxy returning\n // incorrect bulk data URIs\n if (server.wadoRoot.indexOf('https') === 0 && !uri.includes('https')) {\n uri = uri.replace('http', 'https');\n }\n\n const config = {\n url: server.wadoRoot, //BulkDataURI is absolute, so this isn't used\n headers: DICOMWeb.getAuthorizationHeader(server),\n errorInterceptor: errorHandler.getHTTPErrorHandler(),\n requestHooks: [getXHRRetryRequestHook()],\n };\n const dicomWeb = new api.DICOMwebClient(config);\n const options = {\n BulkDataURI: uri,\n };\n\n return dicomWeb\n .retrieveBulkData(options)\n .then(result => result[0])\n .then(arrayBufferToPaletteColorLUT);\n } else if (paletteColorLookupTableData.InlineBinary) {\n const inlineBinaryData = atob(paletteColorLookupTableData.InlineBinary);\n const arraybuffer = str2ab(inlineBinaryData);\n\n return new Promise(resolve => {\n resolve(arrayBufferToPaletteColorLUT(arraybuffer));\n });\n } else {\n return Promise.resolve(\n arrayBufferToPaletteColorLUT(paletteColorLookupTableData)\n );\n }\n}\n","export default function unpackOverlay(arrayBuffer) {\n const bitArray = new Uint8Array(arrayBuffer);\n const byteArray = new Uint8Array(8 * bitArray.length);\n\n for (let byteIndex = 0; byteIndex < byteArray.length; byteIndex++) {\n const bitIndex = byteIndex % 8;\n const bitByteIndex = Math.floor(byteIndex / 8);\n byteArray[byteIndex] =\n 1 * ((bitArray[bitByteIndex] & (1 << bitIndex)) >> bitIndex);\n }\n\n return byteArray;\n}\n","import { api } from 'dicomweb-client';\nimport DICOMWeb from '../../DICOMWeb';\nimport str2ab from '../str2ab';\nimport unpackOverlay from './unpackOverlay';\n\nimport errorHandler from '../../errorHandler';\nimport getXHRRetryRequestHook from '../xhrRetryRequestHook';\n\nexport default async function fetchOverlayData(instance, server) {\n const OverlayDataPromises = [];\n const OverlayDataTags = [];\n\n return new Promise((resolve, reject) => {\n for (let overlayGroup = 0x00; overlayGroup <= 0x1e; overlayGroup += 0x02) {\n let groupStr = `60${overlayGroup.toString(16)}`;\n\n if (groupStr.length === 3) {\n groupStr = `600${overlayGroup.toString(16)}`;\n }\n\n const OverlayDataTag = `${groupStr}3000`;\n\n if (instance[OverlayDataTag] && instance[OverlayDataTag].InlineBinary) {\n const inlineBinaryData = atob(instance[OverlayDataTag].InlineBinary);\n const arraybuffer = str2ab(inlineBinaryData);\n\n instance[OverlayDataTag] = unpackOverlay(arraybuffer);\n } else if (\n instance[OverlayDataTag] &&\n instance[OverlayDataTag].BulkDataURI\n ) {\n OverlayDataPromises.push(\n _getOverlayData(instance[OverlayDataTag], server)\n );\n OverlayDataTags.push(OverlayDataTag);\n } else if (\n instance[OverlayDataTag] &&\n instance[OverlayDataTag] instanceof ArrayBuffer\n ) {\n instance[OverlayDataTag] = unpackOverlay(instance[OverlayDataTag]);\n }\n }\n\n if (OverlayDataPromises.length) {\n Promise.all(OverlayDataPromises).then(results => {\n for (let i = 0; i < results.length; i++) {\n instance[OverlayDataTags[i]] = results[i];\n }\n\n resolve();\n });\n } else {\n resolve();\n }\n });\n}\n\nasync function _getOverlayData(tag, server) {\n const { BulkDataURI } = tag;\n\n let uri = BulkDataURI;\n\n // TODO: Workaround for dcm4chee behind SSL-terminating proxy returning\n // incorrect bulk data URIs\n if (server.wadoRoot.indexOf('https') === 0 && !uri.includes('https')) {\n uri = uri.replace('http', 'https');\n }\n\n const config = {\n url: server.wadoRoot, //BulkDataURI is absolute, so this isn't used\n headers: DICOMWeb.getAuthorizationHeader(server),\n errorInterceptor: errorHandler.getHTTPErrorHandler(),\n requestHooks: [getXHRRetryRequestHook()],\n };\n const dicomWeb = new api.DICOMwebClient(config);\n const options = {\n BulkDataURI: uri,\n };\n\n return dicomWeb\n .retrieveBulkData(options)\n .then(result => result[0])\n .then(unpackOverlay);\n}\n","const validNumber = val => {\n if (Array.isArray(val)) {\n return val.map(v => (v !== undefined ? Number(v) : v));\n } else {\n return val !== undefined ? Number(val) : val;\n }\n};\n\nexport default validNumber;\n","import dcmjs from 'dcmjs';\nimport queryString from 'query-string';\nimport dicomParser from 'dicom-parser';\nimport getPixelSpacingInformation from '../utils/metadataProvider/getPixelSpacingInformation';\nimport fetchPaletteColorLookupTableData from '../utils/metadataProvider/fetchPaletteColorLookupTableData';\nimport fetchOverlayData from '../utils/metadataProvider/fetchOverlayData';\nimport validNumber from '../utils/metadataProvider/validNumber';\n\nclass MetadataProvider {\n constructor() {\n // Define the main \"metadataLookup\" private property as an immutable property.\n Object.defineProperty(this, 'studies', {\n configurable: false,\n enumerable: false,\n writable: false,\n value: new Map(),\n });\n Object.defineProperty(this, 'imageIdToUIDs', {\n configurable: false,\n enumerable: false,\n writable: false,\n value: new Map(),\n });\n this.datasets = {};\n }\n\n async addInstance(dicomJSONDatasetOrP10ArrayBuffer, options = {}) {\n let dicomJSONDataset;\n\n // If Arraybuffer, parse to DICOMJSON before naturalizing.\n if (dicomJSONDatasetOrP10ArrayBuffer instanceof ArrayBuffer) {\n const dicomData = DicomMessage.readFile(dicomJSONDatasetOrP10ArrayBuffer);\n\n dicomJSONDataset = dicomData.dict;\n } else {\n dicomJSONDataset = dicomJSONDatasetOrP10ArrayBuffer;\n }\n\n // Check if dataset is already naturalized.\n\n let naturalizedDataset;\n\n if (dicomJSONDataset['SeriesInstanceUID'] === undefined) {\n naturalizedDataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(\n dicomJSONDataset\n );\n } else {\n naturalizedDataset = dicomJSONDataset;\n }\n\n const {\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID,\n } = naturalizedDataset;\n\n this._getAndCacheStudyDataset(StudyInstanceUID, dicomJSONDataset);\n const study = this._getAndCacheStudy(StudyInstanceUID);\n const series = this._getAndCacheSeriesFromStudy(study, SeriesInstanceUID);\n const instance = this._getAndCacheInstanceFromStudy(series, SOPInstanceUID);\n\n Object.assign(instance, naturalizedDataset);\n\n await this._checkBulkDataAndInlineBinaries(instance, options.server);\n\n return instance;\n }\n\n addImageIdToUIDs(imageId, uids) {\n // This method is a fallback for when you don't have WADO-URI or WADO-RS.\n // You can add instances fetched by any method by calling addInstance, and hook an imageId to point at it here.\n // An example would be dicom hosted at some random site.\n\n this.imageIdToUIDs.set(imageId, uids);\n }\n\n _getAndCacheStudyDataset(StudyInstanceUID, dataset) {\n if (!this.datasets[StudyInstanceUID]) {\n this.datasets[StudyInstanceUID] = dataset;\n }\n }\n\n getStudyDataset(StudyInstanceUID) {\n return this.datasets[StudyInstanceUID];\n }\n\n _getAndCacheStudy(StudyInstanceUID) {\n const studies = this.studies;\n\n let study = studies.get(StudyInstanceUID);\n\n if (!study) {\n study = { series: new Map() };\n studies.set(StudyInstanceUID, study);\n }\n\n return study;\n }\n\n _getAndCacheSeriesFromStudy(study, SeriesInstanceUID) {\n let series = study.series.get(SeriesInstanceUID);\n\n if (!series) {\n series = { instances: new Map() };\n study.series.set(SeriesInstanceUID, series);\n }\n\n return series;\n }\n\n _getAndCacheInstanceFromStudy(series, SOPInstanceUID) {\n let instance = series.instances.get(SOPInstanceUID);\n\n if (!instance) {\n instance = {};\n series.instances.set(SOPInstanceUID, instance);\n }\n\n return instance;\n }\n\n async _checkBulkDataAndInlineBinaries(instance, server) {\n await fetchOverlayData(instance, server);\n\n if (instance.PhotometricInterpretation === 'PALETTE COLOR') {\n await fetchPaletteColorLookupTableData(instance, server);\n }\n }\n\n _getInstance(imageId) {\n const uids = this._getUIDsFromImageID(imageId);\n\n if (!uids) {\n return;\n }\n\n const { StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID } = uids;\n\n return this._getInstanceData(\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID\n );\n }\n\n get(query, imageId, options = { fallback: false }) {\n const instance = this._getInstance(imageId);\n\n if (query === INSTANCE) {\n return instance;\n }\n\n return this.getTagFromInstance(query, instance, options);\n }\n\n getTag(query, imageId, options) {\n return this.get(query, imageId, options);\n }\n\n getInstance(imageId) {\n return this.get(INSTANCE, imageId);\n }\n\n getTagFromInstance(\n naturalizedTagOrWADOImageLoaderTag,\n instance,\n options = { fallback: false }\n ) {\n if (!instance) {\n return;\n }\n\n // If its a naturalized dcmjs tag present on the instance, return.\n if (instance[naturalizedTagOrWADOImageLoaderTag]) {\n return instance[naturalizedTagOrWADOImageLoaderTag];\n }\n\n // Maybe its a legacy CornerstoneWADOImageLoader tag then:\n return this._getCornerstoneWADOImageLoaderTag(\n naturalizedTagOrWADOImageLoaderTag,\n instance\n );\n }\n\n _getCornerstoneWADOImageLoaderTag(wadoImageLoaderTag, instance) {\n let metadata;\n\n switch (wadoImageLoaderTag) {\n case WADO_IMAGE_LOADER_TAGS.GENERAL_SERIES_MODULE:\n const { SeriesDate, SeriesTime } = instance;\n\n let seriesDate;\n let seriesTime;\n\n if (SeriesDate) {\n seriesDate = dicomParser.parseDA(SeriesDate);\n }\n\n if (SeriesTime) {\n seriesTime = dicomParser.parseTM(SeriesTime);\n }\n\n metadata = {\n modality: instance.Modality,\n seriesInstanceUID: instance.SeriesInstanceUID,\n seriesNumber: instance.SeriesNumber,\n studyInstanceUID: instance.StudyInstanceUID,\n seriesDate,\n seriesTime,\n };\n break;\n case WADO_IMAGE_LOADER_TAGS.PATIENT_STUDY_MODULE:\n metadata = {\n patientAge: instance.PatientAge,\n patientSize: instance.PatientSize,\n patientWeight: instance.PatientWeight,\n };\n break;\n case WADO_IMAGE_LOADER_TAGS.IMAGE_PLANE_MODULE:\n const { ImageOrientationPatient } = instance;\n\n // Fallback for DX images.\n // TODO: We should use the rest of the results of this function\n // to update the UI somehow\n const { PixelSpacing } = getPixelSpacingInformation(instance);\n\n let rowPixelSpacing;\n let columnPixelSpacing;\n\n let rowCosines;\n let columnCosines;\n\n if (PixelSpacing) {\n rowPixelSpacing = validNumber(PixelSpacing[0]);\n columnPixelSpacing = validNumber(PixelSpacing[1]);\n }\n\n if (ImageOrientationPatient) {\n rowCosines = validNumber(ImageOrientationPatient.slice(0, 3));\n columnCosines = validNumber(ImageOrientationPatient.slice(3, 6));\n }\n\n metadata = {\n frameOfReferenceUID: instance.FrameOfReferenceUID,\n rows: instance.Rows,\n columns: instance.Columns,\n imageOrientationPatient: validNumber(ImageOrientationPatient),\n rowCosines,\n columnCosines,\n imagePositionPatient: validNumber(instance.ImagePositionPatient),\n sliceThickness: validNumber(instance.SliceThickness),\n sliceLocation: validNumber(instance.SliceLocation),\n pixelSpacing: validNumber(PixelSpacing),\n rowPixelSpacing,\n columnPixelSpacing,\n };\n break;\n case WADO_IMAGE_LOADER_TAGS.IMAGE_PIXEL_MODULE:\n metadata = {\n samplesPerPixel: instance.SamplesPerPixel,\n photometricInterpretation: instance.PhotometricInterpretation,\n rows: instance.Rows,\n columns: instance.Columns,\n bitsAllocated: instance.BitsAllocated,\n bitsStored: instance.BitsStored,\n highBit: instance.HighBit,\n pixelRepresentation: instance.PixelRepresentation,\n planarConfiguration: instance.PlanarConfiguration,\n pixelAspectRatio: instance.PixelAspectRatio,\n smallestPixelValue: instance.SmallestPixelValue,\n largestPixelValue: instance.LargestPixelValue,\n redPaletteColorLookupTableDescriptor:\n instance.RedPaletteColorLookupTableDescriptor,\n greenPaletteColorLookupTableDescriptor:\n instance.GreenPaletteColorLookupTableDescriptor,\n bluePaletteColorLookupTableDescriptor:\n instance.BluePaletteColorLookupTableDescriptor,\n redPaletteColorLookupTableData:\n instance.RedPaletteColorLookupTableData,\n greenPaletteColorLookupTableData:\n instance.GreenPaletteColorLookupTableData,\n bluePaletteColorLookupTableData:\n instance.BluePaletteColorLookupTableData,\n };\n\n break;\n case WADO_IMAGE_LOADER_TAGS.VOI_LUT_MODULE:\n let { WindowCenter, WindowWidth } = instance;\n\n const windowCenter = Array.isArray(WindowCenter)\n ? WindowCenter\n : [WindowCenter];\n const windowWidth = Array.isArray(WindowWidth)\n ? WindowWidth\n : [WindowWidth];\n\n metadata = {\n windowCenter: validNumber(windowCenter),\n windowWidth: validNumber(windowWidth),\n };\n\n break;\n case WADO_IMAGE_LOADER_TAGS.MODALITY_LUT_MODULE:\n const rescaleSlope = validNumber(instance.RescaleSlope);\n const rescaleIntercept = validNumber(instance.RescaleIntercept);\n metadata = {\n rescaleIntercept,\n rescaleSlope,\n rescaleType: instance.RescaleType,\n };\n break;\n case WADO_IMAGE_LOADER_TAGS.SOP_COMMON_MODULE:\n metadata = {\n sopClassUID: instance.SOPClassUID,\n sopInstanceUID: instance.SOPInstanceUID,\n };\n break;\n case WADO_IMAGE_LOADER_TAGS.PET_ISOTOPE_MODULE:\n const { RadiopharmaceuticalInformationSequence } = instance;\n\n if (RadiopharmaceuticalInformationSequence) {\n const RadiopharmaceuticalInformation = Array.isArray(\n RadiopharmaceuticalInformationSequence\n )\n ? RadiopharmaceuticalInformationSequence[0]\n : RadiopharmaceuticalInformationSequence;\n\n const {\n RadiopharmaceuticalStartTime,\n RadionuclideTotalDose,\n RadionuclideHalfLife,\n } = RadiopharmaceuticalInformation;\n\n const radiopharmaceuticalInfo = {\n radiopharmaceuticalStartTime: dicomParser.parseTM(\n RadiopharmaceuticalStartTime\n ),\n radionuclideTotalDose: RadionuclideTotalDose,\n radionuclideHalfLife: RadionuclideHalfLife,\n };\n metadata = {\n radiopharmaceuticalInfo,\n };\n }\n\n break;\n case WADO_IMAGE_LOADER_TAGS.OVERLAY_PLANE_MODULE:\n const overlays = [];\n\n for (\n let overlayGroup = 0x00;\n overlayGroup <= 0x1e;\n overlayGroup += 0x02\n ) {\n let groupStr = `60${overlayGroup.toString(16)}`;\n\n if (groupStr.length === 3) {\n groupStr = `600${overlayGroup.toString(16)}`;\n }\n\n const OverlayDataTag = `${groupStr}3000`;\n const OverlayData = instance[OverlayDataTag];\n\n if (!OverlayData) {\n continue;\n }\n\n const OverlayRowsTag = `${groupStr}0010`;\n const OverlayColumnsTag = `${groupStr}0011`;\n const OverlayType = `${groupStr}0040`;\n const OverlayOriginTag = `${groupStr}0050`;\n const OverlayDescriptionTag = `${groupStr}0022`;\n const OverlayLabelTag = `${groupStr}1500`;\n const ROIAreaTag = `${groupStr}1301`;\n const ROIMeanTag = `${groupStr}1302`;\n const ROIStandardDeviationTag = `${groupStr}1303`;\n const OverlayOrigin = instance[OverlayOriginTag];\n\n const overlay = {\n rows: instance[OverlayRowsTag],\n columns: instance[OverlayColumnsTag],\n type: instance[OverlayType],\n x: OverlayOrigin[0],\n y: OverlayOrigin[1],\n pixelData: OverlayData,\n description: instance[OverlayDescriptionTag],\n label: instance[OverlayLabelTag],\n roiArea: instance[ROIAreaTag],\n roiMean: instance[ROIMeanTag],\n roiStandardDeviation: instance[ROIStandardDeviationTag],\n };\n\n overlays.push(overlay);\n }\n\n metadata = {\n overlays,\n };\n\n break;\n\n case WADO_IMAGE_LOADER_TAGS.PATIENT_MODULE:\n const { PatientName } = instance;\n\n let patientName;\n if (PatientName) {\n patientName = PatientName.Alphabetic;\n }\n\n metadata = {\n patientName,\n patientId: instance.PatientID,\n };\n\n break;\n\n case WADO_IMAGE_LOADER_TAGS.GENERAL_IMAGE_MODULE:\n metadata = {\n sopInstanceUid: instance.SOPInstanceUID,\n instanceNumber: instance.InstanceNumber,\n lossyImageCompression: instance.LossyImageCompression,\n lossyImageCompressionRatio: instance.LossyImageCompressionRatio,\n lossyImageCompressionMethod: instance.LossyImageCompressionMethod,\n };\n\n break;\n case WADO_IMAGE_LOADER_TAGS.GENERAL_STUDY_MODULE:\n metadata = {\n studyDescription: instance.StudyDescription,\n studyDate: instance.StudyDate,\n studyTime: instance.StudyTime,\n accessionNumber: instance.AccessionNumber,\n };\n\n break;\n case WADO_IMAGE_LOADER_TAGS.CINE_MODULE:\n metadata = {\n frameTime: instance.FrameTime,\n };\n\n break;\n }\n\n return metadata;\n }\n\n _getInstanceData(StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID) {\n const study = this.studies.get(StudyInstanceUID);\n\n if (!study) {\n return;\n }\n\n const series = study.series.get(SeriesInstanceUID);\n\n if (!series) {\n return;\n }\n\n const instance = series.instances.get(SOPInstanceUID);\n\n return instance;\n }\n\n _getUIDsFromImageID(imageId) {\n if (imageId.includes('wadors:')) {\n const strippedImageId = imageId.split('studies/')[1];\n const splitImageId = strippedImageId.split('/');\n\n return {\n StudyInstanceUID: splitImageId[0], // Note: splitImageId[1] === 'series'\n SeriesInstanceUID: splitImageId[2], // Note: splitImageId[3] === 'instances'\n SOPInstanceUID: splitImageId[4],\n };\n }\n if (imageId.includes('wado?requestType=WADO')) {\n const qs = queryString.parse(imageId);\n\n return {\n StudyInstanceUID: qs.studyUID,\n SeriesInstanceUID: qs.seriesUID,\n SOPInstanceUID: qs.objectUID,\n };\n } else {\n // Maybe its a non-standard imageId\n return this.imageIdToUIDs.get(imageId);\n }\n }\n}\n\nconst metadataProvider = new MetadataProvider();\n\nexport default metadataProvider;\n\nconst WADO_IMAGE_LOADER_TAGS = {\n // CornerstoneWADOImageLoader specific\n GENERAL_SERIES_MODULE: 'generalSeriesModule',\n PATIENT_STUDY_MODULE: 'patientStudyModule',\n IMAGE_PLANE_MODULE: 'imagePlaneModule',\n IMAGE_PIXEL_MODULE: 'imagePixelModule',\n VOI_LUT_MODULE: 'voiLutModule',\n MODALITY_LUT_MODULE: 'modalityLutModule',\n SOP_COMMON_MODULE: 'sopCommonModule',\n PET_ISOTOPE_MODULE: 'petIsotopeModule',\n OVERLAY_PLANE_MODULE: 'overlayPlaneModule',\n\n // react-cornerstone-viewport specifc\n PATIENT_MODULE: 'patientModule',\n GENERAL_IMAGE_MODULE: 'generalImageModule',\n GENERAL_STUDY_MODULE: 'generalStudyModule',\n CINE_MODULE: 'cineModule',\n};\n\nconst INSTANCE = 'instance';\n","import log from '../../log';\n\nexport default function getPixelSpacingInformation(instance) {\n // See http://gdcm.sourceforge.net/wiki/index.php/Imager_Pixel_Spacing\n\n // TODO: Add Ultrasound region spacing\n // TODO: Add manual calibration\n\n // TODO: Use ENUMS from dcmjs\n const projectionRadiographSOPClassUIDs = [\n '1.2.840.10008.5.1.4.1.1.1', //\tCR Image Storage\n '1.2.840.10008.5.1.4.1.1.1.1', //\tDigital X-Ray Image Storage – for Presentation\n '1.2.840.10008.5.1.4.1.1.1.1.1', //\tDigital X-Ray Image Storage – for Processing\n '1.2.840.10008.5.1.4.1.1.1.2', //\tDigital Mammography X-Ray Image Storage – for Presentation\n '1.2.840.10008.5.1.4.1.1.1.2.1', //\tDigital Mammography X-Ray Image Storage – for Processing\n '1.2.840.10008.5.1.4.1.1.1.3', //\tDigital Intra – oral X-Ray Image Storage – for Presentation\n '1.2.840.10008.5.1.4.1.1.1.3.1', //\tDigital Intra – oral X-Ray Image Storage – for Processing\n '1.2.840.10008.5.1.4.1.1.12.1', //\tX-Ray Angiographic Image Storage\n '1.2.840.10008.5.1.4.1.1.12.1.1', //\tEnhanced XA Image Storage\n '1.2.840.10008.5.1.4.1.1.12.2', //\tX-Ray Radiofluoroscopic Image Storage\n '1.2.840.10008.5.1.4.1.1.12.2.1', //\tEnhanced XRF Image Storage\n '1.2.840.10008.5.1.4.1.1.12.3', // X-Ray Angiographic Bi-plane Image Storage\tRetired\n ];\n\n const {\n PixelSpacing,\n ImagerPixelSpacing,\n SOPClassUID,\n PixelSpacingCalibrationType,\n PixelSpacingCalibrationDescription,\n EstimatedRadiographicMagnificationFactor,\n SequenceOfUltrasoundRegions,\n } = instance;\n const isProjection = projectionRadiographSOPClassUIDs.includes(SOPClassUID);\n\n const TYPES = {\n NOT_APPLICABLE: 'NOT_APPLICABLE',\n UNKNOWN: 'UNKNOWN',\n CALIBRATED: 'CALIBRATED',\n DETECTOR: 'DETECTOR',\n };\n\n if (isProjection && !ImagerPixelSpacing) {\n // If only Pixel Spacing is present, and this is a projection radiograph,\n // PixelSpacing should be used, but the user should be informed that\n // what it means is unknown\n return {\n PixelSpacing,\n type: TYPES.UNKNOWN,\n isProjection,\n };\n } else if (\n PixelSpacing &&\n ImagerPixelSpacing &&\n PixelSpacing === ImagerPixelSpacing\n ) {\n // If Imager Pixel Spacing and Pixel Spacing are present and they have the same values,\n // then the user should be informed that the measurements are at the detector plane\n return {\n PixelSpacing,\n type: TYPES.DETECTOR,\n isProjection,\n };\n } else if (\n PixelSpacing &&\n ImagerPixelSpacing &&\n PixelSpacing !== ImagerPixelSpacing\n ) {\n // If Imager Pixel Spacing and Pixel Spacing are present and they have different values,\n // then the user should be informed that these are \"calibrated\"\n // (in some unknown manner if Pixel Spacing Calibration Type and/or\n // Pixel Spacing Calibration Description are absent)\n return {\n PixelSpacing,\n type: TYPES.CALIBRATED,\n isProjection,\n PixelSpacingCalibrationType,\n PixelSpacingCalibrationDescription,\n };\n } else if (!PixelSpacing && ImagerPixelSpacing) {\n let CorrectedImagerPixelSpacing = ImagerPixelSpacing;\n if (EstimatedRadiographicMagnificationFactor) {\n // Note that in IHE Mammo profile compliant displays, the value of Imager Pixel Spacing is required to be corrected by\n // Estimated Radiographic Magnification Factor and the user informed of that.\n // TODO: should this correction be done before all of this logic?\n CorrectedImagerPixelSpacing = ImagerPixelSpacing.map(\n pixelSpacing => pixelSpacing / EstimatedRadiographicMagnificationFactor\n );\n } else {\n log.info(\n 'EstimatedRadiographicMagnificationFactor was not present. Unable to correct ImagerPixelSpacing.'\n );\n }\n\n return {\n PixelSpacing: CorrectedImagerPixelSpacing,\n isProjection,\n };\n } else if (\n SequenceOfUltrasoundRegions &&\n typeof SequenceOfUltrasoundRegions === 'object'\n ) {\n const { PhysicalDeltaX, PhysicalDeltaY } = SequenceOfUltrasoundRegions;\n const USPixelSpacing = [PhysicalDeltaX * 10, PhysicalDeltaY * 10];\n\n return {\n PixelSpacing: USPixelSpacing,\n };\n } else if (\n SequenceOfUltrasoundRegions &&\n Array.isArray(SequenceOfUltrasoundRegions) &&\n SequenceOfUltrasoundRegions.length > 1\n ) {\n log.warn(\n 'Sequence of Ultrasound Regions > one entry. This is not yet implemented, all measurements will be shown in pixels.'\n );\n } else if (isProjection === false && !ImagerPixelSpacing) {\n // If only Pixel Spacing is present, and this is not a projection radiograph,\n // we can stop here\n return {\n PixelSpacing,\n type: TYPES.NOT_APPLICABLE,\n isProjection,\n };\n }\n\n log.info(\n 'Unknown combination of PixelSpacing and ImagerPixelSpacing identified. Unable to determine spacing.'\n );\n}\n","/**\n * adds a pause and unpause method to Mousetrap\n * this allows you to enable or disable keyboard shortcuts\n * without having to reset Mousetrap and rebind everything\n *\n * https://github.com/ccampbell/mousetrap/blob/master/plugins/pause/mousetrap-pause.js\n */\nexport default function(Mousetrap) {\n var _originalStopCallback = Mousetrap.prototype.stopCallback;\n\n Mousetrap.prototype.stopCallback = function(e, element, combo) {\n var self = this;\n\n if (self.paused) {\n return true;\n }\n\n return _originalStopCallback.call(self, e, element, combo);\n };\n\n Mousetrap.prototype.pause = function() {\n var self = this;\n self.paused = true;\n };\n\n Mousetrap.prototype.unpause = function() {\n var self = this;\n self.paused = false;\n };\n\n Mousetrap.init();\n}\n","/**\n * This extension allows you to record a sequence using Mousetrap.\n * {@link https://craig.is/killing/mice}\n *\n * @author Dan Tao \n */\nexport default function(Mousetrap) {\n /**\n * the sequence currently being recorded\n *\n * @type {Array}\n */\n var _recordedSequence = [],\n /**\n * a callback to invoke after recording a sequence\n *\n * @type {Function|null}\n */\n _recordedSequenceCallback = null,\n /**\n * a list of all of the keys currently held down\n *\n * @type {Array}\n */\n _currentRecordedKeys = [],\n /**\n * temporary state where we remember if we've already captured a\n * character key in the current combo\n *\n * @type {boolean}\n */\n _recordedCharacterKey = false,\n /**\n * a handle for the timer of the current recording\n *\n * @type {null|number}\n */\n _recordTimer = null,\n /**\n * the original handleKey method to override when Mousetrap.record() is\n * called\n *\n * @type {Function}\n */\n _origHandleKey = Mousetrap.prototype.handleKey;\n\n /**\n * handles a character key event\n *\n * @param {string} character\n * @param {Array} modifiers\n * @param {Event} e\n * @returns void\n */\n function _handleKey(character, modifiers, e) {\n var self = this;\n\n if (!self.recording) {\n _origHandleKey.apply(self, arguments);\n return;\n }\n\n // remember this character if we're currently recording a sequence\n if (e.type == 'keydown') {\n if (character.length === 1 && _recordedCharacterKey) {\n _recordCurrentCombo();\n }\n\n for (let i = 0; i < modifiers.length; ++i) {\n _recordKey(modifiers[i]);\n }\n _recordKey(character);\n\n // once a key is released, all keys that were held down at the time\n // count as a keypress\n } else if (e.type == 'keyup' && _currentRecordedKeys.length > 0) {\n _recordCurrentCombo();\n }\n }\n\n /**\n * marks a character key as held down while recording a sequence\n *\n * @param {string} key\n * @returns void\n */\n function _recordKey(key) {\n // one-off implementation of Array.indexOf, since IE6-9 don't support it\n for (let i = 0; i < _currentRecordedKeys.length; ++i) {\n if (_currentRecordedKeys[i] === key) {\n return;\n }\n }\n\n _currentRecordedKeys.push(key);\n\n if (key.length === 1) {\n _recordedCharacterKey = true;\n }\n }\n\n /**\n * marks whatever key combination that's been recorded so far as finished\n * and gets ready for the next combo\n *\n * @returns void\n */\n function _recordCurrentCombo() {\n _recordedSequence.push(_currentRecordedKeys);\n _currentRecordedKeys = [];\n _recordedCharacterKey = false;\n _finishRecording();\n }\n\n /**\n * ensures each combo in a sequence is in a predictable order and formats\n * key combos to be '+'-delimited\n *\n * modifies the sequence in-place\n *\n * @param {Array} sequence\n * @returns void\n */\n function _normalizeSequence(sequence) {\n for (let i = 0; i < sequence.length; ++i) {\n sequence[i].sort(function(x, y) {\n // modifier keys always come first, in alphabetical order\n if (x.length > 1 && y.length === 1) {\n return -1;\n } else if (x.length === 1 && y.length > 1) {\n return 1;\n }\n\n // character keys come next (list should contain no duplicates,\n // so no need for equality check)\n return x > y ? 1 : -1;\n });\n\n sequence[i] = sequence[i].join('+');\n }\n }\n\n /**\n * finishes the current recording, passes the recorded sequence to the stored\n * callback, and sets Mousetrap.handleKey back to its original function\n *\n * @returns void\n */\n function _finishRecording() {\n if (_recordedSequenceCallback) {\n _normalizeSequence(_recordedSequence);\n _recordedSequenceCallback(_recordedSequence);\n }\n\n // reset all recorded state\n _recordedSequence = [];\n _recordedSequenceCallback = null;\n _currentRecordedKeys = [];\n }\n\n /**\n * called to set a 1 second timeout on the current recording\n *\n * this is so after each key press in the sequence the recording will wait for\n * 1 more second before executing the callback\n *\n * @returns void\n */\n function _restartRecordTimer() {\n clearTimeout(_recordTimer);\n _recordTimer = setTimeout(_finishRecording, 1000);\n }\n\n /**\n * records the next sequence and passes it to a callback once it's\n * completed\n *\n * @param {Function} callback\n * @returns void\n */\n Mousetrap.prototype.record = function(callback) {\n var self = this;\n self.recording = true;\n _recordedSequenceCallback = function() {\n self.recording = false;\n callback.apply(self, arguments);\n };\n };\n\n /**\n * stop recording\n *\n * @param {Function} callback\n * @returns void\n */\n Mousetrap.prototype.stopRecord = function() {\n var self = this;\n self.recording = false;\n };\n\n /**\n * start recording\n *\n * @param {Function} callback\n * @returns void\n */\n Mousetrap.prototype.startRecording = function() {\n var self = this;\n self.recording = true;\n };\n\n Mousetrap.prototype.handleKey = function() {\n var self = this;\n _handleKey.apply(self, arguments);\n };\n\n Mousetrap.init();\n}\n","import Mousetrap from 'mousetrap';\nimport pausePlugin from './pausePlugin';\nimport recordPlugin from './recordPlugin';\n\nrecordPlugin(Mousetrap);\npausePlugin(Mousetrap);\n\nexport default Mousetrap;\n","const ReconstructionIssues = {\n DATASET_4D: 'datasetis4D',\n VARYING_IMAGESDIMENSIONS: 'imagesdimensionsvarying',\n VARYING_IMAGESCOMPONENTS: 'imagescomponentsvarying',\n VARYING_IMAGESORIENTATION: 'imagesorientationvarying',\n MISSING_FRAMES: 'missingframes',\n IRREGULAR_SPACING: 'irregularspacing',\n MULTIFFRAMES: 'multiframe',\n};\n\nexport {ReconstructionIssues};\n","import { TypeSafeCollection } from '../classes/TypeSafeCollection';\n\nconst studyMetadataList = new TypeSafeCollection();\n\nfunction add(studyMetadata) {\n studyMetadataList.insert(studyMetadata);\n}\n\nfunction get(studyInstanceUID) {\n return studyMetadataList.findBy({ studyInstanceUID });\n}\n\nfunction all(options) {\n return studyMetadataList.all(options);\n}\n\nfunction remove(studyInstanceUID) {\n studyMetadataList.remove({ studyInstanceUID });\n}\n\nfunction purge() {\n studyMetadataList.removeAll();\n}\n\nexport default {\n add,\n get,\n all,\n remove,\n purge,\n};\n","import { InstanceMetadata } from './InstanceMetadata';\nimport getImageId from '../../utils/getImageId.js';\n\nexport class OHIFInstanceMetadata extends InstanceMetadata {\n /**\n * @param {Object} Instance object.\n */\n constructor(data, series, study, uid) {\n super(data, uid);\n this.init(series, study);\n }\n\n init(series, study) {\n const instance = this.getData();\n\n // Initialize Private Properties\n Object.defineProperties(this, {\n _sopInstanceUID: {\n configurable: false,\n enumerable: false,\n writable: false,\n value: instance.SOPInstanceUID,\n },\n _study: {\n configurable: false,\n enumerable: false,\n writable: false,\n value: study,\n },\n _series: {\n configurable: false,\n enumerable: false,\n writable: false,\n value: series,\n },\n _instance: {\n configurable: false,\n enumerable: false,\n writable: false,\n value: instance,\n },\n _cache: {\n configurable: false,\n enumerable: false,\n writable: false,\n value: Object.create(null),\n },\n });\n }\n\n // Override\n getTagValue(tagOrProperty, defaultValue, bypassCache) {\n // check if this property has been cached...\n if (tagOrProperty in this._cache && bypassCache !== true) {\n return this._cache[tagOrProperty];\n }\n\n const instanceData = this._instance.metadata;\n\n // Search property value in the whole study metadata chain...\n let rawValue;\n if (tagOrProperty in instanceData) {\n rawValue = instanceData[tagOrProperty];\n } else if (tagOrProperty in this._series) {\n rawValue = this._series[tagOrProperty];\n } else if (tagOrProperty in this._study) {\n rawValue = this._study[tagOrProperty];\n }\n\n if (rawValue !== void 0) {\n // if rawValue value is not undefined, cache result...\n this._cache[tagOrProperty] = rawValue;\n return rawValue;\n }\n\n return defaultValue;\n }\n\n // Override\n tagExists(tagOrProperty) {\n return (\n tagOrProperty in this._instance.metadata ||\n tagOrProperty in this._series ||\n tagOrProperty in this._study\n );\n }\n\n // Override\n getImageId(frame, thumbnail) {\n // If _imageID is not cached, create it\n if (this._imageId === null) {\n this._imageId = getImageId(this.getData(), frame, thumbnail);\n }\n\n return this._imageId;\n }\n}\n","import { SeriesMetadata } from './SeriesMetadata';\nimport { OHIFInstanceMetadata } from './OHIFInstanceMetadata';\n\nexport class OHIFSeriesMetadata extends SeriesMetadata {\n /**\n * @param {Object} Series object.\n */\n constructor(data, study, uid) {\n super(data, uid);\n this.init(study);\n }\n\n init(study) {\n const series = this.getData();\n\n // define \"_seriesInstanceUID\" protected property...\n Object.defineProperty(this, '_seriesInstanceUID', {\n configurable: false,\n enumerable: false,\n writable: false,\n value: series.SeriesInstanceUID,\n });\n\n // populate internal list of instances...\n series.instances.forEach(instance => {\n this.addInstance(new OHIFInstanceMetadata(instance, series, study));\n });\n }\n}\n","import { StudyMetadata } from './StudyMetadata';\nimport { OHIFSeriesMetadata } from './OHIFSeriesMetadata';\n\nexport class OHIFStudyMetadata extends StudyMetadata {\n /**\n * @param {Object} Study object.\n */\n constructor(data, uid) {\n super(data, uid);\n this.init();\n }\n\n init() {\n const study = this.getData();\n\n // define \"_studyInstanceUID\" protected property\n Object.defineProperty(this, '_studyInstanceUID', {\n configurable: false,\n enumerable: false,\n writable: false,\n value: study.StudyInstanceUID,\n });\n\n // populate internal list of series\n study.series.forEach(series => {\n this.addSeries(new OHIFSeriesMetadata(series, study));\n });\n }\n}\n","import { InstanceMetadata } from './InstanceMetadata';\nimport { Metadata } from './Metadata';\nimport { OHIFInstanceMetadata } from './OHIFInstanceMetadata';\nimport { OHIFSeriesMetadata } from './OHIFSeriesMetadata';\nimport { OHIFStudyMetadata } from './OHIFStudyMetadata';\nimport { SeriesMetadata } from './SeriesMetadata';\nimport { StudyMetadata } from './StudyMetadata';\n\nconst metadata = {\n Metadata,\n StudyMetadata,\n SeriesMetadata,\n InstanceMetadata,\n OHIFStudyMetadata,\n OHIFSeriesMetadata,\n OHIFInstanceMetadata,\n};\n\nexport {\n Metadata,\n StudyMetadata,\n SeriesMetadata,\n InstanceMetadata,\n OHIFStudyMetadata,\n OHIFSeriesMetadata,\n OHIFInstanceMetadata,\n};\n\nexport default metadata;\n","import { ReconstructionIssues } from './../enums.js';\n\n/**\n * Checks if a series is reconstructable to a 3D volume.\n *\n * @param {Object[]} An array of `OHIFInstanceMetadata` objects.\n *\n * @returns {Object} value, reconstructionIssues.\n */\nfunction isDisplaySetReconstructable(instances) {\n if (!instances.length) {\n return { value: false };\n }\n\n const firstInstance = instances[0].getData().metadata;\n\n const Modality = firstInstance.Modality;\n const isMultiframe = firstInstance.NumberOfFrames > 1;\n\n if (!constructableModalities.includes(Modality)) {\n return { value: false };\n }\n\n // Can't reconstruct if we only have one image.\n if (!isMultiframe && instances.length === 1) {\n return { value: false };\n }\n\n if (isMultiframe) {\n return processMultiframe();\n } else {\n return processSingleframe(instances);\n }\n}\n\n/**\n * Process reconstructable multiframes checks\n * TODO: deal with multriframe checks! return false for now as can't reconstruct.\n * *\n * @returns {Object} value and reconstructionIssues.\n */\nfunction processMultiframe() {\n const reconstructionIssues = [ReconstructionIssues.MULTIFRAMES];\n return { value: false, reconstructionIssues };\n}\n\n/**\n * Process reconstructable single frame checks\n *\n * @param {Object[]} An array of `OHIFInstanceMetadata` objects.\n *\n * @returns {Object} value and reconstructionIssues.\n */\nfunction processSingleframe(instances) {\n const n = instances.length;\n const firstImage = instances[0].getData().metadata;\n const firstImageRows = firstImage.Rows;\n const firstImageColumns = firstImage.Columns;\n const firstImageSamplesPerPixel = firstImage.SamplesPerPixel;\n const firstImageOrientationPatient = firstImage.ImageOrientationPatient;\n\n const reconstructionIssues = [];\n // Can't reconstruct if we:\n // -- Have a different dimensions within a displaySet.\n // -- Have a different number of components within a displaySet.\n // -- Have different orientations within a displaySet.\n for (let ii = 1; ii < n; ++ii) {\n const instance = instances[ii].getData().metadata;\n const {\n Rows,\n Columns,\n SamplesPerPixel,\n ImageOrientationPatient,\n } = instance;\n\n if (Rows !== firstImageRows || Columns !== firstImageColumns) {\n reconstructionIssues.push(ReconstructionIssues.VARYING_IMAGESDIMENSIONS);\n } else if (SamplesPerPixel !== firstImageSamplesPerPixel) {\n reconstructionIssues.push(ReconstructionIssues.VARYING_IMAGESCOMPONENTS);\n } else if (\n !_isSameArray(ImageOrientationPatient, firstImageOrientationPatient)\n ) {\n reconstructionIssues.push(ReconstructionIssues.VARYING_IMAGESORIENTATION);\n }\n\n if (reconstructionIssues.length !== 0) {\n break;\n }\n }\n\n // check if dataset is 4D\n if (_isDataset4D(instances)) {\n reconstructionIssues.push(ReconstructionIssues.DATASET_4D);\n }\n\n return {\n value: reconstructionIssues.length === 0 ? true : false,\n reconstructionIssues,\n };\n}\n\n/**\n * Check is the spacing is uniform.\n * The input metadata array has to be ordered by image position.\n *\n * @param {Object[]} An array of `OHIFInstanceMetadata` objects.\n * @param {boolean} is the dataset 4D.\n *\n * @returns {Object} isUniform, reconstructionIssues and missingFrames\n */\nfunction isSpacingUniform(instances, datasetIs4D) {\n const n = instances.length;\n const firstImage = instances[0].getData().metadata;\n const firstImagePositionPatient = firstImage.ImagePositionPatient;\n\n const reconstructionIssues = [];\n let missingFrames = 0;\n\n // Check if frame spacing is approximately equal within a spacingTolerance.\n // If spacing is on a uniform grid but we are missing frames,\n // Allow reconstruction, but pass back the number of missing frames.\n if (n > 2) {\n const lastIpp = instances[n - 1].getData().metadata.ImagePositionPatient;\n\n // We can't reconstruct if we are missing ImagePositionPatient values\n if (firstImagePositionPatient && lastIpp) {\n const averageSpacingBetweenFrames =\n _getPerpendicularDistance(firstImagePositionPatient, lastIpp) / (n - 1);\n\n let previousImagePositionPatient = firstImagePositionPatient;\n\n for (let ii = 1; ii < n; ++ii) {\n const instance = instances[ii].getData().metadata;\n const { ImagePositionPatient } = instance;\n\n const spacingBetweenFrames = _getPerpendicularDistance(\n ImagePositionPatient,\n previousImagePositionPatient\n );\n\n if (datasetIs4D && spacingBetweenFrames < 1e-3) {\n // the dataset is 4D, if the distance is zero, means that we are\n // checking the 4th dimension. Do not return, since we want still to\n // check the 3rd dimension spacing.\n continue;\n }\n\n const spacingIssue = _getSpacingIssue(\n spacingBetweenFrames,\n averageSpacingBetweenFrames\n );\n\n if (spacingIssue) {\n const issue = spacingIssue.issue;\n\n if (issue === ReconstructionIssues.MISSING_FRAMES) {\n missingFrames += spacingIssue.missingFrames;\n } else if (issue === ReconstructionIssues.IRREGULAR_SPACING) {\n reconstructionIssues.push(issue);\n break;\n }\n }\n\n previousImagePositionPatient = ImagePositionPatient;\n }\n }\n }\n\n return {\n isUniform: reconstructionIssues.length === 0 ? true : false,\n missingFrames,\n reconstructionIssues,\n };\n}\n\n/**\n * Check if 4D dataset.\n *\n * Assuming that slices at different time have the same position, here we just check if\n * there are multiple slices for the same ImagePositionPatient and disable MPR.\n *\n * A better heuristic would be checking 4D tags, e.g. the presence of multiple TemporalPositionIdentifier values.\n * However, some studies (e.g. https://github.com/OHIF/Viewers/issues/2113) do not have such tags.\n *\n * @param {Object[]} instances An array of `OHIFInstanceMetadata` objects.\n *\n * @returns {boolean} dataset4D value.\n */\nfunction _isDataset4D(instances) {\n const n = instances.length;\n for (let ii = 0; ii < n; ++ii) {\n const instanceMetadataControl = instances[ii].getData().metadata;\n if (\n !instanceMetadataControl ||\n instanceMetadataControl === undefined ||\n !instanceMetadataControl.ImagePositionPatient ||\n instanceMetadataControl.ImagePositionPatient === undefined\n ) {\n continue;\n }\n for (let jj = ii + 1; jj < n; ++jj) {\n const instanceMetadata = instances[jj].getData().metadata;\n if (\n !instanceMetadata ||\n instanceMetadata === undefined ||\n !instanceMetadata.ImagePositionPatient ||\n instanceMetadata.ImagePositionPatient === undefined\n ) {\n continue;\n }\n\n if (\n _isSameArray(\n instanceMetadataControl.ImagePositionPatient,\n instanceMetadata.ImagePositionPatient\n )\n ) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nfunction _isSameArray(iop1, iop2) {\n if (iop1 === undefined || !iop2 === undefined) {\n return;\n }\n\n return (\n Math.abs(iop1[0] - iop2[0]) < iopTolerance &&\n Math.abs(iop1[1] - iop2[1]) < iopTolerance &&\n Math.abs(iop1[2] - iop2[2]) < iopTolerance\n );\n}\n\n// TODO: Is 10% a reasonable spacingTolerance for spacing?\nconst spacingTolerance = 0.1;\nconst iopTolerance = 0.01;\n\n/**\n * Checks for spacing issues.\n *\n * @param {number} spacing The spacing between two frames.\n * @param {number} averageSpacing The average spacing between all frames.\n *\n * @returns {Object} An object containing the issue and extra information if necessary.\n */\nfunction _getSpacingIssue(spacing, averageSpacing) {\n const equalWithinTolerance =\n Math.abs(spacing - averageSpacing) < averageSpacing * spacingTolerance;\n\n if (equalWithinTolerance) {\n return;\n }\n\n const multipleOfAverageSpacing = spacing / averageSpacing;\n\n const numberOfSpacings = Math.round(multipleOfAverageSpacing);\n\n const errorForEachSpacing =\n Math.abs(spacing - numberOfSpacings * averageSpacing) / numberOfSpacings;\n\n if (errorForEachSpacing < spacingTolerance * averageSpacing) {\n return {\n issue: ReconstructionIssues.MISSING_FRAMES,\n missingFrames: numberOfSpacings - 1,\n };\n }\n\n return { issue: ReconstructionIssues.IRREGULAR_SPACING };\n}\n\nfunction _getPerpendicularDistance(a, b) {\n return Math.sqrt(\n Math.pow(a[0] - b[0], 2) +\n Math.pow(a[1] - b[1], 2) +\n Math.pow(a[2] - b[2], 2)\n );\n}\n\nconst constructableModalities = ['MR', 'CT', 'PT', 'NM'];\n\nexport { isDisplaySetReconstructable, isSpacingUniform };\n","// - createStacks\nimport DICOMWeb from './../../DICOMWeb';\nimport ImageSet from './../ImageSet';\nimport { InstanceMetadata } from './InstanceMetadata';\nimport { Metadata } from './Metadata';\nimport { SeriesMetadata } from './SeriesMetadata';\n// - createStacks\nimport { api } from 'dicomweb-client';\n// - createStacks\nimport { isImage } from '../../utils/isImage';\nimport { naturalizeSOPClassUID } from '../../utils/naturalizeSOPClassUID';\nimport {\n isDisplaySetReconstructable,\n isSpacingUniform,\n} from '../../utils/isDisplaySetReconstructable';\nimport errorHandler from '../../errorHandler';\nimport isLowPriorityModality from '../../utils/isLowPriorityModality';\nimport getXHRRetryRequestHook from '../../utils/xhrRetryRequestHook';\n\nclass StudyMetadata extends Metadata {\n constructor(data, uid) {\n super(data, uid);\n // Initialize Private Properties\n Object.defineProperties(this, {\n _studyInstanceUID: {\n configurable: true, // configurable so that it can be redefined in sub-classes...\n enumerable: false,\n writable: true,\n value: null,\n },\n _series: {\n configurable: false,\n enumerable: false,\n writable: false,\n value: [],\n },\n _displaySets: {\n configurable: false,\n enumerable: false,\n writable: false,\n value: [],\n },\n _derivedDisplaySets: {\n configurable: false,\n enumerable: false,\n writable: false,\n value: [],\n },\n _firstSeries: {\n configurable: false,\n enumerable: false,\n writable: true,\n value: null,\n },\n _firstInstance: {\n configurable: false,\n enumerable: false,\n writable: true,\n value: null,\n },\n });\n // Initialize Public Properties\n this._definePublicProperties();\n }\n\n /**\n * Private Methods\n */\n\n /**\n * Define Public Properties\n * This method should only be called during initialization (inside the class constructor)\n */\n _definePublicProperties() {\n /**\n * Property: this.studyInstanceUID\n * Same as this.getStudyInstanceUID()\n * It's specially useful in contexts where a method call is not suitable like in search criteria. For example:\n * studyCollection.findBy({\n * studyInstanceUID: '1.2.3.4.5.6.77777.8888888.99999999999.0'\n * });\n */\n Object.defineProperty(this, 'studyInstanceUID', {\n configurable: false,\n enumerable: false,\n get: function() {\n return this.getStudyInstanceUID();\n },\n });\n }\n\n /**\n * Public Methods\n */\n\n /**\n * Getter for displaySets\n * @return {Array} Array of display set object\n */\n getDisplaySets() {\n return this._displaySets.slice();\n }\n\n /**\n * Split a series metadata object into display sets\n * @param {Array} sopClassHandlerModules List of SOP Class Modules\n * @param {SeriesMetadata} series The series metadata object from which the display sets will be created\n * @returns {Array} The list of display sets created for the given series object\n */\n _createDisplaySetsForSeries(sopClassHandlerModules, series) {\n const study = this;\n const displaySets = [];\n\n const anyInstances = series.getInstanceCount() > 0;\n\n if (!anyInstances) {\n const displaySet = new ImageSet([]);\n const seriesData = series.getData();\n\n displaySet.setAttributes({\n displaySetInstanceUID: displaySet.uid,\n SeriesInstanceUID: seriesData.SeriesInstanceUID,\n SeriesDescription: seriesData.SeriesDescription,\n SeriesNumber: seriesData.SeriesNumber,\n Modality: seriesData.Modality,\n });\n\n displaySets.push(displaySet);\n\n return displaySets;\n }\n\n const sopClassUIDs = getSopClassUIDs(series);\n\n if (sopClassHandlerModules && sopClassHandlerModules.length > 0) {\n const displaySet = _getDisplaySetFromSopClassModule(\n sopClassHandlerModules,\n series,\n study,\n sopClassUIDs\n );\n\n if (displaySet) {\n displaySet.sopClassModule = true;\n\n if (displaySet.isDerived) {\n this._addDerivedDisplaySet(displaySet);\n }\n\n displaySets.push(displaySet);\n\n return displaySets;\n }\n }\n\n // WE NEED A BETTER WAY TO NOTE THAT THIS IS THE DEFAULT BEHAVIOR FOR LOADING\n // A DISPLAY SET IF THERE IS NO MATCHING SOP CLASS PLUGIN\n\n // Search through the instances (InstanceMetadata object) of this series\n // Split Multi-frame instances and Single-image modalities\n // into their own specific display sets. Place the rest of each\n // series into another display set.\n const stackableInstances = [];\n series.forEachInstance(instance => {\n let displaySet;\n\n // All imaging modalities must have a valid value for SOPClassUID (x00080016) or Rows (x00280010)\n if (\n !isImage(instance.getTagValue('SOPClassUID')) &&\n !instance.getTagValue('Rows')\n ) {\n // we set an empty display and we add a isSOPClassUIDSupported variable to\n // print a warning that the series is not supported in the thumbnail.\n // SOPClassUIDNaturalized is human readable name, since for non image series,\n // we could have a mismatch between the SOPClassUID and the Modality.\n // For example, in the Parametric map IOD Modality is expected to match\n // the value for the series used to generate Parametric map, and there is no \"PM\" modality.\n const displaySet = new ImageSet([]);\n const seriesData = series.getData();\n displaySet.setAttributes({\n displaySetInstanceUID: displaySet.uid,\n SeriesDate: seriesData.SeriesDate,\n SeriesTime: seriesData.SeriesTime,\n SeriesInstanceUID: series.getSeriesInstanceUID(),\n SeriesNumber: instance.getTagValue('SeriesNumber'),\n SeriesDescription: instance.getTagValue('SeriesDescription'),\n numImageFrames: instance.getTagValue('NumberOfFrames'),\n frameRate: instance.getTagValue('FrameTime'),\n Modality: instance.getTagValue('Modality'),\n isMultiFrame: false,\n StudyInstanceUID: study.getStudyInstanceUID(), // Include the study instance UID\n InstanceNumber: instance.getTagValue('InstanceNumber'), // Include the instance number\n AcquisitionDatetime: instance.getTagValue('AcquisitionDateTime'), // Include the acquisition datetime\n isReconstructable: false,\n isSOPClassUIDSupported: false,\n SOPClassUIDNaturalized: naturalizeSOPClassUID(\n instance.getTagValue('SOPClassUID')\n ),\n metadata: instance.getData().metadata,\n });\n\n displaySets.push(displaySet);\n } else {\n if (isMultiFrame(instance)) {\n displaySet = makeDisplaySet(series, [instance]);\n\n displaySet.setAttributes({\n sopClassUIDs,\n isClip: true,\n SeriesInstanceUID: series.getSeriesInstanceUID(),\n StudyInstanceUID: study.getStudyInstanceUID(), // Include the study instance UID for drag/drop purposes\n numImageFrames: instance.getTagValue('NumberOfFrames'), // Override the default value of instances.length\n InstanceNumber: instance.getTagValue('InstanceNumber'), // Include the instance number\n AcquisitionDatetime: instance.getTagValue('AcquisitionDateTime'), // Include the acquisition datetime\n });\n displaySets.push(displaySet);\n } else if (isSingleImageModality(instance.Modality)) {\n displaySet = makeDisplaySet(series, [instance]);\n displaySet.setAttributes({\n sopClassUIDs,\n StudyInstanceUID: study.getStudyInstanceUID(), // Include the study instance UID\n SeriesInstanceUID: series.getSeriesInstanceUID(),\n InstanceNumber: instance.getTagValue('InstanceNumber'), // Include the instance number\n AcquisitionDatetime: instance.getTagValue('AcquisitionDateTime'), // Include the acquisition datetime\n });\n displaySets.push(displaySet);\n } else {\n stackableInstances.push(instance);\n }\n }\n });\n\n if (stackableInstances.length) {\n const displaySet = makeDisplaySet(series, stackableInstances);\n displaySet.setAttribute('StudyInstanceUID', study.getStudyInstanceUID());\n displaySet.setAttributes({\n sopClassUIDs,\n });\n displaySets.push(displaySet);\n }\n\n return displaySets;\n }\n\n /**\n * Adds the displaySets to the studies list of derived displaySets.\n * @param {object} displaySet The displaySet to append to the derived displaysets list.\n */\n _addDerivedDisplaySet(displaySet) {\n this._derivedDisplaySets.push(displaySet);\n // --> Perhaps that logic should exist in the extension sop class handler and this be a dumb list.\n // TODO -> Get x Modality by referencedSeriesInstanceUid, FoR, etc.\n }\n\n /**\n * Adds the displaySets to the studies list of derived displaySets.\n * @param {array} displaySets The displaySets array to append to the derived displaysets list.\n */\n _addDerivedDisplaySets(displaySets) {\n displaySets.map(displaySet => this._derivedDisplaySets.push(displaySet));\n }\n\n /**\n * Returns the source display set of the derivated display set.\n * @param {object} derivatedDisplaySet\n * @param {array[StudyMetadata]} studies\n * @return {object} source display set.\n */\n static getReferencedDisplaySet(derivatedDisplaySet, studies) {\n let allDisplaySets = [];\n\n studies.forEach(study => {\n allDisplaySets = allDisplaySets.concat(study.displaySets);\n });\n\n const otherDisplaySets = allDisplaySets.filter(\n ds =>\n ds.displaySetInstanceUID !== derivatedDisplaySet.displaySetInstanceUID\n );\n\n const { metadata } = derivatedDisplaySet;\n\n let referencedSeriesInstanceUIDs = _findReferencedSeriesInstanceUIDsFromSourceImageSequence(\n metadata,\n otherDisplaySets\n );\n\n let noReferencedSeriesAvailable =\n !referencedSeriesInstanceUIDs ||\n referencedSeriesInstanceUIDs.length === 0;\n if (noReferencedSeriesAvailable) {\n referencedSeriesInstanceUIDs = _findReferencedSeriesInstanceUIDsFromReferencedSeriesSequence(\n metadata\n );\n }\n\n noReferencedSeriesAvailable =\n !referencedSeriesInstanceUIDs ||\n referencedSeriesInstanceUIDs.length === 0;\n if (noReferencedSeriesAvailable) {\n referencedSeriesInstanceUIDs = _findReferencedSeriesInstanceUIDsFromReferencedImageSequence(\n metadata,\n otherDisplaySets\n );\n }\n\n const referencedSeriesAvailable =\n referencedSeriesInstanceUIDs && referencedSeriesInstanceUIDs.length !== 0;\n if (referencedSeriesAvailable) {\n const referencedDisplaySet = otherDisplaySets.find(ds =>\n referencedSeriesInstanceUIDs.includes(ds.SeriesInstanceUID)\n );\n return referencedDisplaySet;\n }\n }\n\n /**\n * Returns a list of derived datasets in the study, filtered by the given filter.\n * @param {object} filter An object containing search filters\n * @param {object} filter.Modality\n * @param {object} filter.referencedSeriesInstanceUID\n * @param {object} filter.referencedFrameOfReferenceUID\n * @return {Array} filtered derived display sets\n */\n getDerivedDatasets(filter) {\n const {\n Modality,\n referencedSeriesInstanceUID,\n referencedFrameOfReferenceUID,\n } = filter;\n\n let filteredDerivedDisplaySets = this._derivedDisplaySets;\n\n if (Modality) {\n filteredDerivedDisplaySets = filteredDerivedDisplaySets.filter(\n displaySet => displaySet.Modality === Modality\n );\n }\n\n if (referencedSeriesInstanceUID) {\n filteredDerivedDisplaySets = filteredDerivedDisplaySets.filter(\n displaySet => {\n const referencedDisplaySet = StudyMetadata.getReferencedDisplaySet(\n displaySet,\n [this]\n );\n if (referencedDisplaySet) {\n return (\n referencedDisplaySet.SeriesInstanceUID ===\n referencedSeriesInstanceUID\n );\n } else {\n return false;\n }\n }\n );\n }\n\n if (referencedFrameOfReferenceUID) {\n filteredDerivedDisplaySets = filteredDerivedDisplaySets.filter(\n displaySet =>\n displaySet.FrameOfReferenceUID === referencedFrameOfReferenceUID\n );\n }\n\n return filteredDerivedDisplaySets;\n }\n\n /**\n * Creates a set of displaySets to be placed in the Study Metadata\n * The displaySets that appear in the Study Metadata must represent\n * imaging modalities. A series may be split into one or more displaySets.\n *\n * Furthermore, for drag/drop functionality,\n * it is easiest if the stack objects also contain information about\n * which study they are linked to.\n *\n * @param {StudyMetadata} study The study instance metadata to be used\n * @returns {Array} An array of series to be placed in the Study Metadata\n */\n createDisplaySets(sopClassHandlerModules) {\n const displaySets = [];\n const anyDisplaySets = this.getSeriesCount();\n\n if (!anyDisplaySets) {\n return displaySets;\n }\n\n // Loop through the series (SeriesMetadata)\n this.forEachSeries(series => {\n const displaySetsForSeries = this._createDisplaySetsForSeries(\n sopClassHandlerModules,\n series\n );\n\n displaySetsForSeries.forEach(ds => this._insertDisplaySet(ds));\n });\n\n return this._displaySets;\n }\n\n /**\n * Method to append display sets from a given series to the internal list of display sets\n * @param {Array} sopClassHandlerModules A list of SOP Class Handler Modules\n * @param {SeriesMetadata} series The series metadata object from which the display sets will be created\n * @returns {boolean} Returns true on success or false on failure (e.g., the series does not belong to this study)\n */\n createAndAddDisplaySetsForSeries(sopClassHandlerModules, series) {\n if (!this.containsSeries(series)) {\n return false;\n }\n\n const displaySets = this._createDisplaySetsForSeries(\n sopClassHandlerModules,\n series\n );\n\n // Note: filtering in place because this._displaySets has writable: false\n for (let i = this._displaySets.length - 1; i >= 0; i--) {\n const displaySet = this._displaySets[i];\n if (displaySet.SeriesInstanceUID === series.getSeriesInstanceUID()) {\n this._displaySets.splice(i, 1);\n }\n }\n\n displaySets.forEach(displaySet => {\n this.addDisplaySet(displaySet);\n });\n\n return true;\n }\n\n /**\n * Add a single display set to the list\n * @param {Object} displaySet Display set object\n * @returns {boolean} True on success, false on failure.\n */\n addDisplaySet(displaySet) {\n if (displaySet instanceof ImageSet || displaySet.sopClassModule) {\n this._insertDisplaySet(displaySet);\n return true;\n }\n return false;\n }\n\n /**\n * Invokes the supplied callback for each display set in the current study passing\n * two arguments: display set (a ImageSet instance) and index (the integer\n * index of the display set within the current study)\n * @param {function} callback The callback function which will be invoked for each display set instance.\n * @returns {undefined} Nothing is returned.\n */\n forEachDisplaySet(callback) {\n if (Metadata.isValidCallback(callback)) {\n this._displaySets.forEach((displaySet, index) => {\n callback.call(null, displaySet, index);\n });\n }\n }\n\n /**\n * Insert the displaySet so that the list has an increasing SeriesNumber,\n * with the most recent series first for displaySets with the same SeriesNumber.\n *\n * If the displaySet is low priority, the same logic is applied, but is sorted within a sub list\n * At the end of the list, where all low priority data is found.\n */\n _insertDisplaySet(displaySet) {\n const { SeriesNumber } = displaySet;\n const displaySets = this._displaySets;\n let insertIndex = displaySets.length;\n let firstIndexWithSameSeriesNumber;\n\n // If low priority, start search from next low priority.\n if (isLowPriorityModality(displaySet.Modality)) {\n let startingIndex;\n\n // Find where the first low priority displaySet is.\n for (let i = 0; i < displaySets.length; i++) {\n if (isLowPriorityModality(displaySets[i].Modality)) {\n startingIndex = i;\n break;\n }\n }\n\n if (!startingIndex) {\n startingIndex = displaySets.length;\n }\n\n // Find the correct SeriesNumber location to insert within the low priority\n // Modality displaySets\n for (let i = startingIndex; i < displaySets.length; i++) {\n if (\n displaySets[i].SeriesNumber === SeriesNumber &&\n !firstIndexWithSameSeriesNumber\n ) {\n firstIndexWithSameSeriesNumber = i;\n }\n\n if (displaySets[i].SeriesNumber > SeriesNumber) {\n insertIndex = i;\n break;\n }\n }\n } else {\n // Find correct SeriesNumber to insert or where the low priority modalities start.\n for (let i = 0; i < displaySets.length; i++) {\n if (\n displaySets[i].SeriesNumber === SeriesNumber &&\n !firstIndexWithSameSeriesNumber\n ) {\n firstIndexWithSameSeriesNumber = i;\n }\n\n if (\n displaySets[i].SeriesNumber > SeriesNumber ||\n isLowPriorityModality(displaySets[i].Modality)\n ) {\n insertIndex = i;\n break;\n }\n }\n }\n\n // If we have multiple displaySets with the same series number, find the insert position based on\n // SeriesDate and SeriesTime.\n if (firstIndexWithSameSeriesNumber !== undefined) {\n // If no SeriesDate, is just a placeholder displaySet, just insert anywhere, it will be re-added later.\n if (displaySet.SeriesDate) {\n const seriesDateTime = `${displaySet.SeriesDate}${displaySet.SeriesTime}`;\n\n for (let i = firstIndexWithSameSeriesNumber; i < insertIndex; i++) {\n const displaySetI = displaySets[i];\n\n if (\n displaySetI.SeriesDate &&\n `${displaySetI.SeriesDate}${displaySetI.SeriesTime}` <\n seriesDateTime\n ) {\n insertIndex = i;\n break;\n }\n }\n }\n }\n\n if (\n this._displaySets.some(\n ds => ds.displaySetInstanceUID === displaySet.displaySetInstanceUID\n )\n ) {\n return;\n }\n\n this._displaySets.splice(insertIndex, 0, displaySet);\n this.displaySets = this._displaySets;\n }\n\n /**\n * Search the associated display sets using the supplied callback as criteria. The callback is passed\n * two arguments: display set (an ImageSet instance) and index (the integer\n * index of the display set within the current study)\n * @param {function} callback The callback function which will be invoked for each display set instance.\n * @returns {undefined} Nothing is returned.\n */\n findDisplaySet(callback) {\n if (Metadata.isValidCallback(callback)) {\n return this._displaySets.find((displaySet, index) => {\n return callback.call(null, displaySet, index);\n });\n }\n }\n\n /**\n * Retrieve the number of display sets within the current study.\n * @returns {number} The number of display sets in the current study.\n */\n getDisplaySetCount() {\n return this._displaySets.length;\n }\n\n /**\n * Returns the StudyInstanceUID of the current study.\n */\n getStudyInstanceUID() {\n return this._studyInstanceUID;\n }\n\n /**\n * Getter for series\n * @return {Array} Array of SeriesMetadata object\n */\n getSeries() {\n return this._series.slice();\n }\n\n /**\n * Append a series to the current study.\n * @param {SeriesMetadata} series The series to be added to the current study.\n * @returns {boolean} Returns true on success, false otherwise.\n */\n addSeries(series) {\n let result = false;\n if (\n series instanceof SeriesMetadata &&\n this.getSeriesByUID(series.getSeriesInstanceUID()) === void 0\n ) {\n this._series.push(series);\n result = true;\n }\n return result;\n }\n\n /**\n * Update a series in the current study by SeriesInstanceUID.\n * @param {String} SeriesInstanceUID The SeriesInstanceUID to be updated\n * @param {SeriesMetadata} series The series to be added to the current study.\n * @returns {boolean} Returns true on success, false otherwise.\n */\n updateSeries(SeriesInstanceUID, series) {\n const index = this._series.findIndex(series => {\n return series.getSeriesInstanceUID() === SeriesInstanceUID;\n });\n\n if (index < 0) {\n return false;\n }\n\n if (!(series instanceof SeriesMetadata)) {\n throw new Error('Series must be an instance of SeriesMetadata');\n }\n\n this._series[index] = series;\n\n return true;\n }\n\n /**\n * Find a series by index.\n * @param {number} index An integer representing a list index.\n * @returns {SeriesMetadata} Returns a SeriesMetadata instance when found or undefined otherwise.\n */\n getSeriesByIndex(index) {\n let found; // undefined by default...\n if (Metadata.isValidIndex(index)) {\n found = this._series[index];\n }\n return found;\n }\n\n /**\n * Find a series by SeriesInstanceUID.\n * @param {string} uid An UID string.\n * @returns {SeriesMetadata} Returns a SeriesMetadata instance when found or undefined otherwise.\n */\n getSeriesByUID(uid) {\n let found; // undefined by default...\n if (Metadata.isValidUID(uid)) {\n found = this._series.find(series => {\n return series.getSeriesInstanceUID() === uid;\n });\n }\n return found;\n }\n\n containsSeries(series) {\n return (\n series instanceof SeriesMetadata && this._series.indexOf(series) >= 0\n );\n }\n\n /**\n * Retrieve the number of series within the current study.\n * @returns {number} The number of series in the current study.\n */\n getSeriesCount() {\n return this._series.length;\n }\n\n /**\n * Retrieve the number of instances within the current study.\n * @returns {number} The number of instances in the current study.\n */\n getInstanceCount() {\n return this._series.reduce((sum, series) => {\n return sum + series.getInstanceCount();\n }, 0);\n }\n\n /**\n * Invokes the supplied callback for each series in the current study passing\n * two arguments: series (a SeriesMetadata instance) and index (the integer\n * index of the series within the current study)\n * @param {function} callback The callback function which will be invoked for each series instance.\n * @returns {undefined} Nothing is returned.\n */\n forEachSeries(callback) {\n if (Metadata.isValidCallback(callback)) {\n this._series.forEach((series, index) => {\n callback.call(null, series, index);\n });\n }\n }\n\n /**\n * Find the index of a series inside the study.\n * @param {SeriesMetadata} series An instance of the SeriesMetadata class.\n * @returns {number} The index of the series inside the study or -1 if not found.\n */\n indexOfSeries(series) {\n return this._series.indexOf(series);\n }\n\n /**\n * Compares the current study instance with another one.\n * @param {StudyMetadata} study An instance of the StudyMetadata class.\n * @returns {boolean} Returns true if both instances refer to the same study.\n */\n equals(study) {\n const self = this;\n return (\n study === self ||\n (study instanceof StudyMetadata &&\n study.getStudyInstanceUID() === self.getStudyInstanceUID())\n );\n }\n\n /**\n * Get the first series of the current study retaining a consistent result across multiple calls.\n * @return {SeriesMetadata} An instance of the SeriesMetadata class or null if it does not exist.\n */\n getFirstSeries() {\n let series = this._firstSeries;\n if (!(series instanceof SeriesMetadata)) {\n series = null;\n const found = this.getSeriesByIndex(0);\n if (found instanceof SeriesMetadata) {\n this._firstSeries = found;\n series = found;\n }\n }\n return series;\n }\n\n /**\n * Get the first image id given display instance uid.\n * @return {string} The image id.\n */\n getFirstImageId(displaySetInstanceUID) {\n try {\n const displaySet = this.findDisplaySet(\n displaySet => displaySet.displaySetInstanceUID === displaySetInstanceUID\n );\n return displaySet.images[0].getImageId();\n } catch (error) {\n console.error('Failed to retrieve image metadata');\n return null;\n }\n }\n\n /**\n * Get the first instance of the current study retaining a consistent result across multiple calls.\n * @return {InstanceMetadata} An instance of the InstanceMetadata class or null if it does not exist.\n */\n getFirstInstance() {\n let instance = this._firstInstance;\n if (!(instance instanceof InstanceMetadata)) {\n instance = null;\n const firstSeries = this.getFirstSeries();\n if (firstSeries instanceof SeriesMetadata) {\n const found = firstSeries.getFirstInstance();\n if (found instanceof InstanceMetadata) {\n this._firstInstance = found;\n instance = found;\n }\n }\n }\n return instance;\n }\n\n /**\n * Search the associated series to find an specific instance using the supplied callback as criteria.\n * The callback is passed two arguments: instance (a InstanceMetadata instance) and index (the integer\n * index of the instance within the current series)\n * @param {function} callback The callback function which will be invoked for each instance instance.\n * @returns {Object} Result object containing series (SeriesMetadata) and instance (InstanceMetadata)\n * objects or an empty object if not found.\n */\n findSeriesAndInstanceByInstance(callback) {\n let result;\n\n if (Metadata.isValidCallback(callback)) {\n let instance;\n\n const series = this._series.find(series => {\n instance = series.findInstance(callback);\n return instance instanceof InstanceMetadata;\n });\n\n // No series found\n if (series instanceof SeriesMetadata) {\n result = {\n series,\n instance,\n };\n }\n }\n\n return result || {};\n }\n\n /**\n * Find series by instance using the supplied callback as criteria. The callback is passed\n * two arguments: instance (a InstanceMetadata instance) and index (the integer index of\n * the instance within its series)\n * @param {function} callback The callback function which will be invoked for each instance.\n * @returns {SeriesMetadata|undefined} If a series is found based on callback criteria it\n * returns a SeriesMetadata. \"undefined\" is returned otherwise\n */\n findSeriesByInstance(callback) {\n const result = this.findSeriesAndInstanceByInstance(callback);\n\n return result.series;\n }\n\n /**\n * Find an instance using the supplied callback as criteria. The callback is passed\n * two arguments: instance (a InstanceMetadata instance) and index (the integer index of\n * the instance within its series)\n * @param {function} callback The callback function which will be invoked for each instance.\n * @returns {InstanceMetadata|undefined} If an instance is found based on callback criteria it\n * returns a InstanceMetadata. \"undefined\" is returned otherwise\n */\n findInstance(callback) {\n const result = this.findSeriesAndInstanceByInstance(callback);\n\n return result.instance;\n }\n}\n\n/**\n *\n * @typedef StudyMetadata\n * @property {function} getSeriesCount - returns the number of series in the study\n * @property {function} forEachSeries - function that invokes callback with each series and index\n * @property {function} getStudyInstanceUID - returns the study's instance UID\n *\n */\n\n/**\n * @typedef SeriesMetadata\n * @property {function} getSeriesInstanceUID - returns the series's instance UID\n * @property {function} getData - ???\n * @property {function} forEachInstance - ???\n */\n\nconst dwc = api.DICOMwebClient;\n\nconst isMultiFrame = instance => {\n return instance.getTagValue('NumberOfFrames') > 1;\n};\n\n/**\n * Creates a display set for a series.\n * Checks if a series is reconstructable to a 3D volume.\n * If reconstructable, the frames are sorted.\n *\n * @param {SeriesMetadata} series The series metadata object from which the display sets will be created\n * @param {Object[]} instances An array of `OHIFInstanceMetadata` objects.\n *\n * @returns {Object} imageSet.\n */\nconst makeDisplaySet = (series, instances) => {\n const instance = instances[0];\n const imageSet = new ImageSet(instances);\n const seriesData = series.getData();\n\n // set appropriate attributes to image set...\n imageSet.setAttributes({\n displaySetInstanceUID: imageSet.uid, // create a local alias for the imageSet UID\n SeriesDate: seriesData.SeriesDate,\n SeriesTime: seriesData.SeriesTime,\n SeriesInstanceUID: series.getSeriesInstanceUID(),\n SeriesNumber: instance.getTagValue('SeriesNumber'),\n SeriesDescription: instance.getTagValue('SeriesDescription'),\n numImageFrames: instances.length,\n frameRate: instance.getTagValue('FrameTime'),\n Modality: instance.getTagValue('Modality'),\n isMultiFrame: isMultiFrame(instance),\n });\n\n // Sort the images in this series by instanceNumber\n const shallSort = true; //!OHIF.utils.ObjectPath.get(Meteor, 'settings.public.ui.sortSeriesByIncomingOrder');\n if (shallSort) {\n imageSet.sortBy((a, b) => {\n // Sort by InstanceNumber (0020,0013)\n return (\n (parseInt(a.getTagValue('InstanceNumber', 0)) || 0) -\n (parseInt(b.getTagValue('InstanceNumber', 0)) || 0)\n );\n });\n }\n\n // Include the first image instance number (after sorted)\n imageSet.setAttribute(\n 'InstanceNumber',\n imageSet.getImage(0).getTagValue('InstanceNumber')\n );\n\n const displayReconstructableInfo = isDisplaySetReconstructable(instances);\n imageSet.isReconstructable = displayReconstructableInfo.value;\n\n let displaySpacingInfo = undefined;\n if (shallSort && imageSet.isReconstructable) {\n // sort images by image position\n imageSet.sortByImagePositionPatient();\n\n // check if the spacing is uniform and update isReconstructable\n const datasetIs4D = displayReconstructableInfo.reconstructionIssues.find(\n issue => issue === ReconstructionIssues.DATASET_4D\n );\n displaySpacingInfo = isSpacingUniform(imageSet.images, datasetIs4D);\n imageSet.isReconstructable = displaySpacingInfo.isUniform;\n\n if (displaySpacingInfo.missingFrames) {\n // TODO -> This is currently unused, but may be used for reconstructing\n // Volumes with gaps later on.\n imageSet.missingFrames = displaySpacingInfo.missingFrames;\n }\n }\n\n if (!imageSet.displayReconstructableInfo) {\n // It is not reconstrabale Save type of warning\n imageSet.reconstructionIssues = displaySpacingInfo\n ? displayReconstructableInfo.reconstructionIssues.concat(\n displaySpacingInfo.reconstructionIssues\n )\n : displayReconstructableInfo.reconstructionIssues;\n }\n\n imageSet.isSOPClassUIDSupported = true;\n\n return imageSet;\n};\n\nconst isSingleImageModality = Modality => {\n return Modality === 'CR' || Modality === 'MG' || Modality === 'DX';\n};\n\nfunction getSopClassUIDs(series) {\n const uniqueSopClassUIDsInSeries = new Set();\n series.forEachInstance(instance => {\n const instanceSopClassUID = instance.getTagValue('SOPClassUID');\n\n uniqueSopClassUIDsInSeries.add(instanceSopClassUID);\n });\n const sopClassUIDs = Array.from(uniqueSopClassUIDsInSeries);\n\n return sopClassUIDs;\n}\n\n/**\n * @private\n * @param {SeriesMetadata} series\n * @param {StudyMetadata} study\n * @param {string[]} sopClassUIDs\n */\nfunction _getDisplaySetFromSopClassModule(\n sopClassHandlerExtensions, // TODO: Update Usage\n series,\n study,\n sopClassUIDs\n) {\n // TODO: For now only use the plugins if all instances have the same SOPClassUID\n if (sopClassUIDs.length !== 1) {\n console.warn(\n 'getDisplaySetFromSopClassPlugin: More than one SOPClassUID in the same series is not yet supported.'\n );\n return;\n }\n\n const SOPClassUID = sopClassUIDs[0];\n const sopClassHandlerModules = sopClassHandlerExtensions.map(extension => {\n return extension.module;\n });\n\n const handlersForSopClassUID = sopClassHandlerModules.filter(module => {\n return module.sopClassUIDs.includes(SOPClassUID);\n });\n\n // TODO: Sort by something, so we can determine which plugin to use\n if (!handlersForSopClassUID || !handlersForSopClassUID.length) {\n return;\n }\n\n const plugin = handlersForSopClassUID[0];\n const headers = DICOMWeb.getAuthorizationHeader();\n const errorInterceptor = errorHandler.getHTTPErrorHandler();\n const dicomWebClient = new dwc({\n url: study.getData().wadoRoot,\n headers,\n errorInterceptor,\n requestHooks: [getXHRRetryRequestHook()],\n });\n\n let displaySet = plugin.getDisplaySetFromSeries(\n series,\n study,\n dicomWebClient,\n headers\n );\n if (displaySet && !displaySet.Modality) {\n const instance = series.getFirstInstance();\n displaySet.Modality = instance.getTagValue('Modality');\n }\n return displaySet;\n}\n\n/**\n * Returns the referenced series instance UIDs by searching the information in the\n * ReferencedSeriesSequence.\n * @param {object} derivatedDisplaySet.metadata\n * @return {array[string]} referenced series instance UIDs.\n */\nfunction _findReferencedSeriesInstanceUIDsFromReferencedSeriesSequence(\n metadata\n) {\n if (!metadata.ReferencedSeriesSequence) {\n return;\n }\n\n let referencedSeriesInstanceUIDs;\n const ReferencedSeriesSequence = _toArray(metadata.ReferencedSeriesSequence);\n\n referencedSeriesInstanceUIDs = ReferencedSeriesSequence.map(\n ReferencedSeries => ReferencedSeries.SeriesInstanceUID\n );\n\n return referencedSeriesInstanceUIDs;\n}\n\n/**\n * Returns the referenced series instance UIDs by searching the information in the\n * ReferencedImageSequence.\n * @param {object} derivatedDisplaySet.metadata\n * @param {array[object]} displaysets\n * @return {array[string]} referenced series instance UIDs.\n */\nfunction _findReferencedSeriesInstanceUIDsFromReferencedImageSequence(\n metadata,\n displaySets\n) {\n if (!metadata.ReferencedImageSequence) {\n return;\n }\n\n let referencedSeriesInstanceUIDs;\n const referencedImageArray = _toArray(metadata.ReferencedImageSequence);\n for (let i = 0; i < referencedImageArray.length; i++) {\n const { ReferencedSOPInstanceUID } = referencedImageArray[i];\n if (!ReferencedSOPInstanceUID) {\n continue;\n }\n\n referencedSeriesInstanceUIDs = _findReferencedSeriesInstanceUIDsFromSOPInstanceUID(\n displaySets,\n ReferencedSOPInstanceUID\n );\n\n if (\n referencedSeriesInstanceUIDs &&\n referencedSeriesInstanceUIDs.length !== 0\n ) {\n break;\n }\n }\n\n return referencedSeriesInstanceUIDs;\n}\n\n/**\n * Returns the referenced series instance UIDs by searching the information in the\n * SourceImageSequence.\n * @param {object} derivatedDisplaySet.metadata\n * @param {array[object]} displaysets\n * @return {array[string]} referenced series instance UIDs.\n */\nfunction _findReferencedSeriesInstanceUIDsFromSourceImageSequence(\n metadata,\n displaySets\n) {\n let SourceImageSequence;\n\n if (metadata.SourceImageSequence) {\n SourceImageSequence = metadata.SourceImageSequence;\n } else {\n const { PerFrameFunctionalGroupsSequence } = metadata;\n const firstFunctionalGroups = _toArray(PerFrameFunctionalGroupsSequence)[0];\n if (firstFunctionalGroups) {\n const { DerivationImageSequence } = firstFunctionalGroups;\n SourceImageSequence = DerivationImageSequence;\n }\n }\n\n if (!SourceImageSequence) {\n return;\n }\n\n const sourceImageArray = _toArray(SourceImageSequence);\n\n let referencedSeriesInstanceUIDs;\n for (let i = 0; i < sourceImageArray.length; i++) {\n const { ReferencedSOPInstanceUID } = sourceImageArray[i];\n referencedSeriesInstanceUIDs = _findReferencedSeriesInstanceUIDsFromSOPInstanceUID(\n displaySets,\n ReferencedSOPInstanceUID\n );\n if (\n referencedSeriesInstanceUIDs &&\n referencedSeriesInstanceUIDs.length !== 0\n ) {\n break;\n }\n }\n\n return referencedSeriesInstanceUIDs;\n}\n\n/**\n * Returns the referenced series instance UIDs by searching the information in the\n * SOPInstanceUID of the displaySets.\n * @param {array[object]} displaysets\n * @param {string} SOPInstanceUID\n * @return {array[string]} referenced series instance UIDs.\n */\nfunction _findReferencedSeriesInstanceUIDsFromSOPInstanceUID(\n displaySets,\n SOPInstanceUID\n) {\n const imageSets = displaySets.filter(ds => ds instanceof ImageSet);\n\n for (let i = 0; i < imageSets.length; i++) {\n const { images } = imageSets[i];\n if (!images) {\n continue;\n }\n for (let j = 0; j < images.length; j++) {\n const image = images[j];\n if (!image) {\n continue;\n }\n if (image.SOPInstanceUID === SOPInstanceUID) {\n return [image.getData().metadata.SeriesInstanceUID];\n }\n }\n }\n}\n\nfunction _toArray(arrayOrObject) {\n return Array.isArray(arrayOrObject) ? arrayOrObject : [arrayOrObject];\n}\n\nexport { StudyMetadata };\n","import { sopClassDictionary } from './sopClassDictionary';\nimport { isImage } from './isImage';\n\n/**\n * Naturalize SOP Class UID which do not have image data\n * @param {string} SOPClassUID - SOP Class UID to be converted\n * @returns {string} - human readable name\n */\nexport const naturalizeSOPClassUID = SOPClassUID => {\n let naturalizedName = '';\n if (!SOPClassUID) return naturalizedName;\n if (!isImage) return naturalizedName;\n\n if (sopClassDictionary.MRSpectroscopyStorage === SOPClassUID) {\n naturalizedName = 'MRSpectroscopy';\n } else if (sopClassDictionary.EnhancedUSVolumeStorage === SOPClassUID) {\n naturalizedName = 'EnhancedUSVolume';\n } else if (sopClassDictionary.Sop12LeadECGWaveformStorage === SOPClassUID) {\n naturalizedName = 'Sop12LeadECGWaveform';\n } else if (sopClassDictionary.GeneralECGWaveformStorage === SOPClassUID) {\n naturalizedName = 'GeneralECGWaveform';\n } else if (sopClassDictionary.AmbulatoryECGWaveformStorage === SOPClassUID) {\n naturalizedName = 'AECAmbulatoryECGWaveformGW';\n } else if (sopClassDictionary.HemodynamicWaveformStorage === SOPClassUID) {\n naturalizedName = 'HemodynamicWaveform';\n } else if (\n sopClassDictionary.CardiacElectrophysiologyWaveformStorage === SOPClassUID\n ) {\n naturalizedName = 'CardiacElectrophysiologyWaveform';\n } else if (\n sopClassDictionary.BasicVoiceAudioWaveformStorage === SOPClassUID\n ) {\n naturalizedName = 'BasicVoiceAudioWaveform';\n } else if (sopClassDictionary.GeneralAudioWaveformStorage === SOPClassUID) {\n naturalizedName = 'GGeneralAudioWaveformAW';\n } else if (sopClassDictionary.ArterialPulseWaveformStorage === SOPClassUID) {\n naturalizedName = 'APArterialPulseWaveformW';\n } else if (sopClassDictionary.RespiratoryWaveformStorage === SOPClassUID) {\n naturalizedName = 'RespiratoryWaveform';\n } else if (\n sopClassDictionary.GrayscaleSoftcopyPresentationStateStorage === SOPClassUID\n ) {\n naturalizedName = 'GrayscaleSoftcopyPresentationState';\n } else if (\n sopClassDictionary.ColorSoftcopyPresentationStateStorage === SOPClassUID\n ) {\n naturalizedName = 'ColorSoftcopyPresentationState';\n } else if (\n sopClassDictionary.PseudoColorSoftcopyPresentationStateStorage ===\n SOPClassUID\n ) {\n naturalizedName = 'PseudoColorSoftcopyPresentationState';\n } else if (\n sopClassDictionary.BlendingSoftcopyPresentationStateStorage === SOPClassUID\n ) {\n naturalizedName = 'BlendingSoftcopyPresentationState';\n } else if (\n sopClassDictionary.XAXRFGrayscaleSoftcopyPresentationStateStorage ===\n SOPClassUID\n ) {\n naturalizedName = 'XAXRFGrayscaleSoftcopyPresentationState';\n } else if (sopClassDictionary.RawDataStorage === SOPClassUID) {\n naturalizedName = 'RawData';\n } else if (sopClassDictionary.SpatialRegistrationStorage === SOPClassUID) {\n naturalizedName = 'SpatialRegistration';\n } else if (sopClassDictionary.SpatialFiducialsStorage === SOPClassUID) {\n naturalizedName = 'SpatialFiducials';\n } else if (\n sopClassDictionary.DeformableSpatialRegistrationStorage === SOPClassUID\n ) {\n naturalizedName = 'DeformableSpatialRegistration';\n } else if (sopClassDictionary.SegmentationStorage === SOPClassUID) {\n naturalizedName = 'SEG';\n } else if (sopClassDictionary.SurfaceSegmentationStorage === SOPClassUID) {\n naturalizedName = 'SurfaceSEG';\n } else if (sopClassDictionary.RealWorldValueMappingStorage === SOPClassUID) {\n naturalizedName = 'RealWorldValueMapping';\n } else if (sopClassDictionary.SurfaceScanMeshStorage === SOPClassUID) {\n naturalizedName = 'SurfaceScanMesh';\n } else if (sopClassDictionary.SurfaceScanPointCloudStorage === SOPClassUID) {\n naturalizedName = 'SurfaceScanPointCloud';\n } else if (\n sopClassDictionary.StereometricRelationshipStorage === SOPClassUID\n ) {\n naturalizedName = 'StereometricRelationship';\n } else if (sopClassDictionary.LensometryMeasurementsStorage === SOPClassUID) {\n naturalizedName = 'LensometryMeasurements';\n } else if (\n sopClassDictionary.AutorefractionMeasurementsStorage === SOPClassUID\n ) {\n naturalizedName = 'AutorefractionMeasurements';\n } else if (\n sopClassDictionary.KeratometryMeasurementsStorage === SOPClassUID\n ) {\n naturalizedName = 'KeratometryMeasurements';\n } else if (\n sopClassDictionary.SubjectiveRefractionMeasurementsStorage === SOPClassUID\n ) {\n naturalizedName = 'SubjectiveRefractionMeasurements';\n } else if (\n sopClassDictionary.VisualAcuityMeasurementsStorage === SOPClassUID\n ) {\n naturalizedName = 'VisualAcuityMeasurements';\n } else if (\n sopClassDictionary.SpectaclePrescriptionReportStorage === SOPClassUID\n ) {\n naturalizedName = 'SpectaclePrescriptionReport';\n } else if (\n sopClassDictionary.OphthalmicAxialMeasurementsStorage === SOPClassUID\n ) {\n naturalizedName = 'OphthalmicAxialMeasurements';\n } else if (\n sopClassDictionary.IntraocularLensCalculationsStorage === SOPClassUID\n ) {\n naturalizedName = 'IntraocularLensCalculations';\n } else if (\n sopClassDictionary.MacularGridThicknessandVolumeReport === SOPClassUID\n ) {\n naturalizedName = 'MacularGridThicknessandVolume';\n } else if (\n sopClassDictionary.OphthalmicVisualFieldStaticPerimetryMeasurementsStorage ===\n SOPClassUID\n ) {\n naturalizedName = 'OphthalmicVisualFieldStaticPerimetryMeasurements';\n } else if (sopClassDictionary.OphthalmicThicknessMapStorage === SOPClassUID) {\n naturalizedName = 'OphthalmicThicknessMap';\n } else if (sopClassDictionary.CornealTopographyMapStorage === SOPClassUID) {\n naturalizedName = 'CornealTopographyMap';\n } else if (sopClassDictionary.BasicTextSR === SOPClassUID) {\n naturalizedName = 'BasicTextSR';\n } else if (sopClassDictionary.EnhancedSR === SOPClassUID) {\n naturalizedName = 'EnhancedSR';\n } else if (sopClassDictionary.ComprehensiveSR === SOPClassUID) {\n naturalizedName = 'ComprehensiveSR';\n } else if (sopClassDictionary.Comprehensive3DSR === SOPClassUID) {\n naturalizedName = 'Comprehensive3DSR';\n } else if (sopClassDictionary.ProcedureLog === SOPClassUID) {\n naturalizedName = 'ProcedureLog';\n } else if (sopClassDictionary.MammographyCADSR === SOPClassUID) {\n naturalizedName = 'MammographyCADSR';\n } else if (sopClassDictionary.KeyObjectSelection === SOPClassUID) {\n naturalizedName = 'KeyObject';\n } else if (sopClassDictionary.ChestCADSR === SOPClassUID) {\n naturalizedName = 'ChestCADSR';\n } else if (sopClassDictionary.XRayRadiationDoseSR === SOPClassUID) {\n naturalizedName = 'XRayRadiationDoseSR';\n } else if (\n sopClassDictionary.RadiopharmaceuticalRadiationDoseSR === SOPClassUID\n ) {\n naturalizedName = 'RadiopharmaceuticalRadiationDoseSR';\n } else if (sopClassDictionary.ColonCADSR === SOPClassUID) {\n naturalizedName = 'ColonCADSR';\n } else if (\n sopClassDictionary.ImplantationPlanSRDocumentStorage === SOPClassUID\n ) {\n naturalizedName = 'ImplantationPlanSRDocument';\n } else if (sopClassDictionary.EncapsulatedPDFStorage === SOPClassUID) {\n naturalizedName = 'EncapsulatedPDF';\n } else if (sopClassDictionary.EncapsulatedCDAStorage === SOPClassUID) {\n naturalizedName = 'EncapsulatedCDA';\n } else if (sopClassDictionary.BasicStructuredDisplayStorage === SOPClassUID) {\n naturalizedName = 'BasicStructuredDisplay';\n } else if (sopClassDictionary.RTDoseStorage === SOPClassUID) {\n naturalizedName = 'RTDose';\n } else if (sopClassDictionary.RTStructureSetStorage === SOPClassUID) {\n naturalizedName = 'RTStructureSet';\n } else if (sopClassDictionary.RTBeamsTreatmentRecordStorage === SOPClassUID) {\n naturalizedName = 'RTBeamsTreatmentRecord';\n } else if (sopClassDictionary.RTPlanStorage === SOPClassUID) {\n naturalizedName = 'RTPlan';\n } else if (\n sopClassDictionary.RTBrachyTreatmentRecordStorage === SOPClassUID\n ) {\n naturalizedName = 'RTBrachyTreatmentRecord';\n } else if (\n sopClassDictionary.RTTreatmentSummaryRecordStorage === SOPClassUID\n ) {\n naturalizedName = 'RTTreatmentSummaryRecord';\n } else if (sopClassDictionary.RTIonPlanStorage === SOPClassUID) {\n naturalizedName = 'RTIonPlan';\n } else if (\n sopClassDictionary.RTIonBeamsTreatmentRecordStorage === SOPClassUID\n ) {\n naturalizedName = 'RTIonBeamsTreatmentRecord';\n } else if (\n sopClassDictionary.RTBeamsDeliveryInstructionStorage === SOPClassUID\n ) {\n naturalizedName = 'RTBeamsDeliveryInstruction';\n } else if (sopClassDictionary.GenericImplantTemplateStorage === SOPClassUID) {\n naturalizedName = 'GenericImplantTemplate';\n } else if (\n sopClassDictionary.ImplantAssemblyTemplateStorage === SOPClassUID\n ) {\n naturalizedName = 'ImplantAssemblyTemplate';\n } else if (sopClassDictionary.ImplantTemplateGroupStorage === SOPClassUID) {\n naturalizedName = 'ImplantTemplateGroup';\n }\n\n return naturalizedName;\n};\n","import guid from '../utils/guid.js';\nimport OHIFError from './OHIFError';\nimport { Vector3 } from 'cornerstone-math';\n\nconst OBJECT = 'object';\n\n/**\n * This class defines an ImageSet object which will be used across the viewer. This object represents\n * a list of images that are associated by any arbitrary criteria being thus content agnostic. Besides the\n * main attributes (images and uid) it allows additional attributes to be appended to it (currently\n * indiscriminately, but this should be changed).\n */\nclass ImageSet {\n constructor(images) {\n if (Array.isArray(images) !== true) {\n throw new OHIFError('ImageSet expects an array of images');\n }\n\n // @property \"images\"\n Object.defineProperty(this, 'images', {\n enumerable: false,\n configurable: false,\n writable: false,\n value: images,\n });\n\n // @property \"uid\"\n Object.defineProperty(this, 'uid', {\n enumerable: false,\n configurable: false,\n writable: false,\n value: guid(), // Unique ID of the instance\n });\n }\n\n getUID() {\n return this.uid;\n }\n\n setAttribute(attribute, value) {\n this[attribute] = value;\n }\n\n getAttribute(attribute) {\n return this[attribute];\n }\n\n setAttributes(attributes) {\n if (typeof attributes === OBJECT && attributes !== null) {\n const imageSet = this,\n hasOwn = Object.prototype.hasOwnProperty;\n for (let attribute in attributes) {\n if (hasOwn.call(attributes, attribute)) {\n imageSet[attribute] = attributes[attribute];\n }\n }\n }\n }\n\n getImage(index) {\n return this.images[index];\n }\n\n sortBy(sortingCallback) {\n return this.images.sort(sortingCallback);\n }\n\n sortByImagePositionPatient() {\n const images = this.images;\n const referenceImagePositionPatient = _getImagePositionPatient(images[0]);\n\n const refIppVec = new Vector3(\n referenceImagePositionPatient[0],\n referenceImagePositionPatient[1],\n referenceImagePositionPatient[2]\n );\n\n const ImageOrientationPatient = _getImageOrientationPatient(images[0]);\n\n const scanAxisNormal = new Vector3(\n ImageOrientationPatient[0],\n ImageOrientationPatient[1],\n ImageOrientationPatient[2]\n ).cross(\n new Vector3(\n ImageOrientationPatient[3],\n ImageOrientationPatient[4],\n ImageOrientationPatient[5]\n )\n );\n\n const distanceImagePairs = images.map(function(image) {\n const ippVec = new Vector3(..._getImagePositionPatient(image));\n const positionVector = refIppVec.clone().sub(ippVec);\n const distance = positionVector.dot(scanAxisNormal);\n\n return {\n distance,\n image,\n };\n });\n\n distanceImagePairs.sort(function(a, b) {\n return b.distance - a.distance;\n });\n\n const sortedImages = distanceImagePairs.map(a => a.image);\n\n images.sort(function(a, b) {\n return sortedImages.indexOf(a) - sortedImages.indexOf(b);\n });\n }\n}\n\nfunction _getImagePositionPatient(image) {\n return image.getData().metadata.ImagePositionPatient;\n}\n\nfunction _getImageOrientationPatient(image) {\n return image.getData().metadata.ImageOrientationPatient;\n}\n\nexport default ImageSet;\n","import getWADORSImageId from './getWADORSImageId';\n\n// https://stackoverflow.com/a/6021027/3895126\nfunction updateQueryStringParameter(uri, key, value) {\n const regex = new RegExp('([?&])' + key + '=.*?(&|$)', 'i');\n const separator = uri.indexOf('?') !== -1 ? '&' : '?';\n if (uri.match(regex)) {\n return uri.replace(regex, '$1' + key + '=' + value + '$2');\n } else {\n return uri + separator + key + '=' + value;\n }\n}\n\n/**\n * Obtain an imageId for Cornerstone from an image instance\n *\n * @param instance\n * @param frame\n * @param thumbnail\n * @returns {string} The imageId to be used by Cornerstone\n */\nexport default function getImageId(instance, frame, thumbnail = false) {\n if (!instance) {\n return;\n }\n\n if (typeof instance.getImageId === 'function') {\n return instance.getImageId();\n }\n\n if (instance.url) {\n if (frame !== undefined) {\n instance.url = updateQueryStringParameter(instance.url, 'frame', frame);\n }\n\n return instance.url;\n }\n\n const renderingAttr = thumbnail ? 'thumbnailRendering' : 'imageRendering';\n\n if (\n !instance[renderingAttr] ||\n instance[renderingAttr] === 'wadouri' ||\n !instance.wadorsuri\n ) {\n let imageId = 'dicomweb:' + instance.wadouri;\n if (frame !== undefined) {\n imageId += '&frame=' + frame;\n }\n\n return imageId;\n } else {\n return getWADORSImageId(instance, frame, thumbnail); // WADO-RS Retrieve Frame\n }\n}\n","import OHIFError from './OHIFError';\n\n/**\n * Abstract class to fetch study metadata.\n */\nexport class StudyMetadataSource {\n /**\n * Get study metadata for a study with given study InstanceUID.\n * @param {String} studyInstanceUID Study InstanceUID.\n */\n getByInstanceUID(studyInstanceUID) {\n /**\n * Please override this method on a specialized class.\n */\n throw new OHIFError(\n 'StudyMetadataSource::getByInstanceUID is not overriden. Please, override it in a specialized class. See OHIFStudyMetadataSource for example'\n );\n }\n\n /**\n * Load study info and study metadata for a given study into the viewer.\n * @param {StudyMetadata} study StudyMetadata object.\n */\n loadStudy(study) {\n /**\n * Please override this method on a specialized class.\n */\n throw new OHIFError(\n 'StudyMetadataSource::loadStudy is not overriden. Please, override it in a specialized class. See OHIFStudyMetadataSource for example'\n );\n }\n}\n","const debugMode = !!(\n process.env.NODE_ENV !== 'production' && process.env.REACT_APP_I18N_DEBUG\n);\n\nconst detectionOptions = {\n // order and from where user language should be detected\n order: ['querystring', 'cookie', 'localStorage', 'navigator', 'htmlTag', 'path', 'subdomain'],\n\n // keys or params to lookup language from\n lookupQuerystring: 'lng',\n lookupCookie: 'i18next',\n lookupLocalStorage: 'i18nextLng',\n lookupFromPathIndex: 0,\n lookupFromSubdomainIndex: 0,\n\n // cache user language on\n caches: ['localStorage', 'cookie'],\n excludeCacheFor: ['cimode'], // languages to not persist (cookie, localStorage)\n\n // optional htmlTag with lang attribute, the default is:\n htmlTag: document.documentElement\n};\n\nexport { debugMode, detectionOptions };\n","import { debugMode } from './config';\n\nexport default (message, level = 'log') => {\n if (debugMode) {\n // eslint-disable-next-line\n console[level]('@ohif/i18n: ', message);\n }\n};\n","import de from './de/';\nimport en_US from './en-US/';\nimport es from './es/';\nimport fr from './fr/';\nimport ja_JP from './ja-JP/';\nimport nl from './nl/';\nimport pt_BR from './pt-BR/';\nimport ru from './ru/';\nimport vi from './vi/';\nimport zh from './zh/';\n\nexport default {\n ...de,\n ...en_US,\n ...es,\n ...fr,\n ...ja_JP,\n ...nl,\n ...pt_BR,\n ...ru,\n ...vi,\n ...zh,\n};\n","import AboutModal from './AboutModal.json';\nimport Buttons from './Buttons.json';\nimport CineDialog from './CineDialog.json';\nimport Common from './Common.json';\nimport DatePicker from './DatePicker.json';\nimport Header from './Header.json';\nimport MeasurementTable from './MeasurementTable.json';\nimport StudyList from './StudyList.json';\nimport UserPreferencesModal from './UserPreferencesModal.json';\nimport ViewportDownloadForm from './ViewportDownloadForm.json';\n\nexport default { \n 'de': {\n AboutModal,\n Buttons,\n CineDialog,\n Common,\n DatePicker,\n Header,\n MeasurementTable,\n StudyList,\n UserPreferencesModal,\n ViewportDownloadForm,\n }\n};\n","import AboutModal from './AboutModal.json';\nimport Buttons from './Buttons.json';\nimport CineDialog from './CineDialog.json';\nimport Common from './Common.json';\nimport DatePicker from './DatePicker.json';\nimport Header from './Header.json';\nimport MeasurementTable from './MeasurementTable.json';\nimport StudyList from './StudyList.json';\nimport UserPreferencesModal from './UserPreferencesModal.json';\nimport ViewportDownloadForm from './ViewportDownloadForm.json';\n\nexport default { \n 'en-US': {\n AboutModal,\n Buttons,\n CineDialog,\n Common,\n DatePicker,\n Header,\n MeasurementTable,\n StudyList,\n UserPreferencesModal,\n ViewportDownloadForm,\n }\n};\n","import AboutModal from './AboutModal.json';\nimport Buttons from './Buttons.json';\nimport CineDialog from './CineDialog.json';\nimport Common from './Common.json';\nimport DatePicker from './DatePicker.json';\nimport Header from './Header.json';\nimport MeasurementTable from './MeasurementTable.json';\nimport StudyList from './StudyList.json';\nimport UserPreferencesModal from './UserPreferencesModal.json';\nimport ViewportDownloadForm from './ViewportDownloadForm.json';\n\nexport default { \n 'es': {\n AboutModal,\n Buttons,\n CineDialog,\n Common,\n DatePicker,\n Header,\n MeasurementTable,\n StudyList,\n UserPreferencesModal,\n ViewportDownloadForm,\n }\n};\n","import AboutModal from './AboutModal.json';\nimport Buttons from './Buttons.json';\nimport CineDialog from './CineDialog.json';\nimport Common from './Common.json';\nimport DatePicker from './DatePicker.json';\nimport Header from './Header.json';\nimport MeasurementTable from './MeasurementTable.json';\nimport StudyList from './StudyList.json';\nimport UserPreferencesModal from './UserPreferencesModal.json';\nimport ViewportDownloadForm from './ViewportDownloadForm.json';\n\nexport default { \n 'fr': {\n AboutModal,\n Buttons,\n CineDialog,\n Common,\n DatePicker,\n Header,\n MeasurementTable,\n StudyList,\n UserPreferencesModal,\n ViewportDownloadForm,\n }\n};\n","import AboutModal from './AboutModal.json';\nimport Buttons from './Buttons.json';\nimport CineDialog from './CineDialog.json';\nimport Common from './Common.json';\nimport DatePicker from './DatePicker.json';\nimport Header from './Header.json';\nimport MeasurementTable from './MeasurementTable.json';\nimport StudyList from './StudyList.json';\nimport UserPreferencesModal from './UserPreferencesModal.json';\nimport ViewportDownloadForm from './ViewportDownloadForm.json';\n\nexport default { \n 'ja-JP': {\n AboutModal,\n Buttons,\n CineDialog,\n Common,\n DatePicker,\n Header,\n MeasurementTable,\n StudyList,\n UserPreferencesModal,\n ViewportDownloadForm,\n }\n};\n","import AboutModal from './AboutModal.json';\nimport Buttons from './Buttons.json';\nimport CineDialog from './CineDialog.json';\nimport Common from './Common.json';\nimport DatePicker from './DatePicker.json';\nimport Header from './Header.json';\nimport MeasurementTable from './MeasurementTable.json';\nimport StudyList from './StudyList.json';\nimport UserPreferencesModal from './UserPreferencesModal.json';\nimport ViewportDownloadForm from './ViewportDownloadForm.json';\n\nexport default { \n 'nl': {\n AboutModal,\n Buttons,\n CineDialog,\n Common,\n DatePicker,\n Header,\n MeasurementTable,\n StudyList,\n UserPreferencesModal,\n ViewportDownloadForm,\n }\n};\n","import AboutModal from './AboutModal.json';\nimport Buttons from './Buttons.json';\nimport CineDialog from './CineDialog.json';\nimport Common from './Common.json';\nimport DatePicker from './DatePicker.json';\nimport Header from './Header.json';\nimport MeasurementTable from './MeasurementTable.json';\nimport StudyList from './StudyList.json';\nimport UserPreferencesModal from './UserPreferencesModal.json';\nimport ViewportDownloadForm from './ViewportDownloadForm.json';\n\nexport default { \n 'pt-BR': {\n AboutModal,\n Buttons,\n CineDialog,\n Common,\n DatePicker,\n Header,\n MeasurementTable,\n StudyList,\n UserPreferencesModal,\n ViewportDownloadForm,\n }\n};\n","import AboutModal from './AboutModal.json';\nimport Buttons from './Buttons.json';\nimport CineDialog from './CineDialog.json';\nimport Common from './Common.json';\nimport DatePicker from './DatePicker.json';\nimport Header from './Header.json';\nimport MeasurementTable from './MeasurementTable.json';\nimport StudyList from './StudyList.json';\nimport UserPreferencesModal from './UserPreferencesModal.json';\nimport ViewportDownloadForm from './ViewportDownloadForm.json';\n\nexport default { \n 'ru': {\n AboutModal,\n Buttons,\n CineDialog,\n Common,\n DatePicker,\n Header,\n MeasurementTable,\n StudyList,\n UserPreferencesModal,\n ViewportDownloadForm,\n }\n};\n","import AboutModal from './AboutModal.json';\nimport Buttons from './Buttons.json';\nimport CineDialog from './CineDialog.json';\nimport Common from './Common.json';\nimport DatePicker from './DatePicker.json';\nimport Header from './Header.json';\nimport MeasurementTable from './MeasurementTable.json';\nimport StudyList from './StudyList.json';\nimport UserPreferencesModal from './UserPreferencesModal.json';\nimport ViewportDownloadForm from './ViewportDownloadForm.json';\n\nexport default { \n 'vi': {\n AboutModal,\n Buttons,\n CineDialog,\n Common,\n DatePicker,\n Header,\n MeasurementTable,\n StudyList,\n UserPreferencesModal,\n ViewportDownloadForm,\n }\n};\n","import AboutModal from './AboutModal.json';\nimport Buttons from './Buttons.json';\nimport CineDialog from './CineDialog.json';\nimport Common from './Common.json';\nimport DatePicker from './DatePicker.json';\nimport Header from './Header.json';\nimport MeasurementTable from './MeasurementTable.json';\nimport StudyList from './StudyList.json';\nimport UserPreferencesModal from './UserPreferencesModal.json';\nimport ViewportDownloadForm from './ViewportDownloadForm.json';\n\nexport default { \n 'zh': {\n AboutModal,\n Buttons,\n CineDialog,\n Common,\n DatePicker,\n Header,\n MeasurementTable,\n StudyList,\n UserPreferencesModal,\n ViewportDownloadForm,\n }\n};\n","const languagesMap = {\n ar: 'Arabic',\n am: 'Amharic',\n bg: 'Bulgarian',\n bn: 'Bengali',\n ca: 'Catalan',\n cs: 'Czech',\n da: 'Danish',\n de: 'German',\n el: 'Greek',\n en: 'English',\n 'en-GB': 'English (Great Britain)',\n 'en-US': 'English (USA)',\n es: 'Spanish',\n et: 'Estonian',\n fa: 'Persian',\n fi: 'Finnish',\n fil: 'Filipino',\n fr: 'French',\n gu: 'Gujarati',\n he: 'Hebrew',\n hi: 'Hindi',\n hr: 'Croatian',\n hu: 'Hungarian',\n id: 'Indonesian',\n it: 'Italian',\n ja: 'Japanese',\n 'ja-JP': 'Japanese (Japan)',\n kn: 'Kannada',\n ko: 'Korean',\n lt: 'Lithuanian',\n lv: 'Latvian',\n ml: 'Malayalam',\n mr: 'Marathi',\n ms: 'Malay',\n nl: 'Dutch',\n no: 'Norwegian',\n pl: 'Polish',\n 'pt-BR': 'Portuguese (Brazil)',\n 'pt-PT': 'Portuguese (Portugal)',\n ro: 'Romanian',\n ru: 'Russian',\n sk: 'Slovak',\n sl: 'Slovenian',\n sr: 'Serbian',\n sv: 'Swedish',\n sw: 'Swahili',\n ta: 'Tamil',\n te: 'Telugu',\n th: 'Thai',\n tr: 'Turkish',\n uk: 'Ukrainian',\n vi: 'Vietnamese',\n zh: 'Chinese',\n 'zh-CN': 'Chinese (China)',\n 'zh-TW': 'Chinese (Taiwan)',\n};\n\nexport default function getAvailableLanguagesInfo(locales) {\n const availableLanguagesInfo = [];\n\n Object.keys(locales).forEach(key => {\n availableLanguagesInfo.push({\n value: key,\n label: languagesMap[key] || key,\n });\n });\n\n return availableLanguagesInfo;\n}\n","import i18n from 'i18next';\nimport Backend from 'i18next-locize-backend';\nimport LastUsed from 'locize-lastused';\nimport Editor from 'locize-editor';\nimport LanguageDetector from 'i18next-browser-languagedetector';\nimport { initReactI18next } from 'react-i18next';\nimport customDebug from './debugger';\nimport pkg from '../package.json';\nimport { debugMode, detectionOptions } from './config';\n\n// Note: The index.js files inside src/locales are dynamically generated\n// by the pullTranslations.sh script\nimport locales from './locales';\n\nfunction addLocales(newLocales) {\n customDebug(`Adding locales ${newLocales}`, 'info');\n\n let resourceBundle = [];\n\n Object.keys(newLocales).map(key => {\n Object.keys(newLocales[key]).map(namespace => {\n const locale = newLocales[key][namespace];\n resourceBundle.push({ key, namespace, locale });\n i18n.addResourceBundle(key, namespace, locale, true, true);\n });\n });\n\n customDebug(`Locales added successfully`, 'info');\n customDebug(resourceBundle, 'info');\n}\n\n/*\n * Note: Developers can add the API key to use the\n * in-context editor using environment variables.\n * (DO NOT commit the API key)\n */\nconst locizeOptions = {\n projectId: process.env.LOCIZE_PROJECTID,\n apiKey: process.env.LOCIZE_API_KEY,\n referenceLng: 'en-US',\n fallbacklng: 'en-US',\n};\n\nconst envUseLocize = !!process.env.USE_LOCIZE;\nconst envApiKeyAvailable = !!process.env.LOCIZE_API_KEY;\nconst DEFAULT_LANGUAGE = 'en-US';\n\nfunction initI18n(\n detection = detectionOptions,\n useLocize = envUseLocize,\n apiKeyAvailable = envApiKeyAvailable\n) {\n let initialized;\n\n if (useLocize) {\n customDebug(`Using Locize for translation files`, 'info');\n initialized = i18n\n // i18next-locize-backend\n // loads translations from your project, saves new keys to it (saveMissing: true)\n // https://github.com/locize/i18next-locize-backend\n .use(Backend)\n // locize-lastused\n // sets a timestamp of last access on every translation segment on locize\n // -> safely remove the ones not being touched for weeks/months\n // https://github.com/locize/locize-lastused\n .use(LastUsed)\n // locize-editor\n // InContext Editor of locize ?locize=true to show it\n // https://github.com/locize/locize-editor\n .use(Editor)\n // detect user language\n // learn more: https://github.com/i18next/i18next-browser-languageDetector\n .use(LanguageDetector)\n // pass the i18n instance to react-i18next.\n .use(initReactI18next)\n // init i18next\n // for all options read: https://www.i18next.com/overview/configuration-options\n .init({\n fallbackLng: DEFAULT_LANGUAGE,\n saveMissing: apiKeyAvailable,\n debug: debugMode,\n keySeparator: false,\n interpolation: {\n escapeValue: false, // not needed for react as it escapes by default\n },\n detection,\n backend: locizeOptions,\n locizeLastUsed: locizeOptions,\n editor: {\n ...locizeOptions,\n onEditorSaved: async (lng, ns) => {\n // reload that namespace in given language\n await i18n.reloadResources(lng, ns);\n // trigger an event on i18n which triggers a rerender\n // based on bindI18n below in react options\n i18n.emit('editorSaved');\n },\n },\n react: {\n useSuspense: false, // TODO: Was seeing weird errors without this\n wait: true,\n bindI18n: 'languageChanged editorSaved',\n },\n });\n } else {\n customDebug(`Using local translation files`, 'info');\n initialized = i18n\n // detect user language\n // learn more: https://github.com/i18next/i18next-browser-languageDetector\n .use(LanguageDetector)\n // pass the i18n instance to react-i18next.\n .use(initReactI18next)\n // init i18next\n // for all options read: https://www.i18next.com/overview/configuration-options\n .init({\n fallbackLng: DEFAULT_LANGUAGE,\n resources: locales,\n debug: debugMode,\n keySeparator: false,\n interpolation: {\n escapeValue: false, // not needed for react as it escapes by default\n },\n detection,\n react: {\n wait: true,\n },\n });\n }\n\n return initialized.then(function(t) {\n i18n.T = t;\n customDebug(`T function available.`, 'info');\n });\n}\n\ncustomDebug(`version ${pkg.version} loaded.`, 'info');\n\ni18n.initializing = initI18n();\ni18n.initI18n = initI18n;\ni18n.addLocales = addLocales;\ni18n.defaultLanguage = DEFAULT_LANGUAGE;\n\nimport getAvailableLanguagesInfo from './getAvailableLanguagesInfo.js';\ni18n.availableLanguages = getAvailableLanguagesInfo(locales);\n\nexport default i18n;\n","import RetrieveMetadata from './services/wado/retrieveMetadata.js';\n\nconst moduleName = 'RetrieveStudyMetadata';\n// Cache for promises. Prevents unnecessary subsequent calls to the server\nconst StudyMetaDataPromises = new Map();\n\n/**\n * Retrieves study metadata\n *\n * @param {Object} server Object with server configuration parameters\n * @param {string} StudyInstanceUID The UID of the Study to be retrieved\n * @param {Object} [filters] - Object containing filters to be applied on retrieve metadata process\n * @param {string} [filter.seriesInstanceUID] - series instance uid to filter results against\n * @param {boolean} [separateSeriesInstanceUIDFilters = false] - If true, split filtered metadata calls into multiple calls,\n * as some DICOMWeb implementations only support single filters.\n * @returns {Promise} that will be resolved with the metadata or rejected with the error\n */\nexport function retrieveStudyMetadata(\n server,\n StudyInstanceUID,\n filters,\n separateSeriesInstanceUIDFilters = false\n) {\n // @TODO: Whenever a study metadata request has failed, its related promise will be rejected once and for all\n // and further requests for that metadata will always fail. On failure, we probably need to remove the\n // corresponding promise from the \"StudyMetaDataPromises\" map...\n\n if (!server) {\n throw new Error(`${moduleName}: Required 'server' parameter not provided.`);\n }\n if (!StudyInstanceUID) {\n throw new Error(\n `${moduleName}: Required 'StudyInstanceUID' parameter not provided.`\n );\n }\n\n // Already waiting on result? Return cached promise\n if (StudyMetaDataPromises.has(StudyInstanceUID)) {\n return StudyMetaDataPromises.get(StudyInstanceUID);\n }\n\n // Create a promise to handle the data retrieval\n let promise;\n\n if (\n filters &&\n filters.seriesInstanceUID &&\n separateSeriesInstanceUIDFilters\n ) {\n promise = __separateSeriesRequestToAggregatePromiseateSeriesRequestToAggregatePromise(\n server,\n StudyInstanceUID,\n filters\n );\n } else {\n promise = RetrieveMetadata(server, StudyInstanceUID, filters);\n\n /*\n promise = new Promise((resolve, reject) => {\n RetrieveMetadata(server, StudyInstanceUID, filters).then(function(data) {\n resolve(data);\n }, reject);\n });\n */\n }\n\n // Store the promise in cache\n StudyMetaDataPromises.set(StudyInstanceUID, promise);\n\n return promise;\n}\n\n/**\n * Splits up seriesInstanceUID filters to multiple calls for platforms\n * @param {Object} server Object with server configuration parameters\n * @param {string} StudyInstanceUID The UID of the Study to be retrieved\n * @param {Object} filters - Object containing filters to be applied on retrieve metadata process\n */\nfunction __separateSeriesRequestToAggregatePromiseateSeriesRequestToAggregatePromise(\n server,\n StudyInstanceUID,\n filters\n) {\n const { seriesInstanceUID } = filters;\n const seriesInstanceUIDs = seriesInstanceUID.split(',');\n\n return new Promise((resolve, reject) => {\n const promises = [];\n\n seriesInstanceUIDs.forEach(uid => {\n const seriesSpecificFilters = Object.assign({}, filters, {\n seriesInstanceUID: uid,\n });\n\n promises.push(\n RetrieveMetadata(server, StudyInstanceUID, seriesSpecificFilters)\n );\n });\n\n Promise.all(promises).then(results => {\n const data = results[0];\n\n let series = [];\n\n results.forEach(result => {\n series = [...series, ...result.series];\n });\n\n data.series = series;\n\n resolve(data);\n }, reject);\n });\n}\n\n/**\n * Delete the cached study metadata retrieval promise to ensure that the browser will\n * re-retrieve the study metadata when it is next requested\n *\n * @param {String} StudyInstanceUID The UID of the Study to be removed from cache\n *\n */\nexport function deleteStudyMetadataPromise(StudyInstanceUID) {\n if (StudyMetaDataPromises.has(StudyInstanceUID)) {\n StudyMetaDataPromises.delete(StudyInstanceUID);\n }\n}\n","/**\n * Convert String to ArrayBuffer\n *\n * @param {String} str Input String\n * @return {ArrayBuffer} Output converted ArrayBuffer\n */\nexport default function str2ab(str) {\n const strLen = str.length;\n const bytes = new Uint8Array(strLen);\n\n for (let i = 0; i < strLen; i++) {\n bytes[i] = str.charCodeAt(i);\n }\n\n return bytes.buffer;\n}\n","export class ObjectPath {\n /**\n * Set an object property based on \"path\" (namespace) supplied creating\n * ... intermediary objects if they do not exist.\n * @param object {Object} An object where the properties specified on path should be set.\n * @param path {String} A string representing the property to be set, e.g. \"user.study.series.timepoint\".\n * @param value {Any} The value of the property that will be set.\n * @return {Boolean} Returns \"true\" on success, \"false\" if any intermediate component of the supplied path\n * ... is not a valid Object, in which case the property cannot be set. No excpetions are thrown.\n */\n static set(object, path, value) {\n let components = ObjectPath.getPathComponents(path),\n length = components !== null ? components.length : 0,\n result = false;\n\n if (length > 0 && ObjectPath.isValidObject(object)) {\n let i = 0,\n last = length - 1,\n currentObject = object;\n\n while (i < last) {\n let field = components[i];\n\n if (field in currentObject) {\n if (!ObjectPath.isValidObject(currentObject[field])) {\n break;\n }\n } else {\n currentObject[field] = {};\n }\n\n currentObject = currentObject[field];\n i++;\n }\n\n if (i === last) {\n currentObject[components[last]] = value;\n result = true;\n }\n }\n\n return result;\n }\n\n /**\n * Get an object property based on \"path\" (namespace) supplied traversing the object\n * ... tree as necessary.\n * @param object {Object} An object where the properties specified might exist.\n * @param path {String} A string representing the property to be searched for, e.g. \"user.study.series.timepoint\".\n * @return {Any} The value of the property if found. By default, returns the special type \"undefined\".\n */\n static get(object, path) {\n let found, // undefined by default\n components = ObjectPath.getPathComponents(path),\n length = components !== null ? components.length : 0;\n\n if (length > 0 && ObjectPath.isValidObject(object)) {\n let i = 0,\n last = length - 1,\n currentObject = object;\n\n while (i < last) {\n let field = components[i];\n\n const isValid = ObjectPath.isValidObject(currentObject[field]);\n if (field in currentObject && isValid) {\n currentObject = currentObject[field];\n i++;\n } else {\n break;\n }\n }\n\n if (i === last && components[last] in currentObject) {\n found = currentObject[components[last]];\n }\n }\n\n return found;\n }\n\n /**\n * Check if the supplied argument is a real JavaScript Object instance.\n * @param object {Any} The subject to be tested.\n * @return {Boolean} Returns \"true\" if the object is a real Object instance and \"false\" otherwise.\n */\n static isValidObject(object) {\n return (\n typeof object === 'object' && object !== null && object instanceof Object\n );\n }\n\n static getPathComponents(path) {\n return typeof path === 'string' ? path.split('.') : null;\n }\n}\n\nexport default ObjectPath;\n","const absoluteUrl = path => {\n let absolutePath = '/';\n\n if (!path) return absolutePath;\n\n // TODO: Find another way to get root url\n const absoluteUrl = window.location.origin;\n const absoluteUrlParts = absoluteUrl.split('/');\n\n if (absoluteUrlParts.length > 4) {\n const rootUrlPrefixIndex = absoluteUrl.indexOf(absoluteUrlParts[3]);\n absolutePath += absoluteUrl.substring(rootUrlPrefixIndex) + path;\n } else {\n absolutePath += path;\n }\n\n return absolutePath.replace(/\\/\\/+/g, '/');\n};\n\nexport default absoluteUrl;\n","// TODO: figure out where else to put this function\nconst addServers = (servers, store) => {\n if (!servers || !store) {\n throw new Error('The servers and store must be defined');\n }\n\n Object.keys(servers).forEach(serverType => {\n const endpoints = servers[serverType];\n endpoints.forEach(endpoint => {\n const server = Object.assign({}, endpoint);\n server.type = serverType;\n\n store.dispatch({\n type: 'ADD_SERVER',\n server,\n });\n });\n });\n};\n\nexport default addServers;\n","import cornerstone from 'cornerstone-core';\nimport cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';\nimport { api } from 'dicomweb-client';\nimport DICOMWeb from '../DICOMWeb';\n\nimport errorHandler from '../errorHandler';\nimport getXHRRetryRequestHook from './xhrRetryRequestHook';\n\nconst getImageId = imageObj => {\n if (!imageObj) {\n return;\n }\n\n return typeof imageObj.getImageId === 'function'\n ? imageObj.getImageId()\n : imageObj.url;\n};\n\nconst findImageIdOnStudies = (studies, displaySetInstanceUID) => {\n const study = studies.find(study => {\n const displaySet = study.displaySets.some(\n displaySet => displaySet.displaySetInstanceUID === displaySetInstanceUID\n );\n return displaySet;\n });\n const { series = [] } = study;\n const { instances = [] } = series[0] || {};\n const instance = instances[0];\n\n return getImageId(instance);\n};\n\nconst someInvalidStrings = strings => {\n const stringsArray = Array.isArray(strings) ? strings : [strings];\n const emptyString = string => !string;\n let invalid = stringsArray.some(emptyString);\n return invalid;\n};\n\nconst getImageInstance = dataset => {\n return dataset && dataset.images && dataset.images[0];\n};\n\nconst getImageInstanceId = imageInstance => {\n return getImageId(imageInstance);\n};\n\nconst fetchIt = (url, headers = DICOMWeb.getAuthorizationHeader()) => {\n return fetch(url, headers).then(response => response.arrayBuffer());\n};\n\nconst cornerstoneRetriever = imageId => {\n return cornerstone.loadAndCacheImage(imageId).then(image => {\n return image && image.data && image.data.byteArray.buffer;\n });\n};\n\nconst wadorsRetriever = (\n url,\n studyInstanceUID,\n seriesInstanceUID,\n sopInstanceUID,\n headers = DICOMWeb.getAuthorizationHeader(),\n errorInterceptor = errorHandler.getHTTPErrorHandler()\n) => {\n const config = {\n url,\n headers,\n errorInterceptor,\n requestHooks: [getXHRRetryRequestHook()],\n };\n const dicomWeb = new api.DICOMwebClient(config);\n\n return dicomWeb.retrieveInstance({\n studyInstanceUID,\n seriesInstanceUID,\n sopInstanceUID,\n });\n};\n\nconst getImageLoaderType = imageId => {\n const loaderRegExp = /^\\w+\\:/;\n const loaderType = loaderRegExp.exec(imageId);\n\n return (\n (loaderRegExp.lastIndex === 0 &&\n loaderType &&\n loaderType[0] &&\n loaderType[0].replace(':', '')) ||\n ''\n );\n};\n\nclass DicomLoaderService {\n getLocalData(dataset, studies) {\n if (dataset && dataset.localFile) {\n // Use referenced imageInstance\n const imageInstance = getImageInstance(dataset);\n let imageId = getImageInstanceId(imageInstance);\n\n // or Try to get it from studies\n if (someInvalidStrings(imageId)) {\n imageId = findImageIdOnStudies(studies, dataset.displaySetInstanceUID);\n }\n\n if (!someInvalidStrings(imageId)) {\n return cornerstoneWADOImageLoader.wadouri.loadFileRequest(imageId);\n }\n }\n }\n\n getDataByImageType(dataset) {\n const imageInstance = getImageInstance(dataset);\n\n if (imageInstance) {\n const imageId = getImageInstanceId(imageInstance);\n let getDicomDataMethod = fetchIt;\n const loaderType = getImageLoaderType(imageId);\n\n switch (loaderType) {\n case 'dicomfile':\n getDicomDataMethod = cornerstoneRetriever.bind(this, imageId);\n break;\n case 'wadors':\n const url = imageInstance.getData().wadoRoot;\n const studyInstanceUID = imageInstance.getStudyInstanceUID();\n const seriesInstanceUID = imageInstance.getSeriesInstanceUID();\n const sopInstanceUID = imageInstance.getSOPInstanceUID();\n const invalidParams = someInvalidStrings([\n url,\n studyInstanceUID,\n seriesInstanceUID,\n sopInstanceUID,\n ]);\n if (invalidParams) {\n return;\n }\n\n getDicomDataMethod = wadorsRetriever.bind(\n this,\n url,\n studyInstanceUID,\n seriesInstanceUID,\n sopInstanceUID\n );\n break;\n case 'wadouri':\n // Strip out the image loader specifier\n imageId = imageId.substring(imageId.indexOf(':') + 1);\n\n if (someInvalidStrings(imageId)) {\n return;\n }\n getDicomDataMethod = fetchIt.bind(this, imageId);\n break;\n }\n\n return getDicomDataMethod();\n }\n }\n\n getDataByDatasetType(dataset) {\n const {\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID,\n authorizationHeaders,\n wadoRoot,\n wadoUri,\n } = dataset;\n // Retrieve wadors or just try to fetch wadouri\n if (!someInvalidStrings(wadoRoot)) {\n return wadorsRetriever(\n wadoRoot,\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID,\n authorizationHeaders\n );\n } else if (!someInvalidStrings(wadoUri)) {\n return fetchIt(wadoUri, { headers: authorizationHeaders });\n }\n }\n\n *getLoaderIterator(dataset, studies) {\n yield this.getLocalData(dataset, studies);\n yield this.getDataByImageType(dataset);\n yield this.getDataByDatasetType(dataset);\n }\n\n findDicomDataPromise(dataset, studies) {\n const loaderIterator = this.getLoaderIterator(dataset, studies);\n // it returns first valid retriever method.\n for (const loader of loaderIterator) {\n if (loader) {\n return loader;\n }\n }\n\n // in case of no valid loader\n throw new Error('Invalid dicom data loader');\n }\n}\n\nconst dicomLoaderService = new DicomLoaderService();\n\nexport default dicomLoaderService;\n","/* Enabled JPEG images downloading on IE11. */\nconst b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {\n const byteCharacters = atob(b64Data);\n const byteArrays = [];\n\n for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {\n const slice = byteCharacters.slice(offset, offset + sliceSize);\n\n const byteNumbers = new Array(slice.length);\n for (let i = 0; i < slice.length; i++) {\n byteNumbers[i] = slice.charCodeAt(i);\n }\n\n const byteArray = new Uint8Array(byteNumbers);\n byteArrays.push(byteArray);\n }\n\n const blob = new Blob(byteArrays, { type: contentType });\n return blob;\n};\n\nexport default b64toBlob;\n","import studyMetadataManager from './studyMetadataManager';\n\n/**\n * Study schema\n *\n * @typedef {Object} Study\n * @property {Array} seriesList -\n * @property {Object} seriesMap -\n * @property {Object} seriesLoader -\n * @property {string} wadoUriRoot -\n * @property {string} wadoRoot -\n * @property {string} qidoRoot -\n * @property {string} patientName -\n * @property {string} patientId -\n * @property {number} patientAge -\n * @property {number} patientSize -\n * @property {number} patientWeight -\n * @property {string} accessionNumber -\n * @property {string} studyDate -\n * @property {string} studyTime -\n * @property {string} modalities -\n * @property {string} studyDescription -\n * @property {string} imageCount -\n * @property {string} studyInstanceUid -\n * @property {string} institutionName -\n * @property {Array} displaySets -\n */\n\n/**\n * Factory function to load and cache derived display sets.\n *\n * @param {object} referencedDisplaySet Display set\n * @param {string} referencedDisplaySet.displaySetInstanceUid Display set instance uid\n * @param {string} referencedDisplaySet.seriesDate\n * @param {string} referencedDisplaySet.seriesTime\n * @param {string} referencedDisplaySet.seriesInstanceUid\n * @param {string} referencedDisplaySet.seriesNumber\n * @param {string} referencedDisplaySet.seriesDescription\n * @param {number} referencedDisplaySet.numImageFrames\n * @param {string} referencedDisplaySet.frameRate\n * @param {string} referencedDisplaySet.modality\n * @param {boolean} referencedDisplaySet.isMultiFrame\n * @param {number} referencedDisplaySet.instanceNumber\n * @param {boolean} referencedDisplaySet.isReconstructable\n * @param {string} referencedDisplaySet.studyInstanceUid\n * @param {Array} referencedDisplaySet.sopClassUids\n * @param {Study[]} studies Collection of studies\n * @param {object} logger\n * @param {object} snackbar\n * @returns void\n */\nasync function loadAndCacheDerivedDisplaySets(\n referencedDisplaySet,\n studies,\n logger,\n snackbar\n) {\n const { StudyInstanceUID, SeriesInstanceUID } = referencedDisplaySet;\n const promises = [];\n const studyMetadata = studyMetadataManager.get(StudyInstanceUID);\n\n if (!studyMetadata) {\n return promises;\n }\n\n const derivedDisplaySets = studyMetadata.getDerivedDatasets({\n referencedSeriesInstanceUID: SeriesInstanceUID,\n });\n\n if (!derivedDisplaySets.length) {\n return promises;\n }\n\n // Filter by type\n const displaySetsPerModality = {};\n\n derivedDisplaySets.forEach(displaySet => {\n const Modality = displaySet.Modality;\n\n if (displaySetsPerModality[Modality] === undefined) {\n displaySetsPerModality[Modality] = [];\n }\n\n displaySetsPerModality[Modality].push(displaySet);\n });\n\n // For each type, see if any are loaded, if not load the most recent.\n await Promise.all(\n Object.keys(displaySetsPerModality).map(async key => {\n const displaySets = displaySetsPerModality[key];\n\n const isLoaded = displaySets.some(displaySet => displaySet.isLoaded);\n if (isLoaded) {\n return;\n }\n\n if (displaySets.some(displaySet => displaySet.loadError)) {\n return;\n }\n\n // find most recent and load it.\n let recentDateTime = 0;\n let recentDisplaySet = displaySets[0];\n\n displaySets.forEach(displaySet => {\n const dateTime = Number(\n `${displaySet.SeriesDate}${displaySet.SeriesTime}`\n );\n if (dateTime > recentDateTime) {\n recentDateTime = dateTime;\n recentDisplaySet = displaySet;\n }\n });\n\n try {\n if (\n recentDisplaySet.hasOwnProperty('getSourceDisplaySet') &&\n typeof recentDisplaySet.getSourceDisplaySet === 'function'\n ) {\n if (recentDisplaySet.Modality === 'SEG' && logger) {\n const onDisplaySetLoadFailureHandler = error => {\n logger.error({ error, message: error.message });\n snackbar.show({\n title: 'DICOM Segmentation Loader',\n message: error.message,\n type: 'error',\n autoClose: true,\n });\n };\n\n let activatedLabelmapIndex = -1;\n while (activatedLabelmapIndex == -1) {\n const {\n referencedDisplaySet,\n activatedLabelmapPromise,\n } = await recentDisplaySet.getSourceDisplaySet(\n studies,\n true,\n onDisplaySetLoadFailureHandler\n );\n\n activatedLabelmapIndex = await activatedLabelmapPromise;\n const selectionFired = new CustomEvent(\n 'extensiondicomsegmentationsegselected',\n {\n detail: { activatedLabelmapIndex: activatedLabelmapIndex },\n }\n );\n document.dispatchEvent(selectionFired);\n\n const lastDateTime = Number(\n `${recentDisplaySet.SeriesDate}${recentDisplaySet.SeriesTime}`\n );\n recentDateTime = 0;\n displaySets.forEach(displaySet => {\n const dateTime = Number(\n `${displaySet.SeriesDate}${displaySet.SeriesTime}`\n );\n if (dateTime > recentDateTime && dateTime < lastDateTime) {\n recentDateTime = dateTime;\n recentDisplaySet = displaySet;\n }\n });\n }\n } else {\n await recentDisplaySet.getSourceDisplaySet(studies);\n }\n } else {\n await recentDisplaySet.load(referencedDisplaySet, studies);\n }\n } catch (error) {\n recentDisplaySet.isLoaded = false;\n recentDisplaySet.loadError = true;\n logger.error({ error, message: error.message });\n snackbar.show({\n title: 'Error loading derived display set:',\n message: error.message,\n type: 'error',\n error,\n autoClose: false,\n });\n }\n })\n );\n\n /*\n * TODO: Improve the way we notify parts of the app\n * that depends on derived display sets to be loaded.\n * (Implement pubsub for better tracking of derived display sets)\n */\n const event = new CustomEvent('deriveddisplaysetsloadedandcached');\n document.dispatchEvent(event);\n}\n\nexport default loadAndCacheDerivedDisplaySets;\n","import lib from 'query-string';\n\nconst PARAM_SEPARATOR = ';';\nconst PARAM_PATTERN_IDENTIFIER = ':';\n\nfunction toLowerCaseFirstLetter(word) {\n return word[0].toLowerCase() + word.slice(1);\n}\nconst getQueryFilters = (location = {}) => {\n const { search } = location;\n\n if (!search) {\n return;\n }\n\n const searchParameters = parse(search);\n const filters = {};\n\n Object.entries(searchParameters).forEach(([key, value]) => {\n filters[toLowerCaseFirstLetter(key)] = value;\n });\n\n return filters;\n};\n\nconst decode = (strToDecode = '') => {\n try {\n const decoded = window.atob(strToDecode);\n return decoded;\n } catch (e) {\n return strToDecode;\n }\n};\n\nconst parse = toParse => {\n if (toParse) {\n return lib.parse(toParse);\n }\n\n return {};\n};\nconst parseParam = paramStr => {\n const _paramDecoded = decode(paramStr);\n if (_paramDecoded && typeof _paramDecoded === 'string') {\n return _paramDecoded.split(PARAM_SEPARATOR);\n }\n};\n\nconst replaceParam = (path = '', paramKey, paramValue) => {\n const paramPattern = `${PARAM_PATTERN_IDENTIFIER}${paramKey}`;\n if (paramValue) {\n return path.replace(paramPattern, paramValue);\n }\n\n return path;\n};\n\nconst isValidPath = path => {\n const paramPatternPiece = `/${PARAM_PATTERN_IDENTIFIER}`;\n return path.indexOf(paramPatternPiece) < 0;\n};\n\nconst queryString = {\n getQueryFilters,\n};\n\nconst paramString = {\n isValidPath,\n parseParam,\n replaceParam,\n};\n\nexport { parse, queryString, paramString };\n","export default function makeDeferred() {\n let reject, resolve, promise = new Promise(function (res, rej) {\n resolve = res;\n reject = rej;\n });\n return Object.freeze({ promise, resolve, reject });\n}\n","\nexport default class Queue {\n\n constructor(limit) {\n this.limit = limit;\n this.size = 0;\n this.awaiting = null;\n }\n\n /**\n * Creates a new \"proxy\" function associated with the current execution queue\n * instance. When the returned function is invoked, the queue limit is checked\n * to make sure the limit of scheduled tasks is repected (throwing an\n * exception when the limit has been reached and before calling the original\n * function). The original function is only invoked after all the previously\n * scheduled tasks have finished executing (their returned promises have\n * resolved/rejected);\n *\n * @param {function} task The function whose execution will be associated\n * with the current Queue instance;\n * @returns {function} The \"proxy\" function bound to the current Queue\n * instance;\n */\n bind(task) {\n return bind(this, task);\n }\n\n bindSafe(task, onError) {\n const boundTask = bind(this, task);\n return async function safeTask(...args) {\n try {\n return await boundTask(...args);\n } catch (e) {\n onError(e);\n }\n };\n }\n}\n\n/**\n * Utils\n */\n\nfunction bind(queue, task) {\n const cleaner = clean.bind(null, queue);\n return async function boundTask(...args) {\n if (queue.size >= queue.limit) {\n throw new Error('Queue limit reached');\n }\n const promise = chain(queue.awaiting, task, args);\n queue.awaiting = promise.then(cleaner, cleaner);\n queue.size++;\n return promise;\n };\n}\n\nfunction clean(queue) {\n if (queue.size > 0 && --queue.size === 0) {\n queue.awaiting = null;\n }\n}\n\nasync function chain(prev, task, args) {\n await prev;\n return task(...args);\n}\n","/**\n * Constants\n */\n\nconst SEPARATOR = '/';\n\n/**\n * API\n */\n\n/**\n * Add values to a list hierarchically.\n * @ For example:\n * addToList([], 'a', 'b', 'c');\n * will add the following hierarchy to the list:\n * a > b > c\n * resulting in the following array:\n * [['a', [['b', ['c']]]]]\n * @param {Array} list The target list;\n * @param {...string} values The values to be hierarchically added to the list;\n * @returns {Array} Returns the provided list possibly updated with the given\n * values or null when a bad list (not an actual array) is provided\n */\nfunction addToList(list, ...values) {\n if (Array.isArray(list)) {\n if (values.length > 0) {\n addValuesToList(list, values);\n }\n return list;\n }\n return null;\n}\n\n/**\n * Iterates through the provided hierarchical list executing the callback\n * once for each leaf-node of the tree. The ancestors of the leaf-node being\n * visited are passed to the callback function along with the leaf-node in\n * the exact same order they appear on the tree (from root to leaf);\n * @ For example, if the hierachy `a > b > c` appears on the tree (\"a\" being\n * the root and \"c\" being the leaf) the callback function will be called as:\n * callback('a', 'b', 'c');\n * @param {Array} list The hierarchical list to be iterated\n * @param {function} callback The callback which will be exected once for\n * each leaf-node of the hierarchical list;\n * @returns {Array} Returns the provided list or null for bad arguments;\n */\nfunction forEach(list, callback) {\n if (Array.isArray(list)) {\n if (typeof callback === 'function') {\n forEachValue(list, callback);\n }\n return list;\n }\n return null;\n}\n\n/**\n * Retrieves an item from the given hierarchical list based on an index (number)\n * or a path (string).\n * @ For example:\n * getItem(list, '1/0/4')\n * will retrieve the fourth grandchild, from the first child of the second\n * element of the list;\n * @param {Array} list The source list;\n * @param {string|number} indexOrPath The index of the element inside list\n * (number) or the path to reach the desired element (string). The slash \"/\"\n * character is cosidered the path separator;\n */\nfunction getItem(list, indexOrPath) {\n if (Array.isArray(list)) {\n let subpath = null;\n let index = typeof indexOrPath === 'number' ? indexOrPath : -1;\n if (typeof indexOrPath === 'string') {\n const separator = indexOrPath.indexOf(SEPARATOR);\n if (separator > 0) {\n index = parseInt(indexOrPath.slice(0, separator), 10);\n if (separator + 1 < indexOrPath.length) {\n subpath = indexOrPath.slice(separator + 1, indexOrPath.length);\n }\n } else {\n index = parseInt(indexOrPath, 10);\n }\n }\n if (index >= 0 && index < list.length) {\n const item = list[index];\n if (isSublist(item)) {\n if (subpath !== null) {\n return getItem(item[1], subpath);\n }\n return item[0];\n }\n return item;\n }\n }\n}\n\n/**\n * Pretty-print the provided hierarchical list;\n * @param {Array} list The source list;\n * @returns {string} The textual representation of the hierarchical list;\n */\nfunction print(list) {\n let text = '';\n if (Array.isArray(list)) {\n let prev = [];\n forEachValue(list, function(...args) {\n let prevLen = prev.length;\n for (let i = 0, l = args.length; i < l; ++i) {\n if (i < prevLen && args[i] === prev[i]) {\n continue;\n }\n text += ' '.repeat(i) + args[i] + '\\n';\n }\n prev = args;\n });\n }\n return text;\n}\n\n/**\n * Utils\n */\n\nfunction forEachValue(list, callback) {\n for (let i = 0, l = list.length; i < l; ++i) {\n let item = list[i];\n if (isSublist(item)) {\n if (item[1].length > 0) {\n forEachValue(item[1], callback.bind(null, item[0]));\n continue;\n }\n item = item[0];\n }\n callback(item);\n }\n}\n\nfunction addValuesToList(list, values) {\n let value = values.shift();\n let index = add(list, value);\n if (index >= 0) {\n if (values.length > 0) {\n let sublist = list[index];\n if (!isSublist(sublist)) {\n sublist = toSublist(value);\n list[index] = sublist;\n }\n return addValuesToList(sublist[1], values);\n }\n return true;\n }\n return false;\n}\n\nfunction add(list, value) {\n let index = find(list, value);\n if (index === -2) {\n index = list.push(value) - 1;\n }\n return index;\n}\n\nfunction find(list, value) {\n if (typeof value === 'string') {\n for (let i = 0, l = list.length; i < l; ++i) {\n let item = list[i];\n if (item === value || (isSublist(item) && item[0] === value)) {\n return i;\n }\n }\n return -2;\n }\n return -1;\n}\n\nfunction isSublist(subject) {\n return (\n Array.isArray(subject) &&\n subject.length === 2 &&\n typeof subject[0] === 'string' &&\n Array.isArray(subject[1])\n );\n}\n\nfunction toSublist(value) {\n return [value + '', []];\n}\n\n/**\n * Exports\n */\n\nexport { addToList, getItem, forEach, print };\n","import makeDeferred from './makeDeferred';\n\n/**\n * Constants\n */\n\nconst TYPE = Symbol('Type');\nconst TASK = Symbol('Task');\nconst LIST = Symbol('List');\n\n/**\n * Public Methods\n */\n\n/**\n * Creates an instance of a task list\n * @returns {Object} A task list object\n */\nfunction createList() {\n return objectWithType(LIST, {\n head: null,\n named: Object.create(null),\n observers: [],\n });\n}\n\n/**\n * Checks if the given argument is a List instance\n * @param {any} subject The value to be tested\n * @returns {boolean} true if a valid List instance is given, false otherwise\n */\nfunction isList(subject) {\n return isOfType(LIST, subject);\n}\n\n/**\n * Creates an instance of a task\n * @param {Object} list The List instance related to this task\n * @param {Object} next The next Task instance to link to\n * @returns {Object} A task object\n */\nfunction createTask(list, next) {\n return objectWithType(TASK, {\n list: isList(list) ? list : null,\n next: isTask(next) ? next : null,\n failed: false,\n awaiting: null,\n progress: 0.0,\n });\n}\n\n/**\n * Checks if the given argument is a Task instance\n * @param {any} subject The value to be tested\n * @returns {boolean} true if a valid Task instance is given, false otherwise\n */\nfunction isTask(subject) {\n return isOfType(TASK, subject);\n}\n\n/**\n * Appends a new Task to the given List instance and notifies the list observers\n * @param {Object} list A List instance\n * @returns {Object} The new Task instance appended to the List or null if the\n * given List instanc is not valid\n */\nfunction increaseList(list) {\n if (isList(list)) {\n const task = createTask(list, list.head);\n list.head = task;\n notify(list, getOverallProgress(list));\n return task;\n }\n return null;\n}\n\n/**\n * Updates the internal progress value of the given Task instance and notifies\n * the observers of the associated list.\n * @param {Object} task The Task instance to be updated\n * @param {number} value A number between 0 (inclusive) and 1 (exclusive)\n * indicating the progress of the task;\n * @returns {void} Nothing is returned\n */\nfunction update(task, value) {\n if (isTask(task) && isValidProgress(value) && value < 1.0) {\n if (task.progress !== value) {\n task.progress = value;\n if (isList(task.list)) {\n notify(task.list, getOverallProgress(task.list));\n }\n }\n }\n}\n\n/**\n * Sets a Task instance as finished (progress = 1.0), freezes it in order to\n * prevent further modifications and notifies the observers of the associated\n * list.\n * @param {Object} task The Task instance to be finalized\n * @returns {void} Nothing is returned\n */\nfunction finish(task) {\n if (isTask(task)) {\n task.progress = 1.0;\n task.awaiting = null;\n Object.freeze(task);\n if (isList(task.list)) {\n notify(task.list, getOverallProgress(task.list));\n }\n }\n}\n\n/**\n * Generate a summarized snapshot of the current status of the given task List\n * @param {Object} list The List instance to be scanned\n * @returns {Object} An obeject representing the summarized status of the list\n */\nfunction getOverallProgress(list) {\n const status = createStatus();\n if (isList(list)) {\n let task = list.head;\n while (isTask(task)) {\n status.total++;\n if (isValidProgress(task.progress)) {\n status.partial += task.progress;\n if (task.progress === 1.0 && task.failed) status.failures++;\n }\n task = task.next;\n }\n }\n if (status.total > 0) {\n status.progress = status.partial / status.total;\n }\n return Object.freeze(status);\n}\n\n/**\n * Adds a Task instance to the given list that waits on a given \"thenable\". When\n * the thenable resolves the \"finish\" method is called on the newly created\n * instance thus notifying the observers of the list.\n * @param {Object} list The List instance to which the new task will be added\n * @param {Object|Promise} thenable The thenable to be waited on\n * @returns {Object} A reference to the newly created Task;\n */\nfunction waitOn(list, thenable) {\n const task = increaseList(list);\n if (isTask(task)) {\n task.awaiting = Promise.resolve(thenable).then(\n function() {\n finish(task);\n },\n function() {\n task.failed = true;\n finish(task);\n }\n );\n return task;\n }\n return null;\n}\n\n/**\n * Adds a Task instance to the given list using a deferred (a Promise that can\n * be externally resolved) notifying the observers of the list.\n * @param {Object} list The List instance to which the new task will be added\n * @returns {Object} An object with references to the created deferred and task\n */\nfunction addDeferred(list) {\n const deferred = makeDeferred();\n const task = waitOn(list, deferred.promise);\n return Object.freeze({\n deferred,\n task,\n });\n}\n\n/**\n * Assigns a name to a specific task of the list\n * @param {Object} list The List instance whose task will be named\n * @param {Object} task The specified Task instance\n * @param {string} name The name of the task\n * @returns {boolean} Returns true on success, false otherwise\n */\nfunction setTaskName(list, task, name) {\n if (\n contains(list, task) &&\n list.named !== null &&\n typeof list.named === 'object' &&\n typeof name === 'string'\n ) {\n list.named[name] = task;\n return true;\n }\n return false;\n}\n\n/**\n * Retrieves a task by name\n * @param {Object} list The List instance whose task will be retrieved\n * @param {string} name The name of the task to be retrieved\n * @returns {Object} The Task instance or null if not found\n */\nfunction getTaskByName(list, name) {\n if (\n isList(list) &&\n list.named !== null &&\n typeof list.named === 'object' &&\n typeof name === 'string'\n ) {\n const task = list.named[name];\n if (isTask(task)) {\n return task;\n }\n }\n return null;\n}\n\n/**\n * Adds an observer (callback function) to a given List instance\n * @param {Object} list The List instance to which the observer will be appended\n * @param {Function} observer The observer (function) that will be executed\n * every time a change happens within the list\n * @returns {boolean} Returns true on success and false otherewise\n */\nfunction addObserver(list, observer) {\n if (\n isList(list) &&\n Array.isArray(list.observers) &&\n typeof observer === 'function'\n ) {\n list.observers.push(observer);\n return true;\n }\n return false;\n}\n\n/**\n * Removes an observer (callback function) from a given List instance\n * @param {Object} list The instance List from which the observer will removed\n * @param {Function} observer The observer function to be removed\n * @returns {boolean} Returns true on success and false otherewise\n */\nfunction removeObserver(list, observer) {\n if (\n isList(list) &&\n Array.isArray(list.observers) &&\n list.observers.length > 0\n ) {\n const index = list.observers.indexOf(observer);\n if (index >= 0) {\n list.observers.splice(index, 1);\n return true;\n }\n }\n return false;\n}\n\n/**\n * Utils\n */\n\nfunction createStatus() {\n return Object.seal({\n total: 0,\n partial: 0.0,\n progress: 0.0,\n failures: 0,\n });\n}\n\nfunction objectWithType(type, object) {\n return Object.seal(Object.defineProperty(object, TYPE, { value: type }));\n}\n\nfunction isOfType(type, subject) {\n return (\n subject !== null && typeof subject === 'object' && subject[TYPE] === type\n );\n}\n\nfunction isValidProgress(value) {\n return typeof value === 'number' && value >= 0.0 && value <= 1.0;\n}\n\nfunction contains(list, task) {\n if (isList(list) && isTask(task)) {\n let item = list.head;\n while (isTask(item)) {\n if (item === task) {\n return true;\n }\n item = item.next;\n }\n }\n return false;\n}\n\nfunction notify(list, data) {\n if (\n isList(list) &&\n Array.isArray(list.observers) &&\n list.observers.length > 0\n ) {\n list.observers.slice().forEach(function(observer) {\n if (typeof observer === 'function') {\n try {\n observer(data, list);\n } catch (e) {\n /* Oops! */\n }\n }\n });\n }\n}\n\n/**\n * Exports\n */\n\nexport {\n createList,\n isList,\n createTask,\n isTask,\n increaseList,\n update,\n finish,\n getOverallProgress,\n waitOn,\n addDeferred,\n setTaskName,\n getTaskByName,\n addObserver,\n removeObserver,\n};\n","import ObjectPath from './objectPath';\nimport StackManager from './StackManager.js';\nimport absoluteUrl from './absoluteUrl';\nimport addServers from './addServers';\nimport guid from './guid';\nimport sortBy from './sortBy.js';\nimport studyMetadataManager from './studyMetadataManager';\nimport writeScript from './writeScript.js';\nimport DicomLoaderService from './dicomLoaderService.js';\nimport b64toBlob from './b64toBlob.js';\nimport loadAndCacheDerivedDisplaySets from './loadAndCacheDerivedDisplaySets.js';\nimport * as urlUtil from './urlUtil';\nimport makeDeferred from './makeDeferred';\nimport makeCancelable from './makeCancelable';\nimport hotkeys from './hotkeys';\nimport Queue from './Queue';\nimport isDicomUid from './isDicomUid';\nimport resolveObjectPath from './resolveObjectPath';\nimport * as hierarchicalListUtils from './hierarchicalListUtils';\nimport * as progressTrackingUtils from './progressTrackingUtils';\nimport xhrRetryRequestHook from './xhrRetryRequestHook';\n\nconst utils = {\n guid,\n ObjectPath,\n absoluteUrl,\n addServers,\n sortBy,\n writeScript,\n b64toBlob,\n StackManager,\n studyMetadataManager,\n DicomLoaderService,\n urlUtil,\n loadAndCacheDerivedDisplaySets,\n makeDeferred,\n makeCancelable,\n hotkeys,\n Queue,\n isDicomUid,\n resolveObjectPath,\n hierarchicalListUtils,\n progressTrackingUtils,\n xhrRetryRequestHook,\n};\n\nexport {\n guid,\n ObjectPath,\n absoluteUrl,\n addServers,\n sortBy,\n writeScript,\n b64toBlob,\n StackManager,\n studyMetadataManager,\n DicomLoaderService,\n urlUtil,\n loadAndCacheDerivedDisplaySets,\n makeDeferred,\n makeCancelable,\n hotkeys,\n Queue,\n isDicomUid,\n resolveObjectPath,\n hierarchicalListUtils,\n progressTrackingUtils,\n xhrRetryRequestHook,\n};\n\nexport default utils;\n","/* jshint -W060 */\nimport absoluteUrl from './absoluteUrl';\n\nexport default function writeScript(fileName, callback) {\n const script = document.createElement('script');\n script.src = absoluteUrl(fileName);\n script.onload = () => {\n if (typeof callback === 'function') {\n callback(script);\n }\n };\n\n document.body.appendChild(script);\n}\n","export default function makeCancelable(thenable) {\n let isCanceled = false;\n const promise = Promise.resolve(thenable).then(\n function(result) {\n if (isCanceled) throw Object.freeze({ isCanceled });\n return result;\n },\n function(error) {\n if (isCanceled) throw Object.freeze({ isCanceled, error });\n throw error;\n }\n );\n return Object.assign(Object.create(promise), {\n then: promise.then.bind(promise),\n cancel() {\n isCanceled = true;\n },\n });\n}\n","export default function isDicomUid(subject) {\n const regex = /^\\d+(?:\\.\\d+)*$/;\n return typeof subject === 'string' && regex.test(subject.trim());\n}\n","export default function resolveObjectPath(root, path, defaultValue) {\n if (root !== null && typeof root === 'object' && typeof path === 'string') {\n let value,\n separator = path.indexOf('.');\n if (separator >= 0) {\n return resolveObjectPath(\n root[path.slice(0, separator)],\n path.slice(separator + 1, path.length),\n defaultValue\n );\n }\n value = root[path];\n return value === undefined && defaultValue !== undefined\n ? defaultValue\n : value;\n }\n}\n","import cornerstone from 'cornerstone-core';\nimport getImageId from '../utils/getImageId.js';\n\nconst noop = () => {};\n\nexport class StudyPrefetcher {\n options = {\n order: 'closest',\n displaySetCount: 1,\n onImageCached: noop,\n requestType: 'prefetch',\n preventCache: false,\n prefetchDisplaySetsTimeout: 300,\n maxNumPrefetchRequests: 100,\n includeActiveDisplaySet: false,\n };\n\n constructor(studies, options) {\n this.studies = studies || [];\n\n if (options) {\n this.options = { ...this.options, ...options };\n this.options.requestType = 'prefetch';\n }\n\n cornerstone.events.addEventListener(\n 'cornerstoneimagecachefull.StudyPrefetcher',\n this.cacheFullHandler\n );\n }\n\n /**\n * Remove previously set event listeners and stop prefetching.\n */\n destroy() {\n this.stopPrefetching();\n cornerstone.events.removeEventListener(\n 'cornerstoneimagecachefull.StudyPrefetcher',\n this.cacheFullHandler\n );\n }\n\n /**\n * Get StudyPrefetcher singleton instance.\n *\n * @param {array} studies\n * @param {object} options\n * @returns\n */\n static getInstance(studies = [], options) {\n if (!StudyPrefetcher.instance) {\n StudyPrefetcher.instance = new StudyPrefetcher(studies, options);\n }\n\n if (options) {\n this.options = { ...this.options, ...options };\n this.options.requestType = 'prefetch';\n }\n\n return StudyPrefetcher.instance;\n }\n\n /**\n * OHIF study metadata instances.\n *\n * @param {array} studies\n */\n setStudies(studies) {\n this.stopPrefetching();\n this.studies = studies;\n }\n\n /**\n * Get previously prefetched element.\n *\n * @returns {HTMLElement} Previously prefetched element.\n */\n getElement() {\n return this.element;\n }\n\n /**\n * Prefetch related display sets based on cornerstone viewport element\n * with previously set options.\n *\n * @param {*} element\n * @param {string} displaySetInstanceUID the display set instance uid\n * @returns\n */\n prefetch(element, displaySetInstanceUID) {\n if (!this.studies || !this.studies.length) {\n return;\n }\n\n this.element = element;\n try {\n this.enabledElement = cornerstone.getEnabledElement(element);\n } catch {\n throw new Error('Failed to find the enabled element');\n }\n\n this.stopPrefetching();\n this.prefetchDisplaySets(displaySetInstanceUID);\n }\n\n /**\n * Stop prefetching images.\n */\n stopPrefetching() {\n cornerstone.imageLoadPoolManager.clearRequestStack('prefetch');\n }\n\n /**\n * Prefetch display sets async.\n *\n * @param {HTMLElement} element cornerstone viewport element\n * @param {number} timeout\n */\n prefetchDisplaySetsAsync(element, timeout) {\n try {\n this.enabledElement = cornerstone.getEnabledElement(element);\n } catch {\n throw new Error('Failed to find the enabled element');\n }\n timeout = timeout || this.options.prefetchDisplaySetsTimeout;\n clearTimeout(this.prefetchDisplaySetsHandler);\n this.prefetchDisplaySetsHandler = setTimeout(() => {\n this.prefetchDisplaySets(element);\n }, timeout);\n }\n\n /**\n * Extract all image ids from all display sets to be fetched and\n * call method to add images to request pool manager.\n *\n * @param {string} displaySetInstanceUID the display set instance uid\n */\n prefetchDisplaySets(displaySetInstanceUID) {\n const displaySetsToPrefetch = this.getDisplaySetsToPrefetch(\n displaySetInstanceUID\n );\n const imageIds = this.getImageIdsFromDisplaySets(displaySetsToPrefetch);\n this.prefetchImageIds(imageIds);\n }\n\n /**\n * Add image ids to request pool manager.\n *\n * @param {array} imageIds\n */\n prefetchImageIds(imageIds) {\n const nonCachedImageIds = this.filterCachedImageIds(imageIds);\n const imageLoadPoolManager = cornerstone.imageLoadPoolManager;\n\n imageLoadPoolManager.maxNumRequests = {\n ...imageLoadPoolManager.maxNumRequests,\n prefetch: this.options.maxNumPrefetchRequests,\n };\n\n let requestFn;\n if (this.options.preventCache) {\n requestFn = id => cornerstone.loadImage(id);\n } else {\n requestFn = id => cornerstone.loadAndCacheImage(id);\n }\n\n nonCachedImageIds.forEach(imageId => {\n imageLoadPoolManager.addRequest(\n requestFn.bind(this, imageId),\n this.options.requestType,\n {\n imageId,\n }\n );\n });\n }\n\n /**\n * Get study by cornerstone image instance.\n *\n * @param {object} image\n * @returns\n */\n getStudy(image) {\n const StudyInstanceUID = cornerstone.metaData.get(\n 'StudyInstanceUID',\n image.imageId\n );\n const studies = this.studies;\n return studies.find(\n study => study.getData().StudyInstanceUID === StudyInstanceUID\n );\n }\n\n /**\n * Get study series by cornerstone image instance.\n *\n * @param {object} study OHIF study instance\n * @param {object} image cornerstone image instance object\n * @returns\n */\n getSeries(study, image) {\n const SeriesInstanceUID = cornerstone.metaData.get(\n 'SeriesInstanceUID',\n image.imageId\n );\n return study.getSeriesByUID(SeriesInstanceUID);\n }\n\n /**\n * Get sop instance by cornerstone image instance.\n *\n * @param {array} series\n * @param {object} image\n * @returns\n */\n getInstance(series, image) {\n const instanceMetadata = cornerstone.metaData.get(\n 'instance',\n image.imageId\n );\n return series.getInstanceByUID(instanceMetadata.SOPInstanceUID);\n }\n\n /**\n * Returns the display set with given uid.\n *\n * @param {string} displaySetInstanceUID the display set instance uid\n * @returns {object} displaySet\n */\n getDisplaySetByUID(displaySetInstanceUID) {\n let displaySet;\n this.studies.forEach(study => {\n const ds = study.displaySets.find(\n ds => ds.displaySetInstanceUID === displaySetInstanceUID\n );\n if (ds) {\n displaySet = ds;\n }\n });\n return displaySet;\n }\n\n /**\n * Get display set by SOPInstanceUID.\n *\n * @param {array} displaySets\n * @param {object} instance\n * @returns\n */\n getDisplaySetBySOPInstanceUID(displaySets, instance) {\n return displaySets.find(displaySet => {\n return displaySet.images.some(displaySetImage => {\n return displaySetImage.SOPInstanceUID === instance.SOPInstanceUID;\n });\n });\n }\n\n /**\n * Get active viewport image based on cornerstone viewport element.\n * @returns\n */\n getActiveViewportImage() {\n if (!this.enabledElement) {\n return;\n }\n\n return this.enabledElement.image;\n }\n\n /**\n * Prefetch display sets based on cornerstone viewport element image.\n *\n * @param {string} displaySetInstanceUID the display set instance uid\n * @returns {array} displaySets\n */\n getDisplaySetsToPrefetch(displaySetInstanceUID) {\n const image = this.getActiveViewportImage();\n\n if (!image) {\n return [];\n }\n\n const study = this.getStudy(image);\n const series = this.getSeries(study, image);\n const instance = this.getInstance(series, image);\n const displaySets = study.displaySets;\n const activeDisplaySet = displaySetInstanceUID\n ? this.getDisplaySetByUID(displaySetInstanceUID)\n : this.getDisplaySetBySOPInstanceUID(displaySets, instance);\n\n const prefetchMethodMap = {\n topdown: 'getFirstDisplaySets',\n downward: 'getNextDisplaySets',\n upward: 'getPreviousDisplaySets',\n closest: 'getClosestDisplaySets',\n all: 'getAllDisplaySets',\n };\n\n const prefetchOrder = this.options.order;\n const methodName = prefetchMethodMap[prefetchOrder];\n const getDisplaySets = this[methodName];\n\n if (!getDisplaySets) {\n if (prefetchOrder) {\n log.warn(`Invalid prefetch order configuration (${prefetchOrder})`);\n }\n\n return [];\n }\n\n return getDisplaySets.call(\n this,\n displaySets,\n activeDisplaySet,\n this.options.displaySetCount,\n this.options.includeActiveDisplaySet\n );\n }\n\n /**\n * Get all display sets.\n *\n * @param {array} displaySets\n * @param {object} activeDisplaySet\n * @param {number} displaySetCount\n * @param {boolean} includeActiveDisplaySet\n * @returns\n */\n getAllDisplaySets(\n displaySets,\n activeDisplaySet,\n displaySetCount,\n includeActiveDisplaySet\n ) {\n const length = displaySets.length;\n const selectedDisplaySets = [];\n\n for (let i = 0; i < length; i++) {\n const displaySet = displaySets[i];\n selectedDisplaySets.push(displaySet);\n }\n\n return selectedDisplaySets;\n }\n\n /**\n * Get all display sets in order after the active display set.\n *\n * @param {array} displaySets\n * @param {object} activeDisplaySet\n * @param {number} displaySetCount\n * @param {boolean} includeActiveDisplaySet\n * @returns\n */\n getFirstDisplaySets(\n displaySets,\n activeDisplaySet,\n displaySetCount,\n includeActiveDisplaySet\n ) {\n const length = displaySets.length;\n const selectedDisplaySets = [];\n\n for (let i = 0; i < length && displaySetCount; i++) {\n const displaySet = displaySets[i];\n\n if (includeActiveDisplaySet || displaySet !== activeDisplaySet) {\n selectedDisplaySets.push(displaySet);\n displaySetCount--;\n }\n }\n\n return selectedDisplaySets;\n }\n\n /**\n * Get all display sets before the active display set.\n *\n * @param {array} displaySets\n * @param {object} activeDisplaySet\n * @param {number} displaySetCount\n * @param {boolean} includeActiveDisplaySet\n * @returns\n */\n getPreviousDisplaySets(\n displaySets,\n activeDisplaySet,\n displaySetCount,\n includeActiveDisplaySet\n ) {\n const activeDisplaySetIndex = displaySets.indexOf(activeDisplaySet);\n const end = includeActiveDisplaySet\n ? activeDisplaySetIndex + 1\n : activeDisplaySetIndex;\n const previousDisplaySets = displaySets.slice(0, end);\n return previousDisplaySets.reverse().slice(0, displaySetCount);\n }\n\n /**\n * Get all display sets after the active display set.\n *\n * @param {array} displaySets\n * @param {object} activeDisplaySet\n * @param {number} displaySetCount\n * @param {boolean} includeActiveDisplaySet\n * @returns\n */\n getNextDisplaySets(\n displaySets,\n activeDisplaySet,\n displaySetCount,\n includeActiveDisplaySet\n ) {\n const activeDisplaySetIndex = displaySets.indexOf(activeDisplaySet);\n const begin = includeActiveDisplaySet\n ? activeDisplaySetIndex\n : activeDisplaySetIndex + 1;\n const end = Math.min(begin + displaySetCount, displaySets.length);\n return displaySets.slice(begin, end);\n }\n\n /**\n * Get all display set closest to the active display set.\n *\n * @param {array} displaySets\n * @param {object} activeDisplaySet\n * @param {number} displaySetCount\n * @param {boolean} includeActiveDisplaySet\n * @returns\n */\n getClosestDisplaySets(\n displaySets,\n activeDisplaySet,\n displaySetCount,\n includeActiveDisplaySet\n ) {\n const activeDisplaySetIndex = displaySets.indexOf(activeDisplaySet);\n const length = displaySets.length;\n const selectedDisplaySets = [];\n let left = activeDisplaySetIndex - 1;\n let right = activeDisplaySetIndex + 1;\n\n if (includeActiveDisplaySet) {\n selectedDisplaySets.push(displaySets[activeDisplaySetIndex]);\n displaySetCount--;\n }\n\n while ((left >= 0 || right < length) && displaySetCount) {\n if (left >= 0) {\n selectedDisplaySets.push(displaySets[left]);\n displaySetCount--;\n left--;\n }\n\n if (right < length && displaySetCount) {\n selectedDisplaySets.push(displaySets[right]);\n displaySetCount--;\n right++;\n }\n }\n\n return selectedDisplaySets;\n }\n\n /**\n * Get all image ids from display sets.\n *\n * @param {array} displaySets\n * @returns {array} image ids\n */\n getImageIdsFromDisplaySets(displaySets) {\n let imageIds = [];\n\n displaySets.forEach(displaySet => {\n imageIds = imageIds.concat(this.getImageIdsFromDisplaySet(displaySet));\n });\n\n return imageIds;\n }\n\n /**\n * Get all image ids from a given display set.\n *\n * @param {array} displaySet\n * @returns\n */\n getImageIdsFromDisplaySet(displaySet) {\n const imageIds = [];\n\n if (!displaySet.images || displaySet.images.length < 1) {\n return [];\n }\n\n // TODO: This duplicates work done by the stack manager\n displaySet.images.forEach(image => {\n const numFrames = image.numFrames;\n if (numFrames > 1) {\n for (let i = 0; i < numFrames; i++) {\n let imageId = getImageId(image, i);\n imageIds.push(imageId);\n }\n } else {\n let imageId = getImageId(image);\n imageIds.push(imageId);\n }\n });\n\n return imageIds;\n }\n\n /**\n * Filter cached image ids from a set of image ids.\n *\n * @param {array} imageIds\n * @returns {array} images not cached\n */\n filterCachedImageIds(imageIds) {\n return imageIds.filter(imageId => !this.isImageCached(imageId));\n }\n\n /**\n * Check if image id is cached in cornerstone.\n *\n * @param {string} imageId\n * @returns\n */\n isImageCached(imageId) {\n const image = cornerstone.imageCache.imageCache[imageId];\n return image && image.sizeInBytes;\n }\n\n /**\n * Warns that cache is full and stops prefetching.\n */\n cacheFullHandler = () => {\n log.warn('Cache full');\n this.stopPrefetching();\n };\n}\n","import cornerstone from 'cornerstone-core';\nimport cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';\nimport debounce from 'lodash.debounce';\n\nimport StackManager from '../utils/StackManager';\nimport { StudyPrefetcher } from './StudyPrefetcher';\n\nclass BaseLoadingListener {\n constructor(stack, options = {}) {\n this.id = BaseLoadingListener.getNewId();\n this.stack = stack;\n this.statsItemsLimit = options.statsItemsLimit || 2;\n this.stats = {\n items: [],\n total: 0,\n elapsedTime: 0,\n speed: 0,\n };\n\n this._setProgressData = options._setProgressData;\n this._clearProgressById = options._clearProgressById;\n\n // Register the start point to make it possible to calculate\n // bytes/s or frames/s when the first byte or frame is received\n this._addStatsData(0);\n\n // Update the progress before starting the download\n // to make it possible to update the UI\n this._updateProgress();\n }\n\n _addStatsData(value) {\n const date = new Date();\n const stats = this.stats;\n const items = stats.items;\n const newItem = {\n value,\n date,\n };\n\n items.push(newItem);\n stats.total += newItem.value;\n\n // Remove items until it gets below the limit\n while (items.length > this.statsItemsLimit) {\n const item = items.shift();\n stats.total -= item.value;\n }\n\n // Update the elapsedTime (seconds) based on first and last\n // elements and recalculate the speed (bytes/s or frames/s)\n if (items.length > 1) {\n const oldestItem = items[0];\n stats.elapsedTime =\n (newItem.date.getTime() - oldestItem.date.getTime()) / 1000;\n stats.speed = (stats.total - oldestItem.value) / stats.elapsedTime;\n }\n }\n\n _getProgressId() {\n /**\n * TODO: The id key should be configurable.\n */\n const displaySetInstanceUID = this.stack.displaySetInstanceUID;\n return 'StackProgress:' + displaySetInstanceUID;\n }\n\n _clearProgress() {\n const progressId = this._getProgressId();\n this._clearProgressById(progressId);\n }\n\n startListening() {\n throw new Error('`startListening` must be implemented by child classes');\n }\n\n stopListening() {\n throw new Error('`stopListening` must be implemented by child classes');\n }\n\n destroy() {\n this.stopListening();\n this._clearProgress();\n }\n\n static getNewId() {\n const timeSlice = new Date()\n .getTime()\n .toString()\n .slice(-8);\n const randomNumber = parseInt(Math.random() * 1000000000);\n\n return timeSlice.toString() + randomNumber.toString();\n }\n}\n\nclass DICOMFileLoadingListener extends BaseLoadingListener {\n constructor(stack, options) {\n super(stack, options);\n\n this.imageLoadProgressEventHandler = this._imageLoadProgressEventHandler.bind(\n this\n );\n\n this._dataSetUrl = this._getDataSetUrl(stack);\n this._lastLoaded = 0;\n\n // Check how many instances has already been download (cached)\n this._checkCachedData();\n\n this.startListening();\n }\n\n _checkCachedData() {\n const dataSet = cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.get(\n this._dataSetUrl\n );\n\n if (dataSet) {\n const dataSetLength = dataSet.byteArray.length;\n\n this._updateProgress({\n percentComplete: 100,\n loaded: dataSetLength,\n total: dataSetLength,\n });\n }\n }\n\n _getImageLoadProgressEventName() {\n // TODO: Add this event as a constant in Cornerstone\n return 'cornerstoneimageloadprogress.' + this.id;\n }\n\n startListening() {\n const imageLoadProgressEventName = this._getImageLoadProgressEventName();\n\n this.stopListening();\n\n cornerstone.events.addEventListener(\n imageLoadProgressEventName,\n this.imageLoadProgressEventHandle\n );\n }\n\n stopListening() {\n const imageLoadProgressEventName = this._getImageLoadProgressEventName();\n cornerstone.events.removeEventListener(\n imageLoadProgressEventName,\n this.imageLoadProgressEventHandle\n );\n }\n\n _imageLoadProgressEventHandler = e => {\n const eventData = e.detail;\n const dataSetUrl = this._convertImageIdToDataSetUrl(eventData.imageId);\n const bytesDiff = eventData.loaded - this._lastLoaded;\n\n if (!this._dataSetUrl === dataSetUrl) {\n return;\n }\n\n // Add the bytes downloaded to the stats\n this._addStatsData(bytesDiff);\n\n // Update the download progress\n this._updateProgress(eventData);\n\n // Cache the last eventData.loaded value\n this._lastLoaded = eventData.loaded;\n };\n\n _updateProgress(eventData) {\n const progressId = this._getProgressId();\n eventData = eventData || {};\n\n const progressData = {\n multiFrame: false,\n percentComplete: eventData.percentComplete,\n bytesLoaded: eventData.loaded,\n bytesTotal: eventData.total,\n bytesPerSecond: this.stats.speed,\n };\n\n this._setProgressData(progressId, progressData);\n }\n\n _convertImageIdToDataSetUrl(imageId) {\n // Remove the prefix (\"dicomweb:\" or \"wadouri:\"\")\n imageId = imageId.replace(/^(dicomweb:|wadouri:)/i, '');\n\n // Remove \"frame=999&\" from the imageId\n imageId = imageId.replace(/frame=\\d+&?/i, '');\n\n // Remove the last \"&\" like in \"http://...?foo=1&bar=2&\"\n imageId = imageId.replace(/&$/, '');\n\n return imageId;\n }\n\n _getDataSetUrl(stack) {\n const imageId = stack.imageIds[0];\n return this._convertImageIdToDataSetUrl(imageId);\n }\n}\n\nconst StudyLoadingListenerEvents = {\n OnProgress: 'StudyLoadingListenerEvents.OnProgress',\n};\n\nfunction promiseState(promise, callback) {\n // Symbols and RegExps are never content-equal\n var uniqueValue = window['Symbol'] ? Symbol('unique') : /unique/;\n\n function notifyPendingOrResolved(value) {\n if (value === uniqueValue) {\n return callback('pending');\n } else {\n return callback('fulfilled');\n }\n }\n\n function notifyRejected(reason) {\n return callback('rejected');\n }\n\n var race = [promise, Promise.resolve(uniqueValue)];\n Promise.race(race).then(notifyPendingOrResolved, notifyRejected);\n}\n\nclass StackLoadingListener extends BaseLoadingListener {\n constructor(stack, options = {}) {\n options.statsItemsLimit = 20;\n\n super(stack, options);\n\n this.imageLoadedEventHandler = this._imageLoadedEventHandler.bind(this);\n this.imageCachePromiseRemovedEventHandler = this._imageCachePromiseRemovedEventHandler.bind(\n this\n );\n\n this.imageDataMap = this._convertImageIdsArrayToMap(stack.imageIds);\n this.framesStatus = this._createArray(stack.imageIds.length, false);\n this.loadedCount = 0;\n\n // Check how many instances has already been download (cached)\n this._debouncedSetProgressData = debounce((...args) => {\n this._setProgressData(...args);\n\n /** After checking cache, continue prefetch */\n const studyPrefetcher = StudyPrefetcher.getInstance();\n studyPrefetcher.prefetch(studyPrefetcher.getElement());\n }, 300);\n const debounced = true;\n this._checkCachedData(debounced);\n\n this.startListening();\n }\n\n _convertImageIdsArrayToMap(imageIds) {\n const imageIdsMap = new Map();\n\n for (let i = 0; i < imageIds.length; i++) {\n imageIdsMap.set(imageIds[i], {\n index: i,\n loaded: false,\n });\n }\n\n return imageIdsMap;\n }\n\n _createArray(length, defaultValue) {\n // `new Array(length)` is an anti-pattern in javascript because its\n // funny API. Otherwise I would go for `new Array(length).fill(false)`\n const array = [];\n\n for (let i = 0; i < length; i++) {\n array[i] = defaultValue;\n }\n\n return array;\n }\n\n /**\n * Check if image id is cached in cornerstone.\n *\n * @param {string} imageId\n * @returns\n */\n isImageCached(imageId) {\n const image = cornerstone.imageCache.imageCache[imageId];\n return image && image.sizeInBytes;\n }\n\n _checkCachedData(debounced = false) {\n const imageIds = this.stack.imageIds;\n\n for (let i = 0; i < imageIds.length; i++) {\n const imageId = imageIds[i];\n\n const imageObject = cornerstone.imageCache.getImageLoadObject(imageId);\n\n if (this.isImageCached(imageId)) {\n this._updateFrameStatus(imageId, true, debounced);\n }\n\n if (imageObject && imageObject.promise) {\n promiseState(imageObject.promise, state => {\n if (state === 'fulfilled') {\n this._updateFrameStatus(imageId, true, debounced);\n }\n });\n }\n }\n }\n\n _getImageLoadedEventName() {\n return `${cornerstone.EVENTS.IMAGE_LOADED}.${this.id}`;\n }\n\n _getImageCachePromiseRemoveEventName() {\n return `${cornerstone.EVENTS.IMAGE_CACHE_PROMISE_REMOVED}.${this.id}`;\n }\n\n _imageLoadedEventHandler(e) {\n this._updateFrameStatus(e.detail.image.imageId, true);\n }\n\n _imageCachePromiseRemovedEventHandler(e) {\n this._updateFrameStatus(e.detail.imageId, false);\n }\n\n startListening() {\n const imageLoadedEventName = this._getImageLoadedEventName();\n const imageCachePromiseRemovedEventName = this._getImageCachePromiseRemoveEventName();\n\n this.stopListening();\n\n cornerstone.events.addEventListener(\n imageLoadedEventName,\n this.imageLoadedEventHandler\n );\n cornerstone.events.addEventListener(\n imageCachePromiseRemovedEventName,\n this.imageCachePromiseRemovedEventHandler\n );\n }\n\n stopListening() {\n const imageLoadedEventName = this._getImageLoadedEventName();\n const imageCachePromiseRemovedEventName = this._getImageCachePromiseRemoveEventName();\n\n cornerstone.events.removeEventListener(\n imageLoadedEventName,\n this.imageLoadedEventHandler\n );\n cornerstone.events.removeEventListener(\n imageCachePromiseRemovedEventName,\n this.imageCachePromiseRemovedEventHandler\n );\n }\n\n _updateFrameStatus(imageId, loaded, debounced) {\n const imageData = this.imageDataMap.get(imageId);\n\n if (!imageData || imageData.loaded === loaded) {\n return;\n }\n\n // Add one more frame to the stats\n if (loaded) {\n this._addStatsData(1);\n }\n\n imageData.loaded = loaded;\n this.framesStatus[imageData.index] = loaded;\n this.loadedCount += loaded ? 1 : -1;\n this._updateProgress(debounced);\n }\n\n _setProgressData(progressId, progressData) {\n // TODO: This method (and _clearProgressById) need to access\n // the Redux store and should therefore be provided from the\n // application. I've added a workaround to pass this in through\n // the 'options' variable on instantiation, but this is really ugly.\n // We could consider making the StudyLoadingListener a higher-order\n // component which would set this stuff itself.\n throw new Error(\n \"The _setProgressData function must be provided in StudyLoadingListener's options\"\n );\n }\n\n _clearProgressById(progressId) {\n throw new Error(\n \"The _clearProgressById function must be provided in StudyLoadingListener's options\"\n );\n }\n\n _updateProgress(debounced) {\n const totalFramesCount = this.stack.imageIds.length;\n const loadedFramesCount = this.loadedCount;\n const loadingFramesCount = totalFramesCount - loadedFramesCount;\n const percentComplete = Math.ceil(\n (loadedFramesCount / totalFramesCount) * 100\n );\n const progressId = this._getProgressId();\n const progressData = {\n multiFrame: true,\n totalFramesCount,\n loadedFramesCount,\n loadingFramesCount,\n percentComplete,\n framesPerSecond: this.stats.speed,\n framesStatus: this.framesStatus,\n };\n\n if (debounced) {\n this._debouncedSetProgressData(progressId, progressData);\n return;\n }\n\n this._setProgressData(progressId, progressData);\n }\n\n _logProgress() {\n const totalFramesCount = this.stack.imageIds.length;\n const displaySetInstanceUID = this.stack.displaySetInstanceUID;\n let progressBar = '[';\n\n for (let i = 0; i < totalFramesCount; i++) {\n const ch = this.framesStatus[i] ? '|' : '.';\n progressBar += `${ch}`;\n }\n\n progressBar += ']';\n console.info(`${displaySetInstanceUID}: ${progressBar}`);\n }\n}\n\nclass StudyLoadingListener {\n static events = StudyLoadingListenerEvents;\n\n constructor(options) {\n this.listeners = {};\n this.options = options;\n }\n\n addStack(stack, stackMetaData) {\n // TODO: Make this work for plugins\n if (!stack) {\n //console.log('Skipping adding stack to StudyLoadingListener');\n return;\n }\n\n const displaySetInstanceUID = stack.displaySetInstanceUID;\n\n if (!this.listeners[displaySetInstanceUID]) {\n const listener = this._createListener(stack, stackMetaData);\n if (listener) {\n this.listeners[displaySetInstanceUID] = listener;\n }\n }\n }\n\n addStudy(study) {\n study.displaySets.forEach(displaySet => {\n const stack = StackManager.findOrCreateStack(study, displaySet);\n\n // TODO: Make this work for plugins\n if (!stack) {\n console.warn('Skipping adding displaySet to StudyLoadingListener');\n console.warn(displaySet);\n return;\n }\n\n this.addStack(stack, {\n isMultiFrame: displaySet.isMultiFrame,\n });\n });\n }\n\n addStudies(studies) {\n if (!studies || !studies.length) {\n return;\n }\n\n studies.forEach(study => this.addStudy(study));\n }\n\n clear() {\n const displaySetInstanceUIDs = Object.keys(this.listeners);\n const length = displaySetInstanceUIDs.length;\n\n for (let i = 0; i < length; i++) {\n const displaySetInstanceUID = displaySetInstanceUIDs[i];\n const displaySet = this.listeners[displaySetInstanceUID];\n\n displaySet.destroy();\n }\n\n this.listeners = {};\n }\n\n _createListener(stack, stackMetaData) {\n const schema = this._getSchema(stack);\n\n // A StackLoadingListener can be created if it's wadors or not a multiframe\n // wadouri instance (single file) that means \"N\" files will have to be\n // downloaded where \"N\" is the number of frames. DICOMFileLoadingListener\n // is created only if it's a single DICOM file and there's no way to know\n // how many frames has already been loaded (bytes/s instead of frames/s).\n if (schema === 'wadors' || !stackMetaData.isMultiFrame) {\n return new StackLoadingListener(stack, this.options);\n } else {\n return new DICOMFileLoadingListener(stack, this.options);\n }\n }\n\n _getSchema(stack) {\n const imageId = stack.imageIds[0];\n if (!imageId) {\n return;\n }\n const colonIndex = imageId.indexOf(':');\n return imageId.substring(0, colonIndex);\n }\n\n static getInstance(options) {\n /**\n * TODO: Use a different alternative without the use of events.\n */\n const DEFAULT_OPTIONS = {\n _setProgressData: (progressId, progressData) => {\n const event = new CustomEvent(StudyLoadingListenerEvents.OnProgress, {\n detail: { progressId, progressData },\n });\n document.dispatchEvent(event);\n },\n _clearProgressById: progressId => {\n const event = new CustomEvent(StudyLoadingListenerEvents.OnProgress, {\n detail: { progressId, percentComplete: 0 },\n });\n document.dispatchEvent(event);\n },\n };\n\n if (!StudyLoadingListener._instance) {\n StudyLoadingListener._instance = new StudyLoadingListener(\n options || DEFAULT_OPTIONS\n );\n }\n\n return StudyLoadingListener._instance;\n }\n}\n\nexport { StudyLoadingListener, StackLoadingListener, DICOMFileLoadingListener };\n","const _subscriptions = Symbol('subscriptions');\nconst _lastSubscriptionId = Symbol('lastSubscriptionId');\n\n/**\n * Class to implement publish/subscribe pattern\n *\n * @class\n * @classdesc Pub/sub mechanism\n */\nexport default class PubSub {\n constructor() {\n this[_subscriptions] = {};\n this[_lastSubscriptionId] = 0;\n }\n\n /**\n * Subscribe to event\n *\n * @param {string} eventName Event name\n * @param {Function} callback Callback function\n * @returns {void}\n */\n subscribe(eventName, callback) {\n if (eventName === undefined) {\n throw new Error('Event name is required');\n }\n\n if (typeof callback !== 'function') {\n throw new Error('Callback must be a function');\n }\n\n if (!this[_subscriptions].hasOwnProperty(eventName)) {\n this[_subscriptions][eventName] = {};\n }\n\n const subscriptionId = `sub${this[_lastSubscriptionId]++}`;\n this[_subscriptions][eventName][subscriptionId] = callback;\n }\n\n /**\n * Removes a subscription\n *\n * @param {string} eventName Event name\n * @param {Function} [callback] Callback function\n * @returns {void}\n */\n unsubscribe(eventName, callback) {\n const callbacks = this[_subscriptions][eventName] || {};\n for (let subscriptionId in callbacks) {\n if (!callback) {\n delete callbacks[subscriptionId];\n } else if (callbacks[subscriptionId] === callback) {\n delete callbacks[subscriptionId];\n }\n }\n }\n\n /**\n * Publish event to all subscriptions\n *\n * @param {String} eventName Event name\n * @param {any} [payload] Data that will be published\n * @returns {void}\n */\n publish(eventName, ...payload) {\n if (eventName === undefined) {\n throw new Error('Event name is required');\n }\n\n const callbacks = this[_subscriptions][eventName] || {};\n for (let subscriptionId in callbacks) {\n callbacks[subscriptionId](...payload);\n }\n }\n}\n","import PubSub from './PubSub';\n\n/** Log Events */\nexport const LogEvents = Object.freeze({\n OnLog: 'onLog',\n});\n\n/**\n * Log manager that implements pub/sub.\n * This manager can be used to send logs across different packages\n * using previously registered events.\n */\nclass LogManager extends PubSub {\n EVENTS = LogEvents;\n}\n\n/** Singleton */\nexport default new LogManager();\n","import { studyMetadataManager } from '../utils';\n\nimport OHIFError from './OHIFError';\nimport { StudyMetadata } from './metadata/StudyMetadata';\nimport { StudyMetadataSource } from './StudyMetadataSource.js';\nimport { retrieveStudyMetadata } from '../studies/retrieveStudyMetadata.js';\n\nexport class OHIFStudyMetadataSource extends StudyMetadataSource {\n /**\n * Get study metadata for a study with given study InstanceUID\n * @param server\n * @param {String} studyInstanceUID Study InstanceUID\n * @return {Promise} A Promise object\n */\n getByInstanceUID(server, studyInstanceUID) {\n return retrieveStudyMetadata(server, studyInstanceUID);\n }\n\n /**\n * Load study info (OHIF.viewer.Studies) and study metadata (OHIF.viewer.StudyMetadataList) for a given study.\n * @param {StudyMetadata} study StudyMetadata object.\n */\n loadStudy(study) {\n if (!(study instanceof StudyMetadata)) {\n throw new OHIFError(\n 'OHIFStudyMetadataSource::loadStudy study is not an instance of StudyMetadata'\n );\n }\n\n return new Promise((resolve, reject) => {\n const studyInstanceUID = study.getStudyInstanceUID();\n\n if (study instanceof StudyMetadata) {\n const alreadyLoaded = OHIF.viewer.Studies.findBy({\n StudyInstanceUID: studyInstanceUID,\n });\n\n if (!alreadyLoaded) {\n OHIFStudyMetadataSource._updateStudyCollections(study);\n }\n\n resolve(study);\n return;\n }\n\n this.getByInstanceUID(studyInstanceUID)\n .then(studyInfo => {\n // Create study metadata object\n const studyMetadata = new StudyMetadata(\n studyInfo,\n studyInfo.StudyInstanceUID\n );\n\n // Get Study display sets\n const displaySets = studyMetadata.createDisplaySets();\n\n OHIFStudyMetadataSource._updateStudyCollections(studyMetadata);\n resolve(studyMetadata);\n })\n .catch(reject);\n });\n }\n\n // Static methods\n static _updateStudyCollections(studyMetadata) {\n const studyInfo = studyMetadata.getData();\n\n // Set some studyInfo properties\n studyInfo.selected = true;\n studyInfo.displaySets = studyMetadata.getDisplaySets();\n studyMetadataManager.add(studyMetadata);\n }\n}\n","import { InstanceMetadata, SeriesMetadata, StudyMetadata } from './metadata';\n\nimport CommandsManager from './CommandsManager.js';\nimport { DICOMFileLoadingListener } from './StudyLoadingListener';\nimport HotkeysManager from './HotkeysManager.js';\nimport ImageSet from './ImageSet';\nimport LogManager from './LogManager';\nimport PubSub from './PubSub';\nimport MetadataProvider from './MetadataProvider';\nimport OHIFError from './OHIFError.js';\nimport { OHIFStudyMetadataSource } from './OHIFStudyMetadataSource';\nimport { StackLoadingListener } from './StudyLoadingListener';\nimport { StudyLoadingListener } from './StudyLoadingListener';\nimport { StudyMetadataSource } from './StudyMetadataSource';\nimport { StudyPrefetcher } from './StudyPrefetcher';\nimport { TypeSafeCollection } from './TypeSafeCollection';\n\nexport {\n OHIFStudyMetadataSource,\n MetadataProvider,\n CommandsManager,\n HotkeysManager,\n ImageSet,\n StudyPrefetcher,\n StudyLoadingListener,\n StackLoadingListener,\n DICOMFileLoadingListener,\n StudyMetadata,\n SeriesMetadata,\n InstanceMetadata,\n TypeSafeCollection,\n OHIFError,\n StudyMetadataSource,\n};\n\nconst classes = {\n OHIFStudyMetadataSource,\n MetadataProvider,\n CommandsManager,\n HotkeysManager,\n LogManager,\n ImageSet,\n PubSub,\n StudyPrefetcher,\n StudyLoadingListener,\n StackLoadingListener,\n DICOMFileLoadingListener,\n StudyMetadata,\n SeriesMetadata,\n InstanceMetadata,\n TypeSafeCollection,\n OHIFError,\n StudyMetadataSource,\n};\n\nexport default classes;\n","import { sopClassDictionary } from './sopClassDictionary';\n\nconst imagesTypes = [\n sopClassDictionary.ComputedRadiographyImageStorage,\n sopClassDictionary.DigitalXRayImageStorageForPresentation,\n sopClassDictionary.DigitalXRayImageStorageForProcessing,\n sopClassDictionary.DigitalMammographyXRayImageStorageForPresentation,\n sopClassDictionary.DigitalMammographyXRayImageStorageForProcessing,\n sopClassDictionary.DigitalIntraOralXRayImageStorageForPresentation,\n sopClassDictionary.DigitalIntraOralXRayImageStorageForProcessing,\n sopClassDictionary.CTImageStorage,\n sopClassDictionary.EnhancedCTImageStorage,\n sopClassDictionary.LegacyConvertedEnhancedCTImageStorage,\n sopClassDictionary.UltrasoundMultiframeImageStorage,\n sopClassDictionary.MRImageStorage,\n sopClassDictionary.EnhancedMRImageStorage,\n sopClassDictionary.EnhancedMRColorImageStorage,\n sopClassDictionary.LegacyConvertedEnhancedMRImageStorage,\n sopClassDictionary.UltrasoundImageStorage,\n sopClassDictionary.SecondaryCaptureImageStorage,\n sopClassDictionary.MultiframeSingleBitSecondaryCaptureImageStorage,\n sopClassDictionary.MultiframeGrayscaleByteSecondaryCaptureImageStorage,\n sopClassDictionary.MultiframeGrayscaleWordSecondaryCaptureImageStorage,\n sopClassDictionary.MultiframeTrueColorSecondaryCaptureImageStorage,\n sopClassDictionary.XRayAngiographicImageStorage,\n sopClassDictionary.EnhancedXAImageStorage,\n sopClassDictionary.XRayRadiofluoroscopicImageStorage,\n sopClassDictionary.EnhancedXRFImageStorage,\n sopClassDictionary.XRay3DAngiographicImageStorage,\n sopClassDictionary.XRay3DCraniofacialImageStorage,\n sopClassDictionary.BreastTomosynthesisImageStorage,\n sopClassDictionary.BreastProjectionXRayImageStorageForPresentation,\n sopClassDictionary.BreastProjectionXRayImageStorageForProcessing,\n sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForPresentation,\n sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForProcessing,\n sopClassDictionary.NuclearMedicineImageStorage,\n sopClassDictionary.VLEndoscopicImageStorage,\n sopClassDictionary.VideoEndoscopicImageStorage,\n sopClassDictionary.VLMicroscopicImageStorage,\n sopClassDictionary.VideoMicroscopicImageStorage,\n sopClassDictionary.VLSlideCoordinatesMicroscopicImageStorage,\n sopClassDictionary.VLPhotographicImageStorage,\n sopClassDictionary.VideoPhotographicImageStorage,\n sopClassDictionary.OphthalmicPhotography8BitImageStorage,\n sopClassDictionary.OphthalmicPhotography16BitImageStorage,\n sopClassDictionary.OphthalmicTomographyImageStorage,\n sopClassDictionary.VLWholeSlideMicroscopyImageStorage,\n sopClassDictionary.PositronEmissionTomographyImageStorage,\n sopClassDictionary.EnhancedPETImageStorage,\n sopClassDictionary.LegacyConvertedEnhancedPETImageStorage,\n sopClassDictionary.RTImageStorage,\n];\n\n/**\n * Checks whether dicom files with specified SOP Class UID have image data\n * @param {string} SOPClassUID - SOP Class UID to be checked\n * @returns {boolean} - true if it has image data\n */\nexport const isImage = SOPClassUID => {\n if (!SOPClassUID) return false;\n return imagesTypes.indexOf(SOPClassUID) !== -1;\n};\n","const LOW_PRIORITY_MODALITIES = Object.freeze([\n 'SEG',\n 'DOC',\n 'RTSTRUCT',\n 'SR',\n 'KO',\n 'PR',\n]);\n\nexport default function isLowPriorityModality(Modality) {\n return LOW_PRIORITY_MODALITIES.includes(Modality);\n}\n","// Return the array sorting function for its object's properties\nexport default function sortBy() {\n var fields = [].slice.call(arguments),\n n_fields = fields.length;\n\n return function(A, B) {\n var a, b, field, key, reverse, result, i;\n\n for (i = 0; i < n_fields; i++) {\n result = 0;\n field = fields[i];\n\n key = typeof field === 'string' ? field : field.name;\n\n a = A[key];\n b = B[key];\n\n if (typeof field.primer !== 'undefined') {\n a = field.primer(a);\n b = field.primer(b);\n }\n\n reverse = field.reverse ? -1 : 1;\n\n if (a < b) {\n result = reverse * -1;\n }\n\n if (a > b) {\n result = reverse * 1;\n }\n\n if (result !== 0) {\n break;\n }\n }\n\n return result;\n };\n}\n","import OHIFError from '../classes/OHIFError.js';\nimport getImageId from './getImageId';\nimport metadataProvider from '../classes/MetadataProvider.js';\n\nlet stackMap = {};\nlet configuration = {};\nconst stackUpdatedCallbacks = [];\n\n/**\n * Loop through the current series and add metadata to the\n * Cornerstone meta data provider. This will be used to fill information\n * into the viewport overlays, and to calculate reference lines and orientation markers\n * @param {Object} stackMap stackMap object\n * @param {Object} study Study object\n * @param {Object} displaySet The set of images to make the stack from\n * @return {Array} Array with image IDs\n */\nfunction createAndAddStack(stackMap, study, displaySet, stackUpdatedCallbacks) {\n const images = displaySet.images;\n if (!images) {\n return;\n }\n\n const numImages = images.length;\n const imageIds = [];\n let imageId;\n\n displaySet.images.forEach((instance, imageIndex) => {\n const image = instance.getData();\n const metaData = {\n instance: image, // in this context, instance will be the data of the InstanceMetadata object...\n series: displaySet, // TODO: Check this\n study,\n numImages,\n imageIndex: imageIndex + 1,\n };\n\n const naturalizedInstance = instance.getData().metadata;\n const NumberOfFrames = naturalizedInstance.NumberOfFrames;\n\n if (NumberOfFrames > 1) {\n for (let i = 0; i < NumberOfFrames; i++) {\n metaData.frameNumber = i;\n imageId = getImageId(image, i);\n imageIds.push(imageId);\n\n const {\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID,\n } = instance.getData().metadata;\n\n metadataProvider.addImageIdToUIDs(imageId, {\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID,\n });\n }\n } else {\n metaData.frameNumber = 1;\n imageId = getImageId(image);\n imageIds.push(imageId);\n\n const {\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID,\n } = naturalizedInstance;\n\n metadataProvider.addImageIdToUIDs(imageId, {\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID,\n });\n }\n });\n\n const stack = {\n StudyInstanceUID: study.StudyInstanceUID,\n displaySetInstanceUID: displaySet.displaySetInstanceUID,\n imageIds,\n frameRate: displaySet.frameRate,\n isClip: displaySet.isClip,\n };\n\n stackMap[displaySet.displaySetInstanceUID] = stack;\n\n return stack;\n}\n\nconfiguration = {\n createAndAddStack,\n};\n\n/**\n * This object contains all the functions needed for interacting with the stack manager.\n * Generally, findStack is the only function used. If you want to know when new stacks\n * come in, you can register a callback with addStackUpdatedCallback.\n */\nconst StackManager = {\n /**\n * Removes all current stacks\n */\n clearStacks() {\n stackMap = {};\n },\n /**\n * Create a stack from an image set, as well as add in the metadata on a per image bases.\n * @param study The study who's metadata will be added\n * @param displaySet The set of images to make the stack from\n * @return {Array} Array with image IDs\n */\n makeAndAddStack(study, displaySet) {\n return configuration.createAndAddStack(\n stackMap,\n study,\n displaySet,\n stackUpdatedCallbacks\n );\n },\n /**\n * Find a stack from the currently created stacks.\n * @param displaySetInstanceUID The UID of the stack to find.\n * @returns {*} undefined if not found, otherwise the stack object is returned.\n */\n findStack(displaySetInstanceUID) {\n return stackMap[displaySetInstanceUID];\n },\n /**\n * Find a stack or reate one if it has not been created yet\n * @param study The study who's metadata will be added\n * @param displaySet The set of images to make the stack from\n * @return {Array} Array with image IDs\n */\n findOrCreateStack(study, displaySet) {\n let stack = this.findStack(displaySet.displaySetInstanceUID);\n\n if (!stack || !stack.imageIds) {\n stack = this.makeAndAddStack(study, displaySet);\n }\n\n return stack;\n },\n /**\n * Gets the underlying map of displaySetInstanceUID to stack object.\n * WARNING: Do not change this object. It directly affects the manager.\n * @returns {{}} map of displaySetInstanceUID -> stack.\n */\n getAllStacks() {\n return stackMap;\n },\n /**\n * Adds in a callback to be called on a stack being added / updated.\n * @param callback must accept at minimum one argument,\n * which is the stack that was added / updated.\n */\n addStackUpdatedCallback(callback) {\n if (typeof callback !== 'function') {\n throw new OHIFError('callback must be provided as a function');\n }\n stackUpdatedCallbacks.push(callback);\n },\n /**\n * Return configuration\n */\n getConfiguration() {\n return configuration;\n },\n /**\n * Set configuration, in order to provide compatibility\n * with other systems by overriding this functions\n * @param {Object} config object with functions to be overrided\n *\n * For now, only makeAndAddStack can be overrided\n */\n setConfiguration(config) {\n configuration = config;\n },\n};\n\nexport { StackManager };\nexport default StackManager;\n","import guid from '../utils/guid';\n\n/**\n * Constants\n */\nconst PROPERTY_SEPARATOR = '.';\nconst ORDER_ASC = 'asc';\nconst ORDER_DESC = 'desc';\nconst MIN_COUNT = 0x00000000;\nconst MAX_COUNT = 0x7fffffff;\n\n/**\n * Class Definition\n */\nexport class TypeSafeCollection {\n constructor() {\n this._operationCount = MIN_COUNT;\n this._elementList = [];\n this._handlers = Object.create(null);\n }\n\n /**\n * Private Methods\n */\n\n _invalidate() {\n let count = this._operationCount;\n this._operationCount = count < MAX_COUNT ? count + 1 : MIN_COUNT;\n }\n\n _elements(silent) {\n silent === true || this._operationCount;\n return this._elementList;\n }\n\n _elementWithPayload(payload, silent) {\n return this._elements(silent).find(item => item.payload === payload);\n }\n\n _elementWithId(id, silent) {\n return this._elements(silent).find(item => item.id === id);\n }\n\n _trigger(event, data) {\n let handlers = this._handlers;\n if (event in handlers) {\n handlers = handlers[event];\n if (!(handlers instanceof Array)) {\n return;\n }\n for (let i = 0, limit = handlers.length; i < limit; ++i) {\n let handler = handlers[i];\n if (_isFunction(handler)) {\n handler.call(null, data);\n }\n }\n }\n }\n\n /**\n * Public Methods\n */\n\n onInsert(callback) {\n if (_isFunction(callback)) {\n let handlers = this._handlers.insert;\n if (!(handlers instanceof Array)) {\n handlers = [];\n this._handlers.insert = handlers;\n }\n handlers.push(callback);\n }\n }\n\n /**\n * Update the payload associated with the given ID to be the new supplied payload.\n * @param {string} id The ID of the entry that will be updated.\n * @param {any} payload The element that will replace the previous payload.\n * @returns {boolean} Returns true if the given ID is present in the collection, false otherwise.\n */\n updateById(id, payload) {\n let result = false,\n found = this._elementWithPayload(payload, true);\n if (found) {\n // nothing to do since the element is already in the collection...\n if (found.id === id) {\n // set result to true since the ids match...\n result = true;\n this._invalidate();\n }\n } else {\n found = this._elementWithId(id, true);\n if (found) {\n found.payload = payload;\n result = true;\n this._invalidate();\n }\n }\n return result;\n }\n\n /**\n * Signal that the given element has been changed by notifying reactive data-source observers.\n * This method is basically a means to invalidate the inernal reactive data-source.\n * @param {any} payload The element that has been altered.\n * @returns {boolean} Returns true if the element is present in the collection, false otherwise.\n */\n update(payload) {\n let result = false,\n found = this._elementWithPayload(payload, true);\n if (found) {\n // nothing to do since the element is already in the collection...\n result = true;\n this._invalidate();\n }\n return result;\n }\n\n /**\n * Insert an element in the collection. On success, the element ID (a unique string) is returned. On failure, returns null.\n * A failure scenario only happens when the given payload is already present in the collection. Note that NO exceptions are thrown!\n * @param {any} payload The element to be stored.\n * @returns {string} The ID of the inserted element or null if the element already exists...\n */\n insert(payload) {\n let id = null,\n found = this._elementWithPayload(payload, true);\n if (!found) {\n id = guid();\n this._elements(true).push({ id, payload });\n this._invalidate();\n this._trigger('insert', { id, data: payload });\n }\n return id;\n }\n\n /**\n * Remove all elements from the collection.\n * @returns {void} No meaningful value is returned.\n */\n removeAll() {\n let all = this._elements(true),\n length = all.length;\n for (let i = length - 1; i >= 0; i--) {\n let item = all[i];\n delete item.id;\n delete item.payload;\n all[i] = null;\n }\n all.splice(0, length);\n this._invalidate();\n }\n\n /**\n * Remove elements from the collection that match the criteria given in the property map.\n * @param {Object} propertyMap A property map that will be macthed against all collection elements.\n * @returns {Array} A list with all removed elements.\n */\n remove(propertyMap) {\n let found = this.findAllEntriesBy(propertyMap),\n foundCount = found.length,\n removed = [];\n if (foundCount > 0) {\n const all = this._elements(true);\n for (let i = foundCount - 1; i >= 0; i--) {\n let item = found[i];\n all.splice(item[2], 1);\n removed.push(item[0]);\n }\n this._invalidate();\n }\n return removed;\n }\n\n /**\n * Provides the ID of the given element inside the collection.\n * @param {any} payload The element being searched for.\n * @returns {string} The ID of the given element or undefined if the element is not present.\n */\n getElementId(payload) {\n let found = this._elementWithPayload(payload);\n return found && found.id;\n }\n\n /**\n * Provides the position of the given element in the internal list returning -1 if the element is not present.\n * @param {any} payload The element being searched for.\n * @returns {number} The position of the given element in the internal list. If the element is not present -1 is returned.\n */\n findById(id) {\n let found = this._elementWithId(id);\n return found && found.payload;\n }\n\n /**\n * Provides the position of the given element in the internal list returning -1 if the element is not present.\n * @param {any} payload The element being searched for.\n * @returns {number} The position of the given element in the internal list. If the element is not present -1 is returned.\n */\n indexOfElement(payload) {\n return this._elements().indexOf(this._elementWithPayload(payload, true));\n }\n\n /**\n * Provides the position of the element associated with the given ID in the internal list returning -1 if the element is not present.\n * @param {string} id The index of the element.\n * @returns {number} The position of the element associated with the given ID in the internal list. If the element is not present -1 is returned.\n */\n indexOfId(id) {\n return this._elements().indexOf(this._elementWithId(id, true));\n }\n\n /**\n * Provides a list-like approach to the collection returning an element by index.\n * @param {number} index The index of the element.\n * @returns {any} If out of bounds, undefined is returned. Otherwise the element in the given position is returned.\n */\n getElementByIndex(index) {\n let found = this._elements()[index >= 0 ? index : -1];\n return found && found.payload;\n }\n\n /**\n * Find an element by a criteria defined by the given callback function.\n * Attention!!! The reactive source will not be notified if no valid callback is supplied...\n * @param {function} callback A callback function which will define the search criteria. The callback\n * function will be passed the collection element, its ID and its index in this very order. The callback\n * shall return true when its criterea has been fulfilled.\n * @returns {any} The matched element or undefined if not match was found.\n */\n find(callback) {\n let found;\n if (_isFunction(callback)) {\n found = this._elements().find((item, index) => {\n return callback.call(this, item.payload, item.id, index);\n });\n }\n return found && found.payload;\n }\n\n /**\n * Find the first element that strictly matches the specified property map.\n * @param {Object} propertyMap A property map that will be macthed against all collection elements.\n * @param {Object} options A set of options. Currently only \"options.sort\" option is supported.\n * @param {Object.SortingSpecifier} options.sort An optional sorting specifier. If a sorting specifier is supplied\n * but is not valid, an exception will be thrown.\n * @returns {Any} The matched element or undefined if not match was found.\n */\n findBy(propertyMap, options) {\n let found;\n if (_isObject(options)) {\n // if the \"options\" argument is provided and is a valid object,\n // it must be applied to the dataset before search...\n const all = this.all(options);\n if (all.length > 0) {\n if (_isObject(propertyMap)) {\n found = all.find(item =>\n _compareToPropertyMapStrict(propertyMap, item)\n );\n } else {\n found = all[0]; // simply extract the first element...\n }\n }\n } else if (_isObject(propertyMap)) {\n found = this._elements().find(item =>\n _compareToPropertyMapStrict(propertyMap, item.payload)\n );\n if (found) {\n found = found.payload;\n }\n }\n return found;\n }\n\n /**\n * Find all elements that strictly match the specified property map.\n * Attention!!! The reactive source will not be notified if no valid property map is supplied...\n * @param {Object} propertyMap A property map that will be macthed against all collection elements.\n * @returns {Array} An array of entries of all elements that match the given criteria. Each set in\n * in the array has the following format: [ elementData, elementId, elementIndex ].\n */\n findAllEntriesBy(propertyMap) {\n const found = [];\n if (_isObject(propertyMap)) {\n this._elements().forEach((item, index) => {\n if (_compareToPropertyMapStrict(propertyMap, item.payload)) {\n // Match! Add it to the found list...\n found.push([item.payload, item.id, index]);\n }\n });\n }\n return found;\n }\n\n /**\n * Find all elements that match a specified property map.\n * Attention!!! The reactive source will not be notified if no valid property map is supplied...\n * @param {Object} propertyMap A property map that will be macthed against all collection elements.\n * @param {Object} options A set of options. Currently only \"options.sort\" option is supported.\n * @param {Object.SortingSpecifier} options.sort An optional sorting specifier. If a sorting specifier is supplied\n * but is not valid, an exception will be thrown.\n * @returns {Array} An array with all elements that match the given criteria and sorted in the specified sorting order.\n */\n findAllBy(propertyMap, options) {\n const found = this.findAllEntriesBy(propertyMap).map(item => item[0]); // Only payload is relevant...\n if (_isObject(options)) {\n if ('sort' in options) {\n _sortListBy(found, options.sort);\n }\n }\n return found;\n }\n\n /**\n * Executes the supplied callback function for each element of the collection.\n * Attention!!! The reactive source will not be notified if no valid property map is supplied...\n * @param {function} callback The callback function to be executed. The callback is passed the element,\n * its ID and its index in this very order.\n * @returns {void} Nothing is returned.\n */\n forEach(callback) {\n if (_isFunction(callback)) {\n this._elements().forEach((item, index) => {\n callback.call(this, item.payload, item.id, index);\n });\n }\n }\n\n /**\n * Count the number of elements currently in the collection.\n * @returns {number} The current number of elements in the collection.\n */\n count() {\n return this._elements().length;\n }\n\n /**\n * Returns a list with all elements of the collection optionally sorted by a sorting specifier criteria.\n * @param {Object} options A set of options. Currently only \"options.sort\" option is supported.\n * @param {Object.SortingSpecifier} options.sort An optional sorting specifier. If a sorting specifier is supplied\n * but is not valid, an exception will be thrown.\n * @returns {Array} An array with all elements stored in the collection.\n */\n all(options) {\n let list = this._elements().map(item => item.payload);\n if (_isObject(options)) {\n if ('sort' in options) {\n _sortListBy(list, options.sort);\n }\n }\n return list;\n }\n}\n\n/**\n * Utility Functions\n */\n\n/**\n * Test if supplied argument is a valid object for current class purposes.\n * Atention! The underscore version of this function should not be used for performance reasons.\n */\nfunction _isObject(subject) {\n return (\n subject instanceof Object ||\n (typeof subject === 'object' && subject !== null)\n );\n}\n\n/**\n * Test if supplied argument is a valid string for current class purposes.\n * Atention! The underscore version of this function should not be used for performance reasons.\n */\nfunction _isString(subject) {\n return typeof subject === 'string';\n}\n\n/**\n * Test if supplied argument is a valid function for current class purposes.\n * Atention! The underscore version of this function should not be used for performance reasons.\n */\nfunction _isFunction(subject) {\n return typeof subject === 'function';\n}\n\n/**\n * Shortcut for Object's prototype \"hasOwnProperty\" method.\n */\nconst _hasOwnProperty = Object.prototype.hasOwnProperty;\n\n/**\n * Retrieve an object's property value by name. Composite property names (e.g., 'address.country.name') are accepted.\n * @param {Object} targetObject The object we want read the property from...\n * @param {String} propertyName The property to be read (e.g., 'address.street.name' or 'address.street.number'\n * to read object.address.street.name or object.address.street.number, respectively);\n * @returns {Any} Returns whatever the property holds or undefined if the property cannot be read or reached.\n */\nfunction _getPropertyValue(targetObject, propertyName) {\n let propertyValue; // undefined (the default return value)\n if (_isObject(targetObject) && _isString(propertyName)) {\n const fragments = propertyName.split(PROPERTY_SEPARATOR);\n const fragmentCount = fragments.length;\n if (fragmentCount > 0) {\n const firstFragment = fragments[0];\n const remainingFragments =\n fragmentCount > 1 ? fragments.slice(1).join(PROPERTY_SEPARATOR) : null;\n propertyValue = targetObject[firstFragment];\n if (remainingFragments !== null) {\n propertyValue = _getPropertyValue(propertyValue, remainingFragments);\n }\n }\n }\n return propertyValue;\n}\n\n/**\n * Compare a property map with a target object using strict comparison.\n * @param {Object} propertyMap The property map whose properties will be used for comparison. Composite\n * property names (e.g., 'address.country.name') will be tested against the \"resolved\" properties from the target object.\n * @param {Object} targetObject The target object whose properties will be tested.\n * @returns {boolean} Returns true if the properties match, false otherwise.\n */\nfunction _compareToPropertyMapStrict(propertyMap, targetObject) {\n let result = false;\n // \"for in\" loops do not thown exceptions for invalid data types...\n for (let propertyName in propertyMap) {\n if (_hasOwnProperty.call(propertyMap, propertyName)) {\n if (\n propertyMap[propertyName] !==\n _getPropertyValue(targetObject, propertyName)\n ) {\n result = false;\n break;\n } else if (result !== true) {\n result = true;\n }\n }\n }\n return result;\n}\n\n/**\n * Checks if a sorting specifier is valid.\n * A valid sorting specifier consists of an array of arrays being each subarray a pair\n * in the format [\"property name\", \"sorting order\"].\n * The following exemple can be used to sort studies by \"date\"\" and use \"time\" to break ties in descending order.\n * [ [ 'study.date', 'desc' ], [ 'study.time', 'desc' ] ]\n * @param {Array} specifiers The sorting specifier to be tested.\n * @returns {boolean} Returns true if the specifiers are valid, false otherwise.\n */\nfunction _isValidSortingSpecifier(specifiers) {\n let result = true;\n if (specifiers instanceof Array && specifiers.length > 0) {\n for (let i = specifiers.length - 1; i >= 0; i--) {\n const item = specifiers[i];\n if (item instanceof Array) {\n const property = item[0];\n const order = item[1];\n if (\n _isString(property) &&\n (order === ORDER_ASC || order === ORDER_DESC)\n ) {\n continue;\n }\n }\n result = false;\n break;\n }\n }\n return result;\n}\n\n/**\n * Sorts an array based on sorting specifier options.\n * @param {Array} list The that needs to be sorted.\n * @param {Array} specifiers An array of specifiers. Please read isValidSortingSpecifier method definition for further details.\n * @returns {void} No value is returned. The array is sorted in place.\n */\nfunction _sortListBy(list, specifiers) {\n if (list instanceof Array && _isValidSortingSpecifier(specifiers)) {\n const specifierCount = specifiers.length;\n list.sort(function _sortListByCallback(a, b) {\n // callback name for stack traces...\n let index = 0;\n while (index < specifierCount) {\n const specifier = specifiers[index];\n const property = specifier[0];\n const order = specifier[1] === ORDER_DESC ? -1 : 1;\n const aValue = _getPropertyValue(a, property);\n const bValue = _getPropertyValue(b, property);\n // @TODO: should we check for the types being compared, like:\n // ~~ if (typeof aValue !== typeof bValue) continue;\n // Not sure because dates, for example, can be correctly compared to numbers...\n if (aValue < bValue) {\n return order * -1;\n }\n if (aValue > bValue) {\n return order * 1;\n }\n if (++index >= specifierCount) {\n return 0;\n }\n }\n });\n } else {\n throw new Error('Invalid Arguments');\n }\n}\n","const displayFunction = data => {\n return data.text || '';\n};\n\nexport const arrowAnnotate = {\n id: 'ArrowAnnotate',\n name: 'ArrowAnnotate',\n toolGroup: 'allTools',\n cornerstoneToolType: 'ArrowAnnotate',\n options: {\n measurementTable: {\n displayFunction,\n },\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","const displayFunction = data => {\n if (data.shortestDiameter) {\n // TODO: Make this check criteria again to see if we should display shortest x longest\n return data.longestDiameter + ' x ' + data.shortestDiameter;\n }\n\n return data.longestDiameter;\n};\n\nexport const bidirectional = {\n id: 'Bidirectional',\n name: 'Target',\n toolGroup: 'allTools',\n cornerstoneToolType: 'Bidirectional',\n options: {\n measurementTable: {\n displayFunction,\n },\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","const displayFunction = data => {\n let meanValue = '';\n const { cachedStats } = data;\n if (cachedStats && cachedStats.mean && !isNaN(cachedStats.mean)) {\n meanValue = cachedStats.mean.toFixed(2) + ' HU';\n }\n return meanValue;\n};\n\nexport const ellipticalRoi = {\n id: 'EllipticalRoi',\n name: 'Ellipse',\n toolGroup: 'allTools',\n cornerstoneToolType: 'EllipticalRoi',\n options: {\n measurementTable: {\n displayFunction,\n },\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","const displayFunction = data => {\n let meanValue = '';\n const { cachedStats } = data;\n if (cachedStats && cachedStats.mean && !isNaN(cachedStats.mean)) {\n meanValue = cachedStats.mean.toFixed(2) + ' HU';\n }\n return meanValue;\n};\n\nexport const circleRoi = {\n id: 'CircleRoi',\n name: 'Circle',\n toolGroup: 'allTools',\n cornerstoneToolType: 'CircleRoi',\n options: {\n measurementTable: {\n displayFunction,\n },\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","const displayFunction = data => {\n let meanValue = '';\n if (data.meanStdDev && data.meanStdDev.mean && !isNaN(data.meanStdDev.mean)) {\n meanValue = data.meanStdDev.mean.toFixed(2) + ' HU';\n }\n return meanValue;\n};\n\nexport const freehandMouse = {\n id: 'FreehandMouse',\n name: 'Freehand',\n toolGroup: 'allTools',\n cornerstoneToolType: 'FreehandMouse',\n options: {\n measurementTable: {\n displayFunction,\n },\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","const displayFunction = data => {\n let lengthValue = '';\n if (data.length && !isNaN(data.length)) {\n lengthValue = data.length.toFixed(2) + ' mm';\n }\n return lengthValue;\n};\n\nexport const length = {\n id: 'Length',\n name: 'Length',\n toolGroup: 'allTools',\n cornerstoneToolType: 'Length',\n options: {\n measurementTable: {\n displayFunction,\n },\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","export const nonTarget = {\n id: 'NonTarget',\n name: 'Non-Target',\n toolGroup: 'allTools',\n cornerstoneToolType: 'NonTarget',\n options: {\n measurementTable: {\n displayFunction: data => data.response,\n },\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","const displayFunction = data => {\n let meanValue = '';\n const { cachedStats } = data;\n if (cachedStats && cachedStats.mean && !isNaN(cachedStats.mean)) {\n meanValue = cachedStats.mean.toFixed(2) + ' HU';\n }\n return meanValue;\n};\n\nexport const rectangleRoi = {\n id: 'RectangleRoi',\n name: 'Rectangle',\n toolGroup: 'allTools',\n cornerstoneToolType: 'RectangleRoi',\n options: {\n measurementTable: {\n displayFunction,\n },\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","const displayFunction = data => {\n let text = '';\n if (data.rAngle && !isNaN(data.rAngle)) {\n text = data.rAngle.toFixed(2) + String.fromCharCode(parseInt('00B0', 16));\n }\n return text;\n};\n\nexport const angle = {\n id: 'Angle',\n name: 'Angle',\n toolGroup: 'allTools',\n cornerstoneToolType: 'Angle',\n options: {\n measurementTable: {\n displayFunction,\n },\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","export const targetCR = {\n id: 'TargetCR',\n name: 'CR Target',\n toolGroup: 'allTools',\n cornerstoneToolType: 'TargetCR',\n options: {\n measurementTable: {\n displayFunction: data => data.response,\n },\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","export const targetNE = {\n id: 'TargetNE',\n name: 'NE Target',\n toolGroup: 'allTools',\n cornerstoneToolType: 'TargetNE',\n options: {\n measurementTable: {\n displayFunction: data => data.response,\n },\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","export const targetUN = {\n id: 'TargetUN',\n name: 'UN Target',\n toolGroup: 'allTools',\n cornerstoneToolType: 'TargetUN',\n options: {\n measurementTable: {\n displayFunction: data => data.response,\n },\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","export const dicomSRDisplayTool = {\n id: 'DICOMSRDisplayTool',\n name: 'DICOMSRDisplayTool',\n toolGroup: 'allTools',\n cornerstoneToolType: 'DICOMSRDisplayTool',\n options: {\n measurementTable: {\n displayFunction: data => {\n return `(SR) ${data.lesionNamingNumber ||\n data.measurementNumber ||\n data.text ||\n ''}`;\n },\n },\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n\nexport default dicomSRDisplayTool;\n","import * as tools from '../tools';\n\nconst childTools = [];\nObject.keys(tools).forEach(key => childTools.push(tools[key]));\n\nexport const allTools = {\n id: 'allTools',\n name: 'Medidas',\n childTools: childTools,\n options: {\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","import { allTools } from './toolGroups/allTools';\nimport {\n retrieveMeasurements,\n storeMeasurements,\n retrieveTimepoints,\n storeTimepoints,\n removeTimepoint,\n updateTimepoint,\n disassociateStudy,\n} from './dataExchange';\n\nconst measurementApiDefaultConfig = {\n measurementTools: [allTools],\n newLesions: [\n {\n id: 'newTargets',\n name: 'New Targets',\n toolGroupId: 'targets',\n },\n {\n id: 'newNonTargets',\n name: 'New Non-Targets',\n toolGroupId: 'nonTargets',\n },\n ],\n dataExchange: {\n retrieve: retrieveMeasurements,\n store: storeMeasurements,\n },\n};\n\nconst timepointApiDefaultConfig = {\n dataExchange: {\n retrieve: retrieveTimepoints,\n store: storeTimepoints,\n remove: removeTimepoint,\n update: updateTimepoint,\n disassociate: disassociateStudy,\n },\n};\n\nexport { measurementApiDefaultConfig, timepointApiDefaultConfig };\n","import log from '../log';\n\nexport const retrieveMeasurements = (PatientID, timepointIds) => {\n log.error('retrieveMeasurements');\n return Promise.resolve();\n};\n\nexport const storeMeasurements = (measurementData, timepointIds) => {\n log.error('storeMeasurements');\n return Promise.resolve();\n};\n\nexport const retrieveTimepoints = filter => {\n log.error('retrieveTimepoints');\n return Promise.resolve();\n};\n\nexport const storeTimepoints = timepointData => {\n log.error('storeTimepoints');\n return Promise.resolve();\n};\n\nexport const updateTimepoint = (timepointData, query) => {\n log.error('updateTimepoint');\n return Promise.resolve();\n};\n\nexport const removeTimepoint = timepointId => {\n log.error('removeTimepoint');\n return Promise.resolve();\n};\n\nexport const disassociateStudy = (timepointIds, StudyInstanceUID) => {\n log.error('disassociateStudy');\n return Promise.resolve();\n};\n","import log from '../../log';\nimport { timepointApiDefaultConfig } from './../configuration.js';\n\nconst configuration = {\n ...timepointApiDefaultConfig,\n};\n\nconst TIMEPOINT_TYPE_NAMES = {\n prebaseline: 'Pre-Baseline',\n baseline: 'Baseline',\n followup: 'Follow-up',\n};\n\nexport default class TimepointApi {\n static Instance;\n\n static setConfiguration(config) {\n Object.assign(configuration, config);\n }\n\n static getConfiguration() {\n return configuration;\n }\n\n constructor(currentTimepointId, options = {}) {\n if (TimepointApi.Instance) {\n TimepointApi.Instance.initialize(currentTimepointId, options);\n return TimepointApi.Instance;\n }\n\n this.initialize(currentTimepointId, options);\n TimepointApi.Instance = this;\n }\n\n initialize(currentTimepointId, options = {}) {\n this.currentTimepointId = currentTimepointId;\n this.comparisonTimepointKey = options.comparisonTimepointKey || 'baseline';\n this.options = options;\n this.timepoints = [];\n }\n\n onTimepointsUpdated() {\n if (typeof this.options.onTimepointsUpdated !== 'function') {\n log.warn('Timepoints update callback is not defined');\n return;\n }\n\n this.options.onTimepointsUpdated(Object.assign([], this.timepoints));\n }\n\n calculateVisitNumber(timepoint) {\n // Retrieve all of the relevant follow-up timepoints for this patient\n const sortedTimepoints = this.timepoints.sort((tp1, tp2) => {\n return tp1.visitDate > tp2.visitDate ? 1 : -1;\n });\n const filteredTimepoints = sortedTimepoints.find(\n tp =>\n tp.PatientID === timepoint.PatientID &&\n tp.timepointType === timepoint.timepointType\n );\n\n // Create an array of just timepointIds, so we can use indexOf\n // on it to find the current timepoint's relative position\n const timepointIds = filteredTimepoints.map(\n timepoint => timepoint.timepointId\n );\n\n // Calculate the index of the current timepoint in the array of all\n // relevant follow-up timepoints\n const visitNumber = timepointIds.indexOf(timepoint.timepointId) + 1;\n\n // If visitNumber is 0, it means that the current timepoint was not in the list\n if (!visitNumber) {\n throw new Error(\n 'Current timepoint was not in the list of relevant timepoints?'\n );\n }\n\n return visitNumber;\n }\n\n retrieveTimepoints(filter) {\n const retrievalFn = configuration.dataExchange.retrieve;\n if (typeof retrievalFn !== 'function') {\n log.error('Timepoint retrieval function has not been configured.');\n return;\n }\n\n return new Promise((resolve, reject) => {\n retrievalFn(filter)\n .then(timepointData => {\n log.info('Timepoint data retrieval');\n\n timepointData.forEach(timepoint => {\n const timepointIndex = this.timepoints.findIndex(\n tp => tp.timepointId === timepoint.timepointId\n );\n if (timepointIndex < 0) {\n this.timepoints.push(timepoint);\n } else {\n this.timepoints[timepointIndex] = timepoint;\n }\n });\n\n // Let others know that the timepoints are updated\n this.onTimepointsUpdated();\n\n resolve();\n })\n .catch(reason => {\n log.error(`Timepoint retrieval function failed: ${reason}`);\n reject(reason);\n });\n });\n }\n\n storeTimepoints() {\n const storeFn = configuration.dataExchange.store;\n if (typeof storeFn !== 'function') {\n log.error('Timepoint store function has not been configured.');\n return;\n }\n\n log.info('Preparing to store timepoints');\n log.info(JSON.stringify(this.timepoints, null, 2));\n\n storeFn(this.timepoints).then(() =>\n log.info('Timepoint storage completed')\n );\n }\n\n disassociateStudy(timepointIds, StudyInstanceUID) {\n const disassociateFn = configuration.dataExchange.disassociate;\n if (typeof disassociateFn !== 'function') {\n log.error('Study disassociate function has not been configured.');\n return;\n }\n\n disassociateFn(timepointIds, StudyInstanceUID).then(() => {\n log.info('Disassociation completed');\n\n this.timepoints = [];\n this.retrieveTimepoints({});\n });\n }\n\n removeTimepoint(timepointId) {\n const removeFn = configuration.dataExchange.remove;\n if (typeof removeFn !== 'function') {\n log.error('Timepoint remove function has not been configured.');\n return;\n }\n\n const timepointData = {\n timepointId,\n };\n\n log.info('Preparing to remove timepoint');\n log.info(JSON.stringify(timepointData, null, 2));\n\n removeFn(timepointData).then(() => {\n log.info('Timepoint removal completed');\n\n const tpIndex = this.timepoints.findIndex(\n tp => tp.timepointId === timepointId\n );\n if (tpIndex > -1) {\n this.timepoints.splice(tpIndex, 1);\n }\n\n // Let others know that the timepoints are updated\n this.onTimepointsUpdated();\n });\n }\n\n updateTimepoint(timepointId, query) {\n const updateFn = configuration.dataExchange.update;\n if (typeof updateFn !== 'function') {\n log.error('Timepoint update function has not been configured.');\n return;\n }\n\n const timepointData = {\n timepointId,\n };\n\n log.info('Preparing to update timepoint');\n log.info(JSON.stringify(timepointData, null, 2));\n log.info(JSON.stringify(query, null, 2));\n\n updateFn(timepointData, query).then(() => {\n log.info('Timepoint updated completed');\n\n const tpIndex = this.timepoints.findIndex(\n tp => tp.timepointId === timepointId\n );\n if (tpIndex > -1) {\n this.timepoints[tpIndex] = Object.assign(\n {},\n this.timepoints[tpIndex],\n query\n );\n }\n\n // Let others know that the timepoints are updated\n this.onTimepointsUpdated();\n });\n }\n\n // Return all timepoints\n all(filter) {\n let timepointsToReturn;\n if (filter) {\n timepointsToReturn = this.timepoints.filter(filter);\n } else {\n timepointsToReturn = this.timepoints;\n }\n\n return timepointsToReturn.sort((tp1, tp2) => {\n return tp1.visitDate < tp2.visitDate ? 1 : -1;\n });\n }\n\n // Return only the current timepoint\n current() {\n return this.timepoints.find(\n tp => tp.timepointId === this.currentTimepointId\n );\n }\n\n lock() {\n const tpIndex = this.timepoints.findIndex(\n tp => tp.timepointId === this.currentTimepointId\n );\n if (tpIndex < 0) {\n return;\n }\n\n this.timepoints[tpIndex] = Object.assign({}, this.timepoints[tpIndex], {\n locked: true,\n });\n }\n\n // Return the prior timepoint\n prior() {\n const current = this.current();\n if (!current) {\n return;\n }\n\n return this.all().find(tp => tp.visitDate < current.visitDate);\n }\n\n // Return only the current and prior timepoints\n currentAndPrior() {\n const timepoints = [];\n\n const current = this.current();\n if (current) {\n timepoints.push(current);\n }\n\n const prior = this.prior();\n if (current && prior && prior.timepointId !== current.timepointId) {\n timepoints.push(prior);\n }\n\n return timepoints;\n }\n\n // Return the current and the comparison timepoints\n currentAndComparison(comparisonTimepointKey = this.comparisonTimepointKey) {\n const current = this.current();\n const comparisonTimepoint = this.comparison(comparisonTimepointKey);\n const timepoints = [current];\n\n if (\n comparisonTimepoint &&\n !timepoints.find(tp => tp.timepointId === comparisonTimepoint.timepointId)\n ) {\n timepoints.push(comparisonTimepoint);\n }\n\n return timepoints;\n }\n\n /**\n * Return true if there are 2 or more baseline timepoints before and at the current timepoint, otherwise false\n * @returns {boolean}\n */\n isRebaseline(timepointId) {\n const current = timepointId\n ? this.timepoints.find(tp => tp.timepointId === timepointId)\n : this.current();\n if (!current) {\n return false;\n }\n\n const baselines = this.timepoints.filter(\n tp => tp.timepointType === 'baseline' && tp.visitDate <= current.visitDate\n );\n return baselines.length > 1;\n }\n\n /**\n * Return the next (closest future) baseline after current timepoint\n * @returns {*}\n */\n nextBaselineAfterCurrent() {\n let current = this.current();\n\n // Get all next timepoints newer than the current timepoint sorted by visitDate ascending\n const sortedTimepoints = this.timepoints.sort((tp1, tp2) => {\n return tp1.visitDate > tp2.visitDate ? 1 : -1;\n });\n return sortedTimepoints.find(\n tp => tp.visitDate > current.visitDate && tp.timepointType === 'baseline'\n );\n }\n\n /**\n * Set the current timepoint id\n * @param timepointId\n */\n setCurrentTimepointId(timepointId) {\n this.currentTimepointId = timepointId;\n }\n\n /**\n * Set the comparison timepoint that overrides the default comparison timepoint (called based on user selection in a viewport)\n * @param timepoint\n */\n setUserComparison(timepoint) {\n this.userComparison = timepoint;\n }\n\n /**\n * Return only the comparison timepoint\n * @param {String} [comparisonTimepointKey]\n * @return {*}\n */\n comparison(comparisonTimepointKey = this.comparisonTimepointKey) {\n // Return the comparison timepoint set by user if exists\n if (this.userComparison) {\n return this.userComparison;\n }\n\n const current = this.current();\n if (!current) {\n return;\n }\n\n // If current timepoint is prebaseline, the first (closest future) BL after current is comparison regardless of default comparison timepoint\n if (current.timepointType === 'prebaseline') {\n const nextBaselineAfterCurrent = this.nextBaselineAfterCurrent();\n // If there is a next baseline, make it comparison, otherwise comparison is done by default comparison timepoint\n if (nextBaselineAfterCurrent) {\n return nextBaselineAfterCurrent;\n }\n }\n\n // If current timepoint is baseline, the prior is comparison if exists regardless of default comparison timepoint\n if (current.timepointType === 'baseline') {\n const prior = this.prior();\n if (prior) {\n return prior;\n }\n }\n\n const comparison = this[comparisonTimepointKey]();\n\n // Do not return a comparison if it would be identical to\n // the current.\n if (comparison && comparison.timepointId === current.timepointId) {\n return;\n }\n\n return comparison;\n }\n\n /**\n * Return the latest initial (prebaseline or baseline) timepoint after current and before the next followup timepoint\n * @returns {*}\n */\n latestInitialTimepointAfterCurrent() {\n let currentTimepoint = this.current();\n\n // Skip if the current timepoint is FU since there is no initial timepoint after follow-up\n if (currentTimepoint.timepointType === 'followup') {\n return;\n }\n\n // Get all next timepoints newer than the current timepoint sorted by visitDate ascending\n const sortedTimepoints = this.timepoints.sort((tp1, tp2) => {\n return tp1.visitDate > tp2.visitDate ? 1 : -1;\n });\n const allNextTimepoints = sortedTimepoints.filter(\n tp => tp.visitDate > currentTimepoint.visitDate\n );\n\n const nextFollowupIndex = allNextTimepoints.findIndex(\n tp => tp.timepointType === 'followup'\n );\n const latestInitialBeforeNextFUIndex = nextFollowupIndex - 1;\n\n if (latestInitialBeforeNextFUIndex < 0) {\n // There is no FU and all next timepoints are initial, so return the last one\n return allNextTimepoints[allNextTimepoints.length - 1];\n }\n\n // Return the latest initial timepoint before the next FU\n return allNextTimepoints[latestInitialBeforeNextFUIndex];\n }\n\n /**\n * Return timepoint ids of initial timepoints which are prebaseline and baseline\n * @returns {*}\n */\n initialTimepointIds() {\n let timepointToCheck = this.current();\n\n // If the current timepoint is PBL or BL, then get the recent PBL/BL of the current timepoint by its first FU\n // If it does not exist, then there is no newer initial timepoint, so the current timepoint is used to determine initial timepoint ids\n if (\n timepointToCheck.timepointType === 'prebaseline' ||\n timepointToCheck.timepointType === 'baseline'\n ) {\n timepointToCheck =\n this.latestInitialTimepointAfterCurrent() || timepointToCheck;\n }\n\n const visitDateToCheck = timepointToCheck.visitDate;\n\n const preBaselineTimepoints =\n this.timepoints.filter(\n tp =>\n tp.timepointType === 'prebaseline' && tp.visitDate <= visitDateToCheck\n ) || [];\n const preBaselineTimepointIds = preBaselineTimepoints.map(\n timepoint => timepoint.timepointId\n );\n\n const baselineTimepoints =\n this.timepoints.filter(\n tp =>\n tp.timepointType === 'baseline' && tp.visitDate <= visitDateToCheck\n ) || [];\n const baselineTimepointIds = baselineTimepoints.map(\n timepoint => timepoint.timepointId\n );\n\n return preBaselineTimepointIds.concat(baselineTimepointIds);\n }\n\n // Return only the baseline timepoint\n baseline() {\n const currentVisitDate = this.current().visitDate;\n return this.all().find(\n tp => tp.timepointType === 'baseline' && tp.visitDate <= currentVisitDate\n );\n }\n\n /**\n * Return only the nadir timepoint. Must be prior to the current timepoint\n * @return {any}\n */\n nadir() {\n const current = this.current();\n const nadir = this.all().find(\n tp =>\n tp.timepointId !== current.timepointId &&\n tp.timepointKey === 'nadir' &&\n tp.visitDate <= current.visitDate\n );\n\n // If we have found a nadir, return that\n if (nadir) {\n return nadir;\n }\n\n // Otherwise, return the most recent baseline\n // This should only happen if we are only at FU1,\n // so the baseline is the nadir.\n return this.baseline();\n }\n\n // Return only the key timepoints (current, prior, nadir and baseline)\n key() {\n const result = [this.current()];\n const prior = this.prior();\n const nadir = this.nadir();\n const baseline = this.baseline();\n\n const resultIncludes = timepoint =>\n !!result.find(x => x.timepointId === timepoint.timepointId);\n\n if (prior && resultIncludes(prior) === false) {\n result.push(prior);\n }\n\n if (nadir && resultIncludes(nadir) === false) {\n result.push(nadir);\n }\n\n if (baseline && resultIncludes(baseline) === false) {\n result.push(baseline);\n }\n\n return result;\n }\n\n // Return only the timepoints for the given study\n study(StudyInstanceUID) {\n return this.all().filter(timepoint =>\n timepoint.studyInstanceUIDs.includes(StudyInstanceUID)\n );\n }\n\n // Return the timepoint's name\n name(timepoint) {\n const timepointTypeName = TIMEPOINT_TYPE_NAMES[timepoint.timepointType];\n\n // Check if this is a Baseline timepoint, if it is, return 'Baseline'\n if (timepoint.timepointType === 'baseline') {\n return 'Baseline';\n } else if (timepoint.visitNumber) {\n return `${timepointTypeName} ${timepoint.visitNumber}`;\n }\n\n const visitNumber = this.calculateVisitNumber(timepoint);\n\n // Return the timepoint name as 'Follow-up N'\n return `${timepointTypeName} ${visitNumber}`;\n }\n\n // Build the timepoint title based on its date\n title(timepoint) {\n const timepointName = this.name(timepoint);\n\n const all = this.all();\n let index = -1;\n let currentIndex = null;\n for (let i = 0; i < all.length; i++) {\n const currentTimepoint = all[i];\n\n // Skip the iterations until we can't find the selected timepoint on study list\n if (this.currentTimepointId === currentTimepoint.timepointId) {\n currentIndex = 0;\n }\n\n if (currentIndex !== null) {\n index = currentIndex++;\n }\n\n // Break the loop if reached the timepoint to get the title\n if (currentTimepoint.timepointId === timepoint.timepointId) {\n break;\n }\n }\n\n const states = {\n 0: ['Current'],\n 1: ['Prior'],\n };\n const parenthesis = states[index] || [];\n const nadir = this.nadir();\n\n if (nadir && nadir.timepointId === timepoint.timepointId) {\n parenthesis.push('Nadir');\n }\n\n let parenthesisText = '';\n if (parenthesis.length) {\n parenthesisText = `(${parenthesis.join(', ')})`;\n }\n\n return `${timepointName} ${parenthesisText}`;\n }\n}\n","export default function(measurement) {\n if (!measurement) {\n return;\n }\n\n switch (measurement.toolType) {\n case 'Bidirectional':\n case 'TargetCR':\n case 'TargetNE':\n case 'TargetUN':\n return `Target ${measurement.lesionNamingNumber}`;\n case 'NonTarget':\n return `Non-Target ${measurement.lesionNamingNumber}`;\n }\n}\n","export default function(measurement) {\n return measurement.description;\n}\n","import studyMetadataManager from '../../utils/studyMetadataManager';\n\nexport default function(imagePath, thumbnail = false) {\n const [\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID,\n frameIndex,\n ] = imagePath.split('_');\n const studyMetadata = studyMetadataManager.get(StudyInstanceUID);\n const series = studyMetadata.getSeriesByUID(SeriesInstanceUID);\n const instance = series.getInstanceByUID(SOPInstanceUID);\n return instance.getImageId(frameIndex, thumbnail);\n}\n","import cornerstoneTools from 'cornerstone-tools';\nimport cornerstone from 'cornerstone-core';\nimport log from '../../log';\nimport getLabel from '../lib/getLabel';\nimport getDescription from '../lib/getDescription';\nimport getImageIdForImagePath from '../lib/getImageIdForImagePath';\nimport guid from '../../utils/guid';\nimport studyMetadataManager from '../../utils/studyMetadataManager';\nimport { measurementApiDefaultConfig } from './../configuration.js';\n\nconst configuration = {\n ...measurementApiDefaultConfig,\n};\n\nexport default class MeasurementApi {\n static Instance;\n\n /**\n * Set configuration: It should merge default configuration with any new one\n *\n * @static\n * @param {Object} config\n * @param {Object} config.server\n * @param {string} config.server.type - The server type\n * @param {string} config.server.wadoRoot - The server wado URL root\n * @param {Array} config.measurementTools\n * @param {string} config.measurementTools[].id - The tool group id\n * @param {string} config.measurementTools[].name - The tool group name\n * @param {Array} config.measurementTools[].childTools - The child tool's configuration\n * @param {Object} config.dataExchange\n * @param {Function} config.dataExchange.store - Function that store measurement data\n * @param {Function} config.dataExchange.retrieve - Function that retrieves measurement data\n *\n * @memberof MeasurementApi\n */\n static setConfiguration(config) {\n Object.assign(configuration, config);\n }\n\n static getConfiguration() {\n return configuration;\n }\n\n static getToolsGroupsMap() {\n const toolsGroupsMap = {};\n configuration.measurementTools.forEach(toolGroup => {\n toolGroup.childTools.forEach(\n tool => (toolsGroupsMap[tool.id] = toolGroup.id)\n );\n });\n\n return toolsGroupsMap;\n }\n\n static getToolGroupTools(toolsGroupsMap) {\n const result = {};\n Object.keys(toolsGroupsMap).forEach(toolType => {\n const toolGroupId = toolsGroupsMap[toolType];\n if (!result[toolGroupId]) {\n result[toolGroupId] = [];\n }\n\n result[toolGroupId].push(toolType);\n });\n\n return result;\n }\n\n static getToolConfiguration(toolType) {\n const configuration = MeasurementApi.getConfiguration();\n const toolsGroupsMap = MeasurementApi.getToolsGroupsMap();\n\n const toolGroupId = toolsGroupsMap[toolType];\n const toolGroup = configuration.measurementTools.find(\n toolGroup => toolGroup.id === toolGroupId\n );\n\n let tool;\n if (toolGroup) {\n tool = toolGroup.childTools.find(tool => tool.id === toolType);\n }\n\n return {\n toolGroupId,\n toolGroup,\n tool,\n };\n }\n\n static syncMeasurementAndToolData(measurement) {\n log.info('syncMeasurementAndToolData');\n\n const measurementLabel = getLabel(measurement);\n if (measurementLabel) {\n measurement.labels = [measurementLabel];\n }\n\n const toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.saveToolState();\n\n // Stop here if the metadata for the measurement's study is not loaded yet\n const { StudyInstanceUID } = measurement;\n const metadata = studyMetadataManager.get(StudyInstanceUID);\n if (!metadata) return;\n\n // Iterate each child tool if the current tool has children\n const toolType = measurement.toolType;\n const { tool } = MeasurementApi.getToolConfiguration(toolType);\n if (Array.isArray(tool.childTools)) {\n tool.childTools.forEach(childToolKey => {\n const childMeasurement = measurement[childToolKey];\n if (!childMeasurement) return;\n childMeasurement._id = measurement._id;\n childMeasurement.measurementNumber = measurement.measurementNumber;\n childMeasurement.lesionNamingNumber = measurement.lesionNamingNumber;\n\n MeasurementApi.syncMeasurementAndToolData(childMeasurement);\n });\n\n return;\n }\n\n const imageId = getImageIdForImagePath(measurement.imagePath);\n\n // If no tool state exists for this imageId, create an empty object to store it\n if (!toolState[imageId]) {\n toolState[imageId] = {};\n }\n\n const currentToolState = toolState[imageId][toolType];\n const toolData = currentToolState && currentToolState.data;\n\n // Check if we already have toolData for this imageId and toolType\n if (toolData && toolData.length) {\n // If we have toolData, we should search it for any data related to the current Measurement\n const toolData = toolState[imageId][toolType].data;\n\n // Create a flag so we know if we've successfully updated the Measurement in the toolData\n let alreadyExists = false;\n\n // Loop through the toolData to search for this Measurement\n toolData.forEach(tool => {\n // Break the loop if this isn't the Measurement we are looking for\n if (tool._id !== measurement._id) {\n return;\n }\n\n // If we have found the Measurement, set the flag to True\n alreadyExists = true;\n\n // Update the toolData from the Measurement data\n Object.assign(tool, measurement);\n return false;\n });\n\n // If we have found the Measurement we intended to update, we can stop this function here\n if (alreadyExists === true) {\n return;\n }\n } else {\n // If no toolData exists for this toolType, create an empty array to hold some\n toolState[imageId][toolType] = {\n data: [],\n };\n }\n\n // If we have reached this point, it means we haven't found the Measurement we are looking for\n // in the current toolData. This means we need to add it.\n\n // Add the MeasurementData into the toolData for this imageId\n toolState[imageId][toolType].data.push(measurement);\n\n cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState(\n toolState\n );\n }\n\n static isToolIncluded(tool) {\n return (\n tool.options &&\n tool.options.caseProgress &&\n tool.options.caseProgress.include\n );\n }\n\n constructor(timepointApi, options = {}) {\n if (MeasurementApi.Instance) {\n MeasurementApi.Instance.initialize(timepointApi, options);\n return MeasurementApi.Instance;\n }\n\n this.initialize(timepointApi, options);\n MeasurementApi.Instance = this;\n }\n\n initialize(timepointApi, options = {}) {\n this.timepointApi = timepointApi;\n this.options = options;\n this.toolGroups = {};\n this.tools = {};\n this.toolsGroupsMap = MeasurementApi.getToolsGroupsMap();\n this.toolGroupTools = MeasurementApi.getToolGroupTools(this.toolsGroupsMap);\n\n // Iterate over each tool group and create collection\n configuration.measurementTools.forEach(toolGroup => {\n this.toolGroups[toolGroup.id] = [];\n\n // Iterate over each tool group child tools (e.g. bidirectional, targetCR, etc.) and create collection\n toolGroup.childTools.forEach(tool => {\n this.tools[tool.id] = [];\n });\n });\n }\n\n onMeasurementsUpdated() {\n if (typeof this.options.onMeasurementsUpdated !== 'function') {\n log.warn('Measurements update callback is not defined');\n return;\n }\n\n this.options.onMeasurementsUpdated(Object.assign({}, this.tools));\n }\n\n retrieveMeasurements(PatientID, timepointIds) {\n const retrievalFn = configuration.dataExchange.retrieve;\n const { server } = configuration;\n if (typeof retrievalFn !== 'function') {\n log.error('Measurement retrieval function has not been configured.');\n return;\n }\n\n return new Promise((resolve, reject) => {\n retrievalFn(server).then(measurementData => {\n if (measurementData) {\n log.info('Measurement data retrieval');\n log.info(measurementData);\n\n Object.keys(measurementData).forEach(measurementTypeId => {\n const measurements = measurementData[measurementTypeId];\n\n measurements.forEach(measurement => {\n const { toolType } = measurement;\n\n this.addMeasurement(toolType, measurement);\n });\n });\n }\n\n resolve();\n\n // Synchronize the new tool data\n this.syncMeasurementsAndToolData();\n\n cornerstone.getEnabledElements().forEach(enabledElement => {\n if (enabledElement.image) {\n cornerstone.updateImage(enabledElement.element);\n }\n });\n\n // Let others know that the measurements are updated\n this.onMeasurementsUpdated();\n }, reject);\n });\n }\n\n storeMeasurements(timepointId) {\n const { server } = configuration;\n const storeFn = configuration.dataExchange.store;\n if (typeof storeFn !== 'function') {\n log.error('Measurement store function has not been configured.');\n return;\n }\n\n let measurementData = {};\n configuration.measurementTools.forEach(toolGroup => {\n // Skip the tool groups excluded from case progress\n if (!MeasurementApi.isToolIncluded(toolGroup)) {\n return;\n }\n\n toolGroup.childTools.forEach(tool => {\n // Skip the tools excluded from case progress\n if (!MeasurementApi.isToolIncluded(tool)) {\n return;\n }\n\n if (!measurementData[toolGroup.id]) {\n measurementData[toolGroup.id] = [];\n }\n\n measurementData[toolGroup.id] = measurementData[toolGroup.id].concat(\n this.tools[tool.id]\n );\n });\n });\n\n const timepointFilter = timepointId\n ? tp => tp.timepointId === timepointId\n : null;\n const timepoints = this.timepointApi.all(timepointFilter);\n const timepointIds = timepoints.map(t => t.timepointId);\n const PatientID = timepoints[0].PatientID;\n const filter = {\n PatientID,\n timepointIds,\n };\n\n log.info('Saving Measurements for timepoints:', timepoints);\n return storeFn(measurementData, filter, server).then(result => {\n log.info('Measurement storage completed');\n return result;\n });\n }\n\n calculateLesionNamingNumber(measurements) {\n const sortedMeasurements = measurements.sort((a, b) => {\n if (a.lesionNamingNumber > b.lesionNamingNumber) {\n return 1;\n } else if (a.lesionNamingNumber < b.lesionNamingNumber) {\n return -1;\n }\n\n return 0;\n });\n\n // Calculate lesion naming number starting from 1 not to miss any measurement (as seen in MM)\n // A measurement from beginning of the list might be deleted, so a new measurement should replace that\n let i;\n for (i = 1; i < sortedMeasurements.length + 1; i++) {\n if (i < sortedMeasurements[i - 1].lesionNamingNumber) {\n break;\n }\n }\n\n return i;\n }\n\n fetch(toolGroupId, filter) {\n if (!this.toolGroups[toolGroupId]) {\n throw new Error(\n `MeasurementApi: No Collection with the id: ${toolGroupId}`\n );\n }\n\n let items;\n if (filter) {\n items = this.toolGroups[toolGroupId].filter(filter);\n } else {\n items = this.toolGroups[toolGroupId];\n }\n\n return items.map(item => {\n if (item.toolId) {\n return this.tools[item.toolId].find(\n tool => tool._id === item.toolItemId\n );\n }\n\n return { lesionNamingNumber: item.lesionNamingNumber };\n });\n }\n\n getFirstMeasurement(timepointId) {\n // Get child tools from all included tool groups\n let childTools = [];\n configuration.measurementTools.forEach(toolGroup => {\n // Skip the tool groups excluded from case progress\n if (!MeasurementApi.isToolIncluded(toolGroup)) {\n return false;\n }\n\n childTools = childTools.concat(toolGroup.childTools);\n });\n\n // Get all included child tools\n const includedChildTools = childTools.filter(tool =>\n MeasurementApi.isToolIncluded(tool)\n );\n\n // Get the first measurement for the given timepoint\n let measurement = undefined;\n includedChildTools.every(tool => {\n measurement = this.tools[tool.id].find(\n t => t.timepointId === timepointId && t.measurementNumber === 1\n );\n\n return !measurement;\n });\n\n // Return the found measurement object or undefined if not found\n return measurement;\n }\n\n lesionExistsAtTimepoints(lesionNamingNumber, toolGroupId, timepointIds) {\n // Retrieve all the data for the given tool group (e.g. 'targets')\n const measurementsAtTimepoint = this.fetch(toolGroupId, tool =>\n timepointIds.includes(tool.timepointId)\n );\n\n // Return whether or not any lesion at this timepoint has the same lesionNamingNumber\n return !!measurementsAtTimepoint.find(\n m => m.lesionNamingNumber === lesionNamingNumber\n );\n }\n\n isNewLesionsMeasurement(measurementData) {\n if (!measurementData) {\n return;\n }\n\n const toolConfig = MeasurementApi.getToolConfiguration(\n measurementData.toolType\n );\n const toolType = toolConfig.tool.parentTool || measurementData.toolType;\n const { timepointApi } = this;\n const currentMeasurement =\n this.tools[toolType].find(tool => tool._id === measurementData._id) || {};\n const timepointId =\n currentMeasurement.timepointId || measurementData.timepointId;\n const lesionNamingNumber =\n currentMeasurement.lesionNamingNumber ||\n measurementData.lesionNamingNumber;\n\n // Stop here if the needed information is not set\n if (!timepointApi || !timepointId || !toolConfig) {\n return;\n }\n\n const { toolGroupId } = toolConfig;\n const current = timepointApi.timepoints.find(\n tp => tp.timepointId === timepointId\n );\n const initialTimepointIds = timepointApi.initialTimepointIds();\n\n // Stop here if there's no initial timepoint, or if the current is any initial\n if (\n !initialTimepointIds ||\n initialTimepointIds.length < 1 ||\n initialTimepointIds.some(\n initialtpid => initialtpid === current.timepointId\n )\n ) {\n return false;\n }\n\n return (\n this.lesionExistsAtTimepoints(\n lesionNamingNumber,\n toolGroupId,\n initialTimepointIds\n ) === false\n );\n }\n\n calculateLesionMaxMeasurementNumber(groupId, filter) {\n let measurements = [];\n if (groupId) {\n // Get the measurements of the group\n measurements = this.toolGroups[groupId] || [];\n } else {\n // Get all measurements of all groups\n measurements = Object.keys(this.toolGroups).reduce((acc, val) => {\n acc.push(...this.toolGroups[val]);\n return acc;\n }, []);\n }\n\n const sortedMeasurements = measurements.filter(filter).sort((tp1, tp2) => {\n return tp1.measurementNumber < tp2.measurementNumber ? 1 : -1;\n });\n\n for (let i = 0; i < sortedMeasurements.length; i++) {\n const toolGroupMeasurement = sortedMeasurements[i];\n const measurement = this.tools[toolGroupMeasurement.toolId].find(\n tool => tool._id === toolGroupMeasurement.toolItemId\n );\n const isNew = this.isNewLesionsMeasurement(measurement);\n if (!isNew) {\n return measurement.measurementNumber;\n }\n }\n\n return 0;\n }\n\n calculateNewLesionMaxMeasurementNumber(groupId, filter) {\n const sortedMeasurements = this.toolGroups[groupId]\n .filter(filter)\n .sort((tp1, tp2) => {\n return tp1.measurementNumber < tp2.measurementNumber ? 1 : -1;\n });\n\n for (let i = 0; i < sortedMeasurements.length; i++) {\n const toolGroupMeasurement = sortedMeasurements[i];\n const measurement = this.tools[toolGroupMeasurement.toolId].find(\n tool => tool._id === toolGroupMeasurement.toolItemId\n );\n const isNew = this.isNewLesionsMeasurement(measurement);\n if (isNew) {\n return measurement.measurementNumber;\n }\n }\n\n return 0;\n }\n\n calculateMeasurementNumber(measurement) {\n const toolGroupId = this.toolsGroupsMap[measurement.toolType];\n\n const filter = tool => tool._id !== measurement._id;\n\n const isNew = this.isNewLesionsMeasurement(measurement);\n\n if (isNew) {\n const maxTargetMeasurementNumber = this.calculateLesionMaxMeasurementNumber(\n 'targets',\n filter\n );\n const maxNonTargetMeasurementNumber = this.calculateLesionMaxMeasurementNumber(\n 'nonTargets',\n filter\n );\n const maxNewTargetMeasurementNumber = this.calculateNewLesionMaxMeasurementNumber(\n 'targets',\n filter\n );\n if (toolGroupId === 'targets') {\n return Math.max(\n maxTargetMeasurementNumber,\n maxNonTargetMeasurementNumber,\n maxNewTargetMeasurementNumber\n );\n } else if (toolGroupId === 'nonTargets') {\n const maxNewNonTargetMeasurementNumber = this.calculateNewLesionMaxMeasurementNumber(\n 'nonTargets',\n filter\n );\n return Math.max(\n maxTargetMeasurementNumber,\n maxNonTargetMeasurementNumber,\n maxNewTargetMeasurementNumber,\n maxNewNonTargetMeasurementNumber\n );\n }\n } else {\n const maxTargetMeasurementNumber = this.calculateLesionMaxMeasurementNumber(\n 'targets',\n filter\n );\n if (toolGroupId === 'targets') {\n return maxTargetMeasurementNumber;\n } else if (toolGroupId === 'nonTargets') {\n const maxNonTargetMeasurementNumber = this.calculateLesionMaxMeasurementNumber(\n 'nonTargets',\n filter\n );\n return Math.max(\n maxTargetMeasurementNumber,\n maxNonTargetMeasurementNumber\n );\n } else {\n return this.calculateLesionMaxMeasurementNumber(null, filter);\n }\n }\n\n return 0;\n }\n\n getPreviousMeasurement(measurementData) {\n if (!measurementData) {\n return;\n }\n\n const { timepointId, toolType, lesionNamingNumber } = measurementData;\n if (!timepointId || !toolType || !lesionNamingNumber) {\n return;\n }\n\n const toolGroupId = this.toolsGroupsMap[measurementData.toolType];\n\n // TODO: Remove TrialPatientLocationUID from here and override it somehow\n // by dependant applications. Here we should use the location attribute instead of the uid\n let filter;\n const uid =\n measurementData.additionalData &&\n measurementData.additionalData.TrialPatientLocationUID;\n if (uid) {\n filter = tool =>\n tool._id !== measurementData._id &&\n tool.additionalData &&\n tool.additionalData.TrialPatientLocationUID === uid;\n } else {\n filter = tool =>\n tool._id !== measurementData._id &&\n tool.lesionNamingNumber === lesionNamingNumber;\n }\n\n const childToolTypes = this.toolGroupTools[toolGroupId];\n for (let i = 0; i < childToolTypes.length; i++) {\n const childToolType = childToolTypes[i];\n const toolCollection = this.tools[childToolType];\n const item = toolCollection.find(filter);\n\n if (item) {\n return item;\n }\n }\n }\n\n hasDuplicateMeasurementNumber(measurementData) {\n if (!measurementData) {\n return;\n }\n\n const { toolType, measurementNumber } = measurementData;\n if (!toolType || !measurementNumber) {\n return;\n }\n\n const filter = tool =>\n tool._id !== measurementData._id &&\n tool.measurementNumber === measurementData.measurementNumber;\n\n return configuration.measurementTools\n .filter(toolGroup => toolGroup.id !== 'temp')\n .some(toolGroup => {\n if (this.toolGroups[toolGroup.id].find(filter)) {\n return true;\n }\n return toolGroup.childTools.some(tool => {\n if (this.tools[tool.id].find(filter)) {\n return true;\n }\n });\n });\n }\n\n updateNumbering(collectionToUpdate, propertyFilter, propertyName, increment) {\n collectionToUpdate.filter(propertyFilter).forEach(item => {\n item[propertyName] += increment;\n });\n }\n\n updateMeasurementNumberForAllMeasurements(measurement, increment) {\n const filter = tool =>\n tool._id !== measurement._id &&\n tool.measurementNumber >= measurement.measurementNumber;\n\n configuration.measurementTools\n .filter(toolGroup => toolGroup.id !== 'temp')\n .forEach(toolGroup => {\n this.updateNumbering(\n this.toolGroups[toolGroup.id],\n filter,\n 'measurementNumber',\n increment\n );\n\n toolGroup.childTools.forEach(tool => {\n this.updateNumbering(\n this.tools[tool.id],\n filter,\n 'measurementNumber',\n increment\n );\n });\n });\n }\n\n addMeasurement(toolType, measurement) {\n const toolGroup = this.toolsGroupsMap[toolType];\n const groupCollection = this.toolGroups[toolGroup];\n const collection = this.tools[toolType];\n\n // Get the related measurement by the measurement number and use its location if defined\n const relatedMeasurement = collection.find(\n t =>\n t.lesionNamingNumber === measurement.lesionNamingNumber &&\n t.toolType === measurement.toolType\n );\n\n // Use the related measurement location if found and defined\n if (relatedMeasurement && relatedMeasurement.location) {\n measurement.location = relatedMeasurement.location;\n }\n\n // Use the related measurement description if found and defined\n if (relatedMeasurement && relatedMeasurement.description) {\n measurement.description = relatedMeasurement.description;\n }\n\n measurement._id = guid();\n\n // Get the timepoint\n let timepoint;\n if (measurement.StudyInstanceUID) {\n timepoint = this.timepointApi.study(measurement.StudyInstanceUID)[0];\n } else {\n const { timepointId } = measurement;\n timepoint = this.timepointApi.timepoints.find(\n t => t.timepointId === timepointId\n );\n }\n\n // Preventing errors thrown when non-associated (standalone) study is opened...\n // @TODO: Make sure this logic is correct.\n if (!timepoint) return;\n\n // Empty Item is the lesion just added in cornerstoneTools, but does not have measurement data yet\n const emptyItem = groupCollection.find(\n groupTool =>\n !groupTool.toolId && groupTool.timepointId === timepoint.timepointId\n );\n\n // Set the timepointId attribute to measurement to make it easier to filter measurements by timepoint\n measurement.timepointId = timepoint.timepointId;\n\n // Check if the measurement data is just added by a cornerstone tool and is still empty\n if (emptyItem) {\n // Set relevant initial data and measurement number to the measurement\n measurement.lesionNamingNumber = emptyItem.lesionNamingNumber;\n measurement.measurementNumber = emptyItem.measurementNumber;\n\n groupCollection\n .filter(\n groupTool =>\n groupTool.timepointId === timepoint.timepointId &&\n groupTool.lesionNamingNumber === measurement.lesionNamingNumber\n )\n .forEach(groupTool => {\n groupTool.toolId = tool.id;\n groupTool.toolItemId = measurement._id;\n groupTool.createdAt = measurement.createdAt;\n groupTool.measurementNumber = measurement.measurementNumber;\n });\n } else {\n // Handle measurements not added by cornerstone tools and update its number\n const measurementsInTimepoint = groupCollection.filter(\n groupTool => groupTool.timepointId === timepoint.timepointId\n );\n measurement.lesionNamingNumber = this.calculateLesionNamingNumber(\n measurementsInTimepoint\n );\n measurement.measurementNumber =\n measurement.measurementNumber ||\n this.calculateMeasurementNumber(measurement) + 1;\n }\n\n // Define an update object to reflect the changes in the collection\n const updateObject = {\n timepointId: timepoint.timepointId,\n lesionNamingNumber: measurement.lesionNamingNumber,\n measurementNumber: measurement.measurementNumber,\n };\n\n // Find the matched measurement from other timepoints\n const found = this.getPreviousMeasurement(measurement);\n\n // Check if a previous related meausurement was found on other timepoints\n if (found) {\n // Use the same number as the previous measurement\n measurement.lesionNamingNumber = found.lesionNamingNumber;\n measurement.measurementNumber = found.measurementNumber;\n\n // TODO: Remove TrialPatientLocationUID from here and override it somehow\n // by dependant applications\n\n // Change the update object to set the same number, additionalData,\n // location, label and description to the current measurement\n updateObject.lesionNamingNumber = found.lesionNamingNumber;\n updateObject.measurementNumber = found.measurementNumber;\n updateObject.additionalData = measurement.additionalData || {};\n updateObject.additionalData.TrialPatientLocationUID =\n found.additionalData && found.additionalData.TrialPatientLocationUID;\n updateObject.location = found.location;\n updateObject.label = found.label;\n updateObject.description = found.description;\n updateObject.isSplitLesion = found.isSplitLesion;\n updateObject.isNodal = found.isNodal;\n\n const description = getDescription(found, measurement);\n if (description) {\n updateObject.description = description;\n }\n } else if (this.hasDuplicateMeasurementNumber(measurement)) {\n // Update measurementNumber for the measurements with masurementNumber greater or equal than\n // measurementNumber of the added measurement (except the added one)\n // only if there is another measurement with the same measurementNumber\n this.updateMeasurementNumberForAllMeasurements(measurement, 1);\n }\n\n let addedMeasurement;\n\n // Upsert the measurement in collection\n const toolIndex = collection.findIndex(\n tool => tool._id === measurement._id\n );\n if (toolIndex > -1) {\n addedMeasurement = Object.assign({}, collection[toolIndex], updateObject);\n collection[toolIndex] = addedMeasurement;\n } else {\n addedMeasurement = Object.assign({}, measurement, updateObject);\n collection.push(addedMeasurement);\n }\n\n if (measurement.isReadOnly) {\n addedMeasurement.isReadOnly = measurement.isReadOnly;\n }\n\n if (!emptyItem) {\n // Reflect the entry in the tool group collection\n groupCollection.push({\n toolId: toolType,\n toolItemId: addedMeasurement._id,\n timepointId: timepoint.timepointId,\n StudyInstanceUID: addedMeasurement.StudyInstanceUID,\n createdAt: addedMeasurement.createdAt,\n lesionNamingNumber: addedMeasurement.lesionNamingNumber,\n measurementNumber: addedMeasurement.measurementNumber,\n });\n }\n\n // Let others know that the measurements are updated\n this.onMeasurementsUpdated();\n\n // TODO: Enable reactivity\n // this.timepointChanged.set(timepoint.timepointId);\n\n return addedMeasurement;\n }\n\n updateMeasurement(toolType, measurement) {\n const collection = this.tools[toolType];\n\n const toolIndex = collection.findIndex(\n tool => tool._id === measurement._id\n );\n if (toolIndex < 0) {\n return;\n }\n\n collection[toolIndex] = Object.assign({}, measurement);\n\n // Let others know that the measurements are updated\n this.onMeasurementsUpdated();\n\n // TODO: Enable reactivity\n // this.timepointChanged.set(timepoint.timepointId);\n }\n\n onMeasurementRemoved(toolType, measurement) {\n const { lesionNamingNumber, measurementNumber } = measurement;\n\n const toolGroupId = this.toolsGroupsMap[toolType];\n const groupCollection = this.toolGroups[toolGroupId];\n\n const groupIndex = groupCollection.findIndex(\n group => group.toolItemId === measurement._id\n );\n if (groupIndex < 0) {\n return;\n }\n\n // Remove the deleted measurement only in its timepoint from the collection\n groupCollection.splice(groupIndex, 1);\n\n // Check which timepoints have the deleted measurement\n const timepointsWithDeletedMeasurement = groupCollection\n .filter(tool => tool.measurementNumber === measurementNumber)\n .map(tool => tool.timepointId);\n\n // Update lesionNamingNumber and measurementNumber only if there is no timepoint with that measurement\n if (timepointsWithDeletedMeasurement.length < 1) {\n // Decrease lesionNamingNumber of all measurements with lesionNamingNumber greater than lesionNamingNumber of the deleted measurement by 1\n const lesionNamingNumberFilter = tool =>\n tool.lesionNamingNumber >= lesionNamingNumber;\n this.updateNumbering(\n groupCollection,\n lesionNamingNumberFilter,\n 'lesionNamingNumber',\n -1\n );\n\n const toolGroup = configuration.measurementTools.find(\n tGroup => tGroup.id === toolGroupId\n );\n if (toolGroup && toolGroup.childTools) {\n toolGroup.childTools.forEach(childTool => {\n const collection = this.tools[childTool.id];\n this.updateNumbering(\n collection,\n lesionNamingNumberFilter,\n 'lesionNamingNumber',\n -1\n );\n });\n }\n\n // Decrease measurementNumber of all measurements with measurementNumber greater than measurementNumber of the deleted measurement by 1\n this.updateMeasurementNumberForAllMeasurements(measurement, -1);\n }\n\n // Synchronize the new tool data\n this.syncMeasurementsAndToolData();\n\n // Let others know that the measurements are updated\n this.onMeasurementsUpdated();\n\n // TODO: Enable reactivity\n // this.timepointChanged.set(timepoint.timepointId);\n }\n\n syncMeasurementsAndToolData() {\n configuration.measurementTools.forEach(toolGroup => {\n // Skip the tool groups excluded from case progress\n if (!MeasurementApi.isToolIncluded(toolGroup)) {\n return;\n }\n toolGroup.childTools.forEach(tool => {\n // Skip the tools excluded from case progress\n if (!MeasurementApi.isToolIncluded(tool)) {\n return;\n }\n const measurements = this.tools[tool.id];\n measurements.forEach(measurement => {\n MeasurementApi.syncMeasurementAndToolData(measurement);\n });\n });\n });\n }\n\n deleteMeasurements(toolType, measurementTypeId, filter) {\n const filterKeys = Object.keys(filter);\n const groupCollection = this.toolGroups[measurementTypeId];\n\n // Stop here if it is a temporary toolGroups\n if (!groupCollection) return;\n\n // Get the entries information before removing them\n const groupItems = groupCollection.filter(toolGroup => {\n return filterKeys.every(\n filterKey => toolGroup[filterKey] === filter[filterKey]\n );\n });\n const entries = [];\n groupItems.forEach(groupItem => {\n if (!groupItem.toolId) {\n return;\n }\n\n const collection = this.tools[groupItem.toolId];\n const toolIndex = collection.findIndex(\n tool => tool._id === groupItem.toolItemId\n );\n if (toolIndex > -1) {\n entries.push(collection[toolIndex]);\n collection.splice(toolIndex, 1);\n }\n });\n\n // Stop here if no entries were found\n if (!entries.length) {\n return;\n }\n\n // If the filter doesn't have the measurement number, get it from the first entry\n const lesionNamingNumber =\n filter.lesionNamingNumber || entries[0].lesionNamingNumber;\n\n // Synchronize the new data with cornerstone tools\n const toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.saveToolState();\n\n entries.forEach(entry => {\n const measurementsData = [];\n const { tool } = MeasurementApi.getToolConfiguration(entry.toolType);\n if (Array.isArray(tool.childTools)) {\n tool.childTools.forEach(key => {\n const childMeasurement = entry[key];\n if (!childMeasurement) return;\n measurementsData.push(childMeasurement);\n });\n } else {\n measurementsData.push(entry);\n }\n\n measurementsData.forEach(measurementData => {\n const { imagePath, toolType } = measurementData;\n const imageId = getImageIdForImagePath(imagePath);\n if (imageId && toolState[imageId]) {\n const toolData = toolState[imageId][toolType];\n const measurementEntries = toolData && toolData.data;\n const measurementEntry = measurementEntries.find(\n mEntry => mEntry._id === entry._id\n );\n if (measurementEntry) {\n const index = measurementEntries.indexOf(measurementEntry);\n measurementEntries.splice(index, 1);\n }\n }\n });\n\n this.onMeasurementRemoved(toolType, entry);\n });\n\n cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState(\n toolState\n );\n\n // Synchronize the updated measurements with Cornerstone Tools\n // toolData to make sure the displayed measurements show 'Target X' correctly\n const syncFilter = Object.assign({}, filter);\n delete syncFilter.timepointId;\n delete syncFilter.lesionNamingNumber;\n\n const syncFilterKeys = Object.keys(syncFilter);\n\n const toolTypes = [...new Set(entries.map(entry => entry.toolType))];\n toolTypes.forEach(toolType => {\n const collection = this.tools[toolType];\n collection\n .filter(tool => {\n return (\n tool.lesionNamingNumber > lesionNamingNumber - 1 &&\n syncFilterKeys.every(\n syncFilterKey => tool[syncFilterKey] === filter[syncFilterKey]\n )\n );\n })\n .forEach(measurement => {\n MeasurementApi.syncMeasurementAndToolData(measurement);\n });\n });\n }\n}\n","export class BaseCriterion {\n constructor(options, criterionName) {\n this.options = options;\n this.criterionName = criterionName;\n }\n\n generateResponse(message, measurements) {\n const passed = !message;\n const isGlobal = !measurements || !measurements.length;\n\n return {\n passed,\n isGlobal,\n message,\n measurements,\n criterionName: this.criterionName,\n };\n }\n\n getNewTargetNumbers(data) {\n const { options } = this;\n const baselineMeasurementNumbers = [];\n const newTargetNumbers = new Set();\n\n if (options.newTarget) {\n data.targets.forEach(target => {\n const { measurementNumber } = target.measurement;\n if (target.timepoint.timepointType === 'baseline') {\n baselineMeasurementNumbers.push(measurementNumber);\n }\n });\n data.targets.forEach(target => {\n const { measurementNumber } = target.measurement;\n if (target.timepoint.timepointType === 'followup') {\n if (!baselineMeasurementNumbers.includes(measurementNumber)) {\n newTargetNumbers.add(measurementNumber);\n }\n }\n });\n }\n\n return newTargetNumbers;\n }\n}\n","import { BaseCriterion } from './BaseCriterion';\n\nexport const LocationSchema = {\n type: 'object',\n};\n\n/* LocationCriterion\n * Check if the there are non-target measurements with response different than \"present\" on baseline\n */\nexport class LocationCriterion extends BaseCriterion {\n constructor(...props) {\n super(...props);\n }\n\n evaluate(data) {\n const items = data.targets.concat(data.nonTargets);\n const measurements = [];\n let message;\n\n items.forEach(item => {\n const measurement = item.measurement;\n\n if (!measurement.location) {\n measurements.push(measurement);\n }\n });\n\n if (measurements.length) {\n message = 'All measurements should have a location';\n }\n\n return this.generateResponse(message, measurements);\n }\n}\n","import { BaseCriterion } from './BaseCriterion';\n\nexport const MaxTargetsPerOrganSchema = {\n type: 'object',\n properties: {\n limit: {\n label: 'Max targets allowed per organ',\n type: 'integer',\n minimum: 1,\n },\n newTarget: {\n label: 'Flag to evaluate only new targets',\n type: 'boolean',\n },\n isNodal: {\n label: 'Filter to evaluate only nodal or extranodal measurements',\n type: 'boolean'\n },\n message: {\n label: 'Message to be displayed in case of nonconformity',\n type: 'string',\n }\n },\n required: ['limit'],\n};\n\n/*\n * MaxTargetsPerOrganCriterion\n * Check if the number of target measurements per organ exceeded the limit allowed\n * Options:\n * limit: Max targets allowed in study\n * newTarget: Flag to evaluate only new targets (must be evaluated on both)\n * isNodal: Filter to evaluate only nodal or extranodal measurements\n * message: Message to be displayed in case of nonconformity\n */\nexport class MaxTargetsPerOrganCriterion extends BaseCriterion {\n constructor(...props) {\n super(...props);\n }\n\n evaluate(data) {\n const { options } = this;\n const targetsPerOrgan = {};\n let measurements = [];\n\n const newTargetNumbers = this.getNewTargetNumbers(data);\n data.targets.forEach(target => {\n const { measurement } = target;\n const { location, measurementNumber, isSplitLesion, isNodal } = measurement;\n\n if (isSplitLesion)\n return;\n\n if (typeof isNodal === 'boolean' && typeof options.isNodal === 'boolean' && options.isNodal !== isNodal)\n return;\n\n if (!targetsPerOrgan[location]) {\n targetsPerOrgan[location] = new Set();\n }\n\n if (!options.newTarget || newTargetNumbers.has(measurementNumber)) {\n targetsPerOrgan[location].add(measurementNumber);\n }\n\n if (targetsPerOrgan[location].size > options.limit) {\n measurements.push(measurement);\n }\n });\n\n let message;\n if (measurements.length) {\n const increment = options.newTarget ? 'new ' : '';\n message =\n options.message ||\n `Each organ should not have more than ${\n options.limit\n } ${increment}targets.`;\n }\n\n return this.generateResponse(message, measurements);\n }\n}\n","import { BaseCriterion } from './BaseCriterion';\n\nexport const MaxTargetsSchema = {\n type: 'object',\n properties: {\n limit: {\n label: 'Max targets allowed in study',\n type: 'integer',\n minimum: 0,\n },\n newTarget: {\n label: 'Flag to evaluate only new targets',\n type: 'boolean',\n },\n locationIn: {\n label:\n 'Filter to evaluate only measurements with the specified locations',\n type: 'array',\n items: {\n type: 'string',\n },\n minItems: 1,\n uniqueItems: true,\n },\n locationNotIn: {\n label:\n 'Filter to evaluate only measurements without the specified locations',\n type: 'array',\n items: {\n type: 'string',\n },\n minItems: 1,\n uniqueItems: true,\n },\n isNodal: {\n label: 'Filter to evaluate only nodal or extranodal measurements',\n type: 'boolean'\n },\n message: {\n label: 'Message to be displayed in case of nonconformity',\n type: 'string',\n }\n },\n required: ['limit'],\n};\n\n/* MaxTargetsCriterion\n * Check if the number of target measurements exceeded the limit allowed\n * Options:\n * limit: Max targets allowed in study\n * newTarget: Flag to evaluate only new targets (must be evaluated on both)\n * locationIn: Filter to evaluate only measurements with the specified locations\n * locationNotIn: Filter to evaluate only measurements without the specified locations\n * isNodal: Filter to evaluate only nodal or extranodal measurements\n * message: Message to be displayed in case of nonconformity\n */\nexport class MaxTargetsCriterion extends BaseCriterion {\n constructor(...props) {\n super(...props);\n }\n\n evaluate(data) {\n const { options } = this;\n\n const newTargetNumbers = this.getNewTargetNumbers(data);\n const measurementNumbers = [];\n data.targets.forEach(target => {\n const { location, measurementNumber, isSplitLesion, isNodal } = target.measurement;\n\n if (isSplitLesion)\n return;\n\n if (typeof isNodal === 'boolean' && typeof options.isNodal === 'boolean' && options.isNodal !== isNodal)\n return;\n\n if (options.newTarget && !newTargetNumbers.has(measurementNumber))\n return;\n\n if (options.locationIn && options.locationIn.indexOf(location) === -1)\n return;\n\n if (options.locationNotIn && options.locationNotIn.indexOf(location) > -1)\n return;\n\n measurementNumbers.push(measurementNumber);\n });\n\n let lesionType = '';\n if (typeof options.isNodal === 'boolean') {\n lesionType = options.isNodal ? 'nodal ' : 'extranodal ';\n }\n\n let message;\n if (measurementNumbers.length > options.limit) {\n const increment = options.newTarget ? 'new ' : '';\n const plural = options.limit === 1 ? '' : 's';\n const amount = options.limit === 0 ? '' : `more than ${options.limit}`;\n message =\n options.message ||\n `The study should not have ${amount} ${increment}${lesionType}target${plural}.`;\n }\n\n return this.generateResponse(message);\n }\n}\n","import { BaseCriterion } from './BaseCriterion';\n\nexport const MeasurementsLengthSchema = {\n type: 'object',\n properties: {\n longAxis: {\n label: 'Minimum length of long axis',\n type: 'number',\n minimum: 0,\n },\n shortAxis: {\n label: 'Minimum length of short axis',\n type: 'number',\n minimum: 0,\n },\n longAxisSliceThicknessMultiplier: {\n label: 'Length of long axis multiplier',\n type: 'number',\n minimum: 0,\n },\n shortAxisSliceThicknessMultiplier: {\n label: 'Length of short axis multiplier',\n type: 'number',\n minimum: 0,\n },\n modalityIn: {\n label:\n 'Filter to evaluate only measurements with the specified modalities',\n type: 'array',\n items: {\n type: 'string',\n },\n minItems: 1,\n uniqueItems: true,\n },\n modalityNotIn: {\n label:\n 'Filter to evaluate only measurements without the specified modalities',\n type: 'array',\n items: {\n type: 'string',\n },\n minItems: 1,\n uniqueItems: true,\n },\n locationIn: {\n label:\n 'Filter to evaluate only measurements with the specified locations',\n type: 'array',\n items: {\n type: 'string',\n },\n minItems: 1,\n uniqueItems: true,\n },\n locationNotIn: {\n label:\n 'Filter to evaluate only measurements without the specified locations',\n type: 'array',\n items: {\n type: 'string',\n },\n minItems: 1,\n uniqueItems: true,\n },\n isNodal: {\n label: 'Filter to evaluate only nodal or extranodal measurements',\n type: 'boolean',\n },\n message: {\n label: 'Message to be displayed in case of nonconformity',\n type: 'string',\n },\n },\n anyOf: [\n { required: ['message', 'longAxis'] },\n { required: ['message', 'shortAxis'] },\n { required: ['message', 'longAxisSliceThicknessMultiplier'] },\n { required: ['message', 'shortAxisSliceThicknessMultiplier'] },\n ],\n};\n\n/*\n * MeasurementsLengthCriterion\n * Check the measurements of all bidirectional tools based on\n * short axis, long axis, modalities, location and slice thickness\n * Options:\n * longAxis: Minimum length of long axis\n * shortAxis: Minimum length of short axis\n * longAxisSliceThicknessMultiplier: Length of long axis multiplier\n * shortAxisSliceThicknessMultiplier: Length of short axis multiplier\n * modalityIn: Filter to evaluate only measurements with the specified modalities\n * modalityNotIn: Filter to evaluate only measurements without the specified modalities\n * locationIn: Filter to evaluate only measurements with the specified locations\n * locationNotIn: Filter to evaluate only measurements without the specified locations\n * isNodal: Filter to evaluate only nodal or extranodal measurements\n * message: Message to be displayed in case of nonconformity\n */\nexport class MeasurementsLengthCriterion extends BaseCriterion {\n constructor(...props) {\n super(...props);\n }\n\n evaluate(data) {\n let message;\n let measurements = [];\n const { options } = this;\n const longMultiplier = options.longAxisSliceThicknessMultiplier;\n const shortMultiplier = options.shortAxisSliceThicknessMultiplier;\n\n data.targets.forEach(item => {\n const { metadata, measurement } = item;\n const { location } = measurement;\n\n let { longestDiameter, shortestDiameter, isNodal } = measurement;\n if (measurement.childToolsCount) {\n const child = measurement.bidirectional;\n longestDiameter = (child && child.longestDiameter) || 0;\n shortestDiameter = (child && child.shortestDiameter) || 0;\n }\n\n const { SliceThickness } = metadata;\n\n const Modality = metadata.getTagValue('Modality') || '';\n\n // Stop here if the measurement does not match the Modality and location filters\n if (\n typeof isNodal === 'boolean' &&\n typeof options.isNodal === 'boolean' &&\n options.isNodal !== isNodal\n )\n return;\n if (options.locationIn && options.locationIn.indexOf(location) === -1)\n return;\n if (options.modalityIn && options.modalityIn.indexOf(Modality) === -1)\n return;\n if (options.locationNotIn && options.locationNotIn.indexOf(location) > -1)\n return;\n if (options.modalityNotIn && options.modalityNotIn.indexOf(Modality) > -1)\n return;\n\n // Check the measurement length\n const failed =\n (options.longAxis && longestDiameter < options.longAxis) ||\n (options.shortAxis && shortestDiameter < options.shortAxis) ||\n (longMultiplier &&\n !isNaN(SliceThickness) &&\n longestDiameter < longMultiplier * SliceThickness) ||\n (shortMultiplier &&\n !isNaN(SliceThickness) &&\n shortestDiameter < shortMultiplier * SliceThickness);\n\n // Mark this measurement as invalid if some of the checks have failed\n if (failed) {\n measurements.push(measurement);\n }\n });\n\n // Use the options' message if some measurement is invalid\n if (measurements.length) {\n message = options.message;\n }\n\n return this.generateResponse(message, measurements);\n }\n}\n","import { BaseCriterion } from './BaseCriterion';\n\nexport const ModalitySchema = {\n type: 'object',\n properties: {\n method: {\n label: 'Specify if it\\'s goinig to \"allow\" or \"deny\" the modalities',\n type: 'string',\n enum: ['allow', 'deny'],\n },\n measurementTypes: {\n label: 'List of measurement types that will be evaluated',\n type: 'array',\n items: {\n type: 'string',\n },\n minItems: 1,\n uniqueItems: true,\n },\n modalities: {\n label: 'List of allowed/denied modalities',\n type: 'array',\n items: {\n type: 'string',\n },\n minItems: 1,\n uniqueItems: true,\n },\n },\n required: ['method', 'modalities'],\n};\n\n/*\n * ModalityCriteria\n * Check if a Modality is allowed or denied\n * Options:\n * method (string): Specify if it\\'s goinig to \"allow\" or \"deny\" the modalities\n * measurementTypes (string[]): List of measurement types that will be evaluated\n * modalities (string[]): List of allowed/denied modalities\n */\nexport class ModalityCriterion extends BaseCriterion {\n constructor(...props) {\n super(...props);\n }\n\n evaluate(data) {\n const measurementTypes = this.options.measurementTypes || ['targets'];\n const modalitiesSet = new Set(this.options.modalities);\n const validationMethod = this.options.method;\n const measurements = [];\n const invalidModalities = new Set();\n let message;\n\n measurementTypes.forEach(measurementType => {\n const items = data[measurementType];\n\n items.forEach(item => {\n const { measurement, metadata } = item;\n const Modality = metadata.getTagValue('Modality') || '';\n\n if (\n (validationMethod === 'allow' && !modalitiesSet.has(Modality)) ||\n (validationMethod === 'deny' && modalitiesSet.has(Modality))\n ) {\n measurements.push(measurement);\n invalidModalities.add(Modality);\n }\n });\n });\n\n if (measurements.length) {\n const uniqueModalities = Array.from(invalidModalities);\n const uniqueModalitiesText = uniqueModalities.join(', ');\n const modalityText =\n uniqueModalities.length > 1 ? 'modalities' : 'Modality';\n\n message = `The ${modalityText} ${uniqueModalitiesText} should not be used as a method of measurement`;\n }\n\n return this.generateResponse(message, measurements);\n }\n}\n","import { BaseCriterion } from './BaseCriterion';\n\nexport const NonTargetResponseSchema = {\n type: 'object',\n};\n\n/* NonTargetResponseCriterion\n * Check if the there are non-target measurements with response different than \"present\" on baseline\n */\nexport class NonTargetResponseCriterion extends BaseCriterion {\n constructor(...props) {\n super(...props);\n }\n\n evaluate(data) {\n const items = data.nonTargets;\n const measurements = [];\n let message;\n\n items.forEach(item => {\n const measurement = item.measurement;\n const response = (measurement.response || '').toLowerCase();\n\n if (response !== 'present') {\n measurements.push(measurement);\n }\n });\n\n if (measurements.length) {\n message = 'Non-targets can only be assessed as \"present\"';\n }\n\n return this.generateResponse(message, measurements);\n }\n}\n","import { BaseCriterion } from './BaseCriterion';\n\nexport const TargetTypeSchema = {\n type: 'object',\n};\n\n/* TargetTypeCriterion\n * Check if the there are non-bidirectional target measurements on baseline\n */\nexport class TargetTypeCriterion extends BaseCriterion {\n constructor(...props) {\n super(...props);\n }\n\n evaluate(data) {\n const items = data.targets;\n const measurements = [];\n let message;\n\n items.forEach(item => {\n const measurement = item.measurement;\n\n if (\n measurement.toolType !== 'Bidirectional' &&\n !measurement.bidirectional\n ) {\n measurements.push(measurement);\n }\n });\n\n if (measurements.length) {\n message =\n 'Target lesions must have measurements (cannot be assessed as CR, UN/NE, EX)';\n }\n\n return this.generateResponse(message, measurements);\n }\n}\n","import { BaseCriterion } from './criteria/BaseCriterion';\nimport * as initialCriteria from './criteria';\nimport Ajv from 'ajv';\n\nconst Criteria = Object.assign({}, initialCriteria);\n\nexport class CriteriaEvaluator {\n constructor(criteriaObject) {\n const criteriaValidator = this.getCriteriaValidator();\n this.criteria = [];\n\n if (!criteriaValidator(criteriaObject)) {\n let message = '';\n criteriaValidator.errors.forEach(error => {\n message += `\\noptions${error.dataPath} ${error.message}`;\n });\n throw new Error(message);\n }\n\n Object.keys(criteriaObject).forEach(criterionkey => {\n const optionsObject = criteriaObject[criterionkey];\n const Criterion = Criteria[`${criterionkey}Criterion`];\n const optionsArray =\n optionsObject instanceof Array ? optionsObject : [optionsObject];\n optionsArray.forEach(options =>\n this.criteria.push(new Criterion(options, criterionkey))\n );\n });\n }\n\n getMaxTargets(newTarget = false) {\n let result = 0;\n this.criteria.forEach(criterion => {\n const newTargetMatch = newTarget === !!criterion.options.newTarget;\n if (criterion instanceof Criteria.MaxTargetsCriterion && newTargetMatch) {\n const { limit } = criterion.options;\n if (limit > result) {\n result = limit;\n }\n }\n });\n return result;\n }\n\n getCriteriaValidator() {\n if (CriteriaEvaluator.criteriaValidator) {\n return CriteriaEvaluator.criteriaValidator;\n }\n\n const schema = {\n properties: {},\n definitions: {},\n };\n\n Object.keys(Criteria).forEach(key => {\n const Criterion = Criteria[key];\n if (Criterion.prototype instanceof BaseCriterion) {\n const criterionkey = key.replace(/Criterion$/, '');\n const criterionDefinition = `#/definitions/${criterionkey}`;\n\n schema.definitions[criterionkey] = Criteria[`${criterionkey}Schema`];\n schema.properties[criterionkey] = {\n oneOf: [\n { $ref: criterionDefinition },\n {\n type: 'array',\n items: {\n $ref: criterionDefinition,\n },\n },\n ],\n };\n }\n });\n\n CriteriaEvaluator.criteriaValidator = new Ajv().compile(schema);\n return CriteriaEvaluator.criteriaValidator;\n }\n\n evaluate(data) {\n const nonconformities = [];\n this.criteria.forEach(criterion => {\n const criterionResult = criterion.evaluate(data);\n if (!criterionResult.passed) {\n nonconformities.push(criterionResult);\n }\n });\n return nonconformities;\n }\n\n static setCriterion(criterionKey, criterionDefinitions) {\n Criteria[criterionKey] = criterionDefinitions;\n }\n}\n","import * as recistEvaluation from './recist.json';\n\nexport const recist11 = recistEvaluation;\n","import { CriteriaEvaluator } from './CriteriaEvaluator';\nimport * as initialEvaluations from './evaluations';\nimport log from '../../log';\n\nconst evaluations = Object.assign({}, initialEvaluations);\n\nconst BASELINE = 'baseline';\nconst FOLLOWUP = 'followup';\nconst BOTH = 'both';\nconst TARGETS = 'targets';\nconst NONTARGETS = 'nonTargets';\n\nclass ConformanceCriteria {\n constructor(measurementApi, timepointApi, options = {}) {\n this.measurementApi = measurementApi;\n this.timepointApi = timepointApi;\n this.nonconformities = [];\n this.groupedNonConformities = [];\n this.maxTargets = null;\n this.maxNewTargets = null;\n this.options = options;\n }\n\n loadStudy(StudyInstanceUID) {\n if (typeof this.options.loadStudy !== 'function') {\n throw new Error('loadStudy callback is not defined');\n }\n\n return this.options.loadStudy(null, StudyInstanceUID);\n }\n\n async validate(trialCriteriaType) {\n const baselinePromise = this.getData(BASELINE);\n const followupPromise = this.getData(FOLLOWUP);\n const [baselineData, followupData] = await Promise.all([\n baselinePromise,\n followupPromise,\n ]);\n const mergedData = {\n targets: [],\n nonTargets: [],\n };\n\n mergedData.targets = mergedData.targets.concat(baselineData.targets);\n mergedData.targets = mergedData.targets.concat(followupData.targets);\n mergedData.nonTargets = mergedData.nonTargets.concat(\n baselineData.nonTargets\n );\n mergedData.nonTargets = mergedData.nonTargets.concat(\n followupData.nonTargets\n );\n\n this.maxTargets = null;\n this.maxNewTargets = null;\n const resultBoth = this.validateTimepoint(\n BOTH,\n trialCriteriaType,\n mergedData\n );\n const resultBaseline = this.validateTimepoint(\n BASELINE,\n trialCriteriaType,\n baselineData\n );\n const resultFollowup = this.validateTimepoint(\n FOLLOWUP,\n trialCriteriaType,\n followupData\n );\n const nonconformities = resultBaseline\n .concat(resultFollowup)\n .concat(resultBoth);\n const groupedNonConformities = this.groupNonConformities(nonconformities);\n\n // Keep both? Group the data only on viewer/measurementTable views?\n // Work with not grouped data (worse lookup performance on measurementTableRow)?\n this.nonconformities = nonconformities;\n this.groupedNonConformities = groupedNonConformities;\n\n console.warn('nonconformities');\n console.warn(nonconformities);\n console.warn('groupedNonConformities');\n console.warn(groupedNonConformities);\n\n return nonconformities;\n }\n\n groupNonConformities(nonconformities) {\n const groups = {};\n const toolsGroupsMap = this.measurementApi.toolsGroupsMap;\n\n nonconformities.forEach(nonConformity => {\n if (nonConformity.isGlobal) {\n groups.globals = groups.globals || { messages: [] };\n groups.globals.messages.push(nonConformity.message);\n\n return;\n }\n\n nonConformity.measurements.forEach(measurement => {\n const groupName = toolsGroupsMap[measurement.toolType];\n groups[groupName] = groups[groupName] || { measurementNumbers: {} };\n\n const group = groups[groupName];\n const measureNumber = measurement.measurementNumber;\n let measurementNumbers = group.measurementNumbers[measureNumber];\n\n if (!measurementNumbers) {\n measurementNumbers = group.measurementNumbers[measureNumber] = {\n messages: [],\n measurements: [],\n };\n }\n\n measurementNumbers.messages.push(nonConformity.message);\n measurementNumbers.measurements.push(measurement);\n });\n });\n\n return groups;\n }\n\n validateTimepoint(timepointType, trialCriteriaType, data) {\n const evaluators = this.getEvaluators(timepointType, trialCriteriaType);\n let nonconformities = [];\n\n evaluators.forEach(evaluator => {\n const maxTargets = evaluator.getMaxTargets(false);\n const maxNewTargets = evaluator.getMaxTargets(true);\n if (maxTargets) {\n this.maxTargets = maxTargets;\n }\n\n if (maxNewTargets) {\n this.maxNewTargets = maxNewTargets;\n }\n\n const result = evaluator.evaluate(data);\n\n if (result.length > 0) {\n result.forEach(resultItem => {\n resultItem.timepointType = timepointType;\n });\n }\n\n nonconformities = nonconformities.concat(result);\n });\n\n return nonconformities;\n }\n\n getEvaluators(timepointType, trialCriteriaType) {\n const evaluators = [];\n console.warn(evaluations);\n const trialCriteriaTypeId = trialCriteriaType.id.toLowerCase();\n const evaluation = evaluations[trialCriteriaTypeId];\n\n if (evaluation) {\n const evaluationTimepoint = evaluation[timepointType];\n\n if (evaluationTimepoint) {\n evaluators.push(new CriteriaEvaluator(evaluationTimepoint));\n }\n }\n\n return evaluators;\n }\n\n /*\n * Build the data that will be used to do the conformance criteria checks\n */\n async getData(timepointType) {\n const data = {\n targets: [],\n nonTargets: [],\n };\n\n const studyPromises = [];\n\n const fillData = measurementType => {\n const measurements = this.measurementApi.fetch(measurementType);\n\n measurements.forEach(measurement => {\n const { StudyInstanceUID } = measurement;\n\n const timepointId = measurement.timepointId;\n const timepoint =\n timepointId &&\n this.timepointApi.timepoints.find(a => a.timepointId === timepointId);\n\n if (\n !timepoint ||\n (timepointType !== BOTH && timepoint.timepointType !== timepointType)\n ) {\n return;\n }\n\n const promise = this.loadStudy(StudyInstanceUID);\n promise.then(\n studyMetadata => {\n data[measurementType].push({\n measurement,\n metadata: studyMetadata.getFirstInstance(),\n timepoint,\n });\n },\n error => {\n throw new Error(error);\n }\n );\n studyPromises.push(promise);\n });\n };\n\n fillData(TARGETS);\n fillData(NONTARGETS);\n\n await Promise.all(studyPromises);\n\n return data;\n }\n\n static setEvaluationDefinitions(evaluationKey, evaluationDefinitions) {\n evaluations[evaluationKey] = evaluationDefinitions;\n }\n}\n\nexport default ConformanceCriteria;\n//OHIF.measurements.ConformanceCriteria = ConformanceCriteria;\n","import cornerstone from 'cornerstone-core';\n\nexport default function(element, imageId) {\n if (!imageId) {\n // Get the Cornerstone imageId\n const enabledElement = cornerstone.getEnabledElement(element);\n imageId = enabledElement.image.imageId;\n }\n\n // Get StudyInstanceUID & PatientID\n const {\n StudyInstanceUID,\n PatientID,\n SeriesInstanceUID,\n SOPInstanceUID,\n } = cornerstone.metaData.get('instance', imageId);\n\n const splitImageId = imageId.split('&frame');\n const frameIndex =\n splitImageId[1] !== undefined ? Number(splitImageId[1]) : 0;\n\n const imagePath = [\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID,\n frameIndex,\n ].join('_');\n\n return {\n PatientID,\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID,\n frameIndex,\n imagePath,\n };\n}\n","import cornerstone from 'cornerstone-core';\n\nexport default function refreshCornerstoneViewports() {\n cornerstone.getEnabledElements().forEach(enabledElement => {\n if (enabledElement.image) {\n cornerstone.updateImage(enabledElement.element);\n }\n });\n}\n","import cornerstone from 'cornerstone-core';\nimport { MeasurementApi } from '../classes';\nimport log from '../../log';\nimport user from '../../user';\nimport getImageAttributes from '../lib/getImageAttributes';\nimport getLabel from '../lib/getLabel';\nimport refreshCornerstoneViewports from '../lib/refreshCornerstoneViewports';\n\nexport default function handleSingleMeasurementAdded({ eventData, tool }) {\n const measurementApi = MeasurementApi.Instance;\n if (!measurementApi) {\n log.warn('Measurement API is not initialized');\n }\n\n const { measurementData, toolType } = eventData;\n\n const collection = measurementApi.tools[toolType];\n\n // Stop here if the tool data shall not be persisted (e.g. temp tools)\n if (!collection) return;\n\n // Stop here if there's no measurement data or if it was cancelled\n if (!measurementData || measurementData.cancelled) return;\n\n log.info('CornerstoneToolsMeasurementAdded');\n\n const imageAttributes = getImageAttributes(eventData.element);\n const measurement = Object.assign({}, measurementData, imageAttributes, {\n lesionNamingNumber: measurementData.lesionNamingNumber,\n userId: user.getUserId(),\n toolType,\n });\n\n const addedMeasurement = measurementApi.addMeasurement(toolType, measurement);\n Object.assign(measurementData, addedMeasurement);\n\n const measurementLabel = getLabel(measurementData);\n if (measurementLabel) {\n measurementData.labels = [measurementLabel];\n }\n\n // TODO: This is very hacky, but will work for now\n refreshCornerstoneViewports();\n\n // TODO: Notify about the last activated measurement\n\n if (MeasurementApi.isToolIncluded(tool)) {\n // TODO: Notify that viewer suffered changes\n }\n}\n","import cornerstone from 'cornerstone-core';\nimport { MeasurementApi } from '../classes';\nimport log from '../../log';\nimport user from '../../user';\nimport getImageAttributes from '../lib/getImageAttributes';\nimport getLabel from '../lib/getLabel';\nimport refreshCornerstoneViewports from '../lib/refreshCornerstoneViewports';\n\nexport default function({ eventData, tool, toolGroupId, toolGroup }) {\n const measurementApi = MeasurementApi.Instance;\n if (!measurementApi) {\n log.warn('Measurement API is not initialized');\n }\n\n const { measurementData } = eventData;\n\n const collection = measurementApi.tools[tool.parentTool];\n\n // Stop here if the tool data shall not be persisted (e.g. temp tools)\n if (!collection) return;\n\n // Stop here if there's no measurement data or if it was cancelled\n if (!measurementData || measurementData.cancelled) return;\n\n log.info('CornerstoneToolsMeasurementAdded');\n\n const imageAttributes = getImageAttributes(eventData.element);\n\n const additionalProperties = Object.assign(imageAttributes, {\n userId: user.getUserId(),\n });\n\n const childMeasurement = Object.assign(\n {},\n measurementData,\n additionalProperties\n );\n\n const parentMeasurement = collection.find(\n t =>\n t.toolType === tool.parentTool &&\n t.PatientID === imageAttributes.PatientID &&\n t[tool.attribute] === null\n );\n\n // Check if a measurement to fit this child tool already exists\n if (parentMeasurement) {\n const key = tool.attribute;\n\n // Add the createdAt attribute\n childMeasurement.createdAt = new Date();\n\n // Update the parent measurement\n parentMeasurement[key] = childMeasurement;\n parentMeasurement.childToolsCount =\n (parentMeasurement.childToolsCount || 0) + 1;\n measurementApi.updateMeasurement(tool.parentTool, parentMeasurement);\n\n // Update the measurementData ID and lesionNamingNumber\n measurementData._id = parentMeasurement._id;\n measurementData.lesionNamingNumber = parentMeasurement.lesionNamingNumber;\n } else {\n const measurement = {\n toolType: tool.parentTool,\n lesionNamingNumber: measurementData.lesionNamingNumber,\n userId: user.getUserId(),\n PatientID: imageAttributes.PatientID,\n StudyInstanceUID: imageAttributes.StudyInstanceUID,\n };\n\n measurement[tool.attribute] = Object.assign(\n {},\n measurementData,\n additionalProperties\n );\n\n const addedMeasurement = measurementApi.addMeasurement(\n tool.parentTool,\n measurement\n );\n Object.assign(measurementData, addedMeasurement);\n }\n\n const measurementLabel = getLabel(measurementData);\n if (measurementLabel) {\n measurementData.labels = [measurementLabel];\n }\n\n // TODO: This is very hacky, but will work for now\n refreshCornerstoneViewports();\n\n // TODO: Notify about the last activated measurement\n\n if (MeasurementApi.isToolIncluded(tool)) {\n // TODO: Notify that viewer suffered changes\n }\n}\n","import cornerstone from 'cornerstone-core';\nimport { MeasurementApi } from '../classes';\nimport log from '../../log';\n\nexport default function({ eventData, tool, toolGroupId, toolGroup }) {\n const measurementApi = MeasurementApi.Instance;\n if (!measurementApi) {\n log.warn('Measurement API is not initialized');\n }\n\n const { measurementData, toolType } = eventData;\n\n const collection = measurementApi.tools[toolType];\n\n // Stop here if the tool data shall not be persisted (e.g. temp tools)\n if (!collection) return;\n\n log.info('CornerstoneToolsMeasurementModified');\n let measurement = collection.find(t => t._id === measurementData._id);\n\n // Stop here if the measurement is already deleted\n if (!measurement) return;\n\n measurement = Object.assign(measurement, measurementData);\n measurement.viewport = cornerstone.getViewport(eventData.element);\n\n measurementApi.updateMeasurement(toolType, measurement);\n\n // TODO: Notify about the last activated measurement\n\n if (MeasurementApi.isToolIncluded(tool)) {\n // TODO: Notify that viewer suffered changes\n }\n}\n","import cornerstone from 'cornerstone-core';\nimport { MeasurementApi } from '../classes';\nimport log from '../../log';\n\nexport default function({ eventData, tool, toolGroupId, toolGroup }) {\n const measurementApi = MeasurementApi.Instance;\n if (!measurementApi) {\n log.warn('Measurement API is not initialized');\n }\n\n const { measurementData } = eventData;\n\n const collection = measurementApi.tools[tool.parentTool];\n\n // Stop here if the tool data shall not be persisted (e.g. temp tools)\n if (!collection) return;\n\n log.info('CornerstoneToolsMeasurementModified');\n\n const measurement = collection.find(t => t._id === measurementData._id);\n let childMeasurement = measurement && measurement[tool.attribute];\n\n // Stop here if the measurement is already deleted\n if (!childMeasurement) return;\n\n childMeasurement = Object.assign(childMeasurement, measurementData);\n childMeasurement.viewport = cornerstone.getViewport(eventData.element);\n\n // Update the parent measurement\n measurement[tool.attribute] = childMeasurement;\n measurementApi.updateMeasurement(tool.parentTool, measurement);\n\n // TODO: Notify about the last activated measurement\n\n if (MeasurementApi.isToolIncluded(tool)) {\n // TODO: Notify that viewer suffered changes\n }\n}\n","import cornerstone from 'cornerstone-core';\nimport { MeasurementApi } from '../classes';\nimport log from '../../log';\nimport refreshCornerstoneViewports from '../lib/refreshCornerstoneViewports';\n\nexport default function handleSingleMeasurementRemoved({\n eventData,\n tool,\n toolGroupId,\n toolGroup,\n}) {\n log.info('CornerstoneToolsMeasurementRemoved');\n const { measurementData, toolType } = eventData;\n\n const measurementApi = MeasurementApi.Instance;\n if (!measurementApi) {\n log.warn('Measurement API is not initialized');\n }\n\n const collection = measurementApi.tools[toolType];\n\n // Stop here if the tool data shall not be persisted (e.g. temp tools)\n if (!collection) return;\n\n const measurementTypeId = measurementApi.toolsGroupsMap[toolType];\n const measurement = collection.find(t => t._id === measurementData._id);\n\n // Stop here if the measurement is already gone or never existed\n if (!measurement) return;\n\n // Remove all the measurements with the given type and number\n const { lesionNamingNumber, timepointId } = measurement;\n measurementApi.deleteMeasurements(toolType, measurementTypeId, {\n lesionNamingNumber,\n timepointId,\n });\n\n // TODO: This is very hacky, but will work for now\n refreshCornerstoneViewports();\n\n if (MeasurementApi.isToolIncluded(tool)) {\n // TODO: Notify that viewer suffered changes\n }\n}\n","import cornerstone from 'cornerstone-core';\nimport { MeasurementApi } from '../classes';\nimport log from '../../log';\nimport refreshCornerstoneViewports from '../lib/refreshCornerstoneViewports';\n\nexport default function({ eventData, tool, toolGroupId, toolGroup }) {\n log.info('CornerstoneToolsMeasurementRemoved');\n const { measurementData } = eventData;\n\n const measurementApi = MeasurementApi.Instance;\n if (!measurementApi) {\n log.warn('Measurement API is not initialized');\n }\n\n const collection = measurementApi.tools[tool.parentTool];\n\n // Stop here if the tool data shall not be persisted (e.g. temp tools)\n if (!collection) return;\n\n const measurementIndex = collection.findIndex(\n t => t._id === measurementData._id\n );\n const measurement =\n measurementIndex > -1 ? collection[measurementIndex] : null;\n\n // Stop here if the measurement is already gone or never existed\n if (!measurement) return;\n\n if (measurement.childToolsCount === 1) {\n // Remove the measurement\n collection.splice(measurementIndex, 1);\n measurementApi.onMeasurementRemoved(tool.parentTool, measurement);\n } else {\n // Update the measurement\n measurement[tool.attribute] = null;\n measurement.childToolsCount = (measurement.childToolsCount || 0) - 1;\n measurementApi.updateMeasurement(tool.parentTool, measurement);\n }\n\n // TODO: This is very hacky, but will work for now\n refreshCornerstoneViewports();\n\n if (MeasurementApi.isToolIncluded(tool)) {\n // TODO: Notify that viewer suffered changes\n }\n}\n","import { MeasurementApi } from '../classes';\nimport handleSingleMeasurementAdded from './handleSingleMeasurementAdded';\nimport handleChildMeasurementAdded from './handleChildMeasurementAdded';\nimport handleSingleMeasurementModified from './handleSingleMeasurementModified';\nimport handleChildMeasurementModified from './handleChildMeasurementModified';\nimport handleSingleMeasurementRemoved from './handleSingleMeasurementRemoved';\nimport handleChildMeasurementRemoved from './handleChildMeasurementRemoved';\n\nconst getEventData = event => {\n const eventData = event.detail;\n if (eventData.toolName) {\n eventData.toolType = eventData.toolName;\n }\n\n return eventData;\n};\n\nconst MeasurementHandlers = {\n handleSingleMeasurementAdded,\n handleChildMeasurementAdded,\n handleSingleMeasurementModified,\n handleChildMeasurementModified,\n handleSingleMeasurementRemoved,\n handleChildMeasurementRemoved,\n\n onAdded(event) {\n const eventData = getEventData(event);\n const { toolType } = eventData;\n const {\n toolGroupId,\n toolGroup,\n tool,\n } = MeasurementApi.getToolConfiguration(toolType);\n const params = {\n eventData,\n tool,\n toolGroupId,\n toolGroup,\n };\n\n if (!tool) return;\n\n if (tool.parentTool) {\n handleChildMeasurementAdded(params);\n } else {\n handleSingleMeasurementAdded(params);\n }\n },\n\n onModified(event) {\n const eventData = getEventData(event);\n const { toolType } = eventData;\n const {\n toolGroupId,\n toolGroup,\n tool,\n } = MeasurementApi.getToolConfiguration(toolType);\n const params = {\n eventData,\n tool,\n toolGroupId,\n toolGroup,\n };\n\n if (!tool) return;\n\n if (tool.parentTool) {\n handleChildMeasurementModified(params);\n } else {\n handleSingleMeasurementModified(params);\n }\n },\n\n onRemoved(event) {\n const eventData = getEventData(event);\n const { toolType } = eventData;\n const {\n toolGroupId,\n toolGroup,\n tool,\n } = MeasurementApi.getToolConfiguration(toolType);\n const params = {\n eventData,\n tool,\n toolGroupId,\n toolGroup,\n };\n\n if (!tool) return;\n\n if (tool.parentTool) {\n handleChildMeasurementRemoved(params);\n } else {\n handleSingleMeasurementRemoved(params);\n }\n },\n};\n\nexport default MeasurementHandlers;\n","import { bidirectional, targetCR, targetUN, targetNE } from '../tools';\n\nexport const targets = {\n id: 'targets',\n name: 'Targets',\n childTools: [bidirectional, targetCR, targetUN, targetNE],\n options: {\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","import { nonTarget } from '../tools';\n\nexport const nonTargets = {\n id: 'nonTargets',\n name: 'Non-Targets',\n childTools: [nonTarget],\n options: {\n caseProgress: {\n include: true,\n evaluate: true,\n },\n },\n};\n","import { length, ellipticalRoi } from '../tools';\nimport cloneDeep from 'lodash.clonedeep';\n\nconst childTools = cloneDeep([length, ellipticalRoi]);\n\n// Exclude temp tools from case progress\nchildTools.forEach(childTool => {\n childTool.options = Object.assign({}, childTool.options, {\n caseProgress: {\n include: false,\n evaluate: false,\n },\n });\n});\n\nexport const temp = {\n id: 'temp',\n name: 'Temporary',\n childTools,\n options: {\n caseProgress: {\n include: false,\n evaluate: false,\n },\n },\n};\n","import { targets } from './toolGroups/targets';\nimport { nonTargets } from './toolGroups/nonTargets';\nimport { temp } from './toolGroups/temp';\nimport cloneDeep from 'lodash.clonedeep';\n\nconst ltTools = cloneDeep([targets, nonTargets, temp]);\n\nltTools.forEach(toolGroup => {\n toolGroup.childTools.forEach(tool => {\n tool.toolGroup = toolGroup.id;\n });\n});\n\nexport default ltTools;\n","import * as tools from './tools';\n\nimport { MeasurementApi, TimepointApi } from './classes';\nimport { ConformanceCriteria } from './conformance';\nimport MeasurementHandlers from './measurementHandlers';\nimport getDescription from './lib/getDescription';\nimport getImageAttributes from './lib/getImageAttributes';\nimport getImageIdForImagePath from './lib/getImageIdForImagePath';\nimport getLabel from './lib/getLabel';\nimport ltTools from './ltTools';\n\nconst measurements = {\n TimepointApi,\n MeasurementApi,\n ConformanceCriteria,\n MeasurementHandlers,\n ltTools,\n tools,\n getLabel,\n getDescription,\n getImageAttributes,\n getImageIdForImagePath,\n};\n\nexport default measurements;\n","import DICOMWeb from '../../../DICOMWeb/';\nimport { api } from 'dicomweb-client';\n\nimport errorHandler from '../../../errorHandler';\n\n/**\n * Parses data returned from a QIDO search and transforms it into\n * an array of series that are present in the study\n *\n * @param server The DICOM server\n * @param StudyInstanceUID\n * @param resultData\n * @returns {Array} Series List\n */\nfunction resultDataToStudyMetadata(server, StudyInstanceUID, resultData) {\n const seriesMap = {};\n const series = [];\n\n resultData.forEach(function(instance) {\n // Use seriesMap to cache series data\n // If the series instance UID has already been used to\n // process series data, continue using that series\n var SeriesInstanceUID = DICOMWeb.getString(instance['0020000E']);\n var series = seriesMap[SeriesInstanceUID];\n\n // If no series data exists in the seriesMap cache variable,\n // process any available series data\n if (!series) {\n series = {\n SeriesInstanceUID: SeriesInstanceUID,\n SeriesNumber: DICOMWeb.getString(instance['00200011']),\n instances: [],\n };\n\n // Save this data in the seriesMap cache variable\n seriesMap[SeriesInstanceUID] = series;\n series.push(series);\n }\n\n // The uri for the dicomweb\n // NOTE: DCM4CHEE seems to return the data zipped\n // NOTE: Orthanc returns the data with multi-part mime which cornerstoneWADOImageLoader doesn't\n // know how to parse yet\n //var uri = DICOMWeb.getString(instance['00081190']);\n //uri = uri.replace('wado-rs', 'dicom-web');\n\n // manually create a WADO-URI from the UIDs\n // NOTE: Haven't been able to get Orthanc's WADO-URI to work yet - maybe its not configured?\n var SOPInstanceUID = DICOMWeb.getString(instance['00080018']);\n var uri =\n server.wadoUriRoot +\n '?requestType=WADO&studyUID=' +\n StudyInstanceUID +\n '&seriesUID=' +\n SeriesInstanceUID +\n '&objectUID=' +\n SOPInstanceUID +\n '&contentType=application%2Fdicom';\n\n // Add this instance to the current series\n series.instances.push({\n SOPClassUID: DICOMWeb.getString(instance['00080016']),\n SOPInstanceUID: SOPInstanceUID,\n uri: uri,\n InstanceNumber: DICOMWeb.getString(instance['00200013']),\n });\n });\n return series;\n}\n\n/**\n * Retrieve a set of instances using a QIDO call\n * @param server\n * @param StudyInstanceUID\n * @throws ECONNREFUSED\n * @returns {{wadoUriRoot: String, StudyInstanceUID: String, series: Array}}\n */\nexport default function Instances(server, StudyInstanceUID) {\n // TODO: Are we using this function anywhere?? Can we remove it?\n\n const config = {\n url: server.qidoRoot,\n headers: DICOMWeb.getAuthorizationHeader(server),\n errorInterceptor: errorHandler.getHTTPErrorHandler(),\n };\n const dicomWeb = new api.DICOMwebClient(config);\n const queryParams = getQIDOQueryParams(\n filter,\n server.qidoSupportsIncludeField\n );\n const options = {\n studyInstanceUID: StudyInstanceUID,\n };\n\n return dicomWeb.searchForInstances(options).then(result => {\n return {\n wadoUriRoot: server.wadoUriRoot,\n StudyInstanceUID: StudyInstanceUID,\n series: resultDataToStudyMetadata(server, StudyInstanceUID, result.data),\n };\n });\n}\n","import { api } from 'dicomweb-client';\nimport StaticWadoClient from './StaticWadoClient';\nimport DICOMWeb from '../../../DICOMWeb/';\n\nimport errorHandler from '../../../errorHandler';\nimport getXHRRetryRequestHook from '../../../utils/xhrRetryRequestHook';\n\n/**\n * Creates a QIDO date string for a date range query\n * Assumes the year is positive, at most 4 digits long.\n *\n * @param date The Date object to be formatted\n * @returns {string} The formatted date string\n */\nfunction dateToString(date) {\n if (!date) return '';\n let year = date.getFullYear().toString();\n let month = (date.getMonth() + 1).toString();\n let day = date.getDate().toString();\n year = '0'.repeat(4 - year.length).concat(year);\n month = '0'.repeat(2 - month.length).concat(month);\n day = '0'.repeat(2 - day.length).concat(day);\n return ''.concat(year, month, day);\n}\n\n/**\n * Produces a QIDO URL given server details and a set of specified search filter\n * items\n *\n * @param filter\n * @param serverSupportsQIDOIncludeField\n * @returns {string} The URL with encoded filter query data\n */\nfunction getQIDOQueryParams(filter, serverSupportsQIDOIncludeField) {\n const commaSeparatedFields = [\n '00081030', // Study Description\n '00080060', // Modality\n // Add more fields here if you want them in the result\n ].join(',');\n\n const parameters = {\n PatientName: filter.PatientName,\n PatientID: filter.PatientID,\n AccessionNumber: filter.AccessionNumber,\n StudyDescription: filter.StudyDescription,\n ModalitiesInStudy: filter.ModalitiesInStudy,\n limit: filter.limit,\n offset: filter.offset,\n fuzzymatching: filter.fuzzymatching,\n includefield: serverSupportsQIDOIncludeField ? commaSeparatedFields : 'all',\n };\n\n // build the StudyDate range parameter\n if (filter.studyDateFrom || filter.studyDateTo) {\n const dateFrom = dateToString(new Date(filter.studyDateFrom));\n const dateTo = dateToString(new Date(filter.studyDateTo));\n parameters.StudyDate = `${dateFrom}-${dateTo}`;\n }\n\n // Build the StudyInstanceUID parameter\n if (filter.StudyInstanceUID) {\n let studyUIDs = filter.StudyInstanceUID;\n studyUIDs = Array.isArray(studyUIDs) ? studyUIDs.join() : studyUIDs;\n studyUIDs = studyUIDs.replace(/[^0-9.]+/g, '\\\\');\n parameters.StudyInstanceUID = studyUIDs;\n }\n\n // Clean query params of undefined values.\n const params = {};\n Object.keys(parameters).forEach(key => {\n if (parameters[key] !== undefined && parameters[key] !== '') {\n params[key] = parameters[key];\n }\n });\n\n return params;\n}\n\n/**\n * Parses resulting data from a QIDO call into a set of Study MetaData\n *\n * @param resultData\n * @returns {Array} An array of Study MetaData objects\n */\nfunction resultDataToStudies(resultData) {\n const studies = [];\n\n if (!resultData || !resultData.length) return;\n\n resultData.forEach(study =>\n studies.push({\n StudyInstanceUID: DICOMWeb.getString(study['0020000D']),\n // 00080005 = SpecificCharacterSet\n StudyDate: DICOMWeb.getString(study['00080020']),\n StudyTime: DICOMWeb.getString(study['00080030']),\n AccessionNumber: DICOMWeb.getString(study['00080050']),\n referringPhysicianName: DICOMWeb.getString(study['00080090']),\n // 00081190 = URL\n PatientName: DICOMWeb.getName(study['00100010']),\n PatientID: DICOMWeb.getString(study['00100020']),\n PatientBirthdate: DICOMWeb.getString(study['00100030']),\n patientSex: DICOMWeb.getString(study['00100040']),\n studyId: DICOMWeb.getString(study['00200010']),\n numberOfStudyRelatedSeries: DICOMWeb.getString(study['00201206']),\n numberOfStudyRelatedInstances: DICOMWeb.getString(study['00201208']),\n StudyDescription: DICOMWeb.getString(study['00081030']),\n // Modality: DICOMWeb.getString(study['00080060']),\n // ModalitiesInStudy: DICOMWeb.getString(study['00080061']),\n modalities: DICOMWeb.getString(\n DICOMWeb.getModalities(study['00080060'], study['00080061'])\n ),\n })\n );\n\n return studies;\n}\n\nexport default function Studies(server, filter) {\n const { staticWado } = server;\n const config = {\n ...server,\n url: server.qidoRoot,\n headers: DICOMWeb.getAuthorizationHeader(server),\n errorInterceptor: errorHandler.getHTTPErrorHandler(),\n requestHooks: [getXHRRetryRequestHook()],\n };\n\n const dicomWeb = staticWado\n ? new StaticWadoClient(config)\n : new api.DICOMwebClient(config);\n server.qidoSupportsIncludeField =\n server.qidoSupportsIncludeField === undefined\n ? true\n : server.qidoSupportsIncludeField;\n const queryParams = getQIDOQueryParams(\n filter,\n server.qidoSupportsIncludeField\n );\n const options = {\n queryParams,\n };\n\n return dicomWeb.searchForStudies(options).then(resultDataToStudies);\n}\n","// DICOMWeb instance, study, and metadata retrieval\nimport Instances from './qido/instances.js';\nimport Studies from './qido/studies.js';\nimport RetrieveMetadata from './wado/retrieveMetadata.js';\n\nconst WADO = {\n RetrieveMetadata,\n};\n\nconst QIDO = {\n Studies,\n Instances,\n};\n\nexport { QIDO, WADO };\n","import Studies from './services/qido/studies';\n\nconst studySearchPromises = new Map();\n\n/**\n * Search for studies information by the given filter\n *\n * @param {Object} filter Filter that will be used on search\n * @returns {Promise} resolved with an array of studies information or rejected with an error\n */\nexport default function searchStudies(server, filter) {\n const promiseKeyObj = {\n qidoRoot: server.qidoRoot,\n filter,\n };\n const promiseKey = JSON.stringify(promiseKeyObj);\n if (studySearchPromises.has(promiseKey)) {\n return studySearchPromises.get(promiseKey);\n } else {\n const promise = Studies(server, filter);\n\n studySearchPromises.set(promiseKey, promise);\n\n return promise;\n }\n}\n","import { QIDO, WADO } from './services/';\nimport {\n deleteStudyMetadataPromise,\n retrieveStudyMetadata,\n} from './retrieveStudyMetadata.js';\n\nimport getStudyBoxData from './getStudyBoxData';\nimport retrieveStudiesMetadata from './retrieveStudiesMetadata.js';\nimport searchStudies from './searchStudies';\nimport sortStudy from './sortStudy';\n\nconst studies = {\n services: {\n QIDO,\n WADO,\n },\n loadingDict: {},\n retrieveStudyMetadata,\n deleteStudyMetadataPromise,\n retrieveStudiesMetadata,\n getStudyBoxData,\n searchStudies,\n sortStudy,\n};\n\nexport default studies;\n","import log from '../log.js';\nimport { retrieveStudyMetadata } from './retrieveStudyMetadata';\n\n/**\n * Retrieves metaData for multiple studies at once.\n *\n * This function calls retrieveStudyMetadata several times, asynchronously,\n * and waits for all of the results to be returned.\n *\n * @param {Object} server Object with server configuration parameters\n * @param {Array} studyInstanceUIDs The UIDs of the Studies to be retrieved\n * @param {Object} [filters] - Object containing filters to be applied on retrieve metadata process\n * @param {string} [filter.seriesInstanceUID] - series instance uid to filter results against\n * @param {boolean} [separateSeriesInstanceUIDFilters = false] - If true, split filtered metadata calls into multiple calls,\n * as some DICOMWeb implementations only support single filters.\n * @returns {Promise} that will be resolved with the metadata or rejected with the error\n */\nexport default function retrieveStudiesMetadata(\n server,\n studyInstanceUIDs,\n filters,\n separateSeriesInstanceUIDFilters = false\n) {\n // Create an empty array to store the Promises for each metaData retrieval call\n const promises = [];\n\n // Loop through the array of studyInstanceUIDs\n studyInstanceUIDs.forEach(function(StudyInstanceUID) {\n // Send the call and resolve or reject the related promise based on its outcome\n const promise = retrieveStudyMetadata(\n server,\n StudyInstanceUID,\n filters,\n separateSeriesInstanceUIDFilters\n );\n\n // Add the current promise to the array of promises\n promises.push(promise);\n });\n\n // When all of the promises are complete, this callback runs\n const promise = Promise.all(promises);\n\n // Warn the error on console if some retrieval failed\n promise.catch(error => log.warn(error));\n\n return promise;\n}\n","/**\n * Overridable namespace to allow getting study boxes data externally.\n *\n * The function must handle the first parameter as a studyInformation object containing at least the\n * StudyInstanceUID attribute.\n *\n * Shall return a promise that will be resolved with an object containing those attributes:\n * - StudyInstanceUID {String}: copy of studyInformation.StudyInstanceUID\n * - modalities {String}: 2 uppercase letters for each Modality split by any non-alphabetical char(s)\n * - StudyDate {String}: date formatted as YYYYMMDD\n * - StudyDescription {String}: study description string\n */\n// TODO: What is this for?\nconst getStudyBoxData = false;\n\nexport default getStudyBoxData;\n","function getWADORSImageUrl(instance, frame) {\n let wadorsuri = instance.wadorsuri;\n\n if (!wadorsuri) {\n return;\n }\n\n // Use null to obtain an imageId which represents the instance\n if (frame === null) {\n wadorsuri = wadorsuri.replace(/frames\\/(\\d+)/, '');\n } else {\n // We need to sum 1 because WADO-RS frame number is 1-based\n frame = frame ? parseInt(frame) + 1 : 1;\n\n // Replaces /frame/1 by /frame/{frame}\n wadorsuri = wadorsuri.replace(/frames\\/(\\d+)/, `frames/${frame}`);\n }\n\n return wadorsuri;\n}\n\n/**\n * Obtain an imageId for Cornerstone based on the WADO-RS scheme\n *\n * @param {object} instanceMetada metadata object (InstanceMetadata)\n * @param {(string\\|number)} [frame] the frame number\n * @returns {string} The imageId to be used by Cornerstone\n */\nexport default function getWADORSImageId(instance, frame) {\n const uri = getWADORSImageUrl(instance, frame);\n\n if (!uri) {\n return;\n }\n\n return `wadors:${uri}`;\n}\n","import DICOMWeb from '../DICOMWeb/';\nimport isLowPriorityModality from '../utils/isLowPriorityModality';\n\nconst INFO = Symbol('INFO');\n\n/**\n * Creates an object with processed series information and saves its reference\n * inside the series object itself.\n * @param {Object} series The raw series object\n * @returns {Object} object containing some useful info from given series\n */\nexport default function getSeriesInfo(series) {\n let info = series[INFO];\n if (!info) {\n const Modality = DICOMWeb.getString(series['00080060'], '').toUpperCase();\n info = Object.freeze({\n Modality,\n isLowPriority: isLowPriorityModality(Modality),\n SeriesInstanceUID: DICOMWeb.getString(series['0020000E']),\n SeriesNumber: DICOMWeb.getNumber(series['00200011'], 0) || 0,\n });\n series[INFO] = info;\n }\n return info;\n}\n","import getSeriesInfo from './getSeriesInfo';\n\n/**\n * Series sorting criteria: series considered low priority are moved to the end\n * of the list and series number is used to break ties\n * @param {Object} firstSeries\n * @param {Object} secondSeries\n */\nfunction seriesInfoSortingCriteria(firstSeries, secondSeries) {\n const a = getSeriesInfo(firstSeries);\n const b = getSeriesInfo(secondSeries);\n if (!a.isLowPriority && b.isLowPriority) {\n return -1;\n }\n if (a.isLowPriority && !b.isLowPriority) {\n return 1;\n }\n return a.SeriesNumber - b.SeriesNumber;\n}\n\nconst seriesSortCriteria = {\n default: (a, b) => a.SeriesNumber - b.SeriesNumber,\n seriesInfoSortingCriteria,\n};\n\nconst instancesSortCriteria = {\n default: (a, b) => a.InstanceNumber - b.InstanceNumber,\n};\n\nconst sortingCriteria = {\n seriesSortCriteria,\n instancesSortCriteria,\n};\n\n/**\n * Sorts given series (given param is modified)\n * The default criteria is based on series number in ascending order.\n *\n * @param {Array} series List of series\n * @param {function} seriesSortingCriteria method for sorting\n * @returns {Array} sorted series object\n */\nconst sortStudySeries = (\n series,\n seriesSortingCriteria = seriesSortCriteria.default\n) => {\n return series.sort(seriesSortingCriteria);\n};\n\n/**\n * Sorts given instancesList (given param is modified)\n * The default criteria is based on instance number in ascending order.\n *\n * @param {Array} instancesList List of series\n * @param {function} instancesSortingCriteria method for sorting\n * @returns {Array} sorted instancesList object\n */\nconst sortStudyInstances = (\n instancesList,\n instancesSortingCriteria = instancesSortCriteria.default\n) => {\n return instancesList.sort(instancesSortingCriteria);\n};\n\n/**\n * Sorts the series and instances (by default) inside a study instance based on sortingCriteria (given param is modified)\n * The default criteria is based on series and instance numbers in ascending order.\n *\n * @param {Object} study The study instance\n * @param {boolean} [deepSort = true] to sort instance also\n * @param {function} [seriesSortingCriteria = seriesSortCriteria.default] method for sorting series\n * @param {function} [instancesSortingCriteria = instancesSortCriteria.default] method for sorting instances\n * @returns {Object} sorted study object\n */\nexport default function sortStudy(\n study,\n deepSort = true,\n seriesSortingCriteria = seriesSortCriteria.default,\n instancesSortingCriteria = instancesSortCriteria.default\n) {\n if (!study || !study.series) {\n throw new Error('Insufficient study data was provided to sortStudy');\n }\n\n sortStudySeries(study.series, seriesSortingCriteria);\n\n if (deepSort) {\n study.series.forEach(series => {\n sortStudyInstances(series.instances, instancesSortingCriteria);\n });\n }\n\n return study;\n}\n\nexport { sortStudySeries, sortStudyInstances, sortingCriteria };\n","import { asyncComponent, retryImport } from '@ohif/ui';\nimport OHIF from '@ohif/core';\n\nconst { urlUtil: UrlUtil } = OHIF.utils;\n\n// Dynamic Import Routes (CodeSplitting)\nconst IHEInvokeImageDisplay = asyncComponent(() =>\n retryImport(() =>\n import(/* webpackChunkName: \"IHEInvokeImageDisplay\" */ './IHEInvokeImageDisplay.js')\n )\n);\nconst ViewerRouting = asyncComponent(() =>\n retryImport(() => import(/* webpackChunkName: \"ViewerRouting\" */ './ViewerRouting.js'))\n);\n\nconst StudyListRouting = asyncComponent(() =>\n retryImport(() => import(\n /* webpackChunkName: \"StudyListRouting\" */ '../studylist/StudyListRouting.js'\n ))\n);\nconst StandaloneRouting = asyncComponent(() =>\n retryImport(() => import(\n /* webpackChunkName: \"ConnectedStandaloneRouting\" */ '../connectedComponents/ConnectedStandaloneRouting.js'\n ))\n);\nconst ViewerLocalFileData = asyncComponent(() =>\n retryImport(() => import(\n /* webpackChunkName: \"ViewerLocalFileData\" */ '../connectedComponents/ViewerLocalFileData.js'\n ))\n);\n\nconst reload = () => window.location.reload();\n\nconst ROUTES_DEF = {\n default: {\n viewer: {\n path: '/viewer/:studyInstanceUIDs',\n component: ViewerRouting,\n },\n standaloneViewer: {\n path: '/viewer',\n component: StandaloneRouting,\n },\n list: {\n path: ['/studylist', '/'],\n component: StudyListRouting,\n condition: appConfig => {\n return appConfig.showStudyList;\n },\n },\n local: {\n path: '/local',\n component: ViewerLocalFileData,\n },\n IHEInvokeImageDisplay: {\n path: '/IHEInvokeImageDisplay',\n component: IHEInvokeImageDisplay\n },\n },\n gcloud: {\n viewer: {\n path:\n '/projects/:project/locations/:location/datasets/:dataset/dicomStores/:dicomStore/study/:studyInstanceUIDs',\n component: ViewerRouting,\n condition: appConfig => {\n return !!appConfig.enableGoogleCloudAdapter;\n },\n },\n list: {\n path:\n '/projects/:project/locations/:location/datasets/:dataset/dicomStores/:dicomStore',\n component: StudyListRouting,\n condition: appConfig => {\n const showList = appConfig.showStudyList;\n\n return showList && !!appConfig.enableGoogleCloudAdapter;\n },\n },\n },\n};\n\nconst getRoutes = appConfig => {\n const routes = [];\n for (let keyConfig in ROUTES_DEF) {\n const routesConfig = ROUTES_DEF[keyConfig];\n\n for (let routeKey in routesConfig) {\n const route = routesConfig[routeKey];\n const validRoute =\n typeof route.condition === 'function'\n ? route.condition(appConfig)\n : true;\n\n if (validRoute) {\n routes.push({\n path: route.path,\n Component: route.component,\n });\n }\n }\n }\n\n return routes;\n};\n\nconst parsePath = (path, server, params) => {\n let _path = path;\n const _paramsCopy = Object.assign({}, server, params);\n\n for (let key in _paramsCopy) {\n _path = UrlUtil.paramString.replaceParam(_path, key, _paramsCopy[key]);\n }\n\n return _path;\n};\n\nconst parseViewerPath = (appConfig = {}, server = {}, params) => {\n let viewerPath = ROUTES_DEF.default.viewer.path;\n if (appConfig.enableGoogleCloudAdapter) {\n viewerPath = ROUTES_DEF.gcloud.viewer.path;\n }\n\n return parsePath(viewerPath, server, params);\n};\n\nconst parseStudyListPath = (appConfig = {}, server = {}, params) => {\n let studyListPath = ROUTES_DEF.default.list.path;\n if (appConfig.enableGoogleCloudAdapter) {\n studyListPath = ROUTES_DEF.gcloud.list.path || studyListPath;\n }\n\n return parsePath(studyListPath, server, params);\n};\n\nexport { getRoutes, parseViewerPath, parseStudyListPath, reload };\n","import DICOMWeb from '../../../DICOMWeb';\n\n/**\n * Function to get series sequence (sequence of pepeating items where each\n * item includes the attributes of one or more series) based on a given sopInstance.\n *\n * @param {Object} instance The sop instance\n * @returns {Promise} Referenced series sequence\n */\nconst getReferencedSeriesSequence = instance => {\n const referencedSeriesSequenceRaw = instance['00081115'];\n\n const referencedSeriesSequence = [];\n\n if (referencedSeriesSequenceRaw && referencedSeriesSequenceRaw.Value) {\n referencedSeriesSequenceRaw.Value.forEach(referencedSeries => {\n const referencedSeriesInstanceUID = DICOMWeb.getString(\n referencedSeries['0020000E']\n );\n\n const referencedInstanceSequenceRaw = referencedSeries['0008114A'];\n const referencedInstanceSequence = [];\n\n referencedInstanceSequenceRaw.Value.forEach(referencedInstance => {\n referencedInstanceSequence.push({\n referencedSOPClassUID: DICOMWeb.getString(\n referencedInstance['00081150']\n ),\n referencedSOPInstanceUID: DICOMWeb.getString(\n referencedInstance['00081155']\n ),\n });\n });\n\n referencedSeriesSequence.push({\n referencedSeriesInstanceUID,\n referencedInstanceSequence,\n });\n });\n }\n\n return referencedSeriesSequence;\n};\n\nexport default getReferencedSeriesSequence;\n","import DICOMWeb from '../../../DICOMWeb';\nimport metadataProvider from '../../../classes/MetadataProvider';\nimport getWADORSImageId from '../../../utils/getWADORSImageId';\nimport cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';\nimport getReferencedSeriesSequence from './getReferencedSeriesSequence';\n\n/**\n * Create a plain JS object that describes a study (a study descriptor object)\n * @param {Object} server Object with server configuration parameters\n * @param {Object} aSopInstance a SOP Instance from which study information will be added\n */\nfunction createStudy(server, aSopInstance) {\n // TODO: Pass a reference ID to the server instead of including the URLs here\n return {\n series: [],\n seriesMap: Object.create(null),\n seriesLoader: null,\n wadoUriRoot: server.wadoUriRoot,\n wadoRoot: server.wadoRoot,\n qidoRoot: server.qidoRoot,\n PatientName: DICOMWeb.getName(aSopInstance['00100010']),\n PatientID: DICOMWeb.getString(aSopInstance['00100020']),\n PatientAge: DICOMWeb.getNumber(aSopInstance['00101010']),\n PatientSize: DICOMWeb.getNumber(aSopInstance['00101020']),\n PatientWeight: DICOMWeb.getNumber(aSopInstance['00101030']),\n AccessionNumber: DICOMWeb.getString(aSopInstance['00080050']),\n StudyTime: DICOMWeb.getString(aSopInstance['00080030']),\n StudyDate: DICOMWeb.getString(aSopInstance['00080020']),\n FrameOfReferenceUID: DICOMWeb.getString(aSopInstance['00200052']),\n ReferencedSeriesSequence: getReferencedSeriesSequence(aSopInstance),\n modalities: DICOMWeb.getString(aSopInstance['00080061']), // TODO -> Rename this.. it'll take a while to not mess this one up.\n StudyDescription: DICOMWeb.getString(aSopInstance['00081030']),\n NumberOfStudyRelatedInstances: DICOMWeb.getString(aSopInstance['00201208']),\n StudyInstanceUID: DICOMWeb.getString(aSopInstance['0020000D']),\n InstitutionName: DICOMWeb.getString(aSopInstance['00080080']),\n };\n}\n\n/** Returns a WADO url for an instance\n *\n * @param StudyInstanceUID\n * @param SeriesInstanceUID\n * @param SOPInstanceUID\n * @returns {string}\n */\nfunction buildInstanceWadoUrl(\n server,\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID\n) {\n // TODO: This can be removed, since DICOMWebClient has the same function. Not urgent, though\n const params = [];\n\n params.push('requestType=WADO');\n params.push(`studyUID=${StudyInstanceUID}`);\n params.push(`seriesUID=${SeriesInstanceUID}`);\n params.push(`objectUID=${SOPInstanceUID}`);\n params.push('contentType=application/dicom');\n params.push('transferSyntax=*');\n\n const paramString = params.join('&');\n\n return `${server.wadoUriRoot}?${paramString}`;\n}\n\nfunction buildInstanceWadoRsUri(\n server,\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID\n) {\n return `${server.wadoRoot}/studies/${StudyInstanceUID}/series/${SeriesInstanceUID}/instances/${SOPInstanceUID}`;\n}\n\nfunction buildInstanceFrameWadoRsUri(\n server,\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID,\n frame\n) {\n const baseWadoRsUri = buildInstanceWadoRsUri(\n server,\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID\n );\n frame = frame != null || 1;\n\n return `${baseWadoRsUri}/frames/${frame}`;\n}\n\nasync function makeSOPInstance(server, study, instance) {\n const naturalizedInstance = await metadataProvider.addInstance(instance, {\n server,\n });\n\n const {\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID,\n } = naturalizedInstance;\n\n let series = study.seriesMap[SeriesInstanceUID];\n\n if (!series) {\n series = {\n SeriesInstanceUID,\n SeriesDescription: naturalizedInstance.SeriesDescription,\n Modality: naturalizedInstance.Modality,\n SeriesNumber: naturalizedInstance.SeriesNumber,\n SeriesDate: naturalizedInstance.SeriesDate,\n SeriesTime: naturalizedInstance.SeriesTime,\n instances: [],\n };\n study.seriesMap[SeriesInstanceUID] = series;\n study.series.push(series);\n } else {\n if (series.SeriesDate === undefined)\n series.SeriesDate = naturalizedInstance.SeriesDate;\n if (series.SeriesTime === undefined)\n series.SeriesTime = naturalizedInstance.SeriesTime;\n }\n\n const wadouri = buildInstanceWadoUrl(\n server,\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID\n );\n const baseWadoRsUri = buildInstanceWadoRsUri(\n server,\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID\n );\n const wadorsuri = buildInstanceFrameWadoRsUri(\n server,\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID\n );\n\n const sopInstance = {\n metadata: naturalizedInstance,\n baseWadoRsUri,\n wadouri,\n wadorsuri,\n wadoRoot: server.wadoRoot,\n imageRendering: server.imageRendering,\n thumbnailRendering: server.thumbnailRendering,\n };\n\n series.instances.push(sopInstance);\n\n if (\n sopInstance.thumbnailRendering === 'wadors' ||\n sopInstance.imageRendering === 'wadors'\n ) {\n // If using WADO-RS for either images or thumbnails,\n // Need to add this to cornerstoneWADOImageLoader's provider\n // (it won't be hit on cornerstone.metaData.get, but cornerstoneWADOImageLoader\n // will cry if you don't add data to cornerstoneWADOImageLoader.wadors.metaDataManager).\n\n const wadoRSMetadata = Object.assign(instance);\n\n const { NumberOfFrames } = sopInstance.metadata;\n\n if (NumberOfFrames) {\n for (let i = 0; i < NumberOfFrames; i++) {\n const wadorsImageId = getWADORSImageId(sopInstance, i);\n\n cornerstoneWADOImageLoader.wadors.metaDataManager.add(\n wadorsImageId,\n wadoRSMetadata\n );\n }\n } else {\n const wadorsImageId = getWADORSImageId(sopInstance);\n\n cornerstoneWADOImageLoader.wadors.metaDataManager.add(\n wadorsImageId,\n wadoRSMetadata\n );\n }\n }\n\n return sopInstance;\n}\n\n/**\n * Add a list of SOP Instances to a given study object descriptor\n * @param {Object} server Object with server configuration parameters\n * @param {Object} study The study descriptor to which the given SOP instances will be added\n * @param {Array} sopInstanceList A list of SOP instance objects\n */\nasync function addInstancesToStudy(server, study, sopInstanceList) {\n return Promise.all(\n sopInstanceList.map(function(sopInstance) {\n return makeSOPInstance(server, study, sopInstance);\n })\n );\n}\n\nconst createStudyFromSOPInstanceList = async (server, sopInstanceList) => {\n if (Array.isArray(sopInstanceList) && sopInstanceList.length > 0) {\n const firstSopInstance = sopInstanceList[0];\n const study = createStudy(server, firstSopInstance);\n await addInstancesToStudy(server, study, sopInstanceList);\n return study;\n }\n throw new Error('Failed to create study out of provided SOP instance list');\n};\n\nexport { createStudyFromSOPInstanceList, addInstancesToStudy };\n","/**\n * Class to define inheritance of load retrieve strategy.\n * The process can be async load (lazy) or sync load\n *\n * There are methods that must be implemented at consumer level\n * To retrieve study call execLoad\n */\nexport default class RetrieveMetadataLoader {\n /**\n * @constructor\n * @param {Object} server Object with server configuration parameters\n * @param {Array} studyInstanceUID Study instance ui to be retrieved\n * @param {Object} [filters] - Object containing filters to be applied on retrieve metadata process\n * @param {string} [filter.seriesInstanceUID] - series instance uid to filter results against\n */\n constructor(server, studyInstanceUID, filters = {}) {\n this.server = server;\n this.studyInstanceUID = studyInstanceUID;\n this.filters = filters;\n }\n\n async execLoad() {\n await this.configLoad();\n const preLoadData = await this.preLoad();\n const loadData = await this.load(preLoadData);\n const postLoadData = await this.posLoad(loadData);\n\n return postLoadData;\n }\n\n /**\n * It iterates over given loaders running each one. Loaders parameters must be bind when getting it.\n * @param {Array} loaders - array of loader to retrieve data.\n */\n async runLoaders(loaders) {\n let result;\n for (const loader of loaders) {\n try {\n result = await loader();\n if (result && result.length) {\n break; // closes iterator in case data is retrieved successfully\n }\n } catch (e) {\n throw e;\n }\n }\n\n if (loaders.next().done && !result) {\n throw new Error('RetrieveMetadataLoader failed');\n }\n\n return result;\n }\n\n // Methods to be overwrite\n async configLoad() {}\n async preLoad() {}\n async load(preLoadData) {}\n async posLoad(loadData) {}\n}\n","import { api } from 'dicomweb-client';\nimport DICOMWeb from '../../../DICOMWeb/';\nimport { createStudyFromSOPInstanceList } from './studyInstanceHelpers';\nimport RetrieveMetadataLoader from './retrieveMetadataLoader';\n\nimport errorHandler from '../../../errorHandler';\nimport getXHRRetryRequestHook from '../../../utils/xhrRetryRequestHook';\n\n/**\n * Class for sync load of study metadata.\n * It inherits from RetrieveMetadataLoader\n *\n * A list of loaders (getLoaders) can be created so, it will be applied a fallback load strategy.\n * I.e Retrieve metadata using all loaders possibilities.\n */\nexport default class RetrieveMetadataLoaderSync extends RetrieveMetadataLoader {\n getOptions() {\n const { studyInstanceUID, filters } = this;\n\n const options = {\n studyInstanceUID,\n };\n\n const { seriesInstanceUID } = filters;\n if (seriesInstanceUID) {\n options['seriesInstanceUID'] = seriesInstanceUID;\n }\n\n return options;\n }\n\n /**\n * @returns {Array} Array of loaders. To be consumed as queue\n */\n *getLoaders() {\n const loaders = [];\n const {\n studyInstanceUID,\n filters: { seriesInstanceUID } = {},\n client,\n } = this;\n\n if (seriesInstanceUID) {\n loaders.push(\n client.retrieveSeriesMetadata.bind(client, {\n studyInstanceUID,\n seriesInstanceUID,\n })\n );\n }\n\n loaders.push(\n client.retrieveStudyMetadata.bind(client, { studyInstanceUID })\n );\n\n yield* loaders;\n }\n\n configLoad() {\n const { server } = this;\n const client = new api.DICOMwebClient({\n url: server.wadoRoot,\n headers: DICOMWeb.getAuthorizationHeader(server),\n errorInterceptor: errorHandler.getHTTPErrorHandler(),\n requestHooks: [getXHRRetryRequestHook()],\n });\n\n this.client = client;\n }\n\n async load(preLoadData) {\n const loaders = this.getLoaders();\n const result = this.runLoaders(loaders);\n return result;\n }\n\n async posLoad(loadData) {\n const { server } = this;\n return createStudyFromSOPInstanceList(server, loadData);\n }\n}\n","import StaticWadoClient from '../qido/StaticWadoClient';\nimport dcmjs from 'dcmjs';\nimport DICOMWeb from '../../../DICOMWeb/';\nimport RetrieveMetadataLoader from './retrieveMetadataLoader';\nimport { sortStudySeries, sortingCriteria } from '../../sortStudy';\nimport getSeriesInfo from '../../getSeriesInfo';\nimport {\n createStudyFromSOPInstanceList,\n addInstancesToStudy,\n} from './studyInstanceHelpers';\n\nimport errorHandler from '../../../errorHandler';\nimport { getXHRRetryRequestHook } from '../../../utils/xhrRetryRequestHook';\n\nconst { naturalizeDataset } = dcmjs.data.DicomMetaDictionary;\n\n/**\n * Map series to an array of SeriesInstanceUID\n * @param {Arrays} series list of Series Instance UIDs\n * @returns {Arrays} A list of Series Instance UIDs\n */\nfunction mapStudySeries(series) {\n return series.map(series => getSeriesInfo(series).SeriesInstanceUID);\n}\n\nfunction attachSeriesLoader(server, study, seriesLoader) {\n study.seriesLoader = Object.freeze({\n hasNext() {\n return seriesLoader.hasNext();\n },\n async next() {\n const series = await seriesLoader.next();\n await addInstancesToStudy(server, study, series.sopInstances);\n return study.seriesMap[series.seriesInstanceUID];\n },\n });\n}\n\n/**\n * Creates an immutable series loader object which loads each series sequentially using the iterator interface\n * @param {DICOMWebClient} dicomWebClient The DICOMWebClient instance to be used for series load\n * @param {string} studyInstanceUID The Study Instance UID from which series will be loaded\n * @param {Array} seriesInstanceUIDList A list of Series Instance UIDs\n * @returns {Object} Returns an object which supports loading of instances from each of given Series Instance UID\n */\nfunction makeSeriesAsyncLoader(\n dicomWebClient,\n studyInstanceUID,\n seriesInstanceUIDList\n) {\n return Object.freeze({\n hasNext() {\n return seriesInstanceUIDList.length > 0;\n },\n async next() {\n const seriesInstanceUID = seriesInstanceUIDList.shift();\n const sopInstances = await dicomWebClient.retrieveSeriesMetadata({\n studyInstanceUID,\n seriesInstanceUID,\n });\n return { studyInstanceUID, seriesInstanceUID, sopInstances };\n },\n });\n}\n\n/**\n * Class for async load of study metadata.\n * It inherits from RetrieveMetadataLoader\n *\n * It loads the one series and then append to seriesLoader the others to be consumed/loaded\n */\nexport default class RetrieveMetadataLoaderAsync extends RetrieveMetadataLoader {\n configLoad() {\n const { server } = this;\n\n const client = new StaticWadoClient({\n ...server,\n url: server.qidoRoot,\n headers: DICOMWeb.getAuthorizationHeader(server),\n errorInterceptor: errorHandler.getHTTPErrorHandler(),\n requestHooks: [getXHRRetryRequestHook()],\n });\n\n this.client = client;\n }\n\n /**\n * @returns {Array} Array of preLoaders. To be consumed as queue\n */\n *getPreLoaders() {\n const preLoaders = [];\n const {\n studyInstanceUID,\n filters: { seriesInstanceUID } = {},\n client,\n } = this;\n\n if (seriesInstanceUID) {\n const options = {\n studyInstanceUID,\n queryParams: { SeriesInstanceUID: seriesInstanceUID },\n };\n preLoaders.push(client.searchForSeries.bind(client, options));\n }\n // Fallback preloader\n preLoaders.push(client.searchForSeries.bind(client, { studyInstanceUID }));\n\n yield* preLoaders;\n }\n\n async preLoad() {\n const preLoaders = this.getPreLoaders();\n\n // seriesData is the result of the QIDO-RS Search For Series request\n // It's an array of Objects containing DICOM Tag values at the Series level\n const seriesData = await this.runLoaders(preLoaders);\n\n const seriesSorted = sortStudySeries(\n seriesData,\n sortingCriteria.seriesSortCriteria.seriesInfoSortingCriteria\n );\n const seriesInstanceUIDsMap = mapStudySeries(seriesSorted);\n\n return {\n seriesInstanceUIDsMap,\n seriesData,\n };\n }\n\n async load(preLoadData) {\n const { client, studyInstanceUID } = this;\n\n const seriesAsyncLoader = makeSeriesAsyncLoader(\n client,\n studyInstanceUID,\n preLoadData.seriesInstanceUIDsMap\n );\n\n const firstSeries = await seriesAsyncLoader.next();\n\n return {\n sopInstances: firstSeries.sopInstances,\n asyncLoader: seriesAsyncLoader,\n seriesData: preLoadData.seriesData,\n };\n }\n\n async posLoad(loadData) {\n const { server } = this;\n\n const { sopInstances, asyncLoader, seriesData } = loadData;\n\n const study = await createStudyFromSOPInstanceList(server, sopInstances);\n\n // TODO: Should this be in a helper\n const seriesDataNaturalized = seriesData.map(naturalizeDataset);\n\n seriesDataNaturalized.forEach((series, idx) => {\n const seriesDataFromQIDO = {\n SeriesInstanceUID: series.SeriesInstanceUID,\n SeriesDescription: series.SeriesDescription,\n SeriesNumber: series.SeriesNumber,\n Modality: series.Modality,\n instances: [],\n };\n\n if (study.series[idx]) {\n study.series[idx] = Object.assign(\n seriesDataFromQIDO,\n study.series[idx]\n );\n } else {\n study.series[idx] = seriesDataFromQIDO;\n }\n\n study.seriesMap[series.SeriesInstanceUID] = study.series[idx];\n });\n\n if (asyncLoader.hasNext()) {\n attachSeriesLoader(server, study, asyncLoader);\n }\n\n return study;\n }\n}\n","import RetrieveMetadataLoaderSync from './retrieveMetadataLoaderSync';\nimport RetrieveMetadataLoaderAsync from './retrieveMetadataLoaderAsync';\n\n/**\n * Retrieve Study metadata from a DICOM server. If the server is configured to use lazy load, only the first series\n * will be loaded and the property \"studyLoader\" will be set to let consumer load remaining series as needed.\n *\n * @param {Object} server Object with server configuration parameters\n * @param {string} StudyInstanceUID The Study Instance UID of the study which needs to be loaded\n * @param {Object} [filters] - Object containing filters to be applied on retrieve metadata process\n * @param {string} [filter.seriesInstanceUID] - series instance uid to filter results against\n * @returns {Object} A study descriptor object\n */\nasync function RetrieveMetadata(server, StudyInstanceUID, filters = {}) {\n const RetrieveMetadataLoader =\n server.enableStudyLazyLoad != false\n ? RetrieveMetadataLoaderAsync\n : RetrieveMetadataLoaderSync;\n\n const retrieveMetadataLoader = new RetrieveMetadataLoader(\n server,\n StudyInstanceUID,\n filters\n );\n const studyMetadata = retrieveMetadataLoader.execLoad();\n\n return studyMetadata;\n}\n\nexport default RetrieveMetadata;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nexport function ViewportErrorIndicator(props) {\n return (\n \n

    Error

    \n

    An error has occurred.

    \n

    {props.details}

    \n \n );\n}\n\nViewportErrorIndicator.propTypes = {\n details: PropTypes.string,\n};\n\nexport default ViewportErrorIndicator;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nexport function ViewportLoadingIndicator(props) {\n return (\n \n Loading {props.percentComplete}\n \n );\n}\n\nViewportLoadingIndicator.propTypes = {\n percentComplete: PropTypes.number,\n};\n\nexport default ViewportLoadingIndicator;\n","/* global cornerstone */\nimport './ImageThumbnail.styl';\n\nimport { utils } from '@ohif/core';\nimport React, { useState, useEffect, createRef, useCallback } from 'react';\nimport classNames from 'classnames';\n\nimport PropTypes from 'prop-types';\nimport ViewportErrorIndicator from '../../viewer/ViewportErrorIndicator';\nimport ViewportLoadingIndicator from '../../viewer/ViewportLoadingIndicator';\n\n// TODO: How should we have this component depend on Cornerstone?\n// - Passed in as a prop?\n// - Set as external dependency?\n// - Pass in the entire load and render function as a prop?\n//import cornerstone from 'cornerstone-core';\nfunction ImageThumbnail(props) {\n const {\n active,\n width,\n height,\n imageSrc,\n imageId,\n stackPercentComplete,\n error: propsError,\n showProgressBar,\n } = props;\n\n const [isLoading, setLoading] = useState(false);\n const [error, setError] = useState(false);\n const [image, setImage] = useState({});\n const canvasRef = createRef();\n\n let loadingOrError;\n let cancelablePromise;\n\n if (propsError || error) {\n loadingOrError = ;\n } else if (isLoading) {\n loadingOrError = ;\n }\n\n const showStackLoadingProgressBar =\n showProgressBar && stackPercentComplete !== undefined;\n\n const shouldRenderToCanvas = () => {\n return imageId && !imageSrc;\n };\n\n const fetchImagePromise = () => {\n if (!cancelablePromise) {\n return;\n }\n\n setLoading(true);\n cancelablePromise\n .then(response => {\n setImage(response);\n })\n .catch(error => {\n if (error.isCanceled) return;\n // setLoading(false);\n // setError(true);\n // throw new Error(error);\n });\n };\n\n const setImagePromise = () => {\n if (shouldRenderToCanvas()) {\n cancelablePromise = utils.makeCancelable(\n cornerstone.loadAndCacheImage(imageId)\n );\n }\n };\n\n const purgeCancelablePromise = useCallback(() => {\n if (cancelablePromise) {\n cancelablePromise.cancel();\n }\n });\n\n useEffect(() => {\n return () => {\n purgeCancelablePromise();\n };\n }, [purgeCancelablePromise]);\n\n useEffect(() => {\n if (image.imageId) {\n cornerstone.renderToCanvas(canvasRef.current, image);\n setLoading(false);\n }\n }, [canvasRef, image, image.imageId]);\n\n useEffect(() => {\n if (!image.imageId || image.imageId !== imageId) {\n purgeCancelablePromise();\n setImagePromise();\n fetchImagePromise();\n }\n }, [\n fetchImagePromise,\n image.imageId,\n imageId,\n purgeCancelablePromise,\n setImagePromise,\n ]);\n\n return (\n
    \n
    \n {shouldRenderToCanvas() ? (\n \n ) : (\n \n )}\n
    \n {loadingOrError}\n {showStackLoadingProgressBar && (\n
    \n \n
    \n )}\n {isLoading &&
    }\n
    \n );\n}\n\nImageThumbnail.propTypes = {\n active: PropTypes.bool,\n imageSrc: PropTypes.string,\n imageId: PropTypes.string,\n error: PropTypes.bool,\n width: PropTypes.number,\n height: PropTypes.number,\n stackPercentComplete: PropTypes.number.isRequired,\n showProgressBar: PropTypes.bool,\n};\n\nImageThumbnail.defaultProps = {\n active: false,\n error: false,\n stackPercentComplete: 0,\n width: 217,\n height: 123,\n showProgressBar: true,\n};\n\nexport default ImageThumbnail;\n","import React, { useState, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport throttle from 'lodash.throttle';\nimport { useDrag } from 'react-dnd';\nimport { classes } from '@ohif/core';\nimport ImageThumbnail from './ImageThumbnail';\nimport classNames from 'classnames';\nimport { Icon } from './../../elements/Icon';\nimport { Tooltip } from './../tooltip';\nimport { OverlayTrigger } from './../overlayTrigger';\nimport './Thumbnail.styl';\n\nconst StudyLoadingListener = classes.StudyLoadingListener;\n\nfunction ThumbnailFooter({\n SeriesDescription,\n SeriesNumber,\n numImageFrames,\n hasWarnings,\n hasDerivedDisplaySets,\n}) {\n const [inconsistencyWarnings, inconsistencyWarningsSet] = useState([]);\n const [derivedDisplaySetsActive, derivedDisplaySetsActiveSet] = useState([]);\n\n useEffect(() => {\n let unmounted = false;\n hasWarnings.then(response => {\n if (!unmounted) {\n inconsistencyWarningsSet(response);\n }\n });\n hasDerivedDisplaySets.then(response => {\n if (!unmounted) {\n derivedDisplaySetsActiveSet(response);\n }\n });\n return () => {\n unmounted = true;\n };\n }, [hasWarnings, hasDerivedDisplaySets]);\n\n const infoOnly = !SeriesDescription;\n\n const getInfo = (value, icon, className = '') => {\n return (\n
    \n
    {icon}
    \n
    {value}
    \n
    \n );\n };\n\n const getWarningContent = inconsistencyWarnings => {\n if (Array.isArray(inconsistencyWarnings)) {\n const listedWarnings = inconsistencyWarnings.map((warn, index) => {\n return
  • {warn}
  • ;\n });\n\n return
      {listedWarnings}
    ;\n } else {\n return {inconsistencyWarnings};\n }\n };\n\n const getWarningInfo = (SeriesNumber, inconsistencyWarnings) => {\n return (\n \n {inconsistencyWarnings && inconsistencyWarnings.length != 0 ? (\n \n
    Series Inconsistencies
    \n
    \n {getWarningContent(inconsistencyWarnings)}\n
    \n \n }\n >\n
    \n \n \n \n
    \n \n ) : (\n \n )}\n
    \n );\n };\n\n const getDerivedInfo = derivedDisplaySetsActive => {\n return (\n \n {derivedDisplaySetsActive ? (\n
    \n \n
    \n ) : (\n \n )}\n
    \n );\n };\n\n const getSeriesInformation = (\n SeriesNumber,\n numImageFrames,\n inconsistencyWarnings,\n derivedDisplaySetsActive\n ) => {\n if (!SeriesNumber && !numImageFrames) {\n return;\n }\n const seriesInformation = (\n
    \n \n {SeriesNumber !== undefined ? (\n getInfo(SeriesNumber, 'S:')\n ) : (\n \n )}\n \n \n {numImageFrames !== undefined ? (\n getInfo(numImageFrames, '', 'image-frames')\n ) : (\n \n )}\n \n {getDerivedInfo(derivedDisplaySetsActive)}\n {getWarningInfo(SeriesNumber, inconsistencyWarnings)}\n
    \n );\n\n return seriesInformation;\n };\n\n return (\n
    \n
    {SeriesDescription}
    \n {getSeriesInformation(\n SeriesNumber,\n numImageFrames,\n inconsistencyWarnings,\n derivedDisplaySetsActive\n )}\n
    \n );\n}\n\nfunction Thumbnail(props) {\n const {\n active,\n altImageText,\n error,\n displaySetInstanceUID,\n imageId,\n imageSrc,\n StudyInstanceUID,\n onClick,\n onDoubleClick,\n onMouseDown,\n supportsDrag,\n showProgressBar,\n } = props;\n\n const [stackPercentComplete, setStackPercentComplete] = useState(0);\n useEffect(() => {\n const onProgressChange = throttle(({ detail }) => {\n const { progressId, progressData } = detail;\n if (`StackProgress:${displaySetInstanceUID}` === progressId) {\n const percent = progressData ? progressData.percentComplete : 0;\n if (percent > stackPercentComplete) {\n setStackPercentComplete(percent);\n }\n }\n }, 100);\n\n document.addEventListener(\n StudyLoadingListener.events.OnProgress,\n onProgressChange\n );\n\n return () => {\n document.removeEventListener(\n StudyLoadingListener.events.OnProgress,\n onProgressChange\n );\n };\n }, [displaySetInstanceUID]);\n\n const [collectedProps, drag, dragPreview] = useDrag({\n // `droppedItem` in `dropTarget`\n // The only data it will have access to\n item: {\n StudyInstanceUID,\n displaySetInstanceUID,\n type: 'thumbnail', // Has to match `dropTarget`'s type\n },\n canDrag: function(monitor) {\n return supportsDrag;\n },\n });\n\n const hasImage = imageSrc || imageId;\n const hasAltText = altImageText !== undefined;\n\n return (\n \n {/* SHOW IMAGE */}\n {hasImage && (\n \n )}\n {/* SHOW TEXT ALTERNATIVE */}\n {!hasImage && hasAltText && (\n
    \n

    {altImageText}

    \n
    \n )}\n {ThumbnailFooter(props)}\n \n );\n}\n\nconst noop = () => {};\n\nThumbnail.propTypes = {\n supportsDrag: PropTypes.bool,\n id: PropTypes.string.isRequired,\n displaySetInstanceUID: PropTypes.string.isRequired,\n StudyInstanceUID: PropTypes.string.isRequired,\n imageSrc: PropTypes.string,\n imageId: PropTypes.string,\n error: PropTypes.bool,\n active: PropTypes.bool,\n stackPercentComplete: PropTypes.number,\n /**\n altImageText will be used when no imageId or imageSrc is provided.\n It will be displayed inside the
    . This is useful when it is difficult\n to make a preview for a type of DICOM series (e.g. DICOM-SR)\n */\n altImageText: PropTypes.string,\n SeriesDescription: PropTypes.string,\n SeriesNumber: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n hasWarnings: PropTypes.instanceOf(Promise),\n hasDerivedDisplaySets: PropTypes.instanceOf(Promise),\n numImageFrames: PropTypes.number,\n onDoubleClick: PropTypes.func,\n onClick: PropTypes.func,\n onMouseDown: PropTypes.func,\n showProgressBar: PropTypes.bool,\n};\n\nThumbnail.defaultProps = {\n supportsDrag: false,\n active: false,\n error: false,\n stackPercentComplete: 0,\n onDoubleClick: noop,\n onClick: noop,\n onMouseDown: noop,\n};\n\nexport { Thumbnail };\n","import { api } from 'dicomweb-client';\n\n/**\n * An implementation of the static wado client, that fetches data from\n * a static response rather than actually doing real queries. This allows\n * fast encoding of test data, but because it is static, anything actually\n * performing searches doesn't work. This version fixes the query issue\n * by manually implementing a query option.\n */\nexport default class StaticWadoClient extends api.DICOMwebClient {\n static filterKeys = {\n \"StudyInstanceUID\": \"0020000D\",\n \"PatientName\": \"00100010\",\n \"00100020\": \"mrn\",\n \"PatientID\": \"00100020\",\n \"StudyDescription\": \"00081030\",\n \"StudyDate\": \"00080020\",\n \"ModalitiesInStudy\": \"00080061\",\n AccessionNumber: \"00080050\",\n };\n\n constructor(qidoConfig) {\n super(qidoConfig);\n this.staticWado = qidoConfig.staticWado;\n }\n\n /**\n * Replace the search for studies remote query with a local version which\n * retrieves a complete query list and then sub-selects from it locally.\n * @param {*} options\n * @returns\n */\n async searchForStudies(options) {\n if (!this.staticWado) return super.searchForStudies(options);\n\n let searchResult = await super.searchForStudies(options);\n const { queryParams } = options;\n if (!queryParams) return searchResult;\n const filtered = searchResult.filter(study => {\n for (const key of Object.keys(StaticWadoClient.filterKeys)) {\n if (!this.filterItem(key, queryParams, study)) return false;\n }\n return true;\n });\n return filtered;\n }\n\n /**\n * Compares values, matching any instance of desired to any instance of\n * actual by recursively go through the paired set of values. That is,\n * this is O(m*n) where m is how many items in desired and n is the length of actual\n * Then, at the individual item node, compares the Alphabetic name if present,\n * and does a sub-string matching on string values, and otherwise does an\n * exact match comparison.\n *\n * @param {*} desired\n * @param {*} actual\n * @returns true if the values match\n */\n compareValues(desired, actual) {\n if (Array.isArray(desired)) {\n return desired.find(item => this.compareValues(item, actual));\n }\n if (Array.isArray(actual)) {\n return actual.find(actualItem => this.compareValues(desired, actualItem));\n }\n if (actual && actual.Alphabetic) {\n actual = actual.Alphabetic;\n }\n if (typeof (actual) == 'string') {\n if (actual.length === 0) return true;\n if (desired.length === 0 || desired === '*') return true;\n if (desired[0] === '*' && desired[desired.length - 1] === '*') {\n console.log(`Comparing ${actual} to ${desired.substring(1, desired.length - 1)}`)\n return actual.indexOf(desired.substring(1, desired.length - 1)) != -1;\n } else if (desired[desired.length - 1] === '*') {\n return actual.indexOf(desired.substring(0, desired.length - 1)) != -1;\n } else if (desired[0] === '*') {\n return actual.indexOf(desired.substring(1)) === actual.length - desired.length + 1;\n }\n }\n return desired === actual;\n }\n\n /** Compares a pair of dates to see if the value is within the range */\n compareDateRange(range, value) {\n if (!value) return true;\n const dash = range.indexOf('-');\n if (dash === -1) return this.compareValues(range, value);\n const start = range.substring(0, dash);\n const end = range.substring(dash + 1);\n return (!start || value >= start) &&\n (!end || value <= end);\n }\n\n /**\n * Filters the return list by the query parameters.\n *\n * @param {*} key\n * @param {*} queryParams\n * @param {*} study\n * @returns\n */\n filterItem(key, queryParams, study) {\n const altKey = StaticWadoClient.filterKeys[key] || key;\n if (!queryParams) return true;\n const testValue = queryParams[key] || queryParams[altKey];\n if (!testValue) return true;\n const valueElem = study[key] || study[altKey];\n if (!valueElem) return false;\n if (valueElem.vr == 'DA') return this.compareDateRange(testValue, valueElem.Value[0]);\n const value = valueElem.Value;\n return this.compareValues(testValue, value) && true;\n }\n}\n","import { createSelector } from 'reselect';\n\nconst getActiveViewportIndex = state => state.viewports.activeViewportIndex;\nconst getLayoutViewports = state => state.viewports.layout.viewports;\nconst getViewportSpecificData = state => state.viewports.viewportSpecificData;\n\n/**\n * Think of this as a computed getter for our store. It lets us watch parts of\n * our redux state, and only update/recalculate when those values change.\n */\nexport const getActiveContexts = createSelector(\n [getActiveViewportIndex, getLayoutViewports, getViewportSpecificData],\n (activeViewportIndex, layoutViewports, viewportSpecificData) => {\n const activeContexts = ['VIEWER'];\n const activeLayoutViewport = layoutViewports[activeViewportIndex] || {};\n const activeViewportSpecificData =\n viewportSpecificData[activeViewportIndex] || {};\n const activeViewportPluginName =\n activeLayoutViewport.plugin || activeViewportSpecificData.plugin;\n\n if (activeViewportPluginName) {\n const activeViewportExtension = `ACTIVE_VIEWPORT::${activeViewportPluginName.toUpperCase()}`;\n activeContexts.push(activeViewportExtension);\n }\n\n return activeContexts;\n }\n);\n","import OHIFLogo from '../components/OHIFLogo/OHIFLogo.js';\nimport React from 'react';\n\nconst defaultContextValues = {\n createLogoComponentFn: React => OHIFLogo(),\n};\n\nconst WhiteLabelingContext = React.createContext(defaultContextValues);\n\nexport default WhiteLabelingContext;\n","import log from '../log.js';\n\n/**\n * The definition of a command\n *\n * @typedef {Object} CommandDefinition\n * @property {Function} commandFn - Command to call\n * @property {Array} storeContexts - Array of string of modules required from store\n * @property {Object} options - Object of params to pass action\n */\n\n/**\n * The Commands Manager tracks named commands (or functions) that are scoped to\n * a context. When we attempt to run a command with a given name, we look for it\n * in our active contexts. If found, we run the command, passing in any application\n * or call specific data specified in the command's definition.\n *\n * NOTE: A more robust version of the CommandsManager lives in v1. If you're looking\n * to extend this class, please check it's source before adding new methods.\n */\nexport class CommandsManager {\n constructor({ getAppState, getActiveContexts } = {}) {\n this.contexts = {};\n\n if (!getAppState || !getActiveContexts) {\n log.warn(\n 'CommandsManager was instantiated without getAppState() or getActiveContexts()'\n );\n }\n\n this._getAppState = getAppState;\n this._getActiveContexts = getActiveContexts;\n }\n\n /**\n * Allows us to create commands \"per context\". An example would be the \"Cornerstone\"\n * context having a `SaveImage` command, and the \"VTK\" context having a `SaveImage`\n * command. The distinction of a context allows us to call the command in either\n * context, and have faith that the correct command will be run.\n *\n * @method\n * @param {string} contextName - Namespace for commands\n * @returns {undefined}\n */\n createContext(contextName) {\n if (!contextName) {\n return;\n }\n\n if (this.contexts[contextName]) {\n return this.clearContext(contextName);\n }\n\n this.contexts[contextName] = {};\n }\n\n /**\n * Returns all command definitions for a given context\n *\n * @method\n * @param {string} contextName - Namespace for commands\n * @returns {Object} - the matched context\n */\n getContext(contextName) {\n const context = this.contexts[contextName];\n\n if (!context) {\n return;\n }\n\n return context;\n }\n\n /**\n * Clears all registered commands for a given context.\n *\n * @param {string} contextName - Namespace for commands\n * @returns {undefined}\n */\n clearContext(contextName) {\n if (!contextName) {\n return;\n }\n\n this.contexts[contextName] = {};\n }\n\n /**\n * Register a new command with the command manager. Scoped to a context, and\n * with a definition to assist command callers w/ providing the necessary params\n *\n * @method\n * @param {string} contextName - Namespace for command; often scoped to the extension that added it\n * @param {string} commandName - Unique name identifying the command\n * @param {CommandDefinition} definition - {@link CommandDefinition}\n */\n registerCommand(contextName, commandName, definition) {\n if (typeof definition !== 'object') {\n return;\n }\n\n const context = this.getContext(contextName);\n if (!context) {\n return;\n }\n\n context[commandName] = definition;\n }\n\n /**\n * Finds a command with the provided name if it exists in the specified context,\n * or a currently active context.\n *\n * @method\n * @param {String} commandName - Command to find\n * @param {String} [contextName] - Specific command to look in. Defaults to current activeContexts\n */\n getCommand(commandName, contextName) {\n let contexts = [];\n\n if (contextName) {\n const context = this.getContext(contextName);\n if (context) {\n contexts.push(context);\n }\n } else {\n const activeContexts = this._getActiveContexts();\n activeContexts.forEach(activeContext => {\n const context = this.getContext(activeContext);\n if (context) {\n contexts.push(context);\n }\n });\n }\n\n if (contexts.length === 0) {\n return;\n }\n\n let foundCommand;\n contexts.forEach(context => {\n if (context[commandName]) {\n foundCommand = context[commandName];\n }\n });\n\n return foundCommand;\n }\n\n /**\n *\n * @method\n * @param {String} commandName\n * @param {Object} [options={}] - Extra options to pass the command. Like a mousedown event\n * @param {String} [contextName]\n */\n runCommand(commandName, options = {}, contextName) {\n const definition = this.getCommand(commandName, contextName);\n if (!definition) {\n log.warn(`Command \"${commandName}\" not found in current context`);\n return;\n }\n\n const { commandFn, storeContexts = [] } = definition;\n const definitionOptions = definition.options;\n\n let commandParams = {};\n const appState = this._getAppState();\n storeContexts.forEach(context => {\n commandParams[context] = appState[context];\n });\n\n commandParams = Object.assign(\n {},\n commandParams, // Required store contexts\n definitionOptions, // \"Command configuration\"\n options // \"Time of call\" info\n );\n\n if (typeof commandFn !== 'function') {\n log.warn(`No commandFn was defined for command \"${commandName}\"`);\n return;\n } else {\n return commandFn(commandParams);\n }\n }\n}\n\nexport default CommandsManager;\n","import hotkeys from './../utils/hotkeys';\nimport log from './../log.js';\n\n/**\n *\n *\n * @typedef {Object} HotkeyDefinition\n * @property {String} commandName - Command to call\n * @property {String} label - Display name for hotkey\n * @property {String[]} keys - Keys to bind; Follows Mousetrap.js binding syntax\n */\n\nexport class HotkeysManager {\n constructor(commandsManager, servicesManager) {\n this.hotkeyDefinitions = {};\n this.hotkeyDefaults = [];\n this.isEnabled = true;\n\n if (!commandsManager) {\n log.warn(\n 'HotkeysManager instantiated without a commandsManager. Hotkeys will be unable to find and run commands.'\n );\n }\n\n this._servicesManager = servicesManager;\n this._commandsManager = commandsManager;\n }\n\n /**\n * Exposes Mousetrap.js's `.record` method, added by the record plugin.\n *\n * @param {*} event\n */\n record(event) {\n return hotkeys.record(event);\n }\n\n /**\n * Disables all hotkeys. Hotkeys added while disabled will not listen for\n * input.\n */\n disable() {\n this.isEnabled = false;\n hotkeys.pause();\n }\n\n /**\n * Enables all hotkeys.\n */\n enable() {\n this.isEnabled = true;\n hotkeys.unpause();\n }\n\n /**\n * Registers a list of hotkeydefinitions.\n *\n * @param {HotkeyDefinition[] | Object} [hotkeyDefinitions=[]] Contains hotkeys definitions\n */\n setHotkeys(hotkeyDefinitions = []) {\n try {\n const definitions = this._getValidDefinitions(hotkeyDefinitions);\n\n definitions.forEach(definition => this.registerHotkeys(definition));\n } catch (error) {\n const {\n UINotificationService,\n LoggerService,\n } = this._servicesManager.services;\n const message = 'Erro while setting hotkeys';\n LoggerService.error({ error, message });\n UINotificationService.show({\n title: 'Hotkeys Manager',\n message,\n type: 'error',\n });\n }\n }\n\n /**\n * Set default hotkey bindings. These\n * values are used in `this.restoreDefaultBindings`.\n *\n * @param {HotkeyDefinition[] | Object} [hotkeyDefinitions=[]] Contains hotkeys definitions\n */\n setDefaultHotKeys(hotkeyDefinitions = []) {\n const definitions = this._getValidDefinitions(hotkeyDefinitions);\n\n this.hotkeyDefaults = definitions;\n }\n\n /**\n * Take hotkey definitions that can be an array or object and make sure that it\n * returns an array of hotkeys\n *\n * @param {HotkeyDefinition[] | Object} [hotkeyDefinitions=[]] Contains hotkeys definitions\n */\n _getValidDefinitions(hotkeyDefinitions) {\n const definitions = Array.isArray(hotkeyDefinitions)\n ? [...hotkeyDefinitions]\n : this._parseToArrayLike(hotkeyDefinitions);\n\n return definitions;\n }\n\n /**\n * It parses given object containing hotkeyDefinition to array like.\n * Each property of given object will be mapped to an object of an array. And its property name will be the value of a property named as commandName\n *\n * @param {HotkeyDefinition[] | Object} [hotkeyDefinitions={}] Contains hotkeys definitions\n * @returns {HotkeyDefinition[]}\n */\n _parseToArrayLike(hotkeyDefinitionsObj = {}) {\n const copy = { ...hotkeyDefinitionsObj };\n return Object.entries(copy).map(entryValue =>\n this._parseToHotKeyObj(entryValue[0], entryValue[1])\n );\n }\n\n /**\n * Return HotkeyDefinition object like based on given property name and property value\n * @param {string} propertyName property name of hotkey definition object\n * @param {object} propertyValue property value of hotkey definition object\n *\n * @example\n *\n * const hotKeyObj = {hotKeyDefA: {keys:[],....}}\n *\n * const parsed = _parseToHotKeyObj(Object.keys(hotKeyDefA)[0], hotKeyObj[hotKeyDefA]);\n * {\n * commandName: hotKeyDefA,\n * keys: [],\n * ....\n * }\n *\n */\n _parseToHotKeyObj(propertyName, propertyValue) {\n return {\n commandName: propertyName,\n ...propertyValue,\n };\n }\n\n /**\n * (unbinds and) binds the specified command to one or more key combinations.\n * When a hotkey combination is triggered, the command name and active contexts\n * are used to locate the correct command to call.\n *\n * @param {HotkeyDefinition} commandName\n * @param {String} extension\n * @returns {undefined}\n */\n registerHotkeys({ commandName, keys, label } = {}, extension) {\n if (!commandName) {\n log.warn(`No command was defined for hotkey \"${keys}\"`);\n return;\n }\n\n const previouslyRegisteredDefinition = this.hotkeyDefinitions[commandName];\n\n if (previouslyRegisteredDefinition) {\n const previouslyRegisteredKeys = previouslyRegisteredDefinition.keys;\n this._unbindHotkeys(commandName, previouslyRegisteredKeys);\n log.info(`Unbinding ${commandName} from ${previouslyRegisteredKeys}`);\n }\n\n // Set definition & bind\n this.hotkeyDefinitions[commandName] = { keys, label };\n this._bindHotkeys(commandName, keys);\n log.info(`Binding ${commandName} to ${keys}`);\n }\n\n /**\n * Uses most recent\n *\n * @returns {undefined}\n */\n restoreDefaultBindings() {\n this.setHotkeys(this.hotkeyDefaults);\n }\n\n /**\n *\n */\n destroy() {\n this.hotkeyDefaults = [];\n this.hotkeyDefinitions = {};\n hotkeys.reset();\n }\n\n /**\n * Binds one or more set of hotkey combinations for a given command\n *\n * @private\n * @param {string} commandName - The name of the command to trigger when hotkeys are used\n * @param {string[]} keys - One or more key combinations that should trigger command\n * @returns {undefined}\n */\n _bindHotkeys(commandName, keys) {\n const isKeyDefined = keys === '' || keys === undefined;\n if (isKeyDefined) {\n return;\n }\n\n const isKeyArray = keys instanceof Array;\n const combinedKeys = isKeyArray ? keys.join('+') : keys;\n\n hotkeys.bind(combinedKeys, evt => {\n evt.preventDefault();\n evt.stopPropagation();\n this._commandsManager.runCommand(commandName, { evt });\n });\n }\n\n /**\n * unbinds one or more set of hotkey combinations for a given command\n *\n * @private\n * @param {string} commandName - The name of the previously bound command\n * @param {string[]} keys - One or more sets of previously bound keys\n * @returns {undefined}\n */\n _unbindHotkeys(commandName, keys) {\n const isKeyDefined = keys !== '' && keys !== undefined;\n if (!isKeyDefined) {\n return;\n }\n\n const isKeyArray = keys instanceof Array;\n if (isKeyArray) {\n const combinedKeys = keys.join('+');\n this._unbindHotkeys(commandName, combinedKeys);\n return;\n }\n\n hotkeys.unbind(keys);\n }\n}\n\nexport default HotkeysManager;\n\n// Commands Contexts:\n\n// --> Name and Priority\n// GLOBAL: 0\n// VIEWER::CORNERSTONE: 1\n// VIEWER::VTK: 1\n","export const CodeNameCodeSequenceValues = {\n ImagingMeasurementReport: '126000',\n ImageLibrary: '111028',\n ImagingMeasurements: '126010',\n MeasurementGroup: '125007',\n ImageLibraryGroup: '126200',\n TrackingUniqueIdentifier: '112040',\n TrackingIdentifier: '112039',\n Finding: '121071',\n FindingSite: 'G-C0E3', // SRT\n CornerstoneFreeText: 'CORNERSTONEFREETEXT', // CST4\n Score: '246262008',\n};\n\nexport const RELATIONSHIP_TYPE = {\n INFERRED_FROM: 'INFERRED FROM',\n SELECTED_FROM: 'SELECTED FROM',\n};\n\nexport const CodingSchemeDesignators = {\n SRT: 'SRT',\n cornerstoneTools4: 'CST4',\n};\n\nexport default {\n CodeNameCodeSequenceValues,\n RELATIONSHIP_TYPE,\n CodingSchemeDesignators,\n};\n","const getSequenceAsArray = sequence =>\n Array.isArray(sequence) ? sequence : [sequence];\n\nexport default getSequenceAsArray;\n","import getSequenceAsArray from './getSequenceAsArray';\nimport { CodeNameCodeSequenceValues } from '../enums';\n\nconst getMergedContentSequencesByTrackingUniqueIdentifiers = MeasurementGroups => {\n const mergedContentSequencesByTrackingUniqueIdentifiers = {};\n\n MeasurementGroups.forEach(MeasurementGroup => {\n const ContentSequence = getSequenceAsArray(\n MeasurementGroup.ContentSequence\n );\n\n const TrackingUniqueIdentifierItem = ContentSequence.find(\n item =>\n item.ConceptNameCodeSequence.CodeValue ===\n CodeNameCodeSequenceValues.TrackingUniqueIdentifier\n );\n\n if (!TrackingUniqueIdentifierItem) {\n console.warn(\n 'No Tracking Unique Identifier, skipping ambiguous measurement.'\n );\n }\n\n const trackingUniqueIdentifier = TrackingUniqueIdentifierItem.UID;\n\n if (\n mergedContentSequencesByTrackingUniqueIdentifiers[\n trackingUniqueIdentifier\n ] === undefined\n ) {\n // Add the full ContentSequence\n mergedContentSequencesByTrackingUniqueIdentifiers[\n trackingUniqueIdentifier\n ] = [...ContentSequence];\n } else {\n // Add the ContentSequence minus the tracking identifier, as we have this\n // Information in the merged ContentSequence anyway.\n ContentSequence.forEach(item => {\n if (\n item.ConceptNameCodeSequence.CodeValue !==\n CodeNameCodeSequenceValues.TrackingUniqueIdentifier\n ) {\n mergedContentSequencesByTrackingUniqueIdentifiers[\n trackingUniqueIdentifier\n ].push(item);\n }\n });\n }\n });\n\n return mergedContentSequencesByTrackingUniqueIdentifiers;\n};\n\nexport default getMergedContentSequencesByTrackingUniqueIdentifiers;\n","const getLabelFromMeasuredValueSequence = (\n ConceptNameCodeSequence,\n MeasuredValueSequence\n) => {\n const { CodeMeaning } = ConceptNameCodeSequence;\n const { NumericValue, MeasurementUnitsCodeSequence } = MeasuredValueSequence;\n const { CodeValue } = MeasurementUnitsCodeSequence;\n\n const formatedNumericValue = NumericValue\n ? Number(NumericValue).toFixed(1)\n : '';\n\n return {\n label: CodeMeaning,\n value: `${formatedNumericValue} ${CodeValue}`,\n }; // E.g. Long Axis: 31.0 mm\n};\n\nexport default getLabelFromMeasuredValueSequence;\n","const getCoordsFromSCOORDOrSCOORD3D = (graphicItem, displaySet) => {\n const { ValueType, RelationshipType, GraphicType, GraphicData } = graphicItem;\n\n // if (RelationshipType !== RELATIONSHIP_TYPE.INFERRED_FROM) {\n // console.warn(\n // `Relationshiptype === ${RelationshipType}. Cannot deal with NON TID-1400 SCOORD group with RelationshipType !== \"INFERRED FROM.\"`\n // );\n // return;\n // }\n\n const coords = { ValueType, GraphicType, GraphicData };\n\n // ContentSequence has length of 1 as RelationshipType === 'INFERRED FROM'\n if (ValueType === 'SCOORD') {\n const { ReferencedSOPSequence } = graphicItem.ContentSequence;\n coords.ReferencedSOPSequence = ReferencedSOPSequence;\n } else if (ValueType === 'SCOORD3D') {\n if (graphicItem.ReferencedFrameOfReferenceUID) {\n coords.ReferencedFrameOfReferenceSequence = graphicItem.ReferencedFrameOfReferenceUID;\n } else if (graphicItem.ContentSequence) {\n const {\n ReferencedFrameOfReferenceSequence,\n } = graphicItem.ContentSequence;\n coords.ReferencedFrameOfReferenceSequence = ReferencedFrameOfReferenceSequence;\n }\n }\n\n return coords;\n};\n\nexport default getCoordsFromSCOORDOrSCOORD3D;\n","import getLabelFromMeasuredValueSequence from './getLabelFromMeasuredValueSequence';\nimport getCoordsFromSCOORDOrSCOORD3D from './getCoordsFromSCOORDOrSCOORD3D';\nimport { RELATIONSHIP_TYPE, CodeNameCodeSequenceValues } from '../enums';\n\n/**\n * TID 1410 Planar ROI Measurements and Qualitative Evaluations.\n *\n * @param {*} mergedContentSequence\n * @returns\n */\nconst processTID1410Measurement = (mergedContentSequence, displaySet) => {\n // Need to deal with TID 1410 style measurements, which will have a SCOORD or SCOORD3D at the top level,\n // And non-geometric representations where each NUM has \"INFERRED FROM\" SCOORD/SCOORD3D\n\n const graphicItem = mergedContentSequence.find(\n group => group.ValueType === 'SCOORD' || group.ValueType === 'SCOORD3D'\n );\n\n if (!graphicItem) {\n console.warn(\n `graphic ValueType ${graphicItem.ValueType} not currently supported, skipping annotation.`\n );\n return;\n }\n\n const UIDREFContentItem = mergedContentSequence.find(\n group => group.ValueType === 'UIDREF'\n );\n\n const TrackingIdentifierContentItem = mergedContentSequence.find(\n item =>\n item.ConceptNameCodeSequence.CodeValue ===\n CodeNameCodeSequenceValues.TrackingIdentifier\n );\n\n const NUMContentItems = mergedContentSequence.filter(\n group => group.ValueType === 'NUM'\n );\n\n const measurement = {\n loaded: false,\n labels: [],\n coords: [getCoordsFromSCOORDOrSCOORD3D(graphicItem, displaySet)],\n TrackingUniqueIdentifier: UIDREFContentItem.UID,\n TrackingIdentifier: TrackingIdentifierContentItem.TextValue,\n };\n\n NUMContentItems.forEach(item => {\n const {\n ConceptNameCodeSequence,\n ContentSequence,\n MeasuredValueSequence,\n } = item;\n\n if (\n item.ConceptNameCodeSequence.CodeValue ===\n CodeNameCodeSequenceValues.Score\n ) {\n ContentSequence.forEach(item => {\n if (\n [\n RELATIONSHIP_TYPE.SELECTED_FROM,\n RELATIONSHIP_TYPE.INFERRED_FROM,\n ].includes(item.RelationshipType)\n ) {\n if (item.ReferencedSOPSequence) {\n measurement.coords.forEach(coord => {\n coord.ReferencedSOPSequence = item.ReferencedSOPSequence;\n });\n }\n }\n });\n }\n\n if (MeasuredValueSequence) {\n measurement.labels.push(\n getLabelFromMeasuredValueSequence(\n ConceptNameCodeSequence,\n MeasuredValueSequence\n )\n );\n }\n });\n\n return measurement;\n};\n\nexport default processTID1410Measurement;\n","import getLabelFromMeasuredValueSequence from './getLabelFromMeasuredValueSequence';\nimport getCoordsFromSCOORDOrSCOORD3D from './getCoordsFromSCOORDOrSCOORD3D';\nimport { CodeNameCodeSequenceValues, CodingSchemeDesignators } from '../enums';\n\nconst CORNERSTONE_FREETEXT_CODE_VALUE = 'CORNERSTONEFREETEXT';\n\nconst processNonGeometricallyDefinedMeasurement = mergedContentSequence => {\n const NUMContentItems = mergedContentSequence.filter(\n group => group.ValueType === 'NUM'\n );\n\n const UIDREFContentItem = mergedContentSequence.find(\n group => group.ValueType === 'UIDREF'\n );\n\n const TrackingIdentifierContentItem = mergedContentSequence.find(\n item =>\n item.ConceptNameCodeSequence.CodeValue ===\n CodeNameCodeSequenceValues.TrackingIdentifier\n );\n\n const Finding = mergedContentSequence.find(\n item =>\n item.ConceptNameCodeSequence.CodeValue ===\n CodeNameCodeSequenceValues.Finding\n );\n\n const FindingSites = mergedContentSequence.filter(\n item =>\n item.ConceptNameCodeSequence.CodingSchemeDesignator ===\n CodingSchemeDesignators.SRT &&\n item.ConceptNameCodeSequence.CodeValue ===\n CodeNameCodeSequenceValues.FindingSite\n );\n\n const measurement = {\n loaded: false,\n labels: [],\n coords: [],\n TrackingUniqueIdentifier: UIDREFContentItem.UID,\n TrackingIdentifier: TrackingIdentifierContentItem.TextValue,\n };\n\n if (\n Finding &&\n Finding.ConceptCodeSequence.CodingSchemeDesignator ===\n CodingSchemeDesignators.cornerstoneTools4 &&\n Finding.ConceptCodeSequence.CodeValue ===\n CodeNameCodeSequenceValues.CornerstoneFreeText\n ) {\n measurement.labels.push({\n label: CORNERSTONE_FREETEXT_CODE_VALUE,\n value: Finding.ConceptCodeSequence.CodeMeaning,\n });\n }\n\n // TODO -> Eventually hopefully support SNOMED or some proper code library, just free text for now.\n if (FindingSites.length) {\n const cornerstoneFreeTextFindingSite = FindingSites.find(\n FindingSite =>\n FindingSite.ConceptCodeSequence.CodingSchemeDesignator ===\n CodingSchemeDesignators.cornerstoneTools4 &&\n FindingSite.ConceptCodeSequence.CodeValue ===\n CodeNameCodeSequenceValues.CornerstoneFreeText\n );\n\n if (cornerstoneFreeTextFindingSite) {\n measurement.labels.push({\n label: CORNERSTONE_FREETEXT_CODE_VALUE,\n value: cornerstoneFreeTextFindingSite.ConceptCodeSequence.CodeMeaning,\n });\n }\n }\n\n NUMContentItems.forEach(item => {\n const {\n ConceptNameCodeSequence,\n ContentSequence,\n MeasuredValueSequence,\n } = item;\n\n if (!ContentSequence) {\n console.warn(`Graphic ${ContentSequence} missing, skipping annotation.`);\n\n return;\n }\n\n const { ValueType } = ContentSequence;\n\n if (!ValueType === 'SCOORD' && !ValueType === 'SCOORD3D') {\n console.warn(\n `Graphic ${ValueType} not currently supported, skipping annotation.`\n );\n\n return;\n }\n\n const coords = getCoordsFromSCOORDOrSCOORD3D(ContentSequence);\n\n if (coords) {\n measurement.coords.push(coords);\n }\n\n if (MeasuredValueSequence) {\n measurement.labels.push(\n getLabelFromMeasuredValueSequence(\n ConceptNameCodeSequence,\n MeasuredValueSequence\n )\n );\n }\n });\n\n return measurement;\n};\n\nexport default processNonGeometricallyDefinedMeasurement;\n","import processTID1410Measurement from './processTID1410Measurement';\nimport processNonGeometricallyDefinedMeasurement from './processNonGeometricallyDefinedMeasurement';\n\nconst processMeasurement = (mergedContentSequence, displaySet) => {\n if (\n mergedContentSequence.some(\n group => group.ValueType === 'SCOORD' || group.ValueType === 'SCOORD3D'\n )\n ) {\n return processTID1410Measurement(mergedContentSequence, displaySet);\n }\n\n return processNonGeometricallyDefinedMeasurement(mergedContentSequence);\n};\n\nexport default processMeasurement;\n","import { CodeNameCodeSequenceValues } from '../enums';\nimport getSequenceAsArray from './getSequenceAsArray';\nimport getMergedContentSequencesByTrackingUniqueIdentifiers from './getMergedContentSequencesByTrackingUniqueIdentifiers';\nimport processMeasurement from './processMeasurement';\n\nconst getMeasurements = (\n ImagingMeasurementReportContentSequence,\n displaySet\n) => {\n const ImagingMeasurements = ImagingMeasurementReportContentSequence.find(\n item =>\n item.ConceptNameCodeSequence.CodeValue ===\n CodeNameCodeSequenceValues.ImagingMeasurements\n );\n\n const MeasurementGroups = getSequenceAsArray(\n ImagingMeasurements.ContentSequence\n ).filter(\n item =>\n item.ConceptNameCodeSequence.CodeValue ===\n CodeNameCodeSequenceValues.MeasurementGroup\n );\n\n const mergedContentSequencesByTrackingUniqueIdentifiers = getMergedContentSequencesByTrackingUniqueIdentifiers(\n MeasurementGroups\n );\n\n let measurements = [];\n\n Object.keys(mergedContentSequencesByTrackingUniqueIdentifiers).forEach(\n trackingUniqueIdentifier => {\n const mergedContentSequence =\n mergedContentSequencesByTrackingUniqueIdentifiers[\n trackingUniqueIdentifier\n ];\n\n const measurement = processMeasurement(mergedContentSequence, displaySet);\n if (measurement) {\n measurements.push(measurement);\n }\n }\n );\n\n return measurements;\n};\n\nexport default getMeasurements;\n","import getSequenceAsArray from './getSequenceAsArray';\nimport { CodeNameCodeSequenceValues } from '../enums';\n\nconst getReferencedImagesList = ImagingMeasurementReportContentSequence => {\n const referencedImages = [];\n\n const ImageLibrary = ImagingMeasurementReportContentSequence.find(\n item =>\n item.ConceptNameCodeSequence.CodeValue ===\n CodeNameCodeSequenceValues.ImageLibrary\n );\n\n if (!ImageLibrary.ContentSequence) {\n return referencedImages;\n }\n\n const ImageLibraryGroup = getSequenceAsArray(\n ImageLibrary.ContentSequence\n ).find(\n item =>\n item.ConceptNameCodeSequence.CodeValue ===\n CodeNameCodeSequenceValues.ImageLibraryGroup\n );\n\n getSequenceAsArray(ImageLibraryGroup.ContentSequence).forEach(item => {\n const { ReferencedSOPSequence } = item;\n if (ReferencedSOPSequence) {\n const {\n ReferencedSOPClassUID,\n ReferencedSOPInstanceUID,\n } = ReferencedSOPSequence;\n\n referencedImages.push({\n ReferencedSOPClassUID,\n ReferencedSOPInstanceUID,\n });\n }\n });\n\n return referencedImages;\n};\n\nexport default getReferencedImagesList;\n","import { adapters } from 'dcmjs';\n\nconst cornerstoneAdapters = adapters.Cornerstone;\n\n/**\n * Checks if the given `displaySet`can be rehydrated into the `MeasurementService`.\n *\n * @param {object} displaySet The SR `displaySet` to check.\n * @param {object[]} mappings The CornerstoneTools 4 mappings to the `MeasurementService`.\n * @returns {boolean} True if the SR can be rehydrated into the `MeasurementService`.\n */\nexport default function isRehydratable(displaySet, mappings) {\n if (!mappings || !mappings.length) {\n return false;\n }\n\n const mappingDefinitions = mappings.map(m => m.definition);\n const { measurements } = displaySet;\n\n const adapterKeys = Object.keys(cornerstoneAdapters).filter(\n adapterKey =>\n typeof cornerstoneAdapters[adapterKey]\n .isValidCornerstoneTrackingIdentifier === 'function'\n );\n\n const adapters = [];\n\n adapterKeys.forEach(key => {\n if (mappingDefinitions.includes(key)) {\n // Must have both a dcmjs adapter and a MeasurementService\n // Definition in order to be a candidate for import.\n adapters.push(cornerstoneAdapters[key]);\n }\n });\n\n for (let i = 0; i < measurements.length; i++) {\n const TrackingIdentifier = measurements[i].TrackingIdentifier;\n const hydratable = adapters.some(adapter =>\n adapter.isValidCornerstoneTrackingIdentifier(TrackingIdentifier)\n );\n\n if (hydratable) {\n return true;\n }\n }\n\n return false;\n}\n","const TOOL_NAMES = {\n DICOM_SR_DISPLAY_TOOL: 'DICOMSRDisplayTool',\n};\n\nexport default TOOL_NAMES;\n","export default {\n POINT: 'POINT',\n MULTIPOINT: 'MULTIPOINT',\n POLYLINE: 'POLYLINE',\n CIRCLE: 'CIRCLE',\n ELLIPSE: 'ELLIPSE',\n POLYGON: 'POLYGON',\n};\n","import csMath from 'cornerstone-math';\nimport SCOORD_TYPES from '../constants/scoordTypes';\nimport { inv } from 'mathjs';\n\nconst getRenderableData = (\n GraphicType,\n GraphicData,\n ValueType,\n imageMetadata\n) => {\n let renderableData;\n\n const orientation = imageMetadata.ImageOrientationPatient;\n const position = imageMetadata.ImagePositionPatient;\n const pixelSpacing = imageMetadata.PixelSpacing;\n const sliceSpacing = imageMetadata.SliceThickness\n ? imageMetadata.SliceThickness\n : 1;\n // https://nipy.org/nibabel/dicom/dicom_orientation.html\n const M = [\n [\n orientation[0] * pixelSpacing[0],\n orientation[3] * pixelSpacing[1],\n sliceSpacing,\n position[0],\n ],\n [\n orientation[1] * pixelSpacing[0],\n orientation[4] * pixelSpacing[1],\n sliceSpacing,\n position[1],\n ],\n [\n orientation[2] * pixelSpacing[0],\n orientation[5] * pixelSpacing[1],\n sliceSpacing,\n position[2],\n ],\n [0, 0, 0, 1],\n ];\n\n // we need to go from 3D to pixel (cornerstone2D works in pixel coordinates),\n // we take the inverse.\n const M1 = inv(M);\n\n const worldToIJK = (point, M1) => {\n const worldPoint = {\n x:\n M1[0][0] * point.x + M1[0][1] * point.y + M1[0][2] * point.z + M1[0][3],\n y:\n M1[1][0] * point.x + M1[1][1] * point.y + M1[1][2] * point.z + M1[1][3],\n z:\n M1[2][0] * point.x + M1[2][1] * point.y + M1[2][2] * point.z + M1[2][3],\n };\n return worldPoint;\n };\n\n // https://dicom.innolitics.com/ciods/procedure-log/sr-document-content/00700023\n switch (GraphicType) {\n case SCOORD_TYPES.POINT:\n renderableData = [];\n\n if (ValueType === 'SCOORD3D') {\n for (let i = 0; i < GraphicData.length; i += 3) {\n const point = {\n x: GraphicData[i],\n y: GraphicData[i + 1],\n z: GraphicData[i + 2],\n };\n\n renderableData.push(worldToIJK(point, M1));\n }\n } else {\n for (let i = 0; i < GraphicData.length; i += 2) {\n renderableData.push({ x: GraphicData[i], y: GraphicData[i + 1] });\n }\n }\n\n break;\n case SCOORD_TYPES.MULTIPOINT:\n renderableData = [];\n\n if (ValueType === 'SCOORD3D') {\n for (let i = 0; i < GraphicData.length; i += 3) {\n const point = {\n x: GraphicData[i],\n y: GraphicData[i + 1],\n z: GraphicData[i + 2],\n };\n\n renderableData.push(worldToIJK(point, M1));\n }\n } else {\n for (let i = 0; i < GraphicData.length; i += 2) {\n renderableData.push({ x: GraphicData[i], y: GraphicData[i + 1] });\n }\n }\n\n break;\n case SCOORD_TYPES.POLYLINE:\n renderableData = [];\n\n if (ValueType === 'SCOORD3D') {\n for (let i = 0; i < GraphicData.length; i += 3) {\n const point = {\n x: GraphicData[i],\n y: GraphicData[i + 1],\n z: GraphicData[i + 2],\n };\n\n renderableData.push(worldToIJK(point, M1));\n }\n } else {\n for (let i = 0; i < GraphicData.length; i += 2) {\n renderableData.push({ x: GraphicData[i], y: GraphicData[i + 1] });\n }\n }\n\n break;\n case SCOORD_TYPES.POLYGON:\n // this is only scoord3d\n renderableData = [];\n for (let i = 0; i < GraphicData.length; i += 3) {\n const point = {\n x: GraphicData[i],\n y: GraphicData[i + 1],\n z: GraphicData[i + 2],\n };\n\n renderableData.push(worldToIJK(point, M1));\n }\n break;\n case SCOORD_TYPES.CIRCLE: {\n // this is only scoord\n const center = { x: GraphicData[0], y: GraphicData[1] };\n const onPerimeter = { x: GraphicData[2], y: GraphicData[3] };\n\n const radius = csMath.point.distance(center, onPerimeter);\n\n renderableData = {\n center,\n radius,\n };\n break;\n }\n case SCOORD_TYPES.ELLIPSE: {\n console.warn('ROTATED ELLIPSE NOT YET SUPPORTED!');\n // To Do: scoord3d ellips, need data for testing\n const majorAxis = [\n { x: GraphicData[0], y: GraphicData[1] },\n { x: GraphicData[2], y: GraphicData[3] },\n ];\n const minorAxis = [\n { x: GraphicData[4], y: GraphicData[5] },\n { x: GraphicData[6], y: GraphicData[7] },\n ];\n\n // Calculate two opposite corners of box defined by two axes.\n\n const minorAxisLength = csMath.point.distance(minorAxis[0], minorAxis[1]);\n\n const minorAxisDirection = {\n x: (minorAxis[1].x - minorAxis[0].x) / minorAxisLength,\n y: (minorAxis[1].y - minorAxis[0].y) / minorAxisLength,\n };\n\n const halfMinorAxisLength = minorAxisLength / 2;\n\n // First end point of major axis + half minor axis vector\n const corner1 = {\n x: majorAxis[0].x + minorAxisDirection.x * halfMinorAxisLength,\n y: majorAxis[0].y + minorAxisDirection.y * halfMinorAxisLength,\n };\n\n // Second end point of major axis - half of minor axis vector\n const corner2 = {\n x: majorAxis[1].x - minorAxisDirection.x * halfMinorAxisLength,\n y: majorAxis[1].y - minorAxisDirection.y * halfMinorAxisLength,\n };\n\n renderableData = {\n corner1,\n corner2,\n };\n break;\n }\n }\n\n return renderableData;\n};\n\nexport default getRenderableData;\n","import csTools from 'cornerstone-tools';\nimport OHIF from '../../../';\n\n/** Internal imports */\nimport TOOL_NAMES from '../constants/toolNames';\nimport getRenderableData from './getRenderableData';\n\nconst globalImageIdSpecificToolStateManager =\n csTools.globalImageIdSpecificToolStateManager;\n\n/**\n * Add a measurement to a display set.\n *\n * @param {*} measurement\n * @param {*} imageId\n * @param {*} displaySetInstanceUID\n */\nexport default function addMeasurement(\n measurement,\n imageId,\n imageMetadata,\n displaySetInstanceUID\n) {\n // TODO -> Render rotated ellipse .\n const toolName = TOOL_NAMES.DICOM_SR_DISPLAY_TOOL;\n\n const measurementData = {\n TrackingUniqueIdentifier: measurement.TrackingUniqueIdentifier,\n renderableData: {},\n labels: measurement.labels,\n };\n\n measurement.coords.forEach(coord => {\n const { GraphicType, GraphicData, ValueType } = coord;\n\n if (measurementData.renderableData[GraphicType] === undefined) {\n measurementData.renderableData[GraphicType] = [];\n }\n measurementData.renderableData[GraphicType].push(\n getRenderableData(GraphicType, GraphicData, ValueType, imageMetadata)\n );\n });\n\n const toolState = globalImageIdSpecificToolStateManager.saveToolState();\n\n if (toolState[imageId] === undefined) {\n toolState[imageId] = {};\n }\n\n const imageIdToolState = toolState[imageId];\n\n // If we don't have tool state for this type of tool, add an empty object\n if (imageIdToolState[toolName] === undefined) {\n imageIdToolState[toolName] = {\n data: [],\n };\n }\n\n const toolData = imageIdToolState[toolName];\n\n measurementData.description = `Read-only annotation`;\n measurementData.isReadOnly = true;\n toolData.data.push(measurementData);\n\n addToMeasurementApi({ measurementData, toolName, imageId });\n\n measurement.loaded = true;\n measurement.imageId = imageId;\n measurement.displaySetInstanceUID = displaySetInstanceUID;\n\n // Remove the unneeded coord now its processed, but keep the SOPInstanceUID.\n // NOTE: We assume that each SCOORD in the MeasurementGroup maps onto one frame,\n // It'd be super werid if it didn't anyway as a SCOORD.\n measurement.ReferencedSOPInstanceUID =\n measurement.coords[0].ReferencedSOPSequence.ReferencedSOPInstanceUID;\n\n return measurement;\n}\n\nconst addToMeasurementApi = ({ measurementData, toolName, imageId }) => {\n const measurementApi = OHIF.measurements.MeasurementApi.Instance;\n\n const toolType = toolName;\n const collection = measurementApi.tools[toolType];\n if (!collection) return;\n if (!measurementData || measurementData.cancelled) return;\n\n const imageAttributes = OHIF.measurements.getImageAttributes(null, imageId);\n const measurement = Object.assign({}, measurementData, imageAttributes, {\n lesionNamingNumber: measurementData.lesionNamingNumber,\n userId: OHIF.user.getUserId(),\n toolType,\n });\n\n const addedMeasurement = measurementApi.addMeasurement(toolType, measurement);\n Object.assign(measurementData, addedMeasurement);\n\n const measurementLabel = OHIF.measurements.getLabel(measurementData);\n if (measurementLabel) {\n measurementData.labels = [measurementLabel];\n }\n};\n","import { ImageSet } from '../../classes';\nimport getMeasurements from './utils/getMeasurements';\nimport getReferencedImagesList from './utils/getReferencedImagesList';\nimport isRehydratable from './utils/isRehydratable';\nimport addMeasurement from './utils/addMeasurement';\n\nconst parseSCOORD3D = ({ servicesManager, displaySets }) => {\n const { MeasurementService } = servicesManager.services;\n\n const srDisplaySets = displaySets.filter(ds => ds.Modality === 'SR');\n\n srDisplaySets.forEach(srDisplaySet => {\n const firstInstance = srDisplaySet.metadata;\n if (!firstInstance) {\n return;\n }\n\n const { ContentSequence } = firstInstance;\n\n srDisplaySet.referencedImages = getReferencedImagesList(ContentSequence);\n srDisplaySet.measurements = getMeasurements(ContentSequence, srDisplaySet);\n const mappings = MeasurementService.getSourceMappings(\n 'CornerstoneTools',\n '4'\n );\n\n srDisplaySet.isHydrated = false;\n srDisplaySet.isRehydratable = isRehydratable(srDisplaySet, mappings);\n srDisplaySet.isLoaded = true;\n\n const imageDisplaySets = displaySets.filter(\n ds =>\n ds.Modality !== 'SR' &&\n ds.Modality !== 'SEG' &&\n ds.Modality !== 'RTSTRUCT' &&\n ds.Modality !== 'RTDOSE'\n );\n imageDisplaySets.forEach(imageDisplaySet => {\n // Check currently added displaySets and add measurements if the sources exist.\n checkIfCanAddMeasurementsToDisplaySet(srDisplaySet, imageDisplaySet);\n });\n });\n};\n\nconst checkIfCanAddMeasurementsToDisplaySet = (\n srDisplaySet,\n imageDisplaySet\n) => {\n let measurements = srDisplaySet.measurements;\n\n /**\n * Look for image sets.\n * This also filters out _this_ displaySet, as it is not an image set.\n */\n if (!(imageDisplaySet instanceof ImageSet)) {\n return;\n }\n\n const { sopClassUIDs, images } = imageDisplaySet;\n\n /**\n * Filter measurements that references the correct sop class.\n */\n measurements = measurements.filter(measurement => {\n return measurement.coords.some(coord => {\n if (coord.ReferencedSOPSequence === undefined) {\n /** we miss the referenced information. We can compare the annotation SCOORD3D coordinates with\n * the ImagePatientPosition of the frames. However (WARNING!!!),\n * if more than a source series is present, this logic can find the wrong frame\n * (i.e. two source series, with the same frameOfReferenceUID,\n * that have each a frame with the same ImagePositionPatient of the annotation 3D coordinates)\n */\n for (let i = 0; i < images.length; ++i) {\n const imageMetadata = images[i].getData().metadata;\n if (\n imageMetadata.FrameOfReferenceUID !==\n coord.ReferencedFrameOfReferenceSequence\n ) {\n continue;\n }\n\n let sliceNormal = [0, 0, 0];\n const orientation = imageMetadata.ImageOrientationPatient;\n sliceNormal[0] =\n orientation[1] * orientation[5] - orientation[2] * orientation[4];\n sliceNormal[1] =\n orientation[2] * orientation[3] - orientation[0] * orientation[5];\n sliceNormal[2] =\n orientation[0] * orientation[4] - orientation[1] * orientation[3];\n\n let distanceAlongNormal = 0;\n for (let j = 0; j < 3; ++j) {\n distanceAlongNormal +=\n sliceNormal[j] * imageMetadata.ImagePositionPatient[j];\n }\n\n // assuming 1 mm tolerance\n if (Math.abs(distanceAlongNormal - coord.GraphicData[2]) > 1) {\n continue;\n }\n\n coord.ReferencedSOPSequence = {\n ReferencedSOPClassUID: imageMetadata.SOPClassUID,\n ReferencedSOPInstanceUID: imageMetadata.SOPInstanceUID,\n };\n\n break;\n }\n\n if (coord.ReferencedSOPSequence === undefined) {\n return false;\n }\n }\n\n return sopClassUIDs.includes(\n coord.ReferencedSOPSequence.ReferencedSOPClassUID\n );\n });\n });\n\n /**\n * New display set doesn't have measurements that references the correct sop class.\n */\n if (measurements.length === 0) {\n return;\n }\n\n const imageIds = images.map(i => i.getImageId());\n const SOPInstanceUIDs = images.map(i => i.SOPInstanceUID);\n measurements.forEach(measurement => {\n const { coords } = measurement;\n\n coords.forEach(coord => {\n if (coord.ReferencedSOPSequence !== undefined) {\n const imageIndex = SOPInstanceUIDs.findIndex(\n SOPInstanceUID =>\n SOPInstanceUID ===\n coord.ReferencedSOPSequence.ReferencedSOPInstanceUID\n );\n if (imageIndex > -1) {\n const imageId = imageIds[imageIndex];\n const imageMetadata = images[imageIndex].getData().metadata;\n addMeasurement(\n measurement,\n imageId,\n imageMetadata,\n imageDisplaySet.displaySetInstanceUID\n );\n }\n }\n });\n });\n};\n\nexport default parseSCOORD3D;\n","/**\n * Should Find the requested instance metadata into the displaySets and return\n *\n * @param {Array} displaySets - List of displaySets\n * @param {string} SOPInstanceUID - sopInstanceUID to look for\n * @returns {Object} - instance metadata found\n */\nconst findInstanceMetadataBySopInstanceUID = (displaySets, SOPInstanceUID) => {\n let instanceFound;\n\n displaySets.find(displaySet => {\n if (!displaySet.images) return false;\n\n instanceFound = displaySet.images.find(\n instanceMetadata =>\n instanceMetadata.getSOPInstanceUID() === SOPInstanceUID\n );\n\n return !!instanceFound;\n });\n\n return instanceFound;\n};\n\nexport default findInstanceMetadataBySopInstanceUID;\n","import dcmjs from 'dcmjs';\nimport classes from '../classes';\nimport parseSCOORD3D from './SCOORD3D/parseSCOORD3D';\n\nimport findInstanceMetadataBySopInstanceUID from './utils/findInstanceMetadataBySopInstanceUid';\n\nconst { LogManager } = classes;\n\n/**\n * Function to parse the part10 array buffer that comes from a DICOM Structured report into measurementData\n * measurementData format is a viewer specific format to be stored into the redux and consumed by other components\n * (e.g. measurement table)\n *\n * @param {ArrayBuffer} part10SRArrayBuffer\n * @param {Array} displaySets\n * @param {object} external\n * @returns\n */\nconst parseDicomStructuredReport = (\n part10SRArrayBuffer,\n displaySets,\n external\n) => {\n if (external && external.servicesManager) {\n parseSCOORD3D({ servicesManager: external.servicesManager, displaySets });\n }\n\n // Get the dicom data as an Object\n const dicomData = dcmjs.data.DicomMessage.readFile(part10SRArrayBuffer);\n const dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(\n dicomData.dict\n );\n\n const { MeasurementReport } = dcmjs.adapters.Cornerstone;\n\n let storedMeasurementByToolType;\n try {\n storedMeasurementByToolType = MeasurementReport.generateToolState(dataset);\n } catch (error) {\n const seriesDescription = dataset.SeriesDescription || '';\n LogManager.publish(LogManager.EVENTS.OnLog, {\n title: `Failed to parse ${seriesDescription} measurement report`,\n type: 'warning',\n message: error.message || '',\n notify: true,\n });\n return;\n }\n\n const measurementData = {};\n let measurementNumber = 0;\n\n Object.keys(storedMeasurementByToolType).forEach(toolName => {\n const measurements = storedMeasurementByToolType[toolName];\n measurementData[toolName] = [];\n\n measurements.forEach(measurement => {\n const instanceMetadata = findInstanceMetadataBySopInstanceUID(\n displaySets,\n measurement.sopInstanceUid\n );\n\n const { _study: study, _series: series } = instanceMetadata;\n const { StudyInstanceUID, PatientID } = study;\n const { SeriesInstanceUID } = series;\n const { sopInstanceUid, frameIndex } = measurement;\n const imagePath = getImagePath(\n StudyInstanceUID,\n SeriesInstanceUID,\n sopInstanceUid,\n frameIndex\n );\n\n const imageId = instanceMetadata.getImageId();\n if (!imageId) {\n return;\n }\n\n // TODO: We need the currentTimepointID set into the viewer\n const currentTimepointId = 'TimepointId';\n\n const toolData = Object.assign({}, measurement, {\n imageId,\n imagePath,\n SOPInstanceUID: sopInstanceUid,\n SeriesInstanceUID,\n StudyInstanceUID,\n PatientID,\n measurementNumber: ++measurementNumber,\n timepointId: currentTimepointId,\n toolType: toolName,\n _id: imageId + measurementNumber,\n });\n\n measurementData[toolName].push(toolData);\n });\n });\n\n return measurementData;\n};\n\n/**\n * Function to create imagePath with all imageData related\n * @param {string} StudyInstanceUID\n * @param {string} SeriesInstanceUID\n * @param {string} SOPInstanceUID\n * @param {string} frameIndex\n * @returns\n */\nconst getImagePath = (\n StudyInstanceUID,\n SeriesInstanceUID,\n SOPInstanceUID,\n frameIndex\n) => {\n return [StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID, frameIndex].join(\n '_'\n );\n};\n\nexport default parseDicomStructuredReport;\n","import dcmjs from 'dcmjs';\n\n/**\n * Checks if dcmjs has support to determined tool\n *\n * @param {string} toolName\n * @returns {boolean}\n */\nconst isToolSupported = toolName => {\n const adapter = dcmjs.adapters.Cornerstone;\n return !!adapter[toolName];\n};\n\nexport default isToolSupported;\n","import dcmjs from 'dcmjs';\nimport cornerstone from 'cornerstone-core';\n\nimport log from '../log';\nimport measurements from '../measurements';\nimport isToolSupported from './utils/isToolSupported';\n\n/**\n * Function to parse OHIF viewer measurementData into a dcmjs MeasurementReport\n *\n * @param {Object} measurementsData - OHIF measurementData object\n * @returns {Object} Dataset: measurement report from dcmjs\n */\nconst parseMeasurementsData = measurementsData => {\n const { MeasurementReport } = dcmjs.adapters.Cornerstone;\n const { getImageIdForImagePath } = measurements;\n\n const toolState = {};\n const unsupportedTools = [];\n\n Object.keys(measurementsData).forEach(measurementType => {\n const annotations = measurementsData[measurementType];\n\n annotations.forEach(annotation => {\n const { toolType, imagePath } = annotation;\n\n if (isToolSupported(toolType)) {\n const imageId = getImageIdForImagePath(imagePath);\n toolState[imageId] = toolState[imageId] || {};\n toolState[imageId][toolType] = toolState[imageId][toolType] || {\n data: [],\n };\n\n toolState[imageId][toolType].data.push(annotation);\n } else {\n unsupportedTools.push(toolType);\n }\n });\n });\n\n if (unsupportedTools.length > 0) {\n log.warn(\n `[DICOMSR] Tooltypes not supported: ${unsupportedTools.join(', ')}`\n );\n }\n\n const report = MeasurementReport.generateReport(\n toolState,\n cornerstone.metaData\n );\n\n return {\n dataset: report.dataset,\n };\n};\n\nexport default parseMeasurementsData;\n","/**\n * Retrieve a list of all displaySets of all studies\n *\n * @param {Object} studies - List of studies loaded into the viewer\n * @returns {Object} List of DisplaySets\n */\nconst getAllDisplaySets = studies => {\n let allDisplaySets = [];\n\n studies.forEach(study => {\n if (study.getDisplaySets) {\n allDisplaySets = allDisplaySets.concat(study.getDisplaySets());\n }\n });\n\n return allDisplaySets;\n};\n\nexport default getAllDisplaySets;\n","import dcmjs from 'dcmjs';\nimport { api } from 'dicomweb-client';\n\nimport DICOMWeb from '../DICOMWeb';\nimport parseDicomStructuredReport from './parseDicomStructuredReport';\nimport parseMeasurementsData from './parseMeasurementsData';\nimport getAllDisplaySets from './utils/getAllDisplaySets';\nimport errorHandler from '../errorHandler';\nimport getXHRRetryRequestHook from '../utils/xhrRetryRequestHook';\n\nconst VERSION_NAME = 'dcmjs-0.0';\nconst TRANSFER_SYNTAX_UID = '1.2.840.10008.1.2.1';\n\n/**\n * Function to retrieve measurements from DICOM Structured Reports coming from determined server\n *\n * @param {Array} series - List of all series metaData loaded\n * @param {Array} studies - List of all studies metaData loaded\n * @param {string} serverUrl - Server URL to be used on request\n * @param {object} external\n * @returns {Object} MeasurementData\n */\nconst retrieveMeasurementFromSR = async (\n series,\n studies,\n serverUrl,\n external\n) => {\n const config = {\n url: serverUrl,\n headers: DICOMWeb.getAuthorizationHeader(),\n errorInterceptor: errorHandler.getHTTPErrorHandler(),\n requestHooks: [getXHRRetryRequestHook()],\n };\n\n const dicomWeb = new api.DICOMwebClient(config);\n\n const instance = series.getFirstInstance();\n const options = {\n studyInstanceUID: instance.getStudyInstanceUID(),\n seriesInstanceUID: instance.getSeriesInstanceUID(),\n sopInstanceUID: instance.getSOPInstanceUID(),\n };\n\n const part10SRArrayBuffer = await dicomWeb.retrieveInstance(options);\n const displaySets = getAllDisplaySets(studies);\n const measurementsData = parseDicomStructuredReport(\n part10SRArrayBuffer,\n displaySets,\n external\n );\n\n return measurementsData;\n};\n\n/**\n * Function to store measurements to DICOM Structured Reports in determined server\n *\n * @param {Object} measurements - OHIF measurementData object\n * @param {string} serverUrl - Server URL to be used on request\n * @returns {Promise}\n */\nconst stowSRFromMeasurements = async (measurements, serverUrl) => {\n const { dataset } = parseMeasurementsData(measurements);\n const { DicomMetaDictionary, DicomDict } = dcmjs.data;\n const meta = {\n FileMetaInformationVersion: dataset._meta.FileMetaInformationVersion.Value,\n MediaStorageSOPClassUID: dataset.SOPClassUID,\n MediaStorageSOPInstanceUID: dataset.SOPInstanceUID,\n TransferSyntaxUID: TRANSFER_SYNTAX_UID,\n ImplementationClassUID: DicomMetaDictionary.uid(),\n ImplementationVersionName: VERSION_NAME,\n };\n\n const denaturalized = DicomMetaDictionary.denaturalizeDataset(meta);\n const dicomDict = new DicomDict(denaturalized);\n\n dicomDict.dict = DicomMetaDictionary.denaturalizeDataset(dataset);\n\n const part10Buffer = dicomDict.write();\n\n const config = {\n url: serverUrl,\n headers: DICOMWeb.getAuthorizationHeader(),\n errorInterceptor: errorHandler.getHTTPErrorHandler(),\n requestHooks: [getXHRRetryRequestHook()],\n };\n\n const dicomWeb = new api.DICOMwebClient(config);\n const options = {\n datasets: [part10Buffer],\n };\n\n await dicomWeb.storeInstances(options);\n};\n\nexport { retrieveMeasurementFromSR, stowSRFromMeasurements };\n","/**\n * Should find the most recent Structured Report metadata\n *\n * @param {Array} studies\n * @returns {Object} Series\n */\nconst findMostRecentStructuredReport = studies => {\n let mostRecentStructuredReport;\n\n studies.forEach(study => {\n const allSeries = study.getSeries ? study.getSeries() : [];\n allSeries.forEach(series => {\n // Skip series that may not have instances yet\n // This can happen if we have retrieved just the initial\n // details about the series via QIDO-RS, but not the full metadata\n if (!series || series.getInstanceCount() === 0) {\n return;\n }\n\n if (isStructuredReportSeries(series)) {\n if (\n !mostRecentStructuredReport ||\n compareSeriesDate(series, mostRecentStructuredReport)\n ) {\n mostRecentStructuredReport = series;\n }\n }\n });\n });\n\n return mostRecentStructuredReport;\n};\n\n/**\n * Checks if series sopClassUID matches with the supported Structured Reports sopClassUID\n *\n * @param {Object} series - Series metadata\n * @returns {boolean}\n */\nconst isStructuredReportSeries = series => {\n const supportedSopClassUIDs = [\n '1.2.840.10008.5.1.4.1.1.88.22',\n '1.2.840.10008.5.1.4.1.1.11.1',\n '1.2.840.10008.5.1.4.1.1.88.34', // COMPREHENSIVE_3D_SR\n ];\n\n const firstInstance = series.getFirstInstance();\n const SOPClassUID = firstInstance.getData().metadata.SOPClassUID;\n\n return supportedSopClassUIDs.includes(SOPClassUID);\n};\n\n/**\n * Checkes if series1 is newer than series2\n *\n * @param {Object} series1 - Series Metadata 1\n * @param {Object} series2 - Series Metadata 2\n * @returns {boolean} true/false if series1 is newer than series2\n */\nconst compareSeriesDate = (series1, series2) => {\n return (\n series1._data.SeriesDate > series2._data.SeriesDate ||\n (series1._data.SeriesDate === series2._data.SeriesDate &&\n series1._data.SeriesTime > series2._data.SeriesTime)\n );\n};\n\nexport default findMostRecentStructuredReport;\n","import log from '../log';\nimport studies from '../studies';\nimport utils from '../utils';\nimport {\n retrieveMeasurementFromSR,\n stowSRFromMeasurements,\n} from './handleStructuredReport';\nimport findMostRecentStructuredReport from './utils/findMostRecentStructuredReport';\n\n/**\n *\n * @typedef serverType\n * @property {string} type - type of the server\n * @property {string} wadoRoot - server wado root url\n *\n */\n\n/**\n * Function to be registered into MeasurementAPI to retrieve measurements from DICOM Structured Reports\n *\n * @param {serverType} server\n * @param {object} external\n * @returns {Promise} Should resolve with OHIF measurementData object\n */\nconst retrieveMeasurements = (server, external = {}) => {\n log.info('[DICOMSR] retrieveMeasurements');\n\n if (!server || server.type !== 'dicomWeb') {\n log.error('[DICOMSR] DicomWeb server is required!');\n return Promise.reject({});\n }\n\n const serverUrl = server.wadoRoot;\n const studies = utils.studyMetadataManager.all();\n\n const latestSeries = findMostRecentStructuredReport(studies);\n\n if (!latestSeries) return Promise.resolve({});\n\n return retrieveMeasurementFromSR(latestSeries, studies, serverUrl, external);\n};\n\n/**\n * Function to be registered into MeasurementAPI to store measurements into DICOM Structured Reports\n *\n * @param {Object} measurementData - OHIF measurementData object\n * @param {Object} filter\n * @param {serverType} server\n * @returns {Object} With message to be displayed on success\n */\nconst storeMeasurements = async (measurementData, filter, server) => {\n log.info('[DICOMSR] storeMeasurements');\n\n if (!server || server.type !== 'dicomWeb') {\n log.error('[DICOMSR] DicomWeb server is required!');\n return Promise.reject({});\n }\n\n const serverUrl = server.wadoRoot;\n const firstMeasurementKey = Object.keys(measurementData)[0];\n const firstMeasurement = measurementData[firstMeasurementKey][0];\n const StudyInstanceUID =\n firstMeasurement && firstMeasurement.StudyInstanceUID;\n\n try {\n await stowSRFromMeasurements(measurementData, serverUrl);\n if (StudyInstanceUID) {\n studies.deleteStudyMetadataPromise(StudyInstanceUID);\n }\n\n return {\n message: 'Measurements saved successfully',\n };\n } catch (error) {\n log.error(\n `[DICOMSR] Error while saving the measurements: ${error.message}`\n );\n throw new Error('Error while saving the measurements.');\n }\n};\n\nexport { retrieveMeasurements, storeMeasurements };\n","import { retrieveMeasurements, storeMeasurements } from './dataExchange';\nimport isToolSupported from './utils/isToolSupported';\n\nconst DICOMSR = {\n retrieveMeasurements,\n storeMeasurements,\n isToolSupported,\n};\n\nexport default DICOMSR;\n","/**\n * VIEWPORT\n */\nexport const SET_VIEWPORT = 'VIEWPORT::SET';\nexport const SET_VIEWPORT_ACTIVE = 'VIEWPORT::SET_ACTIVE';\nexport const SET_VIEWPORT_LAYOUT = 'VIEWPORT::SET_LAYOUT';\nexport const SET_VIEWPORT_LAYOUT_AND_DATA =\n 'VIEWPORT::SET_VIEWPORT_LAYOUT_AND_DATA';\nexport const CLEAR_VIEWPORT = 'VIEWPORT::CLEAR';\nexport const SET_SPECIFIC_DATA = 'VIEWPORT::SET_SPECIFIC_DATA';\nexport const SET_ACTIVE_SPECIFIC_DATA = 'VIEWPORT::SET_ACTIVE_SPECIFIC_DATA';\n\n/**\n * SERVERS\n */\nexport const ADD_SERVER = 'ADD_SERVER';\nexport const SET_SERVERS = 'SET_SERVERS';\n\n/**\n * EXTENSIONS\n */\nexport const SET_EXTENSION_DATA = 'SET_EXTENSION_DATA';\n\n/**\n * PREFERENCES\n * */\nexport const SET_USER_PREFERENCES = 'SET_USER_PREFERENCES';\n","/** Action Creators:\n * https://redux.js.org/basics/actions#action-creators\n */\n\nimport {\n CLEAR_VIEWPORT,\n SET_ACTIVE_SPECIFIC_DATA,\n SET_SERVERS,\n SET_VIEWPORT,\n SET_VIEWPORT_ACTIVE,\n SET_VIEWPORT_LAYOUT,\n SET_VIEWPORT_LAYOUT_AND_DATA,\n SET_USER_PREFERENCES,\n} from './constants/ActionTypes.js';\n\n/**\n * The definition of a viewport layout.\n *\n * @typedef {Object} ViewportLayout\n * @property {number} numRows -\n * @property {number} numColumns -\n * @property {array} viewports -\n */\n\n/**\n * VIEWPORT\n */\nexport const setViewportSpecificData = (\n viewportIndex,\n viewportSpecificData\n) => ({\n type: SET_VIEWPORT,\n viewportIndex,\n viewportSpecificData,\n});\n\nexport const setViewportActive = viewportIndex => ({\n type: SET_VIEWPORT_ACTIVE,\n viewportIndex,\n});\n\n/**\n * @param {ViewportLayout} layout\n */\nexport const setLayout = ({ numRows, numColumns, viewports }) => ({\n type: SET_VIEWPORT_LAYOUT,\n numRows,\n numColumns,\n viewports,\n});\n\n/**\n * @param {number} layout.numRows\n * @param {number} layout.numColumns\n * @param {array} viewports\n */\nexport const setViewportLayoutAndData = (\n { numRows, numColumns, viewports },\n viewportSpecificData\n) => ({\n type: SET_VIEWPORT_LAYOUT_AND_DATA,\n numRows,\n numColumns,\n viewports,\n viewportSpecificData,\n});\n\nexport const clearViewportSpecificData = viewportIndex => ({\n type: CLEAR_VIEWPORT,\n viewportIndex,\n});\n\nexport const setActiveViewportSpecificData = viewportSpecificData => ({\n type: SET_ACTIVE_SPECIFIC_DATA,\n viewportSpecificData,\n});\n\n/**\n * NOT-VIEWPORT\n */\nexport const setUserPreferences = state => ({\n type: SET_USER_PREFERENCES,\n state,\n});\n\nexport const setExtensionData = (extension, data) => ({\n type: 'SET_EXTENSION_DATA',\n extension,\n data,\n});\n\nexport const setTimepoints = state => ({\n type: 'SET_TIMEPOINTS',\n state,\n});\n\nexport const setMeasurements = state => ({\n type: 'SET_MEASUREMENTS',\n state,\n});\n\nexport const setStudyData = (StudyInstanceUID, data) => ({\n type: 'SET_STUDY_DATA',\n StudyInstanceUID,\n data,\n});\n\nexport const setServers = servers => ({\n type: SET_SERVERS,\n servers,\n});\n\nconst actions = {\n /**\n * VIEWPORT\n */\n setViewportActive,\n setViewportSpecificData,\n setViewportLayoutAndData,\n setLayout,\n clearViewportSpecificData,\n setActiveViewportSpecificData,\n /**\n * NOT-VIEWPORT\n */\n setUserPreferences,\n setExtensionData,\n setTimepoints,\n setMeasurements,\n setStudyData,\n setServers,\n};\n\nexport default actions;\n","export const defaultState = {};\n\nconst extensions = (state = defaultState, action) => {\n switch (action.type) {\n case 'SET_EXTENSION_DATA':\n const extensionName = action.extension;\n const currentData = state[extensionName] || {};\n\n const incomingData = action.data;\n\n const extension = {\n [extensionName]: {\n ...currentData,\n ...incomingData,\n },\n };\n\n return { ...state, ...extension };\n\n default:\n return state;\n }\n};\n\nexport default extensions;\n","const defaultState = {\n windowLevelData: {\n 1: { description: 'Soft tissue', window: '550', level: '40' },\n 2: { description: 'Lung', window: '150', level: '-600' },\n 3: { description: 'Liver', window: '150', level: '90' },\n 4: { description: 'Bone', window: '2500', level: '480' },\n 5: { description: 'Brain', window: '80', level: '40' },\n 6: { description: 'Trest', window: '1', level: '1' },\n 7: { description: '', window: '', level: '' },\n 8: { description: '', window: '', level: '' },\n 9: { description: '', window: '', level: '' },\n 10: { description: '', window: '', level: '' },\n },\n generalPreferences: {\n // language: 'en-US'\n },\n};\n\nconst preferences = (state = defaultState, action) => {\n switch (action.type) {\n case 'SET_USER_PREFERENCES': {\n return Object.assign({}, state, action.state);\n }\n default:\n return state;\n }\n};\n\nexport { defaultState };\nexport default preferences;\n","import uniqBy from 'lodash/uniqBy';\n\nexport const defaultState = {\n servers: [],\n};\n\nconst servers = (state = defaultState, action) => {\n switch (action.type) {\n case 'ADD_SERVER':\n let servers = uniqBy([...state.servers, action.server], 'id');\n servers.forEach(s => (s.active = true));\n return { ...state, servers };\n\n case 'ACTIVATE_SERVER': {\n const newServer = { ...action.server, active: true };\n const newServers = state.servers;\n newServers.forEach(s => (s.active = false));\n return {\n ...state,\n servers: uniqBy([...newServers, newServer], 'wadoRoot'),\n };\n }\n\n case 'SET_SERVERS':\n return { ...state, servers: action.servers };\n\n default:\n return state;\n }\n};\n\nexport default servers;\n","import cloneDeep from 'lodash.clonedeep';\n\nconst defaultState = {\n studyData: {},\n};\n\nconst servers = (state = defaultState, action) => {\n switch (action.type) {\n case 'SET_STUDY_DATA': {\n const updatedStudyData = cloneDeep(state.studyData);\n updatedStudyData[action.StudyInstanceUID] = cloneDeep(action.data);\n\n return Object.assign({}, state, { studyData: updatedStudyData });\n }\n default:\n return state;\n }\n};\n\nexport default servers;\n","const defaultState = {\n timepoints: [],\n measurements: [],\n};\n\nconst timepointManager = (state = defaultState, action) => {\n switch (action.type) {\n case 'SET_TIMEPOINTS':\n return Object.assign({}, state, { timepoints: action.state });\n case 'SET_MEASUREMENTS':\n return Object.assign({}, state, { measurements: action.state });\n default:\n return state;\n }\n};\n\nexport default timepointManager;\n","import cloneDeep from 'lodash.clonedeep';\nimport produce, { setAutoFreeze } from 'immer';\n\nimport {\n CLEAR_VIEWPORT,\n SET_ACTIVE_SPECIFIC_DATA,\n SET_SPECIFIC_DATA,\n SET_VIEWPORT,\n SET_VIEWPORT_ACTIVE,\n SET_VIEWPORT_LAYOUT,\n SET_VIEWPORT_LAYOUT_AND_DATA,\n} from './../constants/ActionTypes.js';\n\nsetAutoFreeze(false);\n\nexport const DEFAULT_STATE = {\n numRows: 1,\n numColumns: 1,\n activeViewportIndex: 0,\n layout: {\n viewports: [{}],\n },\n viewportSpecificData: {},\n};\n\n/**\n * Take the new number of Rows and Columns, delete all not used viewport data and also set\n * active viewport as default in case current one is not available anymore.\n *\n * @param {Number} numRows\n * @param {Number} numColumns\n * @param {Object} currentViewportSpecificData\n * @returns\n */\nconst findActiveViewportSpecificData = (\n numRows,\n numColumns,\n currentViewportSpecificData = {}\n) => {\n const numberOfViewports = numRows * numColumns;\n const viewportSpecificData = cloneDeep(currentViewportSpecificData);\n\n if (numberOfViewports < Object.keys(viewportSpecificData).length) {\n Object.keys(viewportSpecificData).forEach(key => {\n if (key > numberOfViewports - 1) {\n delete viewportSpecificData[key];\n }\n });\n }\n\n return viewportSpecificData;\n};\n/**\n * Take new number of Rows and Columns and make sure the current active viewport index is still available, if not, return the default\n *\n * @param {Number} numRows\n * @param {Number} numColumns\n * @param {Number} currentActiveViewportIndex\n * @returns\n */\nconst getActiveViewportIndex = (\n numRows,\n numColumns,\n currentActiveViewportIndex\n) => {\n const numberOfViewports = numRows * numColumns;\n\n return currentActiveViewportIndex > numberOfViewports - 1\n ? DEFAULT_STATE.activeViewportIndex\n : currentActiveViewportIndex;\n};\n\n/**\n * The definition of a viewport action.\n *\n * @typedef {Object} ViewportAction\n * @property {string} type -\n * @property {Object} data -\n * @property {Object} layout -\n * @property {number} viewportIndex -\n * @property {Object} viewportSpecificData -\n */\n\n/**\n * @param {Object} [state=DEFAULT_STATE] The current viewport state.\n * @param {ViewportAction} action A viewport action.\n */\nconst viewports = (state = DEFAULT_STATE, action) => {\n let useActiveViewport = false;\n\n switch (action.type) {\n /**\n * Sets the active viewport index.\n *\n * @return {Object} New state.\n */\n case SET_VIEWPORT_ACTIVE: {\n return produce(state, draftState => {\n draftState.activeViewportIndex = getActiveViewportIndex(\n draftState.numRows,\n draftState.numColumns,\n action.viewportIndex\n );\n });\n }\n\n /**\n * Sets viewport layout.\n *\n * @return {Object} New state.\n */\n case SET_VIEWPORT_LAYOUT: {\n const { numRows, numColumns } = action;\n const viewportSpecificData = findActiveViewportSpecificData(\n numRows,\n numColumns,\n state.viewportSpecificData\n );\n const activeViewportIndex = getActiveViewportIndex(\n numRows,\n numColumns,\n state.activeViewportIndex\n );\n\n return {\n ...state,\n numRows: action.numRows,\n numColumns: action.numColumns,\n layout: { viewports: [...action.viewports] },\n viewportSpecificData,\n activeViewportIndex,\n };\n }\n\n /**\n * Sets viewport layout and data.\n *\n * @return {Object} New state.\n */\n case SET_VIEWPORT_LAYOUT_AND_DATA: {\n const { numRows, numColumns } = action;\n const viewportSpecificData = findActiveViewportSpecificData(\n numRows,\n numColumns,\n action.viewportSpecificData\n );\n const activeViewportIndex = getActiveViewportIndex(\n numRows,\n numColumns,\n state.activeViewportIndex\n );\n\n return {\n ...state,\n numRows: action.numRows,\n numColumns: action.numColumns,\n layout: { viewports: [...action.viewports] },\n viewportSpecificData,\n activeViewportIndex,\n };\n }\n\n /**\n * Sets viewport specific data of active viewport.\n *\n * @return {Object} New state.\n */\n case SET_VIEWPORT: {\n return produce(state, draftState => {\n draftState.viewportSpecificData[action.viewportIndex] =\n draftState.viewportSpecificData[action.viewportIndex] || {};\n\n Object.keys(action.viewportSpecificData).forEach(key => {\n draftState.viewportSpecificData[action.viewportIndex][key] =\n action.viewportSpecificData[key];\n });\n\n if (action.viewportSpecificData && action.viewportSpecificData.plugin) {\n draftState.layout.viewports[action.viewportIndex].plugin =\n action.viewportSpecificData.plugin;\n }\n });\n }\n\n /**\n * Sets viewport specific data of active/any viewport.\n *\n * @return {Object} New state.\n */\n case SET_ACTIVE_SPECIFIC_DATA:\n useActiveViewport = true;\n // Allow fall-through\n // eslint-disable-next-line\n case SET_SPECIFIC_DATA: {\n const layout = cloneDeep(state.layout);\n const viewportIndex = useActiveViewport\n ? state.activeViewportIndex\n : action.viewportIndex;\n\n let viewportSpecificData = cloneDeep(state.viewportSpecificData);\n viewportSpecificData[viewportIndex] = {\n ...action.viewportSpecificData,\n };\n\n if (action.viewportSpecificData && action.viewportSpecificData.plugin) {\n layout.viewports[viewportIndex].plugin =\n action.viewportSpecificData.plugin;\n }\n\n return { ...state, layout, viewportSpecificData };\n }\n\n /**\n * Clears viewport specific data of any viewport.\n *\n * @return {Object} New state.\n */\n case CLEAR_VIEWPORT: {\n let viewportSpecificData = cloneDeep(state.viewportSpecificData);\n\n if (action.viewportIndex) {\n viewportSpecificData[action.viewportIndex] = {};\n return { ...state, viewportSpecificData };\n } else {\n return DEFAULT_STATE;\n }\n }\n\n /**\n * Returns the current application state.\n *\n * @return {Object} The current state.\n */\n default: {\n return state;\n }\n }\n};\n\nexport default viewports;\n","import extensions from './extensions';\nimport preferences from './preferences';\nimport servers from './servers';\nimport studies from './studies';\nimport timepointManager from './timepointManager';\nimport viewports from './viewports';\n\nconst reducers = {\n extensions,\n preferences,\n servers,\n studies,\n timepointManager,\n viewports,\n};\n\nexport default reducers;\n","const LocalStorageApi = window.localStorage;\nconst localStorageKey = 'state';\nexport const loadState = () => {\n try {\n const serializedState = LocalStorageApi.getItem(localStorageKey);\n if (!serializedState) {\n return undefined;\n }\n\n return JSON.parse(serializedState);\n } catch (e) {\n return undefined;\n }\n};\n\nexport const saveState = state => {\n try {\n const serializedState = JSON.stringify(state);\n LocalStorageApi.setItem(localStorageKey, serializedState);\n } catch (e) {}\n};\n\nconst localStorage = {\n saveState,\n loadState,\n};\n\nexport default localStorage;\n","const SessionStorageApi = window.sessionStorage;\nconst sessionStorageKey = 'state';\nexport const loadState = () => {\n try {\n const serializedState = SessionStorageApi.getItem(sessionStorageKey);\n if (!serializedState) {\n return undefined;\n }\n\n return JSON.parse(serializedState);\n } catch (e) {\n return undefined;\n }\n};\n\nexport const saveState = state => {\n try {\n const serializedState = JSON.stringify(state);\n SessionStorageApi.setItem(sessionStorageKey, serializedState);\n } catch (e) {}\n};\n\nconst sessionStorage = {\n saveState,\n loadState,\n};\n\nexport default sessionStorage;\n","import actions from './actions.js';\nimport reducers from './reducers';\nimport localStorage from './localStorage.js';\nimport sessionStorage from './sessionStorage.js';\n\nconst redux = {\n reducers,\n actions,\n localStorage,\n sessionStorage,\n};\n\nexport default redux;\n","import Hammer from 'hammerjs';\nimport cornerstone from 'cornerstone-core';\nimport cornerstoneMath from 'cornerstone-math';\nimport cornerstoneTools from 'cornerstone-tools';\nimport OHIF from '@ohif/core';\n\nconst { log } = OHIF;\n\nexport default function(configuration = {}) {\n // For debugging\n window.cornerstoneTools = cornerstoneTools;\n\n cornerstoneTools.external.cornerstone = cornerstone;\n cornerstoneTools.external.Hammer = Hammer;\n cornerstoneTools.external.cornerstoneMath = cornerstoneMath;\n cornerstoneTools.init(configuration);\n\n cornerstoneTools.loadHandlerManager.setErrorLoadingHandler(\n (element, imageId, error) => {\n log.error(imageId);\n throw error;\n }\n );\n\n // Set the tool font and font size\n // context.font = \"[style] [variant] [weight] [size]/[line height] [font family]\";\n const fontFamily =\n 'Roboto, OpenSans, HelveticaNeue-Light, Helvetica Neue Light, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif';\n cornerstoneTools.textStyle.setFont(`16px ${fontFamily}`);\n\n // Tool styles/colors\n cornerstoneTools.toolStyle.setToolWidth(2);\n cornerstoneTools.toolColors.setToolColor('rgb(255, 255, 0)');\n cornerstoneTools.toolColors.setActiveColor('rgb(0, 255, 0)');\n\n cornerstoneTools.store.state.touchProximity = 40;\n\n // Configure stack prefetch\n cornerstoneTools.stackPrefetch.setConfiguration({\n maxImagesToPrefetch: configuration.maxImagesToPrefetch,\n preserveExistingPool: configuration.preserveExistingPool,\n maxSimultaneousRequests: configuration.maxSimultaneousRequests,\n });\n}\n","import cornerstone from 'cornerstone-core';\n\nconst SUPPORTED_TOOLS = [\n 'Length',\n 'EllipticalRoi',\n 'RectangleRoi',\n 'ArrowAnnotate',\n];\n\nconst measurementServiceMappingsFactory = measurementService => {\n /**\n * Maps measurement service format object to cornerstone annotation object.\n *\n * @param {Measurement} measurement The measurement instance\n * @param {string} definition The source definition\n * @return {Object} Cornerstone annotation data\n */\n const toAnnotation = (measurement, definition) => {\n const {\n id,\n label,\n description,\n points,\n unit,\n SOPInstanceUID,\n FrameOfReferenceUID,\n referenceSeriesUID,\n } = measurement;\n\n return {\n toolName: definition,\n measurementData: {\n sopInstanceUid: SOPInstanceUID,\n frameOfReferenceUID: FrameOfReferenceUID,\n SeriesInstanceUID: referenceSeriesUID,\n unit,\n text: label,\n description,\n handles: _getHandlesFromPoints(points),\n _measurementServiceId: id,\n },\n };\n };\n\n /**\n * Maps cornerstone annotation event data to measurement service format.\n *\n * @param {Object} cornerstone Cornerstone event data\n * @return {Measurement} Measurement instance\n */\n const toMeasurement = csToolsAnnotation => {\n const { element, measurementData } = csToolsAnnotation;\n const tool =\n csToolsAnnotation.toolType ||\n csToolsAnnotation.toolName ||\n measurementData.toolType;\n\n const validToolType = toolName => SUPPORTED_TOOLS.includes(toolName);\n\n if (!validToolType(tool)) {\n throw new Error('Tool not supported');\n }\n\n const {\n SOPInstanceUID,\n FrameOfReferenceUID,\n SeriesInstanceUID,\n } = _getAttributes(element);\n\n const points = [];\n points.push(measurementData.handles);\n\n return {\n id: measurementData._measurementServiceId,\n SOPInstanceUID: SOPInstanceUID,\n FrameOfReferenceUID,\n referenceSeriesUID: SeriesInstanceUID,\n label: measurementData.text,\n description: measurementData.description,\n unit: measurementData.unit,\n area:\n measurementData.cachedStats &&\n measurementData.cachedStats\n .area /* TODO: Add concept names instead (descriptor) */,\n type: _getValueTypeFromToolType(tool),\n points: _getPointsFromHandles(measurementData.handles),\n };\n };\n\n const _getAttributes = element => {\n const enabledElement = cornerstone.getEnabledElement(element);\n const imageId = enabledElement.image.imageId;\n const instance = cornerstone.metaData.get('instance', imageId);\n\n return {\n SOPInstanceUID: instance.SOPInstanceUID,\n FrameOfReferenceUID: instance.FrameOfReferenceUID,\n SeriesInstanceUID: instance.SeriesInstanceUID,\n };\n };\n\n const _getValueTypeFromToolType = toolType => {\n const { POLYLINE, ELLIPSE, POINT } = measurementService.VALUE_TYPES;\n\n /* TODO: Relocate static value types */\n const TOOL_TYPE_TO_VALUE_TYPE = {\n Length: POLYLINE,\n EllipticalRoi: ELLIPSE,\n RectangleRoi: POLYLINE,\n ArrowAnnotate: POINT,\n };\n\n return TOOL_TYPE_TO_VALUE_TYPE[toolType];\n };\n\n const _getPointsFromHandles = handles => {\n let points = [];\n Object.keys(handles).map(handle => {\n if (['start', 'end'].includes(handle)) {\n let point = {};\n if (handles[handle].x) point.x = handles[handle].x;\n if (handles[handle].y) point.y = handles[handle].y;\n points.push(point);\n }\n });\n return points;\n };\n\n const _getHandlesFromPoints = points => {\n return points\n .map((p, i) => (i % 10 === 0 ? { start: p } : { end: p }))\n .reduce((obj, item) => Object.assign(obj, { ...item }), {});\n };\n\n return {\n toAnnotation,\n toMeasurement,\n };\n};\n\nexport default measurementServiceMappingsFactory;\n","import cornerstone from 'cornerstone-core';\n\nconst state = {\n TrackingUniqueIdentifier: null,\n trackingIdentifiersByEnabledElementUUID: {},\n};\n\nfunction setTrackingUniqueIdentifiersForElement(\n element,\n trackingUniqueIdentifiers,\n activeIndex = 0\n) {\n const enabledElement = cornerstone.getEnabledElement(element);\n const { uuid } = enabledElement;\n\n state.trackingIdentifiersByEnabledElementUUID[uuid] = {\n trackingUniqueIdentifiers,\n activeIndex,\n };\n}\n\nfunction setActiveTrackingUniqueIdentifierForElement(\n element,\n TrackingUniqueIdentifier\n) {\n const enabledElement = cornerstone.getEnabledElement(element);\n const { uuid } = enabledElement;\n\n const trackingIdentifiersForElement =\n state.trackingIdentifiersByEnabledElementUUID[uuid];\n\n if (trackingIdentifiersForElement) {\n const activeIndex = trackingIdentifiersForElement.trackingUniqueIdentifiers.findIndex(\n tuid => tuid === TrackingUniqueIdentifier\n );\n\n trackingIdentifiersForElement.activeIndex = activeIndex;\n }\n}\n\nfunction getTrackingUniqueIdentifiersForElement(element) {\n const enabledElement = cornerstone.getEnabledElement(element);\n const { uuid } = enabledElement;\n\n if (state.trackingIdentifiersByEnabledElementUUID[uuid]) {\n return state.trackingIdentifiersByEnabledElementUUID[uuid];\n }\n\n return { trackingUniqueIdentifiers: [] };\n}\n\nexport default {\n state,\n getters: {\n trackingUniqueIdentifiersForElement: getTrackingUniqueIdentifiersForElement,\n },\n setters: {\n trackingUniqueIdentifiersForElement: setTrackingUniqueIdentifiersForElement,\n activeTrackingUniqueIdentifierForElement: setActiveTrackingUniqueIdentifierForElement,\n },\n};\n","import OHIF from '@ohif/core';\nimport { SimpleDialog } from '@ohif/ui';\nimport cornerstone from 'cornerstone-core';\nimport csTools from 'cornerstone-tools';\nimport merge from 'lodash.merge';\nimport initCornerstoneTools from './initCornerstoneTools.js';\nimport measurementServiceMappingsFactory from './utils/measurementServiceMappings/measurementServiceMappingsFactory';\nimport dicomSRModule from './tools/modules/dicomSRModule';\nimport srModuleId from './tools/id';\n\n/**\n *\n * @param {Object} servicesManager\n * @param {Object} configuration\n * @param {Object|Array} configuration.csToolsConfig\n */\nexport default function init({ servicesManager, configuration }) {\n const { UIDialogService, MeasurementService } = servicesManager.services;\n\n csTools.register('module', srModuleId, dicomSRModule);\n\n const callInputDialog = (data, event, callback) => {\n if (UIDialogService) {\n let dialogId = UIDialogService.create({\n centralize: true,\n isDraggable: false,\n content: SimpleDialog.InputDialog,\n useLastPosition: false,\n showOverlay: true,\n contentProps: {\n title: 'Enter your annotation',\n label: 'New label',\n measurementData: data ? { description: data.text } : {},\n onClose: () => UIDialogService.dismiss({ id: dialogId }),\n onSubmit: value => {\n callback(value);\n UIDialogService.dismiss({ id: dialogId });\n },\n },\n });\n }\n };\n\n const {\n csToolsConfig,\n stackPrefetch = {\n maxImagesToPrefetch: Infinity,\n preserveExistingPool: false,\n maxSimultaneousRequests: 20,\n },\n } = configuration;\n const metadataProvider = OHIF.cornerstone.metadataProvider;\n\n cornerstone.metaData.addProvider(\n metadataProvider.get.bind(metadataProvider),\n 9999\n );\n\n // ~~\n const defaultCsToolsConfig = csToolsConfig || {\n globalToolSyncEnabled: true,\n showSVGCursors: true,\n autoResizeViewports: false,\n };\n\n initCornerstoneTools({ ...defaultCsToolsConfig, ...stackPrefetch });\n\n const toolsGroupedByType = {\n touch: [csTools.PanMultiTouchTool, csTools.ZoomTouchPinchTool],\n annotations: [\n csTools.ArrowAnnotateTool,\n csTools.BidirectionalTool,\n csTools.LengthTool,\n csTools.AngleTool,\n csTools.FreehandRoiTool,\n csTools.EllipticalRoiTool,\n csTools.DragProbeTool,\n csTools.RectangleRoiTool,\n ],\n other: [\n csTools.PanTool,\n csTools.ZoomTool,\n csTools.WwwcTool,\n csTools.WwwcRegionTool,\n csTools.MagnifyTool,\n csTools.StackScrollTool,\n csTools.StackScrollMouseWheelTool,\n csTools.OverlayTool,\n ],\n };\n\n let tools = [];\n Object.keys(toolsGroupedByType).forEach(toolsGroup =>\n tools.push(...toolsGroupedByType[toolsGroup])\n );\n\n /* Measurement Service */\n _connectToolsToMeasurementService(MeasurementService);\n\n /* Add extension tools configuration here. */\n const internalToolsConfig = {\n ArrowAnnotate: {\n configuration: {\n getTextCallback: (callback, eventDetails) =>\n callInputDialog(null, eventDetails, callback),\n changeTextCallback: (data, eventDetails, callback) =>\n callInputDialog(data, eventDetails, callback),\n },\n },\n };\n\n /* Abstract tools configuration using extension configuration. */\n const parseToolProps = (props, tool) => {\n const { annotations } = toolsGroupedByType;\n // An alternative approach would be to remove the `drawHandlesOnHover` config\n // from the supported configuration properties in `cornerstone-tools`\n const toolsWithHideableHandles = annotations.filter(\n tool => !['RectangleRoiTool', 'EllipticalRoiTool'].includes(tool.name)\n );\n\n let parsedProps = { ...props };\n\n /**\n * drawHandles - Never/Always show handles\n * drawHandlesOnHover - Only show handles on handle hover (pointNearHandle)\n *\n * Does not apply to tools where handles aren't placed in predictable\n * locations.\n */\n if (\n configuration.hideHandles !== false &&\n toolsWithHideableHandles.includes(tool)\n ) {\n if (props.configuration) {\n parsedProps.configuration.drawHandlesOnHover = true;\n } else {\n parsedProps.configuration = { drawHandlesOnHover: true };\n }\n }\n\n return parsedProps;\n };\n\n /* Add tools with its custom props through extension configuration. */\n tools.forEach(tool => {\n const toolName = tool.name.replace('Tool', '');\n const externalToolsConfig = configuration.tools || {};\n const externalToolProps = externalToolsConfig[toolName] || {};\n const internalToolProps = internalToolsConfig[toolName] || {};\n const props = merge(\n internalToolProps,\n parseToolProps(externalToolProps, tool)\n );\n csTools.addTool(tool, props);\n });\n\n // TODO -> We need a better way to do this with maybe global tool state setting all tools passive.\n const BaseAnnotationTool = csTools.importInternal('base/BaseAnnotationTool');\n tools.forEach(tool => {\n if (tool.prototype instanceof BaseAnnotationTool) {\n // BaseAnnotationTool would likely come from csTools lib exports\n const toolName = new tool().name;\n csTools.setToolPassive(toolName); // there may be a better place to determine name; may not be on uninstantiated class\n }\n });\n\n csTools.setToolActive('Pan', { mouseButtonMask: 4 });\n csTools.setToolActive('Zoom', { mouseButtonMask: 2 });\n csTools.setToolActive('Wwwc', { mouseButtonMask: 1 });\n csTools.setToolActive('StackScrollMouseWheel', {}); // TODO: Empty options should not be required\n csTools.setToolActive('PanMultiTouch', { pointers: 2 }); // TODO: Better error if no options\n csTools.setToolActive('ZoomTouchPinch', {});\n csTools.setToolEnabled('Overlay', {});\n}\n\nconst _initMeasurementService = measurementService => {\n /* Initialization */\n const { toAnnotation, toMeasurement } = measurementServiceMappingsFactory(\n measurementService\n );\n const csToolsVer4MeasurementSource = measurementService.createSource(\n 'CornerstoneTools',\n '4'\n );\n\n /* Matching Criterias */\n const matchingCriteria = {\n valueType: measurementService.VALUE_TYPES.POLYLINE,\n points: 2,\n };\n\n /* Mappings */\n measurementService.addMapping(\n csToolsVer4MeasurementSource,\n 'Length',\n matchingCriteria,\n toAnnotation,\n toMeasurement\n );\n\n return csToolsVer4MeasurementSource;\n};\n\nconst _connectToolsToMeasurementService = measurementService => {\n const csToolsVer4MeasurementSource = _initMeasurementService(\n measurementService\n );\n const {\n id: sourceId,\n addOrUpdate,\n getAnnotation,\n } = csToolsVer4MeasurementSource;\n\n /* Measurement Service Events */\n cornerstone.events.addEventListener(\n cornerstone.EVENTS.ELEMENT_ENABLED,\n event => {\n const {\n MEASUREMENT_ADDED,\n MEASUREMENT_UPDATED,\n } = measurementService.EVENTS;\n\n measurementService.subscribe(\n MEASUREMENT_ADDED,\n ({ source, measurement }) => {\n if (![sourceId].includes(source.id)) {\n const annotation = getAnnotation('Length', measurement.id);\n\n console.log(\n 'Measurement Service [Cornerstone]: Measurement added',\n measurement\n );\n console.log('Mapped annotation:', annotation);\n }\n }\n );\n\n measurementService.subscribe(\n MEASUREMENT_UPDATED,\n ({ source, measurement }) => {\n if (![sourceId].includes(source.id)) {\n const annotation = getAnnotation('Length', measurement.id);\n\n console.log(\n 'Measurement Service [Cornerstone]: Measurement updated',\n measurement\n );\n console.log('Mapped annotation:', annotation);\n }\n }\n );\n\n const addOrUpdateMeasurement = csToolsAnnotation => {\n try {\n const { toolName, toolType, measurementData } = csToolsAnnotation;\n const csTool = toolName || measurementData.toolType || toolType;\n csToolsAnnotation.id = measurementData._measurementServiceId;\n const measurementServiceId = addOrUpdate(csTool, csToolsAnnotation);\n\n if (!measurementData._measurementServiceId) {\n addMeasurementServiceId(measurementServiceId, csToolsAnnotation);\n }\n } catch (error) {\n console.warn('Failed to add or update measurement:', error);\n }\n };\n\n const addMeasurementServiceId = (id, csToolsAnnotation) => {\n const { measurementData } = csToolsAnnotation;\n Object.assign(measurementData, { _measurementServiceId: id });\n };\n\n [\n csTools.EVENTS.MEASUREMENT_ADDED,\n csTools.EVENTS.MEASUREMENT_MODIFIED,\n ].forEach(csToolsEvtName => {\n event.detail.element.addEventListener(\n csToolsEvtName,\n ({ detail: csToolsAnnotation }) => {\n console.log(`Cornerstone Element Event: ${csToolsEvtName}`);\n addOrUpdateMeasurement(csToolsAnnotation);\n }\n );\n });\n }\n );\n};\n","import { redux } from '@ohif/core';\n\nconst { setLayout } = redux.actions;\n\n/**\n * Update the current layout with a simple Cornerstone one\n *\n * @return void\n */\nconst setCornerstoneLayout = () => {\n const layout = {\n numRows: 1,\n numColumns: 1,\n viewports: [{ plugin: 'cornerstone' }],\n };\n\n const action = setLayout(layout);\n\n window.store.dispatch(action);\n}\n\nexport default setCornerstoneLayout;\n","import React from 'react';\nimport cornerstone from 'cornerstone-core';\nimport cornerstoneTools from 'cornerstone-tools';\nimport PropTypes from 'prop-types';\n\nimport { ViewportDownloadForm } from '@ohif/ui';\nimport { utils } from '@ohif/core';\n\nimport { getEnabledElement } from './state';\n\nconst MINIMUM_SIZE = 100;\nconst DEFAULT_SIZE = 512;\nconst MAX_TEXTURE_SIZE = 10000;\n\nconst CornerstoneViewportDownloadForm = ({ onClose, activeViewportIndex }) => {\n const activeEnabledElement = getEnabledElement(activeViewportIndex);\n\n const enableViewport = viewportElement => {\n if (viewportElement) {\n cornerstone.enable(viewportElement);\n }\n };\n\n const disableViewport = viewportElement => {\n if (viewportElement) {\n cornerstone.disable(viewportElement);\n }\n };\n\n const updateViewportPreview = (viewportElement, downloadCanvas, fileType) =>\n new Promise(resolve => {\n cornerstone.fitToWindow(viewportElement);\n\n viewportElement.addEventListener(\n 'cornerstoneimagerendered',\n function updateViewport(event) {\n const enabledElement = cornerstone.getEnabledElement(event.target)\n .element;\n const type = 'image/' + fileType;\n const dataUrl = downloadCanvas.toDataURL(type, 1);\n\n let newWidth = enabledElement.offsetHeight;\n let newHeight = enabledElement.offsetWidth;\n\n if (newWidth > DEFAULT_SIZE || newHeight > DEFAULT_SIZE) {\n const multiplier = DEFAULT_SIZE / Math.max(newWidth, newHeight);\n newHeight *= multiplier;\n newWidth *= multiplier;\n }\n\n resolve({ dataUrl, width: newWidth, height: newHeight });\n\n viewportElement.removeEventListener(\n 'cornerstoneimagerendered',\n updateViewport\n );\n }\n );\n });\n\n const loadImage = (activeViewport, viewportElement, width, height) =>\n new Promise(resolve => {\n if (activeViewport && viewportElement) {\n const enabledElement = cornerstone.getEnabledElement(activeViewport);\n const viewport = Object.assign({}, enabledElement.viewport);\n delete viewport.scale;\n viewport.translation = {\n x: 0,\n y: 0,\n };\n\n cornerstone.loadImage(enabledElement.image.imageId).then(image => {\n cornerstone.displayImage(viewportElement, image);\n cornerstone.setViewport(viewportElement, viewport);\n cornerstone.resize(viewportElement, true);\n\n const newWidth = Math.min(width || image.width, MAX_TEXTURE_SIZE);\n const newHeight = Math.min(height || image.height, MAX_TEXTURE_SIZE);\n\n resolve({ image, width: newWidth, height: newHeight });\n });\n }\n });\n\n const toggleAnnotations = (toggle, viewportElement) => {\n cornerstoneTools.store.state.tools.forEach(({ name }) => {\n if (toggle) {\n cornerstoneTools.setToolEnabledForElement(viewportElement, name);\n } else {\n cornerstoneTools.setToolDisabledForElement(viewportElement, name);\n }\n });\n };\n\n const downloadBlob = (\n filename,\n fileType,\n viewportElement,\n downloadCanvas\n ) => {\n const file = `${filename}.${fileType}`;\n const mimetype = `image/${fileType}`;\n\n /* Handles JPEG images for IE11 */\n if (downloadCanvas.msToBlob && fileType === 'jpeg') {\n const image = downloadCanvas.toDataURL(mimetype, 1);\n const blob = utils.b64toBlob(\n image.replace('data:image/jpeg;base64,', ''),\n mimetype\n );\n return window.navigator.msSaveBlob(blob, file);\n }\n\n viewportElement.querySelector('canvas').toBlob(blob => {\n const URLObj = window.URL || window.webkitURL;\n const a = document.createElement('a');\n a.href = URLObj.createObjectURL(blob);\n a.download = file;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n });\n };\n\n return (\n \n );\n};\n\nCornerstoneViewportDownloadForm.propTypes = {\n onClose: PropTypes.func,\n activeViewportIndex: PropTypes.number.isRequired,\n};\n\nexport default CornerstoneViewportDownloadForm;\n","import cornerstone from 'cornerstone-core';\nimport cornerstoneTools from 'cornerstone-tools';\nimport OHIF from '@ohif/core';\n\nimport setCornerstoneLayout from './utils/setCornerstoneLayout.js';\nimport { getEnabledElement } from './state';\nimport CornerstoneViewportDownloadForm from './CornerstoneViewportDownloadForm';\nconst scroll = cornerstoneTools.import('util/scroll');\n\nconst { studyMetadataManager } = OHIF.utils;\nconst { setViewportSpecificData } = OHIF.redux.actions;\n\nconst refreshCornerstoneViewports = () => {\n cornerstone.getEnabledElements().forEach(enabledElement => {\n if (enabledElement.image) {\n cornerstone.updateImage(enabledElement.element);\n }\n });\n};\n\nconst commandsModule = ({ servicesManager }) => {\n const actions = {\n rotateViewport: ({ viewports, rotation }) => {\n const enabledElement = getEnabledElement(viewports.activeViewportIndex);\n\n if (enabledElement) {\n let viewport = cornerstone.getViewport(enabledElement);\n viewport.rotation += rotation;\n cornerstone.setViewport(enabledElement, viewport);\n }\n },\n flipViewportHorizontal: ({ viewports }) => {\n const enabledElement = getEnabledElement(viewports.activeViewportIndex);\n\n if (enabledElement) {\n let viewport = cornerstone.getViewport(enabledElement);\n viewport.hflip = !viewport.hflip;\n cornerstone.setViewport(enabledElement, viewport);\n }\n },\n flipViewportVertical: ({ viewports }) => {\n const enabledElement = getEnabledElement(viewports.activeViewportIndex);\n\n if (enabledElement) {\n let viewport = cornerstone.getViewport(enabledElement);\n viewport.vflip = !viewport.vflip;\n cornerstone.setViewport(enabledElement, viewport);\n }\n },\n scaleViewport: ({ direction, viewports }) => {\n const enabledElement = getEnabledElement(viewports.activeViewportIndex);\n const step = direction * 0.15;\n\n if (enabledElement) {\n if (step) {\n let viewport = cornerstone.getViewport(enabledElement);\n viewport.scale += step;\n cornerstone.setViewport(enabledElement, viewport);\n } else {\n cornerstone.fitToWindow(enabledElement);\n }\n }\n },\n resetViewport: ({ viewports }) => {\n const enabledElement = getEnabledElement(viewports.activeViewportIndex);\n\n if (enabledElement) {\n cornerstone.reset(enabledElement);\n }\n },\n invertViewport: ({ viewports }) => {\n const enabledElement = getEnabledElement(viewports.activeViewportIndex);\n\n if (enabledElement) {\n let viewport = cornerstone.getViewport(enabledElement);\n viewport.invert = !viewport.invert;\n cornerstone.setViewport(enabledElement, viewport);\n }\n },\n // TODO: this is receiving `evt` from `ToolbarRow`. We could use it to have\n // better mouseButtonMask sets.\n setToolActive: ({ toolName }) => {\n if (!toolName) {\n console.warn('No toolname provided to setToolActive command');\n }\n cornerstoneTools.setToolActive(toolName, { mouseButtonMask: 1 });\n },\n clearAnnotations: ({ viewports }) => {\n const element = getEnabledElement(viewports.activeViewportIndex);\n if (!element) {\n return;\n }\n\n const enabledElement = cornerstone.getEnabledElement(element);\n if (!enabledElement || !enabledElement.image) {\n return;\n }\n\n const {\n toolState,\n } = cornerstoneTools.globalImageIdSpecificToolStateManager;\n if (\n !toolState ||\n toolState.hasOwnProperty(enabledElement.image.imageId) === false\n ) {\n return;\n }\n\n const imageIdToolState = toolState[enabledElement.image.imageId];\n\n const measurementsToRemove = [];\n\n Object.keys(imageIdToolState).forEach(toolType => {\n const { data } = imageIdToolState[toolType];\n\n data.forEach(measurementData => {\n const {\n _id,\n lesionNamingNumber,\n measurementNumber,\n } = measurementData;\n if (!_id) {\n return;\n }\n\n measurementsToRemove.push({\n toolType,\n _id,\n lesionNamingNumber,\n measurementNumber,\n });\n });\n });\n\n measurementsToRemove.forEach(measurementData => {\n OHIF.measurements.MeasurementHandlers.onRemoved({\n detail: {\n toolType: measurementData.toolType,\n measurementData,\n },\n });\n });\n },\n nextImage: ({ viewports }) => {\n const enabledElement = getEnabledElement(viewports.activeViewportIndex);\n scroll(enabledElement, 1);\n },\n previousImage: ({ viewports }) => {\n const enabledElement = getEnabledElement(viewports.activeViewportIndex);\n scroll(enabledElement, -1);\n },\n getActiveViewportEnabledElement: ({ viewports }) => {\n const enabledElement = getEnabledElement(viewports.activeViewportIndex);\n return enabledElement;\n },\n showDownloadViewportModal: ({ title, viewports }) => {\n const activeViewportIndex = viewports.activeViewportIndex;\n const { UIModalService } = servicesManager.services;\n if (UIModalService) {\n UIModalService.show({\n content: CornerstoneViewportDownloadForm,\n title,\n contentProps: {\n activeViewportIndex,\n onClose: UIModalService.hide,\n },\n });\n }\n },\n updateTableWithNewMeasurementData({\n toolType,\n measurementNumber,\n location,\n description,\n }) {\n // Update all measurements by measurement number\n const measurementApi = OHIF.measurements.MeasurementApi.Instance;\n const measurements = measurementApi.tools[toolType].filter(\n m => m.measurementNumber === measurementNumber\n );\n\n measurements.forEach(measurement => {\n measurement.location = location;\n measurement.description = description;\n\n measurementApi.updateMeasurement(measurement.toolType, measurement);\n });\n\n measurementApi.syncMeasurementsAndToolData();\n\n refreshCornerstoneViewports();\n },\n getNearbyToolData({ element, canvasCoordinates, availableToolTypes }) {\n const nearbyTool = {};\n let pointNearTool = false;\n\n availableToolTypes.forEach(toolType => {\n const elementToolData = cornerstoneTools.getToolState(\n element,\n toolType\n );\n\n if (!elementToolData) {\n return;\n }\n\n elementToolData.data.forEach((toolData, index) => {\n let elementToolInstance = cornerstoneTools.getToolForElement(\n element,\n toolType\n );\n\n if (!elementToolInstance) {\n elementToolInstance = cornerstoneTools.getToolForElement(\n element,\n `${toolType}Tool`\n );\n }\n\n if (!elementToolInstance) {\n console.warn('Tool not found.');\n return undefined;\n }\n\n if (\n elementToolInstance.pointNearTool(\n element,\n toolData,\n canvasCoordinates\n )\n ) {\n pointNearTool = true;\n nearbyTool.tool = toolData;\n nearbyTool.index = index;\n nearbyTool.toolType = toolType;\n }\n });\n\n if (pointNearTool) {\n return false;\n }\n });\n\n return pointNearTool ? nearbyTool : undefined;\n },\n removeToolState: ({ element, toolType, tool }) => {\n cornerstoneTools.removeToolState(element, toolType, tool);\n cornerstone.updateImage(element);\n },\n setCornerstoneLayout: () => {\n setCornerstoneLayout();\n },\n setWindowLevel: ({ viewports, window, level }) => {\n const enabledElement = getEnabledElement(viewports.activeViewportIndex);\n\n if (enabledElement) {\n let viewport = cornerstone.getViewport(enabledElement);\n\n viewport.voi = {\n windowWidth: Number(window),\n windowCenter: Number(level),\n };\n cornerstone.setViewport(enabledElement, viewport);\n }\n },\n jumpToImage: ({\n StudyInstanceUID,\n SOPInstanceUID,\n frameIndex,\n activeViewportIndex,\n refreshViewports = true,\n }) => {\n const study = studyMetadataManager.get(StudyInstanceUID);\n\n const displaySet = study.findDisplaySet(ds => {\n return (\n ds.images &&\n ds.images.find(i => i.getSOPInstanceUID() === SOPInstanceUID)\n );\n });\n\n if (!displaySet) {\n return;\n }\n\n displaySet.SOPInstanceUID = SOPInstanceUID;\n displaySet.frameIndex = frameIndex;\n\n window.store.dispatch(\n setViewportSpecificData(activeViewportIndex, displaySet)\n );\n\n if (refreshViewports) {\n refreshCornerstoneViewports();\n }\n },\n };\n\n const definitions = {\n jumpToImage: {\n commandFn: actions.jumpToImage,\n storeContexts: [],\n options: {},\n },\n getNearbyToolData: {\n commandFn: actions.getNearbyToolData,\n storeContexts: [],\n options: {},\n },\n removeToolState: {\n commandFn: actions.removeToolState,\n storeContexts: [],\n options: {},\n },\n updateTableWithNewMeasurementData: {\n commandFn: actions.updateTableWithNewMeasurementData,\n storeContexts: [],\n options: {},\n },\n showDownloadViewportModal: {\n commandFn: actions.showDownloadViewportModal,\n storeContexts: ['viewports'],\n options: {},\n },\n getActiveViewportEnabledElement: {\n commandFn: actions.getActiveViewportEnabledElement,\n storeContexts: ['viewports'],\n options: {},\n },\n rotateViewportCW: {\n commandFn: actions.rotateViewport,\n storeContexts: ['viewports'],\n options: { rotation: 90 },\n },\n rotateViewportCCW: {\n commandFn: actions.rotateViewport,\n storeContexts: ['viewports'],\n options: { rotation: -90 },\n },\n invertViewport: {\n commandFn: actions.invertViewport,\n storeContexts: ['viewports'],\n options: {},\n },\n flipViewportVertical: {\n commandFn: actions.flipViewportVertical,\n storeContexts: ['viewports'],\n options: {},\n },\n flipViewportHorizontal: {\n commandFn: actions.flipViewportHorizontal,\n storeContexts: ['viewports'],\n options: {},\n },\n scaleUpViewport: {\n commandFn: actions.scaleViewport,\n storeContexts: ['viewports'],\n options: { direction: 1 },\n },\n scaleDownViewport: {\n commandFn: actions.scaleViewport,\n storeContexts: ['viewports'],\n options: { direction: -1 },\n },\n fitViewportToWindow: {\n commandFn: actions.scaleViewport,\n storeContexts: ['viewports'],\n options: { direction: 0 },\n },\n resetViewport: {\n commandFn: actions.resetViewport,\n storeContexts: ['viewports'],\n options: {},\n },\n clearAnnotations: {\n commandFn: actions.clearAnnotations,\n storeContexts: ['viewports'],\n options: {},\n },\n nextImage: {\n commandFn: actions.nextImage,\n storeContexts: ['viewports'],\n options: {},\n },\n previousImage: {\n commandFn: actions.previousImage,\n storeContexts: ['viewports'],\n options: {},\n },\n // TOOLS\n setToolActive: {\n commandFn: actions.setToolActive,\n storeContexts: [],\n options: {},\n },\n setZoomTool: {\n commandFn: actions.setToolActive,\n storeContexts: [],\n options: { toolName: 'Zoom' },\n },\n setCornerstoneLayout: {\n commandFn: actions.setCornerstoneLayout,\n storeContexts: [],\n options: {},\n context: 'VIEWER',\n },\n setWindowLevel: {\n commandFn: actions.setWindowLevel,\n storeContexts: ['viewports'],\n options: {},\n },\n };\n\n return {\n actions,\n definitions,\n defaultContext: 'ACTIVE_VIEWPORT::CORNERSTONE',\n };\n};\n\nexport default commandsModule;\n","// TODO: A way to add Icons that don't already exist?\n// - Register them and add\n// - Include SVG Source/Inline?\n// - By URL, or own component?\n\n// What KINDS of toolbar buttons do we have...\n// - One's that dispatch commands\n// - One's that set tool's active\n// - More custom, like CINE\n// - Built in for one's like this, or custom components?\n\n// Visible?\n// Disabled?\n// Based on contexts or misc. criteria?\n// -- ACTIVE_ROUTE::VIEWER\n// -- ACTIVE_VIEWPORT::CORNERSTONE\n// setToolActive commands should receive the button event that triggered\n// so we can do the \"bind to this button\" magic\n\nconst TOOLBAR_BUTTON_TYPES = {\n COMMAND: 'command',\n SET_TOOL_ACTIVE: 'setToolActive',\n BUILT_IN: 'builtIn',\n};\n\nconst TOOLBAR_BUTTON_BEHAVIORS = {\n CINE: 'CINE',\n DOWNLOAD_SCREEN_SHOT: 'DOWNLOAD_SCREEN_SHOT',\n};\n\n/* TODO: Export enums through a extension manager. */\nconst enums = {\n TOOLBAR_BUTTON_TYPES,\n TOOLBAR_BUTTON_BEHAVIORS,\n};\n\nconst definitions = [\n {\n id: 'StackScroll',\n label: 'Stack Scroll',\n icon: 'bars',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'StackScroll' },\n },\n {\n id: 'Zoom',\n label: 'Zoom',\n icon: 'search-plus',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'Zoom' },\n },\n {\n id: 'Wwwc',\n label: 'Levels',\n icon: 'level',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'Wwwc' },\n },\n {\n id: 'Pan',\n label: 'Pan',\n icon: 'arrows',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'Pan' },\n },\n {\n id: 'Length',\n label: 'Length',\n icon: 'measure-temp',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'Length' },\n },\n {\n id: 'ArrowAnnotate',\n label: 'Annotate',\n icon: 'measure-non-target',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'ArrowAnnotate' },\n },\n {\n id: 'Angle',\n label: 'Angle',\n icon: 'angle-left',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'Angle' },\n },\n {\n id: 'Reset',\n label: 'Reset',\n icon: 'reset',\n //\n type: TOOLBAR_BUTTON_TYPES.COMMAND,\n commandName: 'resetViewport',\n },\n {\n id: 'Cine',\n label: 'CINE',\n icon: 'youtube',\n //\n type: TOOLBAR_BUTTON_TYPES.BUILT_IN,\n options: {\n behavior: TOOLBAR_BUTTON_BEHAVIORS.CINE,\n },\n },\n {\n id: 'More',\n label: 'More',\n icon: 'ellipse-circle',\n buttons: [\n {\n id: 'Magnify',\n label: 'Magnify',\n icon: 'circle',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'Magnify' },\n },\n {\n id: 'WwwcRegion',\n label: 'ROI Window',\n icon: 'stop',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'WwwcRegion' },\n },\n {\n id: 'DragProbe',\n label: 'Probe',\n icon: 'dot-circle',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'DragProbe' },\n },\n {\n id: 'EllipticalRoi',\n label: 'Ellipse',\n icon: 'circle-o',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'EllipticalRoi' },\n },\n {\n id: 'RectangleRoi',\n label: 'Rectangle',\n icon: 'square-o',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'RectangleRoi' },\n },\n {\n id: 'Invert',\n label: 'Invert',\n icon: 'adjust',\n //\n type: TOOLBAR_BUTTON_TYPES.COMMAND,\n commandName: 'invertViewport',\n },\n {\n id: 'RotateRight',\n label: 'Rotate Right',\n icon: 'rotate-right',\n //\n type: TOOLBAR_BUTTON_TYPES.COMMAND,\n commandName: 'rotateViewportCW',\n },\n {\n id: 'FlipH',\n label: 'Flip H',\n icon: 'ellipse-h',\n //\n type: TOOLBAR_BUTTON_TYPES.COMMAND,\n commandName: 'flipViewportHorizontal',\n },\n {\n id: 'FlipV',\n label: 'Flip V',\n icon: 'ellipse-v',\n //\n type: TOOLBAR_BUTTON_TYPES.COMMAND,\n commandName: 'flipViewportVertical',\n },\n {\n id: 'Clear',\n label: 'Clear',\n icon: 'trash',\n //\n type: TOOLBAR_BUTTON_TYPES.COMMAND,\n commandName: 'clearAnnotations',\n },\n {\n id: 'Bidirectional',\n label: 'Bidirectional',\n icon: 'measure-target',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'Bidirectional' },\n },\n {\n id: 'Download',\n label: 'Download',\n icon: 'create-screen-capture',\n //\n type: TOOLBAR_BUTTON_TYPES.BUILT_IN,\n options: {\n behavior: TOOLBAR_BUTTON_BEHAVIORS.DOWNLOAD_SCREEN_SHOT,\n togglable: true,\n },\n },\n ],\n },\n {\n id: 'Exit2DMPR',\n label: 'Exit 2D MPR',\n icon: 'times',\n //\n type: TOOLBAR_BUTTON_TYPES.COMMAND,\n commandName: 'setCornerstoneLayout',\n context: 'ACTIVE_VIEWPORT::VTK',\n },\n];\n\nexport default {\n definitions,\n defaultContext: 'ACTIVE_VIEWPORT::CORNERSTONE',\n};\n","import React from 'react';\nimport init from './init.js';\nimport commandsModule from './commandsModule.js';\nimport toolbarModule from './toolbarModule.js';\nimport CornerstoneViewportDownloadForm from './CornerstoneViewportDownloadForm';\nimport { version } from '../package.json';\n\nconst Component = React.lazy(() => {\n return import('./OHIFCornerstoneViewport');\n});\n\nconst OHIFCornerstoneViewport = props => {\n return (\n Loading...
    }>\n \n \n );\n};\n\n/**\n *\n */\nexport default {\n /**\n * Only required property. Should be a unique value across all extensions.\n */\n id: 'cornerstone',\n version,\n\n /**\n *\n *\n * @param {object} [configuration={}]\n * @param {object|array} [configuration.csToolsConfig] - Passed directly to `initCornerstoneTools`\n */\n preRegistration({ servicesManager, configuration = {} }) {\n init({ servicesManager, configuration });\n },\n getViewportModule({ commandsManager, appConfig }) {\n const ExtendedOHIFCornerstoneViewport = props => {\n /**\n * TODO: This appears to be used to set the redux parameters for\n * the viewport when new images are loaded. It's very ugly\n * and we should remove it.\n */\n const onNewImageHandler = jumpData => {\n /** Do not trigger all viewports to render unnecessarily */\n jumpData.refreshViewports = false;\n commandsManager.runCommand('jumpToImage', jumpData);\n };\n\n const { studyPrefetcher } = appConfig;\n const isStackPrefetchEnabled =\n studyPrefetcher && !studyPrefetcher.enabled;\n\n return (\n \n );\n };\n\n return ExtendedOHIFCornerstoneViewport;\n },\n getToolbarModule() {\n return toolbarModule;\n },\n getCommandsModule({ servicesManager }) {\n return commandsModule({ servicesManager });\n },\n};\n\nexport { CornerstoneViewportDownloadForm };\n","export default '0.0.50';\n","// https://github.com/maxmantz/redux-oidc/blob/master/docs/API.md\nimport { loadUser, createUserManager } from 'redux-oidc';\n\n/**\n * Creates a userManager from oidcSettings;\n * loads the user into the provided redux store\n * LINK: https://github.com/IdentityModel/oidc-client-js/wiki#configuration\n *\n * @param {*} store\n * @param {Object} oidcSettings\n * @param {string} oidcSettings.authServerUrl,\n * @param {string} oidcSettings.clientId,\n * @param {string} oidcSettings.authRedirectUri,\n * @param {string} oidcSettings.postLogoutRedirectUri,\n * @param {string} oidcSettings.responseType,\n * @param {string} oidcSettings.extraQueryParams,\n */\nexport default function(store, oidcSettings) {\n if (!store || !oidcSettings) {\n return;\n }\n\n const settings = {\n ...oidcSettings,\n automaticSilentRenew: true,\n revokeAccessTokenOnSignout: true,\n filterProtocolClaims: true,\n };\n\n const userManager = createUserManager(settings);\n\n loadUser(store, userManager);\n\n return userManager;\n}\n","import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';\n\nlet initialized = false;\n\nconst MAX_CONCURRENCY = 6;\n\nexport default function initWebWorkers() {\n const config = {\n maxWebWorkers: Math.max(Math.min(navigator.hardwareConcurrency - 1, MAX_CONCURRENCY), 1),\n startWebWorkersOnDemand: true,\n taskConfiguration: {\n decodeTask: {\n initializeCodecsOnStartup: false,\n usePDFJS: false,\n strict: false,\n },\n },\n };\n\n if (!initialized) {\n cornerstoneWADOImageLoader.webWorkerManager.initialize(config);\n initialized = true;\n }\n}\n","import {\n applyMiddleware,\n combineReducers,\n createStore,\n compose,\n} from 'redux/es/redux.js';\n\n// import { createLogger } from 'redux-logger';\nimport { reducer as oidcReducer } from 'redux-oidc';\nimport { redux } from '@ohif/core';\nimport thunkMiddleware from 'redux-thunk';\n\n// Combine our @ohif/core and oidc reducers\n// Set init data, using values found in localStorage\nconst { reducers, localStorage, sessionStorage } = redux;\nconst middleware = [thunkMiddleware];\nconst composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;\n\nreducers.oidc = oidcReducer;\n\nconst rootReducer = combineReducers(reducers);\nconst preloadedState = {\n ...localStorage.loadState(),\n ...sessionStorage.loadState(),\n};\n\nif (window.config && window.config.disableServersCache === true) {\n delete preloadedState.servers;\n}\n\nconst store = createStore(\n rootReducer,\n preloadedState,\n composeEnhancers(applyMiddleware(...middleware))\n);\n\n// When the store's preferences change,\n// Update our cached preferences in localStorage\nstore.subscribe(() => {\n localStorage.saveState({\n preferences: store.getState().preferences,\n });\n sessionStorage.saveState({\n servers: store.getState().servers,\n });\n});\n\nexport default store;\n","import { redux } from '@ohif/core';\nimport store from './../../store';\n\nconst commandsModule = ({ commandsManager }) => {\n const { setViewportActive, setActiveViewportSpecificData } = redux.actions;\n\n const actions = {\n updateActiveViewport: ({ viewports, direction }) => {\n const { viewportSpecificData, activeViewportIndex } = viewports;\n const maxIndex = Object.keys(viewportSpecificData).length - 1;\n\n let newIndex = activeViewportIndex + direction;\n newIndex = newIndex > maxIndex ? 0 : newIndex;\n newIndex = newIndex < 0 ? maxIndex : newIndex;\n\n store.dispatch(setViewportActive(newIndex));\n },\n setWindowLevelPreset: ({ viewports, preset }) => {\n const state = store.getState();\n const { preferences = {} } = state;\n const { window, level } =\n preferences.windowLevelData && preferences.windowLevelData[preset];\n\n if (window && level) {\n commandsManager.runCommand('setWindowLevel', {\n viewports,\n window,\n level,\n });\n }\n },\n updateViewportDisplaySet: ({ viewports, direction }) => {\n const viewportSpecificData = { ...viewports.viewportSpecificData };\n const activeViewport =\n viewportSpecificData[viewports.activeViewportIndex];\n const studyMetadata = utils.studyMetadataManager.get(\n activeViewport.StudyInstanceUID\n );\n\n if (!studyMetadata) {\n return;\n }\n\n const allDisplaySets = studyMetadata.getDisplaySets();\n const currentDisplaySetIndex = allDisplaySets.findIndex(\n displaySet =>\n displaySet.displaySetInstanceUID ===\n activeViewport.displaySetInstanceUID\n );\n if (currentDisplaySetIndex < 0) {\n return;\n }\n\n const newDisplaySetIndex = currentDisplaySetIndex + direction;\n const newDisplaySetData = allDisplaySets[newDisplaySetIndex];\n if (!newDisplaySetData) {\n return;\n }\n\n store.dispatch(setActiveViewportSpecificData(newDisplaySetData));\n },\n };\n\n const definitions = {\n // Next/Previous active viewport\n incrementActiveViewport: {\n commandFn: actions.updateActiveViewport,\n storeContexts: ['viewports'],\n options: { direction: 1 },\n },\n decrementActiveViewport: {\n commandFn: actions.updateActiveViewport,\n storeContexts: ['viewports'],\n options: { direction: -1 },\n },\n // Window level Presets\n windowLevelPreset1: {\n commandFn: actions.setWindowLevelPreset,\n storeContexts: ['viewports'],\n options: { preset: 1 },\n },\n windowLevelPreset2: {\n commandFn: actions.setWindowLevelPreset,\n storeContexts: ['viewports'],\n options: { preset: 2 },\n },\n windowLevelPreset3: {\n commandFn: actions.setWindowLevelPreset,\n storeContexts: ['viewports'],\n options: { preset: 3 },\n },\n windowLevelPreset4: {\n commandFn: actions.setWindowLevelPreset,\n storeContexts: ['viewports'],\n options: { preset: 4 },\n },\n windowLevelPreset5: {\n commandFn: actions.setWindowLevelPreset,\n storeContexts: ['viewports'],\n options: { preset: 5 },\n },\n windowLevelPreset6: {\n commandFn: actions.setWindowLevelPreset,\n storeContexts: ['viewports'],\n options: { preset: 6 },\n },\n windowLevelPreset7: {\n commandFn: actions.setWindowLevelPreset,\n storeContexts: ['viewports'],\n options: { preset: 7 },\n },\n windowLevelPreset8: {\n commandFn: actions.setWindowLevelPreset,\n storeContexts: ['viewports'],\n options: { preset: 8 },\n },\n windowLevelPreset9: {\n commandFn: actions.setWindowLevelPreset,\n storeContexts: ['viewports'],\n options: { preset: 9 },\n },\n nextViewportDisplaySet: {\n commandFn: actions.updateViewportDisplaySet,\n storeContexts: ['viewports'],\n options: { direction: 1 },\n },\n previousViewportDisplaySet: {\n commandFn: actions.updateViewportDisplaySet,\n storeContexts: ['viewports'],\n options: { direction: -1 },\n },\n };\n\n return {\n definitions,\n defaultContext: 'VIEWER',\n };\n};\n\nexport default commandsModule;\n","import commandsModule from './commandsModule.js';\n\nexport default {\n id: 'generic-viewer-commands',\n get version() {\n return window.version;\n },\n getCommandsModule({ commandsManager }) {\n return commandsModule({ commandsManager });\n },\n};\n","import { measurements, utils } from '@ohif/core';\n\nconst { MeasurementApi } = measurements;\nconst { studyMetadataManager } = utils;\n\n// TODO: Move this function to OHIF itself so we can use it on the OHIF measurment table (when it is finished)\n\n/**\n * Activates a set of measurements\n *\n * @param measurementData\n * @param viewportsState\n * @param timepointManagerState\n * @param options\n */\nexport default function jumpToRowItem(\n measurementData,\n viewportsState,\n timepointManagerState,\n options = { invertViewportTimepointsOrder: false, childToolKey: null }\n) {\n const numViewports = viewportsState.layout.viewports.length;\n const numTimepoints = timepointManagerState.timepoints.length;\n const { measurements, timepoints } = timepointManagerState;\n const numViewportsToUpdate = Math.min(numTimepoints, numViewports);\n const { toolType, measurementNumber } = measurementData;\n\n if (options.invertViewportTimepointsOrder) {\n timepoints.reverse();\n }\n\n const measurementsForToolGroup = measurements[toolType];\n\n // Retrieve the measurements data\n const measurementsToJumpTo = [];\n for (let i = 0; i < numViewportsToUpdate; i++) {\n const { timepointId } = timepoints[i];\n\n const dataAtThisTimepoint = measurementsForToolGroup.find(entry => {\n return (\n entry.timepointId === timepointId &&\n entry.measurementNumber === measurementNumber\n );\n });\n\n if (!dataAtThisTimepoint) {\n measurementsToJumpTo.push(null);\n continue;\n }\n\n let measurement = dataAtThisTimepoint;\n\n const { tool } = MeasurementApi.getToolConfiguration(toolType);\n if (options.childToolKey) {\n measurement = dataAtThisTimepoint[options.childToolKey];\n } else if (Array.isArray(tool.childTools)) {\n const key = tool.childTools.find(key => !!dataAtThisTimepoint[key]);\n measurement = dataAtThisTimepoint[key];\n }\n\n measurementsToJumpTo.push(measurement);\n }\n\n // TODO: Add a single viewports state action which allows\n // - viewportData to be set\n // - layout to be set\n // - activeViewport to be set\n\n // Needs to update viewports.viewportData state to set image set data\n\n const displaySetContainsSopInstance = (displaySet, SOPInstanceUID) => {\n if (!displaySet.images || !displaySet.images.length) {\n return;\n }\n\n return displaySet.images.find(\n image => image.getSOPInstanceUID() === SOPInstanceUID\n );\n };\n\n const viewportSpecificData = [];\n measurementsToJumpTo.forEach((data, viewportIndex) => {\n // Skip if there is no measurement to jump\n if (!data) {\n return;\n }\n\n const study = studyMetadataManager.get(data.StudyInstanceUID);\n if (!study) {\n throw new Error('Study not found.');\n }\n\n const displaySet = study.findDisplaySet(displaySet => {\n return displaySetContainsSopInstance(displaySet, data.SOPInstanceUID);\n });\n\n if (!displaySet) {\n throw new Error('Display set not found.');\n }\n\n displaySet.SOPInstanceUID = data.SOPInstanceUID;\n if (data.frameIndex) {\n displaySet.frameIndex = data.frameIndex;\n }\n\n viewportIndex =\n (viewportIndex + viewportsState.activeViewportIndex) % numViewports;\n viewportSpecificData.push({\n viewportIndex,\n displaySet,\n });\n });\n\n return {\n viewportSpecificData,\n layout: [], // TODO: if we need to change layout, we should return this here\n };\n}\n","import { connect } from 'react-redux';\nimport { MeasurementTable } from '@ohif/ui';\nimport OHIF, { DICOMSR } from '@ohif/core';\nimport moment from 'moment';\nimport cornerstone from 'cornerstone-core';\n\nimport jumpToRowItem from './jumpToRowItem.js';\n\nconst { setViewportSpecificData } = OHIF.redux.actions;\nconst { MeasurementApi } = OHIF.measurements;\n\n/**\n * Takes a list of objects and a property and return the list grouped by the property\n *\n * @param {Array} list - The objects to be grouped by\n * @param {string} props - The property to group the objects\n * @returns {Object}\n */\nfunction groupBy(list, props) {\n return list.reduce((a, b) => {\n (a[b[props]] = a[b[props]] || []).push(b);\n return a;\n }, {});\n}\n\n/**\n * Takes a list of tools grouped and return all tools separately\n *\n * @param {Array} [toolGroups=[]] - The grouped tools\n * @returns {Array} - The list of all tools on all groups\n */\nfunction getAllTools(toolGroups = []) {\n let tools = [];\n toolGroups.forEach(toolGroup => (tools = tools.concat(toolGroup.childTools)));\n\n return tools;\n}\n\n/**\n * Takes measurementData and build the measurement text to be used into the table\n *\n * @param {Object} [measurementData={}]\n * @param {string} measurementData.location - The measurement location\n * @param {string} measurementData.description - The measurement description\n * @returns {string}\n */\nfunction getMeasurementText(measurementData = {}) {\n const defaultText = '...';\n const { location = '', description = '' } = measurementData;\n const result = location + (description ? ` (${description})` : '');\n\n return result || defaultText;\n}\n\n/**\n * Takes a list of measurements grouped by measurement numbers and return each measurement data by available timepoint\n *\n * @param {Array} measurementNumberList - The list of measurements\n * @param {Array} timepoints - The list of available timepoints\n * @param {Function} displayFunction - The function that builds the display text by each tool\n * @returns\n */\nfunction getDataForEachMeasurementNumber(\n measurementNumberList,\n timepoints,\n displayFunction\n) {\n const data = [];\n // on each measurement number we should get each measurement data by available timepoint\n measurementNumberList.forEach(measurement => {\n timepoints.forEach(timepoint => {\n const eachData = {\n displayText: '...',\n };\n if (measurement.timepointId === timepoint.timepointId) {\n eachData.displayText = displayFunction(measurement);\n }\n data.push(eachData);\n });\n });\n\n return data;\n}\n\n/**\n * Take a measurement toolName and return if any warnings\n *\n * @param {string} toolName - The tool name\n * @returns {string}\n */\nfunction getWarningsForMeasurement(toolName) {\n const isToolSupported = DICOMSR.isToolSupported(toolName);\n\n return {\n hasWarnings: !isToolSupported,\n warningTitle: isToolSupported ? '' : 'Unsupported Tool',\n warningList: isToolSupported\n ? []\n : [`${toolName} cannot be persisted at this time`],\n };\n}\n\n/**\n * Take measurements from MeasurementAPI structure and convert into a measurementTable structure\n *\n * @param {Object} toolCollections - The list of all measurement grouped by groupTool and toolName\n * @param {Array} timepoints - The list of available timepoints\n * @returns\n */\nfunction convertMeasurementsToTableData(toolCollections, timepoints) {\n const config = OHIF.measurements.MeasurementApi.getConfiguration();\n const toolGroups = config.measurementTools;\n const tools = getAllTools(toolGroups);\n\n const tableMeasurements = toolGroups.map(toolGroup => {\n return {\n groupName: toolGroup.name,\n groupId: toolGroup.id,\n measurements: [],\n };\n });\n\n Object.keys(toolCollections).forEach(toolId => {\n const toolMeasurements = toolCollections[toolId];\n const tool = tools.find(tool => tool.id === toolId);\n const { displayFunction } = tool.options.measurementTable;\n\n // Group by measurementNumber so we can display then all in the same line\n const groupedMeasurements = groupBy(toolMeasurements, 'measurementNumber');\n\n Object.keys(groupedMeasurements).forEach(groupedMeasurementsIndex => {\n const measurementNumberList =\n groupedMeasurements[groupedMeasurementsIndex];\n const measurementData = measurementNumberList[0];\n const {\n measurementNumber,\n lesionNamingNumber,\n toolType,\n isReadOnly\n } = measurementData;\n const measurementId = measurementData._id;\n\n const {\n hasWarnings,\n warningTitle,\n warningList,\n } = getWarningsForMeasurement(toolType);\n\n //check if all measurements with same measurementNumber will have same LABEL\n const tableMeasurement = {\n itemNumber: lesionNamingNumber,\n label: getMeasurementText(measurementData),\n measurementId,\n measurementNumber,\n lesionNamingNumber,\n toolType,\n hasWarnings,\n isReadOnly,\n warningTitle,\n warningList,\n isSplitLesion: false, //TODO\n data: getDataForEachMeasurementNumber(\n measurementNumberList,\n timepoints,\n displayFunction\n ),\n };\n\n // find the group object for the tool\n const toolGroupMeasurements = tableMeasurements.find(group => {\n return group.groupId === tool.toolGroup;\n });\n // inject the new measurement for this measurementNumer\n toolGroupMeasurements.measurements.push(tableMeasurement);\n });\n });\n\n // Sort measurements by lesion naming number\n tableMeasurements.forEach(tm => {\n tm.measurements.sort((m1, m2) =>\n m1.lesionNamingNumber > m2.lesionNamingNumber ? 1 : -1\n );\n });\n\n return tableMeasurements;\n}\n\n/**\n * Take a list of available timepoints and return a list header information for each timepoint\n *\n * @param {Array} timepoints - The list of available timepoints\n * @param {string} timepoints[].latestDate - The date of the last study taken on the timepoint\n * @returns {{label: string, key: string, date: string}[]}\n */\nfunction convertTimepointsToTableData(timepoints) {\n if (!timepoints || !timepoints.length) {\n return [];\n }\n\n return [\n {\n label: 'Study date:',\n key: 'StudyDate',\n date: moment(timepoints[0].latestDate).format('DD-MMM-YY'),\n },\n ];\n}\n\n/**\n * Takes server type and return a function or undefined\n *\n * @param {string} serverType - The server type\n * @returns {undefined|Function}\n */\nfunction getSaveFunction(serverType) {\n if (serverType === 'dicomWeb') {\n return () => {\n const measurementApi = OHIF.measurements.MeasurementApi.Instance;\n const promise = measurementApi.storeMeasurements();\n return promise;\n };\n }\n}\n\nconst mapStateToProps = state => {\n const { timepointManager, servers } = state;\n const { timepoints, measurements } = timepointManager;\n const activeServer = servers.servers.find(a => a.active === true);\n const saveFunction = getSaveFunction(activeServer.type);\n\n return {\n timepoints: convertTimepointsToTableData(timepoints),\n measurementCollection: convertMeasurementsToTableData(\n measurements,\n timepoints\n ),\n timepointManager: state.timepointManager,\n viewports: state.viewports,\n saveFunction,\n };\n};\n\nconst mapDispatchToProps = (dispatch, ownProps) => {\n return {\n dispatchRelabel: (event, measurementData, viewportsState) => {\n event.persist();\n\n const activeViewportIndex =\n (viewportsState && viewportsState.activeViewportIndex) || 0;\n\n const enabledElements = cornerstone.getEnabledElements();\n if (!enabledElements || enabledElements.length <= activeViewportIndex) {\n OHIF.log.error('Failed to find the enabled element');\n return;\n }\n\n const { toolType, measurementId } = measurementData;\n const tool = MeasurementApi.Instance.tools[toolType].find(measurement => {\n return measurement._id === measurementId;\n });\n\n // Clone the tool not to set empty location initially\n const toolForLocation = Object.assign({}, tool, { location: null });\n\n if (ownProps.onRelabel) {\n ownProps.onRelabel(toolForLocation);\n }\n },\n dispatchEditDescription: (event, measurementData, viewportsState) => {\n event.persist();\n\n const activeViewportIndex =\n (viewportsState && viewportsState.activeViewportIndex) || 0;\n\n const enabledElements = cornerstone.getEnabledElements();\n if (!enabledElements || enabledElements.length <= activeViewportIndex) {\n OHIF.log.error('Failed to find the enabled element');\n return;\n }\n\n const { toolType, measurementId } = measurementData;\n const tool = MeasurementApi.Instance.tools[toolType].find(measurement => {\n return measurement._id === measurementId;\n });\n\n if (ownProps.onEditDescription) {\n ownProps.onEditDescription(tool);\n }\n },\n dispatchJumpToRowItem: (\n measurementData,\n viewportsState,\n timepointManagerState,\n options\n ) => {\n const actionData = jumpToRowItem(\n measurementData,\n viewportsState,\n timepointManagerState,\n dispatch,\n options\n );\n\n actionData.viewportSpecificData.forEach(viewportSpecificData => {\n const { viewportIndex, displaySet } = viewportSpecificData;\n\n dispatch(setViewportSpecificData(viewportIndex, displaySet));\n });\n\n const { toolType, measurementNumber } = measurementData;\n const measurementApi = MeasurementApi.Instance;\n\n Object.keys(measurementApi.tools).forEach(toolType => {\n const measurements = measurementApi.tools[toolType];\n\n measurements.forEach(measurement => {\n measurement.active = false;\n });\n });\n\n const measurementsToActive = measurementApi.tools[toolType].filter(\n measurement => {\n return measurement.measurementNumber === measurementNumber;\n }\n );\n\n measurementsToActive.forEach(measurementToActive => {\n measurementToActive.active = true;\n });\n\n measurementApi.syncMeasurementsAndToolData();\n\n cornerstone.getEnabledElements().forEach(enabledElement => {\n if (enabledElement.image) {\n cornerstone.updateImage(enabledElement.element);\n }\n });\n\n // Needs to update viewports.layout state to set layout\n //const layout = actionData.layout;\n //dispatch(setLayout(layout))\n\n // Needs to update viewports.activeViewportIndex to the first updated viewport\n //const viewportIndex = actionData.viewportIndex;\n //dispatch(setViewportActive(viewportIndex));\n\n // Needs to update timepointsManager.measurements state to set active measurementId\n // TODO: Not yet implemented\n //dispatch(setActiveMeasurement(measurementData.measurementId))\n\n // (later): Needs to set some property on state.extensions.cornerstone to synchronize viewport scrolling\n },\n };\n};\n\nconst mergeProps = (propsFromState, propsFromDispatch, ownProps) => {\n const { timepoints, saveFunction, measurementCollection } = propsFromState;\n const { onSaveComplete, selectedMeasurementNumber } = ownProps;\n\n return {\n timepoints,\n saveFunction,\n measurementCollection,\n onSaveComplete,\n selectedMeasurementNumber,\n ...propsFromDispatch,\n onItemClick: (event, measurementData) => {\n // TODO: Add timepointId to .data for measurementData?\n // TODO: Tooltype should be on the level below? This should\n // provide the entire row item?\n\n const viewportsState = propsFromState.viewports;\n const timepointManagerState = propsFromState.timepointManager;\n\n // TODO: invertViewportTimepointsOrder should be stored in / read from user preferences\n // TODO: childToolKey should come from the measurement table when it supports child tools\n const options = {\n invertViewportTimepointsOrder: false,\n childToolKey: null,\n };\n\n propsFromDispatch.dispatchJumpToRowItem(\n measurementData,\n viewportsState,\n timepointManagerState,\n options\n );\n },\n onRelabelClick: (event, measurementData) => {\n const viewportsState = propsFromState.viewports;\n propsFromDispatch.dispatchRelabel(event, measurementData, viewportsState);\n },\n onEditDescriptionClick: (event, measurementData) => {\n const viewportsState = propsFromState.viewports;\n propsFromDispatch.dispatchEditDescription(\n event,\n measurementData,\n viewportsState\n );\n },\n onDeleteClick: (event, measurementData) => {\n const { MeasurementHandlers } = OHIF.measurements;\n\n MeasurementHandlers.onRemoved({\n detail: {\n toolType: measurementData.toolType,\n measurementData: {\n _id: measurementData.measurementId,\n lesionNamingNumber: measurementData.lesionNamingNumber,\n measurementNumber: measurementData.measurementNumber,\n },\n },\n });\n },\n };\n};\n\nconst ConnectedMeasurementTable = connect(\n mapStateToProps,\n mapDispatchToProps,\n mergeProps\n)(MeasurementTable);\n\nexport default ConnectedMeasurementTable;\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport { CSSTransition } from 'react-transition-group';\n\nimport './LabellingTransition.css';\n\n// If these variables changes, CSS must be updated\nconst transitionDuration = 500;\nconst transitionClassName = 'labelling';\nconst transitionOnAppear = true;\n\nexport default class LabellingTransition extends Component {\n static propTypes = {\n children: PropTypes.node.isRequired,\n displayComponent: PropTypes.bool.isRequired,\n onTransitionExit: PropTypes.func.isRequired,\n };\n render() {\n return (\n \n {this.props.children}\n \n );\n }\n}\n","const items = [\n 'Abdomen/Chest Wall',\n 'Adrenal',\n 'Bladder',\n 'Bone',\n 'Brain',\n 'Breast',\n 'Colon',\n 'Esophagus',\n 'Extremities',\n 'Gallbladder',\n 'Kidney',\n 'Liver',\n 'Lung',\n 'Lymph Node',\n 'Mediastinum/Hilum',\n 'Muscle',\n 'Neck',\n 'Other Soft Tissue',\n 'Ovary',\n 'Pancreas',\n 'Pelvis',\n 'Peritoneum/Omentum',\n 'Prostate',\n 'Retroperitoneum',\n 'Small Bowel',\n 'Spleen',\n 'Stomach',\n 'Subcutaneous',\n];\n\nconst OHIFLabellingData = items.map(item => {\n return {\n label: item,\n value: item,\n };\n});\n\nexport default OHIFLabellingData;\n","import { Component } from 'react';\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport './SimpleDialog.css';\n\nclass SimpleDialog extends Component {\n static defaultProps = {\n componentStyle: {},\n rootClass: '',\n };\n\n render() {\n return (\n \n
    \n
    \n \n x\n \n

    {this.props.headerTitle}

    \n
    \n
    {this.props.children}
    \n
    \n \n Cancel\n \n \n Confirm\n \n
    \n
    \n \n );\n }\n}\n\nSimpleDialog.propTypes = {\n headerTitle: PropTypes.string.isRequired,\n onClose: PropTypes.func.isRequired,\n onConfirm: PropTypes.func.isRequired,\n};\n\nexport default SimpleDialog;\n","import { Component } from 'react';\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport SimpleDialog from '../SimpleDialog/SimpleDialog.js';\nimport './EditDescriptionDialog.css';\n\nexport default class EditDescriptionDialog extends Component {\n static propTypes = {\n description: PropTypes.string,\n measurementData: PropTypes.object.isRequired,\n onCancel: PropTypes.func.isRequired,\n onUpdate: PropTypes.func.isRequired,\n };\n\n constructor(props) {\n super(props);\n\n this.state = {\n description: props.measurementData.description || '',\n };\n }\n\n componentDidUpdate(prevProps) {\n if (this.props.description !== prevProps.description) {\n this.setState({\n description: this.props.description,\n });\n }\n }\n\n render() {\n return (\n \n \n \n );\n }\n\n onClose = () => {\n this.props.onCancel();\n };\n\n onConfirm = e => {\n e.preventDefault();\n this.props.onUpdate(this.state.description);\n };\n\n handleChange = event => {\n this.setState({ description: event.target.value });\n };\n}\n","import { Icon, SelectTree } from '@ohif/ui';\nimport React, { useState, useEffect, useRef } from 'react';\nimport PropTypes from 'prop-types';\nimport cloneDeep from 'lodash.clonedeep';\n\nimport LabellingTransition from './LabellingTransition.js';\nimport OHIFLabellingData from './OHIFLabellingData.js';\nimport EditDescriptionDialog from './../EditDescriptionDialog/EditDescriptionDialog.js';\nimport './LabellingFlow.css';\n\nconst LabellingFlow = ({\n measurementData,\n editLocation,\n editDescription,\n skipAddLabelButton,\n updateLabelling,\n labellingDoneCallback,\n editDescriptionOnDialog,\n}) => {\n const [fadeOutTimer, setFadeOutTimer] = useState();\n const [showComponent, setShowComponent] = useState(true);\n const descriptionInput = useRef();\n const [state, setState] = useState({\n measurementData,\n editLocation,\n editDescription,\n skipAddLabelButton,\n });\n\n useEffect(() => {\n const newMeasurementData = cloneDeep(measurementData);\n\n if (editDescription) {\n newMeasurementData.description = undefined;\n }\n\n if (editLocation) {\n newMeasurementData.location = undefined;\n }\n\n let newEditLocation = editLocation;\n if (!editDescription && !editLocation) {\n newEditLocation = true;\n }\n\n setState(state => ({\n ...state,\n editLocation: newEditLocation,\n measurementData: newMeasurementData,\n }));\n }, [editDescription, editLocation, measurementData]);\n\n useEffect(() => {\n if (descriptionInput.current) {\n descriptionInput.current.focus();\n }\n }, [state]);\n\n const relabel = event =>\n setState(state => ({ ...state, editLocation: true }));\n\n const setDescriptionUpdateMode = () => {\n descriptionInput.current.focus();\n setState(state => ({ ...state, editDescription: true }));\n };\n\n const descriptionCancel = () => {\n const { description = '' } = cloneDeep(state);\n descriptionInput.current.value = description;\n setState(state => ({ ...state, editDescription: false }));\n };\n\n const handleKeyPress = event => {\n if (event.key === 'Enter') {\n descriptionSave();\n }\n };\n\n const descriptionSave = () => {\n const description = descriptionInput.current.value;\n updateLabelling({ description });\n\n setState(state => ({\n ...state,\n description,\n editDescription: false,\n }));\n };\n\n const selectTreeSelectCallback = (event, itemSelected) => {\n const location = itemSelected.value;\n const locationLabel = itemSelected.label;\n updateLabelling({ location });\n\n setState(state => ({\n ...state,\n editLocation: false,\n measurementData: {\n ...state.measurementData,\n location,\n locationLabel,\n },\n }));\n };\n\n const showLabelling = () => {\n setState(state => ({\n ...state,\n skipAddLabelButton: true,\n editLocation: false,\n }));\n };\n\n /*\n * Waits for 1 sec to dismiss the labelling component.\n *\n */\n const fadeOutAndLeave = () =>\n setFadeOutTimer(setTimeout(fadeOutAndLeaveFast, 1000));\n\n const fadeOutAndLeaveFast = () => setShowComponent(false);\n\n const clearFadeOutTimer = () => {\n if (fadeOutTimer) {\n clearTimeout(fadeOutTimer);\n setFadeOutTimer(null);\n }\n };\n\n const descriptionDialogUpdate = description => {\n updateLabelling({ description });\n labellingDoneCallback();\n };\n\n const labellingStateFragment = () => {\n const { skipAddLabelButton, editLocation, measurementData } = state;\n const { description, locationLabel, location } = measurementData;\n\n if (!skipAddLabelButton) {\n return (\n \n {location ? 'Edit' : 'Add'} Label\n \n );\n } else {\n if (editLocation) {\n return (\n \n );\n } else {\n return (\n <>\n
    \n \n
    \n
    \n
    {locationLabel}
    \n
    \n \n
    \n
    \n
    \n \n Relabel\n \n \n {description ? 'Edit ' : 'Add '}\n Description\n \n
    \n
    \n \n Cancel\n \n \n Save\n \n
    \n \n );\n }\n }\n };\n\n if (editDescriptionOnDialog) {\n return (\n \n );\n }\n\n return (\n \n <>\n \n {labellingStateFragment()}\n \n \n \n );\n};\n\nLabellingFlow.propTypes = {\n measurementData: PropTypes.object.isRequired,\n labellingDoneCallback: PropTypes.func.isRequired,\n updateLabelling: PropTypes.func.isRequired,\n initialTopDistance: PropTypes.number,\n skipAddLabelButton: PropTypes.bool,\n editLocation: PropTypes.bool,\n editDescription: PropTypes.bool,\n editDescriptionOnDialog: PropTypes.bool,\n};\n\nLabellingFlow.defaultProps = {\n skipAddLabelButton: false,\n editLocation: false,\n editDescription: false,\n editDescriptionOnDialog: false,\n};\n\nexport default LabellingFlow;\n","import { ContextMenu } from '@ohif/ui';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport { commandsManager } from './../App.js';\n\nconst toolTypes = [\n 'Angle',\n 'Bidirectional',\n 'Length',\n 'FreehandMouse',\n 'EllipticalRoi',\n 'CircleRoi',\n 'RectangleRoi',\n];\n\nconst ToolContextMenu = ({\n onSetLabel,\n onSetDescription,\n isTouchEvent,\n eventData,\n onClose,\n onDelete,\n}) => {\n const defaultDropdownItems = [\n {\n label: 'Delete measurement',\n actionType: 'Delete',\n action: ({ nearbyToolData, eventData }) =>\n onDelete(nearbyToolData, eventData),\n },\n {\n label: 'Relabel',\n actionType: 'setLabel',\n action: ({ nearbyToolData, eventData }) => {\n const { tool: measurementData } = nearbyToolData;\n onSetLabel(eventData, measurementData);\n },\n },\n {\n actionType: 'setDescription',\n action: ({ nearbyToolData, eventData }) => {\n const { tool: measurementData } = nearbyToolData;\n onSetDescription(eventData, measurementData);\n },\n },\n ];\n\n const getDropdownItems = (eventData, isTouchEvent = false) => {\n const nearbyToolData = commandsManager.runCommand('getNearbyToolData', {\n element: eventData.element,\n canvasCoordinates: eventData.currentPoints.canvas,\n availableToolTypes: toolTypes,\n });\n\n /*\n * Annotate tools for touch events already have a press handle to edit it,\n * has a better UX for deleting it.\n */\n if (\n isTouchEvent &&\n nearbyToolData &&\n nearbyToolData.toolType === 'arrowAnnotate'\n ) {\n return;\n }\n\n let dropdownItems = [];\n if (nearbyToolData) {\n defaultDropdownItems.forEach(item => {\n item.params = { eventData, nearbyToolData };\n\n if (item.actionType === 'setDescription') {\n item.label = `${\n nearbyToolData.tool.description ? 'Edit' : 'Add'\n } Description`;\n }\n\n dropdownItems.push(item);\n });\n }\n\n return dropdownItems;\n };\n\n const onClickHandler = ({ action, params }) => {\n action(params);\n if (onClose) {\n onClose();\n }\n };\n\n const dropdownItems = getDropdownItems(eventData, isTouchEvent);\n\n return (\n
    \n \n
    \n );\n};\n\nToolContextMenu.propTypes = {\n isTouchEvent: PropTypes.bool.isRequired,\n eventData: PropTypes.object,\n onClose: PropTypes.func,\n onSetDescription: PropTypes.func,\n onSetLabel: PropTypes.func,\n onDelete: PropTypes.func,\n};\n\nToolContextMenu.defaultProps = {\n isTouchEvent: false,\n};\n\nexport default ToolContextMenu;\n","import OHIF from '@ohif/core';\nimport cornerstone from 'cornerstone-core';\nimport csTools from 'cornerstone-tools';\nimport throttle from 'lodash.throttle';\n\nimport LabellingFlow from '../../components/Labelling/LabellingFlow';\nimport ToolContextMenu from '../../connectedComponents/ToolContextMenu';\n\nconst {\n onAdded,\n onRemoved,\n onModified,\n} = OHIF.measurements.MeasurementHandlers;\n\nconst MEASUREMENT_ACTION_MAP = {\n added: onAdded,\n removed: onRemoved,\n modified: throttle(event => {\n return onModified(event);\n }, 300),\n};\n\n/**\n *\n *\n * @export\n * @param {Object} servicesManager\n * @param {Object} configuration\n */\nexport default function init({\n servicesManager,\n commandsManager,\n configuration,\n}) {\n const { UIDialogService } = servicesManager.services;\n\n // TODO: MEASUREMENT_COMPLETED (not present in initial implementation)\n const onMeasurementsChanged = (action, event) => {\n return MEASUREMENT_ACTION_MAP[action](event);\n };\n const onMeasurementAdded = onMeasurementsChanged.bind(this, 'added');\n const onMeasurementRemoved = onMeasurementsChanged.bind(this, 'removed');\n const onMeasurementModified = onMeasurementsChanged.bind(this, 'modified');\n const onLabelmapModified = onMeasurementsChanged.bind(\n this,\n 'labelmapModified'\n );\n\n const _getDefaultPosition = event => ({\n x: (event && event.currentPoints.client.x) || 0,\n y: (event && event.currentPoints.client.y) || 0,\n });\n\n const _updateLabellingHandler = (labellingData, measurementData) => {\n const { location, description, response } = labellingData;\n\n if (location) {\n measurementData.location = location;\n }\n\n measurementData.description = description || '';\n\n if (response) {\n measurementData.response = response;\n }\n\n commandsManager.runCommand(\n 'updateTableWithNewMeasurementData',\n measurementData\n );\n };\n\n const showLabellingDialog = (props, contentProps, measurementData) => {\n if (!UIDialogService) {\n console.warn('Unable to show dialog; no UI Dialog Service available.');\n return;\n }\n\n UIDialogService.create({\n id: 'labelling',\n isDraggable: false,\n showOverlay: true,\n centralize: true,\n content: LabellingFlow,\n contentProps: {\n measurementData,\n labellingDoneCallback: () =>\n UIDialogService.dismiss({ id: 'labelling' }),\n updateLabelling: labellingData =>\n _updateLabellingHandler(labellingData, measurementData),\n ...contentProps,\n },\n ...props,\n });\n };\n\n const onRightClick = event => {\n if (!UIDialogService) {\n console.warn('Unable to show dialog; no UI Dialog Service available.');\n return;\n }\n\n UIDialogService.dismiss({ id: 'context-menu' });\n UIDialogService.create({\n id: 'context-menu',\n isDraggable: false,\n preservePosition: false,\n defaultPosition: _getDefaultPosition(event.detail),\n content: ToolContextMenu,\n contentProps: {\n eventData: event.detail,\n onDelete: (nearbyToolData, eventData) => {\n const element = eventData.element;\n commandsManager.runCommand('removeToolState', {\n element,\n toolType: nearbyToolData.toolType,\n tool: nearbyToolData.tool,\n });\n },\n onClose: () => UIDialogService.dismiss({ id: 'context-menu' }),\n onSetLabel: (eventData, measurementData) => {\n showLabellingDialog(\n { centralize: true, isDraggable: false },\n { skipAddLabelButton: true, editLocation: true },\n measurementData\n );\n },\n onSetDescription: (eventData, measurementData) => {\n showLabellingDialog(\n { defaultPosition: _getDefaultPosition(eventData) },\n { editDescriptionOnDialog: true },\n measurementData\n );\n },\n },\n });\n };\n\n const onTouchPress = event => {\n if (!UIDialogService) {\n console.warn('Unable to show dialog; no UI Dialog Service available.');\n return;\n }\n\n UIDialogService.create({\n eventData: event.detail,\n content: ToolContextMenu,\n contentProps: {\n isTouchEvent: true,\n },\n });\n };\n\n const onTouchStart = () => resetLabelligAndContextMenu();\n\n const onMouseClick = () => resetLabelligAndContextMenu();\n\n const resetLabelligAndContextMenu = () => {\n if (!UIDialogService) {\n console.warn('Unable to show dialog; no UI Dialog Service available.');\n return;\n }\n\n UIDialogService.dismiss({ id: 'context-menu' });\n UIDialogService.dismiss({ id: 'labelling' });\n };\n\n // TODO: This makes scrolling painfully slow\n // const onNewImage = ...\n\n /*\n * Because click gives us the native \"mouse up\", buttons will always be `0`\n * Need to fallback to event.which;\n *\n */\n const handleClick = cornerstoneMouseClickEvent => {\n const mouseUpEvent = cornerstoneMouseClickEvent.detail.event;\n const isRightClick = mouseUpEvent.which === 3;\n\n if (isRightClick) {\n onRightClick(cornerstoneMouseClickEvent);\n } else {\n onMouseClick(cornerstoneMouseClickEvent);\n }\n };\n\n function elementEnabledHandler(evt) {\n const element = evt.detail.element;\n\n element.addEventListener(\n csTools.EVENTS.MEASUREMENT_ADDED,\n onMeasurementAdded\n );\n element.addEventListener(\n csTools.EVENTS.MEASUREMENT_REMOVED,\n onMeasurementRemoved\n );\n element.addEventListener(\n csTools.EVENTS.MEASUREMENT_MODIFIED,\n onMeasurementModified\n );\n element.addEventListener(\n csTools.EVENTS.LABELMAP_MODIFIED,\n onLabelmapModified\n );\n\n element.addEventListener(csTools.EVENTS.TOUCH_PRESS, onTouchPress);\n element.addEventListener(csTools.EVENTS.MOUSE_CLICK, handleClick);\n element.addEventListener(csTools.EVENTS.TOUCH_START, onTouchStart);\n\n // TODO: This makes scrolling painfully slow\n // element.addEventListener(cornerstone.EVENTS.NEW_IMAGE, onNewImage);\n }\n\n function elementDisabledHandler(evt) {\n const element = evt.detail.element;\n\n element.removeEventListener(\n csTools.EVENTS.MEASUREMENT_ADDED,\n onMeasurementAdded\n );\n element.removeEventListener(\n csTools.EVENTS.MEASUREMENT_REMOVED,\n onMeasurementRemoved\n );\n element.removeEventListener(\n csTools.EVENTS.MEASUREMENT_MODIFIED,\n onMeasurementModified\n );\n element.removeEventListener(\n csTools.EVENTS.LABELMAP_MODIFIED,\n onLabelmapModified\n );\n\n element.removeEventListener(csTools.EVENTS.TOUCH_PRESS, onTouchPress);\n element.removeEventListener(csTools.EVENTS.MOUSE_CLICK, handleClick);\n element.removeEventListener(csTools.EVENTS.TOUCH_START, onTouchStart);\n\n // TODO: This makes scrolling painfully slow\n // element.removeEventListener(cornerstone.EVENTS.NEW_IMAGE, onNewImage);\n }\n\n cornerstone.events.addEventListener(\n cornerstone.EVENTS.ELEMENT_ENABLED,\n elementEnabledHandler\n );\n cornerstone.events.addEventListener(\n cornerstone.EVENTS.ELEMENT_DISABLED,\n elementDisabledHandler\n );\n}\n","import React from 'react';\nimport ConnectedMeasurementTable from './ConnectedMeasurementTable.js';\nimport init from './init.js';\n\nimport LabellingFlow from '../../components/Labelling/LabellingFlow';\n\nexport default {\n /**\n * Only required property. Should be a unique value across all extensions.\n */\n id: 'measurements-table',\n get version() {\n return window.version;\n },\n\n preRegistration({ servicesManager, commandsManager, configuration = {} }) {\n init({ servicesManager, commandsManager, configuration });\n },\n\n getPanelModule({ servicesManager, commandsManager }) {\n const { UINotificationService, UIDialogService } = servicesManager.services;\n\n const showLabellingDialog = (props, measurementData) => {\n if (!UIDialogService) {\n console.warn('Unable to show dialog; no UI Dialog Service available.');\n return;\n }\n\n UIDialogService.dismiss({ id: 'labelling' });\n UIDialogService.create({\n id: 'labelling',\n centralize: true,\n isDraggable: false,\n showOverlay: true,\n content: LabellingFlow,\n contentProps: {\n measurementData,\n labellingDoneCallback: () =>\n UIDialogService.dismiss({ id: 'labelling' }),\n updateLabelling: ({ location, description, response }) => {\n measurementData.location = location || measurementData.location;\n measurementData.description = description || '';\n measurementData.response = response || measurementData.response;\n\n commandsManager.runCommand(\n 'updateTableWithNewMeasurementData',\n measurementData\n );\n },\n ...props,\n },\n });\n };\n\n const ExtendedConnectedMeasurementTable = () => (\n \n showLabellingDialog(\n { editLocation: true, skipAddLabelButton: true },\n tool\n )\n }\n onEditDescription={tool =>\n showLabellingDialog({ editDescriptionOnDialog: true }, tool)\n }\n onSaveComplete={message => {\n if (UINotificationService) {\n UINotificationService.show(message);\n }\n }}\n />\n );\n return {\n menuOptions: [\n {\n icon: 'list',\n label: 'Medidas',\n target: 'measurement-panel',\n },\n ],\n components: [\n {\n id: 'measurement-panel',\n component: ExtendedConnectedMeasurementTable,\n },\n ],\n defaultContext: ['VIEWER'],\n };\n },\n};\n","import React from 'react';\n\nconst Bar = ({ progress, animationDuration }) => (\n \n \n \n);\n\nexport default Bar;\n","import React from 'react';\n\nconst Container = ({ children, isFinished, animationDuration }) => (\n \n {children}\n \n);\n\nexport default Container;\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport { withRouter, matchPath } from 'react-router';\nimport { Route, Switch } from 'react-router-dom';\nimport { NProgress } from '@tanem/react-nprogress';\nimport { CSSTransition } from 'react-transition-group';\nimport { connect } from 'react-redux';\nimport { ViewerbaseDragDropContext, ErrorBoundary, asyncComponent, retryImport } from '@ohif/ui';\nimport { SignoutCallbackComponent } from 'redux-oidc';\nimport * as RoutesUtil from './routes/routesUtil';\n\nimport NotFound from './routes/NotFound.js';\nimport { Bar, Container } from './components/LoadingBar/';\nimport './OHIFStandaloneViewer.css';\nimport './variables.css';\nimport './theme-tide.css';\n// Contexts\nimport AppContext from './context/AppContext';\nconst CallbackPage = asyncComponent(() =>\n retryImport(() => import(/* webpackChunkName: \"CallbackPage\" */ './routes/CallbackPage.js'))\n);\n\nclass OHIFStandaloneViewer extends Component {\n static contextType = AppContext;\n state = {\n isLoading: false,\n };\n\n static propTypes = {\n history: PropTypes.object.isRequired,\n user: PropTypes.object,\n setContext: PropTypes.func,\n userManager: PropTypes.object,\n location: PropTypes.object,\n };\n\n componentDidMount() {\n this.unlisten = this.props.history.listen((location, action) => {\n if (this.props.setContext) {\n this.props.setContext(window.location.pathname);\n }\n });\n }\n\n componentWillUnmount() {\n this.unlisten();\n }\n\n render() {\n const { user, userManager } = this.props;\n const { appConfig = {} } = this.context;\n const userNotLoggedIn = userManager && (!user || user.expired);\n if (userNotLoggedIn) {\n const { pathname, search } = this.props.location;\n\n if (pathname !== '/callback') {\n sessionStorage.setItem(\n 'ohif-redirect-to',\n JSON.stringify({ pathname, search })\n );\n }\n\n return (\n \n \n (\n console.log('Signout successful')}\n errorCallback={error => {\n console.warn(error);\n console.warn('Signout failed');\n }}\n />\n )}\n />\n }\n />\n {\n const queryParams = new URLSearchParams(\n this.props.location.search\n );\n const iss = queryParams.get('iss');\n const loginHint = queryParams.get('login_hint');\n const targetLinkUri = queryParams.get('target_link_uri');\n const oidcAuthority =\n appConfig.oidc !== null && appConfig.oidc[0].authority;\n if (iss !== oidcAuthority) {\n console.error(\n 'iss of /login does not match the oidc authority'\n );\n return null;\n }\n\n userManager.removeUser().then(() => {\n if (targetLinkUri !== null) {\n const ohifRedirectTo = {\n pathname: new URL(targetLinkUri).pathname,\n };\n sessionStorage.setItem(\n 'ohif-redirect-to',\n JSON.stringify(ohifRedirectTo)\n );\n } else {\n const ohifRedirectTo = {\n pathname: '/',\n };\n sessionStorage.setItem(\n 'ohif-redirect-to',\n JSON.stringify(ohifRedirectTo)\n );\n }\n\n if (loginHint !== null) {\n userManager.signinRedirect({ login_hint: loginHint });\n } else {\n userManager.signinRedirect();\n }\n });\n\n return null;\n }}\n />\n {\n userManager.getUser().then(user => {\n if (user) {\n userManager.signinSilent();\n } else {\n userManager.signinRedirect();\n }\n });\n\n return null;\n }}\n />\n \n );\n }\n\n /**\n * Note: this approach for routing is caused by the conflict between\n * react-transition-group and react-router's component.\n *\n * See http://reactcommunity.org/react-transition-group/with-react-router/\n */\n const routes = RoutesUtil.getRoutes(appConfig);\n\n const currentPath = this.props.location.pathname;\n const noMatchingRoutes = !routes.find(r =>\n matchPath(currentPath, {\n path: r.path,\n exact: true,\n })\n );\n\n return (\n <>\n \n {({ isFinished, progress, animationDuration }) => (\n \n \n \n )}\n \n \n \n {!noMatchingRoutes &&\n routes.map(({ path, Component }) => (\n \n {({ match }) => (\n {\n this.setState({\n isLoading: true,\n });\n }}\n onEntered={() => {\n this.setState({\n isLoading: false,\n });\n }}\n >\n {match === null ? (\n <>\n ) : (\n \n \n \n )}\n \n )}\n \n ))}\n {noMatchingRoutes && }\n \n );\n }\n}\n\nconst mapStateToProps = state => {\n return {\n user: state.oidc.user,\n };\n};\n\nconst ConnectedOHIFStandaloneViewer = connect(\n mapStateToProps,\n null\n)(OHIFStandaloneViewer);\n\nexport default ViewerbaseDragDropContext(\n withRouter(ConnectedOHIFStandaloneViewer)\n);\n","import React, { Component } from 'react';\nimport { OidcProvider } from 'redux-oidc';\nimport { I18nextProvider } from 'react-i18next';\nimport PropTypes from 'prop-types';\nimport { Provider } from 'react-redux';\nimport { BrowserRouter as Router } from 'react-router-dom';\nimport { hot } from 'react-hot-loader/root';\n\nimport OHIFCornerstoneExtension from '@ohif/extension-cornerstone';\n\nimport {\n SnackbarProvider,\n ModalProvider,\n DialogProvider,\n OHIFModal,\n LoggerProvider,\n ErrorBoundary,\n} from '@ohif/ui';\n\nimport {\n CommandsManager,\n ExtensionManager,\n ServicesManager,\n HotkeysManager,\n UINotificationService,\n UIModalService,\n UIDialogService,\n LoggerService,\n MeasurementService,\n utils,\n redux as reduxOHIF,\n} from '@ohif/core';\n\nimport i18n from '@ohif/i18n';\n\n// TODO: This should not be here\n//import './config';\nimport { setConfiguration } from './config';\n\n/** Utils */\nimport {\n getUserManagerForOpenIdConnectClient,\n initWebWorkers,\n} from './utils/index.js';\n\n/** Extensions */\nimport { GenericViewerCommands, MeasurementsPanel } from './appExtensions';\n\n/** Viewer */\nimport OHIFStandaloneViewer from './OHIFStandaloneViewer';\n\n/** Store */\nimport { getActiveContexts } from './store/layout/selectors.js';\nimport store from './store';\n\n/** Contexts */\nimport WhiteLabelingContext from './context/WhiteLabelingContext';\nimport UserManagerContext from './context/UserManagerContext';\nimport { AppProvider, useAppContext, CONTEXTS } from './context/AppContext';\n\n/** ~~~~~~~~~~~~~ Application Setup */\nconst commandsManagerConfig = {\n getAppState: () => store.getState(),\n getActiveContexts: () => getActiveContexts(store.getState()),\n};\n\n/** Managers */\nconst commandsManager = new CommandsManager(commandsManagerConfig);\nconst servicesManager = new ServicesManager();\nconst hotkeysManager = new HotkeysManager(commandsManager, servicesManager);\nlet extensionManager;\n/** ~~~~~~~~~~~~~ End Application Setup */\n\n// TODO[react] Use a provider when the whole tree is React\nwindow.store = store;\n\nwindow.ohif = window.ohif || {};\nwindow.ohif.app = {\n commandsManager,\n hotkeysManager,\n servicesManager,\n extensionManager,\n};\n\nclass App extends Component {\n static propTypes = {\n config: PropTypes.oneOfType([\n PropTypes.func,\n PropTypes.shape({\n routerBasename: PropTypes.string.isRequired,\n oidc: PropTypes.array,\n whiteLabeling: PropTypes.shape({\n createLogoComponentFn: PropTypes.func,\n }),\n extensions: PropTypes.array,\n }),\n ]).isRequired,\n defaultExtensions: PropTypes.array,\n };\n\n static defaultProps = {\n config: {\n showStudyList: true,\n oidc: [],\n extensions: [],\n },\n defaultExtensions: [],\n };\n\n _appConfig;\n _userManager;\n\n constructor(props) {\n super(props);\n\n const { config, defaultExtensions } = props;\n\n const appDefaultConfig = {\n showStudyList: true,\n cornerstoneExtensionConfig: {},\n extensions: [],\n routerBasename: '/',\n };\n\n this._appConfig = {\n ...appDefaultConfig,\n ...(typeof config === 'function' ? config({ servicesManager }) : config),\n };\n\n const {\n servers,\n hotkeys: appConfigHotkeys,\n cornerstoneExtensionConfig,\n extensions,\n oidc,\n } = this._appConfig;\n\n setConfiguration(this._appConfig);\n\n this.initUserManager(oidc);\n _initServices([\n UINotificationService,\n UIModalService,\n UIDialogService,\n MeasurementService,\n LoggerService,\n ]);\n _initExtensions(\n [...defaultExtensions, ...extensions],\n cornerstoneExtensionConfig,\n this._appConfig\n );\n\n /*\n * Must run after extension commands are registered\n * if there is no hotkeys from localStorage set up from config.\n */\n _initHotkeys(appConfigHotkeys);\n _initServers(servers);\n initWebWorkers();\n }\n\n render() {\n const { whiteLabeling, routerBasename } = this._appConfig;\n const {\n UINotificationService,\n UIDialogService,\n UIModalService,\n MeasurementService,\n LoggerService,\n } = servicesManager.services;\n\n if (this._userManager) {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n }\n\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n }\n\n initUserManager(oidc) {\n if (oidc && !!oidc.length) {\n const firstOpenIdClient = this._appConfig.oidc[0];\n\n const { protocol, host } = window.location;\n const { routerBasename } = this._appConfig;\n const baseUri = `${protocol}//${host}${routerBasename}`;\n\n const redirect_uri = firstOpenIdClient.redirect_uri || '/callback';\n const silent_redirect_uri =\n firstOpenIdClient.silent_redirect_uri || '/silent-refresh.html';\n const post_logout_redirect_uri =\n firstOpenIdClient.post_logout_redirect_uri || '/';\n\n const openIdConnectConfiguration = Object.assign({}, firstOpenIdClient, {\n redirect_uri: _makeAbsoluteIfNecessary(redirect_uri, baseUri),\n silent_redirect_uri: _makeAbsoluteIfNecessary(\n silent_redirect_uri,\n baseUri\n ),\n post_logout_redirect_uri: _makeAbsoluteIfNecessary(\n post_logout_redirect_uri,\n baseUri\n ),\n });\n\n this._userManager = getUserManagerForOpenIdConnectClient(\n store,\n openIdConnectConfiguration\n );\n }\n }\n}\n\nfunction _initServices(services) {\n servicesManager.registerServices(services);\n}\n\n/**\n * @param\n */\nfunction _initExtensions(extensions, cornerstoneExtensionConfig, appConfig) {\n extensionManager = new ExtensionManager({\n commandsManager,\n servicesManager,\n appConfig,\n api: {\n contexts: CONTEXTS,\n hooks: {\n useAppContext,\n },\n },\n });\n\n const requiredExtensions = [\n GenericViewerCommands,\n [OHIFCornerstoneExtension, cornerstoneExtensionConfig],\n ];\n\n if (appConfig.disableMeasurementPanel !== true) {\n /* WARNING: MUST BE REGISTERED _AFTER_ OHIFCornerstoneExtension */\n requiredExtensions.push(MeasurementsPanel);\n }\n\n const mergedExtensions = requiredExtensions.concat(extensions);\n extensionManager.registerExtensions(mergedExtensions);\n}\n\n/**\n *\n * @param {Object} appConfigHotkeys - Default hotkeys, as defined by app config\n */\nfunction _initHotkeys(appConfigHotkeys) {\n // TODO: Use something more resilient\n // TODO: Mozilla has a special library for this\n const userPreferredHotkeys = JSON.parse(\n localStorage.getItem('hotkey-definitions') || '{}'\n );\n\n // TODO: hotkeysManager.isValidDefinitionObject(/* */)\n const hasUserPreferences =\n userPreferredHotkeys && Object.keys(userPreferredHotkeys).length > 0;\n if (hasUserPreferences) {\n hotkeysManager.setHotkeys(userPreferredHotkeys);\n } else {\n hotkeysManager.setHotkeys(appConfigHotkeys);\n }\n\n hotkeysManager.setDefaultHotKeys(appConfigHotkeys);\n}\n\nfunction _initServers(servers) {\n if (servers) {\n utils.addServers(servers, store);\n }\n}\n\nfunction _isAbsoluteUrl(url) {\n return url.includes('http://') || url.includes('https://');\n}\n\nfunction _makeAbsoluteIfNecessary(url, base_url) {\n if (_isAbsoluteUrl(url)) {\n return url;\n }\n\n /*\n * Make sure base_url and url are not duplicating slashes.\n */\n if (base_url[base_url.length - 1] === '/') {\n base_url = base_url.slice(0, base_url.length - 1);\n }\n\n return base_url + url;\n}\n\n/*\n * Only wrap/use hot if in dev.\n */\nconst ExportedApp = process.env.NODE_ENV === 'development' ? hot(App) : App;\n\nexport default ExportedApp;\nexport { commandsManager, extensionManager, hotkeysManager, servicesManager };\n","import OHIF from '@ohif/core';\nimport cornerstone from 'cornerstone-core';\nimport cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';\nimport dicomParser from 'dicom-parser';\nimport version from './version.js';\nimport AppContext from './context/AppContext';\n\nexport function setConfiguration(appConfig) {\n let homepage;\n const { process } = window;\n if (process && process.env && process.env.PUBLIC_URL) {\n homepage = process.env.PUBLIC_URL;\n }\n\n window.info = {\n version,\n homepage,\n };\n\n // For debugging\n //if (process.env.node_env === 'development') {\n window.cornerstone = cornerstone;\n window.cornerstoneWADOImageLoader = cornerstoneWADOImageLoader;\n //}\n\n cornerstoneWADOImageLoader.external.cornerstone = cornerstone;\n cornerstoneWADOImageLoader.external.dicomParser = dicomParser;\n\n OHIF.user.getAccessToken = () => {\n // TODO: Get the Redux store from somewhere else\n const state = window.store.getState();\n if (!state.oidc || !state.oidc.user) {\n return;\n }\n\n return state.oidc.user.access_token;\n };\n\n OHIF.errorHandler.getHTTPErrorHandler = () => {\n // const { appConfig = {} } = AppContext;\n\n return appConfig.httpErrorHandler;\n };\n\n cornerstoneWADOImageLoader.configure({\n beforeSend: function(xhr) {\n const headers = OHIF.DICOMWeb.getAuthorizationHeader();\n\n if (headers.Authorization) {\n xhr.setRequestHeader('Authorization', headers.Authorization);\n }\n },\n errorInterceptor: error => {\n // const { appConfig = {} } = AppContext;\n\n if (typeof appConfig.httpErrorHandler === 'function') {\n appConfig.httpErrorHandler(error);\n }\n },\n });\n}\n","import React from 'react';\nimport './NotFound.css';\nimport { Link } from 'react-router-dom';\nimport { useAppContext } from '../context/AppContext';\n\nexport default function NotFound({ message = 'Sorry, this page does not exist.', showGoBackButton = true }) {\n \n const context = useAppContext();\n \n return (\n
    \n
    \n

    {message}

    \n {showGoBackButton && context.appConfig.showStudyList && (\n
    \n Go back to the Study List\n
    \n )}\n
    \n
    \n );\n}\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Thumbnail } from './Thumbnail.js';\nimport './StudyBrowser.styl';\n\nfunction StudyBrowser(props) {\n const {\n studies,\n onThumbnailClick,\n onThumbnailDoubleClick,\n supportsDrag,\n showThumbnailProgressBar,\n } = props;\n\n return (\n
    \n
    \n {studies\n .map((study, studyIndex) => {\n const { StudyInstanceUID } = study;\n return study.thumbnails.map((thumb, thumbIndex) => {\n // TODO: Thumb has more props than we care about?\n const {\n active,\n altImageText,\n displaySetInstanceUID,\n imageId,\n derivedDisplaySetsNumber,\n numImageFrames,\n SeriesDescription,\n SeriesNumber,\n hasWarnings,\n hasDerivedDisplaySets,\n } = thumb;\n\n return (\n \n \n
    \n );\n });\n })\n .flat()}\n
    \n \n );\n}\n\nconst noop = () => {};\n\nStudyBrowser.propTypes = {\n studies: PropTypes.arrayOf(\n PropTypes.shape({\n StudyInstanceUID: PropTypes.string.isRequired,\n thumbnails: PropTypes.arrayOf(\n PropTypes.shape({\n altImageText: PropTypes.string,\n displaySetInstanceUID: PropTypes.string.isRequired,\n imageId: PropTypes.string,\n derivedDisplaySetsNumber: PropTypes.number,\n numImageFrames: PropTypes.number,\n SeriesDescription: PropTypes.string,\n SeriesNumber: PropTypes.number,\n stackPercentComplete: PropTypes.number,\n })\n ),\n })\n ).isRequired,\n supportsDrag: PropTypes.bool,\n onThumbnailClick: PropTypes.func,\n onThumbnailDoubleClick: PropTypes.func,\n showThumbnailProgressBar: PropTypes.bool,\n};\n\nStudyBrowser.defaultProps = {\n studies: [],\n supportsDrag: true,\n onThumbnailClick: noop,\n onThumbnailDoubleClick: noop,\n showThumbnailProgressBar: true,\n};\n\nexport { StudyBrowser };\n","const id = 'org.ohif.dicom-sr';\n\nexport default id;\n\nconst SOPClassHandlerName = 'dicom-sr';\nconst SOPClassHandlerId = `${id}.sopClassHandlerModule.${SOPClassHandlerName}`;\nexport { SOPClassHandlerName, SOPClassHandlerId };\n","import React from 'react';\n\nconst UserManagerContext = React.createContext();\n\nexport default UserManagerContext;\n","import './OHIFLogo.css';\n\nimport { Icon } from '@ohif/ui';\nimport React from 'react';\n\nfunction OHIFLogo() {\n return (\n \n \n {/* Logo text would fit smaller displays at two lines:\n *\n * Open Health\n * Imaging Foundation\n *\n * Or as `OHIF` on really small displays\n */}\n \n \n );\n}\n\nexport default OHIFLogo;\n","export default {\n COMMANDS: 'commandsModule',\n PANEL: 'panelModule',\n SOP_CLASS_HANDLER: 'sopClassHandlerModule',\n TOOLBAR: 'toolbarModule',\n VIEWPORT: 'viewportModule',\n};\n","import React, { useEffect, useCallback } from 'react';\nimport { View2D } from 'react-vtkjs-viewport';\nimport PropTypes from 'prop-types';\n\nimport './VTKViewport.css';\n\nconst VTKViewport = props => {\n const style = { width: '100%', height: '100%', position: 'relative' };\n\n const setViewportActiveHandler = useCallback(() => {\n const { setViewportActive, viewportIndex, activeViewportIndex } = props;\n\n if (viewportIndex !== activeViewportIndex) {\n // set in Connected\n setViewportActive();\n }\n });\n\n useEffect(() => {\n const handleScrollEvent = evt => {\n const vtkViewportApiReference = props.onScroll(props.viewportIndex) || {};\n const viewportUID = vtkViewportApiReference.uid;\n const viewportWasScrolled = viewportUID === evt.detail.uid;\n\n if (viewportWasScrolled) {\n setViewportActiveHandler();\n }\n };\n\n window.addEventListener('vtkscrollevent', handleScrollEvent);\n return () =>\n window.removeEventListener('vtkscrollevent', handleScrollEvent);\n }, [props, props.onScroll, props.viewportIndex, setViewportActiveHandler]);\n\n return (\n \n \n \n );\n};\n\nVTKViewport.propTypes = {\n setViewportActive: PropTypes.func.isRequired,\n viewportIndex: PropTypes.number.isRequired,\n activeViewportIndex: PropTypes.number.isRequired,\n /* Receives viewportIndex */\n onScroll: PropTypes.func,\n};\n\nVTKViewport.defaultProps = {\n onScroll: () => {},\n};\n\nexport default VTKViewport;\n","import OHIF from '@ohif/core';\nimport { connect } from 'react-redux';\nimport VTKViewport from './VTKViewport';\n\nconst { setViewportActive, setViewportSpecificData } = OHIF.redux.actions;\n\nconst mapStateToProps = (state, ownProps) => {\n let dataFromStore;\n\n if (state.extensions && state.extensions.vtk) {\n dataFromStore = state.extensions.vtk;\n }\n\n // If this is the active viewport, enable prefetching.\n const { viewportIndex } = ownProps;\n const isActive = viewportIndex === state.viewports.activeViewportIndex;\n const viewportLayout = state.viewports.layout.viewports[viewportIndex];\n const pluginDetails = viewportLayout.vtk || {};\n\n return {\n activeViewportIndex: state.viewports.activeViewportIndex,\n layout: state.viewports.layout,\n isActive,\n ...pluginDetails,\n // Hopefully this doesn't break anything under the hood for this one\n // activeTool: activeButton && activeButton.command,\n ...dataFromStore,\n enableStackPrefetch: isActive,\n };\n};\n\nconst mapDispatchToProps = (dispatch, ownProps) => {\n const { viewportIndex } = ownProps;\n\n return {\n setViewportActive: () => {\n dispatch(setViewportActive(viewportIndex));\n },\n\n setViewportSpecificData: data => {\n dispatch(setViewportSpecificData(viewportIndex, data));\n },\n };\n};\n\nconst mergeProps = (propsFromState, propsFromDispatch, ownProps) => {\n const { afterCreation } = propsFromState;\n\n const props = {\n ...propsFromState,\n ...propsFromDispatch,\n ...ownProps,\n /**\n * Our component sets up the underlying dom element on \"componentDidMount\"\n * for use with VTK.\n *\n * The onCreated prop passes back an Object containing many of the internal\n * components of the VTK scene. We can grab a reference to these here, to\n * make playing with VTK's native methods easier.\n *\n * A similar approach is taken with the Cornerstone extension.\n */\n onCreated: api => {\n // Store the API details for later\n //setViewportSpecificData({ vtkApi: api });\n\n if (afterCreation && typeof afterCreation === 'function') {\n afterCreation(api);\n }\n },\n };\n return props;\n};\n\nconst ConnectedVTKViewport = connect(\n mapStateToProps,\n mapDispatchToProps,\n mergeProps\n)(VTKViewport);\n\nexport default ConnectedVTKViewport;\n","import './LoadingIndicator.css';\n\nimport React, { PureComponent } from 'react';\nimport { withTranslation } from 'react-i18next';\nimport PropTypes from 'prop-types';\n\nclass LoadingIndicator extends PureComponent {\n static propTypes = {\n percentComplete: PropTypes.number.isRequired,\n error: PropTypes.object,\n };\n\n static defaultProps = {\n percentComplete: 0,\n error: null,\n };\n\n render() {\n let percComplete;\n if (this.props.percentComplete && this.props.percentComplete !== 100) {\n percComplete = `${this.props.percentComplete}%`;\n }\n\n return (\n \n {this.props.error ? (\n
    \n
    \n

    Error Loading Image

    \n

    An error has occurred.

    \n

    {this.props.error.message}

    \n
    \n
    \n ) : (\n
    \n
    \n

    \n {this.props.t('Loading...')}\n \n {percComplete}\n

    \n
    \n
    \n )}\n
    \n );\n }\n}\n\nexport default withTranslation('Common')(LoadingIndicator);\n","import React, { Component } from 'react';\nimport { getImageData, loadImageData } from 'react-vtkjs-viewport';\nimport ConnectedVTKViewport from './ConnectedVTKViewport';\nimport LoadingIndicator from './LoadingIndicator.js';\nimport OHIF from '@ohif/core';\nimport PropTypes from 'prop-types';\nimport cornerstone from 'cornerstone-core';\nimport cornerstoneTools from 'cornerstone-tools';\nimport vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray';\nimport vtkImageData from 'vtk.js/Sources/Common/DataModel/ImageData';\nimport vtkVolume from 'vtk.js/Sources/Rendering/Core/Volume';\nimport vtkVolumeMapper from 'vtk.js/Sources/Rendering/Core/VolumeMapper';\n\nconst segmentationModule = cornerstoneTools.getModule('segmentation');\n\nconst { StackManager } = OHIF.utils;\n\n// TODO: Figure out where we plan to put this long term\nconst volumeCache = {};\nconst labelmapCache = {};\n\n/**\n * Create a labelmap image with the same dimensions as our background volume.\n *\n * @param backgroundImageData vtkImageData\n */\n/* TODO: Not currently used until we have drawing tools in vtkjs.\nfunction createLabelMapImageData(backgroundImageData) {\n // TODO => Need to do something like this if we start drawing a new segmentation\n // On a vtkjs viewport.\n\n const labelMapData = vtkImageData.newInstance(\n backgroundImageData.get('spacing', 'origin', 'direction')\n );\n labelMapData.setDimensions(backgroundImageData.getDimensions());\n labelMapData.computeTransforms();\n\n const values = new Uint8Array(backgroundImageData.getNumberOfPoints());\n const dataArray = vtkDataArray.newInstance({\n numberOfComponents: 1, // labelmap with single component\n values,\n });\n labelMapData.getPointData().setScalars(dataArray);\n\n return labelMapData;\n} */\n\nclass OHIFVTKViewport extends Component {\n state = {\n volumes: null,\n paintFilterLabelMapImageData: null,\n paintFilterBackgroundImageData: null,\n percentComplete: 0,\n isLoaded: false,\n };\n\n static propTypes = {\n viewportData: PropTypes.shape({\n studies: PropTypes.array.isRequired,\n displaySet: PropTypes.shape({\n StudyInstanceUID: PropTypes.string.isRequired,\n displaySetInstanceUID: PropTypes.string.isRequired,\n sopClassUIDs: PropTypes.arrayOf(PropTypes.string),\n SOPInstanceUID: PropTypes.string,\n frameIndex: PropTypes.number,\n }),\n }),\n viewportIndex: PropTypes.number.isRequired,\n children: PropTypes.node,\n onScroll: PropTypes.func,\n servicesManager: PropTypes.object.isRequired,\n };\n\n static defaultProps = {\n onScroll: () => { },\n };\n\n static id = 'OHIFVTKViewport';\n\n static init() {\n console.log('OHIFVTKViewport init()');\n }\n\n static destroy() {\n console.log('OHIFVTKViewport destroy()');\n StackManager.clearStacks();\n }\n\n static getCornerstoneStack(\n studies,\n StudyInstanceUID,\n displaySetInstanceUID,\n SOPInstanceUID,\n frameIndex\n ) {\n // Create shortcut to displaySet\n const study = studies.find(\n study => study.StudyInstanceUID === StudyInstanceUID\n );\n\n const displaySet = study.displaySets.find(set => {\n return set.displaySetInstanceUID === displaySetInstanceUID;\n });\n\n // Get stack from Stack Manager\n const storedStack = StackManager.findOrCreateStack(study, displaySet);\n\n // Clone the stack here so we don't mutate it\n const stack = Object.assign({}, storedStack);\n\n if (frameIndex !== undefined) {\n stack.currentImageIdIndex = frameIndex;\n } else if (SOPInstanceUID) {\n const index = stack.imageIds.findIndex(imageId => {\n const imageIdSOPInstanceUID = cornerstone.metaData.get(\n 'SOPInstanceUID',\n imageId\n );\n\n return imageIdSOPInstanceUID === SOPInstanceUID;\n });\n\n if (index > -1) {\n stack.currentImageIdIndex = index;\n }\n } else {\n stack.currentImageIdIndex = 0;\n }\n\n return stack;\n }\n\n getViewportData = (\n studies,\n StudyInstanceUID,\n displaySetInstanceUID,\n SOPClassUID,\n SOPInstanceUID,\n frameIndex\n ) => {\n const { UINotificationService } = this.props.servicesManager.services;\n\n const stack = OHIFVTKViewport.getCornerstoneStack(\n studies,\n StudyInstanceUID,\n displaySetInstanceUID,\n SOPClassUID,\n SOPInstanceUID,\n frameIndex\n );\n\n const imageDataObject = getImageData(stack.imageIds, displaySetInstanceUID);\n let labelmapDataObject;\n let labelmapColorLUT;\n\n const firstImageId = stack.imageIds[0];\n const { state } = segmentationModule;\n const brushStackState = state.series[firstImageId];\n\n if (brushStackState) {\n const { activeLabelmapIndex } = brushStackState;\n const labelmap3D = brushStackState.labelmaps3D[activeLabelmapIndex];\n\n if (\n brushStackState.labelmaps3D.length > 1 &&\n this.props.viewportIndex === 0\n ) {\n UINotificationService.show({\n title: 'Overlapping Segmentation Found',\n message:\n 'Overlapping segmentations cannot be displayed when in MPR mode',\n type: 'info',\n });\n }\n\n this.segmentsDefaultProperties = labelmap3D.segmentsHidden.map(\n isHidden => {\n return { visible: !isHidden };\n }\n );\n\n const vtkLabelmapID = `${firstImageId}_${activeLabelmapIndex}`;\n\n if (labelmapCache[vtkLabelmapID]) {\n labelmapDataObject = labelmapCache[vtkLabelmapID];\n } else {\n // TODO -> We need an imageId based getter in cornerstoneTools\n const labelmapBuffer = labelmap3D.buffer;\n\n // Create VTK Image Data with buffer as input\n labelmapDataObject = vtkImageData.newInstance();\n\n const dataArray = vtkDataArray.newInstance({\n numberOfComponents: 1, // labelmap with single component\n values: new Uint16Array(labelmapBuffer),\n });\n\n labelmapDataObject.getPointData().setScalars(dataArray);\n labelmapDataObject.setDimensions(...imageDataObject.dimensions);\n labelmapDataObject.setSpacing(\n ...imageDataObject.vtkImageData.getSpacing()\n );\n labelmapDataObject.setOrigin(\n ...imageDataObject.vtkImageData.getOrigin()\n );\n labelmapDataObject.setDirection(\n ...imageDataObject.vtkImageData.getDirection()\n );\n\n // Cache the labelmap volume.\n labelmapCache[vtkLabelmapID] = labelmapDataObject;\n }\n\n labelmapColorLUT = state.colorLutTables[labelmap3D.colorLUTIndex];\n }\n\n return {\n imageDataObject,\n labelmapDataObject,\n labelmapColorLUT,\n };\n };\n\n /**\n *\n *\n * @param {object} imageDataObject\n * @param {object} imageDataObject.vtkImageData\n * @param {object} imageDataObject.imageMetaData0\n * @param {number} [imageDataObject.imageMetaData0.WindowWidth] - The volume's initial WindowWidth\n * @param {number} [imageDataObject.imageMetaData0.WindowCenter] - The volume's initial WindowCenter\n * @param {string} imageDataObject.imageMetaData0.Modality - CT, MR, PT, etc\n * @param {string} displaySetInstanceUID\n * @returns vtkVolumeActor\n * @memberof OHIFVTKViewport\n */\n getOrCreateVolume(imageDataObject, displaySetInstanceUID) {\n if (volumeCache[displaySetInstanceUID]) {\n return volumeCache[displaySetInstanceUID];\n }\n\n const { vtkImageData, imageMetaData0 } = imageDataObject;\n // TODO -> Should update react-vtkjs-viewport and react-cornerstone-viewports\n // internals to use naturalized DICOM JSON names.\n const {\n windowWidth: WindowWidth,\n windowCenter: WindowCenter,\n modality: Modality,\n } = imageMetaData0;\n\n const { lower, upper } = _getRangeFromWindowLevels(\n WindowWidth,\n WindowCenter,\n Modality\n );\n const volumeActor = vtkVolume.newInstance();\n const volumeMapper = vtkVolumeMapper.newInstance();\n\n volumeActor.setMapper(volumeMapper);\n volumeMapper.setInputData(vtkImageData);\n\n volumeActor\n .getProperty()\n .getRGBTransferFunction(0)\n .setRange(lower, upper);\n\n const spacing = vtkImageData.getSpacing();\n // Set the sample distance to half the mean length of one side. This is where the divide by 6 comes from.\n // https://github.com/Kitware/VTK/blob/6b559c65bb90614fb02eb6d1b9e3f0fca3fe4b0b/Rendering/VolumeOpenGL2/vtkSmartVolumeMapper.cxx#L344\n const sampleDistance = (spacing[0] + spacing[1] + spacing[2]) / 6;\n\n volumeMapper.setSampleDistance(sampleDistance);\n\n // Be generous to suppress warnings, as the logging really hurts performance.\n // TODO: maybe we should auto adjust samples to 1000.\n volumeMapper.setMaximumSamplesPerRay(4000);\n\n volumeCache[displaySetInstanceUID] = volumeActor;\n\n return volumeActor;\n }\n\n setStateFromProps() {\n const { studies, displaySet } = this.props.viewportData;\n const {\n StudyInstanceUID,\n displaySetInstanceUID,\n sopClassUIDs,\n SOPInstanceUID,\n frameIndex,\n } = displaySet;\n\n if (sopClassUIDs.length > 1) {\n console.warn(\n 'More than one SOPClassUID in the same series is not yet supported.'\n );\n }\n\n const study = studies.find(\n study => study.StudyInstanceUID === StudyInstanceUID\n );\n\n const dataDetails = {\n studyDate: study.studyDate,\n studyTime: study.studyTime,\n studyDescription: study.studyDescription,\n patientName: study.patientName,\n patientId: study.patientId,\n seriesNumber: String(displaySet.seriesNumber),\n seriesDescription: displaySet.seriesDescription,\n };\n\n try {\n const {\n imageDataObject,\n labelmapDataObject,\n labelmapColorLUT,\n } = this.getViewportData(\n studies,\n StudyInstanceUID,\n displaySetInstanceUID,\n SOPInstanceUID,\n frameIndex\n );\n\n this.imageDataObject = imageDataObject;\n\n /* TODO: Not currently used until we have drawing tools in vtkjs.\n if (!labelmap) {\n labelmap = createLabelMapImageData(data);\n } */\n\n const volumeActor = this.getOrCreateVolume(\n imageDataObject,\n displaySetInstanceUID\n );\n\n this.setState(\n {\n percentComplete: 0,\n dataDetails,\n },\n () => {\n this.loadProgressively(imageDataObject);\n\n // TODO: There must be a better way to do this.\n // We do this so that if all the data is available the react-vtkjs-viewport\n // Will render _something_ before the volumes are set and the volume\n // Construction that happens in react-vtkjs-viewport locks up the CPU.\n setTimeout(() => {\n this.setState({\n volumes: [volumeActor],\n paintFilterLabelMapImageData: labelmapDataObject,\n paintFilterBackgroundImageData: imageDataObject.vtkImageData,\n labelmapColorLUT,\n });\n }, 200);\n }\n );\n } catch (error) {\n const errorTitle = 'Failed to load 2D MPR';\n console.error(errorTitle, error);\n const {\n UINotificationService,\n LoggerService,\n } = this.props.servicesManager.services;\n if (this.props.viewportIndex === 0) {\n const message = error.message.includes('buffer')\n ? 'Dataset is too big to display in MPR'\n : error.message;\n LoggerService.error({ error, message });\n UINotificationService.show({\n title: errorTitle,\n message,\n type: 'error',\n autoClose: false,\n action: {\n label: 'Exit 2D MPR',\n onClick: ({ close }) => {\n // context: 'ACTIVE_VIEWPORT::VTK',\n close();\n this.props.commandsManager.runCommand('setCornerstoneLayout');\n },\n },\n });\n }\n this.setState({ isLoaded: true });\n }\n }\n\n componentDidMount() {\n this.setStateFromProps();\n }\n\n componentDidUpdate(prevProps, prevState) {\n const { displaySet } = this.props.viewportData;\n const prevDisplaySet = prevProps.viewportData.displaySet;\n\n if (\n displaySet.displaySetInstanceUID !==\n prevDisplaySet.displaySetInstanceUID ||\n displaySet.SOPInstanceUID !== prevDisplaySet.SOPInstanceUID ||\n displaySet.frameIndex !== prevDisplaySet.frameIndex\n ) {\n this.setStateFromProps();\n }\n }\n\n loadProgressively(imageDataObject) {\n loadImageData(imageDataObject);\n\n const { isLoading, imageIds } = imageDataObject;\n\n if (!isLoading) {\n this.setState({ isLoaded: true });\n return;\n }\n\n const NumberOfFrames = imageIds.length;\n\n const onPixelDataInsertedCallback = numberProcessed => {\n const percentComplete = Math.floor(\n (numberProcessed * 100) / NumberOfFrames\n );\n\n if (percentComplete !== this.state.percentComplete) {\n this.setState({\n percentComplete,\n });\n }\n };\n\n const onPixelDataInsertedErrorCallback = error => {\n const {\n UINotificationService,\n LoggerService,\n } = this.props.servicesManager.services;\n\n if (!this.hasError) {\n if (this.props.viewportIndex === 0) {\n // Only show the notification from one viewport 1 in MPR2D.\n LoggerService.error({ error, message: error.message });\n UINotificationService.show({\n title: 'MPR Load Error',\n message: error.message,\n type: 'error',\n autoClose: false,\n });\n }\n\n this.hasError = true;\n }\n };\n\n const onAllPixelDataInsertedCallback = () => {\n this.setState({\n isLoaded: true,\n });\n };\n\n imageDataObject.onPixelDataInserted(onPixelDataInsertedCallback);\n imageDataObject.onAllPixelDataInserted(onAllPixelDataInsertedCallback);\n imageDataObject.onPixelDataInsertedError(onPixelDataInsertedErrorCallback);\n }\n\n render() {\n let childrenWithProps = null;\n const { configuration } = segmentationModule;\n\n // TODO: Does it make more sense to use Context?\n if (this.props.children && this.props.children.length) {\n childrenWithProps = this.props.children.map((child, index) => {\n return (\n child &&\n React.cloneElement(child, {\n viewportIndex: this.props.viewportIndex,\n key: index,\n })\n );\n });\n }\n\n const style = { width: '100%', height: '100%', position: 'relative' };\n\n return (\n <>\n
    \n {!this.state.isLoaded && (\n \n )}\n {this.state.volumes && (\n {\n this.setStateFromProps();\n },\n }}\n onScroll={this.props.onScroll}\n />\n )}\n
    \n )}\n {childrenWithProps}\n \n );\n }\n}\n\n/**\n * Takes window levels and converts them to a range (lower/upper)\n * for use with VTK RGBTransferFunction\n *\n * @private\n * @param {number} [width] - the width of our window\n * @param {number} [center] - the center of our window\n * @param {string} [Modality] - 'PT', 'CT', etc.\n * @returns { lower, upper } - range\n */\nfunction _getRangeFromWindowLevels(width, center, Modality = undefined) {\n // For PET just set the range to 0-5 SUV\n if (Modality === 'PT') {\n return { lower: 0, upper: 5 };\n }\n\n const levelsAreNotNumbers = isNaN(center) || isNaN(width);\n\n if (levelsAreNotNumbers) {\n return { lower: 0, upper: 512 };\n }\n\n return {\n lower: center - width / 2.0,\n upper: center + width / 2.0,\n };\n}\n\nexport default OHIFVTKViewport;\n","var map = {\n\t\"./af\": 297,\n\t\"./af.js\": 297,\n\t\"./ar\": 298,\n\t\"./ar-dz\": 299,\n\t\"./ar-dz.js\": 299,\n\t\"./ar-kw\": 300,\n\t\"./ar-kw.js\": 300,\n\t\"./ar-ly\": 301,\n\t\"./ar-ly.js\": 301,\n\t\"./ar-ma\": 302,\n\t\"./ar-ma.js\": 302,\n\t\"./ar-sa\": 303,\n\t\"./ar-sa.js\": 303,\n\t\"./ar-tn\": 304,\n\t\"./ar-tn.js\": 304,\n\t\"./ar.js\": 298,\n\t\"./az\": 305,\n\t\"./az.js\": 305,\n\t\"./be\": 306,\n\t\"./be.js\": 306,\n\t\"./bg\": 307,\n\t\"./bg.js\": 307,\n\t\"./bm\": 308,\n\t\"./bm.js\": 308,\n\t\"./bn\": 309,\n\t\"./bn.js\": 309,\n\t\"./bo\": 310,\n\t\"./bo.js\": 310,\n\t\"./br\": 311,\n\t\"./br.js\": 311,\n\t\"./bs\": 312,\n\t\"./bs.js\": 312,\n\t\"./ca\": 313,\n\t\"./ca.js\": 313,\n\t\"./cs\": 314,\n\t\"./cs.js\": 314,\n\t\"./cv\": 315,\n\t\"./cv.js\": 315,\n\t\"./cy\": 316,\n\t\"./cy.js\": 316,\n\t\"./da\": 317,\n\t\"./da.js\": 317,\n\t\"./de\": 318,\n\t\"./de-at\": 319,\n\t\"./de-at.js\": 319,\n\t\"./de-ch\": 320,\n\t\"./de-ch.js\": 320,\n\t\"./de.js\": 318,\n\t\"./dv\": 321,\n\t\"./dv.js\": 321,\n\t\"./el\": 322,\n\t\"./el.js\": 322,\n\t\"./en-SG\": 323,\n\t\"./en-SG.js\": 323,\n\t\"./en-au\": 324,\n\t\"./en-au.js\": 324,\n\t\"./en-ca\": 325,\n\t\"./en-ca.js\": 325,\n\t\"./en-gb\": 326,\n\t\"./en-gb.js\": 326,\n\t\"./en-ie\": 327,\n\t\"./en-ie.js\": 327,\n\t\"./en-il\": 328,\n\t\"./en-il.js\": 328,\n\t\"./en-nz\": 329,\n\t\"./en-nz.js\": 329,\n\t\"./eo\": 330,\n\t\"./eo.js\": 330,\n\t\"./es\": 331,\n\t\"./es-do\": 332,\n\t\"./es-do.js\": 332,\n\t\"./es-us\": 333,\n\t\"./es-us.js\": 333,\n\t\"./es.js\": 331,\n\t\"./et\": 334,\n\t\"./et.js\": 334,\n\t\"./eu\": 335,\n\t\"./eu.js\": 335,\n\t\"./fa\": 336,\n\t\"./fa.js\": 336,\n\t\"./fi\": 337,\n\t\"./fi.js\": 337,\n\t\"./fo\": 338,\n\t\"./fo.js\": 338,\n\t\"./fr\": 339,\n\t\"./fr-ca\": 340,\n\t\"./fr-ca.js\": 340,\n\t\"./fr-ch\": 341,\n\t\"./fr-ch.js\": 341,\n\t\"./fr.js\": 339,\n\t\"./fy\": 342,\n\t\"./fy.js\": 342,\n\t\"./ga\": 343,\n\t\"./ga.js\": 343,\n\t\"./gd\": 344,\n\t\"./gd.js\": 344,\n\t\"./gl\": 345,\n\t\"./gl.js\": 345,\n\t\"./gom-latn\": 346,\n\t\"./gom-latn.js\": 346,\n\t\"./gu\": 347,\n\t\"./gu.js\": 347,\n\t\"./he\": 348,\n\t\"./he.js\": 348,\n\t\"./hi\": 349,\n\t\"./hi.js\": 349,\n\t\"./hr\": 350,\n\t\"./hr.js\": 350,\n\t\"./hu\": 351,\n\t\"./hu.js\": 351,\n\t\"./hy-am\": 352,\n\t\"./hy-am.js\": 352,\n\t\"./id\": 353,\n\t\"./id.js\": 353,\n\t\"./is\": 354,\n\t\"./is.js\": 354,\n\t\"./it\": 355,\n\t\"./it-ch\": 356,\n\t\"./it-ch.js\": 356,\n\t\"./it.js\": 355,\n\t\"./ja\": 357,\n\t\"./ja.js\": 357,\n\t\"./jv\": 358,\n\t\"./jv.js\": 358,\n\t\"./ka\": 359,\n\t\"./ka.js\": 359,\n\t\"./kk\": 360,\n\t\"./kk.js\": 360,\n\t\"./km\": 361,\n\t\"./km.js\": 361,\n\t\"./kn\": 362,\n\t\"./kn.js\": 362,\n\t\"./ko\": 363,\n\t\"./ko.js\": 363,\n\t\"./ku\": 364,\n\t\"./ku.js\": 364,\n\t\"./ky\": 365,\n\t\"./ky.js\": 365,\n\t\"./lb\": 366,\n\t\"./lb.js\": 366,\n\t\"./lo\": 367,\n\t\"./lo.js\": 367,\n\t\"./lt\": 368,\n\t\"./lt.js\": 368,\n\t\"./lv\": 369,\n\t\"./lv.js\": 369,\n\t\"./me\": 370,\n\t\"./me.js\": 370,\n\t\"./mi\": 371,\n\t\"./mi.js\": 371,\n\t\"./mk\": 372,\n\t\"./mk.js\": 372,\n\t\"./ml\": 373,\n\t\"./ml.js\": 373,\n\t\"./mn\": 374,\n\t\"./mn.js\": 374,\n\t\"./mr\": 375,\n\t\"./mr.js\": 375,\n\t\"./ms\": 376,\n\t\"./ms-my\": 377,\n\t\"./ms-my.js\": 377,\n\t\"./ms.js\": 376,\n\t\"./mt\": 378,\n\t\"./mt.js\": 378,\n\t\"./my\": 379,\n\t\"./my.js\": 379,\n\t\"./nb\": 380,\n\t\"./nb.js\": 380,\n\t\"./ne\": 381,\n\t\"./ne.js\": 381,\n\t\"./nl\": 382,\n\t\"./nl-be\": 383,\n\t\"./nl-be.js\": 383,\n\t\"./nl.js\": 382,\n\t\"./nn\": 384,\n\t\"./nn.js\": 384,\n\t\"./pa-in\": 385,\n\t\"./pa-in.js\": 385,\n\t\"./pl\": 386,\n\t\"./pl.js\": 386,\n\t\"./pt\": 387,\n\t\"./pt-br\": 388,\n\t\"./pt-br.js\": 388,\n\t\"./pt.js\": 387,\n\t\"./ro\": 389,\n\t\"./ro.js\": 389,\n\t\"./ru\": 390,\n\t\"./ru.js\": 390,\n\t\"./sd\": 391,\n\t\"./sd.js\": 391,\n\t\"./se\": 392,\n\t\"./se.js\": 392,\n\t\"./si\": 393,\n\t\"./si.js\": 393,\n\t\"./sk\": 394,\n\t\"./sk.js\": 394,\n\t\"./sl\": 395,\n\t\"./sl.js\": 395,\n\t\"./sq\": 396,\n\t\"./sq.js\": 396,\n\t\"./sr\": 397,\n\t\"./sr-cyrl\": 398,\n\t\"./sr-cyrl.js\": 398,\n\t\"./sr.js\": 397,\n\t\"./ss\": 399,\n\t\"./ss.js\": 399,\n\t\"./sv\": 400,\n\t\"./sv.js\": 400,\n\t\"./sw\": 401,\n\t\"./sw.js\": 401,\n\t\"./ta\": 402,\n\t\"./ta.js\": 402,\n\t\"./te\": 403,\n\t\"./te.js\": 403,\n\t\"./tet\": 404,\n\t\"./tet.js\": 404,\n\t\"./tg\": 405,\n\t\"./tg.js\": 405,\n\t\"./th\": 406,\n\t\"./th.js\": 406,\n\t\"./tl-ph\": 407,\n\t\"./tl-ph.js\": 407,\n\t\"./tlh\": 408,\n\t\"./tlh.js\": 408,\n\t\"./tr\": 409,\n\t\"./tr.js\": 409,\n\t\"./tzl\": 410,\n\t\"./tzl.js\": 410,\n\t\"./tzm\": 411,\n\t\"./tzm-latn\": 412,\n\t\"./tzm-latn.js\": 412,\n\t\"./tzm.js\": 411,\n\t\"./ug-cn\": 413,\n\t\"./ug-cn.js\": 413,\n\t\"./uk\": 414,\n\t\"./uk.js\": 414,\n\t\"./ur\": 415,\n\t\"./ur.js\": 415,\n\t\"./uz\": 416,\n\t\"./uz-latn\": 417,\n\t\"./uz-latn.js\": 417,\n\t\"./uz.js\": 416,\n\t\"./vi\": 418,\n\t\"./vi.js\": 418,\n\t\"./x-pseudo\": 419,\n\t\"./x-pseudo.js\": 419,\n\t\"./yo\": 420,\n\t\"./yo.js\": 420,\n\t\"./zh-cn\": 421,\n\t\"./zh-cn.js\": 421,\n\t\"./zh-hk\": 422,\n\t\"./zh-hk.js\": 422,\n\t\"./zh-tw\": 423,\n\t\"./zh-tw.js\": 423\n};\n\n\nfunction webpackContext(req) {\n\tvar id = webpackContextResolve(req);\n\treturn __webpack_require__(id);\n}\nfunction webpackContextResolve(req) {\n\tif(!__webpack_require__.o(map, req)) {\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\treturn map[req];\n}\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = 769;","import { redux } from '@ohif/core';\n\nconst { setViewportLayoutAndData } = redux.actions;\n\n// TODO: Should not be getting dispatch from the window, but I'm not sure how else to do it cleanly\nexport default function setLayoutAndViewportData(layout, viewportSpecificData) {\n const action = setViewportLayoutAndData(layout, viewportSpecificData);\n\n window.store.dispatch(action);\n}\n","import setLayoutAndViewportData from './setLayoutAndViewportData.js';\n\nexport default function setMPRLayout(\n displaySet,\n viewportPropsArray,\n numRows = 1,\n numColumns = 1\n) {\n return new Promise((resolve, reject) => {\n const viewports = [];\n const numViewports = numRows * numColumns;\n\n if (viewportPropsArray && viewportPropsArray.length !== numViewports) {\n reject(\n new Error(\n 'viewportProps is supplied but its length is not equal to numViewports'\n )\n );\n }\n\n const viewportSpecificData = {};\n\n for (let i = 0; i < numViewports; i++) {\n viewports.push({});\n viewportSpecificData[i] = displaySet;\n viewportSpecificData[i].plugin = 'vtk';\n }\n\n const apis = [];\n viewports.forEach((viewport, index) => {\n apis[index] = null;\n const viewportProps = viewportPropsArray[index];\n viewports[index] = Object.assign({}, viewports[index], {\n vtk: {\n mode: 'mpr', // TODO: not used\n afterCreation: api => {\n apis[index] = api;\n\n if (apis.every(a => !!a)) {\n resolve(apis);\n }\n },\n ...viewportProps,\n },\n });\n });\n\n setLayoutAndViewportData(\n {\n numRows,\n numColumns,\n viewports,\n },\n viewportSpecificData\n );\n });\n}\n","import setLayoutAndViewportData from './setLayoutAndViewportData.js';\n\nexport default function setViewportToVTK(\n displaySet,\n viewportIndex,\n numRows,\n numColumns,\n layout,\n viewportSpecificData\n) {\n return new Promise((resolve, reject) => {\n /*const currentData = layout.viewports[viewportIndex];\n if (currentData && currentData.plugin === 'vtk') {\n reject(new Error('Should not have reached this point??'));\n }*/\n\n const viewports = layout.viewports.slice();\n\n viewports[viewportIndex] = Object.assign({}, viewports[viewportIndex], {\n // plugin: 'vtk',\n vtk: {\n mode: 'mpr', // TODO: not used\n afterCreation: api => {\n resolve(api);\n },\n },\n });\n\n const updatedViewportData = viewportSpecificData;\n\n setLayoutAndViewportData(\n {\n numRows,\n numColumns,\n viewports,\n },\n updatedViewportData\n );\n });\n}\n","import throttle from 'lodash.throttle';\nimport {\n vtkInteractorStyleMPRWindowLevel,\n vtkInteractorStyleRotatableMPRCrosshairs,\n vtkSVGRotatableCrosshairsWidget,\n vtkInteractorStyleMPRRotate,\n} from 'react-vtkjs-viewport';\nimport { getImageData } from 'react-vtkjs-viewport';\nimport { vec3 } from 'gl-matrix';\nimport setMPRLayout from './utils/setMPRLayout.js';\nimport setViewportToVTK from './utils/setViewportToVTK.js';\nimport Constants from 'vtk.js/Sources/Rendering/Core/VolumeMapper/Constants.js';\nimport OHIFVTKViewport from './OHIFVTKViewport';\n\nconst { BlendMode } = Constants;\n\nconst commandsModule = ({ commandsManager, servicesManager }) => {\n const { UINotificationService, LoggerService } = servicesManager.services;\n\n // TODO: Put this somewhere else\n let apis = {};\n let defaultVOI;\n\n async function _getActiveViewportVTKApi(viewports) {\n const {\n numRows,\n numColumns,\n layout,\n viewportSpecificData,\n activeViewportIndex,\n } = viewports;\n\n const currentData = layout.viewports[activeViewportIndex];\n if (currentData && currentData.plugin === 'vtk') {\n // TODO: I was storing/pulling this from Redux but ran into weird issues\n if (apis[activeViewportIndex]) {\n return apis[activeViewportIndex];\n }\n }\n\n const displaySet = viewportSpecificData[activeViewportIndex];\n let api;\n if (!api) {\n try {\n api = await setViewportToVTK(\n displaySet,\n activeViewportIndex,\n numRows,\n numColumns,\n layout,\n viewportSpecificData\n );\n } catch (error) {\n throw new Error(error);\n }\n }\n\n return api;\n }\n\n function _setView(api, sliceNormal, viewUp) {\n const renderWindow = api.genericRenderWindow.getRenderWindow();\n const istyle = renderWindow.getInteractor().getInteractorStyle();\n istyle.setSliceNormal(...sliceNormal);\n istyle.setViewUp(...viewUp);\n\n renderWindow.render();\n }\n\n function getVOIFromCornerstoneViewport() {\n const dom = commandsManager.runCommand('getActiveViewportEnabledElement');\n const cornerstoneElement = cornerstone.getEnabledElement(dom);\n\n if (cornerstoneElement) {\n const imageId = cornerstoneElement.image.imageId;\n\n const Modality = cornerstone.metaData.get('Modality', imageId);\n\n if (Modality !== 'PT') {\n const { windowWidth, windowCenter } = cornerstoneElement.viewport.voi;\n\n return {\n windowWidth,\n windowCenter,\n };\n }\n }\n }\n\n function setVOI(voi) {\n const { windowWidth, windowCenter } = voi;\n const lower = windowCenter - windowWidth / 2.0;\n const upper = windowCenter + windowWidth / 2.0;\n\n const rgbTransferFunction = apis[0].volumes[0]\n .getProperty()\n .getRGBTransferFunction(0);\n\n rgbTransferFunction.setRange(lower, upper);\n\n apis.forEach(api => {\n api.updateVOI(windowWidth, windowCenter);\n });\n }\n\n const _convertModelToWorldSpace = (position, vtkImageData) => {\n const indexToWorld = vtkImageData.getIndexToWorld();\n const pos = vec3.create();\n\n position[0] += 0.5; /* Move to the centre of the voxel. */\n position[1] += 0.5; /* Move to the centre of the voxel. */\n position[2] += 0.5; /* Move to the centre of the voxel. */\n\n vec3.set(pos, position[0], position[1], position[2]);\n vec3.transformMat4(pos, pos, indexToWorld);\n\n return pos;\n };\n\n const actions = {\n getVtkApis: ({ index }) => {\n return apis[index];\n },\n resetMPRView() {\n // Reset orientation\n apis.forEach(api => api.resetOrientation());\n\n // Reset VOI\n if (defaultVOI) setVOI(defaultVOI);\n\n // Reset the crosshairs\n apis[0].svgWidgets.rotatableCrosshairsWidget.resetCrosshairs(apis, 0);\n },\n axial: async ({ viewports }) => {\n const api = await _getActiveViewportVTKApi(viewports);\n\n apis[viewports.activeViewportIndex] = api;\n\n _setView(api, [0, 0, 1], [0, -1, 0]);\n },\n sagittal: async ({ viewports }) => {\n const api = await _getActiveViewportVTKApi(viewports);\n\n apis[viewports.activeViewportIndex] = api;\n\n _setView(api, [1, 0, 0], [0, 0, 1]);\n },\n coronal: async ({ viewports }) => {\n const api = await _getActiveViewportVTKApi(viewports);\n\n apis[viewports.activeViewportIndex] = api;\n\n _setView(api, [0, 1, 0], [0, 0, 1]);\n },\n requestNewSegmentation: async ({ viewports }) => {\n const allViewports = Object.values(viewports.viewportSpecificData);\n const promises = allViewports.map(async (viewport, viewportIndex) => {\n let api = apis[viewportIndex];\n\n if (!api) {\n api = await _getActiveViewportVTKApi(viewports);\n apis[viewportIndex] = api;\n }\n\n api.requestNewSegmentation();\n api.updateImage();\n });\n await Promise.all(promises);\n },\n jumpToSlice: async ({\n viewports,\n studies,\n StudyInstanceUID,\n displaySetInstanceUID,\n SOPClassUID,\n SOPInstanceUID,\n segmentNumber,\n frameIndex,\n frame,\n done = () => {},\n }) => {\n let api = apis[viewports.activeViewportIndex];\n\n if (!api) {\n api = await _getActiveViewportVTKApi(viewports);\n apis[viewports.activeViewportIndex] = api;\n }\n\n const stack = OHIFVTKViewport.getCornerstoneStack(\n studies,\n StudyInstanceUID,\n displaySetInstanceUID,\n SOPClassUID,\n SOPInstanceUID,\n frameIndex\n );\n\n const imageDataObject = getImageData(\n stack.imageIds,\n displaySetInstanceUID\n );\n\n let pixelIndex = 0;\n let x = 0;\n let y = 0;\n let count = 0;\n\n const rows = imageDataObject.dimensions[1];\n const cols = imageDataObject.dimensions[0];\n\n for (let j = 0; j < rows; j++) {\n for (let i = 0; i < cols; i++) {\n // [i, j] =\n const pixel = frame.pixelData[pixelIndex];\n if (pixel === segmentNumber) {\n x += i;\n y += j;\n count++;\n }\n pixelIndex++;\n }\n }\n x /= count;\n y /= count;\n\n const position = [x, y, frameIndex];\n const worldPos = _convertModelToWorldSpace(\n position,\n imageDataObject.vtkImageData\n );\n\n api.svgWidgets.rotatableCrosshairsWidget.moveCrosshairs(worldPos, apis);\n done();\n },\n setSegmentationConfiguration: async ({\n viewports,\n globalOpacity,\n visible,\n renderOutline,\n outlineThickness,\n }) => {\n const allViewports = Object.values(viewports.viewportSpecificData);\n const promises = allViewports.map(async (viewport, viewportIndex) => {\n let api = apis[viewportIndex];\n\n if (!api) {\n api = await _getActiveViewportVTKApi(viewports);\n apis[viewportIndex] = api;\n }\n\n api.setGlobalOpacity(globalOpacity);\n api.setVisibility(visible);\n api.setOutlineThickness(outlineThickness);\n api.setOutlineRendering(renderOutline);\n api.updateImage();\n });\n await Promise.all(promises);\n },\n setSegmentConfiguration: async ({ viewports, visible, segmentNumber }) => {\n const allViewports = Object.values(viewports.viewportSpecificData);\n const promises = allViewports.map(async (viewport, viewportIndex) => {\n let api = apis[viewportIndex];\n\n if (!api) {\n api = await _getActiveViewportVTKApi(viewports);\n apis[viewportIndex] = api;\n }\n\n api.setSegmentVisibility(segmentNumber, visible);\n api.updateImage();\n });\n await Promise.all(promises);\n },\n enableRotateTool: () => {\n apis.forEach((api, apiIndex) => {\n const istyle = vtkInteractorStyleMPRRotate.newInstance();\n\n api.setInteractorStyle({\n istyle,\n configuration: { apis, apiIndex, uid: api.uid },\n });\n });\n },\n enableCrosshairsTool: () => {\n apis.forEach((api, apiIndex) => {\n const istyle = vtkInteractorStyleRotatableMPRCrosshairs.newInstance();\n\n api.setInteractorStyle({\n istyle,\n configuration: {\n apis,\n apiIndex,\n uid: api.uid,\n },\n });\n });\n\n const rotatableCrosshairsWidget =\n apis[0].svgWidgets.rotatableCrosshairsWidget;\n\n const referenceLines = rotatableCrosshairsWidget.getReferenceLines();\n\n // Initilise crosshairs if not initialised.\n if (!referenceLines) {\n rotatableCrosshairsWidget.resetCrosshairs(apis, 0);\n }\n },\n enableLevelTool: () => {\n function updateVOI(apis, windowWidth, windowCenter) {\n apis.forEach(api => {\n api.updateVOI(windowWidth, windowCenter);\n });\n }\n\n const throttledUpdateVOIs = throttle(updateVOI, 16, { trailing: true }); // ~ 60 fps\n\n const callbacks = {\n setOnLevelsChanged: ({ windowCenter, windowWidth }) => {\n apis.forEach(api => {\n const renderWindow = api.genericRenderWindow.getRenderWindow();\n\n renderWindow.render();\n });\n\n throttledUpdateVOIs(apis, windowWidth, windowCenter);\n },\n };\n\n apis.forEach((api, apiIndex) => {\n const istyle = vtkInteractorStyleMPRWindowLevel.newInstance();\n\n api.setInteractorStyle({\n istyle,\n callbacks,\n configuration: { apis, apiIndex, uid: api.uid },\n });\n });\n },\n setSlabThickness: ({ slabThickness }) => {\n apis.forEach(api => {\n api.setSlabThickness(slabThickness);\n });\n },\n changeSlabThickness: ({ change }) => {\n apis.forEach(api => {\n const slabThickness = Math.max(api.getSlabThickness() + change, 0.1);\n\n api.setSlabThickness(slabThickness);\n });\n },\n setBlendModeToComposite: () => {\n apis.forEach(api => {\n const renderWindow = api.genericRenderWindow.getRenderWindow();\n const istyle = renderWindow.getInteractor().getInteractorStyle();\n\n const slabThickness = api.getSlabThickness();\n\n const mapper = api.volumes[0].getMapper();\n if (mapper.setBlendModeToComposite) {\n mapper.setBlendModeToComposite();\n }\n\n if (istyle.setSlabThickness) {\n istyle.setSlabThickness(slabThickness);\n }\n renderWindow.render();\n });\n },\n setBlendModeToMaximumIntensity: () => {\n apis.forEach(api => {\n const renderWindow = api.genericRenderWindow.getRenderWindow();\n const mapper = api.volumes[0].getMapper();\n if (mapper.setBlendModeToMaximumIntensity) {\n mapper.setBlendModeToMaximumIntensity();\n }\n renderWindow.render();\n });\n },\n setBlendMode: ({ blendMode }) => {\n apis.forEach(api => {\n const renderWindow = api.genericRenderWindow.getRenderWindow();\n\n api.volumes[0].getMapper().setBlendMode(blendMode);\n\n renderWindow.render();\n });\n },\n mpr2d: async ({ viewports }) => {\n // TODO push a lot of this backdoor logic lower down to the library level.\n const displaySet =\n viewports.viewportSpecificData[viewports.activeViewportIndex];\n\n // Get current VOI if cornerstone viewport.\n const cornerstoneVOI = getVOIFromCornerstoneViewport();\n defaultVOI = cornerstoneVOI;\n\n const viewportProps = [\n {\n //Axial\n orientation: {\n sliceNormal: [0, 0, 1],\n viewUp: [0, -1, 0],\n },\n },\n {\n // Sagittal\n orientation: {\n sliceNormal: [1, 0, 0],\n viewUp: [0, 0, 1],\n },\n },\n {\n // Coronal\n orientation: {\n sliceNormal: [0, 1, 0],\n viewUp: [0, 0, 1],\n },\n },\n ];\n\n try {\n apis = await setMPRLayout(displaySet, viewportProps, 1, 3);\n } catch (error) {\n throw new Error(error);\n }\n\n if (cornerstoneVOI) {\n setVOI(cornerstoneVOI);\n }\n\n // Add widgets and set default interactorStyle of each viewport.\n apis.forEach((api, apiIndex) => {\n api.addSVGWidget(\n vtkSVGRotatableCrosshairsWidget.newInstance(),\n 'rotatableCrosshairsWidget'\n );\n\n const uid = api.uid;\n const istyle = vtkInteractorStyleRotatableMPRCrosshairs.newInstance();\n\n api.setInteractorStyle({\n istyle,\n configuration: { apis, apiIndex, uid },\n });\n\n api.svgWidgets.rotatableCrosshairsWidget.setApiIndex(apiIndex);\n api.svgWidgets.rotatableCrosshairsWidget.setApis(apis);\n });\n\n const firstApi = apis[0];\n\n // Initialise crosshairs\n apis[0].svgWidgets.rotatableCrosshairsWidget.resetCrosshairs(apis, 0);\n\n // Check if we have full WebGL 2 support\n const openGLRenderWindow = apis[0].genericRenderWindow.getOpenGLRenderWindow();\n\n if (!openGLRenderWindow.getWebgl2()) {\n // Throw a warning if we don't have WebGL 2 support,\n // And the volume is too big to fit in a 2D texture\n\n const openGLContext = openGLRenderWindow.getContext();\n const maxTextureSizeInBytes = openGLContext.getParameter(\n openGLContext.MAX_TEXTURE_SIZE\n );\n\n const maxBufferLengthFloat32 =\n (maxTextureSizeInBytes * maxTextureSizeInBytes) / 4;\n\n const dimensions = firstApi.volumes[0]\n .getMapper()\n .getInputData()\n .getDimensions();\n\n const volumeLength = dimensions[0] * dimensions[1] * dimensions[2];\n\n if (volumeLength > maxBufferLengthFloat32) {\n const message =\n 'This volume is too large to fit in WebGL 1 textures and will display incorrectly. Please use a different browser to view this data';\n LoggerService.error({ message });\n UINotificationService.show({\n title: 'Browser does not support WebGL 2',\n message,\n type: 'error',\n autoClose: false,\n });\n }\n }\n },\n };\n\n window.vtkActions = actions;\n\n const definitions = {\n requestNewSegmentation: {\n commandFn: actions.requestNewSegmentation,\n storeContexts: ['viewports'],\n options: {},\n },\n jumpToSlice: {\n commandFn: actions.jumpToSlice,\n storeContexts: ['viewports'],\n options: {},\n },\n setSegmentationConfiguration: {\n commandFn: actions.setSegmentationConfiguration,\n storeContexts: ['viewports'],\n options: {},\n },\n setSegmentConfiguration: {\n commandFn: actions.setSegmentConfiguration,\n storeContexts: ['viewports'],\n options: {},\n },\n axial: {\n commandFn: actions.axial,\n storeContexts: ['viewports'],\n options: {},\n },\n coronal: {\n commandFn: actions.coronal,\n storeContexts: ['viewports'],\n options: {},\n },\n sagittal: {\n commandFn: actions.sagittal,\n storeContexts: ['viewports'],\n options: {},\n },\n enableRotateTool: {\n commandFn: actions.enableRotateTool,\n options: {},\n },\n enableCrosshairsTool: {\n commandFn: actions.enableCrosshairsTool,\n options: {},\n },\n enableLevelTool: {\n commandFn: actions.enableLevelTool,\n options: {},\n },\n resetMPRView: {\n commandFn: actions.resetMPRView,\n options: {},\n },\n setBlendModeToComposite: {\n commandFn: actions.setBlendModeToComposite,\n options: { blendMode: BlendMode.COMPOSITE_BLEND },\n },\n setBlendModeToMaximumIntensity: {\n commandFn: actions.setBlendModeToMaximumIntensity,\n options: { blendMode: BlendMode.MAXIMUM_INTENSITY_BLEND },\n },\n setBlendModeToMinimumIntensity: {\n commandFn: actions.setBlendMode,\n options: { blendMode: BlendMode.MINIMUM_INTENSITY_BLEND },\n },\n setBlendModeToAverageIntensity: {\n commandFn: actions.setBlendMode,\n options: { blendMode: BlendMode.AVERAGE_INTENSITY_BLEND },\n },\n setSlabThickness: {\n // TODO: How do we pass in a function argument?\n commandFn: actions.setSlabThickness,\n options: {},\n },\n increaseSlabThickness: {\n commandFn: actions.changeSlabThickness,\n options: {\n change: 3,\n },\n },\n decreaseSlabThickness: {\n commandFn: actions.changeSlabThickness,\n options: {\n change: -3,\n },\n },\n mpr2d: {\n commandFn: actions.mpr2d,\n storeContexts: ['viewports'],\n options: {},\n context: 'VIEWER',\n },\n getVtkApiForViewportIndex: {\n commandFn: actions.getVtkApis,\n context: 'VIEWER',\n },\n };\n\n return {\n definitions,\n defaultContext: 'ACTIVE_VIEWPORT::VTK',\n };\n};\n\nexport default commandsModule;\n","import React, { useState, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport classnames from 'classnames';\nimport { Range, Checkbox, OldSelect } from '@ohif/ui';\n\nimport './slab-thickness-toolbar-button.styl';\n\nconst SLIDER = {\n MIN: 0.1,\n MAX: 1000,\n STEP: 0.1,\n};\n\nconst ToolbarLabel = props => {\n const { label } = props;\n return
    {label}
    ;\n};\n\nToolbarLabel.propTypes = {\n label: PropTypes.string.isRequired,\n};\n\nconst ToolbarSlider = props => {\n const { value, min, max, onChange } = props;\n return (\n
    \n \n \n
    \n );\n};\n\nToolbarSlider.propTypes = {\n value: PropTypes.number.isRequired,\n min: PropTypes.number.isRequired,\n max: PropTypes.number.isRequired,\n onChange: PropTypes.func.isRequired,\n};\n\nconst _getSelectOptions = button => {\n return button.operationButtons.map(button => {\n return {\n key: button.label,\n value: button.id,\n };\n });\n};\n\nconst _getClassNames = (isActive, className) => {\n return classnames('toolbar-button', 'slab-thickness', className, {\n active: isActive,\n });\n};\n\nconst _applySlabThickness = (\n value,\n modeChecked,\n toolbarClickCallback,\n button\n) => {\n if (!modeChecked || !toolbarClickCallback) {\n return;\n }\n\n const { actionButton } = button;\n\n const generateOperation = (operation, value) => {\n // Combine slider value into slider operation\n const generatedOperation = { ...operation };\n generatedOperation.commandOptions = {\n ...operation.commandOptions,\n slabThickness: value,\n };\n\n return generatedOperation;\n };\n\n const operation = generateOperation(actionButton, value);\n toolbarClickCallback(operation, event);\n};\n\nconst _applyModeOperation = (\n operation,\n modeChecked,\n toolbarClickCallback,\n button\n) => {\n // in case modeChecked has not being triggered by user yet\n if (typeof modeChecked !== 'boolean') {\n return;\n }\n\n const { deactivateButton } = button;\n\n const _operation = modeChecked ? operation : deactivateButton;\n if (toolbarClickCallback && _operation) {\n toolbarClickCallback(_operation);\n }\n};\n\nconst _getInitialState = currentSelectedOption => {\n return {\n value: SLIDER.MIN,\n sliderMin: SLIDER.MIN,\n sliderMax: SLIDER.MAX,\n modeChecked: undefined,\n operation: currentSelectedOption,\n };\n};\n\nconst INITIAL_OPTION_INDEX = 0;\nconst _getInitialtSelectedOption = (button = {}) => {\n return (\n button.operationButtons && button.operationButtons[INITIAL_OPTION_INDEX]\n );\n};\n\nfunction SlabThicknessToolbarComponent({\n parentContext,\n toolbarClickCallback,\n button,\n activeButtons,\n isActive,\n className,\n}) {\n const currentSelectedOption = _getInitialtSelectedOption(button);\n const [state, setState] = useState(_getInitialState(currentSelectedOption));\n const { label, operationButtons } = button;\n const _className = _getClassNames(isActive, className);\n const selectOptions = _getSelectOptions(button);\n function onChangeSelect(selectedValue) {\n // find select value\n const operation = operationButtons.find(\n button => button.id === selectedValue\n );\n\n if (operation === state.operation) {\n return;\n }\n\n setState({ ...state, operation });\n }\n\n function onChangeCheckbox(checked) {\n setState({ ...state, modeChecked: checked });\n }\n\n function onChangeSlider(event) {\n const value = Number(event.target.value);\n\n if (value !== state.value) {\n setState({ ...state, value, modeChecked: true });\n }\n }\n\n useEffect(() => {\n _applyModeOperation(\n state.operation,\n state.modeChecked,\n toolbarClickCallback,\n button\n );\n }, [state.modeChecked, state.operation]);\n\n useEffect(() => {\n _applySlabThickness(\n state.value,\n state.modeChecked,\n toolbarClickCallback,\n button\n );\n }, [state.operation, state.modeChecked, state.value]);\n\n return (\n
    \n
    \n \n \n
    \n
    \n \n \n
    \n
    \n );\n}\n\nSlabThicknessToolbarComponent.propTypes = {\n parentContext: PropTypes.object.isRequired,\n toolbarClickCallback: PropTypes.func.isRequired,\n button: PropTypes.object.isRequired,\n activeButtons: PropTypes.array.isRequired,\n isActive: PropTypes.bool,\n className: PropTypes.string,\n};\n\nexport default SlabThicknessToolbarComponent;\n","import React from 'react';\nimport { useSelector } from 'react-redux';\nimport PropTypes from 'prop-types';\nimport { ToolbarButton } from '@ohif/ui';\nimport { utils } from '@ohif/core';\n\nconst { studyMetadataManager } = utils;\n\nlet isVisible = true;\n\nconst _isDisplaySetReconstructable = (viewportSpecificData = {}, activeViewportIndex) => {\n if (!viewportSpecificData[activeViewportIndex]) {\n return false;\n };\n\n const { displaySetInstanceUID, StudyInstanceUID } = viewportSpecificData[\n activeViewportIndex\n ];\n\n const studies = studyMetadataManager.all();\n\n const study = studies.find(\n study => study.studyInstanceUID === StudyInstanceUID\n );\n\n if (!study) {\n return false;\n }\n\n const displaySet = study._displaySets.find(set => set.displaySetInstanceUID === displaySetInstanceUID);\n\n if (!displaySet) {\n return false;\n };\n\n return displaySet.isReconstructable;\n};\n\nfunction VTKMPRToolbarButton({\n parentContext,\n toolbarClickCallback,\n button,\n activeButtons,\n isActive,\n className,\n}) {\n const { id, label, icon } = button;\n const { viewportSpecificData, activeViewportIndex } = useSelector(state => {\n const { viewports = {} } = state;\n const { viewportSpecificData, activeViewportIndex } = viewports;\n\n return {\n viewportSpecificData,\n activeViewportIndex,\n }\n });\n\n isVisible = _isDisplaySetReconstructable(\n viewportSpecificData,\n activeViewportIndex,\n );\n\n return (\n \n {isVisible && (\n toolbarClickCallback(button, evt)}\n isActive={isActive}\n />\n )}\n \n );\n}\n\nVTKMPRToolbarButton.propTypes = {\n parentContext: PropTypes.object.isRequired,\n toolbarClickCallback: PropTypes.func.isRequired,\n button: PropTypes.object.isRequired,\n activeButtons: PropTypes.array.isRequired,\n isActive: PropTypes.bool,\n className: PropTypes.string,\n};\n\nexport default VTKMPRToolbarButton;\n","import SlabThicknessToolbarComponent from './toolbarComponents/SlabThicknessToolbarComponent';\nimport VTKMPRToolbarButton from './toolbarComponents/VTKMPRToolbarButton';\n\nconst TOOLBAR_BUTTON_TYPES = {\n COMMAND: 'command',\n SET_TOOL_ACTIVE: 'setToolActive',\n};\n\nconst definitions = [\n {\n id: 'Crosshairs',\n label: 'Crosshairs',\n icon: 'crosshairs',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'enableCrosshairsTool',\n commandOptions: {},\n },\n {\n id: 'WWWC',\n label: 'WWWC',\n icon: 'level',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'enableLevelTool',\n commandOptions: {},\n },\n {\n id: 'Reset',\n label: 'Reset',\n icon: 'reset',\n //\n type: TOOLBAR_BUTTON_TYPES.COMMAND,\n commandName: 'resetMPRView',\n commandOptions: {},\n },\n /*\n {\n id: 'Rotate',\n label: 'Rotate',\n icon: '3d-rotate',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'enableRotateTool',\n commandOptions: {},\n },\n */\n /*\n {\n id: 'setBlendModeToComposite',\n label: 'Disable MIP',\n icon: 'times',\n //\n type: TOOLBAR_BUTTON_TYPES.COMMAND,\n commandName: 'setBlendModeToComposite',\n commandOptions: {},\n },\n {\n id: 'setBlendModeToMaximumIntensity',\n label: 'Enable MIP',\n icon: 'soft-tissue',\n //\n type: TOOLBAR_BUTTON_TYPES.COMMAND,\n commandName: 'setBlendModeToMaximumIntensity',\n commandOptions: {},\n },\n\n {\n id: 'increaseSlabThickness',\n label: 'Increase Slab Thickness',\n icon: 'caret-up',\n //\n type: TOOLBAR_BUTTON_TYPES.COMMAND,\n commandName: 'increaseSlabThickness',\n commandOptions: {},\n },\n {\n id: 'decreaseSlabThickness',\n label: 'Decrease Slab Thickness',\n icon: 'caret-down',\n //\n type: TOOLBAR_BUTTON_TYPES.COMMAND,\n commandName: 'decreaseSlabThickness',\n commandOptions: {},\n },\n */\n {\n id: 'changeSlabThickness',\n label: 'Slab Thickness',\n icon: 'soft-tissue',\n CustomComponent: SlabThicknessToolbarComponent,\n commandName: 'setSlabThickness',\n actionButton: {\n id: 'setSlabThickness',\n label: 'slider',\n type: TOOLBAR_BUTTON_TYPES.COMMAND,\n commandName: 'setSlabThickness',\n commandOptions: {},\n },\n deactivateButton: {\n id: 'setBlendModeToComposite',\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setBlendModeToComposite',\n commandOptions: {},\n },\n operationButtons: [\n {\n id: 'setBlendModeToMaximumIntensity',\n label: 'MIP',\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setBlendModeToMaximumIntensity',\n commandOptions: {},\n },\n {\n id: 'setBlendModeToMinimumIntensity',\n label: 'MinIP',\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setBlendModeToMinimumIntensity',\n commandOptions: {},\n },\n {\n id: 'setBlendModeToAverageIntensity',\n label: 'AvgIP',\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setBlendModeToAverageIntensity',\n commandOptions: {},\n },\n ],\n },\n {\n id: '2DMPR',\n label: '2D MPR',\n icon: 'cube',\n //\n CustomComponent: VTKMPRToolbarButton,\n type: TOOLBAR_BUTTON_TYPES.COMMAND,\n commandName: 'mpr2d',\n context: 'ACTIVE_VIEWPORT::CORNERSTONE',\n },\n];\n\nexport default {\n definitions,\n defaultContext: 'ACTIVE_VIEWPORT::VTK',\n};\n","import React from 'react';\n\nexport default function withCommandsManager(Component, commandsManager = {}) {\n return class WithCommandsManager extends React.Component {\n render() {\n return (\n \n commandsManager.runCommand('getVtkApiForViewportIndex', {\n index: viewportIndex,\n })\n }\n />\n );\n }\n };\n}\n","import React from 'react';\nimport { asyncComponent, retryImport } from '@ohif/ui';\n\nimport commandsModule from './commandsModule.js';\nimport toolbarModule from './toolbarModule.js';\nimport withCommandsManager from './withCommandsManager.js';\nimport { version } from '../package.json';\n// This feels weird\n// import loadLocales from './loadLocales';\n\nconst OHIFVTKViewport = asyncComponent(() =>\n retryImport(() =>\n import(/* webpackChunkName: \"OHIFVTKViewport\" */ './OHIFVTKViewport.js')\n )\n);\n\nconst vtkExtension = {\n /**\n * Only required property. Should be a unique value across all extensions.\n */\n id: 'vtk',\n version,\n\n getViewportModule({ commandsManager, servicesManager }) {\n const ExtendedVTKViewport = props => (\n \n );\n return withCommandsManager(ExtendedVTKViewport, commandsManager);\n },\n getToolbarModule() {\n return toolbarModule;\n },\n getCommandsModule({ commandsManager, servicesManager }) {\n return commandsModule({ commandsManager, servicesManager });\n },\n};\n\nexport default vtkExtension;\n\nexport { vtkExtension };\n\n// loadLocales();\n","import { MODULE_TYPES, utils } from '@ohif/core';\n\n// TODO: Should probably use dcmjs for this\nconst SOP_CLASS_UIDS = {\n BASIC_TEXT_SR: '1.2.840.10008.5.1.4.1.1.88.11',\n ENHANCED_SR: '1.2.840.10008.5.1.4.1.1.88.22',\n COMPREHENSIVE_SR: '1.2.840.10008.5.1.4.1.1.88.33',\n COMPREHENSIVE_3D_SR: '1.2.840.10008.5.1.4.1.1.88.34',\n PROCEDURE_LOG_STORAGE: '1.2.840.10008.5.1.4.1.1.88.40',\n MAMMOGRAPHY_CAD_SR: '1.2.840.10008.5.1.4.1.1.88.50',\n CHEST_CAD_SR: '1.2.840.10008.5.1.4.1.1.88.65',\n X_RAY_RADIATION_DOSE_SR: '1.2.840.10008.5.1.4.1.1.88.67',\n ACQUISITION_CONTEXT_SR_STORAGE: '1.2.840.10008.5.1.4.1.1.88.71'\n};\n\nconst sopClassUIDs = Object.values(SOP_CLASS_UIDS);\n\n// TODO: Handle the case where there is more than one SOP Class Handler for the\n// same SOP Class\nconst OHIFDicomHtmlSopClassHandler = {\n id: 'OHIFDicomHtmlSopClassHandler',\n type: MODULE_TYPES.SOP_CLASS_HANDLER,\n sopClassUIDs,\n getDisplaySetFromSeries(series, study, dicomWebClient, authorizationHeaders) {\n const instance = series.getFirstInstance();\n\n const metadata = instance.getData().metadata;\n const {\n SeriesDescription,\n SeriesNumber,\n SeriesDate,\n SeriesTime,\n } = metadata;\n\n return {\n plugin: 'html',\n Modality: 'SR',\n displaySetInstanceUID: utils.guid(),\n wadoRoot: study.getData().wadoRoot,\n wadoUri: instance.getData().wadouri,\n SOPInstanceUID: instance.getSOPInstanceUID(),\n SeriesInstanceUID: series.getSeriesInstanceUID(),\n StudyInstanceUID: study.getStudyInstanceUID(),\n SeriesDescription,\n metadata,\n SeriesDate,\n SeriesTime,\n SeriesNumber,\n authorizationHeaders,\n sopClassUids: sopClassUIDs,\n images: series._instances,\n };\n },\n};\n\nexport default OHIFDicomHtmlSopClassHandler;\n","import React from 'react';\nimport OHIFDicomHtmlSopClassHandler from './OHIFDicomHtmlSopClassHandler.js';\nimport { version } from '../package.json';\n\nconst Component = React.lazy(() => {\n return import('./OHIFDicomHtmlViewport');\n});\n\nconst OHIFDicomHtmlViewport = props => {\n return (\n Loading...}>\n \n \n );\n};\n\nexport default {\n /**\n * Only required property. Should be a unique value across all extensions.\n */\n id: 'html',\n version,\n\n getViewportModule() {\n return OHIFDicomHtmlViewport;\n },\n getSopClassHandlerModule() {\n return OHIFDicomHtmlSopClassHandler;\n },\n};\n","import cornerstone from 'cornerstone-core';\nimport cornerstoneTools from 'cornerstone-tools';\n\nconst { importInternal } = cornerstoneTools;\nconst draw = importInternal('drawing/draw');\nconst drawLine = importInternal('drawing/drawLine');\nconst getNewContext = importInternal('drawing/getNewContext');\n\nexport default function _drawCanvasCrosshairs(eventData, center, options) {\n const context = getNewContext(eventData.canvasContext.canvas);\n const { element } = eventData;\n\n const centerCanvas = cornerstone.pixelToCanvas(element, center);\n\n const { clientWidth: width, clientHeight: height } = element;\n\n const offset = 10;\n\n draw(context, context => {\n drawLine(\n context,\n element,\n { x: centerCanvas.x + offset, y: centerCanvas.y },\n { x: width, y: centerCanvas.y },\n options,\n 'canvas'\n );\n\n drawLine(\n context,\n element,\n { x: centerCanvas.x - offset, y: centerCanvas.y },\n { x: 0, y: centerCanvas.y },\n options,\n 'canvas'\n );\n\n drawLine(\n context,\n element,\n { x: centerCanvas.x, y: centerCanvas.y + offset },\n { x: centerCanvas.x, y: height },\n options,\n 'canvas'\n );\n\n drawLine(\n context,\n element,\n { x: centerCanvas.x, y: centerCanvas.y - offset },\n { x: centerCanvas.x, y: 0 },\n options,\n 'canvas'\n );\n });\n}\n","import cornerstoneTools, {\n importInternal,\n getToolState,\n toolColors,\n getModule,\n globalImageIdSpecificToolStateManager,\n} from 'cornerstone-tools';\nimport cornerstone from 'cornerstone-core';\nimport drawCanvasCrosshairs from '../utils/drawCanvasCrosshairs';\nimport TOOL_NAMES from './TOOL_NAMES';\n\nconst { DICOM_SEG_TEMP_CROSSHAIRS_TOOL } = TOOL_NAMES;\nconst { getters } = getModule('segmentation');\n\n// Cornerstone 3rd party dev kit imports\nconst BaseTool = importInternal('base/BaseTool');\n\n/**\n * @class RTStructDisplayTool - Renders RTSTRUCT data in a read only manner (i.e. as an overlay).\n * @extends cornerstoneTools.BaseTool\n */\nexport default class DICOMSegTempCrosshairsTool extends BaseTool {\n constructor(props = {}) {\n const defaultProps = {\n mixins: ['enabledOrDisabledBinaryTool'],\n name: DICOM_SEG_TEMP_CROSSHAIRS_TOOL,\n };\n\n const initialProps = Object.assign(defaultProps, props);\n\n super(initialProps);\n\n this._rtStructModule = cornerstoneTools.getModule('rtstruct');\n }\n\n renderToolData(evt) {\n const eventData = evt.detail;\n const { element } = eventData;\n const toolState = getToolState(evt.currentTarget, this.name);\n\n if (!toolState) {\n return;\n }\n\n // We have tool data for this element - iterate over each one and draw it\n\n for (let i = 0; i < toolState.data.length; i++) {\n const data = toolState.data[i];\n const crossHairCenter = data.center;\n\n drawCanvasCrosshairs(eventData, crossHairCenter, {\n color: toolColors.getActiveColor(),\n lineWidth: 1,\n });\n\n // Remove the crosshairs, we only render them for one redraw.\n toolState.data.pop();\n }\n }\n}\n\nDICOMSegTempCrosshairsTool.addCrosshair = (element, imageId, segmentNumber) => {\n const labelmap3D = getters.labelmap3D(element);\n const stackToolState = cornerstoneTools.getToolState(element, 'stack');\n const enabledElement = cornerstone.getEnabledElement(element);\n\n const { rows, columns } = enabledElement.image;\n\n if (!stackToolState) {\n return;\n }\n\n const imageIds = stackToolState.data[0].imageIds;\n const imageIdIndex = imageIds.findIndex(imgId => imgId === imageId);\n\n const labelmap2D = labelmap3D.labelmaps2D[imageIdIndex];\n const { pixelData } = labelmap2D;\n\n let xCenter = 0;\n let yCenter = 0;\n\n let count = 0;\n\n for (let y = 0; y < rows; y++) {\n for (let x = 0; x < columns; x++) {\n if (pixelData[y * columns + x] === segmentNumber) {\n count++;\n xCenter += x + 0.5;\n yCenter += y + 0.5;\n }\n }\n }\n\n xCenter /= count;\n yCenter /= count;\n\n const globalToolState = globalImageIdSpecificToolStateManager.saveToolState();\n\n if (!globalToolState[imageId]) {\n globalToolState[imageId] = {};\n }\n\n const imageIdSpecificToolState = globalToolState[imageId];\n\n if (!imageIdSpecificToolState[DICOM_SEG_TEMP_CROSSHAIRS_TOOL]) {\n imageIdSpecificToolState[DICOM_SEG_TEMP_CROSSHAIRS_TOOL] = { data: [] };\n } else if (!imageIdSpecificToolState[DICOM_SEG_TEMP_CROSSHAIRS_TOOL].data) {\n imageIdSpecificToolState[DICOM_SEG_TEMP_CROSSHAIRS_TOOL].data = [];\n }\n\n const toolSpecificData =\n imageIdSpecificToolState[DICOM_SEG_TEMP_CROSSHAIRS_TOOL].data;\n\n toolSpecificData.push({ center: { x: xCenter, y: yCenter }, segmentNumber });\n\n // Enable the tool if not enabled for the element.\n\n const tool = cornerstoneTools.getToolForElement(\n element,\n DICOM_SEG_TEMP_CROSSHAIRS_TOOL\n );\n\n if (tool.mode !== 'enabled') {\n // If not already active or passive, set passive so contours render.\n cornerstoneTools.setToolEnabled(DICOM_SEG_TEMP_CROSSHAIRS_TOOL);\n }\n};\n","const TOOL_NAMES = {\n DICOM_SEG_TEMP_CROSSHAIRS_TOOL: 'DICOMSegTempCrosshairsTool',\n};\n\nexport default TOOL_NAMES;\n","/* TODO: Creation tools (future release).\n\nconst TOOLBAR_BUTTON_TYPES = {\n COMMAND: 'command',\n SET_TOOL_ACTIVE: 'setToolActive',\n BUILT_IN: 'builtIn',\n};\n\n*/\n\nconst definitions = []; /* TODO: Creation tools (future release). [\n {\n id: 'SegDropdown',\n label: 'Segmentation',\n icon: 'ellipse-circle',\n buttons: [\n {\n id: 'Brush',\n label: 'Brush',\n icon: 'brush',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'Brush' },\n },\n {\n id: 'SphericalBrush',\n label: 'Spherical',\n icon: 'sphere',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'SphericalBrush' },\n },\n {\n id: 'CorrectionScissors',\n label: 'Correction Scissors',\n icon: 'scissors',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'CorrectionScissors' },\n },\n {\n id: 'BrushEraser',\n label: 'Eraser',\n icon: 'trash',\n //\n type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,\n commandName: 'setToolActive',\n commandOptions: { toolName: 'BrushEraser' },\n },\n ],\n },\n]; */\n\nexport default {\n definitions,\n defaultContext: 'ACTIVE_VIEWPORT::CORNERSTONE',\n};\n","import dcmjs from 'dcmjs';\nimport cornerstone from 'cornerstone-core';\nimport cornerstoneTools from 'cornerstone-tools';\n\nexport default async function loadSegmentation(\n imageIds,\n segDisplaySet,\n labelmapBuffer,\n segMetadata,\n segmentsOnFrame,\n labelmapSegments\n) {\n const { setters } = cornerstoneTools.getModule('segmentation');\n\n // TODO: Could define a color LUT based on colors in the SEG.\n const labelmapIndex = _getNextLabelmapIndex(imageIds[0]);\n const colorLUTIndex = _makeColorLUTAndGetIndex(segMetadata);\n\n setters.labelmap3DByFirstImageId(\n imageIds[0],\n labelmapBuffer,\n labelmapIndex,\n segMetadata,\n imageIds.length,\n segmentsOnFrame,\n colorLUTIndex\n );\n\n if (!segDisplaySet.labelmapSegments) {\n segDisplaySet.labelmapSegments = {};\n }\n\n /**\n * Cache each labelmap segments.\n * This data is used to determine the active label map when a given segment is activated/clicked.\n */\n segDisplaySet.labelmapSegments[labelmapIndex] = labelmapSegments.length\n ? Array.from(\n new Set(labelmapSegments.filter(a => !!a).reduce((a, b) => a.concat(b)))\n )\n : [];\n segDisplaySet.labelmapIndex = labelmapIndex;\n\n /*\n * TODO: Improve the way we notify parts of the app that depends on segs to be loaded.\n *\n * Currently we are using a non-ideal implementation through a custom event to notify the segmentation panel\n * or other components that could rely on loaded segmentations that\n * the segments were loaded so that e.g. when the user opens the panel\n * before the segments are fully loaded, the panel can subscribe to this custom event\n * and update itself with the new segments.\n *\n * This limitation is due to the fact that the cs segmentation module is an object (which will be\n * updated after the segments are loaded) that React its not aware of its changes\n * because the module object its not passed in to the panel component as prop but accessed externally.\n *\n * Improving this event approach to something reactive that can be tracked inside the react lifecycle,\n * allows us to easily watch the module or the segmentations loading process in any other component\n * without subscribing to external events.\n */\n console.log('Segmentation loaded.');\n const event = new CustomEvent('extensiondicomsegmentationsegloaded', {\n detail: {\n imageIds,\n segDisplaySet,\n labelmapBuffer,\n segMetadata,\n segmentsOnFrame,\n labelmapSegments,\n },\n });\n document.dispatchEvent(event);\n\n return labelmapIndex;\n}\n\nfunction _getNextLabelmapIndex(firstImageId) {\n const { state } = cornerstoneTools.getModule('segmentation');\n const brushStackState = state.series[firstImageId];\n\n let labelmapIndex = 0;\n\n if (brushStackState) {\n const { labelmaps3D } = brushStackState;\n labelmapIndex = labelmaps3D.length;\n\n for (let i = 0; i < labelmaps3D.length; i++) {\n if (!labelmaps3D[i]) {\n labelmapIndex = i;\n break;\n }\n }\n }\n\n return labelmapIndex;\n}\n\nfunction _makeColorLUTAndGetIndex(segMetadata) {\n const { setters, state } = cornerstoneTools.getModule('segmentation');\n const { colorLutTables } = state;\n const colorLUTIndex = _getNextColorLUTIndex();\n\n const { data } = segMetadata;\n\n if (\n !data.some(\n segment =>\n segment &&\n (segment.ROIDisplayColor || segment.RecommendedDisplayCIELabValue)\n )\n ) {\n // Use default cornerstoneTools colorLUT.\n return 0;\n }\n\n const colorLUT = [];\n\n for (let i = 0; i < data.length; i++) {\n const segment = data[i];\n if (!segment) {\n continue;\n }\n\n const { ROIDisplayColor, RecommendedDisplayCIELabValue } = segment;\n\n if (RecommendedDisplayCIELabValue) {\n const rgb = dcmjs.data.Colors.dicomlab2RGB(\n RecommendedDisplayCIELabValue\n ).map(x => Math.round(x * 255));\n\n colorLUT[i] = [...rgb, 255];\n } else if (ROIDisplayColor) {\n colorLUT[i] = [...ROIDisplayColor, 255];\n } else {\n colorLUT[i] = [...colorLutTables[0][i]];\n }\n }\n\n colorLUT.shift();\n setters.colorLUT(colorLUTIndex, colorLUT);\n\n return colorLUTIndex;\n}\n\nfunction _getNextColorLUTIndex() {\n const { state } = cornerstoneTools.getModule('segmentation');\n const { colorLutTables } = state;\n\n let colorLUTIndex = colorLutTables.length;\n\n for (let i = 0; i < colorLutTables.length; i++) {\n if (!colorLutTables[i]) {\n colorLUTIndex = i;\n break;\n }\n }\n\n return colorLUTIndex;\n}\n","export default function refreshViewports() {\n cornerstone.getEnabledElements().forEach(enabledElement => {\n cornerstone.updateImage(enabledElement.element);\n });\n}\n","import { utils, log } from '@ohif/core';\nimport cornerstoneTools from 'cornerstone-tools';\nimport refreshViewports from './refreshViewports';\n\nconst { studyMetadataManager } = utils;\n\n/**\n *\n *\n * @param {*} viewportSpecificData\n * @param {*} studies\n * @param {*} displaySet\n * @param {*} firstImageId\n * @param {*} activeLabelmapIndex\n * @returns\n */\nexport default async function setActiveLabelmap(\n referencedDisplaySet,\n studies,\n displaySet,\n callback = () => {},\n onDisplaySetLoadFailure = err => {\n console.error(err.message);\n }\n) {\n const studyMetadata = studyMetadataManager.get(\n referencedDisplaySet.StudyInstanceUID\n );\n const firstImageId = studyMetadata.getFirstImageId(\n referencedDisplaySet.displaySetInstanceUID\n );\n\n let { state } = cornerstoneTools.getModule('segmentation');\n\n let brushStackState = state.series[firstImageId];\n const activeLabelmapIndex = brushStackState\n ? brushStackState.activeLabelmapIndex\n : undefined;\n\n let labelmapIndex =\n displaySet.hasOverlapping === true\n ? displaySet.originLabelMapIndex\n : displaySet.labelmapIndex;\n\n if (labelmapIndex === activeLabelmapIndex) {\n log.warn(`${activeLabelmapIndex} is already the active labelmap`);\n return labelmapIndex;\n }\n\n if (!displaySet.isLoaded && !displaySet.loadError) {\n try {\n await displaySet.load(referencedDisplaySet, studies);\n } catch (error) {\n displaySet.isLoaded = false;\n displaySet.loadError = true;\n displaySet.segLoadErrorMessagge = error.message;\n onDisplaySetLoadFailure(error);\n\n /*\n * TODO: Improve the way we notify parts of the app\n * that depends on derived display sets to be loaded.\n * (Implement pubsub for better tracking of derived display sets)\n */\n const event = new CustomEvent('segmentationLoadingError');\n document.dispatchEvent(event);\n\n return -1;\n }\n }\n\n labelmapIndex =\n displaySet.hasOverlapping === true\n ? displaySet.originLabelMapIndex\n : displaySet.labelmapIndex;\n\n // This might have just been created, so need to use the non-cached value.\n state = cornerstoneTools.getModule('segmentation').state;\n\n brushStackState = state.series[firstImageId];\n if (brushStackState) {\n brushStackState.activeLabelmapIndex = labelmapIndex;\n }\n\n refreshViewports();\n callback();\n\n return labelmapIndex;\n}\n","import setActiveLabelmap from './utils/setActiveLabelMap';\nimport { metadata } from '@ohif/core';\n\nexport default function getSourceDisplaySet(studies, segDisplaySet, activateLabelMap = true, onDisplaySetLoadFailureHandler) {\n const referencedDisplaySet = metadata.StudyMetadata.getReferencedDisplaySet(segDisplaySet, studies);\n\n let activatedLabelmapPromise;\n if (activateLabelMap) {\n activatedLabelmapPromise = setActiveLabelmap(referencedDisplaySet, studies, segDisplaySet, undefined, onDisplaySetLoadFailureHandler);\n }\n\n return {\n referencedDisplaySet : referencedDisplaySet,\n activatedLabelmapPromise : activatedLabelmapPromise\n }\n}\n","import { MODULE_TYPES, utils } from '@ohif/core';\nimport loadSegmentation from './loadSegmentation';\nimport getSourceDisplaySet from './getSourceDisplaySet';\nimport OHIF from '@ohif/core';\nimport dcmjs from 'dcmjs';\n\nconst { DicomLoaderService } = OHIF.utils;\nconst { DicomMessage, DicomMetaDictionary } = dcmjs.data;\n\n// TODO: Should probably use dcmjs for this\nconst SOP_CLASS_UIDS = {\n DICOM_SEG: '1.2.840.10008.5.1.4.1.1.66.4',\n};\n\nconst sopClassUIDs = Object.values(SOP_CLASS_UIDS);\n\nexport default function getSopClassHandlerModule({ servicesManager }) {\n // TODO: Handle the case where there is more than one SOP Class Handler for the\n // same SOP Class.\n return {\n id: 'OHIFDicomSegSopClassHandler',\n type: MODULE_TYPES.SOP_CLASS_HANDLER,\n sopClassUIDs,\n getDisplaySetFromSeries: function(\n series,\n study,\n dicomWebClient,\n authorizationHeaders\n ) {\n const instance = series.getFirstInstance();\n const metadata = instance.getData().metadata;\n\n const {\n SeriesDate,\n SeriesTime,\n SeriesDescription,\n FrameOfReferenceUID,\n SOPInstanceUID,\n SeriesInstanceUID,\n StudyInstanceUID,\n SeriesNumber,\n } = metadata;\n\n const segDisplaySet = {\n Modality: 'SEG',\n displaySetInstanceUID: utils.guid(),\n wadoRoot: study.getData().wadoRoot,\n wadoUri: instance.getData().wadouri,\n SOPInstanceUID,\n SeriesInstanceUID,\n StudyInstanceUID,\n FrameOfReferenceUID,\n authorizationHeaders,\n isDerived: true,\n referencedDisplaySetUID: null, // Assigned when loaded.\n labelmapIndex: null, // Assigned when loaded.\n isLoaded: false,\n loadError: false,\n hasOverlapping: false,\n SeriesDate,\n SeriesTime,\n SeriesNumber,\n SeriesDescription,\n metadata,\n };\n\n segDisplaySet.getSourceDisplaySet = function(\n studies,\n activateLabelMap = true,\n onDisplaySetLoadFailureHandler\n ) {\n return getSourceDisplaySet(\n studies,\n segDisplaySet,\n activateLabelMap,\n onDisplaySetLoadFailureHandler\n );\n };\n\n segDisplaySet.load = async function(referencedDisplaySet, studies) {\n segDisplaySet.isLoaded = true;\n const { StudyInstanceUID } = referencedDisplaySet;\n const segArrayBuffer = await DicomLoaderService.findDicomDataPromise(\n segDisplaySet,\n studies\n );\n const dicomData = DicomMessage.readFile(segArrayBuffer);\n const dataset = DicomMetaDictionary.naturalizeDataset(dicomData.dict);\n dataset._meta = DicomMetaDictionary.namifyDataset(dicomData.meta);\n const imageIds = _getImageIdsForDisplaySet(\n studies,\n StudyInstanceUID,\n referencedDisplaySet.SeriesInstanceUID\n );\n\n const results = await _parseSeg(segArrayBuffer, imageIds);\n if (results === undefined) {\n return;\n }\n const {\n labelmapBufferArray,\n segMetadata,\n segmentsOnFrame,\n segmentsOnFrameArray,\n } = results;\n let labelmapIndex;\n if (labelmapBufferArray.length > 1) {\n let labelmapIndexes = [];\n for (let i = 0; i < labelmapBufferArray.length; ++i) {\n segMetadata.segmentationSeriesInstanceUID =\n segDisplaySet.SeriesInstanceUID;\n segMetadata.hasOverlapping = true;\n labelmapIndexes.push(\n await loadSegmentation(\n imageIds,\n segDisplaySet,\n labelmapBufferArray[i],\n segMetadata,\n segmentsOnFrame,\n segmentsOnFrameArray[i]\n )\n );\n }\n /**\n * Since overlapping segments have virtual labelmaps,\n * originLabelMapIndex is used in the panel to select the correct dropdown value.\n */\n segDisplaySet.hasOverlapping = true;\n segDisplaySet.originLabelMapIndex = labelmapIndexes[0];\n labelmapIndex = labelmapIndexes[0];\n console.warn('Overlapping segments!');\n } else {\n segMetadata.segmentationSeriesInstanceUID =\n segDisplaySet.SeriesInstanceUID;\n segMetadata.hasOverlapping = false;\n labelmapIndex = await loadSegmentation(\n imageIds,\n segDisplaySet,\n labelmapBufferArray[0],\n segMetadata,\n segmentsOnFrame,\n []\n );\n }\n };\n\n return segDisplaySet;\n },\n };\n}\n\nfunction _parseSeg(arrayBuffer, imageIds) {\n const skipOverlapping = false;\n const tolerance = 1e-2;\n const cornerstoneToolsVersion = 4;\n return dcmjs.adapters.Cornerstone.Segmentation.generateToolState(\n imageIds,\n arrayBuffer,\n cornerstone.metaData,\n skipOverlapping,\n tolerance,\n cornerstoneToolsVersion\n );\n}\n\nfunction _getImageIdsForDisplaySet(\n studies,\n StudyInstanceUID,\n SeriesInstanceUID\n) {\n const study = studies.find(\n study => study.StudyInstanceUID === StudyInstanceUID\n );\n\n const displaySets = study.displaySets.filter(displaySet => {\n return displaySet.SeriesInstanceUID === SeriesInstanceUID;\n });\n\n if (displaySets.length > 1) {\n console.warn(\n 'More than one display set with the same SeriesInstanceUID. This is not supported yet...'\n );\n // TODO -> We could make check the instance list and see if any match?\n // Do we split the segmentation into two cornerstoneTools segmentations if there are images in both series?\n // ^ Will that even happen?\n }\n\n const referencedDisplaySet = displaySets[0];\n\n return referencedDisplaySet.images.map(image => image.getImageId());\n}\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport './BrushColorSelector.css';\n\nconst BrushColorSelector = ({ defaultColor, index, onNext, onPrev }) => (\n
    \n \n {index}\n
    \n
    \n \n \n
    \n \n);\n\nBrushColorSelector.propTypes = {\n defaultColor: PropTypes.string.isRequired,\n index: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,\n onNext: PropTypes.func.isRequired,\n onPrev: PropTypes.func.isRequired,\n};\n\nexport default BrushColorSelector;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Range } from '@ohif/ui';\n\nimport './BrushRadius.css';\n\nconst BrushRadius = ({ value, onChange, min, max, step }) => (\n
    \n \n \n
    \n);\n\nBrushRadius.propTypes = {\n value: PropTypes.number.isRequired,\n onChange: PropTypes.number,\n min: PropTypes.number,\n max: PropTypes.number,\n step: PropTypes.number,\n};\n\nBrushRadius.defaultProps = {\n onChange: () => { },\n min: 1,\n max: 50,\n step: 1,\n};\n\nexport default BrushRadius;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport './SegmentationItem.css';\n\nconst SegmentationItem = ({ onClick, title, description }) => {\n return (\n
  • \n
    \n
    {title}
    \n
    {description}
    \n
    \n
  • \n );\n};\n\nSegmentationItem.propTypes = {\n onClick: PropTypes.func.isRequired,\n title: PropTypes.string.isRequired,\n description: PropTypes.string.isRequired,\n};\n\nSegmentationItem.defaultProps = {\n description: ''\n};\n\nexport default SegmentationItem;\n","import React, { useState, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport { Range } from '@ohif/ui';\n\nimport './SegmentationSettings.css';\n\nconst SegmentationSettings = ({ configuration, onBack, onChange, disabledFields = [] }) => {\n const [state, setState] = useState({\n renderFill: configuration.renderFill,\n renderOutline: configuration.renderOutline,\n shouldRenderInactiveLabelmaps: configuration.shouldRenderInactiveLabelmaps,\n fillAlpha: configuration.fillAlpha,\n outlineAlpha: configuration.outlineAlpha,\n outlineWidth: configuration.outlineWidth,\n fillAlphaInactive: configuration.fillAlphaInactive,\n outlineAlphaInactive: configuration.outlineAlphaInactive\n });\n\n useEffect(() => {\n onChange(state);\n }, [state]);\n\n const check = field => {\n setState(state => ({ ...state, [field]: !state[field] }));\n };\n\n const save = (field, value) => {\n setState(state => ({ ...state, [field]: value }));\n };\n\n const toFloat = value => parseFloat(value / 100).toFixed(2);\n\n return (\n
    \n
    \n

    Segmentations Settings

    \n \n
    \n \n check('renderFill')}\n />\n {state.renderFill && (\n save('fillAlpha', toFloat(event.target.value))}\n showPercentage\n />\n )}\n
    \n \n check('renderOutline')}\n />\n {state.renderOutline && (\n <>\n {!disabledFields.includes('outlineAlpha') && (\n save('outlineAlpha', toFloat(event.target.value))}\n />\n )}\n {!disabledFields.includes('outlineWidth') && (\n save('outlineWidth', parseInt(event.target.value))}\n />\n )}\n \n )}\n \n {(state.renderFill || state.renderOutline) && !disabledFields.includes('shouldRenderInactiveLabelmaps') && (\n \n check('shouldRenderInactiveLabelmaps')}\n />\n {state.shouldRenderInactiveLabelmaps && (\n <>\n {state.renderFill && !disabledFields.includes('fillAlphaInactive') && (\n save('fillAlphaInactive', toFloat(event.target.value))}\n />\n )}\n {state.renderOutline && !disabledFields.includes('outlineAlphaInactive') && (\n save('outlineAlphaInactive', toFloat(event.target.value))}\n />\n )}\n \n )}\n \n )}\n \n );\n};\n\nconst CustomCheck = ({ label, checked, onChange }) => {\n return (\n
    \n \n
    \n );\n};\n\nconst CustomRange = props => {\n const { label, onChange } = props;\n return (\n
    \n \n {\n event.persist();\n onChange(event);\n }}\n />\n
    \n );\n};\n\nSegmentationSettings.propTypes = {\n configuration: PropTypes.shape({\n renderFill: PropTypes.bool.isRequired,\n renderOutline: PropTypes.bool.isRequired,\n shouldRenderInactiveLabelmaps: PropTypes.bool.isRequired,\n fillAlpha: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, /* TODO: why fillAlpha is string? */\n outlineAlpha: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, /* TODO: why fillAlpha is string? */\n outlineWidth: PropTypes.number.isRequired,\n fillAlphaInactive: PropTypes.number.isRequired,\n outlineAlphaInactive: PropTypes.number.isRequired,\n }).isRequired,\n onBack: PropTypes.func.isRequired,\n onChange: PropTypes.func.isRequired,\n};\n\nexport default SegmentationSettings;\n","import React, { useState, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport { TableListItem, Icon } from '@ohif/ui';\nimport ReactTooltip from 'react-tooltip';\n\nimport './SegmentItem.css';\n\nconst ColoredCircle = ({ color }) => {\n return (\n \n );\n};\n\nColoredCircle.propTypes = {\n color: PropTypes.array.isRequired,\n};\n\nconst SegmentItem = ({\n index,\n label,\n onClick,\n itemClass,\n color,\n labelmap3D,\n visible,\n onVisibilityChange,\n}) => {\n const [isVisible, setIsVisible] = useState(visible);\n\n useEffect(() => {\n setIsVisible(visible);\n }, [visible]);\n\n const onClickHandler = () => onClick(index);\n\n const onVisibilityChangeHandler = event => {\n event.stopPropagation();\n const newVisibility = !isVisible;\n setIsVisible(newVisibility);\n onVisibilityChange(newVisibility, index, labelmap3D);\n };\n\n return (\n
    \n }\n itemMetaClass=\"segment-color-section\"\n onItemClick={onClickHandler}\n >\n
    \n
    \n \n {label}\n \n \n {label}\n \n \n
    \n {false &&
    {'...'}
    }\n {false && (\n
    \n console.log('Relabelling...')}\n >\n \n \n \n Relabel\n \n console.log('Editing description...')}\n >\n \n \n \n Description\n \n
    \n )}\n
    \n \n
    \n );\n};\n\nSegmentItem.propTypes = {\n index: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,\n label: PropTypes.string.isRequired,\n onClick: PropTypes.func,\n itemClass: PropTypes.string,\n color: PropTypes.array.isRequired,\n};\n\nSegmentItem.defaultProps = {\n itemClass: '',\n onClick: () => {},\n};\n\nexport default SegmentItem;\n","import React from 'react';\nimport Select from 'react-select';\n\nconst SegmentationSelect = ({ value, formatOptionLabel, options }) => (\n \n);\n\nconst computedstyle = getComputedStyle(document.body);\nconst uiGrayDarker = computedstyle.getPropertyValue('--ui-gray-darker');\nconst activeColor = computedstyle.getPropertyValue('--active-color');\nconst defaultColor = computedstyle.getPropertyValue('--default-color');\nconst uiGrayDark = computedstyle.getPropertyValue('--ui-gray-dark');\n\nconst segmentationSelectStyles = {\n singleValue: (base, state) => ({\n ...base,\n width: '100%'\n }),\n control: (base, state) => ({\n ...base,\n cursor: 'pointer',\n background: uiGrayDarker,\n borderRadius: state.isFocused ? '5px 5px 5px 5px' : 5,\n borderColor: state.isFocused ? activeColor : defaultColor,\n boxShadow: state.isFocused ? null : null,\n minHeight: '50px',\n '&:hover': {\n borderColor: activeColor,\n },\n }),\n menu: base => ({\n ...base,\n borderRadius: 5,\n background: uiGrayDarker,\n }),\n option: (base, state) => ({\n ...base,\n cursor: 'pointer',\n '&:first-of-type': {\n borderTopLeftRadius: 5,\n borderTopRightRadius: 5,\n },\n '&:last-of-type': {\n borderBottomLeftRadius: 5,\n borderBottomRightRadius: 5,\n },\n background: state.isSelected ? uiGrayDark : uiGrayDarker,\n '&:hover': {\n background: uiGrayDark,\n },\n }),\n};\n\nexport default SegmentationSelect;\n","import React, { useState, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport cornerstoneTools from 'cornerstone-tools';\nimport cornerstone from 'cornerstone-core';\nimport moment from 'moment';\nimport classNames from 'classnames';\nimport { utils, log } from '@ohif/core';\nimport { ScrollableArea, TableList, Icon } from '@ohif/ui';\nimport DICOMSegTempCrosshairsTool from '../../tools/DICOMSegTempCrosshairsTool';\n\nimport setActiveLabelmap from '../../utils/setActiveLabelMap';\nimport refreshViewports from '../../utils/refreshViewports';\n\nimport {\n BrushColorSelector,\n BrushRadius,\n SegmentationItem,\n SegmentItem,\n SegmentationSelect,\n} from '../index';\n\nimport './SegmentationPanel.css';\nimport SegmentationSettings from '../SegmentationSettings/SegmentationSettings';\n\nconst { studyMetadataManager } = utils;\n\n/**\n * SegmentationPanel component\n *\n * @param {Array} props.studies - Studies data\n * @param {Array} props.viewports - Viewports data (viewportSpecificData)\n * @param {number} props.activeIndex - Active viewport index\n * @param {boolean} props.isOpen - Boolean that indicates if the panel is expanded\n * @param {Function} props.onSegmentItemClick - Segment click handler\n * @param {Function} props.onSegmentVisibilityChange - Segment visibiliy change handler\n * @param {Function} props.onConfigurationChange - Configuration change handler\n * @param {Function} props.activeContexts - List of active application contexts\n * @param {Function} props.contexts - List of available application contexts\n * @returns component\n */\nconst SegmentationPanel = ({\n studies,\n viewports,\n activeIndex,\n isOpen,\n onSegmentItemClick,\n onSegmentVisibilityChange,\n onConfigurationChange,\n onDisplaySetLoadFailure,\n onSelectedSegmentationChange,\n activeContexts = [],\n contexts = {},\n}) => {\n const isVTK = () => activeContexts.includes(contexts.VTK);\n const isCornerstone = () => activeContexts.includes(contexts.CORNERSTONE);\n\n /*\n * TODO: wrap get/set interactions with the cornerstoneTools\n * store with context to make these kind of things less blurry.\n */\n const { configuration } = cornerstoneTools.getModule('segmentation');\n const DEFAULT_BRUSH_RADIUS = configuration.radius || 10;\n\n /*\n * TODO: We shouldn't hardcode brushColor color, in the future\n * the SEG may set the colorLUT to whatever it wants.\n */\n const [state, setState] = useState({\n brushRadius: DEFAULT_BRUSH_RADIUS,\n brushColor: 'rgba(221, 85, 85, 1)',\n selectedSegment: 0,\n selectedSegmentation: 0,\n showSettings: false,\n labelMapList: [],\n segmentList: [],\n segmentsHidden: [],\n segmentNumbers: [],\n isLoading: false,\n isDisabled: true,\n });\n\n const getActiveViewport = () => viewports[activeIndex];\n\n const getFirstImageId = () => {\n const { StudyInstanceUID, displaySetInstanceUID } = getActiveViewport();\n const studyMetadata = studyMetadataManager.get(StudyInstanceUID);\n return studyMetadata.getFirstImageId(displaySetInstanceUID);\n };\n\n const getActiveLabelMaps3D = () => {\n const { labelmaps3D, activeLabelmapIndex } = getBrushStackState();\n return labelmaps3D[activeLabelmapIndex];\n };\n\n const getActiveLabelMapIndex = () => {\n const { activeLabelmapIndex } = getBrushStackState();\n return activeLabelmapIndex;\n };\n\n const getActiveSegmentIndex = () => {\n const { activeSegmentIndex } = getActiveLabelMaps3D();\n return activeSegmentIndex;\n };\n\n const getActiveLabelMaps2D = () => {\n const { labelmaps2D } = getActiveLabelMaps3D();\n return labelmaps2D;\n };\n\n const getCurrentDisplaySet = () => {\n const { StudyInstanceUID, displaySetInstanceUID } = getActiveViewport();\n const studyMetadata = studyMetadataManager.get(StudyInstanceUID);\n const allDisplaySets = studyMetadata.getDisplaySets();\n return allDisplaySets.find(\n ds => ds.displaySetInstanceUID === displaySetInstanceUID\n );\n };\n\n const setActiveSegment = segmentIndex => {\n const activeSegmentIndex = getActiveSegmentIndex();\n const activeViewport = getActiveViewport();\n\n if (segmentIndex === activeSegmentIndex) {\n log.info(`${activeSegmentIndex} is already the active segment`);\n return;\n }\n\n const labelmap3D = getActiveLabelMaps3D();\n labelmap3D.activeSegmentIndex = segmentIndex;\n\n /**\n * Activates the correct label map if clicked segment\n * does not belong to the active labelmap\n */\n const { StudyInstanceUID } = activeViewport;\n const studyMetadata = studyMetadataManager.get(StudyInstanceUID);\n const allDisplaySets = studyMetadata.getDisplaySets();\n let selectedSegmentation;\n let newLabelmapIndex = getActiveLabelMapIndex();\n allDisplaySets.forEach(displaySet => {\n if (displaySet.labelmapSegments) {\n Object.keys(displaySet.labelmapSegments).forEach(labelmapIndex => {\n if (\n displaySet.labelmapSegments[labelmapIndex].includes(segmentIndex)\n ) {\n newLabelmapIndex = labelmapIndex;\n selectedSegmentation =\n displaySet.hasOverlapping === true\n ? displaySet.originLabelMapIndex\n : labelmapIndex;\n }\n });\n }\n });\n\n const brushStackState = getBrushStackState();\n brushStackState.activeLabelmapIndex = newLabelmapIndex;\n if (selectedSegmentation) {\n setState(state => ({ ...state, selectedSegmentation }));\n }\n\n refreshViewports();\n\n return segmentIndex;\n };\n\n useEffect(() => {\n const labelmapModifiedHandler = event => {\n log.warn('Segmentation Panel: labelmap modified', event);\n refreshSegmentations();\n };\n\n /*\n * TODO: Improve the way we notify parts of the app that depends on segs to be loaded.\n *\n * Currently we are using a non-ideal implementation through a custom event to notify the segmentation panel\n * or other components that could rely on loaded segmentations that\n * the segments were loaded so that e.g. when the user opens the panel\n * before the segments are fully loaded, the panel can subscribe to this custom event\n * and update itself with the new segments.\n *\n * This limitation is due to the fact that the cs segmentation module is an object (which will be\n * updated after the segments are loaded) that React its not aware of its changes\n * because the module object its not passed in to the panel component as prop but accessed externally.\n *\n * Improving this event approach to something reactive that can be tracked inside the react lifecycle,\n * allows us to easily watch the module or the segmentations loading process in any other component\n * without subscribing to external events.\n */\n document.addEventListener(\n 'extensiondicomsegmentationsegloaded',\n refreshSegmentations\n );\n document.addEventListener(\n 'extensiondicomsegmentationsegselected',\n updateSegmentationComboBox\n );\n\n /*\n * These are specific to each element;\n * Need to iterate cornerstone-tools tracked enabled elements?\n * Then only care about the one tied to active viewport?\n */\n cornerstoneTools.store.state.enabledElements.forEach(enabledElement =>\n enabledElement.addEventListener(\n 'cornerstonetoolslabelmapmodified',\n labelmapModifiedHandler\n )\n );\n\n return () => {\n document.removeEventListener(\n 'extensiondicomsegmentationsegloaded',\n refreshSegmentations\n );\n document.removeEventListener(\n 'extensiondicomsegmentationsegselected',\n updateSegmentationComboBox\n );\n cornerstoneTools.store.state.enabledElements.forEach(enabledElement =>\n enabledElement.removeEventListener(\n 'cornerstonetoolslabelmapmodified',\n labelmapModifiedHandler\n )\n );\n };\n }, [\n activeIndex,\n viewports,\n ]);\n\n const updateSegmentationComboBox = e => {\n const index = e.detail.activatedLabelmapIndex;\n if (index !== -1) {\n setState(state => ({ ...state, selectedSegmentation: index }));\n }\n };\n\n const refreshSegmentations = () => {\n const activeViewport = getActiveViewport();\n const isDisabled = !activeViewport || !activeViewport.StudyInstanceUID;\n if (!isDisabled) {\n const brushStackState = getBrushStackState();\n if (brushStackState) {\n const labelMapList = getLabelMapList();\n const {\n items: segmentList,\n numbers: segmentNumbers,\n segmentsHidden,\n } = getSegmentList();\n setState(state => ({\n ...state,\n segmentsHidden,\n segmentNumbers,\n labelMapList,\n segmentList,\n isDisabled,\n }));\n } else {\n setState(state => ({\n ...state,\n segmentsHidden: [],\n segmentNumbers: [],\n labelMapList: [],\n segmentList: [],\n isDisabled,\n }));\n }\n }\n };\n\n useEffect(() => {\n refreshSegmentations();\n }, [\n viewports,\n activeIndex,\n isOpen,\n state.selectedSegmentation,\n activeContexts,\n state.isLoading,\n ]);\n\n /* Handle open/closed panel behaviour */\n useEffect(() => {\n setState(state => ({\n ...state,\n showSettings: state.showSettings && !isOpen,\n }));\n }, [isOpen]);\n\n const getLabelMapList = () => {\n const activeViewport = getActiveViewport();\n\n /* Get list of SEG labelmaps specific to active viewport (reference series) */\n const referencedSegDisplaysets = _getReferencedSegDisplaysets(\n activeViewport.StudyInstanceUID,\n activeViewport.SeriesInstanceUID\n );\n\n const filteredReferencedSegDisplaysets = referencedSegDisplaysets.filter(\n segDisplay => segDisplay.loadError !== true\n );\n\n return filteredReferencedSegDisplaysets.map((displaySet, index) => {\n const {\n labelmapIndex,\n originLabelMapIndex,\n hasOverlapping,\n SeriesDate,\n SeriesTime,\n } = displaySet;\n\n /* Map to display representation */\n const dateStr = `${SeriesDate}:${SeriesTime}`.split('.')[0];\n const date = moment(dateStr, 'YYYYMMDD:HHmmss');\n const displayDate = date.format('ddd, MMM Do YYYY, h:mm:ss a');\n const displayDescription = displaySet.SeriesDescription;\n\n return {\n value: hasOverlapping === true ? originLabelMapIndex : labelmapIndex,\n title: displayDescription,\n description: displayDate,\n onClick: async () => {\n const activatedLabelmapIndex = await setActiveLabelmap(\n activeViewport,\n studies,\n displaySet,\n onSelectedSegmentationChange,\n onDisplaySetLoadFailure\n );\n setState(state => ({\n ...state,\n selectedSegmentation: activatedLabelmapIndex,\n }));\n },\n };\n });\n };\n\n const setCurrentSelectedSegment = segmentNumber => {\n setActiveSegment(segmentNumber);\n\n const sameSegment = state.selectedSegment === segmentNumber;\n if (!sameSegment) {\n setState(state => ({ ...state, selectedSegment: segmentNumber }));\n }\n\n const validIndexList = [];\n getActiveLabelMaps2D().forEach((labelMap2D, index) => {\n if (labelMap2D.segmentsOnLabelmap.includes(segmentNumber)) {\n validIndexList.push(index);\n }\n });\n\n const avg = array => array.reduce((a, b) => a + b) / array.length;\n const average = avg(validIndexList);\n const closest = validIndexList.reduce((prev, curr) => {\n return Math.abs(curr - average) < Math.abs(prev - average) ? curr : prev;\n });\n\n if (isCornerstone()) {\n const element = getEnabledElement();\n const toolState = cornerstoneTools.getToolState(element, 'stack');\n\n if (!toolState) return;\n\n const imageIds = toolState.data[0].imageIds;\n const imageId = imageIds[closest];\n const frameIndex = imageIds.indexOf(imageId);\n\n const SOPInstanceUID = cornerstone.metaData.get(\n 'SOPInstanceUID',\n imageId\n );\n const StudyInstanceUID = cornerstone.metaData.get(\n 'StudyInstanceUID',\n imageId\n );\n\n DICOMSegTempCrosshairsTool.addCrosshair(element, imageId, segmentNumber);\n\n onSegmentItemClick({\n StudyInstanceUID,\n SOPInstanceUID,\n frameIndex,\n activeViewportIndex: activeIndex,\n });\n }\n\n if (isVTK()) {\n const labelMaps3D = getActiveLabelMaps3D();\n const currentDisplaySet = getCurrentDisplaySet();\n const frame = labelMaps3D.labelmaps2D[closest];\n\n onSegmentItemClick({\n studies,\n StudyInstanceUID: currentDisplaySet.StudyInstanceUID,\n displaySetInstanceUID: currentDisplaySet.displaySetInstanceUID,\n SOPClassUID: getActiveViewport().sopClassUIDs[0],\n SOPInstanceUID: currentDisplaySet.SOPInstanceUID,\n segmentNumber,\n frameIndex: closest,\n frame,\n });\n }\n };\n\n const getColorLUTTable = () => {\n const { state } = cornerstoneTools.getModule('segmentation');\n const { colorLUTIndex } = getActiveLabelMaps3D();\n return state.colorLutTables[colorLUTIndex];\n };\n\n const getEnabledElement = () => {\n const enabledElements = cornerstone.getEnabledElements();\n return enabledElements[activeIndex].element;\n };\n\n const onSegmentVisibilityChangeHandler = (\n isVisible,\n segmentNumber,\n labelmap3D\n ) => {\n let segmentsHidden = [];\n if (labelmap3D.metadata.hasOverlapping) {\n /** Get all labelmaps with this segmentNumber and that\n * are from the same series (overlapping segments) */\n const { labelmaps3D } = getBrushStackState();\n\n const sameSeriesLabelMaps3D = labelmaps3D.filter(({ metadata }) => {\n return (\n labelmap3D.metadata.segmentationSeriesInstanceUID ===\n metadata.segmentationSeriesInstanceUID\n );\n });\n\n const possibleLabelMaps3D = sameSeriesLabelMaps3D.filter(\n ({ labelmaps2D }) => {\n return labelmaps2D.some(({ segmentsOnLabelmap }) =>\n segmentsOnLabelmap.includes(segmentNumber)\n );\n }\n );\n\n possibleLabelMaps3D.forEach(labelmap3D => {\n labelmap3D.segmentsHidden[segmentNumber] = !isVisible;\n\n segmentsHidden = [\n ...new Set([...segmentsHidden, ...labelmap3D.segmentsHidden]),\n ];\n });\n } else {\n labelmap3D.segmentsHidden[segmentNumber] = !isVisible;\n segmentsHidden = [...labelmap3D.segmentsHidden];\n }\n\n setState(state => ({ ...state, segmentsHidden }));\n\n refreshSegmentations();\n refreshViewports();\n\n if (isVTK()) {\n onSegmentVisibilityChange(segmentNumber, isVisible);\n }\n };\n\n const getSegmentList = () => {\n /*\n * Newly created segments have no `meta`\n * So we instead build a list of all segment indexes in use\n * Then find any associated metadata\n */\n const uniqueSegmentIndexes = getActiveLabelMaps2D()\n .reduce((acc, labelmap2D) => {\n if (labelmap2D) {\n const segmentIndexes = labelmap2D.segmentsOnLabelmap;\n\n for (let i = 0; i < segmentIndexes.length; i++) {\n if (!acc.includes(segmentIndexes[i]) && segmentIndexes[i] !== 0) {\n acc.push(segmentIndexes[i]);\n }\n }\n }\n\n return acc;\n }, [])\n .sort((a, b) => a - b);\n\n const labelmap3D = getActiveLabelMaps3D();\n const colorLutTable = getColorLUTTable();\n const hasLabelmapMeta = labelmap3D.metadata && labelmap3D.metadata.data;\n\n const segmentList = [];\n const segmentNumbers = [];\n for (let i = 0; i < uniqueSegmentIndexes.length; i++) {\n const segmentIndex = uniqueSegmentIndexes[i];\n\n const color = colorLutTable[segmentIndex];\n let segmentLabel = '(unlabeled)';\n let segmentNumber = segmentIndex;\n\n /* Meta */\n if (hasLabelmapMeta) {\n const segmentMeta = labelmap3D.metadata.data[segmentIndex];\n if (segmentMeta) {\n segmentNumber = segmentMeta.SegmentNumber;\n segmentLabel = segmentMeta.SegmentLabel;\n }\n }\n\n const sameSegment = state.selectedSegment === segmentNumber;\n\n segmentNumbers.push(segmentNumber);\n segmentList.push(\n \n );\n }\n\n return {\n items: segmentList,\n numbers: segmentNumbers,\n segmentsHidden: labelmap3D.segmentsHidden,\n };\n\n /*\n * Let's iterate over segmentIndexes ^ above\n * If meta has a match, use it to show info\n * If now, add \"no-meta\" class\n * Show default name\n */\n };\n\n const updateBrushSize = evt => {\n const updatedRadius = Number(evt.target.value);\n\n if (updatedRadius !== brushRadius) {\n setState(state => ({ ...state, brushRadius: updatedRadius }));\n const module = cornerstoneTools.getModule('segmentation');\n module.setters.radius(updatedRadius);\n }\n };\n\n const decrementSegment = event => {\n const activeSegmentIndex = getActiveSegmentIndex();\n event.preventDefault();\n if (activeSegmentIndex > 1) {\n activeSegmentIndex--;\n }\n setState(state => ({ ...state, selectedSegment: activeSegmentIndex }));\n updateActiveSegmentColor();\n };\n\n const incrementSegment = event => {\n const activeSegmentIndex = getActiveSegmentIndex();\n event.preventDefault();\n activeSegmentIndex++;\n setState(state => ({ ...state, selectedSegment: activeSegmentIndex }));\n updateActiveSegmentColor();\n };\n\n const updateActiveSegmentColor = () => {\n const color = getActiveSegmentColor();\n setState(state => ({ ...state, brushColor: color }));\n };\n\n const getBrushStackState = () => {\n const module = cornerstoneTools.getModule('segmentation');\n const firstImageId = getFirstImageId();\n const brushStackState = module.state.series[firstImageId];\n return brushStackState;\n };\n\n const getActiveSegmentColor = () => {\n const brushStackState = getBrushStackState();\n if (!brushStackState) {\n return 'rgba(255, 255, 255, 1)';\n }\n\n const colorLutTable = getColorLUTTable();\n const color = colorLutTable[labelmap3D.activeSegmentIndex];\n return `rgba(${color.join(',')})`;\n };\n\n const updateConfiguration = newConfiguration => {\n configuration.renderFill = newConfiguration.renderFill;\n configuration.renderOutline = newConfiguration.renderOutline;\n configuration.shouldRenderInactiveLabelmaps =\n newConfiguration.shouldRenderInactiveLabelmaps;\n configuration.fillAlpha = newConfiguration.fillAlpha;\n configuration.outlineAlpha = newConfiguration.outlineAlpha;\n configuration.outlineWidth = newConfiguration.outlineWidth;\n configuration.fillAlphaInactive = newConfiguration.fillAlphaInactive;\n configuration.outlineAlphaInactive = newConfiguration.outlineAlphaInactive;\n onConfigurationChange(newConfiguration);\n refreshViewports();\n };\n\n const onVisibilityChangeHandler = isVisible => {\n let segmentsHidden = [];\n state.segmentNumbers.forEach(segmentNumber => {\n if (isVTK()) {\n onSegmentVisibilityChange(segmentNumber, isVisible);\n }\n\n /** Get all labelmaps with this segmentNumber (overlapping segments) */\n const { labelmaps3D } = getBrushStackState();\n const possibleLabelMaps3D = labelmaps3D.filter(({ labelmaps2D }) => {\n return labelmaps2D.some(({ segmentsOnLabelmap }) =>\n segmentsOnLabelmap.includes(segmentNumber)\n );\n });\n\n possibleLabelMaps3D.forEach(labelmap3D => {\n labelmap3D.segmentsHidden[segmentNumber] = !isVisible;\n segmentsHidden = [\n ...new Set([...segmentsHidden, ...labelmap3D.segmentsHidden]),\n ];\n });\n });\n\n setState(state => ({ ...state, segmentsHidden }));\n\n refreshSegmentations();\n refreshViewports();\n };\n\n const disabledConfigurationFields = [\n 'outlineAlpha',\n 'shouldRenderInactiveLabelmaps',\n ];\n\n const selectedSegmentationOption = state.labelMapList.find(\n i => i.value === state.selectedSegmentation\n );\n\n if (state.showSettings) {\n return (\n setState(state => ({ ...state, showSettings: false }))}\n onChange={updateConfiguration}\n />\n );\n } else {\n return (\n \n {false && (\n
    \n \n \n \n )}\n setState(state => ({ ...state, showSettings: true }))}\n />\n

    Segmentations

    \n
    \n \n
    \n isHidden === true).length <\n state.segmentNumbers.length && state.segmentNumbers.length > 0\n }\n onVisibilityChange={onVisibilityChangeHandler}\n >\n \n {state.segmentList}\n \n \n \n );\n }\n};\n\nSegmentationPanel.propTypes = {\n /*\n * An object, with int index keys?\n * Maps to: state.viewports.viewportSpecificData, in `viewer`\n * Passed in MODULE_TYPES.PANEL when specifying component in viewer\n */\n viewports: PropTypes.shape({\n displaySetInstanceUID: PropTypes.string,\n frameRate: PropTypes.any,\n InstanceNumber: PropTypes.number,\n isMultiFrame: PropTypes.bool,\n isReconstructable: PropTypes.bool,\n Modality: PropTypes.string,\n plugin: PropTypes.string,\n SeriesDate: PropTypes.string,\n SeriesDescription: PropTypes.string,\n SeriesInstanceUID: PropTypes.string,\n SeriesNumber: PropTypes.any,\n SeriesTime: PropTypes.string,\n sopClassUIDs: PropTypes.arrayOf(PropTypes.string),\n StudyInstanceUID: PropTypes.string,\n }),\n activeIndex: PropTypes.number.isRequired,\n studies: PropTypes.array.isRequired,\n isOpen: PropTypes.bool.isRequired,\n};\nSegmentationPanel.defaultProps = {};\n\n/**\n * Returns SEG DisplaySets that reference the target series, sorted by dateTime\n *\n * @param {string} StudyInstanceUID\n * @param {string} SeriesInstanceUID\n * @returns Array\n */\nconst _getReferencedSegDisplaysets = (StudyInstanceUID, SeriesInstanceUID) => {\n /* Referenced DisplaySets */\n const studyMetadata = studyMetadataManager.get(StudyInstanceUID);\n const referencedDisplaysets = studyMetadata.getDerivedDatasets({\n referencedSeriesInstanceUID: SeriesInstanceUID,\n Modality: 'SEG',\n });\n\n /* Sort */\n referencedDisplaysets.sort((a, b) => {\n const aNumber = Number(`${a.SeriesDate}${a.SeriesTime}`);\n const bNumber = Number(`${b.SeriesDate}${b.SeriesTime}`);\n return bNumber - aNumber;\n });\n\n return referencedDisplaysets;\n};\n\nconst SegmentsSection = ({\n count,\n children,\n isVisible: defaultVisibility,\n onVisibilityChange,\n}) => {\n const [isVisible, setIsVisible] = useState(defaultVisibility);\n\n const onVisibilityChangeHandler = () => {\n const newVisibility = !isVisible;\n setIsVisible(newVisibility);\n onVisibilityChange(newVisibility);\n };\n\n useEffect(() => {\n setIsVisible(defaultVisibility);\n }, [defaultVisibility]);\n\n return (\n
    \n
    \n
    Segments
    \n
    \n \n
    {count}
    \n
    \n
    \n {children}\n
    \n );\n};\n\nconst noop = () => {};\n\nSegmentsSection.defaultProps = {\n onVisibilityChange: noop,\n};\n\nexport default SegmentationPanel;\n","import React from 'react';\nimport OHIF from '@ohif/core';\n\nimport init from './init.js';\nimport toolbarModule from './toolbarModule.js';\nimport getSopClassHandlerModule from './getOHIFDicomSegSopClassHandler.js';\nimport SegmentationPanel from './components/SegmentationPanel/SegmentationPanel.js';\nimport { version } from '../package.json';\nconst { studyMetadataManager } = OHIF.utils;\n\nexport default {\n /**\n * Only required property. Should be a unique value across all extensions.\n */\n id: 'com.ohif.dicom-segmentation',\n version,\n\n /**\n *\n *\n * @param {object} [configuration={}]\n * @param {object|array} [configuration.csToolsConfig] - Passed directly to `initCornerstoneTools`\n */\n preRegistration({ servicesManager, configuration = {} }) {\n init({ servicesManager, configuration });\n },\n getToolbarModule({ servicesManager }) {\n return toolbarModule;\n },\n getPanelModule({ commandsManager, api, servicesManager }) {\n const { UINotificationService, LoggerService } = servicesManager.services;\n\n const ExtendedSegmentationPanel = props => {\n const { activeContexts } = api.hooks.useAppContext();\n\n const onDisplaySetLoadFailureHandler = error => {\n LoggerService.error({ error, message: error.message });\n UINotificationService.show({\n title: 'DICOM Segmentation Loader',\n message: error.message,\n type: 'error',\n autoClose: false,\n });\n };\n\n const segmentItemClickHandler = data => {\n commandsManager.runCommand('jumpToImage', data);\n commandsManager.runCommand('jumpToSlice', data);\n };\n\n const onSegmentVisibilityChangeHandler = (segmentNumber, visible) => {\n commandsManager.runCommand('setSegmentConfiguration', {\n segmentNumber,\n visible,\n });\n };\n\n const onConfigurationChangeHandler = configuration => {\n commandsManager.runCommand('setSegmentationConfiguration', {\n globalOpacity: configuration.fillAlpha,\n outlineThickness: configuration.outlineWidth,\n renderOutline: configuration.renderOutline,\n visible: configuration.renderFill,\n });\n };\n\n const onSelectedSegmentationChangeHandler = () => {\n commandsManager.runCommand('requestNewSegmentation');\n };\n\n return (\n \n );\n };\n\n const SegmentationPanelTabUpdatedEvent = 'segmentation-panel-tab-updated';\n\n /**\n * Trigger's an event to update the state of the panel's RoundedButtonGroup.\n *\n * This is required to avoid extension state\n * coupling with the viewer's ToolbarRow component.\n *\n * @param {object} data\n */\n const triggerSegmentationPanelTabUpdatedEvent = data => {\n const event = new CustomEvent(SegmentationPanelTabUpdatedEvent, {\n detail: data,\n });\n document.dispatchEvent(event);\n };\n\n const onSegmentationsLoaded = ({ detail }) => {\n const { segDisplaySet, segMetadata } = detail;\n const studyMetadata = studyMetadataManager.get(\n segDisplaySet.StudyInstanceUID\n );\n const referencedDisplaysets = studyMetadata.getDerivedDatasets({\n referencedSeriesInstanceUID: segMetadata.seriesInstanceUid,\n Modality: 'SEG',\n });\n triggerSegmentationPanelTabUpdatedEvent({\n badgeNumber: referencedDisplaysets.length,\n target: 'segmentation-panel',\n });\n };\n\n document.addEventListener(\n 'extensiondicomsegmentationsegloaded',\n onSegmentationsLoaded\n );\n\n return {\n menuOptions: [\n {\n icon: 'list',\n label: 'Segmentations',\n target: 'segmentation-panel',\n stateEvent: SegmentationPanelTabUpdatedEvent,\n isDisabled: (studies, activeViewport) => {\n if (!studies) {\n return true;\n }\n\n for (let i = 0; i < studies.length; i++) {\n const study = studies[i];\n\n if (study && study.series) {\n for (let j = 0; j < study.series.length; j++) {\n const series = study.series[j];\n\n if (series.Modality === 'SEG') {\n if (activeViewport) {\n const studyMetadata = studyMetadataManager.get(\n activeViewport.StudyInstanceUID\n );\n if (!studyMetadata) {\n return;\n }\n const referencedDS = studyMetadata.getDerivedDatasets({\n referencedSeriesInstanceUID:\n activeViewport.SeriesInstanceUID,\n Modality: 'SEG',\n });\n triggerSegmentationPanelTabUpdatedEvent({\n badgeNumber: referencedDS.length,\n target: 'segmentation-panel',\n });\n }\n return false;\n }\n }\n }\n }\n\n return true;\n },\n },\n ],\n components: [\n {\n id: 'segmentation-panel',\n component: ExtendedSegmentationPanel,\n },\n ],\n defaultContext: ['VIEWER'],\n };\n },\n getSopClassHandlerModule,\n};\n","import csTools from 'cornerstone-tools';\nimport DICOMSegTempCrosshairsTool from './tools/DICOMSegTempCrosshairsTool';\n\n/**\n *\n * @param {object} configuration\n * @param {Object|Array} configuration.csToolsConfig\n */\nexport default function init({ servicesManager, configuration = {} }) {\n const { BrushTool, SphericalBrushTool, CorrectionScissorsTool } = csTools;\n const tools = [BrushTool, SphericalBrushTool, CorrectionScissorsTool];\n\n tools.forEach(tool => csTools.addTool(tool));\n\n csTools.addTool(BrushTool, {\n name: 'BrushEraser',\n configuration: {\n alwaysEraseOnClick: true,\n },\n });\n\n csTools.addTool(DICOMSegTempCrosshairsTool);\n}\n","const TOOL_NAMES = {\n RTSTRUCT_DISPLAY_TOOL: 'RTStructDisplayTool',\n};\n\nexport default TOOL_NAMES;\n","import cornerstone from 'cornerstone-core';\nimport cornerstoneTools from 'cornerstone-tools';\n\nconst { importInternal } = cornerstoneTools;\nconst draw = importInternal('drawing/draw');\nconst drawLine = importInternal('drawing/drawLine');\nconst getNewContext = importInternal('drawing/getNewContext');\n\nexport default function _drawCanvasCrosshairs(eventData, center, options) {\n const context = getNewContext(eventData.canvasContext.canvas);\n const { element } = eventData;\n\n const centerCanvas = cornerstone.pixelToCanvas(element, center);\n\n const { clientWidth: width, clientHeight: height } = element;\n\n const offset = 10;\n\n draw(context, context => {\n drawLine(\n context,\n element,\n { x: centerCanvas.x + offset, y: centerCanvas.y },\n { x: width, y: centerCanvas.y },\n options,\n 'canvas'\n );\n\n drawLine(\n context,\n element,\n { x: centerCanvas.x - offset, y: centerCanvas.y },\n { x: 0, y: centerCanvas.y },\n options,\n 'canvas'\n );\n\n drawLine(\n context,\n element,\n { x: centerCanvas.x, y: centerCanvas.y + offset },\n { x: centerCanvas.x, y: height },\n options,\n 'canvas'\n );\n\n drawLine(\n context,\n element,\n { x: centerCanvas.x, y: centerCanvas.y - offset },\n { x: centerCanvas.x, y: 0 },\n options,\n 'canvas'\n );\n });\n}\n","import { importInternal, getToolState, toolColors } from 'cornerstone-tools';\nimport TOOL_NAMES from '../utils/toolNames';\nimport drawCanvasCrosshairs from '../utils/drawCanvasCrosshairs';\n\n// Cornerstone 3rd party dev kit imports\nconst draw = importInternal('drawing/draw');\nconst drawCircle = importInternal('drawing/drawCircle');\nconst drawJoinedLines = importInternal('drawing/drawJoinedLines');\nconst getNewContext = importInternal('drawing/getNewContext');\nconst BaseTool = importInternal('base/BaseTool');\n\n/**\n * @class RTStructDisplayTool - Renders RTSTRUCT data in a read only manner (i.e. as an overlay).\n * @extends cornerstoneTools.BaseTool\n */\nexport default class RTStructDisplayTool extends BaseTool {\n constructor(props = {}) {\n const defaultProps = {\n mixins: ['enabledOrDisabledBinaryTool'],\n name: TOOL_NAMES.RTSTRUCT_DISPLAY_TOOL,\n };\n\n const initialProps = Object.assign(defaultProps, props);\n\n super(initialProps);\n\n this._rtStructModule = cornerstoneTools.getModule('rtstruct');\n }\n\n renderToolData(evt) {\n const eventData = evt.detail;\n const rtstructModule = this._rtStructModule;\n\n const toolState = getToolState(evt.currentTarget, this.name);\n\n if (!toolState) {\n return;\n }\n\n const {\n lineWidth,\n opacity,\n highlightOpacity,\n } = rtstructModule.configuration;\n\n // We have tool data for this element - iterate over each one and draw it\n const context = getNewContext(eventData.canvasContext.canvas);\n\n let crossHairCenter;\n\n for (let i = 0; i < toolState.data.length; i++) {\n const data = toolState.data[i];\n\n const structureSet = rtstructModule.getters.structureSet(\n data.structureSetSeriesInstanceUid\n );\n\n // Don't render if entire StructureSet is hidden.\n if (structureSet.visible === false) {\n continue;\n }\n\n const ROIContourData = rtstructModule.getters.ROIContour(\n data.structureSetSeriesInstanceUid,\n data.ROINumber\n );\n\n // Don't render if ROIContour is hidden.\n if (ROIContourData.visible === false) {\n continue;\n }\n\n const points = data.handles.points;\n\n if (!points.length) {\n continue;\n }\n\n const colorArray = ROIContourData.colorArray;\n const color = `rgba(${colorArray[0]},${colorArray[1]},${\n colorArray[2]\n },${opacity})`;\n\n let highlight = data.highlight;\n const options = { color, lineWidth };\n\n if (highlight) {\n crossHairCenter = { x: 0, y: 0 };\n\n points.forEach(point => {\n crossHairCenter.x += point.x;\n crossHairCenter.y += point.y;\n });\n\n crossHairCenter.x /= points.length;\n crossHairCenter.y /= points.length;\n\n // TODO: Disabling hightlight for now, it'd be good to bring it back\n // when we have a good way of doing this for SEG.\n\n // options.fillStyle = color = `rgba(${colorArray[0]},${colorArray[1]},${\n // colorArray[2]\n // },${highlightOpacity})`;\n\n // Draw highlight lines.\n\n delete data.highlight; // Don't highlight on next render.\n }\n\n switch (data.type) {\n case 'CLOSED_PLANAR':\n this._renderClosedPlanar(context, eventData.element, points, options);\n break;\n case 'POINT':\n this._renderPoint(context, eventData.element, points, options);\n break;\n case 'OPEN_PLANAR':\n this._renderOpenPlanar(context, eventData.element, points, options);\n break;\n }\n }\n\n if (crossHairCenter) {\n drawCanvasCrosshairs(eventData, crossHairCenter, {\n color: toolColors.getActiveColor(),\n lineWidth: 1,\n });\n }\n }\n\n _renderClosedPlanar(context, element, points, options) {\n draw(context, context => {\n drawJoinedLines(\n context,\n element,\n points[points.length - 1],\n points,\n options\n );\n });\n }\n\n _renderPoint(context, element, points, options) {\n draw(context, context => {\n drawCircle(context, element, points[0], 3, options);\n });\n }\n\n _renderOpenPlanar(context, element, points, options) {\n draw(context, context => {\n drawJoinedLines(context, element, points[0], points, options);\n });\n }\n}\n","import cornerstoneTools from 'cornerstone-tools';\nimport TOOL_NAMES from '../../../utils/toolNames';\n\nconst globalImageIdSpecificToolStateManager =\n cornerstoneTools.globalImageIdSpecificToolStateManager;\n\n/**\n * getImageIdOfCenterFrameOfROIContour - Returns the imageId nearest to the center of the\n * volumes extent in the stack's Z direction which contains one of the ROIContour's Contours.\n * @param {string} structureSetSeriesInstanceUid The SeriesInstanceUID of the structure set.\n * @param {number} ROINumber The ROINumber of the region.\n * @param {string} imageIdsInStack The stack of imageIds.\n *\n * @returns The imageId\n */\nexport default function getImageIdOfCenterFrameOfROIContour(\n structureSetSeriesInstanceUid,\n ROINumber,\n imageIdsInStack\n) {\n const rtStructDisplayToolName = TOOL_NAMES.RTSTRUCT_DISPLAY_TOOL;\n const toolState = globalImageIdSpecificToolStateManager.saveToolState();\n const imageIdIndicies = [];\n\n for (let i = 0; i < imageIdsInStack.length; i++) {\n const imageId = imageIdsInStack[i];\n\n const imageIdSpecificToolState = toolState[imageId];\n\n if (\n !imageIdSpecificToolState ||\n !imageIdSpecificToolState[rtStructDisplayToolName] ||\n !imageIdSpecificToolState[rtStructDisplayToolName].data\n ) {\n continue;\n }\n\n const toolData = imageIdSpecificToolState[rtStructDisplayToolName].data;\n\n if (\n _toolDataContainsROIContour(\n toolData,\n structureSetSeriesInstanceUid,\n ROINumber\n )\n ) {\n imageIdIndicies.push(i);\n }\n }\n\n const centerImageIdIndex =\n imageIdIndicies[Math.floor(imageIdIndicies.length / 2)];\n\n return imageIdsInStack[centerImageIdIndex];\n}\n\nfunction _toolDataContainsROIContour(\n toolData,\n structureSetSeriesInstanceUid,\n ROINumber\n) {\n return !!toolData.some(\n toolDataI =>\n toolDataI.structureSetSeriesInstanceUid ===\n structureSetSeriesInstanceUid && toolDataI.ROINumber === ROINumber\n );\n}\n","import cornerstone from 'cornerstone-core';\nimport getImageIdOfCenterFrameOfROIContour from './lib/getImageIdOfCenterFrameOfROIContour';\nimport structureSetReferencesSeriesInstanceUid from './lib/structureSetReferencesSeriesInstanceUid';\n\n// We should put this as a helper somewhere as we are using it in mutliple places.\nfunction refreshViewport() {\n cornerstone.getEnabledElements().forEach(enabledElement => {\n if (enabledElement.image) {\n cornerstone.updateImage(enabledElement.element);\n }\n });\n}\n\nconst configuration = {\n lineWidth: 3,\n opacity: 0.75,\n highlightOpacity: 0.5,\n};\n\nconst state = {\n StructureSets: [],\n};\n\n/**\n * Adds a structure set to the module.\n * @param {Object} structureSetData The structure set data.\n */\nfunction setStructureSet(structureSetData) {\n state.StructureSets.push(structureSetData);\n}\n\n/**\n * Returns the StructureSet with the given SeriesInstanceUID.\n * @param {string} SeriesInstanceUID The SeriesInstanceUID of the StructureSet.\n *\n * @returns {Object} The StructureSet.\n */\nfunction getStructureSet(SeriesInstanceUID) {\n return state.StructureSets.find(\n structureSet => structureSet.SeriesInstanceUID === SeriesInstanceUID\n );\n}\n\n/**\n * Returns the ROI Contour with the given ROINumber on the StructureSet defined by the given\n * SeriesInstanceUID.\n * @param {string} SeriesInstanceUID The SeriesInstanceUID of the StructureSet.\n * @param {number} ROINumber The ROINUmber of the ROIContour to fetch.\n */\nfunction getROIContour(SeriesInstanceUID, ROINumber) {\n const structureSet = getStructureSet(SeriesInstanceUID);\n\n if (!structureSet) {\n return;\n }\n\n return structureSet.ROIContours.find(\n ROIContour => ROIContour.ROINumber === ROINumber\n );\n}\n\n/**\n * Hides the StructureSet.\n * @param {string} SeriesInstanceUID The SeriesInstanceUID of the StructureSet.\n */\nfunction setHideStructureSet(SeriesInstanceUID) {\n _setStructureSetVisible(SeriesInstanceUID, false);\n}\n\n/**\n * Shows the StructureSet.\n * @param {string} SeriesInstanceUID The SeriesInstanceUID of the StructureSet.\n */\nfunction setShowStructureSet(SeriesInstanceUID) {\n _setStructureSetVisible(SeriesInstanceUID, true);\n}\n\n/**\n * Sets the visibility of the StructureSet.\n * @param {string} SeriesInstanceUID The SeriesInstanceUID of the StructureSet.\n * @param {boolean} visible Whether the StructureSet should visible or not.\n */\nfunction _setStructureSetVisible(SeriesInstanceUID, visible = true) {\n const StructureSet = getStructureSet(SeriesInstanceUID);\n\n if (StructureSet) {\n StructureSet.ROIContours.forEach(ROIContour => {\n ROIContour.visible = visible;\n });\n\n refreshViewport();\n }\n}\n\n/**\n * Toggles the visibility of the StructureSet.\n * @param {string} SeriesInstanceUID The SeriesInstanceUID of the StructureSet.\n */\nfunction setToggleStructureSet(SeriesInstanceUID) {\n const StructureSet = getStructureSet(SeriesInstanceUID);\n\n if (StructureSet) {\n StructureSet.visible = !StructureSet.visible;\n\n refreshViewport();\n }\n}\n\n/**\n * Hides the ROIContour.\n * @param {string} SeriesInstanceUID The SeriesInstanceUID of the StructureSet.\n * @param {number} ROINumber The ROINUmber of the ROIContour.\n */\nfunction setHideROIContour(SeriesInstanceUID, ROINumber) {\n _setROIContourVisible(SeriesInstanceUID, ROINumber, false);\n}\n\n/**\n * Shows the ROIContour.\n * @param {string} SeriesInstanceUID The SeriesInstanceUID of the StructureSet.\n * @param {number} ROINumber The ROINUmber of the ROIContour.\n */\nfunction setShowROIContour(SeriesInstanceUID, ROINumber) {\n _setROIContourVisible(SeriesInstanceUID, ROINumber, true);\n}\n\n/**\n * Sets the visibility of the ROIContour.\n * @param {string} SeriesInstanceUID The SeriesInstanceUID of the StructureSet.\n * @param {number} ROINumber The ROINUmber of the ROIContour.\n * @param {boolean} visible Whether the StructureSet should visible or not.\n */\nfunction _setROIContourVisible(SeriesInstanceUID, ROINumber, visible = true) {\n const ROIContour = getROIContour(SeriesInstanceUID, ROINumber);\n\n if (ROIContour) {\n ROIContour.visible = visible;\n\n refreshViewport();\n }\n}\n\n/**\n * Toggles the visibility of the ROIContour.\n * @param {string} SeriesInstanceUID The SeriesInstanceUID of the StructureSet.\n * @param {number} ROINumber The ROINUmber of the ROIContour.\n */\nfunction setToggleROIContour(SeriesInstanceUID, ROINumber) {\n const ROIContour = getROIContour(SeriesInstanceUID, ROINumber);\n\n if (ROIContour) {\n ROIContour.visible = !ROIContour.visible;\n\n refreshViewport();\n }\n}\n\n/**\n * Returns an array of StructureSets which reference the given SeriesInstanceUID.\n * @param {string} SeriesInstanceUID The SeriesInstanceUID to check.\n */\nfunction getStructuresSetsWhichReferenceSeriesInstanceUid(SeriesInstanceUID) {\n const { StructureSets } = state;\n return StructureSets.filter(StructureSet =>\n structureSetReferencesSeriesInstanceUid(StructureSet, SeriesInstanceUID)\n );\n}\n\nexport default {\n getters: {\n structureSet: getStructureSet,\n ROIContour: getROIContour,\n structuresSetsWhichReferenceSeriesInstanceUid: getStructuresSetsWhichReferenceSeriesInstanceUid,\n imageIdOfCenterFrameOfROIContour: getImageIdOfCenterFrameOfROIContour,\n },\n setters: {\n structureSet: setStructureSet,\n hideROIContour: setHideROIContour,\n showROIContour: setShowROIContour,\n toggleROIContour: setToggleROIContour,\n hideStructureSet: setHideStructureSet,\n showStructureSet: setShowStructureSet,\n toggleStructureSet: setToggleStructureSet,\n },\n state,\n configuration,\n};\n","/**\n * structureSetReferencesSeriesInstanceUid - Returns true if the structure set\n * references the given SeriesInstanceUID.\n * @param {*} StructureSet\n * @param {*} SeriesInstanceUID\n */\nexport default function structureSetReferencesSeriesInstanceUid(\n StructureSet,\n SeriesInstanceUID\n) {\n const { referencedSeriesSequence } = StructureSet;\n return referencedSeriesSequence.some(\n referencedSeries =>\n referencedSeries.SeriesInstanceUID ===\n SeriesInstanceUID\n );\n}\n","import cornerstoneTools from 'cornerstone-tools';\nimport RTStructDisplayTool from './tools/RTStructDisplayTool';\nimport rtStructModule from './tools/modules/rtStructModule';\n\nimport TOOL_NAMES from './utils/toolNames';\n\nconst defaultConfig = {\n TOOL_NAMES: {\n RT_STRUCT_DISPLAY_TOOL: 'RTStructDisplayTool',\n },\n};\n\n/**\n *\n * @param {object} configuration\n * @param {Object|Array} configuration.csToolsConfig\n */\nexport default function init({ servicesManager, configuration = {} }) {\n const conifg = Object.assign({}, defaultConfig, configuration);\n\n TOOL_NAMES.RT_STRUCT_DISPLAY_TOOL = conifg.TOOL_NAMES.RT_STRUCT_DISPLAY_TOOL;\n\n cornerstoneTools.register('module', 'rtstruct', rtStructModule);\n cornerstoneTools.addTool(RTStructDisplayTool);\n}\n","export default function transformPointsToImagePlane(points, imagePlane) {\n // See Equation C.7.6.2.1-1 of the DICOM standard\n\n const {\n rowCosines,\n columnCosines,\n rowPixelSpacing: deltaI,\n columnPixelSpacing: deltaJ,\n imagePositionPatient,\n } = imagePlane;\n\n const X = [rowCosines[0], rowCosines[1], rowCosines[2]];\n const Y = [columnCosines[0], columnCosines[1], columnCosines[2]];\n const S = [\n imagePositionPatient[0],\n imagePositionPatient[1],\n imagePositionPatient[2],\n ];\n\n // 9 sets of simulataneous equations to choose from, choose which set to solve\n // Based on the largest component of each direction cosine.\n // This avoids NaNs or floating point errors caused by dividing by very small numbers and ensures a safe mapping\n // when mapping between planes that are close to orthogonal.\n\n let ix = 0;\n let iy = 0;\n let largestDirectionCosineMagnitude = {\n x: 0,\n y: 0,\n };\n\n // Find the element with the largest magnitude in each direction cosine vector.\n for (let i = 0; i < X.length; i++) {\n if (Math.abs(X[i]) > largestDirectionCosineMagnitude.x) {\n ix = i;\n largestDirectionCosineMagnitude.x = Math.abs(X[i]);\n }\n if (Math.abs(Y[i]) > largestDirectionCosineMagnitude.y) {\n iy = i;\n largestDirectionCosineMagnitude.y = Math.abs(Y[i]);\n }\n }\n\n const ci = {\n // Index of max elements in X and Y\n ix,\n iy,\n };\n\n // Sanity Check\n const directionCosineMagnitude = {\n x: Math.pow(X[0], 2) + Math.pow(X[1], 2) + Math.pow(X[2], 2),\n y: Math.pow(Y[0], 2) + Math.pow(Y[1], 2) + Math.pow(Y[2], 2),\n };\n\n if (directionCosineMagnitude.x < 0.99 || directionCosineMagnitude.y < 0.99) {\n throw Error(\n `Direction cosines do not sum to 1 in quadrature. There is likely a mistake in the DICOM metadata.` +\n `directionCosineMagnitudes: ${directionCosineMagnitude.x}, ${directionCosineMagnitude.y}`\n );\n }\n\n // Fill in elements that won't change between points\n const c = [undefined, Y[ci.ix], X[ci.ix], undefined, X[ci.iy], Y[ci.iy]];\n\n for (let pointI = 0; pointI < points.length; pointI++) {\n // Subtract imagePositionPatient from the coordinate\n const r = [\n points[pointI].x - S[0],\n points[pointI].y - S[1],\n points[pointI].z - S[2],\n ];\n\n // Set the variable terms in c.\n c[0] = r[ci.ix];\n c[3] = r[ci.iy];\n\n // General case: Solves the two choosen simulataneous equations to go from the patient coordinate system to the imagePlane.\n const i =\n (c[0] - (c[1] * c[3]) / c[5]) /\n (c[2] * deltaI * (1 - (c[1] * c[4]) / (c[2] * c[5])));\n const j = (c[3] - c[4] * i * deltaI) / (c[5] * deltaJ);\n\n // NOTE: Add (0.5, 0.5) to the coordinate, as PCS reference frame is with respect to the centre of the first pixel.\n points[pointI].x = i + 0.5;\n points[pointI].y = j + 0.5;\n delete points[pointI].z;\n }\n\n return;\n}\n","import OHIF from '@ohif/core';\nimport dcmjs from 'dcmjs';\nimport cornerstone from 'cornerstone-core';\nimport cornerstoneTools from 'cornerstone-tools';\nimport transformPointsToImagePlane from './utils/transformPointsToImagePlane';\nimport TOOL_NAMES from './utils/toolNames';\nimport { vec3 } from 'gl-matrix';\n\nconst dicomlab2RGB = dcmjs.data.Colors.dicomlab2RGB;\nconst globalImageIdSpecificToolStateManager =\n cornerstoneTools.globalImageIdSpecificToolStateManager;\nconst { DicomLoaderService } = OHIF.utils;\n\nexport default async function loadRTStruct(\n rtStructDisplaySet,\n referencedDisplaySet,\n studies\n) {\n const rtStructModule = cornerstoneTools.getModule('rtstruct');\n // Set here is loading is asynchronous.\n // If this function throws its set back to false.\n rtStructDisplaySet.isLoaded = true;\n\n const { StudyInstanceUID, SeriesInstanceUID } = referencedDisplaySet;\n\n const segArrayBuffer = await DicomLoaderService.findDicomDataPromise(\n rtStructDisplaySet,\n studies\n );\n\n const dicomData = dcmjs.data.DicomMessage.readFile(segArrayBuffer);\n const rtStructDataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(\n dicomData.dict\n );\n\n rtStructDataset._meta = dcmjs.data.DicomMetaDictionary.namifyDataset(\n dicomData.meta\n );\n\n // global cornerstone tools state to attach measurements to.\n const toolState = globalImageIdSpecificToolStateManager.saveToolState();\n\n const {\n StructureSetROISequence,\n ROIContourSequence,\n RTROIObservationsSequence,\n StructureSetLabel,\n } = rtStructDataset;\n\n // Define our structure set entry and add it to the rtstruct module state.\n const structureSet = {\n StructureSetLabel,\n SeriesInstanceUID: rtStructDataset.SeriesInstanceUID,\n ROIContours: [],\n referencedSeriesSequence:\n rtStructDisplaySet.metadata.ReferencedSeriesSequence,\n visible: true,\n };\n\n rtStructModule.setters.structureSet(structureSet);\n\n const imageIdSopInstanceUidPairs = _getImageIdSopInstanceUidPairsForDisplaySet(\n studies,\n StudyInstanceUID,\n SeriesInstanceUID\n );\n\n const rtStructDisplayToolName = TOOL_NAMES.RTSTRUCT_DISPLAY_TOOL;\n\n for (let i = 0; i < ROIContourSequence.length; i++) {\n const ROIContour = ROIContourSequence[i];\n const { ReferencedROINumber, ContourSequence } = ROIContour;\n\n if (!ContourSequence) {\n continue;\n }\n\n const isSupported = false;\n\n const ContourSequenceArray = _toArray(ContourSequence);\n\n for (let c = 0; c < ContourSequenceArray.length; c++) {\n const {\n ContourImageSequence,\n ContourData,\n NumberOfContourPoints,\n ContourGeometricType,\n } = ContourSequenceArray[c];\n\n const sopInstanceUID = ContourImageSequence\n ? ContourImageSequence.ReferencedSOPInstanceUID\n : _getClosestSOPInstanceUID(\n ContourData,\n ContourGeometricType,\n NumberOfContourPoints,\n imageIdSopInstanceUidPairs\n );\n const imageId = _getImageId(imageIdSopInstanceUidPairs, sopInstanceUID);\n\n if (!imageId) {\n continue;\n }\n\n const imageIdSpecificToolData = _getOrCreateImageIdSpecificToolData(\n toolState,\n imageId,\n rtStructDisplayToolName\n );\n\n const imagePlane = cornerstone.metaData.get('imagePlaneModule', imageId);\n const points = [];\n let measurementData;\n\n switch (ContourGeometricType) {\n case 'CLOSED_PLANAR':\n case 'OPEN_PLANAR':\n case 'POINT':\n isSupported = true;\n\n for (let p = 0; p < NumberOfContourPoints * 3; p += 3) {\n points.push({\n x: ContourData[p],\n y: ContourData[p + 1],\n z: ContourData[p + 2],\n });\n }\n\n transformPointsToImagePlane(points, imagePlane);\n\n measurementData = {\n handles: {\n points,\n },\n type: ContourGeometricType,\n structureSetSeriesInstanceUid: rtStructDataset.SeriesInstanceUID,\n ROINumber: ReferencedROINumber,\n };\n\n imageIdSpecificToolData.push(measurementData);\n break;\n default:\n continue;\n }\n }\n\n _setROIContourMetadata(\n structureSet,\n StructureSetROISequence,\n RTROIObservationsSequence,\n ROIContour,\n isSupported\n );\n }\n\n _setToolEnabledIfNotEnabled(rtStructDisplayToolName);\n\n /*\n * TODO: Improve the way we notify parts of the app that depends on rts to be loaded.\n *\n * Currently we are using a non-ideal implementation through a custom event to notify the rtstruct panel\n * or other components that could rely on loaded rtstructs that\n * the first batch of structs were loaded so that e.g. when the user opens the panel\n * before the structs are fully loaded, the panel can subscribe to this custom event\n * and update itself with the new structs.\n *\n * This limitation is due to the fact that the rtmodule is an object (which will be\n * updated after the structs are loaded) that React its not aware of its changes\n * because the module object its not passed in to the panel component as prop but accessed externally.\n *\n * Improving this event approach to something reactive that can be tracked inside the react lifecycle,\n * allows us to easily watch the module or the rtstruct loading process in any other component\n * without subscribing to external events.\n */\n const event = new CustomEvent('extensiondicomrtrtloaded', {\n detail: {\n rtStructDisplaySet,\n referencedDisplaySet,\n studies,\n },\n });\n document.dispatchEvent(event);\n}\n\nfunction _setROIContourMetadata(\n structureSet,\n StructureSetROISequence,\n RTROIObservationsSequence,\n ROIContour,\n isSupported\n) {\n const StructureSetROI = StructureSetROISequence.find(\n structureSetROI =>\n structureSetROI.ROINumber === ROIContour.ReferencedROINumber\n );\n\n const ROIContourData = {\n ROINumber: StructureSetROI.ROINumber,\n ROIName: StructureSetROI.ROIName,\n ROIGenerationAlgorithm: StructureSetROI.ROIGenerationAlgorithm,\n ROIDescription: StructureSetROI.ROIDescription,\n isSupported,\n visible: true,\n };\n\n _setROIContourDataColor(ROIContour, ROIContourData);\n\n if (RTROIObservationsSequence) {\n // If present, add additional RTROIObservations metadata.\n _setROIContourRTROIObservations(\n ROIContourData,\n RTROIObservationsSequence,\n ROIContour.ReferencedROINumber\n );\n }\n\n structureSet.ROIContours.push(ROIContourData);\n}\n\nfunction _setROIContourDataColor(ROIContour, ROIContourData) {\n let { ROIDisplayColor, RecommendedDisplayCIELabValue } = ROIContour;\n\n if (!ROIDisplayColor && RecommendedDisplayCIELabValue) {\n // If ROIDisplayColor is absent, try using the RecommendedDisplayCIELabValue color.\n ROIDisplayColor = dicomlab2RGB(RecommendedDisplayCIELabValue);\n }\n\n if (ROIDisplayColor) {\n ROIContourData.colorArray = [...ROIDisplayColor];\n } else {\n //Choose a color from the cornerstoneTools colorLUT\n // We sample from the default color LUT here (i.e. 0), as we have nothing else to go on.\n const { getters } = cornerstoneTools.getModule('segmentation');\n const color = getters.colorForSegmentIndexColorLUT(\n 0,\n ROIContourData.ROINumber\n );\n\n ROIContourData.colorArray = [...color];\n }\n}\n\nfunction _setROIContourRTROIObservations(\n ROIContourData,\n RTROIObservationsSequence,\n ROINumber\n) {\n const RTROIObservations = RTROIObservationsSequence.find(\n RTROIObservations => RTROIObservations.ReferencedROINumber === ROINumber\n );\n\n if (RTROIObservations) {\n // Deep copy so we don't keep the reference to the dcmjs dataset entry.\n const {\n ObservationNumber,\n ROIObservationDescription,\n RTROIInterpretedType,\n ROIInterpreter,\n } = RTROIObservations;\n\n ROIContourData.RTROIObservations = {\n ObservationNumber,\n ROIObservationDescription,\n RTROIInterpretedType,\n ROIInterpreter,\n };\n }\n}\n\nfunction _setToolEnabledIfNotEnabled(toolName) {\n cornerstone.getEnabledElements().forEach(enabledElement => {\n const { element, image } = enabledElement;\n const tool = cornerstoneTools.getToolForElement(element, toolName);\n\n if (tool.mode !== 'enabled') {\n // If not already active or passive, set passive so contours render.\n cornerstoneTools.setToolEnabled(toolName);\n }\n\n if (image) {\n cornerstone.updateImage(element);\n }\n });\n}\n\nfunction _getOrCreateImageIdSpecificToolData(toolState, imageId, toolName) {\n if (toolState.hasOwnProperty(imageId) === false) {\n toolState[imageId] = {};\n }\n\n const imageIdToolState = toolState[imageId];\n\n // If we don't have tool state for this type of tool, add an empty object\n if (imageIdToolState.hasOwnProperty(toolName) === false) {\n imageIdToolState[toolName] = {\n data: [],\n };\n }\n\n return imageIdToolState[toolName].data;\n}\n\nconst _getImageId = (imageIdSopInstanceUidPairs, sopInstanceUID) => {\n const imageIdSopInstanceUidPairsEntry = imageIdSopInstanceUidPairs.find(\n imageIdSopInstanceUidPairsEntry =>\n imageIdSopInstanceUidPairsEntry.sopInstanceUID === sopInstanceUID\n );\n\n return imageIdSopInstanceUidPairsEntry\n ? imageIdSopInstanceUidPairsEntry.imageId\n : null;\n};\n\nfunction _getImageIdSopInstanceUidPairsForDisplaySet(\n studies,\n StudyInstanceUID,\n SeriesInstanceUID\n) {\n const study = studies.find(\n study => study.StudyInstanceUID === StudyInstanceUID\n );\n\n const displaySets = study.displaySets.filter(set => {\n return set.SeriesInstanceUID === SeriesInstanceUID;\n });\n\n if (displaySets.length > 1) {\n console.warn(\n 'More than one display set with the same SeriesInstanceUID. This is not supported yet...'\n );\n // TODO -> We could make check the instance list and see if any match?\n // Do we split the segmentation into two cornerstoneTools segmentations if there are images in both series?\n // ^ Will that even happen?\n }\n\n const referencedDisplaySet = displaySets[0];\n\n return referencedDisplaySet.images.map(image => {\n return {\n imageId: image.getImageId(),\n sopInstanceUID: image.getSOPInstanceUID(),\n };\n });\n}\n\nfunction _toArray(objOrArray) {\n return Array.isArray(objOrArray) ? objOrArray : [objOrArray];\n}\n\nfunction _getClosestSOPInstanceUID(\n ContourData,\n ContourGeometricType,\n NumberOfContourPoints,\n imageIdSopInstanceUidPairs\n) {\n const closest = {\n distance: Infinity,\n sopInstanceUID: null,\n };\n\n let point;\n\n switch (ContourGeometricType) {\n case 'POINT':\n point = ContourData;\n break;\n case 'CLOSED_PLANAR':\n case 'OPEN_PLANAR':\n // These are defined as planar, so get the of the region to get the\n // Best mapping to a plane even if its potentially off center.\n\n point = [0, 0, 0];\n for (let p = 0; p < NumberOfContourPoints * 3; p += 3) {\n point[0] += ContourData[p];\n point[1] += ContourData[p + 1];\n point[2] += ContourData[p + 2];\n }\n\n point[0] /= NumberOfContourPoints;\n point[1] /= NumberOfContourPoints;\n point[2] /= NumberOfContourPoints;\n }\n\n imageIdSopInstanceUidPairs.forEach(pair => {\n const { imageId } = pair;\n\n const imagePlaneModule = cornerstone.metaData.get(\n 'imagePlaneModule',\n imageId\n );\n\n const distance = distanceFromPointToPlane(point, imagePlaneModule);\n\n if (distance < closest.distance) {\n closest.distance = distance;\n closest.sopInstanceUID = pair.sopInstanceUID;\n }\n });\n\n return closest.sopInstanceUID;\n}\n\n/**\n *\n * @param {number[3]} P - The point\n * @param {object} imagePlaneModule The cornerstone metadata object for the imagePlane\n */\nfunction distanceFromPointToPlane(P, imagePlaneModule) {\n const {\n rowCosines,\n columnCosines,\n imagePositionPatient: Q,\n } = imagePlaneModule;\n\n let N = [];\n vec3.cross(N, rowCosines, columnCosines);\n\n const [A, B, C] = N;\n\n const D = -A * Q[0] - B * Q[1] - C * Q[2];\n\n return Math.abs(A * P[0] + B * P[1] + C * P[2] + D); // Denominator is sqrt(A**2 + B**2 + C**2) which is 1 as its a normal vector\n}\n","import { metadata } from '@ohif/core';\n\nexport default function getSourceDisplaySet(studies, rtStructDisplaySet, activateLabelMap = true) {\n const referencedDisplaySet = metadata.StudyMetadata.getReferencedDisplaySet(\n rtStructDisplaySet,\n studies\n );\n\n if (activateLabelMap) {\n rtStructDisplaySet.load(referencedDisplaySet, studies);\n }\n\n return referencedDisplaySet;\n}\n","import { MODULE_TYPES, utils, DICOMWeb } from '@ohif/core';\nimport loadRTStruct from './loadRTStruct';\nimport getSourceDisplaySet from './getSourceDisplaySet';\n\nimport id from './id';\n\n// TODO: Should probably use dcmjs for this\nconst SOP_CLASS_UIDS = {\n DICOM_RT_STRUCT: '1.2.840.10008.5.1.4.1.1.481.3',\n};\n\nconst sopClassUIDs = Object.values(SOP_CLASS_UIDS);\n\nconst OHIFDicomRTStructSopClassHandler = {\n id: 'OHIFDicomRTStructSopClassHandler',\n type: MODULE_TYPES.SOP_CLASS_HANDLER,\n sopClassUIDs,\n getDisplaySetFromSeries: function (\n series,\n study,\n dicomWebClient,\n authorizationHeaders\n ) {\n const instance = series.getFirstInstance();\n\n const metadata = instance.getData().metadata;\n const {\n SeriesDate,\n SeriesTime,\n SeriesNumber,\n SeriesDescription,\n FrameOfReferenceUID,\n SOPInstanceUID,\n SeriesInstanceUID,\n StudyInstanceUID,\n } = metadata;\n\n // TODO -> GET REFERENCED FRAME OF REFERENCE SEQUENCE.\n\n const rtStructDisplaySet = {\n Modality: 'RTSTRUCT',\n displaySetInstanceUID: utils.guid(),\n wadoRoot: study.getData().wadoRoot,\n wadoUri: instance.getData().wadouri,\n SOPInstanceUID,\n SeriesInstanceUID,\n StudyInstanceUID,\n FrameOfReferenceUID,\n authorizationHeaders,\n metadata,\n isDerived: true,\n referencedDisplaySetUID: null, // Assigned when loaded.\n labelmapIndex: null, // Assigned when loaded.\n isLoaded: false,\n SeriesDate,\n SeriesTime,\n SeriesNumber,\n SeriesDescription,\n metadata,\n };\n\n if (!metadata.ReferencedSeriesSequence) {\n const ReferencedFrameOfReferenceSequence =\n metadata.ReferencedFrameOfReferenceSequence;\n\n if (ReferencedFrameOfReferenceSequence) {\n // TODO -> @dannyrb Do we augment metadata or add a (potentially large? fallback list in filterDerivedDisplaySets )\n metadata.ReferencedSeriesSequence = _deriveReferencedSeriesSequenceFromFrameOfReferenceSequence(\n ReferencedFrameOfReferenceSequence\n );\n }\n }\n\n rtStructDisplaySet.getSourceDisplaySet = function (studies, activateLabelMap = true) {\n return getSourceDisplaySet(studies, rtStructDisplaySet, activateLabelMap);\n };\n\n rtStructDisplaySet.load = function (referencedDisplaySet, studies) {\n return loadRTStruct(\n rtStructDisplaySet,\n referencedDisplaySet,\n studies\n ).catch(error => {\n rtStructDisplaySet.isLoaded = false;\n rtStructDisplaySet.loadError = true;\n throw new Error(error);\n });\n };\n\n return rtStructDisplaySet;\n },\n};\n\nfunction _deriveReferencedSeriesSequenceFromFrameOfReferenceSequence(\n ReferencedFrameOfReferenceSequence\n) {\n const ReferencedSeriesSequence = [];\n\n _getSequenceAsArray(ReferencedFrameOfReferenceSequence).forEach(\n referencedFrameOfReference => {\n const { RTReferencedStudySequence } = referencedFrameOfReference;\n\n _getSequenceAsArray(RTReferencedStudySequence).forEach(\n rtReferencedStudy => {\n const { RTReferencedSeriesSequence } = rtReferencedStudy;\n\n _getSequenceAsArray(RTReferencedSeriesSequence).forEach(\n rtReferencedSeries => {\n const ReferencedInstanceSequence = [];\n const {\n ContourImageSequence,\n SeriesInstanceUID,\n } = rtReferencedSeries;\n\n _getSequenceAsArray(ContourImageSequence).forEach(\n contourImage => {\n ReferencedInstanceSequence.push({\n ReferencedSOPInstanceUID:\n contourImage.ReferencedSOPInstanceUID,\n ReferencedSOPClassUID: contourImage.ReferencedSOPClassUID,\n });\n }\n );\n\n const referencedSeries = {\n SeriesInstanceUID,\n ReferencedInstanceSequence,\n };\n\n ReferencedSeriesSequence.push(referencedSeries);\n }\n );\n }\n );\n }\n );\n\n return ReferencedSeriesSequence;\n}\n\nfunction _getSequenceAsArray(sequence) {\n return Array.isArray(sequence) ? sequence : [sequence];\n}\n\nfunction _getReferencedFrameOfReferenceSequence(instance) {\n const referencedFrameOfReferenceSequenceRaw = instance['30060010'];\n\n const referencedFrameOfReferenceSequence = [];\n\n if (\n !referencedFrameOfReferenceSequenceRaw ||\n !referencedFrameOfReferenceSequenceRaw.Value\n ) {\n return undefined;\n }\n\n referencedFrameOfReferenceSequenceRaw.Value.forEach(\n referencedFrameOfReferenceRaw => {\n const frameOfReferenceUID = DICOMWeb.getString(\n referencedFrameOfReferenceRaw['00200052']\n );\n\n const referencedFrameOfReference = { frameOfReferenceUID };\n const RTReferencedStudySequenceRaw =\n referencedFrameOfReferenceRaw['30060012'];\n\n referencedFrameOfReferenceSequence.push(referencedFrameOfReference);\n\n if (RTReferencedStudySequenceRaw && RTReferencedStudySequenceRaw.Value) {\n referencedFrameOfReference.rtReferencedStudySequence = [];\n\n const { rtReferencedStudySequence } = referencedFrameOfReference;\n\n RTReferencedStudySequenceRaw.Value.forEach(rtReferencedStudyRaw => {\n const referencedSopClassUID = DICOMWeb.getString(\n rtReferencedStudyRaw['00081150']\n );\n\n const referencedSOPInstanceUID = DICOMWeb.getString(\n rtReferencedStudyRaw['00081155']\n );\n\n const rtReferencedStudy = {\n referencedSopClassUID,\n referencedSOPInstanceUID,\n rtReferencedSeriesSequence: [],\n };\n\n rtReferencedStudySequence.push(rtReferencedStudy);\n\n const { rtReferencedSeriesSequence } = rtReferencedStudy;\n\n const rtReferencedSeriesSequenceRaw =\n rtReferencedStudyRaw['30060014'];\n\n rtReferencedSeriesSequenceRaw.Value.forEach(rtReferencedSeriesRaw => {\n const seriesInstanceUID = DICOMWeb.getString(\n rtReferencedSeriesRaw['0020000E']\n );\n\n const rtReferencedSeries = {\n seriesInstanceUID,\n contourImageSequence: [],\n };\n\n rtReferencedSeriesSequence.push(rtReferencedSeries);\n\n const { contourImageSequence } = rtReferencedSeries;\n\n const contourImageSequenceRaw = rtReferencedSeriesRaw['30060016'];\n\n contourImageSequenceRaw.Value.forEach(contourImageRaw => {\n const referencedSOPClassUID = DICOMWeb.getString(\n contourImageRaw['00081150']\n );\n\n const referencedSOPInstanceUID = DICOMWeb.getString(\n contourImageRaw['00081155']\n );\n\n const referencedFrameNumber = DICOMWeb.getString(\n contourImageRaw['00081160']\n );\n const referencedSegmentNumber = DICOMWeb.getString(\n contourImageRaw['0062000B']\n );\n\n const contourImage = {\n referencedSOPClassUID,\n referencedSOPInstanceUID,\n referencedFrameNumber,\n referencedSegmentNumber,\n };\n\n contourImageSequence.push(contourImage);\n });\n });\n });\n }\n }\n );\n\n return referencedFrameOfReferenceSequence;\n}\n\nexport default OHIFDicomRTStructSopClassHandler;\n","import React, { useState, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport { TableListItem, Icon, Tooltip, OverlayTrigger } from '@ohif/ui';\nimport ReactTooltip from 'react-tooltip';\n\nimport './StructureSetItem.css';\n\nconst ColoredCircle = ({ color }) => {\n return (\n \n );\n};\n\nColoredCircle.propTypes = {\n color: PropTypes.array.isRequired,\n};\n\nconst StructureSetItem = ({\n index,\n label,\n isDisabled,\n onClick,\n itemClass,\n color,\n visible = true,\n onVisibilityChange,\n selected = false,\n}) => {\n const [isVisible, setIsVisible] = useState(visible);\n\n useEffect(() => {\n setIsVisible(visible);\n }, [visible]);\n\n let dcmrtClassNames = `dcmrt-structure-set-item`;\n\n if (selected) {\n dcmrtClassNames += ' selected';\n }\n\n if (isDisabled) {\n dcmrtClassNames += ' isDisabled';\n }\n\n const warningIcon = (\n \n \n \n );\n\n const tableListItem = (\n }\n itemMetaClass=\"item-color-section\"\n onItemClick={() => {\n if (isDisabled) {\n return;\n }\n\n onClick();\n }}\n >\n
    \n
    \n \n {label}\n \n \n {label}\n \n {!isDisabled && (\n {\n event.stopPropagation();\n\n if (isDisabled) {\n return;\n }\n\n const newVisibility = !isVisible;\n setIsVisible(newVisibility);\n onVisibilityChange(newVisibility);\n }}\n />\n )}\n
    \n\n {false &&
    {'...'}
    }\n {false && (\n
    \n console.log('Relabelling...')}\n >\n \n \n \n Relabel\n \n console.log('Editing description...')}\n >\n \n \n \n Description\n \n
    \n )}\n
    \n \n );\n\n return (\n
    \n \n {isDisabled ? (\n \n
    Unsupported Region
    \n
    \n Contour type currently unsupported.\n
    \n \n }\n >\n
    {tableListItem}
    \n \n ) : (\n {tableListItem} \n )}\n
    \n
    \n );\n};\n\nStructureSetItem.propTypes = {\n index: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,\n label: PropTypes.string.isRequired,\n onClick: PropTypes.func,\n itemClass: PropTypes.string,\n color: PropTypes.array.isRequired,\n};\n\nStructureSetItem.defaultProps = {\n itemClass: '',\n onClick: () => {},\n};\n\nexport default StructureSetItem;\n","import React, { useState, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport { Range } from '@ohif/ui';\n\nimport './RTSettings.css';\n\nconst RTSettings = ({ configuration, onBack, onChange }) => {\n const toFloat = value => parseFloat(value / 100).toFixed(2);\n\n const save = (field, value) => {\n onChange({ ...configuration, [field]: value });\n };\n\n const SettingsSection = ({ title, children }) => {\n return (\n
    \n
    {title}
    \n
    \n {children}\n
    \n
    \n );\n };\n\n return (\n
    \n
    \n

    RT Structure Set Settings

    \n \n
    \n\n \n
    \n \n save('opacity', toFloat(event.target.value))}\n />\n
    \n
    \n \n save('lineWidth', parseInt(event.target.value))}\n />\n
    \n
    \n
    \n );\n};\n\nRTSettings.propTypes = {\n configuration: PropTypes.shape({\n lineWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,\n opacity: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,\n }).isRequired,\n onBack: PropTypes.func.isRequired,\n onChange: PropTypes.func.isRequired,\n};\n\nexport default RTSettings;\n","import React from 'react';\n\nconst LoadingIndicator = ({ height = \"200px\", width = \"200px\", expand = false }) => {\n return (\n
    \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
    \n );\n};\n\nexport default LoadingIndicator;\n","import React, { useState, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport { Icon } from '@ohif/ui';\n\nimport './PanelSection.css';\nimport LoadingIndicator from '../LoadingIndicator/LoadingIndicator';\n\nconst PanelSection = ({\n title,\n children,\n visible = false,\n expanded = false,\n loading = false,\n hideVisibleButton = false,\n onVisibilityChange = () => { },\n onExpandChange = () => { }\n}) => {\n const [isExpanded, setIsExpanded] = useState(expanded);\n const [isVisible, setIsVisible] = useState(visible);\n\n useEffect(() => {\n setIsVisible(visible);\n }, [visible]);\n\n return (\n \n
    \n
    {title}
    \n
    \n {!hideVisibleButton && (\n {\n const newVisibility = !isVisible;\n setIsVisible(newVisibility);\n onVisibilityChange(newVisibility);\n }}\n />\n )}\n {\n const newExpandValue = !isExpanded;\n setIsExpanded(newExpandValue);\n onExpandChange(newExpandValue);\n }}\n />\n
    \n
    \n {loading && isExpanded && }\n {children}\n \n );\n};\n\nPanelSection.propTypes = {\n title: PropTypes.string.isRequired,\n children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,\n visible: PropTypes.bool,\n expanded: PropTypes.bool,\n onVisibilityChange: PropTypes.func\n};\n\nPanelSection.defaultProps = {\n visible: false,\n expanded: false,\n onVisibilityChange: () => { }\n};\n\nexport default PanelSection;\n","import React, { useState, useEffect, useCallback } from 'react';\nimport PropTypes from 'prop-types';\nimport cornerstoneTools from 'cornerstone-tools';\nimport cornerstone from 'cornerstone-core';\n\nimport { ScrollableArea, TableList, Icon } from '@ohif/ui';\n\nimport { utils } from '@ohif/core';\n\nimport './RTPanel.css';\nimport StructureSetItem from '../StructureSetItem/StructureSetItem';\nimport RTPanelSettings from '../RTSettings/RTSettings';\nimport PanelSection from '../PanelSection/PanelSection';\nimport LoadingIndicator from '../LoadingIndicator/LoadingIndicator';\nimport TOOL_NAMES from '../../utils/toolNames';\n\nconst { RTSTRUCT_DISPLAY_TOOL } = TOOL_NAMES;\n\nconst { studyMetadataManager } = utils;\n\nconst refreshViewport = () => {\n cornerstone.getEnabledElements().forEach(enabledElement => {\n if (enabledElement.image) {\n cornerstone.updateImage(enabledElement.element);\n }\n });\n};\n\n/**\n * RTPanel component\n *\n * @param {Object} props\n * @param {Array} props.studies\n * @param {Array} props.getActiveViewport - get active viewport data\n * @param {number} props.activeIndex - activeViewportIndex\n * @param {number} props.isOpen - isOpen\n * @returns component\n */\nconst RTPanel = ({\n studies,\n activeIndex,\n isOpen,\n onContourItemClick,\n activeContexts = [],\n contexts = {},\n activeViewport,\n getActiveViewport,\n}) => {\n const isVTK = () => activeContexts.includes(contexts.VTK);\n const isCornerstone = () => activeContexts.includes(contexts.CORNERSTONE);\n\n const [selectedContour, setSelectedContour] = useState();\n const DEFAULT_SET_INDEX = 0;\n const DEFAULT_STATE = {\n referencedDisplaysets: [],\n sets: [],\n selectedSet: null,\n isLocked: false,\n };\n\n const [state, setState] = useState(DEFAULT_STATE);\n const [showSettings, setShowSettings] = useState(false);\n\n /*\n * TODO: Improve the way we notify parts of the app that depends on rts to be loaded.\n *\n * Currently we are using a non-ideal implementation through a custom event to notify the rtstruct panel\n * or other components that could rely on loaded rtstructs that\n * the first batch of structs were loaded so that e.g. when the user opens the panel\n * before the structs are fully loaded, the panel can subscribe to this custom event\n * and update itself with the new structs.\n *\n * This limitation is due to the fact that the rtmodule is an object (which will be\n * updated after the structs are loaded) that React its not aware of its changes\n * because the module object its not passed in to the panel component as prop but accessed externally.\n *\n * Improving this event approach to something reactive that can be tracked inside the react lifecycle,\n * allows us to easily watch the module or the rtstruct loading process in any other component\n * without subscribing to external events.\n */\n useEffect(() => {\n updateStructureSets();\n\n document.addEventListener('rt-panel-tab-updated', updateStructureSets);\n\n return () => {\n document.removeEventListener('rt-panel-tab-updated', updateStructureSets);\n };\n }, []);\n\n useEffect(() => {\n const studyMetadata = studyMetadataManager.get(\n activeViewport.StudyInstanceUID\n );\n const referencedDisplaysets = studyMetadata.getDerivedDatasets({\n referencedSeriesInstanceUID: activeViewport.SeriesInstanceUID,\n Modality: 'RTSTRUCT',\n });\n setState(state => ({ ...state, isLocked: !referencedDisplaysets.length }));\n }, [activeViewport]);\n\n const updateStructureSets = () => {\n const viewport = getActiveViewport();\n const module = cornerstoneTools.getModule('rtstruct');\n const StructureSets = module.state.StructureSets;\n\n if (StructureSets && StructureSets.length) {\n const viewportSets = module.getters.structuresSetsWhichReferenceSeriesInstanceUid(\n viewport.SeriesInstanceUID\n );\n\n const studyMetadata = studyMetadataManager.get(viewport.StudyInstanceUID);\n const referencedDisplaysets = studyMetadata.getDerivedDatasets({\n referencedSeriesInstanceUID: viewport.SeriesInstanceUID,\n Modality: 'RTSTRUCT',\n });\n\n if (viewportSets.length) {\n const defaultSet = viewportSets[DEFAULT_SET_INDEX];\n setState({\n referencedDisplaysets,\n selectedSet: defaultSet,\n sets: viewportSets,\n });\n } else {\n setState(DEFAULT_STATE);\n }\n }\n };\n\n useEffect(() => {\n setShowSettings(showSettings && !isOpen);\n }, [isOpen]);\n\n const toContourItem = (\n { ROINumber, ROIName, RTROIObservations, colorArray, visible, isSupported },\n loadedSet\n ) => {\n let interpretedType = '';\n if (RTROIObservations && RTROIObservations.RTROIInterpretedType) {\n interpretedType = `(${RTROIObservations.RTROIInterpretedType})`;\n }\n\n const isSameContour = selectedContour && selectedContour === ROINumber;\n return (\n {\n setSelectedContour(isSameContour ? null : ROINumber);\n\n if (isCornerstone()) {\n const enabledElements = cornerstone.getEnabledElements();\n const element = enabledElements[activeIndex].element;\n const stackToolState = cornerstoneTools.getToolState(\n element,\n 'stack'\n );\n\n if (!stackToolState) {\n return;\n }\n\n const imageIds = stackToolState.data[0].imageIds;\n\n const module = cornerstoneTools.getModule('rtstruct');\n const imageId = module.getters.imageIdOfCenterFrameOfROIContour(\n state.selectedSet.SeriesInstanceUID,\n ROINumber,\n imageIds\n );\n\n const toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.saveToolState();\n const imageIdSpecificToolState = toolState[imageId];\n\n const rtstructData =\n imageIdSpecificToolState[RTSTRUCT_DISPLAY_TOOL];\n\n const specificData = rtstructData.data.find(\n rtData => rtData.ROINumber === ROINumber\n );\n\n specificData.highlight = true;\n\n const frameIndex = imageIds.indexOf(imageId);\n const SOPInstanceUID = cornerstone.metaData.get(\n 'SOPInstanceUID',\n imageId\n );\n const StudyInstanceUID = cornerstone.metaData.get(\n 'StudyInstanceUID',\n imageId\n );\n\n onContourItemClick({\n StudyInstanceUID,\n SOPInstanceUID,\n frameIndex,\n activeViewportIndex: activeIndex,\n });\n }\n }}\n label={`${ROIName} ${interpretedType}`}\n index={ROINumber}\n color={colorArray}\n visible={visible}\n onVisibilityChange={() => {\n const module = cornerstoneTools.getModule('rtstruct');\n module.setters.toggleROIContour(\n state.selectedSet.SeriesInstanceUID,\n ROINumber\n );\n }}\n />\n );\n };\n\n const configurationChangeHandler = newConfiguration => {\n const module = cornerstoneTools.getModule('rtstruct');\n module.configuration.lineWidth = newConfiguration.lineWidth;\n module.configuration.opacity = newConfiguration.opacity;\n refreshViewport();\n };\n\n if (showSettings) {\n const module = cornerstoneTools.getModule('rtstruct');\n return (\n setShowSettings(false)}\n onChange={configurationChangeHandler}\n />\n );\n }\n\n return (\n
    \n
    \n {' '}\n {!state.isLocked && (\n setShowSettings(true)}\n />\n )}\n

    RT Structure Sets

    \n
    \n {!state.isLocked && !state.referencedDisplaysets.length && (\n \n )}\n {state.sets &&\n state.referencedDisplaysets.map(displaySet => {\n const { SeriesInstanceUID, metadata, isLoaded } = displaySet;\n\n const module = cornerstoneTools.getModule('rtstruct');\n const sets = module.getters.structuresSetsWhichReferenceSeriesInstanceUid(\n activeViewport.SeriesInstanceUID\n );\n\n const loadedSet = sets.find(\n set => set.SeriesInstanceUID === SeriesInstanceUID\n );\n\n if (!loadedSet) return null;\n\n return (\n {\n const module = cornerstoneTools.getModule('rtstruct');\n\n if (newVisibility) {\n module.setters.showStructureSet(loadedSet.SeriesInstanceUID);\n } else {\n module.setters.hideStructureSet(loadedSet.SeriesInstanceUID);\n }\n const sets = module.getters.structuresSetsWhichReferenceSeriesInstanceUid(\n activeViewport.SeriesInstanceUID\n );\n setState(state => ({ ...state, sets }));\n refreshViewport();\n }}\n onExpandChange={async () => {\n if (!isLoaded) {\n await displaySet.load(activeViewport, studies);\n const module = cornerstoneTools.getModule('rtstruct');\n const sets = module.getters.structuresSetsWhichReferenceSeriesInstanceUid(\n activeViewport.SeriesInstanceUID\n );\n const selectedSet = sets.find(\n set => set.SeriesInstanceUID === SeriesInstanceUID\n );\n setState(state => ({ ...state, selectedSet, sets }));\n }\n }}\n >\n \n \n {isLoaded &&\n loadedSet.ROIContours.map(c => toContourItem(c, loadedSet))}\n \n \n \n );\n })}\n
    \n );\n};\n\nRTPanel.propTypes = {\n viewports: PropTypes.shape({\n displaySetInstanceUID: PropTypes.string,\n frameRate: PropTypes.any,\n InstanceNumber: PropTypes.number,\n isMultiFrame: PropTypes.bool,\n isReconstructable: PropTypes.bool,\n Modality: PropTypes.string,\n plugin: PropTypes.string,\n SeriesDate: PropTypes.string,\n SeriesDescription: PropTypes.string,\n SeriesInstanceUID: PropTypes.string,\n SeriesNumber: PropTypes.any,\n SeriesTime: PropTypes.string,\n sopClassUIDs: PropTypes.arrayOf(PropTypes.string),\n StudyInstanceUID: PropTypes.string,\n }),\n activeIndex: PropTypes.number.isRequired,\n studies: PropTypes.array.isRequired,\n isOpen: PropTypes.bool.isRequired,\n};\n\nRTPanel.defaultProps = {};\n\nexport default RTPanel;\n","import React from 'react';\nimport { utils } from '@ohif/core';\n\nimport init from './init.js';\nimport sopClassHandlerModule from './OHIFDicomRTStructSopClassHandler';\nimport id from './id.js';\nimport RTPanel from './components/RTPanel/RTPanel';\nimport { version } from '../package.json';\n\nconst { studyMetadataManager } = utils;\n\nexport default {\n /**\n * Only required property. Should be a unique value across all extensions.\n */\n id,\n version,\n\n /**\n *\n *\n * @param {object} [configuration={}]\n * @param {object|array} [configuration.csToolsConfig] - Passed directly to `initCornerstoneTools`\n */\n preRegistration({ servicesManager, configuration = {} }) {\n init({ servicesManager, configuration });\n },\n getPanelModule({ commandsManager, servicesManager, api }) {\n const ExtendedRTPanel = props => {\n const { activeContexts } = api.hooks.useAppContext();\n\n const contourItemClickHandler = contourData => {\n commandsManager.runCommand('jumpToImage', contourData);\n };\n\n return (\n \n );\n };\n\n const RTPanelTabChangedEvent = 'rt-panel-tab-updated';\n\n /**\n * Trigger's an event to update the state of the panel's RoundedButtonGroup.\n *\n * This is required to avoid extension state\n * coupling with the viewer's ToolbarRow component.\n *\n * @param {object} data\n */\n const triggerRTPanelUpdatedEvent = data => {\n const event = new CustomEvent(RTPanelTabChangedEvent, {\n detail: data,\n });\n document.dispatchEvent(event);\n };\n\n const onRTStructsLoaded = ({ detail }) => {\n const { rtStructDisplaySet, referencedDisplaySet } = detail;\n\n const studyMetadata = studyMetadataManager.get(\n rtStructDisplaySet.StudyInstanceUID\n );\n const referencedDisplaysets = studyMetadata.getDerivedDatasets({\n referencedSeriesInstanceUID: referencedDisplaySet.SeriesInstanceUID,\n Modality: 'RTSTRUCT',\n });\n triggerRTPanelUpdatedEvent({\n badgeNumber: referencedDisplaysets.length,\n target: 'rt-panel',\n });\n };\n\n document.addEventListener('extensiondicomrtrtloaded', onRTStructsLoaded);\n\n return {\n menuOptions: [\n {\n icon: 'list',\n label: 'RTSTRUCT',\n target: 'rt-panel',\n stateEvent: RTPanelTabChangedEvent,\n isDisabled: (studies, activeViewport) => {\n if (!studies) {\n return true;\n }\n\n if (activeViewport) {\n const studyMetadata = studyMetadataManager.get(\n activeViewport.StudyInstanceUID\n );\n if (!studyMetadata) {\n return;\n }\n const referencedDisplaySets = studyMetadata.getDerivedDatasets({\n referencedSeriesInstanceUID: activeViewport.SeriesInstanceUID,\n Modality: 'RTSTRUCT',\n });\n if (\n referencedDisplaySets &&\n referencedDisplaySets.some(ds =>\n ['RTSTRUCT'].includes(ds.Modality)\n )\n ) {\n triggerRTPanelUpdatedEvent({\n badgeNumber: referencedDisplaySets.length,\n target: 'rt-panel',\n });\n return false;\n }\n }\n\n return true;\n },\n },\n ],\n components: [\n {\n id: 'rt-panel',\n component: ExtendedRTPanel,\n },\n ],\n defaultContext: ['VIEWER'],\n };\n },\n getSopClassHandlerModule({ servicesManager }) {\n return sopClassHandlerModule;\n },\n};\n","const id = 'rt';\n\nexport default id;\n","import OHIF from '@ohif/core';\n\nconst { utils } = OHIF;\n\nconst SOP_CLASS_UIDS = {\n VL_WHOLE_SLIDE_MICROSCOPY_IMAGE_STORAGE: '1.2.840.10008.5.1.4.1.1.77.1.6',\n};\n\nconst DicomMicroscopySopClassHandler = {\n id: 'DicomMicroscopySopClassHandlerPlugin',\n sopClassUIDs: [SOP_CLASS_UIDS.VL_WHOLE_SLIDE_MICROSCOPY_IMAGE_STORAGE],\n getDisplaySetFromSeries(series, study, dicomWebClient) {\n const instance = series.getFirstInstance();\n\n const metadata = instance.getData().metadata;\n const {\n SeriesDescription,\n SeriesNumber,\n ContentDate,\n ContentTime,\n } = metadata;\n\n // Note: We are passing the dicomweb client into each viewport!\n\n return {\n plugin: 'microscopy',\n Modality: 'SM',\n displaySetInstanceUID: utils.guid(),\n dicomWebClient,\n SOPInstanceUID: instance.getSOPInstanceUID(),\n SeriesInstanceUID: series.getSeriesInstanceUID(),\n StudyInstanceUID: study.getStudyInstanceUID(),\n SeriesDescription,\n SeriesDate: ContentDate, // Map ContentDate/Time to SeriesTime for series list sorting.\n SeriesTime: ContentTime,\n SeriesNumber,\n metadata,\n };\n },\n};\n\nexport default DicomMicroscopySopClassHandler;\n","import React from 'react';\nimport DicomMicroscopySopClassHandler from './DicomMicroscopySopClassHandler.js';\nimport { version } from '../package.json';\n\nconst Component = React.lazy(() => {\n return import('./DicomMicroscopyViewport');\n});\n\nexport default {\n /**\n * Only required property. Should be a unique value across all extensions.\n */\n id: 'microscopy',\n version,\n\n getViewportModule({ servicesManager }) {\n return props => {\n return (\n Loading...}>\n \n \n );\n };\n },\n getSopClassHandlerModule() {\n return DicomMicroscopySopClassHandler;\n },\n};\n","import { MODULE_TYPES, utils } from '@ohif/core';\n\n// TODO: Should probably use dcmjs for this\nconst SOP_CLASS_UIDS = {\n ENCAPSULATED_PDF: '1.2.840.10008.5.1.4.1.1.104.1',\n};\n\nconst OHIFDicomPDFSopClassHandler = {\n id: 'OHIFDicomPDFSopClassHandlerPlugin',\n type: MODULE_TYPES.SOP_CLASS_HANDLER,\n sopClassUIDs: [SOP_CLASS_UIDS.ENCAPSULATED_PDF],\n getDisplaySetFromSeries(series, study, dicomWebClient, authorizationHeaders) {\n const instance = series.getFirstInstance();\n\n const metadata = instance.getData().metadata;\n const {\n ContentDate,\n ContentTime,\n SeriesDescription,\n SeriesNumber,\n } = metadata;\n\n return {\n plugin: 'pdf',\n Modality: 'DOC',\n displaySetInstanceUID: utils.guid(),\n wadoRoot: study.getData().wadoRoot,\n wadoUri: instance.getData().wadouri,\n SOPInstanceUID: instance.getSOPInstanceUID(),\n SeriesInstanceUID: series.getSeriesInstanceUID(),\n StudyInstanceUID: study.getStudyInstanceUID(),\n SeriesDescription,\n SeriesDate: ContentDate, // Map ContentDate/Time to SeriesTime for series list sorting.\n SeriesTime: ContentTime,\n SeriesNumber,\n metadata,\n authorizationHeaders: authorizationHeaders,\n };\n },\n};\n\nexport default OHIFDicomPDFSopClassHandler;\n","import React from 'react';\nimport OHIFDicomPDFSopClassHandler from './OHIFDicomPDFSopClassHandler.js';\nimport { version } from '../package.json';\n\nconst Component = React.lazy(() => {\n return import('./ConnectedOHIFDicomPDFViewer');\n});\n\nconst ConnectedOHIFDicomPDFViewer = props => {\n return (\n Loading...}>\n \n \n );\n};\n\nexport default {\n /**\n * Only required property. Should be a unique value across all extensions.\n */\n id: 'pdf',\n version,\n getViewportModule() {\n return ConnectedOHIFDicomPDFViewer;\n },\n getSopClassHandlerModule() {\n return OHIFDicomPDFSopClassHandler;\n },\n};\n","/**\n * Entry point for development and production PWA builds.\n * Packaged (NPM) builds go through `index-umd.js`\n */\n\nimport 'regenerator-runtime/runtime';\n\nimport App from './App.js';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\n// test\n\n/**\n * EXTENSIONS\n * =================\n *\n * Importing and modifying the extensions our app uses HERE allows us to leverage\n * tree shaking and a few other niceties. However, by including them here they become\n * \"baked in\" to the published application.\n *\n * Depending on your use case/needs, you may want to consider not adding any extensions\n * by default HERE, and instead provide them via the extensions configuration key or\n * by using the exported `App` component, and passing in your extensions as props using\n * the defaultExtensions property.\n */\nimport OHIFVTKExtension from '@ohif/extension-vtk';\nimport OHIFDicomHtmlExtension from '@ohif/extension-dicom-html';\nimport OHIFDicomSegmentationExtension from '@ohif/extension-dicom-segmentation';\nimport OHIFDicomRtExtension from '@ohif/extension-dicom-rt';\nimport OHIFDicomMicroscopyExtension from '@ohif/extension-dicom-microscopy';\nimport OHIFDicomPDFExtension from '@ohif/extension-dicom-pdf';\n//import OHIFDicomTagBrowserExtension from '@ohif/extension-dicom-tag-browser';\n// Add this for Debugging purposes:\n//import OHIFDebuggingExtension from '@ohif/extension-debugging';\nimport { version } from '../package.json';\n\n/*\n * Default Settings\n */\nlet config = {};\n\nif (window) {\n config = window.config || {};\n window.version = version;\n}\n\nconst appProps = {\n config,\n defaultExtensions: [\n OHIFVTKExtension,\n OHIFDicomHtmlExtension,\n OHIFDicomMicroscopyExtension,\n OHIFDicomPDFExtension,\n OHIFDicomSegmentationExtension,\n OHIFDicomRtExtension,\n //OHIFDebuggingExtension,\n //OHIFDicomTagBrowserExtension,\n ],\n};\n\n/** Create App */\nconst app = React.createElement(App, appProps, null);\n\n/** Render */\nReactDOM.render(app, document.getElementById('root'));\n","import MODULE_TYPES from './MODULE_TYPES.js';\nimport log from './../log.js';\n\nexport default class ExtensionManager {\n constructor({ commandsManager, servicesManager, api, appConfig = {} }) {\n this.modules = {};\n this.registeredExtensionIds = [];\n this.registeredExtensionVesions = {};\n this.moduleTypeNames = Object.values(MODULE_TYPES);\n //\n this._commandsManager = commandsManager;\n this._servicesManager = servicesManager;\n this._appConfig = appConfig;\n this._api = api;\n\n this.moduleTypeNames.forEach(moduleType => {\n this.modules[moduleType] = [];\n });\n }\n\n /**\n * An array of extensions, or an array of arrays that contains extension\n * configuration pairs.\n *\n * @param {Object[]} extensions - Array of extensions\n */\n registerExtensions(extensions) {\n extensions.forEach(extension => {\n const hasConfiguration = Array.isArray(extension);\n\n if (hasConfiguration) {\n const [ohifExtension, configuration] = extension;\n this.registerExtension(ohifExtension, configuration);\n } else {\n this.registerExtension(extension);\n }\n });\n }\n\n /**\n *\n * TODO: Id Management: SopClassHandlers currently refer to viewport module by id; setting the extension id as viewport module id is a workaround for now\n * @param {Object} extension\n * @param {Object} configuration\n */\n registerExtension(extension, configuration = {}) {\n if (!extension) {\n log.warn(\n 'Attempting to register a null/undefined extension. Exiting early.'\n );\n return;\n }\n\n let extensionId = extension.id;\n const version = extension.version;\n\n if (!extensionId) {\n extensionId = Math.random()\n .toString(36)\n .substr(2, 5);\n\n log.warn(`Extension ID not set. Using random string ID: ${extensionId}`);\n }\n\n if (this.registeredExtensionIds.includes(extensionId)) {\n log.warn(\n `Extension ID ${extensionId} has already been registered. Exiting before duplicating modules.`\n );\n return;\n }\n\n // preRegistrationHook\n if (extension.preRegistration) {\n extension.preRegistration({\n servicesManager: this._servicesManager,\n commandsManager: this._commandsManager,\n appConfig: this._appConfig,\n configuration,\n });\n }\n\n // Register Modules\n this.moduleTypeNames.forEach(moduleType => {\n const extensionModule = this._getExtensionModule(\n moduleType,\n extension,\n extensionId,\n configuration\n );\n\n if (extensionModule) {\n this._initSpecialModuleTypes(moduleType, extensionModule);\n\n this.modules[moduleType].push({\n extensionId,\n module: extensionModule,\n });\n }\n });\n\n // Track extension registration\n this.registeredExtensionIds.push(extensionId);\n\n this.registeredExtensionVesions[extensionId] = version;\n }\n\n /**\n * @private\n * @param {string} moduleType\n * @param {Object} extension\n * @param {string} extensionId - Used for logging warnings\n */\n _getExtensionModule(moduleType, extension, extensionId, configuration) {\n const getModuleFnName = 'get' + _capitalizeFirstCharacter(moduleType);\n const getModuleFn = extension[getModuleFnName];\n\n if (!getModuleFn) {\n return;\n }\n\n try {\n const extensionModule = getModuleFn({\n servicesManager: this._servicesManager,\n commandsManager: this._commandsManager,\n appConfig: this._appConfig,\n configuration,\n api: this._api,\n extensionManager: this,\n });\n\n if (!extensionModule) {\n log.warn(\n `Null or undefined returned when registering the ${getModuleFnName} module for the ${extensionId} extension`\n );\n }\n\n return extensionModule;\n } catch (ex) {\n log.error(\n `Exception thrown while trying to call ${getModuleFnName} for the ${extensionId} extension`\n );\n }\n }\n\n _initSpecialModuleTypes(moduleType, extensionModule) {\n switch (moduleType) {\n case 'commandsModule': {\n const { definitions, defaultContext } = extensionModule;\n if (!definitions || Object.keys(definitions).length === 0) {\n log.warn('Commands Module contains no command definitions');\n return;\n }\n this._initCommandsModule(definitions, defaultContext);\n break;\n }\n default:\n // code block\n }\n }\n\n /**\n *\n * @private\n * @param {Object[]} commandDefinitions\n */\n _initCommandsModule(commandDefinitions, defaultContext = 'VIEWER') {\n if (!this._commandsManager.getContext(defaultContext)) {\n this._commandsManager.createContext(defaultContext);\n }\n\n Object.keys(commandDefinitions).forEach(commandName => {\n const commandDefinition = commandDefinitions[commandName];\n const commandHasContextThatDoesNotExist =\n commandDefinition.context &&\n !this._commandsManager.getContext(commandDefinition.context);\n\n if (commandHasContextThatDoesNotExist) {\n this._commandsManager.createContext(commandDefinition.context);\n }\n\n this._commandsManager.registerCommand(\n commandDefinition.context || defaultContext,\n commandName,\n commandDefinition\n );\n });\n }\n}\n\n/**\n * @private\n * @param {string} lower\n */\nfunction _capitalizeFirstCharacter(lower) {\n return lower.charAt(0).toUpperCase() + lower.substr(1);\n}\n","import log from './../log.js';\n\nexport default class ServicesManager {\n constructor() {\n this.services = {};\n this.registeredServiceNames = [];\n }\n\n /**\n * Registers a new service.\n *\n * @param {Object} service\n * @param {Object} configuration\n */\n registerService(service, configuration = {}) {\n if (!service) {\n log.warn(\n 'Attempting to register a null/undefined service. Exiting early.'\n );\n return;\n }\n\n if (!service.name) {\n log.warn(`Service name not set. Exiting early.`);\n return;\n }\n\n if (this.registeredServiceNames.includes(service.name)) {\n log.warn(\n `Service name ${service.name} has already been registered. Exiting before duplicating services.`\n );\n return;\n }\n\n if (service.create) {\n this.services[service.name] = service.create({\n configuration,\n });\n } else {\n log.warn(`Service create factory function not defined. Exiting early.`);\n return;\n }\n\n /* Track service registration */\n this.registeredServiceNames.push(service.name);\n }\n\n /**\n * An array of services, or an array of arrays that contains service\n * configuration pairs.\n *\n * @param {Object[]} services - Array of services\n */\n registerServices(services) {\n services.forEach(service => {\n const hasConfiguration = Array.isArray(service);\n\n if (hasConfiguration) {\n const [ohifService, configuration] = service;\n this.registerService(ohifService, configuration);\n } else {\n this.registerService(service);\n }\n });\n }\n}\n","/**\n * A UI Notification\n *\n * @typedef {Object} Notification\n * @property {string} title -\n * @property {string} message -\n * @property {number} [duration=5000] - in ms\n * @property {string} [position=\"bottomRight\"] -\"topLeft\" | \"topCenter | \"topRight\" | \"bottomLeft\" | \"bottomCenter\" | \"bottomRight\"\n * @property {string} [type=\"info\"] - \"info\" | \"error\" | \"warning\" | \"success\"\n * @property {boolean} [autoClose=true]\n * @property {object} [action=null]\n */\n\nconst name = 'UINotificationService';\n\nconst serviceShowRequestQueue = [];\n\nconst publicAPI = {\n name,\n hide: _hide,\n show: _show,\n setServiceImplementation,\n};\n\nconst serviceImplementation = {\n _hide: () => console.warn('hide() NOT IMPLEMENTED'),\n _show: showArguments => {\n serviceShowRequestQueue.push(showArguments);\n\n console.warn('show() NOT IMPLEMENTED');\n },\n};\n\n/**\n * Create and show a new UI notification; returns the\n * ID of the created notification.\n *\n * @param {Notification} notification { title, message, duration, position, type, autoClose, action}\n * @returns {number} id\n */\nfunction _show({\n title,\n message,\n duration = 5000,\n position = 'bottomRight',\n type = 'info',\n autoClose = true,\n action = null,\n}) {\n return serviceImplementation._show({\n title,\n message,\n duration,\n position,\n type,\n autoClose,\n action,\n });\n}\n\n/**\n * Hides/dismisses the notification, if currently shown\n *\n * @param {number} id - id of the notification to hide/dismiss\n * @returns undefined\n */\nfunction _hide(id) {\n return serviceImplementation._hide({ id });\n}\n\n/**\n *\n *\n * @param {*} {\n * hide: hideImplementation,\n * show: showImplementation,\n * }\n */\nfunction setServiceImplementation({\n hide: hideImplementation,\n show: showImplementation,\n}) {\n if (hideImplementation) {\n serviceImplementation._hide = hideImplementation;\n }\n if (showImplementation) {\n serviceImplementation._show = showImplementation;\n\n while (serviceShowRequestQueue.length > 0) {\n const showArguments = serviceShowRequestQueue.pop();\n serviceImplementation._show(showArguments);\n }\n }\n}\n\nexport default {\n name,\n create: ({ configuration = {} }) => {\n return publicAPI;\n },\n};\n","/**\n * UI Modal\n *\n * @typedef {Object} ModalProps\n * @property {ReactElement|HTMLElement} [content=null] Modal content.\n * @property {Object} [contentProps=null] Modal content props.\n * @property {boolean} [shouldCloseOnEsc=false] Modal is dismissible via the esc key.\n * @property {boolean} [isOpen=true] Make the Modal visible or hidden.\n * @property {boolean} [closeButton=true] Should the modal body render the close button.\n * @property {string} [title=null] Should the modal render the title independently of the body content.\n * @property {string} [customClassName=null] The custom class to style the modal.\n * @property {boolean} [showScrollbar=false] Show or hide scrollbar.\n * @property {boolean} [noScroll=false] Disable or not the scrollbar.\n */\n\nconst name = 'UIModalService';\n\nconst publicAPI = {\n name,\n hide: _hide,\n show: _show,\n setServiceImplementation,\n};\n\nconst serviceImplementation = {\n _hide: () => console.warn('hide() NOT IMPLEMENTED'),\n _show: () => console.warn('show() NOT IMPLEMENTED'),\n};\n\n/**\n * Show a new UI modal;\n *\n * @param {ModalProps} props { content, contentProps, shouldCloseOnEsc, isOpen, onClose, closeButton, title, customClassName, showScrollbar, noScroll }\n */\nfunction _show({\n content = null,\n contentProps = null,\n shouldCloseOnEsc = false,\n isOpen = true,\n onClose = null,\n closeButton = true,\n title = null,\n fullscreen = false,\n customClassName = null,\n showScrollbar = false,\n noScroll = false,\n}) {\n return serviceImplementation._show({\n content,\n contentProps,\n shouldCloseOnEsc,\n isOpen,\n onClose,\n closeButton,\n title,\n fullscreen,\n customClassName,\n showScrollbar,\n noScroll,\n });\n}\n\n/**\n * Hides/dismisses the modal, if currently shown\n *\n * @returns void\n */\nfunction _hide() {\n return serviceImplementation._hide();\n}\n\n/**\n *\n *\n * @param {*} {\n * hide: hideImplementation,\n * show: showImplementation,\n * }\n */\nfunction setServiceImplementation({\n hide: hideImplementation,\n show: showImplementation,\n}) {\n if (hideImplementation) {\n serviceImplementation._hide = hideImplementation;\n }\n if (showImplementation) {\n serviceImplementation._show = showImplementation;\n }\n}\n\nexport default {\n name,\n create: ({ configuration = {} }) => {\n return publicAPI;\n },\n};\n","/**\n * A UI Element Position\n *\n * @typedef {Object} ElementPosition\n * @property {number} top -\n * @property {number} left -\n * @property {number} right -\n * @property {number} bottom -\n */\n\n/**\n * UI Dialog\n *\n * @typedef {Object} DialogProps\n * @property {string} id The dialog id.\n * @property {ReactElement|HTMLElement} content The dialog content.\n * @property {Object} contentProps The dialog content props.\n * @property {boolean} [isDraggable=true] Controls if dialog content is draggable or not.\n * @property {boolean} [showOverlay=false] Controls dialog overlay.\n * @property {boolean} [centralize=false] Center the dialog on the screen.\n * @property {boolean} [preservePosition=true] Use last position instead of default.\n * @property {ElementPosition} defaultPosition Specifies the `x` and `y` that the dragged item should start at.\n * @property {Function} onStart Called when dragging starts. If `false` is returned any handler, the action will cancel.\n * @property {Function} onStop Called when dragging stops.\n * @property {Function} onDrag Called while dragging.\n */\n\nconst name = 'UIDialogService';\n\nconst publicAPI = {\n name,\n dismiss: _dismiss,\n dismissAll: _dismissAll,\n create: _create,\n setServiceImplementation,\n};\n\nconst serviceImplementation = {\n _dismiss: () => console.warn('dismiss() NOT IMPLEMENTED'),\n _dismissAll: () => console.warn('dismissAll() NOT IMPLEMENTED'),\n _create: () => console.warn('create() NOT IMPLEMENTED'),\n};\n\n/**\n * Show a new UI dialog;\n *\n * @param {DialogProps} props { id, content, contentProps, onStart, onDrag, onStop, centralize, isDraggable, showOverlay, preservePosition, defaultPosition }\n */\nfunction _create({\n id,\n content,\n contentProps,\n onStart,\n onDrag,\n onStop,\n centralize = false,\n preservePosition = true,\n isDraggable = true,\n showOverlay = false,\n defaultPosition,\n}) {\n return serviceImplementation._create({\n id,\n content,\n contentProps,\n onStart,\n onDrag,\n onStop,\n centralize,\n preservePosition,\n isDraggable,\n showOverlay,\n defaultPosition,\n });\n}\n\n/**\n * Destroys all dialogs, if any\n *\n * @returns void\n */\nfunction _dismissAll() {\n return serviceImplementation._dismissAll();\n}\n\n/**\n * Destroy the dialog, if currently created\n *\n * @returns void\n */\nfunction _dismiss({ id }) {\n return serviceImplementation._dismiss({ id });\n}\n\n/**\n *\n *\n * @param {*} {\n * dismiss: dismissImplementation,\n * dismissAll: dismissAllImplementation,\n * create: createImplementation,\n * }\n */\nfunction setServiceImplementation({\n dismiss: dismissImplementation,\n dismissAll: dismissAllImplementation,\n create: createImplementation,\n}) {\n if (dismissImplementation) {\n serviceImplementation._dismiss = dismissImplementation;\n }\n if (dismissAllImplementation) {\n serviceImplementation._dismissAll = dismissAllImplementation;\n }\n if (createImplementation) {\n serviceImplementation._create = createImplementation;\n }\n}\n\nexport default {\n name,\n create: ({ configuration = {} }) => {\n return publicAPI;\n },\n};\n","const name = 'LoggerService';\n\nconst publicAPI = {\n name,\n info: _info,\n error: _error,\n setServiceImplementation,\n};\n\nconst serviceImplementation = {\n _info: () => console.warn('info() NOT IMPLEMENTED'),\n _error: () => console.warn('error() NOT IMPLEMENTED'),\n};\n\n/**\n * Logs an info\n *\n * @param {object} props { message, displayOnConsole }\n */\nfunction _info({ message, displayOnConsole }) {\n return serviceImplementation._info({\n message,\n displayOnConsole,\n });\n}\n\n/**\n * Logs an error\n *\n * @param {object} props { error, stack, message, displayOnConsole }\n * @returns void\n */\nfunction _error({ error, stack, message, displayOnConsole }) {\n return serviceImplementation._error({\n error,\n stack,\n message,\n displayOnConsole,\n });\n}\n\n/**\n *\n *\n * @param {*} {\n * info: infoImplementation,\n * error: errorImplementation,\n * }\n */\nfunction setServiceImplementation({\n info: infoImplementation,\n error: errorImplementation,\n}) {\n if (infoImplementation) {\n serviceImplementation._info = infoImplementation;\n }\n if (errorImplementation) {\n serviceImplementation._error = errorImplementation;\n }\n}\n\nexport default {\n name,\n create: ({ configuration = {} }) => {\n return publicAPI;\n },\n};\n","import guid from '../../utils/guid';\n\n/**\n * Consumer must implement:\n * this.listeners = {}\n * this.EVENTS = { \"EVENT_KEY\": \"EVENT_VALUE\" }\n */\nexport default {\n subscribe,\n publish,\n _unsubscribe,\n _isValidEvent,\n};\n\n/**\n * Subscribe to updates.\n *\n * @param {string} eventName The name of the event\n * @param {Function} callback Events callback\n * @return {Object} Observable object with actions\n */\nfunction subscribe(eventName, callback) {\n if (this._isValidEvent(eventName)) {\n const listenerId = guid();\n const subscription = { id: listenerId, callback };\n\n console.info(`Subscribing to '${eventName}'.`);\n if (Array.isArray(this.listeners[eventName])) {\n this.listeners[eventName].push(subscription);\n } else {\n this.listeners[eventName] = [subscription];\n }\n\n return {\n unsubscribe: () => this._unsubscribe(eventName, listenerId),\n };\n } else {\n throw new Error(`Event ${eventName} not supported.`);\n }\n}\n\n/**\n * Unsubscribe to measurement updates.\n *\n * @param {string} eventName The name of the event\n * @param {string} listenerId The listeners id\n * @return void\n */\nfunction _unsubscribe(eventName, listenerId) {\n if (!this.listeners[eventName]) {\n return;\n }\n\n const listeners = this.listeners[eventName];\n if (Array.isArray(listeners)) {\n this.listeners[eventName] = listeners.filter(({ id }) => id !== listenerId);\n } else {\n this.listeners[eventName] = undefined;\n }\n}\n\n/**\n * Check if a given event is valid.\n *\n * @param {string} eventName The name of the event\n * @return {boolean} Event name validation\n */\nfunction _isValidEvent(eventName) {\n return Object.values(this.EVENTS).includes(eventName);\n}\n\n/**\n * Broadcasts changes.\n *\n * @param {string} eventName - The event name\n * @param {func} callbackProps - Properties to pass callback\n * @return void\n */\nfunction publish(eventName, callbackProps) {\n const hasListeners = Object.keys(this.listeners).length > 0;\n const hasCallbacks = Array.isArray(this.listeners[eventName]);\n\n if (hasListeners && hasCallbacks) {\n this.listeners[eventName].forEach(listener => {\n listener.callback(callbackProps);\n });\n }\n}\n","/** Internal imports */\nimport log from '../../log';\nimport guid from '../../utils/guid';\nimport pubSubServiceInterface from '../_shared/pubSubServiceInterface';\n\n/**\n * Measurement source schema\n *\n * @typedef {Object} MeasurementSource\n * @property {number} id -\n * @property {string} name -\n * @property {string} version -\n */\n\n/**\n * Measurement schema\n *\n * @typedef {Object} Measurement\n * @property {number} id -\n * @property {string} SOPInstanceUID -\n * @property {string} FrameOfReferenceUID -\n * @property {string} referenceSeriesUID -\n * @property {string} label -\n * @property {string} description -\n * @property {string} type -\n * @property {string} unit -\n * @property {number} area -\n * @property {Array} points -\n * @property {MeasurementSource} source -\n */\n\n/* Measurement schema keys for object validation. */\nconst MEASUREMENT_SCHEMA_KEYS = [\n 'id',\n 'SOPInstanceUID',\n 'FrameOfReferenceUID',\n 'referenceStudyUID',\n 'referenceSeriesUID',\n 'label',\n 'description',\n 'type',\n 'unit',\n 'area', // TODO: Add concept names instead (descriptor)\n 'mean',\n 'stdDev',\n 'length',\n 'shortestDiameter',\n 'longestDiameter',\n 'text', // NOTE: There is nothing like this in SR.\n 'points',\n 'source',\n];\n\nconst EVENTS = {\n MEASUREMENT_UPDATED: 'event::measurement_updated',\n INTERNAL_MEASUREMENT_UPDATED: 'event:internal_measurement_updated',\n MEASUREMENT_ADDED: 'event::measurement_added',\n RAW_MEASUREMENT_ADDED: 'event::raw_measurement_added',\n MEASUREMENT_REMOVED: 'event::measurement_removed',\n MEASUREMENTS_CLEARED: 'event::measurements_cleared',\n JUMP_TO_MEASUREMENT: 'event:jump_to_measurement',\n};\n\nconst VALUE_TYPES = {\n POLYLINE: 'value_type::polyline',\n POINT: 'value_type::point',\n BIDIRECTIONAL: 'value_type::shortAxisLongAxis', // TODO -> Discuss with Danny. => just using SCOORD values isn't enough here.\n ELLIPSE: 'value_type::ellipse',\n MULTIPOINT: 'value_type::multipoint',\n CIRCLE: 'value_type::circle',\n};\n\nclass MeasurementService {\n constructor() {\n this.sources = {};\n this.mappings = {};\n this.measurements = {};\n this.listeners = {};\n this._jumpToMeasurementCache = {};\n Object.defineProperty(this, 'EVENTS', {\n value: EVENTS,\n writable: false,\n enumerable: true,\n configurable: false,\n });\n Object.defineProperty(this, 'VALUE_TYPES', {\n value: VALUE_TYPES,\n writable: false,\n enumerable: true,\n configurable: false,\n });\n\n Object.assign(this, pubSubServiceInterface);\n }\n\n /**\n * Get all measurements.\n *\n * @return {Measurement[]} Array of measurements\n */\n getMeasurements() {\n const measurements = this._arrayOfObjects(this.measurements);\n return (\n measurements &&\n measurements.map(m => this.measurements[Object.keys(m)[0]])\n );\n }\n\n /**\n * Get specific measurement by its id.\n *\n * @param {string} id Id of the measurement\n * @return {Measurement} Measurement instance\n */\n getMeasurement(id) {\n let measurement = null;\n const measurements = this.measurements[id];\n\n if (measurements && Object.keys(measurements).length > 0) {\n measurement = this.measurements[id];\n }\n\n return measurement;\n }\n\n /**\n * Create a new source.\n *\n * @param {string} name Name of the source\n * @param {string} version Source name\n * @return {MeasurementSource} Measurement source instance\n */\n createSource(name, version) {\n if (!name) {\n throw new Error('Source name not provided.');\n }\n\n if (!version) {\n throw new Error('Source version not provided.');\n }\n\n const id = guid();\n const source = {\n id,\n name,\n version,\n };\n source.addOrUpdate = (definition, measurement) => {\n return this.addOrUpdate(source, definition, measurement);\n };\n source.remove = id => {\n return this.remove(id, source);\n };\n source.getAnnotation = (definition, measurementId) => {\n return this.getAnnotation(source, definition, measurementId);\n };\n\n log.info(`New '${name}@${version}' source added.`);\n this.sources[id] = source;\n\n return source;\n }\n\n getSource(name, version) {\n const { sources } = this;\n const id = this._getSourceId(name, version);\n\n return sources[id];\n }\n\n getSourceMappings(name, version) {\n const { mappings } = this;\n const id = this._getSourceId(name, version);\n\n return mappings[id];\n }\n\n _getSourceId(name, version) {\n const { sources } = this;\n\n const sourceId = Object.keys(sources).find(sourceId => {\n const source = sources[sourceId];\n\n return source.name === name && source.version === version;\n });\n\n return sourceId;\n }\n\n /**\n * Add a new measurement matching criteria along with mapping functions.\n *\n * @param {MeasurementSource} source Measurement source instance\n * @param {string} definition Definition of the measurement (Annotation Type)\n * @param {MatchingCriteria} matchingCriteria The matching criteria\n * @param {Function} toSourceSchema Mapping function to source schema\n * @param {Function} toMeasurementSchema Mapping function to measurement schema\n * @return void\n */\n addMapping(\n source,\n definition,\n matchingCriteria,\n toSourceSchema,\n toMeasurementSchema\n ) {\n if (!this._isValidSource(source)) {\n throw new Error('Invalid source.');\n }\n\n if (!matchingCriteria) {\n throw new Error('Matching criteria not provided.');\n }\n\n if (!definition) {\n throw new Error('Definition not provided.');\n }\n\n if (!toSourceSchema) {\n throw new Error('Mapping function to source schema not provided.');\n }\n\n if (!toMeasurementSchema) {\n throw new Error('Measurement mapping function not provided.');\n }\n\n const mapping = {\n matchingCriteria,\n definition,\n toSourceSchema,\n toMeasurementSchema,\n };\n\n if (Array.isArray(this.mappings[source.id])) {\n this.mappings[source.id].push(mapping);\n } else {\n this.mappings[source.id] = [mapping];\n }\n\n log.info(\n `New measurement mapping added to source '${this._getSourceInfo(\n source\n )}'.`\n );\n }\n\n /**\n * Get annotation for specific source.\n *\n * @param {MeasurementSource} source Measurement source instance\n * @param {string} definition The source definition\n * @param {string} measurementId The measurement service measurement id\n * @return {Object} Source measurement schema\n */\n getAnnotation(source, definition, measurementId) {\n if (!this._isValidSource(source)) {\n log.warn('Invalid source. Exiting early.');\n return;\n }\n\n if (!definition) {\n log.warn('No source definition provided. Exiting early.');\n return;\n }\n\n const mapping = this._getMappingByMeasurementSource(\n measurementId,\n definition\n );\n const measurement = this.getMeasurement(measurementId);\n if (mapping) return mapping.toSourceSchema(measurement, definition);\n\n const matchingMapping = this._getMatchingMapping(\n source,\n definition,\n measurement\n );\n\n if (matchingMapping) {\n log.info('Matching mapping found:', matchingMapping);\n const { toSourceSchema, definition } = matchingMapping;\n return toSourceSchema(measurement, definition);\n }\n }\n\n update(id, measurement, notYetUpdatedAtSource = false) {\n if (this.measurements[id]) {\n const updatedMeasurement = {\n ...measurement,\n modifiedTimestamp: Math.floor(Date.now() / 1000),\n };\n\n log.info(\n `Updating internal measurement representation...`,\n updatedMeasurement\n );\n\n this.measurements[id] = updatedMeasurement;\n\n this.publish(\n // Add an internal flag to say the measurement has not yet been updated at source.\n this.EVENTS.MEASUREMENT_UPDATED,\n {\n source: measurement.source,\n measurement: updatedMeasurement,\n notYetUpdatedAtSource,\n }\n );\n\n return updatedMeasurement.id;\n }\n }\n\n /**\n * Add a raw measurement into a source so that it may be\n * Converted to/from annotation in the same way. E.g. import serialized data\n * Of the same form as the measurement source.\n * @param {MeasurementSource} source The measurement source instance.\n * @param {string} definition The source definition you want to add the measurement to.\n * @param {object} data The data you wish to add to the source.\n * @param {function} toMeasurementSchema A function to get the `data` into the same shape as the source definition.\n */\n addRawMeasurement(\n source,\n definition,\n data,\n toMeasurementSchema,\n dataSource = {}\n ) {\n if (!this._isValidSource(source)) {\n log.warn('Invalid source. Exiting early.');\n return;\n }\n\n const sourceInfo = this._getSourceInfo(source);\n\n if (!definition) {\n log.warn('No source definition provided. Exiting early.');\n return;\n }\n\n if (!this._sourceHasMappings(source)) {\n log.warn(\n `No measurement mappings found for '${sourceInfo}' source. Exiting early.`\n );\n return;\n }\n\n let measurement = {};\n try {\n /* Convert measurement */\n measurement = toMeasurementSchema(data);\n /* Assign measurement source instance */\n measurement.source = source;\n } catch (error) {\n log.warn(\n `Failed to map '${sourceInfo}' measurement for definition ${definition}:`,\n error.message\n );\n return;\n }\n\n if (!this._isValidMeasurement(measurement)) {\n log.warn(\n `Attempting to add or update a invalid measurement provided by '${sourceInfo}'. Exiting early.`\n );\n return;\n }\n\n let internalId = data.id;\n if (!internalId) {\n internalId = guid();\n log.warn(`Measurement ID not found. Generating UID: ${internalId}`);\n }\n\n const newMeasurement = {\n ...measurement,\n modifiedTimestamp: Math.floor(Date.now() / 1000),\n id: internalId,\n };\n\n if (this.measurements[internalId]) {\n log.info(\n `Measurement already defined. Updating measurement.`,\n newMeasurement\n );\n this.measurements[internalId] = newMeasurement;\n this.publish(this.EVENTS.MEASUREMENT_UPDATED, {\n source,\n measurement: newMeasurement,\n });\n } else {\n log.info(`Measurement added.`, newMeasurement);\n this.measurements[internalId] = newMeasurement;\n this.publish(this.EVENTS.RAW_MEASUREMENT_ADDED, {\n source,\n measurement: newMeasurement,\n data,\n dataSource,\n });\n }\n\n return newMeasurement.id;\n }\n\n /**\n * Adds or update persisted measurements.\n *\n * @param {MeasurementSource} source The measurement source instance\n * @param {string} definition The source definition\n * @param {Measurement} measurement The source measurement\n * @return {string} A measurement id\n */\n addOrUpdate(source, definition, sourceMeasurement) {\n if (!this._isValidSource(source)) {\n throw new Error('Invalid source.');\n }\n\n if (!definition) {\n throw new Error('No source definition provided.');\n }\n\n const sourceInfo = this._getSourceInfo(source);\n\n if (!this._sourceHasMappings(source)) {\n throw new Error(\n `No measurement mappings found for '${sourceInfo}' source. Exiting early.`\n );\n }\n\n let measurement = {};\n try {\n const sourceMappings = this.mappings[source.id];\n const { toMeasurementSchema } = sourceMappings.find(\n mapping => mapping.definition === definition\n );\n\n /* Convert measurement */\n measurement = toMeasurementSchema(sourceMeasurement);\n\n /* Assign measurement source instance */\n measurement.source = source;\n } catch (error) {\n throw new Error(\n `Failed to map '${sourceInfo}' measurement for definition ${definition}:`,\n error.message\n );\n }\n\n if (!this._isValidMeasurement(measurement)) {\n throw new Error(\n `Attempting to add or update a invalid measurement provided by '${sourceInfo}'. Exiting early.`\n );\n }\n\n let internalId = sourceMeasurement.id;\n if (!internalId) {\n internalId = guid();\n log.info(`Measurement ID not found. Generating UID: ${internalId}`);\n }\n\n const newMeasurement = {\n ...measurement,\n modifiedTimestamp: Math.floor(Date.now() / 1000),\n id: internalId,\n };\n\n if (this.measurements[internalId]) {\n log.info(\n `Measurement already defined. Updating measurement.`,\n newMeasurement\n );\n this.measurements[internalId] = newMeasurement;\n this.publish(this.EVENTS.MEASUREMENT_UPDATED, {\n source,\n measurement: newMeasurement,\n notYetUpdatedAtSource: false,\n });\n } else {\n log.info('Measurement added.', newMeasurement);\n this.measurements[internalId] = newMeasurement;\n this.publish(this.EVENTS.MEASUREMENT_ADDED, {\n source,\n measurement: newMeasurement,\n });\n }\n\n return newMeasurement.id;\n }\n\n /**\n * Removes a measurement and broadcasts the removed event.\n *\n * @param {string} id The measurement id\n * @param {MeasurementSource} source The measurement source instance\n * @return {string} The removed measurement id\n */\n remove(id, source) {\n if (!id || !this.measurements[id]) {\n log.warn(`No id provided, or unable to find measurement by id.`);\n return;\n }\n\n delete this.measurements[id];\n this.publish(this.EVENTS.MEASUREMENT_REMOVED, {\n source,\n measurement: id, // This is weird :shrug:\n });\n }\n\n clearMeasurements() {\n this.measurements = {};\n this._jumpToMeasurementCache = {};\n this.publish(this.EVENTS.MEASUREMENTS_CLEARED);\n }\n\n jumpToMeasurement(viewportIndex, id) {\n const measurement = this.measurements[id];\n\n if (!measurement) {\n log.warn(`No id provided, or unable to find measurement by id.`);\n return;\n }\n\n this._addJumpToMeasurement(viewportIndex, id);\n\n const eventName = this.EVENTS.JUMP_TO_MEASUREMENT;\n\n const hasListeners = Object.keys(this.listeners).length > 0;\n const hasCallbacks = Array.isArray(this.listeners[eventName]);\n\n if (hasListeners && hasCallbacks) {\n this.listeners[eventName].forEach(listener => {\n listener.callback({ viewportIndex, measurement });\n });\n }\n }\n\n _addJumpToMeasurement(viewportIndex, id) {\n this._jumpToMeasurementCache[viewportIndex] = id;\n }\n\n getJumpToMeasurement(viewportIndex) {\n return this._jumpToMeasurementCache[viewportIndex];\n }\n\n removeJumpToMeasurement(viewportIndex) {\n delete this._jumpToMeasurementCache[viewportIndex];\n }\n\n _getMappingByMeasurementSource(measurementId, definition) {\n const measurement = this.getMeasurement(measurementId);\n if (this._isValidSource(measurement.source)) {\n return this.mappings[measurement.source.id].find(\n m => m.definition === definition\n );\n }\n }\n\n /**\n * Clear all measurements and broadcasts cleared event.\n */\n clear() {\n this.measurements = {};\n this.publish(this.EVENTS.MEASUREMENTS_CLEARED);\n }\n\n /**\n * Get measurement mapping function if matching criteria.\n *\n * @param {MeasurementSource} source Measurement source instance\n * @param {string} definition The source definition\n * @param {Measurement} measurement The measurement service measurement\n * @return {Object} The mapping based on matched criteria\n */\n _getMatchingMapping(source, definition, measurement) {\n const sourceMappings = this.mappings[source.id];\n\n const sourceMappingsByDefinition = sourceMappings.filter(\n mapping => mapping.definition === definition\n );\n\n /* Criteria Matching */\n return sourceMappingsByDefinition.find(({ matchingCriteria }) => {\n if (matchingCriteria.type !== measurement.type) {\n return false;\n }\n\n if (\n matchingCriteria.properties &&\n matchingCriteria.properties.every(name =>\n measurement.hasOwnProperty(name)\n )\n ) {\n return true;\n }\n\n if (\n measurement.points &&\n measurement.points.length === matchingCriteria.points\n ) {\n return true;\n }\n\n return false;\n });\n }\n\n /**\n * Returns formatted string with source info.\n *\n * @param {MeasurementSource} source Measurement source\n * @return {string} Source information\n */\n _getSourceInfo(source) {\n return `${source.name}@${source.version}`;\n }\n\n /**\n * Checks if given source is valid.\n *\n * @param {MeasurementSource} source Measurement source\n * @return {boolean} Measurement source validation\n */\n _isValidSource(source) {\n return source && this.sources[source.id];\n }\n\n /**\n * Checks if a given source has mappings.\n *\n * @param {MeasurementSource} source The measurement source\n * @return {boolean} Validation if source has mappings\n */\n _sourceHasMappings(source) {\n return (\n Array.isArray(this.mappings[source.id]) && this.mappings[source.id].length\n );\n }\n\n /**\n * Check if a given measurement data is valid.\n *\n * @param {Measurement} measurementData Measurement data\n * @return {boolean} Measurement validation\n */\n _isValidMeasurement(measurementData) {\n Object.keys(measurementData).forEach(key => {\n if (!MEASUREMENT_SCHEMA_KEYS.includes(key)) {\n log.warn(`Invalid measurement key: ${key}`);\n return false;\n }\n });\n\n return true;\n }\n\n /**\n * Check if a given measurement service event is valid.\n *\n * @param {string} eventName The name of the event\n * @return {boolean} Event name validation\n // */\n // _isValidEvent(eventName) {\n // return Object.values(this.EVENTS).includes(eventName);\n // }\n\n /**\n * Converts object of objects to array.\n *\n * @return {Array} Array of objects\n */\n _arrayOfObjects = obj => {\n return Object.entries(obj).map(e => ({ [e[0]]: e[1] }));\n };\n}\n\nexport default MeasurementService;\nexport { EVENTS, VALUE_TYPES };\n","import MeasurementService from './MeasurementService';\n\nexport default {\n name: 'MeasurementService',\n create: ({ configuration = {} }) => {\n return new MeasurementService();\n },\n};\n"],"sourceRoot":""}