nuxt-cornerstone 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +933 -0
  3. package/dist/module.d.mts +22 -0
  4. package/dist/module.json +12 -0
  5. package/dist/module.mjs +168 -0
  6. package/dist/runtime/annotation-json.d.ts +76 -0
  7. package/dist/runtime/annotation-json.js +176 -0
  8. package/dist/runtime/components/CornerstoneViewport.d.vue.ts +57 -0
  9. package/dist/runtime/components/CornerstoneViewport.vue +227 -0
  10. package/dist/runtime/components/CornerstoneViewport.vue.d.ts +57 -0
  11. package/dist/runtime/composables/useAnnotationReport.d.ts +28 -0
  12. package/dist/runtime/composables/useAnnotationReport.js +66 -0
  13. package/dist/runtime/composables/useCinePlayer.d.ts +52 -0
  14. package/dist/runtime/composables/useCinePlayer.js +95 -0
  15. package/dist/runtime/composables/useCornerstone.d.ts +17 -0
  16. package/dist/runtime/composables/useCornerstone.js +30 -0
  17. package/dist/runtime/composables/useCornerstoneI18n.d.ts +24 -0
  18. package/dist/runtime/composables/useCornerstoneI18n.js +32 -0
  19. package/dist/runtime/composables/useCornerstoneTools.d.ts +21 -0
  20. package/dist/runtime/composables/useCornerstoneTools.js +105 -0
  21. package/dist/runtime/composables/useDicomAnnotations.d.ts +76 -0
  22. package/dist/runtime/composables/useDicomAnnotations.js +220 -0
  23. package/dist/runtime/composables/useDicomFiles.d.ts +87 -0
  24. package/dist/runtime/composables/useDicomFiles.js +234 -0
  25. package/dist/runtime/composables/useDicomGuard.d.ts +24 -0
  26. package/dist/runtime/composables/useDicomGuard.js +30 -0
  27. package/dist/runtime/composables/useDicomStudy.d.ts +122 -0
  28. package/dist/runtime/composables/useDicomStudy.js +222 -0
  29. package/dist/runtime/composables/useImagePrefetch.d.ts +78 -0
  30. package/dist/runtime/composables/useImagePrefetch.js +119 -0
  31. package/dist/runtime/composables/useMeasurements.d.ts +51 -0
  32. package/dist/runtime/composables/useMeasurements.js +138 -0
  33. package/dist/runtime/composables/useRenderingEngine.d.ts +6 -0
  34. package/dist/runtime/composables/useRenderingEngine.js +46 -0
  35. package/dist/runtime/composables/useStackCine.d.ts +50 -0
  36. package/dist/runtime/composables/useStackCine.js +62 -0
  37. package/dist/runtime/composables/useViewerShortcuts.d.ts +94 -0
  38. package/dist/runtime/composables/useViewerShortcuts.js +115 -0
  39. package/dist/runtime/cornerstone.d.ts +21 -0
  40. package/dist/runtime/cornerstone.js +100 -0
  41. package/dist/runtime/dicom-instances.d.ts +32 -0
  42. package/dist/runtime/dicom-instances.js +15 -0
  43. package/dist/runtime/dicom-zip.d.ts +95 -0
  44. package/dist/runtime/dicom-zip.js +149 -0
  45. package/dist/runtime/i18n/detect.d.ts +37 -0
  46. package/dist/runtime/i18n/detect.js +37 -0
  47. package/dist/runtime/i18n/index.d.ts +61 -0
  48. package/dist/runtime/i18n/index.js +145 -0
  49. package/dist/runtime/i18n/messages.d.ts +122 -0
  50. package/dist/runtime/i18n/messages.js +147 -0
  51. package/dist/runtime/plugin.client.d.ts +13 -0
  52. package/dist/runtime/plugin.client.js +31 -0
  53. package/dist/runtime/plugin.i18n.d.ts +12 -0
  54. package/dist/runtime/plugin.i18n.js +15 -0
  55. package/dist/runtime/types.d.ts +150 -0
  56. package/dist/runtime/types.js +10 -0
  57. package/dist/types.d.mts +29 -0
  58. package/package.json +76 -0
@@ -0,0 +1,145 @@
1
+ import { ref } from "vue";
2
+ import { BUILTIN_MESSAGES } from "./messages.js";
3
+ export { BUILTIN_MESSAGES, en, fa } from "./messages.js";
4
+ export const DEFAULT_LOCALE = "en";
5
+ const RTL_LANGUAGES = /* @__PURE__ */ new Set([
6
+ "ar",
7
+ "ckb",
8
+ "dv",
9
+ "fa",
10
+ "he",
11
+ "ku",
12
+ "ps",
13
+ "sd",
14
+ "syr",
15
+ "ug",
16
+ "ur",
17
+ "yi"
18
+ ]);
19
+ const hot = import.meta.hot;
20
+ const state = hot ? hot.data.cornerstoneI18n ??= {} : {};
21
+ state.locale ??= ref(DEFAULT_LOCALE);
22
+ state.fallbackLocale ??= DEFAULT_LOCALE;
23
+ state.enabled ??= true;
24
+ state.numberingSystem ??= "auto";
25
+ state.catalogs ??= cloneCatalogs(BUILTIN_MESSAGES);
26
+ state.translator ??= null;
27
+ function cloneCatalogs(source) {
28
+ const out = {};
29
+ for (const [locale, catalog] of Object.entries(source)) out[locale] = { ...catalog };
30
+ return out;
31
+ }
32
+ export function configureI18n(options) {
33
+ if (options === false) {
34
+ state.enabled = false;
35
+ state.locale.value = DEFAULT_LOCALE;
36
+ return;
37
+ }
38
+ if (!options) return;
39
+ state.enabled = true;
40
+ if (options.messages) {
41
+ for (const [locale, catalog] of Object.entries(options.messages)) {
42
+ if (!catalog) continue;
43
+ state.catalogs[locale] = { ...state.catalogs[locale], ...catalog };
44
+ }
45
+ }
46
+ if (options.fallbackLocale) state.fallbackLocale = options.fallbackLocale;
47
+ if (options.numberingSystem) state.numberingSystem = options.numberingSystem;
48
+ if (options.locale) state.locale.value = options.locale;
49
+ }
50
+ export function getCornerstoneLocale() {
51
+ return state.locale.value;
52
+ }
53
+ export function setCornerstoneLocale(locale) {
54
+ if (!state.enabled) return;
55
+ state.locale.value = locale;
56
+ }
57
+ export function getCornerstoneLocales() {
58
+ return Object.keys(state.catalogs);
59
+ }
60
+ export function hasCornerstoneCatalog(locale) {
61
+ const catalogs = state.catalogs;
62
+ return locale in catalogs || locale.split(/[-_]/)[0] in catalogs;
63
+ }
64
+ export function setCornerstoneTranslator(translator) {
65
+ state.translator = translator;
66
+ }
67
+ export function addCornerstoneMessages(locale, catalog) {
68
+ state.catalogs[locale] = { ...state.catalogs[locale], ...catalog };
69
+ }
70
+ export function isRtlLocale(locale = getCornerstoneLocale()) {
71
+ return RTL_LANGUAGES.has(locale.toLowerCase().split(/[-_]/)[0]);
72
+ }
73
+ export function dirForLocale(locale = getCornerstoneLocale()) {
74
+ return isRtlLocale(locale) ? "rtl" : "ltr";
75
+ }
76
+ export function t(key, params) {
77
+ const locale = getCornerstoneLocale();
78
+ const supplied = state.translator?.(key, params, locale);
79
+ if (typeof supplied === "string") return supplied;
80
+ const value = lookup(key, locale) ?? lookup(key, state.fallbackLocale) ?? lookup(key, DEFAULT_LOCALE);
81
+ if (value === void 0) return key;
82
+ return interpolate(selectPlural(value, params, locale), params, locale);
83
+ }
84
+ function lookup(key, locale) {
85
+ const catalogs = state.catalogs;
86
+ const language = locale.split(/[-_]/)[0];
87
+ return catalogs[locale]?.[key] ?? catalogs[language]?.[key];
88
+ }
89
+ function selectPlural(value, params, locale) {
90
+ if (typeof value === "string") return value;
91
+ const count = params?.count;
92
+ const category = typeof count === "number" ? pluralRules(locale).select(count) : "other";
93
+ return value[category] ?? value.other ?? value.one ?? "";
94
+ }
95
+ function interpolate(template, params, locale) {
96
+ if (!params) return template;
97
+ return template.replace(/\{(\w+)\}/g, (match, name) => {
98
+ const value = params[name];
99
+ if (value === void 0) return match;
100
+ return typeof value === "number" ? formatNumber(value, void 0, locale) : value;
101
+ });
102
+ }
103
+ export function n(value, options) {
104
+ return formatNumber(value, options, getCornerstoneLocale());
105
+ }
106
+ function formatNumber(value, options, locale) {
107
+ return numberFormat(locale, options).format(value);
108
+ }
109
+ const BYTE_UNITS = ["B", "KB", "MB", "GB", "TB"];
110
+ export function formatBytes(bytes) {
111
+ let value = bytes;
112
+ let unit = 0;
113
+ while (value >= 1024 && unit < BYTE_UNITS.length - 1) {
114
+ value /= 1024;
115
+ unit++;
116
+ }
117
+ return t("bytes.value", {
118
+ value: n(value, { maximumFractionDigits: value < 10 && unit > 0 ? 1 : 0 }),
119
+ unit: t(`bytes.unit.${BYTE_UNITS[unit]}`)
120
+ });
121
+ }
122
+ const numberFormats = /* @__PURE__ */ new Map();
123
+ const pluralRulesCache = /* @__PURE__ */ new Map();
124
+ function numberFormat(locale, options) {
125
+ const resolved = withNumberingSystem(locale);
126
+ const key = `${resolved}|${options ? JSON.stringify(options) : ""}`;
127
+ let format = numberFormats.get(key);
128
+ if (!format) {
129
+ format = new Intl.NumberFormat(resolved, options);
130
+ numberFormats.set(key, format);
131
+ }
132
+ return format;
133
+ }
134
+ function pluralRules(locale) {
135
+ let rules = pluralRulesCache.get(locale);
136
+ if (!rules) {
137
+ rules = new Intl.PluralRules(locale);
138
+ pluralRulesCache.set(locale, rules);
139
+ }
140
+ return rules;
141
+ }
142
+ function withNumberingSystem(locale) {
143
+ if (state.numberingSystem !== "latn") return locale;
144
+ return locale.includes("-u-") ? `${locale}-nu-latn` : `${locale}-u-nu-latn`;
145
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Message catalogues for the strings this module produces itself.
3
+ *
4
+ * Both locales are bundled statically rather than imported on demand. They are
5
+ * a few hundred bytes each, and `t()` is called from error paths that are
6
+ * synchronous by nature — `asZipError()` has to return an `Error`, not a
7
+ * promise of one.
8
+ *
9
+ * Keys are flat and dotted. Anything in `{braces}` is interpolated; a numeric
10
+ * parameter is run through the locale's number formatter on the way in, which
11
+ * is what puts Persian-Indic digits into Farsi messages.
12
+ */
13
+ /** CLDR plural categories, as `Intl.PluralRules` selects them. */
14
+ export type PluralCategory = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';
15
+ /**
16
+ * A message is either a plain string, or a set of plural forms chosen by the
17
+ * `count` parameter. Missing categories fall back to `other`, so Farsi — where
18
+ * a counted noun does not inflect — only needs to supply `other`.
19
+ */
20
+ export type MessageValue = string | Partial<Record<PluralCategory, string>>;
21
+ export type MessageCatalog = Record<string, MessageValue>;
22
+ export type MessageParams = Record<string, string | number>;
23
+ /**
24
+ * Identifiers stay in English inside every translation: `cornerstone.autoInit`,
25
+ * `ensureCornerstone()` and `@cornerstonejs/tools` are things the reader has to
26
+ * type or search for, not prose.
27
+ */
28
+ export declare const en: {
29
+ 'error.ssr': string;
30
+ 'error.optionsLocked': string;
31
+ 'error.initFailed': string;
32
+ 'error.toolGroupCreate': string;
33
+ 'error.toolNotInGroup': string;
34
+ 'warn.unknownTool': string;
35
+ 'error.annotationViewport': string;
36
+ 'error.annotationToolGroup': string;
37
+ 'error.annotationTool': string;
38
+ 'annotationJson.notJson': string;
39
+ 'annotationJson.unknownShape': string;
40
+ 'annotationJson.finding': string;
41
+ 'annotationJson.class': string;
42
+ 'annotationJson.labelled': string;
43
+ 'zip.tooLarge': string;
44
+ 'zip.notReadable': string;
45
+ 'zip.readFailed': string;
46
+ 'series.numbered': string;
47
+ 'series.unnamed': string;
48
+ 'series.images': {
49
+ one: string;
50
+ other: string;
51
+ };
52
+ 'series.label': string;
53
+ 'list.separator': string;
54
+ 'bytes.value': string;
55
+ 'bytes.unit.B': string;
56
+ 'bytes.unit.KB': string;
57
+ 'bytes.unit.MB': string;
58
+ 'bytes.unit.GB': string;
59
+ 'bytes.unit.TB': string;
60
+ 'study.progress.reading': string;
61
+ 'study.progress.extracting': string;
62
+ 'study.progress.indexing': string;
63
+ 'study.error.noDicomInZip': string;
64
+ 'study.error.noDicomFiles': {
65
+ one: string;
66
+ other: string;
67
+ };
68
+ 'study.error.noUrls': string;
69
+ 'study.skipped.summary': string;
70
+ 'study.skipped.more': string;
71
+ 'study.skipped.entry': string;
72
+ 'study.skip.metadata': string;
73
+ 'study.skip.notDicomExtension': string;
74
+ 'study.skip.notDicom': string;
75
+ 'study.skip.empty': string;
76
+ 'study.source.files': {
77
+ one: string;
78
+ other: string;
79
+ };
80
+ 'study.source.urls': {
81
+ one: string;
82
+ other: string;
83
+ };
84
+ 'study.source.zip': string;
85
+ 'study.count.series': {
86
+ one: string;
87
+ other: string;
88
+ };
89
+ 'study.count.skipped': {
90
+ one: string;
91
+ other: string;
92
+ };
93
+ 'cine.preparing': string;
94
+ 'cine.prepared': {
95
+ one: string;
96
+ other: string;
97
+ };
98
+ 'cine.preparedWithFailures': {
99
+ one: string;
100
+ other: string;
101
+ };
102
+ 'cine.cacheFull': string;
103
+ 'report.summary': string;
104
+ 'report.waiting': {
105
+ one: string;
106
+ other: string;
107
+ };
108
+ 'report.dropped': {
109
+ one: string;
110
+ other: string;
111
+ };
112
+ 'report.empty': string;
113
+ 'report.unmatched': string;
114
+ 'report.unmatchedNoSeries': string;
115
+ 'report.failed': string;
116
+ };
117
+ export declare const fa: Record<CornerstoneMessageKey, MessageValue>;
118
+ export declare const BUILTIN_MESSAGES: Record<string, MessageCatalog>;
119
+ /** Keys the module itself emits. Extra keys may be added through options. */
120
+ export type CornerstoneMessageKey = keyof typeof en;
121
+ /** A built-in key, or any key an app has registered of its own. */
122
+ export type MessageKey = CornerstoneMessageKey | (string & {});
@@ -0,0 +1,147 @@
1
+ export const en = {
2
+ "error.ssr": "Cornerstone3D is browser-only (WebGL, web workers, WASM) and cannot run during SSR. Call ensureCornerstone() from onMounted, or wrap the caller in <ClientOnly>.",
3
+ "error.optionsLocked": "Cornerstone3D is already initialising; options can no longer be changed. Set `cornerstone.autoInit: false` in nuxt.config and call `ensureCornerstone(options)` from your own plugin.",
4
+ "error.initFailed": "initialisation failed",
5
+ "error.toolGroupCreate": 'could not create tool group "{groupId}".',
6
+ "error.toolNotInGroup": 'tool "{tool}" is not in tool group "{groupId}". Add its class name to `cornerstone.tools.register` in nuxt.config.',
7
+ "warn.unknownTool": '"{tool}" is not an exported tool class of @cornerstonejs/tools; skipping.',
8
+ "error.annotationViewport": "there is no viewport to place annotations on. Wait for the viewport's `ready` event before calling addBoxes().",
9
+ "error.annotationToolGroup": "that viewport is not in a tool group, so annotations would never be drawn. Mount it through <CornerstoneViewport>, or add it with useCornerstoneTools().addViewport().",
10
+ "error.annotationTool": "RectangleROITool is not available from @cornerstonejs/tools, and imported boxes are drawn with it.",
11
+ "annotationJson.notJson": "That file is not valid JSON: {message}",
12
+ "annotationJson.unknownShape": "That JSON is not a recognised annotation file. Expected a list of boxes, each with a `sopInstanceUid` and a `box`, or a report with a `findings` array whose entries carry `slice_findings`.",
13
+ "annotationJson.finding": "Finding {index}",
14
+ "annotationJson.class": "Class {value}",
15
+ "annotationJson.labelled": "{name} \xB7 {confidence}%",
16
+ "zip.tooLarge": "Archive expands to more than {limit} of DICOM data. Extract it and open the series you need, or raise `maxBytes`.",
17
+ "zip.notReadable": "That file is not a readable ZIP archive.",
18
+ "zip.readFailed": "Could not read the ZIP archive: {message}",
19
+ "series.numbered": "Series {number}",
20
+ "series.unnamed": "Unnamed series",
21
+ "series.images": { one: "{count} image", other: "{count} images" },
22
+ "series.label": "{name} ({details})",
23
+ "list.separator": ", ",
24
+ // Byte units come from the catalogue rather than from `Intl`'s unit style:
25
+ // CLDR's short English name for `byte` is "byte", so a 900-byte archive
26
+ // would read "900 byte".
27
+ "bytes.value": "{value} {unit}",
28
+ "bytes.unit.B": "B",
29
+ "bytes.unit.KB": "KB",
30
+ "bytes.unit.MB": "MB",
31
+ "bytes.unit.GB": "GB",
32
+ "bytes.unit.TB": "TB",
33
+ // ---------------------------------------------------------------------
34
+ // useDicomStudy: what was opened, how the opening is going, and what was
35
+ // turned away. Reasons read as a noun phrase so they drop straight into
36
+ // "{name} ({reason})".
37
+ "study.progress.reading": "Reading archive\u2026",
38
+ "study.progress.extracting": "Extracting\u2026",
39
+ "study.progress.indexing": "Reading headers {done} / {total}",
40
+ "study.error.noDicomInZip": "No DICOM images found in {file}.",
41
+ "study.error.noDicomFiles": {
42
+ one: "That file is not DICOM.",
43
+ other: "None of those {count} files is DICOM."
44
+ },
45
+ "study.error.noUrls": "None of those addresses could be read.",
46
+ "study.skipped.summary": "{count}: {named}",
47
+ "study.skipped.more": "{count}: {named}, and {rest} more",
48
+ "study.skipped.entry": "{name} ({reason})",
49
+ "study.skip.metadata": "housekeeping file",
50
+ "study.skip.notDicomExtension": "not a DICOM extension",
51
+ "study.skip.notDicom": "no DICOM header",
52
+ "study.skip.empty": "empty",
53
+ "study.source.files": {
54
+ one: "{count} local file, sorted by InstanceNumber",
55
+ other: "{count} local files, sorted by InstanceNumber"
56
+ },
57
+ "study.source.urls": { one: "{count} image", other: "{count} images" },
58
+ "study.source.zip": "{file} \u2014 {images} in {series}",
59
+ // "Series" is its own plural; a hand-rolled one says "serieses".
60
+ "study.count.series": { one: "{count} series", other: "{count} series" },
61
+ "study.count.skipped": { one: "{count} file skipped", other: "{count} files skipped" },
62
+ // useStackCine: how far decoding the stack ahead of playback has got.
63
+ "cine.preparing": "Preparing\u2026 {percent}%",
64
+ "cine.prepared": { one: "{count} image ready", other: "{count} images ready" },
65
+ "cine.preparedWithFailures": {
66
+ one: "{count} image ready, {failed} could not be decoded",
67
+ other: "{count} images ready, {failed} could not be decoded"
68
+ },
69
+ "cine.cacheFull": "Image cache full at {count} images \u2014 the rest load as you reach them.",
70
+ // useAnnotationReport: what a JSON report placed on the stack on screen.
71
+ "report.summary": "{file}: {placed} of {total} boxes placed.",
72
+ "report.waiting": {
73
+ one: "{count} more appears as you scroll to its slice.",
74
+ other: "{count} more appear as you scroll to their slices."
75
+ },
76
+ "report.dropped": {
77
+ one: "{count} entry could not be read.",
78
+ other: "{count} entries could not be read."
79
+ },
80
+ "report.empty": "{file} lists no annotations.",
81
+ "report.unmatched": "None of the {total} boxes belong to the images on screen \u2014 the report names series {series}. Open that study to see them.",
82
+ "report.unmatchedNoSeries": "None of the {total} boxes belong to the images on screen. They name slices that are not loaded.",
83
+ "report.failed": "Could not read {file}: {message}"
84
+ };
85
+ export const fa = {
86
+ "error.ssr": "Cornerstone3D \u0641\u0642\u0637 \u062F\u0631 \u0645\u0631\u0648\u0631\u06AF\u0631 \u0627\u062C\u0631\u0627 \u0645\u06CC\u200C\u0634\u0648\u062F (WebGL\u060C \u0648\u0628\u200C\u0648\u0631\u06A9\u0631\u060C WASM) \u0648 \u062F\u0631 \u0632\u0645\u0627\u0646 SSR \u0642\u0627\u0628\u0644 \u0627\u0633\u062A\u0641\u0627\u062F\u0647 \u0646\u06CC\u0633\u062A. ensureCornerstone() \u0631\u0627 \u0627\u0632 onMounted \u0641\u0631\u0627\u062E\u0648\u0627\u0646\u06CC \u06A9\u0646\u06CC\u062F\u060C \u06CC\u0627 \u0641\u0631\u0627\u062E\u0648\u0627\u0646 \u0631\u0627 \u062F\u0627\u062E\u0644 <ClientOnly> \u0628\u06AF\u0630\u0627\u0631\u06CC\u062F.",
87
+ "error.optionsLocked": "Cornerstone3D \u0647\u0645\u200C\u0627\u06A9\u0646\u0648\u0646 \u062F\u0631 \u062D\u0627\u0644 \u0631\u0627\u0647\u200C\u0627\u0646\u062F\u0627\u0632\u06CC \u0627\u0633\u062A\u061B \u06AF\u0632\u06CC\u0646\u0647\u200C\u0647\u0627 \u062F\u06CC\u06AF\u0631 \u0642\u0627\u0628\u0644 \u062A\u063A\u06CC\u06CC\u0631 \u0646\u06CC\u0633\u062A\u0646\u062F. \u062F\u0631 nuxt.config \u0645\u0642\u062F\u0627\u0631 `cornerstone.autoInit: false` \u0631\u0627 \u0628\u06AF\u0630\u0627\u0631\u06CC\u062F \u0648 ensureCornerstone(options) \u0631\u0627 \u0627\u0632 \u0627\u0641\u0632\u0648\u0646\u0647\u0654 \u062E\u0648\u062F\u062A\u0627\u0646 \u0641\u0631\u0627\u062E\u0648\u0627\u0646\u06CC \u06A9\u0646\u06CC\u062F.",
88
+ "error.initFailed": "\u0631\u0627\u0647\u200C\u0627\u0646\u062F\u0627\u0632\u06CC \u0646\u0627\u0645\u0648\u0641\u0642 \u0628\u0648\u062F",
89
+ "error.toolGroupCreate": "\u0633\u0627\u062E\u062A \u06AF\u0631\u0648\u0647 \u0627\u0628\u0632\u0627\u0631 \xAB{groupId}\xBB \u0645\u0645\u06A9\u0646 \u0646\u0634\u062F.",
90
+ "error.toolNotInGroup": "\u0627\u0628\u0632\u0627\u0631 \xAB{tool}\xBB \u062F\u0631 \u06AF\u0631\u0648\u0647 \u0627\u0628\u0632\u0627\u0631 \xAB{groupId}\xBB \u0646\u06CC\u0633\u062A. \u0646\u0627\u0645 \u06A9\u0644\u0627\u0633 \u0622\u0646 \u0631\u0627 \u0628\u0647 `cornerstone.tools.register` \u062F\u0631 nuxt.config \u0627\u0636\u0627\u0641\u0647 \u06A9\u0646\u06CC\u062F.",
91
+ "warn.unknownTool": "\xAB{tool}\xBB \u0627\u0632 \u06A9\u0644\u0627\u0633\u200C\u0647\u0627\u06CC \u0627\u0628\u0632\u0627\u0631 \u0635\u0627\u062F\u0631\u0634\u062F\u0647\u0654 @cornerstonejs/tools \u0646\u06CC\u0633\u062A\u061B \u0646\u0627\u062F\u06CC\u062F\u0647 \u06AF\u0631\u0641\u062A\u0647 \u0634\u062F.",
92
+ "error.annotationViewport": "\u0646\u0645\u0627\u06CC\u06CC \u0628\u0631\u0627\u06CC \u0642\u0631\u0627\u0631 \u062F\u0627\u062F\u0646 \u062D\u0627\u0634\u06CC\u0647\u200C\u0646\u0648\u06CC\u0633\u06CC\u200C\u0647\u0627 \u0648\u062C\u0648\u062F \u0646\u062F\u0627\u0631\u062F. \u067E\u06CC\u0634 \u0627\u0632 \u0641\u0631\u0627\u062E\u0648\u0627\u0646\u06CC addBoxes() \u0645\u0646\u062A\u0638\u0631 \u0631\u0648\u06CC\u062F\u0627\u062F `ready` \u0646\u0645\u0627 \u0628\u0645\u0627\u0646\u06CC\u062F.",
93
+ "error.annotationToolGroup": "\u0627\u06CC\u0646 \u0646\u0645\u0627 \u062F\u0631 \u0647\u06CC\u0686 \u06AF\u0631\u0648\u0647 \u0627\u0628\u0632\u0627\u0631\u06CC \u0646\u06CC\u0633\u062A\u060C \u0628\u0646\u0627\u0628\u0631\u0627\u06CC\u0646 \u062D\u0627\u0634\u06CC\u0647\u200C\u0646\u0648\u06CC\u0633\u06CC\u200C\u0647\u0627 \u0647\u0631\u06AF\u0632 \u0631\u0633\u0645 \u0646\u0645\u06CC\u200C\u0634\u0648\u0646\u062F. \u0622\u0646 \u0631\u0627 \u0628\u0627 <CornerstoneViewport> \u0633\u0648\u0627\u0631 \u06A9\u0646\u06CC\u062F\u060C \u06CC\u0627 \u0628\u0627 useCornerstoneTools().addViewport() \u0627\u0636\u0627\u0641\u0647 \u06A9\u0646\u06CC\u062F.",
94
+ "error.annotationTool": "\u0627\u0628\u0632\u0627\u0631 RectangleROITool \u0627\u0632 @cornerstonejs/tools \u062F\u0631 \u062F\u0633\u062A\u0631\u0633 \u0646\u06CC\u0633\u062A\u060C \u0648 \u06A9\u0627\u062F\u0631\u0647\u0627\u06CC \u0648\u0627\u0631\u062F\u0634\u062F\u0647 \u0628\u0627 \u0647\u0645\u06CC\u0646 \u0627\u0628\u0632\u0627\u0631 \u0631\u0633\u0645 \u0645\u06CC\u200C\u0634\u0648\u0646\u062F.",
95
+ "annotationJson.notJson": "\u0627\u06CC\u0646 \u0641\u0627\u06CC\u0644 JSON \u0645\u0639\u062A\u0628\u0631 \u0646\u06CC\u0633\u062A: {message}",
96
+ "annotationJson.unknownShape": "\u0633\u0627\u062E\u062A\u0627\u0631 \u0627\u06CC\u0646 JSON \u0628\u0647\u200C\u0639\u0646\u0648\u0627\u0646 \u0641\u0627\u06CC\u0644 \u062D\u0627\u0634\u06CC\u0647\u200C\u0646\u0648\u06CC\u0633\u06CC \u0634\u0646\u0627\u062E\u062A\u0647 \u0646\u0634\u062F. \u06CC\u06A9 \u0641\u0647\u0631\u0633\u062A \u0627\u0632 \u06A9\u0627\u062F\u0631\u0647\u0627 \u06A9\u0647 \u0647\u0631\u06A9\u062F\u0627\u0645 `sopInstanceUid` \u0648 `box` \u062F\u0627\u0631\u0646\u062F \u0627\u0646\u062A\u0638\u0627\u0631 \u0645\u06CC\u200C\u0631\u0641\u062A\u060C \u06CC\u0627 \u06AF\u0632\u0627\u0631\u0634\u06CC \u0628\u0627 \u0622\u0631\u0627\u06CC\u0647\u0654 `findings` \u06A9\u0647 \u0648\u0631\u0648\u062F\u06CC\u200C\u0647\u0627\u06CC\u0634 `slice_findings` \u062F\u0627\u0631\u0646\u062F.",
97
+ "annotationJson.finding": "\u06CC\u0627\u0641\u062A\u0647\u0654 {index}",
98
+ "annotationJson.class": "\u06A9\u0644\u0627\u0633 {value}",
99
+ "annotationJson.labelled": "{name} \xB7 \u066A{confidence}",
100
+ "zip.tooLarge": "\u062D\u062C\u0645 \u0628\u0627\u0632\u0634\u062F\u0647\u0654 \u0627\u06CC\u0646 \u0628\u0627\u06CC\u06AF\u0627\u0646\u06CC \u0628\u06CC\u0634 \u0627\u0632 {limit} \u062F\u0627\u062F\u0647\u0654 \u062F\u0627\u06CC\u06A9\u0627\u0645 \u0627\u0633\u062A. \u0622\u0646 \u0631\u0627 \u0627\u0633\u062A\u062E\u0631\u0627\u062C \u06A9\u0646\u06CC\u062F \u0648 \u062A\u0646\u0647\u0627 \u0633\u0631\u06CC \u0645\u0648\u0631\u062F\u0646\u06CC\u0627\u0632 \u0631\u0627 \u0628\u0627\u0632 \u06A9\u0646\u06CC\u062F\u060C \u06CC\u0627 \u0645\u0642\u062F\u0627\u0631 `maxBytes` \u0631\u0627 \u0627\u0641\u0632\u0627\u06CC\u0634 \u062F\u0647\u06CC\u062F.",
101
+ "zip.notReadable": "\u0627\u06CC\u0646 \u0641\u0627\u06CC\u0644 \u06CC\u06A9 \u0628\u0627\u06CC\u06AF\u0627\u0646\u06CC ZIP \u062E\u0648\u0627\u0646\u0627 \u0646\u06CC\u0633\u062A.",
102
+ "zip.readFailed": "\u062E\u0648\u0627\u0646\u062F\u0646 \u0628\u0627\u06CC\u06AF\u0627\u0646\u06CC ZIP \u0645\u0645\u06A9\u0646 \u0646\u0634\u062F: {message}",
103
+ "series.numbered": "\u0633\u0631\u06CC {number}",
104
+ "series.unnamed": "\u0633\u0631\u06CC \u0628\u062F\u0648\u0646 \u0646\u0627\u0645",
105
+ // Persian does not inflect a counted noun, so one form covers every count.
106
+ "series.images": { other: "{count} \u062A\u0635\u0648\u06CC\u0631" },
107
+ "series.label": "{name} ({details})",
108
+ "list.separator": "\u060C ",
109
+ "bytes.value": "{value} {unit}",
110
+ "bytes.unit.B": "\u0628\u0627\u06CC\u062A",
111
+ "bytes.unit.KB": "\u06A9\u06CC\u0644\u0648\u0628\u0627\u06CC\u062A",
112
+ "bytes.unit.MB": "\u0645\u06AF\u0627\u0628\u0627\u06CC\u062A",
113
+ "bytes.unit.GB": "\u06AF\u06CC\u06AF\u0627\u0628\u0627\u06CC\u062A",
114
+ "bytes.unit.TB": "\u062A\u0631\u0627\u0628\u0627\u06CC\u062A",
115
+ "study.progress.reading": "\u062F\u0631 \u062D\u0627\u0644 \u062E\u0648\u0627\u0646\u062F\u0646 \u0628\u0627\u06CC\u06AF\u0627\u0646\u06CC\u2026",
116
+ "study.progress.extracting": "\u062F\u0631 \u062D\u0627\u0644 \u0627\u0633\u062A\u062E\u0631\u0627\u062C\u2026",
117
+ "study.progress.indexing": "\u062E\u0648\u0627\u0646\u062F\u0646 \u0633\u0631\u0622\u06CC\u0646\u062F\u0647\u0627 {done} / {total}",
118
+ "study.error.noDicomInZip": "\u0647\u06CC\u0686 \u062A\u0635\u0648\u06CC\u0631 \u062F\u0627\u06CC\u06A9\u0627\u0645\u06CC \u062F\u0631 {file} \u067E\u06CC\u062F\u0627 \u0646\u0634\u062F.",
119
+ "study.error.noDicomFiles": { other: "\u0647\u06CC\u0686\u200C\u06A9\u062F\u0627\u0645 \u0627\u0632 \u0622\u0646 {count} \u0641\u0627\u06CC\u0644 \u062F\u0627\u06CC\u06A9\u0627\u0645 \u0646\u06CC\u0633\u062A." },
120
+ "study.error.noUrls": "\u0647\u06CC\u0686\u200C\u06CC\u06A9 \u0627\u0632 \u0622\u0646 \u0646\u0634\u0627\u0646\u06CC\u200C\u0647\u0627 \u062E\u0648\u0627\u0646\u062F\u0647 \u0646\u0634\u062F.",
121
+ "study.skipped.summary": "{count}: {named}",
122
+ "study.skipped.more": "{count}: {named} \u0648 {rest} \u0645\u0648\u0631\u062F \u062F\u06CC\u06AF\u0631",
123
+ "study.skipped.entry": "{name} ({reason})",
124
+ "study.skip.metadata": "\u0641\u0627\u06CC\u0644 \u062C\u0627\u0646\u0628\u06CC",
125
+ "study.skip.notDicomExtension": "\u067E\u0633\u0648\u0646\u062F \u062F\u0627\u06CC\u06A9\u0627\u0645 \u0646\u06CC\u0633\u062A",
126
+ "study.skip.notDicom": "\u0633\u0631\u0622\u06CC\u0646\u062F \u062F\u0627\u06CC\u06A9\u0627\u0645 \u0646\u062F\u0627\u0631\u062F",
127
+ "study.skip.empty": "\u062E\u0627\u0644\u06CC",
128
+ "study.source.files": { other: "{count} \u0641\u0627\u06CC\u0644 \u0645\u062D\u0644\u06CC\u060C \u0645\u0631\u062A\u0628\u200C\u0634\u062F\u0647 \u0628\u0631 \u0627\u0633\u0627\u0633 InstanceNumber" },
129
+ "study.source.urls": { other: "{count} \u062A\u0635\u0648\u06CC\u0631" },
130
+ "study.source.zip": "{file} \u2014 {images} \u062F\u0631 {series}",
131
+ "study.count.series": { other: "{count} \u0633\u0631\u06CC" },
132
+ "study.count.skipped": { other: "{count} \u0641\u0627\u06CC\u0644 \u0646\u0627\u062F\u06CC\u062F\u0647 \u06AF\u0631\u0641\u062A\u0647 \u0634\u062F" },
133
+ "cine.preparing": "\u062F\u0631 \u062D\u0627\u0644 \u0622\u0645\u0627\u062F\u0647\u200C\u0633\u0627\u0632\u06CC\u2026 \u066A{percent}",
134
+ "cine.prepared": { other: "{count} \u062A\u0635\u0648\u06CC\u0631 \u0622\u0645\u0627\u062F\u0647 \u0627\u0633\u062A" },
135
+ "cine.preparedWithFailures": {
136
+ other: "{count} \u062A\u0635\u0648\u06CC\u0631 \u0622\u0645\u0627\u062F\u0647 \u0627\u0633\u062A\u060C {failed} \u062A\u0635\u0648\u06CC\u0631 \u0631\u0645\u0632\u06AF\u0634\u0627\u06CC\u06CC \u0646\u0634\u062F"
137
+ },
138
+ "cine.cacheFull": "\u062D\u0627\u0641\u0638\u0647\u0654 \u0646\u0647\u0627\u0646 \u062A\u0635\u0627\u0648\u06CC\u0631 \u062F\u0631 {count} \u062A\u0635\u0648\u06CC\u0631 \u067E\u0631 \u0634\u062F \u2014 \u0628\u0642\u06CC\u0647 \u0647\u0646\u06AF\u0627\u0645 \u0631\u0633\u06CC\u062F\u0646 \u0628\u0647 \u0622\u0646\u200C\u0647\u0627 \u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC \u0645\u06CC\u200C\u0634\u0648\u0646\u062F.",
139
+ "report.summary": "{file}: {placed} \u06A9\u0627\u062F\u0631 \u0627\u0632 {total} \u06A9\u0627\u062F\u0631 \u0642\u0631\u0627\u0631 \u06AF\u0631\u0641\u062A.",
140
+ "report.waiting": { other: "{count} \u06A9\u0627\u062F\u0631 \u062F\u06CC\u06AF\u0631 \u0628\u0627 \u067E\u06CC\u0645\u0627\u06CC\u0634 \u0628\u0647 \u0628\u0631\u0634\u200C\u0647\u0627\u06CC\u0634\u0627\u0646 \u0646\u0645\u0627\u06CC\u0627\u0646 \u0645\u06CC\u200C\u0634\u0648\u0646\u062F." },
141
+ "report.dropped": { other: "{count} \u0648\u0631\u0648\u062F\u06CC \u062E\u0648\u0627\u0646\u062F\u0647 \u0646\u0634\u062F." },
142
+ "report.empty": "\u0641\u0627\u06CC\u0644 {file} \u0647\u06CC\u0686 \u062D\u0627\u0634\u06CC\u0647\u200C\u0646\u0648\u06CC\u0633\u06CC\u200C\u0627\u06CC \u0646\u062F\u0627\u0631\u062F.",
143
+ "report.unmatched": "\u0647\u06CC\u0686\u200C\u06CC\u06A9 \u0627\u0632 {total} \u06A9\u0627\u062F\u0631 \u0628\u0647 \u062A\u0635\u0627\u0648\u06CC\u0631 \u0631\u0648\u06CC \u0635\u0641\u062D\u0647 \u062A\u0639\u0644\u0642 \u0646\u062F\u0627\u0631\u062F \u2014 \u0627\u06CC\u0646 \u06AF\u0632\u0627\u0631\u0634 \u0633\u0631\u06CC {series} \u0631\u0627 \u0646\u0627\u0645 \u0645\u06CC\u200C\u0628\u0631\u062F. \u0628\u0631\u0627\u06CC \u062F\u06CC\u062F\u0646 \u0622\u0646\u200C\u0647\u0627 \u0647\u0645\u0627\u0646 \u0645\u0637\u0627\u0644\u0639\u0647 \u0631\u0627 \u0628\u0627\u0632 \u06A9\u0646\u06CC\u062F.",
144
+ "report.unmatchedNoSeries": "\u0647\u06CC\u0686\u200C\u06CC\u06A9 \u0627\u0632 {total} \u06A9\u0627\u062F\u0631 \u0628\u0647 \u062A\u0635\u0627\u0648\u06CC\u0631 \u0631\u0648\u06CC \u0635\u0641\u062D\u0647 \u062A\u0639\u0644\u0642 \u0646\u062F\u0627\u0631\u062F\u061B \u0628\u0631\u0634\u200C\u0647\u0627\u06CC\u06CC \u0631\u0627 \u0646\u0627\u0645 \u0645\u06CC\u200C\u0628\u0631\u0646\u062F \u06A9\u0647 \u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC \u0646\u0634\u062F\u0647\u200C\u0627\u0646\u062F.",
145
+ "report.failed": "\u062E\u0648\u0627\u0646\u062F\u0646 {file} \u0645\u0645\u06A9\u0646 \u0646\u0634\u062F: {message}"
146
+ };
147
+ export const BUILTIN_MESSAGES = { en, fa };
@@ -0,0 +1,13 @@
1
+ import type { ObjectPlugin } from '#app';
2
+ import { getCornerstoneOptions } from './cornerstone.js';
3
+ import type { CornerstoneLibs, CornerstoneModuleOptions } from './types.js';
4
+ /** What this plugin injects, reachable as `$cornerstone` / `useNuxtApp()`. */
5
+ export interface NuxtCornerstone {
6
+ ensure: (overrides?: CornerstoneModuleOptions) => Promise<CornerstoneLibs>;
7
+ get: () => CornerstoneLibs | null;
8
+ options: typeof getCornerstoneOptions;
9
+ }
10
+ declare const plugin: ObjectPlugin<{
11
+ cornerstone: NuxtCornerstone;
12
+ }>;
13
+ export default plugin;
@@ -0,0 +1,31 @@
1
+ import { defineNuxtPlugin, useRuntimeConfig } from "#imports";
2
+ import { t } from "./i18n/index.js";
3
+ import {
4
+ configureCornerstone,
5
+ ensureCornerstone,
6
+ getCornerstoneOptions,
7
+ getLoadedCornerstone
8
+ } from "./cornerstone.js";
9
+ const plugin = defineNuxtPlugin({
10
+ name: "nuxt-cornerstone",
11
+ enforce: "pre",
12
+ setup() {
13
+ const options = useRuntimeConfig().public.cornerstone;
14
+ configureCornerstone(options);
15
+ if (getCornerstoneOptions().autoInit) {
16
+ ensureCornerstone().catch((error) => {
17
+ console.error(`[nuxt-cornerstone] ${t("error.initFailed")}`, error);
18
+ });
19
+ }
20
+ return {
21
+ provide: {
22
+ cornerstone: {
23
+ ensure: (overrides) => ensureCornerstone(overrides),
24
+ get: () => getLoadedCornerstone(),
25
+ options: getCornerstoneOptions
26
+ }
27
+ }
28
+ };
29
+ }
30
+ });
31
+ export default plugin;
@@ -0,0 +1,12 @@
1
+ import type { ObjectPlugin } from '#app';
2
+ /**
3
+ * Install the locale on both server and client, and — when asked — keep it in
4
+ * step with the application that installed the module.
5
+ *
6
+ * Cornerstone itself is client-only, but its strings are not: a series label or
7
+ * an error rendered during SSR has to come back in the configured locale, and
8
+ * `<html lang dir>` has to match what the client will hydrate to. Doing this in
9
+ * the client plugin alone produces a first paint in English that then flips.
10
+ */
11
+ declare const plugin: ObjectPlugin;
12
+ export default plugin;
@@ -0,0 +1,15 @@
1
+ import { defineNuxtPlugin, useRuntimeConfig } from "#imports";
2
+ import { configureI18n } from "./i18n/index.js";
3
+ import { followHostLocale, sourcesOf } from "./i18n/detect.js";
4
+ const plugin = defineNuxtPlugin({
5
+ name: "nuxt-cornerstone:i18n",
6
+ enforce: "pre",
7
+ setup(nuxtApp) {
8
+ const options = useRuntimeConfig().public.cornerstone;
9
+ const i18n = options?.i18n;
10
+ configureI18n(i18n);
11
+ if (import.meta.server || !i18n || !i18n.detect) return;
12
+ followHostLocale(nuxtApp, sourcesOf(i18n.detect));
13
+ }
14
+ });
15
+ export default plugin;
@@ -0,0 +1,150 @@
1
+ import type { MessageCatalog } from './i18n/messages.js';
2
+ import type { Types as CoreTypes } from '@cornerstonejs/core';
3
+ import type { Types as DicomLoaderTypes } from '@cornerstonejs/dicom-image-loader';
4
+ /**
5
+ * Cornerstone3D is imported dynamically and only in the browser, so every
6
+ * reference to it in this module is type-only. `typeof import(...)` is erased
7
+ * at compile time and never produces a runtime import.
8
+ */
9
+ export type CornerstoneCore = typeof import('@cornerstonejs/core');
10
+ export type CornerstoneTools = typeof import('@cornerstonejs/tools');
11
+ export type CornerstoneDicomImageLoader = typeof import('@cornerstonejs/dicom-image-loader');
12
+ export interface CornerstoneLibs {
13
+ core: CornerstoneCore;
14
+ tools: CornerstoneTools;
15
+ dicomImageLoader: CornerstoneDicomImageLoader;
16
+ }
17
+ /** Recursive Partial that leaves functions and arrays alone. */
18
+ export type DeepPartial<T> = T extends (...args: never[]) => unknown ? T : T extends readonly unknown[] ? T : T extends object ? {
19
+ [K in keyof T]?: DeepPartial<T[K]>;
20
+ } : T;
21
+ /**
22
+ * Tools registered by default. Cornerstone's `addTool` is a global registry and
23
+ * throws on a duplicate name, so registration is guarded (see `cornerstone.ts`).
24
+ */
25
+ export declare const DEFAULT_TOOLS: readonly ["WindowLevelTool", "PanTool", "ZoomTool", "StackScrollTool", "LengthTool", "RectangleROITool", "EllipticalROITool", "ProbeTool"];
26
+ export type DefaultToolClassName = (typeof DEFAULT_TOOLS)[number];
27
+ /** Any exported tool class name from `@cornerstonejs/tools`. */
28
+ export type CornerstoneToolClassName = DefaultToolClassName | (string & {});
29
+ export interface CornerstoneToolsOptions {
30
+ /** Run `csToolsInit()` and register the tool classes. Default: `true`. */
31
+ enabled?: boolean;
32
+ /**
33
+ * Tool classes to register globally, by their export name in
34
+ * `@cornerstonejs/tools`. `false` registers none — do it yourself with
35
+ * `addTool()`. Default: {@link DEFAULT_TOOLS}.
36
+ */
37
+ register?: CornerstoneToolClassName[] | false;
38
+ }
39
+ /**
40
+ * Where to read the host application's locale from.
41
+ *
42
+ * - `'i18n'` — `nuxtApp.$i18n.locale`, which is what `@nuxtjs/i18n` and
43
+ * vue-i18n expose. Duck-typed, so nothing is imported and nothing breaks
44
+ * when they are absent. Followed reactively.
45
+ * - `'html'` — the `lang` attribute on `<html>`, watched for changes. Works
46
+ * with any i18n library, since they nearly all set it.
47
+ * - `'navigator'` — the browser's preferred language, read once at startup.
48
+ */
49
+ export type LocaleSource = 'i18n' | 'html' | 'navigator';
50
+ export interface CornerstoneI18nOptions {
51
+ /**
52
+ * Locale for the strings this module produces. Default: `'en'`.
53
+ *
54
+ * `en` and `fa` ship with the module; any other locale needs a catalogue of
55
+ * its own in {@link CornerstoneI18nOptions.messages}.
56
+ */
57
+ locale?: string;
58
+ /** Used for keys the active locale is missing. Default: `'en'`. */
59
+ fallbackLocale?: string;
60
+ /**
61
+ * Catalogues merged over the built-in ones, keyed by locale. Use it to
62
+ * override individual strings, add a locale, or register keys of your own —
63
+ * `t()` resolves anything in here.
64
+ *
65
+ * These travel through `runtimeConfig`, so values must be plain strings (or
66
+ * plural-form objects), not functions.
67
+ */
68
+ messages?: Record<string, MessageCatalog>;
69
+ /**
70
+ * `'auto'` (default) lets each locale use its own digits, which means
71
+ * Persian-Indic digits in Farsi. `'latn'` pins every locale to 0-9, for apps
72
+ * whose users cross-reference slice numbers against other systems.
73
+ */
74
+ numberingSystem?: 'auto' | 'latn';
75
+ /**
76
+ * Follow the locale of the application that installed the module, instead of
77
+ * the one pinned in {@link CornerstoneI18nOptions.locale}. Default: `false`.
78
+ *
79
+ * `true` tries each {@link LocaleSource} in order and stops at the first one
80
+ * that answers; an array picks the sources and their order yourself.
81
+ *
82
+ * Only a locale the module has a catalogue for is adopted, so an app running
83
+ * in a language nobody has translated keeps the configured locale rather than
84
+ * silently flipping text direction under the viewer.
85
+ *
86
+ * Detection is client-side. The locale is module-scoped state, which on the
87
+ * server is shared by every in-flight request, so following a per-request
88
+ * locale there would let one request's language leak into another's. During
89
+ * SSR the configured locale is used — see "Internationalisation" in the
90
+ * README for the per-request case.
91
+ */
92
+ detect?: boolean | LocaleSource[];
93
+ }
94
+ export interface CornerstoneModuleOptions {
95
+ /**
96
+ * Initialise Cornerstone3D from the client plugin, as the app boots, rather
97
+ * than lazily on first viewport mount. Default: `true`.
98
+ *
99
+ * Set to `false` when you need to pass non-serializable options (callbacks
100
+ * such as `dicomImageLoader.beforeSend`, or `core.peerImport`): those cannot
101
+ * travel through `runtimeConfig`, so pass them to `ensureCornerstone()` from
102
+ * a plugin of your own instead.
103
+ */
104
+ autoInit?: boolean;
105
+ /** Passed to `coreInit()`. Deep-merged over Cornerstone's own defaults. */
106
+ core?: DeepPartial<CoreTypes.Cornerstone3DConfig>;
107
+ /** Passed to `dicomImageLoaderInit()`. */
108
+ dicomImageLoader?: DicomLoaderTypes.LoaderOptions;
109
+ tools?: CornerstoneToolsOptions;
110
+ /**
111
+ * Locale and message catalogues for the module's own strings — the errors it
112
+ * throws and the series labels `useDicomFiles()` builds.
113
+ *
114
+ * `false` turns the catalogue off: the module stays on English and ignores
115
+ * locale changes, which is what you want when the host app owns these
116
+ * strings. Route them through its i18n with `setTranslator()` from
117
+ * `useCornerstoneI18n()`.
118
+ */
119
+ i18n?: CornerstoneI18nOptions | false;
120
+ /**
121
+ * Register `@originjs/vite-plugin-commonjs` on the client build. Default:
122
+ * `true`, and it is required for images to decode at all in dev.
123
+ *
124
+ * The DICOM image loader has to stay out of dependency prebundling (esbuild
125
+ * cannot resolve its WASM specifiers), which means Vite serves its imports
126
+ * raw — including the four Emscripten codec bundles, which are UMD/CommonJS.
127
+ * Without this plugin those imports fail with "doesn't provide an export
128
+ * named: 'default'". Only turn it off if you are supplying your own CommonJS
129
+ * interop.
130
+ */
131
+ viteCommonjs?: boolean;
132
+ /** Component name prefix. Default: `'Cornerstone'` (→ `<CornerstoneViewport>`). */
133
+ prefix?: string;
134
+ /** Default rendering engine id shared by viewports. */
135
+ renderingEngineId?: string;
136
+ /** Default tool group id shared by viewports. */
137
+ toolGroupId?: string;
138
+ }
139
+ /** Module options after defaults are applied. */
140
+ export type ResolvedCornerstoneOptions = Required<Pick<CornerstoneModuleOptions, 'autoInit' | 'core' | 'dicomImageLoader' | 'viteCommonjs' | 'prefix' | 'renderingEngineId' | 'toolGroupId'>> & {
141
+ tools: Required<CornerstoneToolsOptions>;
142
+ i18n: Required<CornerstoneI18nOptions> | false;
143
+ };
144
+ /** A mouse/keyboard binding for `setActive`, as `tools.Enums.MouseBindings`. */
145
+ export interface ToolBinding {
146
+ mouseButton?: number;
147
+ modifierKey?: number;
148
+ numTouchPoints?: number;
149
+ }
150
+ export type StackViewport = CoreTypes.IStackViewport;
@@ -0,0 +1,10 @@
1
+ export const DEFAULT_TOOLS = [
2
+ "WindowLevelTool",
3
+ "PanTool",
4
+ "ZoomTool",
5
+ "StackScrollTool",
6
+ "LengthTool",
7
+ "RectangleROITool",
8
+ "EllipticalROITool",
9
+ "ProbeTool"
10
+ ];