@file-viewer/core 2.1.29 → 2.2.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.
@@ -3,6 +3,12 @@ export const DEFAULT_FILE_VIEWER_ARCHIVE_WASM_PATH = 'vendor/libarchive/libarchi
3
3
  export const DEFAULT_FILE_VIEWER_DOCX_WORKER_PATH = 'vendor/docx/docx.worker.js';
4
4
  export const DEFAULT_FILE_VIEWER_DOCX_WORKER_JSZIP_PATH = 'vendor/docx/jszip.min.js';
5
5
  export const DEFAULT_FILE_VIEWER_PRESENTATION_WORKER_PATH = 'vendor/pptx/pptx.worker.js';
6
+ export const DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH = 'vendor/ppt';
7
+ export const DEFAULT_FILE_VIEWER_PPT_MODULE_PATH = `${DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH}/index.mjs`;
8
+ export const DEFAULT_FILE_VIEWER_PPT_WORKER_PATH = `${DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH}/worker.mjs`;
9
+ export const DEFAULT_FILE_VIEWER_PPT_FRAME_CACHE_PATH = `${DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH}/frame-cache.mjs`;
10
+ export const DEFAULT_FILE_VIEWER_PPT_WASM_PATH = `${DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH}/ppt-native.wasm`;
11
+ export const DEFAULT_FILE_VIEWER_PPT_FONT_PATH = `${DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH}/ppt-font-cjk.otf`;
6
12
  export const DEFAULT_FILE_VIEWER_SPREADSHEET_WORKER_PATH = 'vendor/xlsx/sheet.worker.js';
7
13
  export const DEFAULT_FILE_VIEWER_PDF_WORKER_PATH = 'vendor/pdf/pdf.worker.mjs';
8
14
  export const DEFAULT_FILE_VIEWER_PDF_CMAP_PATH = 'vendor/pdf/cmaps/';
@@ -14,6 +20,8 @@ export const DEFAULT_FILE_VIEWER_DRAWIO_ASSET_PATH = 'vendor/drawio/';
14
20
  export const DEFAULT_FILE_VIEWER_CAD_WASM_PATH = 'wasm/cad/';
15
21
  export const DEFAULT_FILE_VIEWER_CAD_WORKER_PATH = 'wasm/cad/dwg-worker.js';
16
22
  export const DEFAULT_FILE_VIEWER_CAD_DWF_WASM_PATH = 'wasm/cad/dwfv-render.wasm';
23
+ export const DEFAULT_FILE_VIEWER_CAD_LIBREDWG_SCRIPT_PATH = 'wasm/cad/libredwg-web.js';
24
+ export const DEFAULT_FILE_VIEWER_CAD_LIBREDWG_WASM_PATH = 'wasm/cad/libredwg-web.wasm';
17
25
  export const DEFAULT_FILE_VIEWER_TYPST_COMPILER_WASM_URL = 'wasm/typst/typst_ts_web_compiler_bg.wasm';
18
26
  export const DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_URL = 'wasm/typst/typst_ts_renderer_bg.wasm';
19
27
  export const DEFAULT_FILE_VIEWER_TYPST_FONT_ASSETS_URL = 'wasm/typst/fonts/';
@@ -25,47 +33,123 @@ export const DEFAULT_FILE_VIEWER_TYPST_COMPILER_WASM_PACKAGE_PATH = '@myriaddrea
25
33
  export const DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_PACKAGE_PATH = '@myriaddreamin/typst-ts-renderer/pkg/typst_ts_renderer_bg.wasm';
26
34
  export const DEFAULT_FILE_VIEWER_DATA_SQL_WASM_URL = 'wasm/data/sql-wasm.wasm';
27
35
  export const DEFAULT_FILE_VIEWER_DATA_SQL_WASM_PACKAGE_PATH = 'sql.js/dist/sql-wasm.wasm';
36
+ export const DEFAULT_FILE_VIEWER_MODEL_WORKER_URL = 'wasm/model/occt-worker.js';
37
+ export const DEFAULT_FILE_VIEWER_MODEL_RUNTIME_URL = 'wasm/model/occt-import-js.js';
38
+ export const DEFAULT_FILE_VIEWER_MODEL_WASM_URL = 'wasm/model/occt-import-js.wasm';
39
+ export const DEFAULT_FILE_VIEWER_MODEL_OCCT_LICENSE_URL = 'wasm/model/LICENSE.occt.txt';
40
+ export const DEFAULT_FILE_VIEWER_MODEL_IMPORT_LICENSE_URL = 'wasm/model/LICENSE.occt-import-js.txt';
41
+ export const DEFAULT_FILE_VIEWER_MODEL_RUNTIME_PACKAGE_PATH = 'occt-import-js/dist/occt-import-js.js';
42
+ export const DEFAULT_FILE_VIEWER_MODEL_WASM_PACKAGE_PATH = 'occt-import-js/dist/occt-import-js.wasm';
43
+ export const DEFAULT_FILE_VIEWER_MODEL_OCCT_LICENSE_PACKAGE_PATH = 'occt-import-js/dist/license.occt.txt';
44
+ export const DEFAULT_FILE_VIEWER_MODEL_IMPORT_LICENSE_PACKAGE_PATH = 'occt-import-js/dist/license.occt-import-js.txt';
45
+ const automaticFileViewerAssetBaseUrl = Symbol('automatic-file-viewer-asset-base');
46
+ let configuredFileViewerAssetBaseUrl = automaticFileViewerAssetBaseUrl;
47
+ export const normalizeFileViewerAssetBaseUrl = (baseUrl) => {
48
+ if (!baseUrl) {
49
+ return undefined;
50
+ }
51
+ const value = String(baseUrl).trim();
52
+ if (!value) {
53
+ return undefined;
54
+ }
55
+ return value.endsWith('/') ? value : `${value}/`;
56
+ };
57
+ export const setDefaultFileViewerAssetBaseUrl = (baseUrl) => {
58
+ configuredFileViewerAssetBaseUrl = normalizeFileViewerAssetBaseUrl(baseUrl);
59
+ };
60
+ export const resetDefaultFileViewerAssetBaseUrl = () => {
61
+ configuredFileViewerAssetBaseUrl = automaticFileViewerAssetBaseUrl;
62
+ };
63
+ const pathDepth = (pathname) => pathname.split('/').filter(Boolean).length;
64
+ const longestCommonDirectoryPath = (left, right) => {
65
+ const leftSegments = left.split('/').filter(Boolean);
66
+ const rightSegments = right.split('/').filter(Boolean);
67
+ const common = [];
68
+ const length = Math.min(leftSegments.length, Math.max(0, rightSegments.length - 1));
69
+ for (let index = 0; index < length && leftSegments[index] === rightSegments[index]; index += 1) {
70
+ common.push(leftSegments[index]);
71
+ }
72
+ return common.length ? `/${common.join('/')}/` : '/';
73
+ };
28
74
  const resolveFileViewerScriptAssetBaseCandidate = (script, documentBaseUrl, index) => {
29
75
  try {
30
76
  const rawScriptUrl = script.src || script.getAttribute('src') || '';
31
77
  if (!rawScriptUrl) {
32
- return null;
78
+ return [];
33
79
  }
34
80
  const scriptUrl = new URL(rawScriptUrl, documentBaseUrl);
35
81
  const viteClient = scriptUrl.pathname.match(/^(.*\/)@vite\/client$/i);
36
82
  const isSourceModule = /\/(?:src|node_modules|@fs|@id|@vite)(?:\/|$)/i.test(scriptUrl.pathname);
37
- const assetDirectory = scriptUrl.pathname.match(/^(.*\/)(?:assets|static|js)\/.+\.(?:m?js)$/i);
38
- const entryScript = isSourceModule
39
- ? null
40
- : scriptUrl.pathname.match(/^(.*\/)(?:app|index|main|runtime|umi)(?:[.-][^/]*)?\.(?:m?js)$/i);
41
- const basePath = (viteClient === null || viteClient === void 0 ? void 0 : viteClient[1]) || (!isSourceModule ? assetDirectory === null || assetDirectory === void 0 ? void 0 : assetDirectory[1] : null) || (entryScript === null || entryScript === void 0 ? void 0 : entryScript[1]);
42
- if (!basePath) {
43
- return null;
44
- }
45
- const url = new URL(basePath, scriptUrl).href;
46
83
  const documentUrl = new URL(documentBaseUrl);
47
- const candidateUrl = new URL(url);
84
+ const documentPathname = documentUrl.pathname.endsWith('/')
85
+ ? documentUrl.pathname
86
+ : `${documentUrl.pathname}/`;
48
87
  const scriptName = scriptUrl.pathname.slice(scriptUrl.pathname.lastIndexOf('/') + 1);
49
- let score = index / 10000;
50
- if (candidateUrl.origin === documentUrl.origin) {
51
- score += 8;
52
- }
53
- if (documentUrl.pathname.startsWith(candidateUrl.pathname)) {
54
- score += 4;
88
+ const isEntryScript = /^(?:app|index|main|runtime|umi)(?:[.-]|$)/i.test(scriptName);
89
+ const candidates = new Map();
90
+ const addCandidate = (basePath, quality) => {
91
+ const url = new URL(basePath, scriptUrl).href;
92
+ const candidateUrl = new URL(url);
93
+ let score = quality + index / 10000;
94
+ if (candidateUrl.origin === documentUrl.origin) {
95
+ score += 8;
96
+ }
97
+ if (documentPathname.startsWith(candidateUrl.pathname)) {
98
+ // Prefer the deepest candidate that is still an ancestor of the SPA
99
+ // route. This avoids stripping an earlier deployment segment named
100
+ // `assets` when the emitted suffix is actually `static/js`.
101
+ score += 16 + pathDepth(candidateUrl.pathname) / 4;
102
+ }
103
+ if (script.type === 'module') {
104
+ score += 2;
105
+ }
106
+ if (isEntryScript) {
107
+ score += 2;
108
+ }
109
+ const previous = candidates.get(url);
110
+ if (!previous || previous.score < score) {
111
+ candidates.set(url, { url, score });
112
+ }
113
+ };
114
+ if (viteClient) {
115
+ addCandidate(viteClient[1], 12);
55
116
  }
56
- if (script.type === 'module') {
57
- score += 2;
117
+ if (isSourceModule) {
118
+ return [...candidates.values()];
58
119
  }
59
- if (/^(?:app|index|main|runtime|umi)(?:[.-]|$)/i.test(scriptName)) {
60
- score += 2;
120
+ const pathSegments = scriptUrl.pathname.split('/').filter(Boolean);
121
+ const directories = pathSegments.slice(0, -1);
122
+ const emittedDirectoryWeights = [
123
+ { segments: ['static', 'js'], weight: 9 },
124
+ { segments: ['assets', 'js'], weight: 9 },
125
+ { segments: ['assets', 'chunks'], weight: 8 },
126
+ { segments: ['assets'], weight: 6 },
127
+ { segments: ['static'], weight: 6 },
128
+ { segments: ['js'], weight: 4 },
129
+ ];
130
+ emittedDirectoryWeights.forEach(({ segments, weight }) => {
131
+ for (let segmentIndex = 0; segmentIndex <= directories.length - segments.length; segmentIndex += 1) {
132
+ const matches = segments.every((segment, offset) => { var _a; return ((_a = directories[segmentIndex + offset]) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === segment; });
133
+ if (!matches) {
134
+ continue;
135
+ }
136
+ const basePath = directories.slice(0, segmentIndex).length
137
+ ? `/${directories.slice(0, segmentIndex).join('/')}/`
138
+ : '/';
139
+ addCandidate(basePath, weight + segments.length);
140
+ }
141
+ });
142
+ if (isEntryScript) {
143
+ const scriptDirectory = scriptUrl.pathname.slice(0, scriptUrl.pathname.lastIndexOf('/') + 1);
144
+ addCandidate(scriptDirectory, 3);
61
145
  }
62
- if (viteClient) {
63
- score += 8;
146
+ if (scriptUrl.origin === documentUrl.origin) {
147
+ addCandidate(longestCommonDirectoryPath(documentUrl.pathname, scriptUrl.pathname), 8);
64
148
  }
65
- return { url, score };
149
+ return [...candidates.values()];
66
150
  }
67
151
  catch {
68
- return null;
152
+ return [];
69
153
  }
70
154
  };
71
155
  /**
@@ -78,16 +162,91 @@ const resolveFileViewerScriptAssetBaseCandidate = (script, documentBaseUrl, inde
78
162
  export const resolveFileViewerRuntimeAssetBaseUrl = (documentRef) => {
79
163
  var _a;
80
164
  const documentBaseUrl = documentRef.baseURI || documentRef.URL || 'file:///';
165
+ if (configuredFileViewerAssetBaseUrl !== automaticFileViewerAssetBaseUrl) {
166
+ if (!configuredFileViewerAssetBaseUrl) {
167
+ return documentBaseUrl;
168
+ }
169
+ try {
170
+ return new URL(configuredFileViewerAssetBaseUrl, documentBaseUrl).href;
171
+ }
172
+ catch {
173
+ return configuredFileViewerAssetBaseUrl;
174
+ }
175
+ }
81
176
  if (documentRef.querySelector('base[href]')) {
82
177
  return documentBaseUrl;
83
178
  }
84
179
  const candidates = Array.from(documentRef.querySelectorAll('script[src]'))
85
- .map((script, index) => resolveFileViewerScriptAssetBaseCandidate(script, documentBaseUrl, index))
86
- .filter((candidate) => Boolean(candidate))
180
+ .flatMap((script, index) => resolveFileViewerScriptAssetBaseCandidate(script, documentBaseUrl, index))
87
181
  .sort((left, right) => right.score - left.score);
88
182
  return ((_a = candidates[0]) === null || _a === void 0 ? void 0 : _a.url) || documentBaseUrl;
89
183
  };
184
+ export const getDefaultFileViewerAssetBaseUrl = (documentRef) => {
185
+ if (configuredFileViewerAssetBaseUrl !== automaticFileViewerAssetBaseUrl) {
186
+ return configuredFileViewerAssetBaseUrl;
187
+ }
188
+ // Core remains environment-neutral: callers that want automatic browser
189
+ // inference pass their owning Document explicitly.
190
+ return documentRef ? resolveFileViewerRuntimeAssetBaseUrl(documentRef) : undefined;
191
+ };
90
192
  export const DEFAULT_FILE_VIEWER_RENDERER_ASSET_MANIFESTS = [
193
+ {
194
+ rendererId: 'model',
195
+ assets: [
196
+ {
197
+ id: 'model-occt-worker',
198
+ rendererId: 'model',
199
+ kind: 'worker',
200
+ target: 'public',
201
+ required: true,
202
+ defaultPath: DEFAULT_FILE_VIEWER_MODEL_WORKER_URL,
203
+ optionPath: 'model.workerUrl',
204
+ description: 'File Viewer worker that runs STEP, IGES, and BREP tessellation off the UI thread.',
205
+ },
206
+ {
207
+ id: 'model-occt-runtime',
208
+ rendererId: 'model',
209
+ kind: 'script',
210
+ target: 'public',
211
+ required: true,
212
+ defaultPath: DEFAULT_FILE_VIEWER_MODEL_RUNTIME_URL,
213
+ packagePath: DEFAULT_FILE_VIEWER_MODEL_RUNTIME_PACKAGE_PATH,
214
+ optionPath: 'model.runtimeUrl',
215
+ description: 'Self-hosted occt-import-js runtime for browser-native STEP, IGES, and BREP preview.',
216
+ },
217
+ {
218
+ id: 'model-occt-wasm',
219
+ rendererId: 'model',
220
+ kind: 'wasm',
221
+ target: 'public',
222
+ required: true,
223
+ defaultPath: DEFAULT_FILE_VIEWER_MODEL_WASM_URL,
224
+ packagePath: DEFAULT_FILE_VIEWER_MODEL_WASM_PACKAGE_PATH,
225
+ optionPath: 'model.wasmUrl',
226
+ description: 'OpenCascade WebAssembly geometry kernel used by the model renderer.',
227
+ },
228
+ {
229
+ id: 'model-occt-license',
230
+ rendererId: 'model',
231
+ kind: 'license',
232
+ target: 'public',
233
+ required: true,
234
+ defaultPath: DEFAULT_FILE_VIEWER_MODEL_OCCT_LICENSE_URL,
235
+ packagePath: DEFAULT_FILE_VIEWER_MODEL_OCCT_LICENSE_PACKAGE_PATH,
236
+ description: 'OpenCascade license notice distributed with the browser geometry kernel.',
237
+ },
238
+ {
239
+ id: 'model-occt-import-license',
240
+ rendererId: 'model',
241
+ kind: 'license',
242
+ target: 'public',
243
+ required: true,
244
+ defaultPath: DEFAULT_FILE_VIEWER_MODEL_IMPORT_LICENSE_URL,
245
+ packagePath: DEFAULT_FILE_VIEWER_MODEL_IMPORT_LICENSE_PACKAGE_PATH,
246
+ description: 'occt-import-js license notice distributed with the browser geometry kernel.',
247
+ },
248
+ ],
249
+ },
91
250
  {
92
251
  rendererId: 'drawing',
93
252
  assets: [
@@ -225,6 +384,24 @@ export const DEFAULT_FILE_VIEWER_RENDERER_ASSET_MANIFESTS = [
225
384
  optionPath: 'cad.dwfWasmUrl',
226
385
  description: 'DWF/DWFx/XPS raster WebAssembly module used by @flyfish-dev/cad-viewer.',
227
386
  },
387
+ {
388
+ id: 'cad-libredwg-script',
389
+ rendererId: 'cad',
390
+ kind: 'script',
391
+ target: 'public',
392
+ required: true,
393
+ defaultPath: DEFAULT_FILE_VIEWER_CAD_LIBREDWG_SCRIPT_PATH,
394
+ description: 'LibreDWG JavaScript runtime loaded by the CAD DWG worker for offline parsing.',
395
+ },
396
+ {
397
+ id: 'cad-libredwg-wasm',
398
+ rendererId: 'cad',
399
+ kind: 'wasm',
400
+ target: 'public',
401
+ required: true,
402
+ defaultPath: DEFAULT_FILE_VIEWER_CAD_LIBREDWG_WASM_PATH,
403
+ description: 'LibreDWG WebAssembly runtime loaded by the CAD DWG worker for offline parsing.',
404
+ },
228
405
  ],
229
406
  },
230
407
  {
@@ -252,6 +429,96 @@ export const DEFAULT_FILE_VIEWER_RENDERER_ASSET_MANIFESTS = [
252
429
  },
253
430
  ],
254
431
  },
432
+ {
433
+ rendererId: 'office-presentation-binary',
434
+ assets: [
435
+ {
436
+ id: 'ppt-module',
437
+ rendererId: 'office-presentation-binary',
438
+ kind: 'script',
439
+ target: 'public',
440
+ required: true,
441
+ defaultPath: DEFAULT_FILE_VIEWER_PPT_MODULE_PATH,
442
+ optionPath: 'presentation.pptModuleUrl',
443
+ description: 'Official @file-viewer/ppt 0.3 browser entry for PowerPoint 97–2003 preview.',
444
+ },
445
+ {
446
+ id: 'ppt-worker',
447
+ rendererId: 'office-presentation-binary',
448
+ kind: 'worker',
449
+ target: 'public',
450
+ required: true,
451
+ defaultPath: DEFAULT_FILE_VIEWER_PPT_WORKER_PATH,
452
+ optionPath: 'presentation.pptWorkerUrl',
453
+ description: 'Official @file-viewer/ppt 0.3 module Worker.',
454
+ },
455
+ {
456
+ id: 'ppt-frame-cache',
457
+ rendererId: 'office-presentation-binary',
458
+ kind: 'script',
459
+ target: 'public',
460
+ required: true,
461
+ defaultPath: DEFAULT_FILE_VIEWER_PPT_FRAME_CACHE_PATH,
462
+ description: 'Bounded IndexedDB frame cache imported by the binary-PPT Worker.',
463
+ },
464
+ {
465
+ id: 'ppt-wasm',
466
+ rendererId: 'office-presentation-binary',
467
+ kind: 'wasm',
468
+ target: 'public',
469
+ required: true,
470
+ defaultPath: DEFAULT_FILE_VIEWER_PPT_WASM_PATH,
471
+ optionPath: 'presentation.pptWasmUrl',
472
+ description: 'Official @file-viewer/ppt 0.3 native WebAssembly parser and renderer.',
473
+ },
474
+ {
475
+ id: 'ppt-cjk-font',
476
+ rendererId: 'office-presentation-binary',
477
+ kind: 'font',
478
+ target: 'public',
479
+ required: true,
480
+ defaultPath: DEFAULT_FILE_VIEWER_PPT_FONT_PATH,
481
+ optionPath: 'presentation.pptFontUrl',
482
+ description: 'CJK font pack verified and loaded by the binary-PPT runtime.',
483
+ },
484
+ {
485
+ id: 'ppt-runtime-manifest',
486
+ rendererId: 'office-presentation-binary',
487
+ kind: 'metadata',
488
+ target: 'public',
489
+ required: true,
490
+ defaultPath: `${DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH}/manifest.json`,
491
+ description: 'Integrity and edition metadata for the official binary-PPT runtime.',
492
+ },
493
+ {
494
+ id: 'ppt-runtime-package',
495
+ rendererId: 'office-presentation-binary',
496
+ kind: 'metadata',
497
+ target: 'public',
498
+ required: true,
499
+ defaultPath: `${DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH}/package.json`,
500
+ description: 'Package identity metadata for the official binary-PPT runtime.',
501
+ },
502
+ {
503
+ id: 'ppt-runtime-license',
504
+ rendererId: 'office-presentation-binary',
505
+ kind: 'license',
506
+ target: 'public',
507
+ required: true,
508
+ defaultPath: `${DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH}/LICENSE`,
509
+ description: 'License shipped by the independently versioned @file-viewer/ppt package.',
510
+ },
511
+ {
512
+ id: 'ppt-runtime-notice',
513
+ rendererId: 'office-presentation-binary',
514
+ kind: 'license',
515
+ target: 'public',
516
+ required: true,
517
+ defaultPath: `${DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH}/NOTICE`,
518
+ description: 'Notices shipped by the independently versioned @file-viewer/ppt package.',
519
+ },
520
+ ],
521
+ },
255
522
  {
256
523
  rendererId: 'office-presentation',
257
524
  assets: [
@@ -340,10 +607,14 @@ const DEFAULT_FILE_VIEWER_DOCUMENT_BASE_URL = 'file:///';
340
607
  export const resolveFileViewerAssetUrl = (value, fallback, options = {}) => {
341
608
  const raw = value ? String(value) : fallback;
342
609
  const documentBaseUrl = options.documentBaseUrl || DEFAULT_FILE_VIEWER_DOCUMENT_BASE_URL;
343
- const baseUrl = options.baseUrl
344
- ? options.baseUrl.endsWith('/') ? options.baseUrl : `${options.baseUrl}/`
610
+ const configuredBaseUrl = !value && configuredFileViewerAssetBaseUrl !== automaticFileViewerAssetBaseUrl
611
+ ? configuredFileViewerAssetBaseUrl
612
+ : undefined;
613
+ const preferredBaseUrl = options.baseUrl || configuredBaseUrl;
614
+ const baseUrl = preferredBaseUrl
615
+ ? preferredBaseUrl.endsWith('/') ? preferredBaseUrl : `${preferredBaseUrl}/`
345
616
  : documentBaseUrl;
346
- const resolvedBase = options.baseUrl
617
+ const resolvedBase = preferredBaseUrl
347
618
  ? new URL(baseUrl, documentBaseUrl).href
348
619
  : baseUrl;
349
620
  const resolved = new URL(raw, resolvedBase).href;
@@ -426,6 +697,11 @@ export const resolveFileViewerTypstFontAssetsUrl = (options, overrides = [], doc
426
697
  export const resolveFileViewerDataSqlWasmUrl = (options, overrides = [], documentBaseUrl) => {
427
698
  return resolveFileViewerAssetUrl((options === null || options === void 0 ? void 0 : options.sqlWasmUrl) || overrides.find(Boolean), DEFAULT_FILE_VIEWER_DATA_SQL_WASM_URL, { documentBaseUrl });
428
699
  };
700
+ export const resolveFileViewerModelAssetUrls = (options, documentBaseUrl) => ({
701
+ workerUrl: resolveFileViewerAssetUrl(options === null || options === void 0 ? void 0 : options.workerUrl, DEFAULT_FILE_VIEWER_MODEL_WORKER_URL, { documentBaseUrl }),
702
+ runtimeUrl: resolveFileViewerAssetUrl(options === null || options === void 0 ? void 0 : options.runtimeUrl, DEFAULT_FILE_VIEWER_MODEL_RUNTIME_URL, { documentBaseUrl }),
703
+ wasmUrl: resolveFileViewerAssetUrl(options === null || options === void 0 ? void 0 : options.wasmUrl, DEFAULT_FILE_VIEWER_MODEL_WASM_URL, { documentBaseUrl }),
704
+ });
429
705
  export const listFileViewerRendererAssetManifests = () => {
430
706
  return [...DEFAULT_FILE_VIEWER_RENDERER_ASSET_MANIFESTS];
431
707
  };
@@ -433,7 +709,7 @@ export const getFileViewerRendererAssetManifest = (rendererId) => {
433
709
  return DEFAULT_FILE_VIEWER_RENDERER_ASSET_MANIFESTS.find(manifest => manifest.rendererId === rendererId) || null;
434
710
  };
435
711
  const getRendererAssetOptionValue = (options, optionPath) => {
436
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
712
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
437
713
  switch (optionPath) {
438
714
  case 'archive.workerUrl':
439
715
  return (_a = options === null || options === void 0 ? void 0 : options.archive) === null || _a === void 0 ? void 0 : _a.workerUrl;
@@ -453,26 +729,40 @@ const getRendererAssetOptionValue = (options, optionPath) => {
453
729
  return (_h = options === null || options === void 0 ? void 0 : options.docx) === null || _h === void 0 ? void 0 : _h.workerUrl;
454
730
  case 'drawing.viewerScriptUrl':
455
731
  return (_j = options === null || options === void 0 ? void 0 : options.drawing) === null || _j === void 0 ? void 0 : _j.viewerScriptUrl;
732
+ case 'model.workerUrl':
733
+ return (_k = options === null || options === void 0 ? void 0 : options.model) === null || _k === void 0 ? void 0 : _k.workerUrl;
734
+ case 'model.runtimeUrl':
735
+ return (_l = options === null || options === void 0 ? void 0 : options.model) === null || _l === void 0 ? void 0 : _l.runtimeUrl;
736
+ case 'model.wasmUrl':
737
+ return (_m = options === null || options === void 0 ? void 0 : options.model) === null || _m === void 0 ? void 0 : _m.wasmUrl;
456
738
  case 'pdf.workerUrl':
457
- return (_k = options === null || options === void 0 ? void 0 : options.pdf) === null || _k === void 0 ? void 0 : _k.workerUrl;
739
+ return (_o = options === null || options === void 0 ? void 0 : options.pdf) === null || _o === void 0 ? void 0 : _o.workerUrl;
458
740
  case 'pdf.cMapUrl':
459
- return (_l = options === null || options === void 0 ? void 0 : options.pdf) === null || _l === void 0 ? void 0 : _l.cMapUrl;
741
+ return (_p = options === null || options === void 0 ? void 0 : options.pdf) === null || _p === void 0 ? void 0 : _p.cMapUrl;
460
742
  case 'pdf.wasmUrl':
461
- return (_m = options === null || options === void 0 ? void 0 : options.pdf) === null || _m === void 0 ? void 0 : _m.wasmUrl;
743
+ return (_q = options === null || options === void 0 ? void 0 : options.pdf) === null || _q === void 0 ? void 0 : _q.wasmUrl;
462
744
  case 'pdf.standardFontDataUrl':
463
- return (_o = options === null || options === void 0 ? void 0 : options.pdf) === null || _o === void 0 ? void 0 : _o.standardFontDataUrl;
745
+ return (_r = options === null || options === void 0 ? void 0 : options.pdf) === null || _r === void 0 ? void 0 : _r.standardFontDataUrl;
464
746
  case 'pdf.cjkFontFallbackPath':
465
- return (_p = options === null || options === void 0 ? void 0 : options.pdf) === null || _p === void 0 ? void 0 : _p.cjkFontFallbackPath;
747
+ return (_s = options === null || options === void 0 ? void 0 : options.pdf) === null || _s === void 0 ? void 0 : _s.cjkFontFallbackPath;
748
+ case 'presentation.pptModuleUrl':
749
+ return (_t = options === null || options === void 0 ? void 0 : options.presentation) === null || _t === void 0 ? void 0 : _t.pptModuleUrl;
750
+ case 'presentation.pptWorkerUrl':
751
+ return (_u = options === null || options === void 0 ? void 0 : options.presentation) === null || _u === void 0 ? void 0 : _u.pptWorkerUrl;
752
+ case 'presentation.pptWasmUrl':
753
+ return (_v = options === null || options === void 0 ? void 0 : options.presentation) === null || _v === void 0 ? void 0 : _v.pptWasmUrl;
754
+ case 'presentation.pptFontUrl':
755
+ return (_w = options === null || options === void 0 ? void 0 : options.presentation) === null || _w === void 0 ? void 0 : _w.pptFontUrl;
466
756
  case 'presentation.workerUrl':
467
- return (_q = options === null || options === void 0 ? void 0 : options.presentation) === null || _q === void 0 ? void 0 : _q.workerUrl;
757
+ return (_x = options === null || options === void 0 ? void 0 : options.presentation) === null || _x === void 0 ? void 0 : _x.workerUrl;
468
758
  case 'spreadsheet.workerUrl':
469
- return (_r = options === null || options === void 0 ? void 0 : options.spreadsheet) === null || _r === void 0 ? void 0 : _r.workerUrl;
759
+ return (_y = options === null || options === void 0 ? void 0 : options.spreadsheet) === null || _y === void 0 ? void 0 : _y.workerUrl;
470
760
  case 'typst.compilerWasmUrl':
471
- return (_s = options === null || options === void 0 ? void 0 : options.typst) === null || _s === void 0 ? void 0 : _s.compilerWasmUrl;
761
+ return (_z = options === null || options === void 0 ? void 0 : options.typst) === null || _z === void 0 ? void 0 : _z.compilerWasmUrl;
472
762
  case 'typst.fontAssetsUrl':
473
- return (_t = options === null || options === void 0 ? void 0 : options.typst) === null || _t === void 0 ? void 0 : _t.fontAssetsUrl;
763
+ return (_0 = options === null || options === void 0 ? void 0 : options.typst) === null || _0 === void 0 ? void 0 : _0.fontAssetsUrl;
474
764
  case 'typst.rendererWasmUrl':
475
- return (_u = options === null || options === void 0 ? void 0 : options.typst) === null || _u === void 0 ? void 0 : _u.rendererWasmUrl;
765
+ return (_1 = options === null || options === void 0 ? void 0 : options.typst) === null || _1 === void 0 ? void 0 : _1.rendererWasmUrl;
476
766
  default:
477
767
  return undefined;
478
768
  }
@@ -484,16 +774,19 @@ export const resolveFileViewerRendererAssets = (rendererId, resolveOptions = {})
484
774
  }
485
775
  return manifest.assets.map(asset => {
486
776
  const optionValue = getRendererAssetOptionValue(resolveOptions.options, asset.optionPath);
487
- const raw = optionValue ? String(optionValue) : asset.defaultUrl || asset.defaultPath;
777
+ const configuredValue = optionValue ? String(optionValue) : undefined;
778
+ const fallbackValue = asset.defaultUrl || asset.defaultPath;
488
779
  const resolved = {
489
780
  ...asset,
490
781
  configured: Boolean(optionValue),
491
782
  };
492
- if (raw) {
493
- resolved.url = resolveFileViewerAssetUrl(raw, raw, {
783
+ if (configuredValue || fallbackValue) {
784
+ resolved.url = resolveFileViewerAssetUrl(configuredValue, fallbackValue || configuredValue || '', {
494
785
  baseUrl: resolveOptions.baseUrl,
495
786
  documentBaseUrl: resolveOptions.documentBaseUrl,
496
- trimTrailingSlash: asset.kind === 'directory' || asset.kind === 'wasm-directory' || resolveOptions.trimTrailingSlash,
787
+ trimTrailingSlash: asset.kind === 'directory' ||
788
+ asset.kind === 'wasm-directory' ||
789
+ resolveOptions.trimTrailingSlash,
497
790
  });
498
791
  }
499
792
  return resolved;
@@ -9,7 +9,7 @@ export declare const createUnsupportedAvailability: (extension: string) => FileV
9
9
  * 它们的在线预览常依赖分页引擎、虚拟渲染或 Worker 生命周期,直接克隆
10
10
  * DOM 很容易只得到当前页或当前视口。
11
11
  */
12
- export declare const ADAPTER_PRINT_REQUIRED_EXTENSIONS: readonly ["docx", "docm", "dotx", "dotm", "doc", "dot", "pdf", "typ", "typst"];
12
+ export declare const ADAPTER_PRINT_REQUIRED_EXTENSIONS: readonly ["docx", "docm", "dotx", "dotm", "doc", "dot", "ppt", "pdf", "typ", "typst"];
13
13
  /**
14
14
  * 这些格式的预览结果是完整 DOM / SVG / Canvas 截图,解除滚动容器裁切后
15
15
  * 可以稳定进入浏览器打印流程。
@@ -18,7 +18,7 @@ export declare const DOM_PRINTABLE_EXTENSIONS: readonly ["pptx", "pptm", "potx",
18
18
  /**
19
19
  * 这些格式默认不展示打印按钮,避免导出半截内容。
20
20
  */
21
- export declare const NON_PRINTABLE_EXTENSIONS: readonly ["xlsx", "xltx", "xlsm", "xlsb", "xls", "xlt", "xltm", "csv", "ods", "fods", "numbers", "zip", "zipx", "7z", "rar", "tar", "gz", "gzip", "tgz", "bz2", "bzip2", "tbz", "tbz2", "xz", "txz", "lzma", "zst", "tzst", "cab", "ar", "cpio", "iso", "xar", "lha", "lzh", "jar", "war", "ear", "apk", "cbz", "cbr", "eml", "msg", "epub", "mp4", "mp3", "mpeg", "wav", "ogg", "oga", "opus", "m4a", "aac", "flac", "weba", "glb", "gltf", "obj", "stl", "ply", "fbx", "dae", "3ds", "3mf", "amf", "usd", "usda", "usdc", "usdz", "kmz", "step", "stp", "iges", "igs", "ifc", "3dm", "brep", "pcd", "wrl", "vrml", "xyz", "vtk", "vtp"];
21
+ export declare const NON_PRINTABLE_EXTENSIONS: readonly ["xlsx", "xltx", "xlsm", "xlsb", "xls", "xlt", "xltm", "csv", "tsv", "ods", "fods", "numbers", "zip", "zipx", "7z", "rar", "tar", "gz", "gzip", "tgz", "bz2", "bzip2", "tbz", "tbz2", "xz", "txz", "lzma", "zst", "tzst", "cab", "ar", "cpio", "iso", "xar", "lha", "lzh", "jar", "war", "ear", "apk", "cbz", "cbr", "eml", "msg", "epub", "mp4", "mp3", "mpeg", "wav", "ogg", "oga", "opus", "m4a", "aac", "flac", "weba", "glb", "gltf", "obj", "stl", "ply", "fbx", "dae", "3ds", "3mf", "amf", "usd", "usda", "usdc", "usdz", "kmz", "step", "stp", "iges", "igs", "ifc", "3dm", "brep", "pcd", "wrl", "vrml", "xyz", "vtk", "vtp"];
22
22
  export declare const needsDedicatedPrintAdapter: (extension: string) => boolean;
23
23
  export declare const isDomPrintableExtension: (extension: string) => boolean;
24
24
  export declare const isKnownNonPrintableExtension: (extension: string) => boolean;
@@ -52,7 +52,7 @@ export const createUnsupportedAvailability = (extension) => ({
52
52
  * DOM 很容易只得到当前页或当前视口。
53
53
  */
54
54
  export const ADAPTER_PRINT_REQUIRED_EXTENSIONS = [
55
- 'docx', 'docm', 'dotx', 'dotm', 'doc', 'dot', 'pdf', 'typ', 'typst',
55
+ 'docx', 'docm', 'dotx', 'dotm', 'doc', 'dot', 'ppt', 'pdf', 'typ', 'typst',
56
56
  ];
57
57
  /**
58
58
  * 这些格式的预览结果是完整 DOM / SVG / Canvas 截图,解除滚动容器裁切后
@@ -69,7 +69,7 @@ export const DOM_PRINTABLE_EXTENSIONS = [
69
69
  * 这些格式默认不展示打印按钮,避免导出半截内容。
70
70
  */
71
71
  export const NON_PRINTABLE_EXTENSIONS = [
72
- 'xlsx', 'xltx', 'xlsm', 'xlsb', 'xls', 'xlt', 'xltm', 'csv', 'ods', 'fods', 'numbers',
72
+ 'xlsx', 'xltx', 'xlsm', 'xlsb', 'xls', 'xlt', 'xltm', 'csv', 'tsv', 'ods', 'fods', 'numbers',
73
73
  ...ARCHIVE_EXTENSIONS,
74
74
  'eml', 'msg', 'epub', 'mp4',
75
75
  'mp3', 'mpeg', 'wav', 'ogg', 'oga', 'opus', 'm4a', 'aac', 'flac', 'weba',
@@ -28,9 +28,22 @@ export declare const DEFAULT_RENDERER_DEFINITIONS: readonly [{
28
28
  readonly zoom: "provider";
29
29
  readonly search: true;
30
30
  };
31
+ }, {
32
+ readonly id: "office-presentation-binary";
33
+ readonly label: "PowerPoint 97–2003";
34
+ readonly category: "office";
35
+ readonly extensions: readonly ["ppt"];
36
+ readonly async: true;
37
+ readonly capabilities: {
38
+ readonly download: true;
39
+ readonly print: "adapter";
40
+ readonly exportHtml: "adapter";
41
+ readonly zoom: "provider";
42
+ readonly search: false;
43
+ };
31
44
  }, {
32
45
  readonly id: "office-presentation";
33
- readonly label: "PowerPoint";
46
+ readonly label: "PowerPoint OpenXML";
34
47
  readonly category: "office";
35
48
  readonly extensions: readonly ["pptx", "pptm", "potx", "potm", "ppsx", "ppsm"];
36
49
  readonly async: true;
@@ -58,7 +71,7 @@ export declare const DEFAULT_RENDERER_DEFINITIONS: readonly [{
58
71
  readonly id: "spreadsheet-openxml";
59
72
  readonly label: "Spreadsheet";
60
73
  readonly category: "office";
61
- readonly extensions: readonly ["xlsx", "xltx", "xlsm", "xlsb", "xls", "xlt", "xltm", "csv", "ods", "fods", "numbers"];
74
+ readonly extensions: readonly ["xlsx", "xltx", "xlsm", "xlsb", "xls", "xlt", "xltm", "csv", "tsv", "ods", "fods", "numbers"];
62
75
  readonly async: true;
63
76
  readonly capabilities: {
64
77
  readonly download: true;
@@ -315,4 +328,4 @@ export declare const DEFAULT_RENDERER_DEFINITIONS: readonly [{
315
328
  readonly search: true;
316
329
  };
317
330
  }];
318
- export declare const DEFAULT_SUPPORTED_EXTENSIONS: readonly ("markdown" | "webp" | "jpeg" | "png" | "xyz" | "wasm" | "pdf" | "typst" | "html" | "svg" | "rb" | "zip" | "zipx" | "7z" | "rar" | "tar" | "gz" | "gzip" | "tgz" | "bz2" | "bzip2" | "tbz" | "tbz2" | "xz" | "txz" | "lzma" | "zst" | "tzst" | "cab" | "ar" | "cpio" | "iso" | "xar" | "lha" | "lzh" | "jar" | "war" | "ear" | "apk" | "cbz" | "cbr" | "glb" | "gltf" | "obj" | "stl" | "ply" | "fbx" | "dae" | "3ds" | "3mf" | "amf" | "usd" | "usda" | "usdc" | "usdz" | "kmz" | "step" | "stp" | "iges" | "igs" | "ifc" | "3dm" | "brep" | "pcd" | "wrl" | "vrml" | "vtk" | "vtp" | "txt" | "json" | "js" | "mjs" | "cjs" | "css" | "java" | "py" | "htm" | "jsx" | "ts" | "tsx" | "xml" | "log" | "vue" | "yaml" | "yml" | "ini" | "sh" | "bash" | "sql" | "go" | "rs" | "php" | "c" | "cpp" | "cc" | "h" | "hpp" | "cs" | "diff" | "patch" | "bundle" | "bdl" | "jsonc" | "json5" | "ipynb" | "toml" | "proto" | "hcl" | "tex" | "gv" | "http" | "react" | "swift" | "kt" | "gif" | "jpg" | "bmp" | "tiff" | "tif" | "avif" | "ico" | "heic" | "heif" | "jxl" | "docx" | "docm" | "dotx" | "dotm" | "doc" | "dot" | "pptx" | "pptm" | "potx" | "potm" | "ppsx" | "ppsm" | "rtf" | "odt" | "odp" | "xlsx" | "xltx" | "xlsm" | "xlsb" | "xls" | "xlt" | "xltm" | "csv" | "ods" | "fods" | "numbers" | "ofd" | "typ" | "eml" | "msg" | "mbox" | "olb" | "dra" | "gds" | "oas" | "oasis" | "dxf" | "dwg" | "dwf" | "dwfx" | "xps" | "geojson" | "kml" | "gpx" | "shp" | "excalidraw" | "drawio" | "dio" | "mermaid" | "mmd" | "plantuml" | "puml" | "xmind" | "epub" | "umd" | "md" | "mp4" | "webm" | "m3u8" | "mp3" | "mpeg" | "wav" | "ogg" | "oga" | "opus" | "m4a" | "aac" | "flac" | "weba" | "midi" | "mid" | "ttf" | "otf" | "woff" | "woff2" | "psd" | "ai" | "eps" | "sqlite" | "parquet" | "avro" | "webarchive")[];
331
+ export declare const DEFAULT_SUPPORTED_EXTENSIONS: readonly ("markdown" | "webp" | "jpeg" | "png" | "xyz" | "wasm" | "pdf" | "typst" | "js" | "html" | "svg" | "rb" | "zip" | "zipx" | "7z" | "rar" | "tar" | "gz" | "gzip" | "tgz" | "bz2" | "bzip2" | "tbz" | "tbz2" | "xz" | "txz" | "lzma" | "zst" | "tzst" | "cab" | "ar" | "cpio" | "iso" | "xar" | "lha" | "lzh" | "jar" | "war" | "ear" | "apk" | "cbz" | "cbr" | "glb" | "gltf" | "obj" | "stl" | "ply" | "fbx" | "dae" | "3ds" | "3mf" | "amf" | "usd" | "usda" | "usdc" | "usdz" | "kmz" | "step" | "stp" | "iges" | "igs" | "ifc" | "3dm" | "brep" | "pcd" | "wrl" | "vrml" | "vtk" | "vtp" | "txt" | "json" | "mjs" | "cjs" | "css" | "java" | "py" | "htm" | "jsx" | "ts" | "tsx" | "xml" | "log" | "vue" | "yaml" | "yml" | "ini" | "sh" | "bash" | "sql" | "go" | "rs" | "php" | "c" | "cpp" | "cc" | "h" | "hpp" | "cs" | "diff" | "patch" | "bundle" | "bdl" | "jsonc" | "json5" | "ipynb" | "toml" | "proto" | "hcl" | "tex" | "gv" | "http" | "react" | "swift" | "kt" | "gif" | "jpg" | "bmp" | "tiff" | "tif" | "avif" | "ico" | "heic" | "heif" | "jxl" | "docx" | "docm" | "dotx" | "dotm" | "doc" | "dot" | "ppt" | "pptx" | "pptm" | "potx" | "potm" | "ppsx" | "ppsm" | "rtf" | "odt" | "odp" | "xlsx" | "xltx" | "xlsm" | "xlsb" | "xls" | "xlt" | "xltm" | "csv" | "tsv" | "ods" | "fods" | "numbers" | "ofd" | "typ" | "eml" | "msg" | "mbox" | "olb" | "dra" | "gds" | "oas" | "oasis" | "dxf" | "dwg" | "dwf" | "dwfx" | "xps" | "geojson" | "kml" | "gpx" | "shp" | "excalidraw" | "drawio" | "dio" | "mermaid" | "mmd" | "plantuml" | "puml" | "xmind" | "epub" | "umd" | "md" | "mp4" | "webm" | "m3u8" | "mp3" | "mpeg" | "wav" | "ogg" | "oga" | "opus" | "m4a" | "aac" | "flac" | "weba" | "midi" | "mid" | "ttf" | "otf" | "woff" | "woff2" | "psd" | "ai" | "eps" | "sqlite" | "parquet" | "avro" | "webarchive")[];
@@ -36,9 +36,17 @@ export const DEFAULT_RENDERER_DEFINITIONS = [
36
36
  async: true,
37
37
  capabilities: { download: true, print: 'adapter', exportHtml: 'adapter', zoom: 'provider', search: true },
38
38
  },
39
+ {
40
+ id: 'office-presentation-binary',
41
+ label: 'PowerPoint 97–2003',
42
+ category: 'office',
43
+ extensions: ['ppt'],
44
+ async: true,
45
+ capabilities: { download: true, print: 'adapter', exportHtml: 'adapter', zoom: 'provider', search: false },
46
+ },
39
47
  {
40
48
  id: 'office-presentation',
41
- label: 'PowerPoint',
49
+ label: 'PowerPoint OpenXML',
42
50
  category: 'office',
43
51
  extensions: ['pptx', 'pptm', 'potx', 'potm', 'ppsx', 'ppsm'],
44
52
  async: true,
@@ -56,7 +64,7 @@ export const DEFAULT_RENDERER_DEFINITIONS = [
56
64
  id: 'spreadsheet-openxml',
57
65
  label: 'Spreadsheet',
58
66
  category: 'office',
59
- extensions: ['xlsx', 'xltx', 'xlsm', 'xlsb', 'xls', 'xlt', 'xltm', 'csv', 'ods', 'fods', 'numbers'],
67
+ extensions: ['xlsx', 'xltx', 'xlsm', 'xlsb', 'xls', 'xlt', 'xltm', 'csv', 'tsv', 'ods', 'fods', 'numbers'],
60
68
  async: true,
61
69
  capabilities: { download: true, print: false, exportHtml: false, zoom: 'provider', search: true },
62
70
  },
@@ -19,15 +19,15 @@ const imageMimeMap = {
19
19
  webp: 'image/webp',
20
20
  };
21
21
  const imageStyle = `
22
- .image-viewer{position:relative;width:100%;height:100%;overflow:auto;background:#eef1f4;box-sizing:border-box}
22
+ .image-viewer{position:relative;width:100%;height:100%;overflow:auto;background:var(--file-viewer-render-surface-background,#eef1f4);box-sizing:border-box}
23
23
  .image-stage{min-width:100%;min-height:100%;display:flex;align-items:center;justify-content:center;padding:24px;box-sizing:border-box}
24
24
  .image-stage img{display:block;width:auto;max-width:none;margin:0 auto;border:0;box-shadow:0 18px 48px rgba(15,23,42,.16);background:#fff;cursor:zoom-in}
25
25
  .image-lightbox{position:fixed;inset:0;z-index:2147483000;display:flex;align-items:center;justify-content:center;padding:40px;background:rgba(15,23,42,.88);box-sizing:border-box}
26
26
  .image-lightbox[hidden]{display:none}
27
27
  .image-lightbox img{display:block;max-width:100%;max-height:100%;object-fit:contain;background:#fff;box-shadow:0 30px 80px rgba(0,0,0,.4);cursor:zoom-out}
28
28
  .image-lightbox button{position:absolute;top:20px;right:20px;width:40px;height:40px;border:0;border-radius:999px;background:rgba(255,255,255,.92);color:#172033;font-size:24px;line-height:40px;cursor:pointer;box-shadow:0 12px 28px rgba(0,0,0,.18)}
29
- [data-viewer-theme='dark'] .image-viewer{background:#101820}
30
- @media (prefers-color-scheme:dark){[data-viewer-theme='system'] .image-viewer{background:#101820}}
29
+ [data-viewer-theme='dark'] .image-viewer{background:var(--file-viewer-render-surface-background,#101820)}
30
+ @media (prefers-color-scheme:dark){[data-viewer-theme='system'] .image-viewer{background:var(--file-viewer-render-surface-background,#101820)}}
31
31
  @media (max-width:767px){.image-stage{padding:12px}.image-lightbox{padding:16px}.image-lightbox button{top:12px;right:12px}}
32
32
  `;
33
33
  const createStyle = (documentRef) => {