@ohif/app 3.7.0-beta.33 → 3.7.0-beta.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/{192.bundle.6290fb2377d6a0ea268d.js → 192.bundle.160fffd248385d501d87.js} +2 -2
  2. package/dist/{199.bundle.4fb8686e11821dae0c90.js → 199.bundle.fe8e31ccab2445a9721d.js} +2 -2
  3. package/dist/{208.bundle.fe1e91f0acf3742925f9.js → 208.bundle.ee392e7c48237252ea8e.js} +2 -2
  4. package/dist/{270.bundle.49a50e13715da82c083f.js → 270.bundle.2d215f8720350f03e171.js} +2 -2
  5. package/dist/{283.bundle.f82d3dc59066b118cf27.js → 283.bundle.b19d7099a6fb8c957fb1.js} +4 -4
  6. package/dist/{351.bundle.444e1c32785871760302.js → 351.bundle.2e949640c417cd735688.js} +6 -10
  7. package/dist/{331.bundle.6d141ff13ae957b1db6f.js → 389.bundle.38df7e54d2f632cfa7a0.js} +36 -3
  8. package/dist/{404.bundle.7b7f4990f9762c2c24ed.js → 404.bundle.051cd13557d04cc76630.js} +2 -2
  9. package/dist/{55.bundle.3fdadd0823a136eb4585.js → 55.bundle.fe53f3784bfe7db4a5a5.js} +4 -4
  10. package/dist/{569.bundle.ee136cf6526a6380633c.js → 569.bundle.e77c17d37a65e5dedfed.js} +2 -2
  11. package/dist/{581.bundle.ab8d1f1e75de3c98dd10.js → 581.bundle.15078e71fe52b53f48b3.js} +2 -2
  12. package/dist/{616.bundle.a18d837e98dc2fad072c.js → 616.bundle.fc1820b3d98da340218c.js} +2 -2
  13. package/dist/{625.bundle.e80ea79cda37ee4b6263.js → 625.bundle.7de4074e256c743ca500.js} +5 -5
  14. package/dist/{642.bundle.23c1d28e6689362f106f.js → 642.bundle.f03da99e63dbfdc1cf1c.js} +2 -2
  15. package/dist/{728.bundle.38ad0fbfcf6cfd8f9e9e.js → 728.bundle.5bef7c8643b42d70a79f.js} +5 -5
  16. package/dist/{744.bundle.fd4eae46f382b3e1d496.js → 744.bundle.08e4a5bbc4fd371a50b3.js} +7 -7
  17. package/dist/{790.bundle.ebfacd71c3af955a92b3.js → 790.bundle.6fa09929a3203bcf3f2c.js} +2 -2
  18. package/dist/{799.bundle.620e1df13daf7b31cb3f.js → 799.bundle.d8e50f1fd6bf4fa3a5e1.js} +2 -2
  19. package/dist/{82.bundle.3328dd25b6fd1c1c43f6.js → 82.bundle.11e08acaf3e1f527278d.js} +124 -98
  20. package/dist/{917.bundle.cb498f4f4d85e0248a14.js → 917.bundle.e0647888c6fff8e72e95.js} +2 -2
  21. package/dist/{953.bundle.4b8fee7d9484456a99b5.js → 953.bundle.95b0621f1da8dfeaed8a.js} +1 -1
  22. package/dist/{973.bundle.62c5bba110e379cef75e.js → 973.bundle.634f585248ead3160ff2.js} +2 -2
  23. package/dist/{976.bundle.b61d2e7e5ed3bc534c2c.js → 976.bundle.9dec94108550ad448773.js} +3 -3
  24. package/dist/{984.bundle.5e08be248b0bced4e89b.js → 984.bundle.1149cce5c5ecb63e76a9.js} +9 -9
  25. package/dist/app-config.js +6 -5
  26. package/dist/{app.bundle.543496e18d21f3595028.js → app.bundle.53e7fd8f8335245828d8.js} +636 -464
  27. package/dist/google.js +5 -4
  28. package/dist/index.html +1 -1
  29. package/dist/sw.js +1 -1
  30. package/package.json +18 -18
  31. /package/dist/{50.bundle.c11736e7c4a5b65f67e6.js → 50.bundle.260f830a3870cae30cf5.js} +0 -0
@@ -4207,16 +4207,15 @@ exports.Z = function (file, acceptedFiles) {
4207
4207
 
4208
4208
  /***/ }),
4209
4209
 
4210
- /***/ 39852:
4210
+ /***/ 42492:
4211
4211
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4212
4212
 
4213
4213
  "use strict";
4214
4214
 
4215
4215
  // EXPORTS
4216
4216
  __webpack_require__.d(__webpack_exports__, {
4217
- Nr: () => (/* reexport */ useDebounce),
4218
- aM: () => (/* reexport */ useQuery),
4219
- lr: () => (/* reexport */ useSearchParams)
4217
+ N: () => (/* reexport */ useDebounce),
4218
+ l: () => (/* reexport */ useSearchParams/* default */.Z)
4220
4219
  });
4221
4220
 
4222
4221
  // EXTERNAL MODULE: ../../../node_modules/react/index.js
@@ -4250,35 +4249,48 @@ function useDebounce(value, delay) {
4250
4249
 
4251
4250
  return debouncedValue;
4252
4251
  }
4253
- // EXTERNAL MODULE: ../node_modules/react-router-dom/dist/index.js
4254
- var dist = __webpack_require__(65783);
4255
- ;// CONCATENATED MODULE: ./hooks/useQuery.js
4252
+ // EXTERNAL MODULE: ./hooks/useSearchParams.ts
4253
+ var useSearchParams = __webpack_require__(2318);
4254
+ ;// CONCATENATED MODULE: ./hooks/index.js
4256
4255
 
4257
- function useQuery() {
4258
- return new URLSearchParams((0,dist/* useLocation */.TH)().search);
4259
- }
4260
- ;// CONCATENATED MODULE: ./hooks/useSearchParams.js
4256
+
4257
+
4258
+
4259
+ /***/ }),
4260
+
4261
+ /***/ 2318:
4262
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4263
+
4264
+ "use strict";
4265
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
4266
+ /* harmony export */ Z: () => (/* binding */ useSearchParams)
4267
+ /* harmony export */ });
4268
+ /* harmony import */ var react_router__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(14935);
4261
4269
 
4262
4270
 
4263
4271
  /**
4264
- * It returns a Map of the query parameters in the URL, where the keys are
4265
- * lowercase
4266
- * @returns A function that returns a Map of the query parameters.
4272
+ * It returns a URLSearchParams of the query parameters in the URL, where the keys are
4273
+ * either lowercase or maintain their case based on the lowerCaseKeys parameter.
4274
+ * @param {lowerCaseKeys:boolean} true to return lower case keys; false (default) to maintain casing;
4275
+ * @returns {URLSearchParams}
4267
4276
  */
4268
4277
  function useSearchParams() {
4269
- const query = useQuery();
4270
- // make query params case-insensitive
4271
- const searchParams = new Map();
4272
- for (const [key, value] of query) {
4273
- searchParams.set(key.toLowerCase(), value);
4278
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
4279
+ lowerCaseKeys: false
4280
+ };
4281
+ const {
4282
+ lowerCaseKeys
4283
+ } = options;
4284
+ const searchParams = new URLSearchParams((0,react_router__WEBPACK_IMPORTED_MODULE_0__/* .useLocation */ .TH)().search);
4285
+ if (!lowerCaseKeys) {
4286
+ return searchParams;
4274
4287
  }
4275
- return searchParams;
4288
+ const lowerCaseSearchParams = new URLSearchParams();
4289
+ for (const [key, value] of searchParams) {
4290
+ lowerCaseSearchParams.set(key.toLowerCase(), value);
4291
+ }
4292
+ return lowerCaseSearchParams;
4276
4293
  }
4277
- ;// CONCATENATED MODULE: ./hooks/index.js
4278
-
4279
-
4280
-
4281
-
4282
4294
 
4283
4295
  /***/ }),
4284
4296
 
@@ -4334,10 +4346,12 @@ Compose.propTypes = {
4334
4346
  var ui_src = __webpack_require__(28619);
4335
4347
  // EXTERNAL MODULE: ./state/index.js + 1 modules
4336
4348
  var state = __webpack_require__(22896);
4337
- // EXTERNAL MODULE: ../../core/src/index.ts + 102 modules
4338
- var core_src = __webpack_require__(62771);
4349
+ // EXTERNAL MODULE: ../../core/src/index.ts + 103 modules
4350
+ var core_src = __webpack_require__(87754);
4339
4351
  // EXTERNAL MODULE: ../node_modules/react-router/dist/index.js
4340
4352
  var react_router_dist = __webpack_require__(14935);
4353
+ // EXTERNAL MODULE: ./hooks/useSearchParams.ts
4354
+ var useSearchParams = __webpack_require__(2318);
4341
4355
  ;// CONCATENATED MODULE: ./routes/DataSourceWrapper.tsx
4342
4356
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
4343
4357
  /* eslint-disable react/jsx-props-no-spreading */
@@ -4348,6 +4362,14 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
4348
4362
 
4349
4363
 
4350
4364
 
4365
+
4366
+ /**
4367
+ * Determines if two React Router location objects are the same.
4368
+ */
4369
+ const areLocationsTheSame = (location0, location1) => {
4370
+ return location0.pathname === location1.pathname && location0.search === location1.search && location0.hash === location1.hash;
4371
+ };
4372
+
4351
4373
  /**
4352
4374
  * Uses route properties to determine the data source that should be passed
4353
4375
  * to the child layout template. In some instances, initiates requests and
@@ -4363,33 +4385,10 @@ function DataSourceWrapper(props) {
4363
4385
  } = props;
4364
4386
  const params = (0,react_router_dist/* useParams */.UO)();
4365
4387
  const location = (0,react_router_dist/* useLocation */.TH)();
4366
-
4367
- // TODO - get the variable from the props all the time...
4368
- let dataSourceName = new URLSearchParams(location.search).get('datasources');
4369
- const dataPath = dataSourceName ? `/${dataSourceName}` : '';
4370
- if (!dataSourceName && window.config.defaultDataSourceName) {
4371
- dataSourceName = window.config.defaultDataSourceName;
4372
- } else if (!dataSourceName) {
4373
- // Gets the first defined datasource with the right name
4374
- // Mostly for historical reasons - new configs should use the defaultDataSourceName
4375
- const dataSourceModules = extensionManager.modules[core_src/* MODULE_TYPES */.OB.DATA_SOURCE];
4376
- // TODO: Good usecase for flatmap?
4377
- const webApiDataSources = dataSourceModules.reduce((acc, curr) => {
4378
- const mods = [];
4379
- curr.module.forEach(mod => {
4380
- if (mod.type === 'webApi') {
4381
- mods.push(mod);
4382
- }
4383
- });
4384
- return acc.concat(mods);
4385
- }, []);
4386
- dataSourceName = webApiDataSources.map(ds => ds.name).find(it => extensionManager.getDataSources(it)?.[0] !== undefined);
4387
- }
4388
- const dataSource = extensionManager.getDataSources(dataSourceName)?.[0];
4389
- if (!dataSource) {
4390
- throw new Error(`No data source found for ${dataSourceName}`);
4391
- }
4392
-
4388
+ const lowerCaseSearchParams = (0,useSearchParams/* default */.Z)({
4389
+ lowerCaseKeys: true
4390
+ });
4391
+ const query = (0,useSearchParams/* default */.Z)();
4393
4392
  // Route props --> studies.mapParams
4394
4393
  // mapParams --> studies.search
4395
4394
  // studies.search --> studies.processResults
@@ -4404,9 +4403,84 @@ function DataSourceWrapper(props) {
4404
4403
  pageNumber: 1,
4405
4404
  location: 'Not a valid location, causes first load to occur'
4406
4405
  };
4406
+ const getInitialDataSourceName = (0,react.useCallback)(() => {
4407
+ // TODO - get the variable from the props all the time...
4408
+ let dataSourceName = lowerCaseSearchParams.get('datasources');
4409
+ if (!dataSourceName && window.config.defaultDataSourceName) {
4410
+ return '';
4411
+ }
4412
+ if (!dataSourceName) {
4413
+ // Gets the first defined datasource with the right name
4414
+ // Mostly for historical reasons - new configs should use the defaultDataSourceName
4415
+ const dataSourceModules = extensionManager.modules[core_src/* MODULE_TYPES */.OB.DATA_SOURCE];
4416
+ // TODO: Good usecase for flatmap?
4417
+ const webApiDataSources = dataSourceModules.reduce((acc, curr) => {
4418
+ const mods = [];
4419
+ curr.module.forEach(mod => {
4420
+ if (mod.type === 'webApi') {
4421
+ mods.push(mod);
4422
+ }
4423
+ });
4424
+ return acc.concat(mods);
4425
+ }, []);
4426
+ dataSourceName = webApiDataSources.map(ds => ds.name).find(it => extensionManager.getDataSources(it)?.[0] !== undefined);
4427
+ }
4428
+ return dataSourceName;
4429
+ }, []);
4430
+ const [isDataSourceInitialized, setIsDataSourceInitialized] = (0,react.useState)(false);
4431
+
4432
+ // The path to the data source to be used in the URL for a mode (e.g. mode/dataSourcePath?StudyIntanceUIDs=1.2.3)
4433
+ const [dataSourcePath, setDataSourcePath] = (0,react.useState)(() => {
4434
+ const dataSourceName = getInitialDataSourceName();
4435
+ return dataSourceName ? `/${dataSourceName}` : '';
4436
+ });
4437
+ const [dataSource, setDataSource] = (0,react.useState)(() => {
4438
+ const dataSourceName = getInitialDataSourceName();
4439
+ if (!dataSourceName) {
4440
+ return extensionManager.getActiveDataSource()[0];
4441
+ }
4442
+ const dataSource = extensionManager.getDataSources(dataSourceName)?.[0];
4443
+ if (!dataSource) {
4444
+ throw new Error(`No data source found for ${dataSourceName}`);
4445
+ }
4446
+ return dataSource;
4447
+ });
4407
4448
  const [data, setData] = (0,react.useState)(DEFAULT_DATA);
4408
4449
  const [isLoading, setIsLoading] = (0,react.useState)(false);
4450
+
4451
+ /**
4452
+ * The effect to initialize the data source whenever it changes. Similar to
4453
+ * whenever a different Mode is entered, the Mode's data source is initialized, so
4454
+ * too this DataSourceWrapper must initialize its data source whenever a different
4455
+ * data source is activated. Furthermore, a data source might be initialized
4456
+ * several times as it gets activated/deactivated because the location URL
4457
+ * might change and data sources initialize based on the URL.
4458
+ */
4459
+ (0,react.useEffect)(() => {
4460
+ const initializeDataSource = async () => {
4461
+ await dataSource.initialize({
4462
+ params,
4463
+ query
4464
+ });
4465
+ setIsDataSourceInitialized(true);
4466
+ };
4467
+ initializeDataSource();
4468
+ }, [dataSource]);
4409
4469
  (0,react.useEffect)(() => {
4470
+ const dataSourceChangedCallback = () => {
4471
+ setIsDataSourceInitialized(false);
4472
+ setDataSourcePath('');
4473
+ setDataSource(extensionManager.getActiveDataSource()[0]);
4474
+ // Setting data to DEFAULT_DATA triggers a new query just like it does for the initial load.
4475
+ setData(DEFAULT_DATA);
4476
+ };
4477
+ const sub = extensionManager.subscribe(core_src/* ExtensionManager */.W$.EVENTS.ACTIVE_DATA_SOURCE_CHANGED, dataSourceChangedCallback);
4478
+ return () => sub.unsubscribe();
4479
+ }, []);
4480
+ (0,react.useEffect)(() => {
4481
+ if (!isDataSourceInitialized) {
4482
+ return;
4483
+ }
4410
4484
  const queryFilterValues = _getQueryFilterValues(location.search, STUDIES_LIMIT);
4411
4485
 
4412
4486
  // 204: no content
@@ -4429,7 +4503,10 @@ function DataSourceWrapper(props) {
4429
4503
  const isSamePage = data.pageNumber === queryFilterValues.pageNumber;
4430
4504
  const previousOffset = Math.floor(data.pageNumber * data.resultsPerPage / STUDIES_LIMIT) * (STUDIES_LIMIT - 1);
4431
4505
  const newOffset = Math.floor(queryFilterValues.pageNumber * queryFilterValues.resultsPerPage / STUDIES_LIMIT) * (STUDIES_LIMIT - 1);
4432
- const isLocationUpdated = data.location !== location;
4506
+ // Simply checking data.location !== location is not sufficient because even though the location href (i.e. entire URL)
4507
+ // has not changed, the React Router still provides a new location reference and would result in two study queries
4508
+ // on initial load. Alternatively, window.location.href could be used.
4509
+ const isLocationUpdated = typeof data.location === 'string' || !areLocationsTheSame(data.location, location);
4433
4510
  const isDataInvalid = !isSamePage || !isLoading && (newOffset !== previousOffset || isLocationUpdated);
4434
4511
  if (isDataInvalid) {
4435
4512
  getData();
@@ -4438,13 +4515,13 @@ function DataSourceWrapper(props) {
4438
4515
  console.warn(ex);
4439
4516
  }
4440
4517
  // eslint-disable-next-line react-hooks/exhaustive-deps
4441
- }, [data, location, params, isLoading, setIsLoading]);
4518
+ }, [data, location, params, isLoading, setIsLoading, dataSource, isDataSourceInitialized]);
4442
4519
  // queryFilterValues
4443
4520
 
4444
4521
  // TODO: Better way to pass DataSource?
4445
4522
  return /*#__PURE__*/react.createElement(LayoutTemplate, _extends({}, rest, {
4446
4523
  data: data.studies,
4447
- dataPath: dataPath,
4524
+ dataPath: dataSourcePath,
4448
4525
  dataTotal: data.total,
4449
4526
  dataSource: dataSource,
4450
4527
  isLoadingData: isLoading
@@ -4777,8 +4854,8 @@ const filtersMeta = [{
4777
4854
  gridCol: 2
4778
4855
  }];
4779
4856
  /* harmony default export */ const WorkList_filtersMeta = (filtersMeta);
4780
- // EXTERNAL MODULE: ./hooks/index.js + 3 modules
4781
- var hooks = __webpack_require__(39852);
4857
+ // EXTERNAL MODULE: ./hooks/index.js + 1 modules
4858
+ var hooks = __webpack_require__(42492);
4782
4859
  ;// CONCATENATED MODULE: ./routes/WorkList/WorkList.tsx
4783
4860
 
4784
4861
 
@@ -4834,7 +4911,7 @@ function WorkList(_ref) {
4834
4911
  // ~ Modes
4835
4912
  const [appConfig] = (0,state/* useAppConfig */.M)();
4836
4913
  // ~ Filters
4837
- const searchParams = (0,hooks/* useSearchParams */.lr)();
4914
+ const searchParams = (0,hooks/* useSearchParams */.l)();
4838
4915
  const navigate = (0,dist/* useNavigate */.s0)();
4839
4916
  const STUDIES_LIMIT = 101;
4840
4917
  const queryFilterValues = WorkList_getQueryFilterValues(searchParams);
@@ -4842,7 +4919,7 @@ function WorkList(_ref) {
4842
4919
  ...defaultFilterValues,
4843
4920
  ...queryFilterValues
4844
4921
  });
4845
- const debouncedFilterValues = (0,hooks/* useDebounce */.Nr)(filterValues, 200);
4922
+ const debouncedFilterValues = (0,hooks/* useDebounce */.N)(filterValues, 200);
4846
4923
  const {
4847
4924
  resultsPerPage,
4848
4925
  pageNumber,
@@ -4890,6 +4967,9 @@ function WorkList(_ref) {
4890
4967
  const [expandedRows, setExpandedRows] = (0,react.useState)([]);
4891
4968
  const [studiesWithSeriesData, setStudiesWithSeriesData] = (0,react.useState)([]);
4892
4969
  const numOfStudies = studiesTotal;
4970
+ const querying = (0,react.useMemo)(() => {
4971
+ return isLoadingData || expandedRows.length > 0;
4972
+ }, [isLoadingData, expandedRows]);
4893
4973
  const setFilterValues = val => {
4894
4974
  if (filterValues.pageNumber === val.pageNumber) {
4895
4975
  val.pageNumber = 1;
@@ -4985,6 +5065,7 @@ function WorkList(_ref) {
4985
5065
  }
4986
5066
  fetchSeries(studyInstanceUid);
4987
5067
  }
5068
+
4988
5069
  // eslint-disable-next-line react-hooks/exhaustive-deps
4989
5070
  }, [expandedRows, studies]);
4990
5071
  const isFiltering = (filterValues, defaultFilterValues) => {
@@ -5118,8 +5199,8 @@ function WorkList(_ref) {
5118
5199
  };
5119
5200
  });
5120
5201
  const hasStudies = numOfStudies > 0;
5121
- const versionNumber = "3.7.0-beta.33";
5122
- const commitHash = "18156bb7b1cc24c47beadb0a6acd31db7fa076a3";
5202
+ const versionNumber = "3.7.0-beta.36";
5203
+ const commitHash = "7bbc213f58a1be3560c0414242549007885d0f13";
5123
5204
  const menuOptions = [{
5124
5205
  title: t('Header:About'),
5125
5206
  icon: 'info',
@@ -5169,7 +5250,7 @@ function WorkList(_ref) {
5169
5250
  const {
5170
5251
  component: dicomUploadComponent
5171
5252
  } = customizationService.get('dicomUploadComponent') ?? {};
5172
- const uploadProps = dicomUploadComponent && dataSource.getConfig().dicomUploadEnabled ? {
5253
+ const uploadProps = dicomUploadComponent && dataSource.getConfig()?.dicomUploadEnabled ? {
5173
5254
  title: 'Upload files',
5174
5255
  closeButton: true,
5175
5256
  shouldCloseOnEsc: false,
@@ -5214,6 +5295,7 @@ function WorkList(_ref) {
5214
5295
  }, /*#__PURE__*/react.createElement(ui_src/* StudyListTable */.X7, {
5215
5296
  tableDataSource: tableDataSource.slice(offset, offsetAndTake),
5216
5297
  numOfStudies: numOfStudies,
5298
+ querying: querying,
5217
5299
  filtersMeta: WorkList_filtersMeta
5218
5300
  }), /*#__PURE__*/react.createElement("div", {
5219
5301
  className: "grow"
@@ -6053,15 +6135,15 @@ async function loadModule(module) {
6053
6135
  return imported.default;
6054
6136
  }
6055
6137
  if (module === "@ohif/extension-cornerstone") {
6056
- const imported = await Promise.all(/* import() */[__webpack_require__.e(780), __webpack_require__.e(381), __webpack_require__.e(331), __webpack_require__.e(270), __webpack_require__.e(935), __webpack_require__.e(728), __webpack_require__.e(625)]).then(__webpack_require__.bind(__webpack_require__, 39501));
6138
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(780), __webpack_require__.e(381), __webpack_require__.e(389), __webpack_require__.e(270), __webpack_require__.e(935), __webpack_require__.e(728), __webpack_require__.e(625)]).then(__webpack_require__.bind(__webpack_require__, 39501));
6057
6139
  return imported.default;
6058
6140
  }
6059
6141
  if (module === "@ohif/extension-measurement-tracking") {
6060
- const imported = await Promise.all(/* import() */[__webpack_require__.e(780), __webpack_require__.e(381), __webpack_require__.e(331), __webpack_require__.e(270), __webpack_require__.e(606), __webpack_require__.e(531), __webpack_require__.e(984), __webpack_require__.e(744)]).then(__webpack_require__.bind(__webpack_require__, 43744));
6142
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(780), __webpack_require__.e(381), __webpack_require__.e(389), __webpack_require__.e(270), __webpack_require__.e(606), __webpack_require__.e(531), __webpack_require__.e(984), __webpack_require__.e(744)]).then(__webpack_require__.bind(__webpack_require__, 43744));
6061
6143
  return imported.default;
6062
6144
  }
6063
6145
  if (module === "@ohif/extension-cornerstone-dicom-sr") {
6064
- const imported = await Promise.all(/* import() */[__webpack_require__.e(780), __webpack_require__.e(381), __webpack_require__.e(331), __webpack_require__.e(270), __webpack_require__.e(606), __webpack_require__.e(984)]).then(__webpack_require__.bind(__webpack_require__, 65948));
6146
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(780), __webpack_require__.e(381), __webpack_require__.e(389), __webpack_require__.e(270), __webpack_require__.e(606), __webpack_require__.e(984)]).then(__webpack_require__.bind(__webpack_require__, 65948));
6065
6147
  return imported.default;
6066
6148
  }
6067
6149
  if (module === "@ohif/extension-cornerstone-dicom-seg") {
@@ -6081,7 +6163,7 @@ async function loadModule(module) {
6081
6163
  return imported.default;
6082
6164
  }
6083
6165
  if (module === "@ohif/extension-tmtv") {
6084
- const imported = await Promise.all(/* import() */[__webpack_require__.e(780), __webpack_require__.e(381), __webpack_require__.e(331), __webpack_require__.e(270), __webpack_require__.e(283)]).then(__webpack_require__.bind(__webpack_require__, 66135));
6166
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(780), __webpack_require__.e(381), __webpack_require__.e(389), __webpack_require__.e(270), __webpack_require__.e(283)]).then(__webpack_require__.bind(__webpack_require__, 66135));
6085
6167
  return imported.default;
6086
6168
  }
6087
6169
  if (module === "@ohif/extension-test") {
@@ -6215,9 +6297,15 @@ function ModeRoute(_ref3) {
6215
6297
  } = _ref3;
6216
6298
  // Parse route params/querystring
6217
6299
  const location = (0,react_router_dist/* useLocation */.TH)();
6218
- const query = (0,hooks/* useQuery */.aM)();
6300
+
6301
+ // The react router DOM placeholder map (see https://reactrouter.com/en/main/hooks/use-params).
6219
6302
  const params = (0,react_router_dist/* useParams */.UO)();
6220
- const searchParams = (0,hooks/* useSearchParams */.lr)();
6303
+ // The URL's query search parameters where the keys casing is maintained
6304
+ const query = (0,hooks/* useSearchParams */.l)();
6305
+ // The URL's query search parameters where the keys are all lower case.
6306
+ const lowerCaseSearchParams = (0,hooks/* useSearchParams */.l)({
6307
+ lowerCaseKeys: true
6308
+ });
6221
6309
  const [studyInstanceUIDs, setStudyInstanceUIDs] = (0,react.useState)();
6222
6310
  const [refresh, setRefresh] = (0,react.useState)(false);
6223
6311
  const [ExtensionDependenciesLoaded, setExtensionDependenciesLoaded] = (0,react.useState)(false);
@@ -6242,8 +6330,8 @@ function ModeRoute(_ref3) {
6242
6330
  hotkeys: hotkeyObj,
6243
6331
  hangingProtocol
6244
6332
  } = mode;
6245
- const runTimeHangingProtocolId = searchParams.get('hangingprotocolid');
6246
- const token = searchParams.get('token');
6333
+ const runTimeHangingProtocolId = lowerCaseSearchParams.get('hangingprotocolid');
6334
+ const token = lowerCaseSearchParams.get('token');
6247
6335
  if (token) {
6248
6336
  // if a token is passed in, set the userAuthenticationService to use it
6249
6337
  // for the Authorization header for all requests
@@ -6269,10 +6357,11 @@ function ModeRoute(_ref3) {
6269
6357
  // Preserve the old array interface for hotkeys
6270
6358
  const hotkeys = Array.isArray(hotkeyObj) ? hotkeyObj : hotkeyObj?.hotkeys;
6271
6359
  const hotkeyName = hotkeyObj?.name || 'hotkey-definitions-v2';
6272
- if (dataSourceName === undefined) {
6273
- dataSourceName = extensionManager.defaultDataSourceName;
6360
+
6361
+ // An undefined dataSourceName implies that the active data source that is already set in the ExtensionManager should be used.
6362
+ if (dataSourceName !== undefined) {
6363
+ extensionManager.setActiveDataSource(dataSourceName);
6274
6364
  }
6275
- extensionManager.setActiveDataSource(dataSourceName);
6276
6365
  const dataSource = extensionManager.getActiveDataSource()[0];
6277
6366
 
6278
6367
  // Only handling one route per mode for now
@@ -6335,11 +6424,14 @@ function ModeRoute(_ref3) {
6335
6424
 
6336
6425
  // Todo: this should not be here, data source should not care about params
6337
6426
  const initializeDataSource = async (params, query) => {
6338
- const studyInstanceUIDs = await dataSource.initialize({
6427
+ await dataSource.initialize({
6339
6428
  params,
6340
6429
  query
6341
6430
  });
6342
- setStudyInstanceUIDs(studyInstanceUIDs);
6431
+ setStudyInstanceUIDs(dataSource.getStudyInstanceUIDs({
6432
+ params,
6433
+ query
6434
+ }));
6343
6435
  };
6344
6436
  initializeDataSource(params, query);
6345
6437
  return () => {
@@ -6574,15 +6666,14 @@ function buildModeRoutes(_ref) {
6574
6666
  private: true
6575
6667
  });
6576
6668
  });
6577
- const defaultDataSourceName = extensionManager.defaultDataSourceName;
6578
6669
 
6579
- // Add default DataSource route.
6670
+ // Add active DataSource route.
6671
+ // This is the DataSource route for the active data source defined in ExtensionManager.getActiveDataSource
6580
6672
  const path = `/${mode.routeName}`;
6581
6673
 
6582
6674
  // TODO move up.
6583
6675
  const children = () => /*#__PURE__*/react.createElement(ModeRoute, {
6584
6676
  mode: mode,
6585
- dataSourceName: defaultDataSourceName,
6586
6677
  extensionManager: extensionManager,
6587
6678
  servicesManager: servicesManager,
6588
6679
  commandsManager: commandsManager,
@@ -6677,7 +6768,8 @@ const createRoutes = _ref => {
6677
6768
  private: true,
6678
6769
  props: {
6679
6770
  children: WorkList_WorkList,
6680
- servicesManager
6771
+ servicesManager,
6772
+ extensionManager
6681
6773
  }
6682
6774
  };
6683
6775
  const customRoutes = customizationService.getGlobalCustomization('customRoutes');
@@ -7448,7 +7540,7 @@ function _getImageOrientationPatient(image) {
7448
7540
 
7449
7541
  /***/ }),
7450
7542
 
7451
- /***/ 62771:
7543
+ /***/ 87754:
7452
7544
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
7453
7545
 
7454
7546
  "use strict";
@@ -7515,379 +7607,6 @@ const log = {
7515
7607
  timeEnd: console.timeEnd
7516
7608
  };
7517
7609
  /* harmony default export */ const src_log = (log);
7518
- ;// CONCATENATED MODULE: ../../core/src/extensions/ExtensionManager.ts
7519
-
7520
-
7521
-
7522
- /**
7523
- * This is the arguments given to create the extension.
7524
- */
7525
-
7526
- /**
7527
- * The configuration of an extension.
7528
- * This uses type as the extension manager only knows that the configuration
7529
- * is an object of some sort, and doesn't know anything else about it.
7530
- */
7531
-
7532
- /**
7533
- * The parameters passed to the extension.
7534
- */
7535
-
7536
- /**
7537
- * The type of an actual extension instance.
7538
- * This is an interface as it declares possible calls, but extensions can
7539
- * have more values than this.
7540
- */
7541
-
7542
- class ExtensionManager {
7543
- constructor(_ref) {
7544
- var _this = this;
7545
- let {
7546
- commandsManager,
7547
- servicesManager,
7548
- hotkeysManager,
7549
- appConfig = {}
7550
- } = _ref;
7551
- this._commandsManager = void 0;
7552
- this._servicesManager = void 0;
7553
- this._hotkeysManager = void 0;
7554
- /**
7555
- * An array of extensions, or an array of arrays that contains extension
7556
- * configuration pairs.
7557
- *
7558
- * @param {Object[]} extensions - Array of extensions
7559
- */
7560
- this.registerExtensions = async function (extensions) {
7561
- let dataSources = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
7562
- // Todo: we ideally should be able to run registrations in parallel
7563
- // but currently since some extensions need to be registered before
7564
- // others, we need to run them sequentially. We need a postInit hook
7565
- // to avoid this sequential async registration
7566
- for (let i = 0; i < extensions.length; i++) {
7567
- const extension = extensions[i];
7568
- const hasConfiguration = Array.isArray(extension);
7569
- try {
7570
- if (hasConfiguration) {
7571
- // Important: for some reason in the line below the type
7572
- // of extension is not recognized as [ExtensionRegister,
7573
- // ExtensionConfiguration] by babel DON"T CHANGE IT
7574
- // Same for the for loop above don't use
7575
- // for (const extension of extensions)
7576
- const ohifExtension = extension[0];
7577
- const configuration = extension[1];
7578
- await _this.registerExtension(ohifExtension, configuration, dataSources);
7579
- } else {
7580
- await _this.registerExtension(extension, {}, dataSources);
7581
- }
7582
- } catch (error) {
7583
- console.error(error);
7584
- }
7585
- }
7586
- };
7587
- /**
7588
- *
7589
- * TODO: Id Management: SopClassHandlers currently refer to viewport module by id; setting the extension id as viewport module id is a workaround for now
7590
- * @param {Object} extension
7591
- * @param {Object} configuration
7592
- */
7593
- this.registerExtension = async function (extension) {
7594
- let configuration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7595
- let dataSources = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
7596
- if (!extension) {
7597
- throw new Error('Attempting to register a null/undefined extension.');
7598
- }
7599
- const extensionId = extension.id;
7600
- if (!extensionId) {
7601
- // Note: Mode framework cannot function without IDs.
7602
- src_log.warn(extension);
7603
- throw new Error(`Extension ID not set`);
7604
- }
7605
- if (_this.registeredExtensionIds.includes(extensionId)) {
7606
- src_log.warn(`Extension ID ${extensionId} has already been registered. Exiting before duplicating modules.`);
7607
- return;
7608
- }
7609
-
7610
- // preRegistrationHook
7611
- if (extension.preRegistration) {
7612
- await extension.preRegistration({
7613
- servicesManager: _this._servicesManager,
7614
- commandsManager: _this._commandsManager,
7615
- hotkeysManager: _this._hotkeysManager,
7616
- extensionManager: _this,
7617
- appConfig: _this._appConfig,
7618
- configuration
7619
- });
7620
- }
7621
- if (extension.onModeEnter) {
7622
- _this._extensionLifeCycleHooks.onModeEnter[extensionId] = extension.onModeEnter;
7623
- }
7624
- if (extension.onModeExit) {
7625
- _this._extensionLifeCycleHooks.onModeExit[extensionId] = extension.onModeExit;
7626
- }
7627
-
7628
- // Register Modules
7629
- _this.moduleTypeNames.forEach(moduleType => {
7630
- const extensionModule = _this._getExtensionModule(moduleType, extension, extensionId, configuration);
7631
- if (extensionModule) {
7632
- switch (moduleType) {
7633
- case MODULE_TYPES.COMMANDS:
7634
- _this._initCommandsModule(extensionModule);
7635
- break;
7636
- case MODULE_TYPES.DATA_SOURCE:
7637
- _this._initDataSourcesModule(extensionModule, extensionId, dataSources);
7638
- break;
7639
- case MODULE_TYPES.HANGING_PROTOCOL:
7640
- _this._initHangingProtocolsModule(extensionModule, extensionId);
7641
- case MODULE_TYPES.TOOLBAR:
7642
- case MODULE_TYPES.VIEWPORT:
7643
- case MODULE_TYPES.PANEL:
7644
- case MODULE_TYPES.SOP_CLASS_HANDLER:
7645
- case MODULE_TYPES.CONTEXT:
7646
- case MODULE_TYPES.LAYOUT_TEMPLATE:
7647
- case MODULE_TYPES.CUSTOMIZATION:
7648
- case MODULE_TYPES.STATE_SYNC:
7649
- case MODULE_TYPES.UTILITY:
7650
- // Default for most extension points,
7651
- // Just adds each entry ready for consumption by mode.
7652
- extensionModule.forEach(element => {
7653
- if (!element.name) {
7654
- throw new Error(`Extension ID ${extensionId} module ${moduleType} element has no name`);
7655
- }
7656
- const id = `${extensionId}.${moduleType}.${element.name}`;
7657
- element.id = id;
7658
- _this.modulesMap[id] = element;
7659
- });
7660
- break;
7661
- default:
7662
- throw new Error(`Module type invalid: ${moduleType}`);
7663
- }
7664
- _this.modules[moduleType].push({
7665
- extensionId,
7666
- module: extensionModule
7667
- });
7668
- }
7669
- });
7670
-
7671
- // Track extension registration
7672
- _this.registeredExtensionIds.push(extensionId);
7673
- };
7674
- this.getModuleEntry = stringEntry => {
7675
- return this.modulesMap[stringEntry];
7676
- };
7677
- this.getDataSources = dataSourceName => {
7678
- if (dataSourceName === undefined) {
7679
- // Default to the activeDataSource
7680
- dataSourceName = this.activeDataSource;
7681
- }
7682
-
7683
- // Note: this currently uses the data source name, which feels weird...
7684
- return this.dataSourceMap[dataSourceName];
7685
- };
7686
- this.getActiveDataSource = () => {
7687
- return this.dataSourceMap[this.activeDataSource];
7688
- };
7689
- this.getDataSource = () => {
7690
- return this.dataSourceMap[this.activeDataSource];
7691
- };
7692
- /**
7693
- * @private
7694
- * @param {string} moduleType
7695
- * @param {Object} extension
7696
- * @param {string} extensionId - Used for logging warnings
7697
- */
7698
- this._getExtensionModule = (moduleType, extension, extensionId, configuration) => {
7699
- const getModuleFnName = 'get' + _capitalizeFirstCharacter(moduleType);
7700
- const getModuleFn = extension[getModuleFnName];
7701
- if (!getModuleFn) {
7702
- return;
7703
- }
7704
- try {
7705
- const extensionModule = extension[getModuleFnName]({
7706
- appConfig: this._appConfig,
7707
- commandsManager: this._commandsManager,
7708
- servicesManager: this._servicesManager,
7709
- hotkeysManager: this._hotkeysManager,
7710
- extensionManager: this,
7711
- configuration
7712
- });
7713
- if (!extensionModule) {
7714
- src_log.warn(`Null or undefined returned when registering the ${getModuleFnName} module for the ${extensionId} extension`);
7715
- }
7716
- return extensionModule;
7717
- } catch (ex) {
7718
- console.log(ex);
7719
- throw new Error(`Exception thrown while trying to call ${getModuleFnName} for the ${extensionId} extension`);
7720
- }
7721
- };
7722
- this._initHangingProtocolsModule = (extensionModule, extensionId) => {
7723
- const {
7724
- hangingProtocolService
7725
- } = this._servicesManager.services;
7726
- extensionModule.forEach(_ref2 => {
7727
- let {
7728
- name,
7729
- protocol
7730
- } = _ref2;
7731
- if (protocol) {
7732
- // Only auto-register if protocol specified, otherwise let mode register
7733
- hangingProtocolService.addProtocol(name, protocol);
7734
- }
7735
- });
7736
- };
7737
- /**
7738
- *
7739
- * @private
7740
- * @param {Object[]} commandDefinitions
7741
- */
7742
- this._initCommandsModule = extensionModule => {
7743
- let {
7744
- definitions,
7745
- defaultContext
7746
- } = extensionModule;
7747
- if (!definitions || Object.keys(definitions).length === 0) {
7748
- src_log.warn('Commands Module contains no command definitions');
7749
- return;
7750
- }
7751
- defaultContext = defaultContext || 'VIEWER';
7752
- if (!this._commandsManager.getContext(defaultContext)) {
7753
- this._commandsManager.createContext(defaultContext);
7754
- }
7755
- Object.keys(definitions).forEach(commandName => {
7756
- const commandDefinition = definitions[commandName];
7757
- const commandHasContextThatDoesNotExist = commandDefinition.context && !this._commandsManager.getContext(commandDefinition.context);
7758
- if (commandHasContextThatDoesNotExist) {
7759
- this._commandsManager.createContext(commandDefinition.context);
7760
- }
7761
- this._commandsManager.registerCommand(commandDefinition.context || defaultContext, commandName, commandDefinition);
7762
- });
7763
- };
7764
- this.modules = {};
7765
- this.registeredExtensionIds = [];
7766
- this.moduleTypeNames = Object.values(MODULE_TYPES);
7767
- //
7768
- this._commandsManager = commandsManager;
7769
- this._servicesManager = servicesManager;
7770
- this._hotkeysManager = hotkeysManager;
7771
- this._appConfig = appConfig;
7772
- this.modulesMap = {};
7773
- this.moduleTypeNames.forEach(moduleType => {
7774
- this.modules[moduleType] = [];
7775
- });
7776
- this._extensionLifeCycleHooks = {
7777
- onModeEnter: {},
7778
- onModeExit: {}
7779
- };
7780
- this.dataSourceMap = {};
7781
- this.dataSourceDefs = {};
7782
- this.defaultDataSourceName = appConfig.defaultDataSourceName;
7783
- this.activeDataSource = undefined;
7784
- }
7785
- setActiveDataSource(dataSourceName) {
7786
- this.activeDataSource = dataSourceName;
7787
- }
7788
-
7789
- /**
7790
- * Calls all the services and extension on mode enters.
7791
- * The service onModeEnter is called first
7792
- * Then registered extensions onModeEnter is called
7793
- * This is supposed to setup the extension for a standard entry.
7794
- */
7795
- onModeEnter() {
7796
- const {
7797
- registeredExtensionIds,
7798
- _servicesManager,
7799
- _commandsManager,
7800
- _hotkeysManager,
7801
- _extensionLifeCycleHooks
7802
- } = this;
7803
-
7804
- // The onModeEnter of the service must occur BEFORE the extension
7805
- // onModeEnter in order to reset the state to a standard state
7806
- // before the extension restores and cached data.
7807
- for (const service of Object.values(_servicesManager.services)) {
7808
- service?.onModeEnter?.();
7809
- }
7810
- registeredExtensionIds.forEach(extensionId => {
7811
- const onModeEnter = _extensionLifeCycleHooks.onModeEnter[extensionId];
7812
- if (typeof onModeEnter === 'function') {
7813
- onModeEnter({
7814
- servicesManager: _servicesManager,
7815
- commandsManager: _commandsManager,
7816
- hotkeysManager: _hotkeysManager
7817
- });
7818
- }
7819
- });
7820
- }
7821
- onModeExit() {
7822
- const {
7823
- registeredExtensionIds,
7824
- _servicesManager,
7825
- _commandsManager,
7826
- _extensionLifeCycleHooks
7827
- } = this;
7828
- registeredExtensionIds.forEach(extensionId => {
7829
- const onModeExit = _extensionLifeCycleHooks.onModeExit[extensionId];
7830
- if (typeof onModeExit === 'function') {
7831
- onModeExit({
7832
- servicesManager: _servicesManager,
7833
- commandsManager: _commandsManager
7834
- });
7835
- }
7836
- });
7837
-
7838
- // The service onModeExit calls must occur after the extension ones
7839
- // so that extension ones can store/restore data.
7840
- for (const service of Object.values(_servicesManager.services)) {
7841
- try {
7842
- service?.onModeExit?.();
7843
- } catch (e) {
7844
- console.warn('onModeExit caught', e);
7845
- }
7846
- }
7847
- }
7848
- _initDataSourcesModule(extensionModule, extensionId) {
7849
- let dataSources = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
7850
- const {
7851
- userAuthenticationService
7852
- } = this._servicesManager.services;
7853
- dataSources.forEach(dataSource => {
7854
- this.dataSourceDefs[dataSource.sourceName] = dataSource;
7855
- });
7856
- extensionModule.forEach(element => {
7857
- const namespace = `${extensionId}.${MODULE_TYPES.DATA_SOURCE}.${element.name}`;
7858
- dataSources.forEach(dataSource => {
7859
- if (dataSource.namespace === namespace) {
7860
- const dataSourceInstance = element.createDataSource(dataSource.configuration, userAuthenticationService);
7861
- if (this.dataSourceMap[dataSource.sourceName]) {
7862
- this.dataSourceMap[dataSource.sourceName].push(dataSourceInstance);
7863
- } else {
7864
- this.dataSourceMap[dataSource.sourceName] = [dataSourceInstance];
7865
- }
7866
- }
7867
- });
7868
- });
7869
- extensionModule.forEach(element => {
7870
- this.modulesMap[`${extensionId}.${MODULE_TYPES.DATA_SOURCE}.${element.name}`] = element;
7871
- });
7872
- }
7873
- }
7874
-
7875
- /**
7876
- * @private
7877
- * @param {string} lower
7878
- */
7879
- function _capitalizeFirstCharacter(lower) {
7880
- return lower.charAt(0).toUpperCase() + lower.substring(1);
7881
- }
7882
- ;// CONCATENATED MODULE: ../../core/src/extensions/index.js
7883
-
7884
-
7885
- const DEFAULT_EXPORTS = {
7886
- ExtensionManager: ExtensionManager,
7887
- MODULE_TYPES: MODULE_TYPES
7888
- };
7889
- /* harmony default export */ const extensions = ((/* unused pure expression or super */ null && (DEFAULT_EXPORTS)));
7890
-
7891
7610
  // EXTERNAL MODULE: ../../core/src/utils/guid.js
7892
7611
  var guid = __webpack_require__(33464);
7893
7612
  ;// CONCATENATED MODULE: ../../core/src/services/_shared/pubSubServiceInterface.js
@@ -14516,6 +14235,450 @@ PanelService.REGISTRATION = {
14516
14235
 
14517
14236
 
14518
14237
 
14238
+ ;// CONCATENATED MODULE: ../../core/src/extensions/ExtensionManager.ts
14239
+
14240
+
14241
+
14242
+
14243
+ /**
14244
+ * This is the arguments given to create the extension.
14245
+ */
14246
+
14247
+ /**
14248
+ * The configuration of an extension.
14249
+ * This uses type as the extension manager only knows that the configuration
14250
+ * is an object of some sort, and doesn't know anything else about it.
14251
+ */
14252
+
14253
+ /**
14254
+ * The parameters passed to the extension.
14255
+ */
14256
+
14257
+ /**
14258
+ * The type of an actual extension instance.
14259
+ * This is an interface as it declares possible calls, but extensions can
14260
+ * have more values than this.
14261
+ */
14262
+
14263
+ class ExtensionManager extends PubSubService {
14264
+ constructor(_ref) {
14265
+ var _this;
14266
+ let {
14267
+ commandsManager,
14268
+ servicesManager,
14269
+ hotkeysManager,
14270
+ appConfig = {}
14271
+ } = _ref;
14272
+ super(ExtensionManager.EVENTS);
14273
+ _this = this;
14274
+ this._commandsManager = void 0;
14275
+ this._servicesManager = void 0;
14276
+ this._hotkeysManager = void 0;
14277
+ /**
14278
+ * An array of extensions, or an array of arrays that contains extension
14279
+ * configuration pairs.
14280
+ *
14281
+ * @param {Object[]} extensions - Array of extensions
14282
+ */
14283
+ this.registerExtensions = async function (extensions) {
14284
+ let dataSources = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
14285
+ // Todo: we ideally should be able to run registrations in parallel
14286
+ // but currently since some extensions need to be registered before
14287
+ // others, we need to run them sequentially. We need a postInit hook
14288
+ // to avoid this sequential async registration
14289
+ for (let i = 0; i < extensions.length; i++) {
14290
+ const extension = extensions[i];
14291
+ const hasConfiguration = Array.isArray(extension);
14292
+ try {
14293
+ if (hasConfiguration) {
14294
+ // Important: for some reason in the line below the type
14295
+ // of extension is not recognized as [ExtensionRegister,
14296
+ // ExtensionConfiguration] by babel DON"T CHANGE IT
14297
+ // Same for the for loop above don't use
14298
+ // for (const extension of extensions)
14299
+ const ohifExtension = extension[0];
14300
+ const configuration = extension[1];
14301
+ await _this.registerExtension(ohifExtension, configuration, dataSources);
14302
+ } else {
14303
+ await _this.registerExtension(extension, {}, dataSources);
14304
+ }
14305
+ } catch (error) {
14306
+ console.error(error);
14307
+ }
14308
+ }
14309
+ };
14310
+ /**
14311
+ *
14312
+ * TODO: Id Management: SopClassHandlers currently refer to viewport module by id; setting the extension id as viewport module id is a workaround for now
14313
+ * @param {Object} extension
14314
+ * @param {Object} configuration
14315
+ */
14316
+ this.registerExtension = async function (extension) {
14317
+ let configuration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
14318
+ let dataSources = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
14319
+ if (!extension) {
14320
+ throw new Error('Attempting to register a null/undefined extension.');
14321
+ }
14322
+ const extensionId = extension.id;
14323
+ if (!extensionId) {
14324
+ // Note: Mode framework cannot function without IDs.
14325
+ src_log.warn(extension);
14326
+ throw new Error(`Extension ID not set`);
14327
+ }
14328
+ if (_this.registeredExtensionIds.includes(extensionId)) {
14329
+ src_log.warn(`Extension ID ${extensionId} has already been registered. Exiting before duplicating modules.`);
14330
+ return;
14331
+ }
14332
+
14333
+ // preRegistrationHook
14334
+ if (extension.preRegistration) {
14335
+ await extension.preRegistration({
14336
+ servicesManager: _this._servicesManager,
14337
+ commandsManager: _this._commandsManager,
14338
+ hotkeysManager: _this._hotkeysManager,
14339
+ extensionManager: _this,
14340
+ appConfig: _this._appConfig,
14341
+ configuration
14342
+ });
14343
+ }
14344
+ if (extension.onModeEnter) {
14345
+ _this._extensionLifeCycleHooks.onModeEnter[extensionId] = extension.onModeEnter;
14346
+ }
14347
+ if (extension.onModeExit) {
14348
+ _this._extensionLifeCycleHooks.onModeExit[extensionId] = extension.onModeExit;
14349
+ }
14350
+
14351
+ // Register Modules
14352
+ _this.moduleTypeNames.forEach(moduleType => {
14353
+ const extensionModule = _this._getExtensionModule(moduleType, extension, extensionId, configuration);
14354
+ if (extensionModule) {
14355
+ switch (moduleType) {
14356
+ case MODULE_TYPES.COMMANDS:
14357
+ _this._initCommandsModule(extensionModule);
14358
+ break;
14359
+ case MODULE_TYPES.DATA_SOURCE:
14360
+ _this._initDataSourcesModule(extensionModule, extensionId, dataSources);
14361
+ break;
14362
+ case MODULE_TYPES.HANGING_PROTOCOL:
14363
+ _this._initHangingProtocolsModule(extensionModule, extensionId);
14364
+ case MODULE_TYPES.TOOLBAR:
14365
+ case MODULE_TYPES.VIEWPORT:
14366
+ case MODULE_TYPES.PANEL:
14367
+ case MODULE_TYPES.SOP_CLASS_HANDLER:
14368
+ case MODULE_TYPES.CONTEXT:
14369
+ case MODULE_TYPES.LAYOUT_TEMPLATE:
14370
+ case MODULE_TYPES.CUSTOMIZATION:
14371
+ case MODULE_TYPES.STATE_SYNC:
14372
+ case MODULE_TYPES.UTILITY:
14373
+ // Default for most extension points,
14374
+ // Just adds each entry ready for consumption by mode.
14375
+ extensionModule.forEach(element => {
14376
+ if (!element.name) {
14377
+ throw new Error(`Extension ID ${extensionId} module ${moduleType} element has no name`);
14378
+ }
14379
+ const id = `${extensionId}.${moduleType}.${element.name}`;
14380
+ element.id = id;
14381
+ _this.modulesMap[id] = element;
14382
+ });
14383
+ break;
14384
+ default:
14385
+ throw new Error(`Module type invalid: ${moduleType}`);
14386
+ }
14387
+ _this.modules[moduleType].push({
14388
+ extensionId,
14389
+ module: extensionModule
14390
+ });
14391
+ }
14392
+ });
14393
+
14394
+ // Track extension registration
14395
+ _this.registeredExtensionIds.push(extensionId);
14396
+ };
14397
+ this.getModuleEntry = stringEntry => {
14398
+ return this.modulesMap[stringEntry];
14399
+ };
14400
+ this.getDataSources = dataSourceName => {
14401
+ if (dataSourceName === undefined) {
14402
+ // Default to the activeDataSource
14403
+ dataSourceName = this.activeDataSource;
14404
+ }
14405
+
14406
+ // Note: this currently uses the data source name, which feels weird...
14407
+ return this.dataSourceMap[dataSourceName];
14408
+ };
14409
+ this.getActiveDataSource = () => {
14410
+ return this.dataSourceMap[this.activeDataSource];
14411
+ };
14412
+ /**
14413
+ * Gets the data source definition for the given data source name.
14414
+ * If no data source name is provided, the active data source definition is
14415
+ * returned.
14416
+ * @param dataSourceName the data source name
14417
+ * @returns the data source definition
14418
+ */
14419
+ this.getDataSourceDef = dataSourceName => {
14420
+ if (dataSourceName === undefined) {
14421
+ // Default to the activeDataSource
14422
+ dataSourceName = this.activeDataSource;
14423
+ }
14424
+ return this.dataSourceDefs[dataSourceName];
14425
+ };
14426
+ /**
14427
+ * @private
14428
+ * @param {string} moduleType
14429
+ * @param {Object} extension
14430
+ * @param {string} extensionId - Used for logging warnings
14431
+ */
14432
+ this._getExtensionModule = (moduleType, extension, extensionId, configuration) => {
14433
+ const getModuleFnName = 'get' + _capitalizeFirstCharacter(moduleType);
14434
+ const getModuleFn = extension[getModuleFnName];
14435
+ if (!getModuleFn) {
14436
+ return;
14437
+ }
14438
+ try {
14439
+ const extensionModule = extension[getModuleFnName]({
14440
+ appConfig: this._appConfig,
14441
+ commandsManager: this._commandsManager,
14442
+ servicesManager: this._servicesManager,
14443
+ hotkeysManager: this._hotkeysManager,
14444
+ extensionManager: this,
14445
+ configuration
14446
+ });
14447
+ if (!extensionModule) {
14448
+ src_log.warn(`Null or undefined returned when registering the ${getModuleFnName} module for the ${extensionId} extension`);
14449
+ }
14450
+ return extensionModule;
14451
+ } catch (ex) {
14452
+ console.log(ex);
14453
+ throw new Error(`Exception thrown while trying to call ${getModuleFnName} for the ${extensionId} extension`);
14454
+ }
14455
+ };
14456
+ this._initHangingProtocolsModule = (extensionModule, extensionId) => {
14457
+ const {
14458
+ hangingProtocolService
14459
+ } = this._servicesManager.services;
14460
+ extensionModule.forEach(_ref2 => {
14461
+ let {
14462
+ name,
14463
+ protocol
14464
+ } = _ref2;
14465
+ if (protocol) {
14466
+ // Only auto-register if protocol specified, otherwise let mode register
14467
+ hangingProtocolService.addProtocol(name, protocol);
14468
+ }
14469
+ });
14470
+ };
14471
+ /**
14472
+ *
14473
+ * @private
14474
+ * @param {Object[]} commandDefinitions
14475
+ */
14476
+ this._initCommandsModule = extensionModule => {
14477
+ let {
14478
+ definitions,
14479
+ defaultContext
14480
+ } = extensionModule;
14481
+ if (!definitions || Object.keys(definitions).length === 0) {
14482
+ src_log.warn('Commands Module contains no command definitions');
14483
+ return;
14484
+ }
14485
+ defaultContext = defaultContext || 'VIEWER';
14486
+ if (!this._commandsManager.getContext(defaultContext)) {
14487
+ this._commandsManager.createContext(defaultContext);
14488
+ }
14489
+ Object.keys(definitions).forEach(commandName => {
14490
+ const commandDefinition = definitions[commandName];
14491
+ const commandHasContextThatDoesNotExist = commandDefinition.context && !this._commandsManager.getContext(commandDefinition.context);
14492
+ if (commandHasContextThatDoesNotExist) {
14493
+ this._commandsManager.createContext(commandDefinition.context);
14494
+ }
14495
+ this._commandsManager.registerCommand(commandDefinition.context || defaultContext, commandName, commandDefinition);
14496
+ });
14497
+ };
14498
+ this.modules = {};
14499
+ this.registeredExtensionIds = [];
14500
+ this.moduleTypeNames = Object.values(MODULE_TYPES);
14501
+ //
14502
+ this._commandsManager = commandsManager;
14503
+ this._servicesManager = servicesManager;
14504
+ this._hotkeysManager = hotkeysManager;
14505
+ this._appConfig = appConfig;
14506
+ this.modulesMap = {};
14507
+ this.moduleTypeNames.forEach(moduleType => {
14508
+ this.modules[moduleType] = [];
14509
+ });
14510
+ this._extensionLifeCycleHooks = {
14511
+ onModeEnter: {},
14512
+ onModeExit: {}
14513
+ };
14514
+ this.dataSourceMap = {};
14515
+ this.dataSourceDefs = {};
14516
+ this.defaultDataSourceName = appConfig.defaultDataSourceName;
14517
+ this.activeDataSource = appConfig.defaultDataSourceName;
14518
+ }
14519
+ setActiveDataSource(dataSource) {
14520
+ if (this.activeDataSource === dataSource) {
14521
+ return;
14522
+ }
14523
+ this.activeDataSource = dataSource;
14524
+ this._broadcastEvent(ExtensionManager.EVENTS.ACTIVE_DATA_SOURCE_CHANGED, this.dataSourceDefs[this.activeDataSource]);
14525
+ }
14526
+
14527
+ /**
14528
+ * Calls all the services and extension on mode enters.
14529
+ * The service onModeEnter is called first
14530
+ * Then registered extensions onModeEnter is called
14531
+ * This is supposed to setup the extension for a standard entry.
14532
+ */
14533
+ onModeEnter() {
14534
+ const {
14535
+ registeredExtensionIds,
14536
+ _servicesManager,
14537
+ _commandsManager,
14538
+ _hotkeysManager,
14539
+ _extensionLifeCycleHooks
14540
+ } = this;
14541
+
14542
+ // The onModeEnter of the service must occur BEFORE the extension
14543
+ // onModeEnter in order to reset the state to a standard state
14544
+ // before the extension restores and cached data.
14545
+ for (const service of Object.values(_servicesManager.services)) {
14546
+ service?.onModeEnter?.();
14547
+ }
14548
+ registeredExtensionIds.forEach(extensionId => {
14549
+ const onModeEnter = _extensionLifeCycleHooks.onModeEnter[extensionId];
14550
+ if (typeof onModeEnter === 'function') {
14551
+ onModeEnter({
14552
+ servicesManager: _servicesManager,
14553
+ commandsManager: _commandsManager,
14554
+ hotkeysManager: _hotkeysManager
14555
+ });
14556
+ }
14557
+ });
14558
+ }
14559
+ onModeExit() {
14560
+ const {
14561
+ registeredExtensionIds,
14562
+ _servicesManager,
14563
+ _commandsManager,
14564
+ _extensionLifeCycleHooks
14565
+ } = this;
14566
+ registeredExtensionIds.forEach(extensionId => {
14567
+ const onModeExit = _extensionLifeCycleHooks.onModeExit[extensionId];
14568
+ if (typeof onModeExit === 'function') {
14569
+ onModeExit({
14570
+ servicesManager: _servicesManager,
14571
+ commandsManager: _commandsManager
14572
+ });
14573
+ }
14574
+ });
14575
+
14576
+ // The service onModeExit calls must occur after the extension ones
14577
+ // so that extension ones can store/restore data.
14578
+ for (const service of Object.values(_servicesManager.services)) {
14579
+ try {
14580
+ service?.onModeExit?.();
14581
+ } catch (e) {
14582
+ console.warn('onModeExit caught', e);
14583
+ }
14584
+ }
14585
+ }
14586
+ /**
14587
+ * Adds the given data source and optionally sets it as the active data source.
14588
+ * The method does this by first creating the data source.
14589
+ * @param dataSourceDef the data source definition to be added
14590
+ * @param activate flag to indicate if the added data source should be set to the active data source
14591
+ */
14592
+ addDataSource(dataSourceDef) {
14593
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
14594
+ activate: false
14595
+ };
14596
+ const existingDataSource = this.getDataSources(dataSourceDef.sourceName);
14597
+ if (existingDataSource?.[0]) {
14598
+ // The data source already exists and cannot be added.
14599
+ return;
14600
+ }
14601
+ this._createDataSourceInstance(dataSourceDef);
14602
+ if (options.activate) {
14603
+ this.setActiveDataSource(dataSourceDef.sourceName);
14604
+ }
14605
+ }
14606
+
14607
+ /**
14608
+ * Updates the configuration of the given data source name. It first creates a new data source with
14609
+ * the existing definition and the new configuration passed in.
14610
+ * @param dataSourceName the name of the data source to update
14611
+ * @param dataSourceConfiguration the new configuration to update the data source with
14612
+ */
14613
+ updateDataSourceConfiguration(dataSourceName, dataSourceConfiguration) {
14614
+ const existingDataSource = this.getDataSources(dataSourceName);
14615
+ if (!existingDataSource?.[0]) {
14616
+ // Cannot update a non existent data source.
14617
+ return;
14618
+ }
14619
+ const dataSourceDef = this.dataSourceDefs[dataSourceName];
14620
+ // Update the configuration.
14621
+ dataSourceDef.configuration = dataSourceConfiguration;
14622
+ this._createDataSourceInstance(dataSourceDef);
14623
+ if (this.activeDataSource === dataSourceName) {
14624
+ // When the active data source is changed/set, fire an event to indicate that its configuration has changed.
14625
+ this._broadcastEvent(ExtensionManager.EVENTS.ACTIVE_DATA_SOURCE_CHANGED, dataSourceDef);
14626
+ }
14627
+ }
14628
+
14629
+ /**
14630
+ * Creates a data source instance from the given definition. The definition is
14631
+ * added to dataSourceDefs and the created instance is added to dataSourceMap.
14632
+ * @param dataSourceDef
14633
+ * @returns
14634
+ */
14635
+ _createDataSourceInstance(dataSourceDef) {
14636
+ const module = this.getModuleEntry(dataSourceDef.namespace);
14637
+ if (!module) {
14638
+ return;
14639
+ }
14640
+ this.dataSourceDefs[dataSourceDef.sourceName] = dataSourceDef;
14641
+ const {
14642
+ userAuthenticationService
14643
+ } = this._servicesManager.services;
14644
+ const dataSourceInstance = module.createDataSource(dataSourceDef.configuration, userAuthenticationService);
14645
+ this.dataSourceMap[dataSourceDef.sourceName] = [dataSourceInstance];
14646
+ }
14647
+ _initDataSourcesModule(extensionModule, extensionId) {
14648
+ let dataSources = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
14649
+ extensionModule.forEach(element => {
14650
+ this.modulesMap[`${extensionId}.${MODULE_TYPES.DATA_SOURCE}.${element.name}`] = element;
14651
+ });
14652
+ extensionModule.forEach(element => {
14653
+ const namespace = `${extensionId}.${MODULE_TYPES.DATA_SOURCE}.${element.name}`;
14654
+ dataSources.forEach(dataSource => {
14655
+ if (dataSource.namespace === namespace) {
14656
+ this.addDataSource(dataSource);
14657
+ }
14658
+ });
14659
+ });
14660
+ }
14661
+ }
14662
+
14663
+ /**
14664
+ * @private
14665
+ * @param {string} lower
14666
+ */
14667
+ ExtensionManager.EVENTS = {
14668
+ ACTIVE_DATA_SOURCE_CHANGED: 'event::activedatasourcechanged'
14669
+ };
14670
+ function _capitalizeFirstCharacter(lower) {
14671
+ return lower.charAt(0).toUpperCase() + lower.substring(1);
14672
+ }
14673
+ ;// CONCATENATED MODULE: ../../core/src/extensions/index.js
14674
+
14675
+
14676
+ const DEFAULT_EXPORTS = {
14677
+ ExtensionManager: ExtensionManager,
14678
+ MODULE_TYPES: MODULE_TYPES
14679
+ };
14680
+ /* harmony default export */ const extensions = ((/* unused pure expression or super */ null && (DEFAULT_EXPORTS)));
14681
+
14519
14682
  ;// CONCATENATED MODULE: ../../core/src/classes/CommandsManager.ts
14520
14683
 
14521
14684
  /**
@@ -16264,6 +16427,9 @@ const bindings = [{
16264
16427
 
16265
16428
  // EXTERNAL MODULE: ../../core/src/classes/Hotkey.ts
16266
16429
  var Hotkey = __webpack_require__(57374);
16430
+ ;// CONCATENATED MODULE: ../../core/src/types/DataSource.ts
16431
+
16432
+
16267
16433
  ;// CONCATENATED MODULE: ../../core/src/services/CustomizationService/types.ts
16268
16434
 
16269
16435
 
@@ -16294,6 +16460,7 @@ var IPubSub = __webpack_require__(98844);
16294
16460
 
16295
16461
 
16296
16462
 
16463
+
16297
16464
  // Separate out some generic types
16298
16465
 
16299
16466
 
@@ -16331,7 +16498,8 @@ function create(_ref) {
16331
16498
  deleteStudyMetadataPromise,
16332
16499
  getImageIdsForDisplaySet,
16333
16500
  getImageIdsForInstance,
16334
- getConfig
16501
+ getConfig,
16502
+ getStudyInstanceUIDs
16335
16503
  } = _ref;
16336
16504
  const defaultQuery = {
16337
16505
  studies: {
@@ -16377,7 +16545,8 @@ function create(_ref) {
16377
16545
  deleteStudyMetadataPromise,
16378
16546
  getImageIdsForDisplaySet,
16379
16547
  getImageIdsForInstance,
16380
- getConfig: getConfig || defaultGetConfig
16548
+ getConfig: getConfig || defaultGetConfig,
16549
+ getStudyInstanceUIDs: getStudyInstanceUIDs
16381
16550
  };
16382
16551
  }
16383
16552
  const IWebApiDataSource = {
@@ -20375,7 +20544,7 @@ const detectionOptions = {
20375
20544
  }
20376
20545
  });
20377
20546
  ;// CONCATENATED MODULE: ../../i18n/package.json
20378
- const package_namespaceObject = JSON.parse('{"i8":"3.7.0-beta.32"}');
20547
+ const package_namespaceObject = JSON.parse('{"i8":"3.7.0-beta.35"}');
20379
20548
  ;// CONCATENATED MODULE: ../../i18n/src/utils.js
20380
20549
  const languagesMap = {
20381
20550
  ar: 'Arabic',
@@ -31266,8 +31435,8 @@ ViewportDialogProvider.propTypes = {
31266
31435
  // EXTERNAL MODULE: ../../../node_modules/lodash.isequal/index.js
31267
31436
  var lodash_isequal = __webpack_require__(68652);
31268
31437
  var lodash_isequal_default = /*#__PURE__*/__webpack_require__.n(lodash_isequal);
31269
- // EXTERNAL MODULE: ../../core/src/index.ts + 102 modules
31270
- var src = __webpack_require__(62771);
31438
+ // EXTERNAL MODULE: ../../core/src/index.ts + 103 modules
31439
+ var src = __webpack_require__(87754);
31271
31440
  ;// CONCATENATED MODULE: ../../ui/src/utils/viewportLabels.ts
31272
31441
  const viewportLabels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
31273
31442
  /* harmony default export */ const utils_viewportLabels = (viewportLabels);
@@ -33260,6 +33429,7 @@ const Footer = _ref => {
33260
33429
  });
33261
33430
  return /*#__PURE__*/react.createElement(components_Button, {
33262
33431
  key: index,
33432
+ name: action.text,
33263
33433
  className: classnames_default()({
33264
33434
  'ml-2': !isFirst
33265
33435
  }, action.classes),
@@ -57220,7 +57390,8 @@ StudyListTableRow.propTypes = {
57220
57390
 
57221
57391
  const StudyListTable_StudyListTable = _ref => {
57222
57392
  let {
57223
- tableDataSource
57393
+ tableDataSource,
57394
+ querying
57224
57395
  } = _ref;
57225
57396
  return /*#__PURE__*/react.createElement("div", {
57226
57397
  className: "bg-black"
@@ -57229,7 +57400,8 @@ const StudyListTable_StudyListTable = _ref => {
57229
57400
  }, /*#__PURE__*/react.createElement("table", {
57230
57401
  className: "w-full text-white"
57231
57402
  }, /*#__PURE__*/react.createElement("tbody", {
57232
- "data-cy": "study-list-results"
57403
+ "data-cy": "study-list-results",
57404
+ "data-querying": querying
57233
57405
  }, tableDataSource.map((tableData, i) => {
57234
57406
  return /*#__PURE__*/react.createElement(StudyListTable_StudyListTableRow, {
57235
57407
  tableData: tableData,
@@ -57241,6 +57413,7 @@ StudyListTable_StudyListTable.propTypes = {
57241
57413
  tableDataSource: prop_types_default().arrayOf(prop_types_default().shape({
57242
57414
  row: (prop_types_default()).array.isRequired,
57243
57415
  expandedContent: (prop_types_default()).node.isRequired,
57416
+ querying: (prop_types_default()).bool,
57244
57417
  onClickRow: (prop_types_default()).func.isRequired,
57245
57418
  isExpanded: (prop_types_default()).bool.isRequired
57246
57419
  }))
@@ -148569,7 +148742,6 @@ module.exports = warning;
148569
148742
  "use strict";
148570
148743
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
148571
148744
  /* harmony export */ AW: () => (/* reexport safe */ react_router__WEBPACK_IMPORTED_MODULE_1__.AW),
148572
- /* harmony export */ TH: () => (/* reexport safe */ react_router__WEBPACK_IMPORTED_MODULE_1__.TH),
148573
148745
  /* harmony export */ VK: () => (/* binding */ BrowserRouter),
148574
148746
  /* harmony export */ Z5: () => (/* reexport safe */ react_router__WEBPACK_IMPORTED_MODULE_1__.Z5),
148575
148747
  /* harmony export */ rU: () => (/* binding */ Link),
@@ -154443,7 +154615,7 @@ var selectOrdinal = function selectOrdinal() {
154443
154615
  /******/ // This function allow to reference async chunks
154444
154616
  /******/ __webpack_require__.u = (chunkId) => {
154445
154617
  /******/ // return url for filenames based on template
154446
- /******/ return "" + (chunkId === 18 ? "dicom-microscopy-viewer" : chunkId) + ".bundle." + {"18":"aa60bdf008c32c39cfd7","50":"c11736e7c4a5b65f67e6","55":"3fdadd0823a136eb4585","82":"3328dd25b6fd1c1c43f6","151":"31ea35044218837bf73f","192":"6290fb2377d6a0ea268d","199":"4fb8686e11821dae0c90","205":"b5a473c200dcf2bbcdb4","208":"fe1e91f0acf3742925f9","270":"49a50e13715da82c083f","283":"f82d3dc59066b118cf27","295":"957b1159fec14b9199a1","331":"6d141ff13ae957b1db6f","351":"444e1c32785871760302","381":"0905e683605fcbc0895f","404":"7b7f4990f9762c2c24ed","531":"2a82fb1d69e5b57cc72b","569":"ee136cf6526a6380633c","581":"ab8d1f1e75de3c98dd10","606":"5d876f5f3dd8287f0a28","616":"a18d837e98dc2fad072c","625":"e80ea79cda37ee4b6263","642":"23c1d28e6689362f106f","664":"09abae984223969d1bde","728":"38ad0fbfcf6cfd8f9e9e","744":"fd4eae46f382b3e1d496","780":"fd0f13dc92e9caa0581e","790":"ebfacd71c3af955a92b3","799":"620e1df13daf7b31cb3f","806":"2e7934d0833c4315c292","917":"cb498f4f4d85e0248a14","926":"dbc9d0e591cb9217fda2","935":"deeffff0e4f7b528e3c3","953":"4b8fee7d9484456a99b5","973":"62c5bba110e379cef75e","976":"b61d2e7e5ed3bc534c2c","984":"5e08be248b0bced4e89b"}[chunkId] + ".js";
154618
+ /******/ return "" + (chunkId === 18 ? "dicom-microscopy-viewer" : chunkId) + ".bundle." + {"18":"aa60bdf008c32c39cfd7","50":"260f830a3870cae30cf5","55":"fe53f3784bfe7db4a5a5","82":"11e08acaf3e1f527278d","151":"31ea35044218837bf73f","192":"160fffd248385d501d87","199":"fe8e31ccab2445a9721d","205":"b5a473c200dcf2bbcdb4","208":"ee392e7c48237252ea8e","270":"2d215f8720350f03e171","283":"b19d7099a6fb8c957fb1","295":"957b1159fec14b9199a1","351":"2e949640c417cd735688","381":"0905e683605fcbc0895f","389":"38df7e54d2f632cfa7a0","404":"051cd13557d04cc76630","531":"2a82fb1d69e5b57cc72b","569":"e77c17d37a65e5dedfed","581":"15078e71fe52b53f48b3","606":"5d876f5f3dd8287f0a28","616":"fc1820b3d98da340218c","625":"7de4074e256c743ca500","642":"f03da99e63dbfdc1cf1c","664":"09abae984223969d1bde","728":"5bef7c8643b42d70a79f","744":"08e4a5bbc4fd371a50b3","780":"fd0f13dc92e9caa0581e","790":"6fa09929a3203bcf3f2c","799":"d8e50f1fd6bf4fa3a5e1","806":"2e7934d0833c4315c292","917":"e0647888c6fff8e72e95","926":"dbc9d0e591cb9217fda2","935":"deeffff0e4f7b528e3c3","953":"95b0621f1da8dfeaed8a","973":"634f585248ead3160ff2","976":"9dec94108550ad448773","984":"1149cce5c5ecb63e76a9"}[chunkId] + ".js";
154447
154619
  /******/ };
154448
154620
  /******/ })();
154449
154621
  /******/