Sign In

@file-viewer/core

Package Overview
Dependencies
Maintainers
1
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@file-viewer/core - npm Package Compare versions

Comparing version
2.2.4
to
2.2.5
+36
dist/source/precheck.d.ts
import type { FileViewerFileRef, FileViewerSource } from '../contracts/types';
export type FileViewerPrecheckStatus = 'ready' | 'invalid' | 'unsupported';
export type FileViewerPrecheckReason = 'content-valid' | 'content-not-inspected' | 'content-inconclusive' | 'empty-structured-file' | 'signature-mismatch' | 'invalid-package' | 'missing-package-part' | 'unsupported-extension';
export interface FileViewerPrecheckOptions {
/** Filename used when a Blob or ArrayBuffer has no name. */
filename?: string;
/** Explicit extension, with or without a leading dot. */
type?: string;
/** Restricts the result to the renderers installed by the host application. */
supportedExtensions?: Iterable<string>;
/** Maximum ZIP central-directory bytes read from a Blob. Defaults to 8 MiB. */
maxPackageMetadataBytes?: number;
}
export interface FileViewerPrecheckResult {
filename: string;
extension: string;
rendererId: string | null;
supported: boolean;
inspected: boolean;
/** `null` means the extension is supported but no structural validator exists. */
valid: boolean | null;
previewable: boolean;
status: FileViewerPrecheckStatus;
reason: FileViewerPrecheckReason;
missingParts: string[];
}
type FileViewerPrecheckInput = FileViewerSource | FileViewerFileRef;
/**
* Performs a cheap, renderer-free capability and structure check.
*
* This intentionally does not promise rendering fidelity. A `ready` result
* means the extension is available and any known container/signature checks
* passed; the real renderer remains the final authority for malformed content.
*/
export declare const precheckFileViewerSource: (input: FileViewerPrecheckInput, options?: FileViewerPrecheckOptions) => Promise<FileViewerPrecheckResult>;
export {};
import { DEFAULT_RENDERER_DEFINITIONS, DEFAULT_SUPPORTED_EXTENSIONS } from '../registry/formats.js';
import { getExtension, normalizeFileExtension, normalizeFilename, normalizeSource, } from './index.js';
const DEFAULT_MAX_PACKAGE_METADATA_BYTES = 8 * 1024 * 1024;
const ZIP_LOCAL_SIGNATURE = 0x04034b50;
const ZIP_CENTRAL_SIGNATURE = 0x02014b50;
const ZIP_END_SIGNATURE = 0x06054b50;
const ZIP64_SENTINEL = 0xffffffff;
const OLE_SIGNATURE = [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1];
const OPEN_XML_REQUIRED_PARTS = {
docx: ['[content_types].xml', 'word/document.xml'],
docm: ['[content_types].xml', 'word/document.xml'],
dotx: ['[content_types].xml', 'word/document.xml'],
dotm: ['[content_types].xml', 'word/document.xml'],
xlsx: ['[content_types].xml', 'xl/workbook.xml'],
xltx: ['[content_types].xml', 'xl/workbook.xml'],
xlsm: ['[content_types].xml', 'xl/workbook.xml'],
xltm: ['[content_types].xml', 'xl/workbook.xml'],
xlsb: ['[content_types].xml', 'xl/workbook.bin'],
pptx: ['[content_types].xml', 'ppt/presentation.xml'],
pptm: ['[content_types].xml', 'ppt/presentation.xml'],
potx: ['[content_types].xml', 'ppt/presentation.xml'],
potm: ['[content_types].xml', 'ppt/presentation.xml'],
ppsx: ['[content_types].xml', 'ppt/presentation.xml'],
ppsm: ['[content_types].xml', 'ppt/presentation.xml'],
odt: ['content.xml'],
ods: ['content.xml'],
odp: ['content.xml'],
ofd: ['ofd.xml'],
numbers: ['index/document.iwa'],
epub: ['meta-inf/container.xml'],
xps: ['[content_types].xml'],
dwfx: ['[content_types].xml'],
};
const ZIP_EXTENSIONS = new Set([
...Object.keys(OPEN_XML_REQUIRED_PARTS),
'zip', 'zipx', 'jar', 'war', 'ear', 'apk', 'cbz',
]);
const OLE_EXTENSIONS = new Set(['doc', 'dot', 'xls', 'xlt', 'ppt', 'msg']);
const TEXT_DECODER = new TextDecoder('utf-8');
const isArrayBuffer = (value) => value instanceof ArrayBuffer;
const isBlob = (value) => (typeof Blob !== 'undefined' && value instanceof Blob);
const toSource = (input, options) => {
if (isArrayBuffer(input)) {
return { buffer: input, filename: options.filename, type: options.type };
}
if (isBlob(input)) {
return { file: input, filename: options.filename, type: options.type };
}
return {
...input,
filename: options.filename || input.filename,
type: options.type || input.type,
};
};
const startsWithBytes = (bytes, expected) => (expected.every((value, index) => bytes[index] === value));
const findEndOfCentralDirectory = (bytes) => {
for (let offset = bytes.byteLength - 22; offset >= 0; offset -= 1) {
if (bytes[offset] === 0x50 &&
bytes[offset + 1] === 0x4b &&
bytes[offset + 2] === 0x05 &&
bytes[offset + 3] === 0x06) {
return offset;
}
}
return -1;
};
const collectCentralDirectoryEntries = (bytes) => {
const entries = new Set();
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
let offset = 0;
while (offset + 46 <= bytes.byteLength) {
if (view.getUint32(offset, true) !== ZIP_CENTRAL_SIGNATURE) {
break;
}
const filenameLength = view.getUint16(offset + 28, true);
const extraLength = view.getUint16(offset + 30, true);
const commentLength = view.getUint16(offset + 32, true);
const end = offset + 46 + filenameLength;
if (end > bytes.byteLength) {
return { entries, complete: false };
}
entries.add(TEXT_DECODER.decode(bytes.subarray(offset + 46, end)).replace(/^\/+/, '').toLowerCase());
offset = end + extraLength + commentLength;
}
return { entries, complete: offset === bytes.byteLength };
};
const inspectZipBuffer = (buffer) => {
const bytes = new Uint8Array(buffer);
if (bytes.byteLength < 22) {
return { signatureValid: false, complete: true, entries: new Set() };
}
const view = new DataView(buffer);
const firstSignature = view.getUint32(0, true);
if (firstSignature !== ZIP_LOCAL_SIGNATURE && firstSignature !== ZIP_END_SIGNATURE) {
return { signatureValid: false, complete: true, entries: new Set() };
}
const endOffset = findEndOfCentralDirectory(bytes);
if (endOffset < 0) {
return { signatureValid: true, complete: false, entries: new Set() };
}
const centralSize = view.getUint32(endOffset + 12, true);
const centralOffset = view.getUint32(endOffset + 16, true);
if (centralSize === ZIP64_SENTINEL || centralOffset === ZIP64_SENTINEL) {
return { signatureValid: true, complete: false, entries: new Set() };
}
if (centralOffset + centralSize > bytes.byteLength) {
return { signatureValid: true, complete: false, entries: new Set() };
}
const result = collectCentralDirectoryEntries(bytes.subarray(centralOffset, centralOffset + centralSize));
return { signatureValid: true, complete: result.complete, entries: result.entries };
};
const inspectZipBlob = async (blob, maxPackageMetadataBytes) => {
if (blob.size < 22) {
return { signatureValid: false, complete: true, entries: new Set() };
}
const prefix = new Uint8Array(await blob.slice(0, 4).arrayBuffer());
const prefixView = new DataView(prefix.buffer, prefix.byteOffset, prefix.byteLength);
const firstSignature = prefixView.getUint32(0, true);
if (firstSignature !== ZIP_LOCAL_SIGNATURE && firstSignature !== ZIP_END_SIGNATURE) {
return { signatureValid: false, complete: true, entries: new Set() };
}
const tailStart = Math.max(0, blob.size - 65557);
const tail = new Uint8Array(await blob.slice(tailStart).arrayBuffer());
const endOffset = findEndOfCentralDirectory(tail);
if (endOffset < 0) {
return { signatureValid: true, complete: false, entries: new Set() };
}
const tailView = new DataView(tail.buffer, tail.byteOffset, tail.byteLength);
const centralSize = tailView.getUint32(endOffset + 12, true);
const centralOffset = tailView.getUint32(endOffset + 16, true);
if (centralSize === ZIP64_SENTINEL ||
centralOffset === ZIP64_SENTINEL ||
centralSize > maxPackageMetadataBytes ||
centralOffset + centralSize > blob.size) {
return { signatureValid: true, complete: false, entries: new Set() };
}
const central = new Uint8Array(await blob.slice(centralOffset, centralOffset + centralSize).arrayBuffer());
const result = collectCentralDirectoryEntries(central);
return { signatureValid: true, complete: result.complete, entries: result.entries };
};
const inspectZip = async (source, maxPackageMetadataBytes) => {
if (source.buffer) {
return inspectZipBuffer(source.buffer);
}
if (source.file) {
return inspectZipBlob(source.file, maxPackageMetadataBytes);
}
return null;
};
const readPrefix = async (source, byteLength = 1024) => {
if (source.buffer) {
return new Uint8Array(source.buffer, 0, Math.min(source.buffer.byteLength, byteLength));
}
if (source.file) {
return new Uint8Array(await source.file.slice(0, byteLength).arrayBuffer());
}
return null;
};
const inspectStructuredContent = async (source, extension, maxPackageMetadataBytes) => {
var _a, _b, _c;
const size = (_b = (_a = source.buffer) === null || _a === void 0 ? void 0 : _a.byteLength) !== null && _b !== void 0 ? _b : (_c = source.file) === null || _c === void 0 ? void 0 : _c.size;
if (size === 0 && (ZIP_EXTENSIONS.has(extension) || OLE_EXTENSIONS.has(extension) || extension === 'pdf')) {
return { inspected: true, valid: false, reason: 'empty-structured-file' };
}
if (ZIP_EXTENSIONS.has(extension)) {
const zip = await inspectZip(source, maxPackageMetadataBytes);
if (!zip) {
return { inspected: false, valid: null, reason: 'content-not-inspected' };
}
if (!zip.signatureValid) {
return { inspected: true, valid: false, reason: 'signature-mismatch' };
}
const required = OPEN_XML_REQUIRED_PARTS[extension] || [];
if (!zip.complete) {
return { inspected: true, valid: null, reason: 'content-inconclusive' };
}
const missingParts = required.filter(part => !zip.entries.has(part));
if (missingParts.length) {
return { inspected: true, valid: false, reason: 'missing-package-part', missingParts };
}
return { inspected: true, valid: true, reason: 'content-valid' };
}
const prefix = await readPrefix(source);
if (!prefix) {
return { inspected: false, valid: null, reason: 'content-not-inspected' };
}
if (OLE_EXTENSIONS.has(extension)) {
return startsWithBytes(prefix, OLE_SIGNATURE)
? { inspected: true, valid: true, reason: 'content-valid' }
: { inspected: true, valid: false, reason: 'signature-mismatch' };
}
if (extension === 'pdf') {
const header = TEXT_DECODER.decode(prefix);
return /%PDF-\d\.\d/.test(header)
? { inspected: true, valid: true, reason: 'content-valid' }
: { inspected: true, valid: false, reason: 'signature-mismatch' };
}
if (extension === 'rtf') {
const header = TEXT_DECODER.decode(prefix);
return /^\s*\{\\rtf\d/.test(header)
? { inspected: true, valid: true, reason: 'content-valid' }
: { inspected: true, valid: false, reason: 'signature-mismatch' };
}
return { inspected: false, valid: null, reason: 'content-not-inspected' };
};
/**
* Performs a cheap, renderer-free capability and structure check.
*
* This intentionally does not promise rendering fidelity. A `ready` result
* means the extension is available and any known container/signature checks
* passed; the real renderer remains the final authority for malformed content.
*/
export const precheckFileViewerSource = async (input, options = {}) => {
var _a;
const source = toSource(input, options);
const normalized = normalizeSource(source);
const extension = normalizeFileExtension(options.type || normalized.extension || getExtension(options.filename || normalized.filename));
const filename = normalizeFilename(options.filename || normalized.filename);
const supportedExtensions = new Set(Array.from(options.supportedExtensions || DEFAULT_SUPPORTED_EXTENSIONS, normalizeFileExtension));
const supported = supportedExtensions.has(extension);
const rendererId = ((_a = DEFAULT_RENDERER_DEFINITIONS.find(definition => definition.extensions.some(candidate => normalizeFileExtension(candidate) === extension))) === null || _a === void 0 ? void 0 : _a.id) || null;
if (!supported) {
return {
filename,
extension,
rendererId,
supported: false,
inspected: false,
valid: null,
previewable: false,
status: 'unsupported',
reason: 'unsupported-extension',
missingParts: [],
};
}
const inspection = await inspectStructuredContent(source, extension, Math.max(64 * 1024, options.maxPackageMetadataBytes || DEFAULT_MAX_PACKAGE_METADATA_BYTES));
const valid = inspection.valid;
return {
filename,
extension,
rendererId,
supported: true,
inspected: inspection.inspected,
valid,
previewable: valid !== false,
status: valid === false ? 'invalid' : 'ready',
reason: inspection.reason,
missingParts: inspection.missingParts || [],
};
};
+58
-3

@@ -6,3 +6,3 @@ export type FileViewerSourceKind = 'file' | 'url' | 'buffer' | 'empty';

export type FileViewerStyleIsolation = 'auto' | 'shadow' | 'scoped' | 'none';
export type FileViewerMessageKey = 'toolbar.zoomGroup' | 'toolbar.zoomOut' | 'toolbar.zoomIn' | 'toolbar.zoomReset' | 'toolbar.download' | 'toolbar.downloadTitle' | 'toolbar.print' | 'toolbar.printTitle' | 'toolbar.printDirect' | 'toolbar.printMask' | 'toolbar.printMaskTitle' | 'toolbar.printMaskAdd' | 'toolbar.printMaskClear' | 'toolbar.printMaskCancel' | 'toolbar.printMaskConfirm' | 'toolbar.printMaskHint' | 'toolbar.exportHtml' | 'toolbar.exportHtmlTitle' | 'toolbar.search' | 'toolbar.searchPlaceholder' | 'toolbar.searchPrevious' | 'toolbar.searchNext' | 'toolbar.searchClear' | 'toolbar.theme' | 'toolbar.themeToLight' | 'toolbar.themeToDark' | 'state.ready.title' | 'state.ready.message' | 'state.empty.title' | 'state.empty.message' | 'state.unsupported.install.title' | 'state.unsupported.install.message' | 'state.unsupported.install.description' | 'state.unsupported.title' | 'state.unsupported.message' | 'state.unsupported.description' | 'state.error.title' | 'preview.downloading' | 'preview.streamingPdf' | 'preview.reading' | 'error.download' | 'error.print' | 'error.exportHtml' | 'error.noDownloadSource' | 'error.noExportContent' | 'error.printUnavailable' | 'error.printWindowBlocked' | 'error.remoteDownload' | 'error.localRead' | 'error.load' | 'error.stream' | 'error.beforeOperation' | 'error.unknown' | 'error.blobUnavailable' | 'error.sourceUnsupported' | 'error.fileReadArrayBuffer' | 'error.fileReadDataUrl' | 'error.fileReadText' | 'error.imageDataUrlRead' | 'operation.download' | 'operation.print' | 'operation.exportHtml' | 'operation.zoomIn' | 'operation.zoomOut' | 'operation.zoomReset' | 'pdf.toolbar.toggleNavigation' | 'pdf.toolbar.previousPage' | 'pdf.toolbar.nextPage' | 'pdf.toolbar.fitWidth' | 'pdf.toolbar.zoomOut' | 'pdf.toolbar.zoomIn' | 'pdf.toolbar.rotateLeft' | 'pdf.toolbar.rotateRight' | 'pdf.nav.typeLabel' | 'pdf.nav.pagesTab' | 'pdf.nav.outlineTab' | 'pdf.nav.pagesTitle' | 'pdf.nav.outlineTitle' | 'pdf.nav.pageCount' | 'pdf.nav.itemCount' | 'pdf.nav.pageLabel' | 'pdf.nav.outlineEmpty' | 'pdf.nav.outlineFallbackTitle' | 'pdf.thumbnail.alt' | 'pdf.state.loading' | 'pdf.error.browserWindow' | 'pdf.error.missingSource' | 'pdf.error.loadFailed' | 'pdf.error.notLoaded' | 'pdf.error.unloaded' | 'pdf.error.canvasUnavailable' | 'pdf.export.pageTitle' | 'spreadsheet.loading.kicker' | 'spreadsheet.loading.title' | 'spreadsheet.loading.hint' | 'spreadsheet.loading.streaming' | 'spreadsheet.tabs.ariaLabel' | 'spreadsheet.state.parsingWorkbook' | 'spreadsheet.state.preparingSheet' | 'spreadsheet.state.preparingSheetNamed' | 'spreadsheet.state.cachedRows' | 'spreadsheet.state.rows' | 'spreadsheet.state.rowsAndColumns' | 'spreadsheet.error.parseFailed' | 'spreadsheet.error.workerFailed' | 'word.error.invalidDocx' | 'word.error.missingOdfContent' | 'word.error.odfXmlParseFailed' | 'word.title.rtf' | 'word.title.openDocumentPresentation' | 'word.title.openDocumentText' | 'word.page.fallback' | 'word.page.empty' | 'word.body' | 'word.body.empty' | 'ofd.state.loading' | 'ofd.error.empty' | 'ofd.error.parseFailed' | 'presentation.state.loading' | 'presentation.error.title' | 'presentation.error.parseFailed' | 'presentation.ppt.state.loading' | 'presentation.ppt.error.title' | 'presentation.ppt.error.parseFailed' | 'presentation.ppt.error.assetHint' | 'archive.error.nestedUnsupported' | 'archive.loading.readingDirectory' | 'archive.loading.readingDirectoryHint' | 'archive.search.placeholder' | 'archive.sidebar.hide' | 'archive.sidebar.show' | 'archive.preview.title' | 'archive.preview.chooseFile' | 'archive.preview.downloadFile' | 'archive.error.title' | 'archive.stats.summary' | 'archive.warning.encrypted' | 'archive.password.title' | 'archive.password.description' | 'archive.password.placeholder' | 'archive.password.invalid' | 'archive.password.required' | 'archive.password.cancel' | 'archive.password.confirm' | 'archive.error.passwordRequired' | 'archive.error.encryptedRequiresWorker' | 'archive.empty.title' | 'archive.empty.message' | 'archive.loading.initializingCandidate' | 'archive.loading.initializingCandidateHint' | 'archive.error.candidateInitTimeout' | 'archive.error.encryptedCheckTimeout' | 'archive.loading.directoryReadyHint' | 'archive.error.candidateReadTimeout' | 'archive.loading.workerFallback' | 'archive.loading.workerFallbackHint' | 'archive.notice.workerFallback' | 'archive.error.tooLarge' | 'archive.loading.initializingWorker' | 'archive.loading.initializingWorkerHint' | 'archive.error.workerInitFailed' | 'archive.error.workerUnsupported' | 'archive.error.indexedDbUnavailable' | 'archive.error.entryTooLarge' | 'archive.loading.extracting' | 'archive.loading.rendering' | 'archive.loading.exporting' | 'media.audio.title' | 'media.audio.description' | 'media.audio.unsupported' | 'media.video.title' | 'media.video.unsupported' | 'media.video.hlsHint' | 'media.midi.title' | 'media.midi.loading' | 'media.midi.trackHeader' | 'media.midi.instrumentHeader' | 'media.midi.channelHeader' | 'media.midi.noteCountHeader' | 'media.midi.durationHeader' | 'media.midi.durationStat' | 'media.midi.trackStat' | 'media.midi.noteStat' | 'media.midi.parseFailed' | 'email.mbox.subject' | 'email.mbox.summary' | 'email.error.title' | 'email.meta.from' | 'email.meta.to' | 'email.meta.cc' | 'email.meta.date' | 'email.tabs.text' | 'email.tabs.headers' | 'email.attachments.title' | 'email.attachments.empty' | 'email.attachments.download' | 'email.attachments.opening' | 'email.attachments.nestedUnavailable' | 'email.loading.parsing' | 'data.font.sample' | 'data.error.fontFaceUnsupported' | 'data.title.font' | 'data.title.sqlite' | 'data.title.parquet' | 'data.title.avro' | 'data.title.wasm' | 'data.title.eps' | 'data.title.ai' | 'data.title.webarchive' | 'data.title.summary' | 'data.label.format' | 'data.label.size' | 'data.label.rendering' | 'data.label.objects' | 'data.label.sampleTable' | 'data.label.rows' | 'data.label.columns' | 'data.label.sampleRows' | 'data.label.imports' | 'data.label.exports' | 'data.label.magic' | 'data.label.note' | 'data.label.container' | 'data.value.schemaRead' | 'data.value.schemaUnread' | 'data.note.aiSummary' | 'data.note.postscriptSummary' | 'data.note.webarchive' | 'data.image.alt' | 'psd.title' | 'psd.action.fit' | 'psd.action.showAll' | 'psd.action.hideAll' | 'psd.layers.title' | 'psd.layers.redrawable' | 'psd.layers.empty' | 'psd.layers.hidden' | 'drawing.error.viewerLoadFailed' | 'drawing.error.excalidrawEmpty' | 'drawing.error.excalidrawTimeout' | 'drawing.error.drawioParseFailed' | 'drawing.error.drawioNoModel' | 'drawing.error.drawioNoElements' | 'drawing.error.viewerInitFailed' | 'drawing.error.drawioTimeout' | 'drawing.error.svgParseFailed' | 'drawing.error.plantumlRenderFailed' | 'drawing.title.excalidraw' | 'drawing.title.mermaid' | 'drawing.title.plantuml' | 'drawing.title.drawio' | 'drawing.toolbar.zoomOut' | 'drawing.toolbar.zoomIn' | 'drawing.toolbar.fit' | 'drawing.toolbar.fitWidth' | 'drawing.state.loading' | 'text.code.loadingHighlight' | 'text.code.indexingLargeFile' | 'text.code.virtualized' | 'text.code.firstSegment' | 'text.code.previousSegment' | 'text.code.nextSegment' | 'text.code.lastSegment' | 'ebook.toc' | 'ebook.reading' | 'ebook.itemCount' | 'epub.title' | 'epub.previousPage' | 'epub.nextPage' | 'epub.loading' | 'epub.chapterFallback' | 'epub.renderIncomplete' | 'umd.title' | 'umd.previousChapter' | 'umd.nextChapter' | 'umd.loading' | 'umd.emptyContent' | 'umd.chapterFallback' | 'umd.galleryFallback' | 'umd.warningBodyTooShort' | 'umd.error.unexpectedEnd' | 'umd.error.invalidFile' | 'typst.summaryRenderer' | 'typst.pageSummary.empty' | 'typst.pageSummary.ready' | 'typst.status.compiling' | 'typst.status.failed' | 'typst.status.rendered' | 'typst.loading.title' | 'typst.loading.hint' | 'typst.error.title' | 'typst.error.timeout' | 'typst.error.timeoutHint' | 'typst.error.assetHint' | 'typst.error.svgParseFailed' | 'typst.error.wasmLoadFailed' | 'xmind.toolbar.zoomOut' | 'xmind.toolbar.zoomIn' | 'xmind.toolbar.fit' | 'xmind.toolbar.fitTitle' | 'xmind.state.loading' | 'xmind.stats.nodes' | 'xmind.stats.depth' | 'xmind.stats.theme' | 'xmind.stats.template' | 'xmind.badge.paused' | 'xmind.badge.collapsed' | 'xmind.badge.floating' | 'xmind.badge.summary' | 'xmind.badge.callout' | 'xmind.imageResource' | 'xmind.error.unrecognized' | 'xmind.error.noCanvas' | 'cad.toolbar.fit' | 'cad.toolbar.zoomOut' | 'cad.toolbar.zoomIn' | 'cad.layers.title' | 'cad.layers.count' | 'cad.layers.merged' | 'cad.inspector.title' | 'cad.inspector.entities' | 'cad.inspector.blocks' | 'cad.inspector.pages' | 'cad.inspector.drawn' | 'cad.state.loadingViewer' | 'cad.state.parsing' | 'cad.error.parseFailed' | 'image.alt' | 'image.lightbox.alt' | 'image.lightbox.close' | 'gitBundle.error.invalid' | 'gitBundle.error.missingPack' | 'gitBundle.notice.delta' | 'gitBundle.title.history' | 'gitBundle.title.fileTree' | 'gitBundle.file.choose' | 'gitBundle.file.noTree' | 'gitBundle.file.none' | 'gitBundle.history.empty' | 'gitBundle.toolbar.summary' | 'gitBundle.meta.bundle' | 'gitBundle.meta.refs' | 'gitBundle.meta.commits' | 'gitBundle.meta.objects' | 'gitBundle.meta.deltas' | 'gitBundle.meta.objectFormat' | 'gitBundle.meta.objectTypes' | 'geo.error.unrecognized' | 'geo.error.xmlParseFailed' | 'geo.error.unsupported' | 'geo.title' | 'geo.featureCount' | 'geo.bounds' | 'geo.geometryTypes' | 'geo.aria' | 'geo.loading' | 'geo.projection' | 'geo.engine' | 'geo.basemap' | 'geo.basemap.offline' | 'geo.basemap.custom' | 'geo.engine.maplibre' | 'geo.engine.svg' | 'geo.error.projection' | 'geo.action.fit' | 'model.toolbar.fit' | 'model.toolbar.rotate' | 'model.toolbar.wireframe' | 'model.toolbar.grid' | 'model.toolbar.axes' | 'model.state.loadingSummary' | 'model.state.loading' | 'model.state.loaded' | 'model.state.parseFailed' | 'model.summary.meshes' | 'model.summary.points' | 'model.error.daeEmpty' | 'model.error.unsupported' | 'model.error.parseFailed' | 'model.notice.signature' | 'loading.generic.label' | 'loading.generic.hint' | 'loading.word.label' | 'loading.word.hint' | 'loading.wordWorker.hint' | 'loading.sheet.label' | 'loading.sheet.hint' | 'loading.csv.label' | 'loading.csv.hint' | 'loading.presentation.label' | 'loading.presentation.hint' | 'loading.pdf.label' | 'loading.pdf.hint' | 'loading.ofd.label' | 'loading.ofd.hint' | 'loading.archive.label' | 'loading.archive.hint' | 'loading.email.label' | 'loading.email.hint' | 'loading.msg.hint' | 'loading.eda.label' | 'loading.eda.hint' | 'loading.cad.label' | 'loading.cad.hint' | 'loading.dwg.hint' | 'loading.dwf.hint' | 'loading.dwfx.hint' | 'loading.xps.hint' | 'loading.drawio.label' | 'loading.drawio.hint' | 'loading.excalidraw.label' | 'loading.excalidraw.hint' | 'loading.epub.label' | 'loading.epub.hint' | 'loading.umd.label' | 'loading.umd.hint' | 'loading.image.label' | 'loading.image.hint' | 'loading.video.label' | 'loading.video.hint' | 'loading.audio.label' | 'loading.audio.hint';
export type FileViewerMessageKey = 'toolbar.zoomGroup' | 'toolbar.zoomOut' | 'toolbar.zoomIn' | 'toolbar.zoomReset' | 'toolbar.download' | 'toolbar.downloadTitle' | 'toolbar.print' | 'toolbar.printTitle' | 'toolbar.printDirect' | 'toolbar.printMask' | 'toolbar.printMaskTitle' | 'toolbar.printMaskAdd' | 'toolbar.printMaskClear' | 'toolbar.printMaskCancel' | 'toolbar.printMaskConfirm' | 'toolbar.printMaskHint' | 'toolbar.printStampUpload' | 'toolbar.printStampRemove' | 'toolbar.printStampResize' | 'toolbar.exportHtml' | 'toolbar.exportHtmlTitle' | 'toolbar.search' | 'toolbar.searchPlaceholder' | 'toolbar.searchPrevious' | 'toolbar.searchNext' | 'toolbar.searchClear' | 'toolbar.theme' | 'toolbar.themeToLight' | 'toolbar.themeToDark' | 'state.ready.title' | 'state.ready.message' | 'state.empty.title' | 'state.empty.message' | 'state.unsupported.install.title' | 'state.unsupported.install.message' | 'state.unsupported.install.description' | 'state.unsupported.title' | 'state.unsupported.message' | 'state.unsupported.description' | 'state.error.title' | 'preview.downloading' | 'preview.streamingPdf' | 'preview.reading' | 'error.download' | 'error.print' | 'error.exportHtml' | 'error.noDownloadSource' | 'error.noExportContent' | 'error.printUnavailable' | 'error.printWindowBlocked' | 'error.remoteDownload' | 'error.localRead' | 'error.load' | 'error.stream' | 'error.beforeOperation' | 'error.unknown' | 'error.blobUnavailable' | 'error.sourceUnsupported' | 'error.fileReadArrayBuffer' | 'error.fileReadDataUrl' | 'error.fileReadText' | 'error.imageDataUrlRead' | 'operation.download' | 'operation.print' | 'operation.exportHtml' | 'operation.zoomIn' | 'operation.zoomOut' | 'operation.zoomReset' | 'pdf.toolbar.toggleNavigation' | 'pdf.toolbar.previousPage' | 'pdf.toolbar.nextPage' | 'pdf.toolbar.fitWidth' | 'pdf.toolbar.zoomOut' | 'pdf.toolbar.zoomIn' | 'pdf.toolbar.rotateLeft' | 'pdf.toolbar.rotateRight' | 'pdf.nav.typeLabel' | 'pdf.nav.pagesTab' | 'pdf.nav.outlineTab' | 'pdf.nav.pagesTitle' | 'pdf.nav.outlineTitle' | 'pdf.nav.pageCount' | 'pdf.nav.itemCount' | 'pdf.nav.pageLabel' | 'pdf.nav.outlineEmpty' | 'pdf.nav.outlineFallbackTitle' | 'pdf.thumbnail.alt' | 'pdf.state.loading' | 'pdf.error.browserWindow' | 'pdf.error.missingSource' | 'pdf.error.loadFailed' | 'pdf.error.notLoaded' | 'pdf.error.unloaded' | 'pdf.error.canvasUnavailable' | 'pdf.export.pageTitle' | 'spreadsheet.loading.kicker' | 'spreadsheet.loading.title' | 'spreadsheet.loading.hint' | 'spreadsheet.loading.streaming' | 'spreadsheet.tabs.ariaLabel' | 'spreadsheet.state.parsingWorkbook' | 'spreadsheet.state.preparingSheet' | 'spreadsheet.state.preparingSheetNamed' | 'spreadsheet.state.cachedRows' | 'spreadsheet.state.rows' | 'spreadsheet.state.rowsAndColumns' | 'spreadsheet.error.parseFailed' | 'spreadsheet.error.workerFailed' | 'word.error.invalidDocx' | 'word.error.missingOdfContent' | 'word.error.odfXmlParseFailed' | 'word.title.rtf' | 'word.title.openDocumentPresentation' | 'word.title.openDocumentText' | 'word.page.fallback' | 'word.page.empty' | 'word.body' | 'word.body.empty' | 'ofd.state.loading' | 'ofd.error.empty' | 'ofd.error.parseFailed' | 'presentation.state.loading' | 'presentation.error.title' | 'presentation.error.parseFailed' | 'presentation.ppt.state.loading' | 'presentation.ppt.error.title' | 'presentation.ppt.error.parseFailed' | 'presentation.ppt.error.assetHint' | 'archive.error.nestedUnsupported' | 'archive.loading.readingDirectory' | 'archive.loading.readingDirectoryHint' | 'archive.search.placeholder' | 'archive.sidebar.hide' | 'archive.sidebar.show' | 'archive.preview.title' | 'archive.preview.chooseFile' | 'archive.preview.downloadFile' | 'archive.error.title' | 'archive.stats.summary' | 'archive.warning.encrypted' | 'archive.password.title' | 'archive.password.description' | 'archive.password.placeholder' | 'archive.password.invalid' | 'archive.password.required' | 'archive.password.cancel' | 'archive.password.confirm' | 'archive.error.passwordRequired' | 'archive.error.encryptedRequiresWorker' | 'archive.empty.title' | 'archive.empty.message' | 'archive.loading.initializingCandidate' | 'archive.loading.initializingCandidateHint' | 'archive.error.candidateInitTimeout' | 'archive.error.encryptedCheckTimeout' | 'archive.loading.directoryReadyHint' | 'archive.error.candidateReadTimeout' | 'archive.loading.workerFallback' | 'archive.loading.workerFallbackHint' | 'archive.notice.workerFallback' | 'archive.error.tooLarge' | 'archive.loading.initializingWorker' | 'archive.loading.initializingWorkerHint' | 'archive.error.workerInitFailed' | 'archive.error.workerUnsupported' | 'archive.error.indexedDbUnavailable' | 'archive.error.entryTooLarge' | 'archive.loading.extracting' | 'archive.loading.rendering' | 'archive.loading.exporting' | 'media.audio.title' | 'media.audio.description' | 'media.audio.unsupported' | 'media.video.title' | 'media.video.unsupported' | 'media.video.hlsHint' | 'media.midi.title' | 'media.midi.loading' | 'media.midi.trackHeader' | 'media.midi.instrumentHeader' | 'media.midi.channelHeader' | 'media.midi.noteCountHeader' | 'media.midi.durationHeader' | 'media.midi.durationStat' | 'media.midi.trackStat' | 'media.midi.noteStat' | 'media.midi.parseFailed' | 'email.mbox.subject' | 'email.mbox.summary' | 'email.error.title' | 'email.meta.from' | 'email.meta.to' | 'email.meta.cc' | 'email.meta.date' | 'email.tabs.text' | 'email.tabs.headers' | 'email.attachments.title' | 'email.attachments.empty' | 'email.attachments.download' | 'email.attachments.opening' | 'email.attachments.nestedUnavailable' | 'email.loading.parsing' | 'data.font.sample' | 'data.error.fontFaceUnsupported' | 'data.title.font' | 'data.title.sqlite' | 'data.title.parquet' | 'data.title.avro' | 'data.title.wasm' | 'data.title.eps' | 'data.title.ai' | 'data.title.webarchive' | 'data.title.summary' | 'data.label.format' | 'data.label.size' | 'data.label.rendering' | 'data.label.objects' | 'data.label.sampleTable' | 'data.label.rows' | 'data.label.columns' | 'data.label.sampleRows' | 'data.label.imports' | 'data.label.exports' | 'data.label.magic' | 'data.label.note' | 'data.label.container' | 'data.value.schemaRead' | 'data.value.schemaUnread' | 'data.note.aiSummary' | 'data.note.postscriptSummary' | 'data.note.webarchive' | 'data.image.alt' | 'psd.title' | 'psd.action.fit' | 'psd.action.showAll' | 'psd.action.hideAll' | 'psd.layers.title' | 'psd.layers.redrawable' | 'psd.layers.empty' | 'psd.layers.hidden' | 'drawing.error.viewerLoadFailed' | 'drawing.error.excalidrawEmpty' | 'drawing.error.excalidrawTimeout' | 'drawing.error.drawioParseFailed' | 'drawing.error.drawioNoModel' | 'drawing.error.drawioNoElements' | 'drawing.error.viewerInitFailed' | 'drawing.error.drawioTimeout' | 'drawing.error.svgParseFailed' | 'drawing.error.plantumlRenderFailed' | 'drawing.title.excalidraw' | 'drawing.title.mermaid' | 'drawing.title.plantuml' | 'drawing.title.drawio' | 'drawing.toolbar.zoomOut' | 'drawing.toolbar.zoomIn' | 'drawing.toolbar.fit' | 'drawing.toolbar.fitWidth' | 'drawing.state.loading' | 'text.code.loadingHighlight' | 'text.code.indexingLargeFile' | 'text.code.virtualized' | 'text.code.firstSegment' | 'text.code.previousSegment' | 'text.code.nextSegment' | 'text.code.lastSegment' | 'ebook.toc' | 'ebook.reading' | 'ebook.itemCount' | 'epub.title' | 'epub.previousPage' | 'epub.nextPage' | 'epub.loading' | 'epub.chapterFallback' | 'epub.renderIncomplete' | 'umd.title' | 'umd.previousChapter' | 'umd.nextChapter' | 'umd.loading' | 'umd.emptyContent' | 'umd.chapterFallback' | 'umd.galleryFallback' | 'umd.warningBodyTooShort' | 'umd.error.unexpectedEnd' | 'umd.error.invalidFile' | 'typst.summaryRenderer' | 'typst.pageSummary.empty' | 'typst.pageSummary.ready' | 'typst.status.compiling' | 'typst.status.failed' | 'typst.status.rendered' | 'typst.loading.title' | 'typst.loading.hint' | 'typst.error.title' | 'typst.error.timeout' | 'typst.error.timeoutHint' | 'typst.error.assetHint' | 'typst.error.svgParseFailed' | 'typst.error.wasmLoadFailed' | 'xmind.toolbar.zoomOut' | 'xmind.toolbar.zoomIn' | 'xmind.toolbar.fit' | 'xmind.toolbar.fitTitle' | 'xmind.state.loading' | 'xmind.stats.nodes' | 'xmind.stats.depth' | 'xmind.stats.theme' | 'xmind.stats.template' | 'xmind.badge.paused' | 'xmind.badge.collapsed' | 'xmind.badge.floating' | 'xmind.badge.summary' | 'xmind.badge.callout' | 'xmind.imageResource' | 'xmind.error.unrecognized' | 'xmind.error.noCanvas' | 'cad.toolbar.fit' | 'cad.toolbar.zoomOut' | 'cad.toolbar.zoomIn' | 'cad.layers.title' | 'cad.layers.count' | 'cad.layers.merged' | 'cad.inspector.title' | 'cad.inspector.entities' | 'cad.inspector.blocks' | 'cad.inspector.pages' | 'cad.inspector.drawn' | 'cad.state.loadingViewer' | 'cad.state.parsing' | 'cad.error.parseFailed' | 'image.alt' | 'image.toolbar.rotation' | 'image.toolbar.rotateLeft' | 'image.toolbar.rotateRight' | 'image.lightbox.alt' | 'image.lightbox.close' | 'gitBundle.error.invalid' | 'gitBundle.error.missingPack' | 'gitBundle.notice.delta' | 'gitBundle.title.history' | 'gitBundle.title.fileTree' | 'gitBundle.file.choose' | 'gitBundle.file.noTree' | 'gitBundle.file.none' | 'gitBundle.history.empty' | 'gitBundle.toolbar.summary' | 'gitBundle.meta.bundle' | 'gitBundle.meta.refs' | 'gitBundle.meta.commits' | 'gitBundle.meta.objects' | 'gitBundle.meta.deltas' | 'gitBundle.meta.objectFormat' | 'gitBundle.meta.objectTypes' | 'geo.error.unrecognized' | 'geo.error.xmlParseFailed' | 'geo.error.unsupported' | 'geo.title' | 'geo.featureCount' | 'geo.bounds' | 'geo.geometryTypes' | 'geo.aria' | 'geo.loading' | 'geo.projection' | 'geo.engine' | 'geo.basemap' | 'geo.basemap.offline' | 'geo.basemap.custom' | 'geo.engine.maplibre' | 'geo.engine.svg' | 'geo.error.projection' | 'geo.action.fit' | 'model.toolbar.fit' | 'model.toolbar.rotate' | 'model.toolbar.wireframe' | 'model.toolbar.grid' | 'model.toolbar.axes' | 'model.state.loadingSummary' | 'model.state.loading' | 'model.state.loaded' | 'model.state.parseFailed' | 'model.summary.meshes' | 'model.summary.points' | 'model.error.daeEmpty' | 'model.error.unsupported' | 'model.error.parseFailed' | 'model.notice.signature' | 'loading.generic.label' | 'loading.generic.hint' | 'loading.word.label' | 'loading.word.hint' | 'loading.wordWorker.hint' | 'loading.sheet.label' | 'loading.sheet.hint' | 'loading.csv.label' | 'loading.csv.hint' | 'loading.presentation.label' | 'loading.presentation.hint' | 'loading.pdf.label' | 'loading.pdf.hint' | 'loading.ofd.label' | 'loading.ofd.hint' | 'loading.archive.label' | 'loading.archive.hint' | 'loading.email.label' | 'loading.email.hint' | 'loading.msg.hint' | 'loading.eda.label' | 'loading.eda.hint' | 'loading.cad.label' | 'loading.cad.hint' | 'loading.dwg.hint' | 'loading.dwf.hint' | 'loading.dwfx.hint' | 'loading.xps.hint' | 'loading.drawio.label' | 'loading.drawio.hint' | 'loading.excalidraw.label' | 'loading.excalidraw.hint' | 'loading.epub.label' | 'loading.epub.hint' | 'loading.umd.label' | 'loading.umd.hint' | 'loading.image.label' | 'loading.image.hint' | 'loading.video.label' | 'loading.video.hint' | 'loading.audio.label' | 'loading.audio.hint';
export type FileViewerMessageParams = Record<string, string | number | boolean | null | undefined>;

@@ -119,2 +119,8 @@ export type FileViewerMessageResolver = (key: FileViewerMessageKey, params: FileViewerMessageParams, locale: FileViewerLocale) => string | undefined;

/**
* Highlights and focuses one or more PDF regions after the document loads.
* Use `pixel` with `sourceWidth` / `sourceHeight` for OCR coordinates, or
* `pdf-point` for native PDF coordinates. Page numbers are one-based.
*/
bbox?: FileViewerPdfBoundingBox | readonly FileViewerPdfBoundingBox[];
/**
* Initial PDF view position. Prefer the top-level `initialViewState` when the

@@ -155,2 +161,25 @@ * same state should be passed through framework-neutral viewer APIs.

}
export type FileViewerPdfBoundingBoxUnit = 'ratio' | 'percent' | 'pixel' | 'pdf-point';
export type FileViewerPdfBoundingBoxOrigin = 'top-left' | 'bottom-left';
export interface FileViewerPdfBoundingBox {
id?: string;
/** One-based PDF page number. Defaults to the current page, then page 1. */
page?: number;
x: number;
y: number;
width: number;
height: number;
/** Defaults to `pdf-point`. */
unit?: FileViewerPdfBoundingBoxUnit;
/** Defaults to `bottom-left` for PDF points and `top-left` otherwise. */
origin?: FileViewerPdfBoundingBoxOrigin;
/** Required when `unit` is `pixel`; this is the OCR/source image width. */
sourceWidth?: number;
/** Required when `unit` is `pixel`; this is the OCR/source image height. */
sourceHeight?: number;
/** CSS color used for the outline and translucent fill. */
color?: string;
/** Optional accessible description for the highlighted region. */
label?: string;
}
export interface FileViewerDocxOptions {

@@ -322,3 +351,4 @@ worker?: boolean;

}
export type FileViewerGeoBasemapPreset = 'none' | 'offline' | 'openfreemap' | 'openfreemap-liberty' | 'openfreemap-bright' | 'openfreemap-positron' | 'openfreemap-dark' | 'openfreemap-fiord' | 'osm-raster';
export type FileViewerGeoBasemapPreset = 'none' | 'offline' | 'openfreemap' | 'openfreemap-liberty' | 'openfreemap-bright' | 'openfreemap-positron' | 'openfreemap-dark' | 'openfreemap-fiord' | 'osm-raster' | 'tianditu-vector' | 'tianditu-imagery' | 'tianditu-terrain';
export type FileViewerTiandituMapStyle = 'vector' | 'imagery' | 'terrain';
export interface FileViewerGeoBasemapOptions {

@@ -328,4 +358,6 @@ /**

* object or URL, which is the best path for OpenFreeMap/OpenMapTiles stacks.
* `tianditu` builds the official base and annotation raster layers from the
* caller-provided Tianditu token.
*/
type?: 'raster' | 'vector-style';
type?: 'raster' | 'vector-style' | 'tianditu';
/**

@@ -354,2 +386,8 @@ * Raster XYZ/TMS tile template, for example `/tiles/{z}/{x}/{y}.png`.

rasterOpacity?: number;
/** Tianditu API token. Required when `type` is `tianditu`. */
token?: string;
/** Tianditu map family. Defaults to `vector`. */
mapStyle?: FileViewerTiandituMapStyle;
/** Include the matching Tianditu annotation layer. Defaults to true. */
labels?: boolean;
}

@@ -381,2 +419,7 @@ export interface FileViewerGeoOptions {

/**
* Tianditu API token used by the `tianditu-*` presets. The viewer never
* supplies or persists a token; obtain one for the deployment's own domain.
*/
tiandituToken?: string;
/**
* Defaults to true. When no CRS is declared and coordinates exceed longitude

@@ -901,5 +944,17 @@ * or latitude ranges, the geo renderer treats Web Mercator-sized values as

}
/** Page-aware image placed above rendered content for printing, such as a seal or signature. */
export interface FileViewerPrintStamp extends FileViewerPrintMaskRegion {
/** Image URL. Uploaded stamps are converted to a local data URL by the designer. */
src: string;
/** Image opacity from 0 to 1. Defaults to 1. */
opacity?: number;
/** Clockwise rotation in degrees. Defaults to 0. */
rotate?: number;
alt?: string;
}
export interface FileViewerPrintMaskOptions {
/** Solid black cover blocks, matching common OFD/business redaction UX. */
regions?: FileViewerPrintMaskRegion[];
/** Image overlays, including locally uploaded seals and signatures. */
stamps?: FileViewerPrintStamp[];
/** Fill color for print masks. Defaults to opaque black. */

@@ -906,0 +961,0 @@ color?: string;

+3
-2

@@ -1,6 +0,7 @@

import type { FileViewerPrintMaskOptions, FileViewerPrintMaskRegion } from '../contracts/types';
import type { FileViewerPrintMaskOptions, FileViewerPrintMaskRegion, FileViewerPrintStamp } from '../contracts/types';
export declare const normalizeFileViewerPrintMaskRegion: (region: Partial<FileViewerPrintMaskRegion> | null | undefined) => FileViewerPrintMaskRegion | null;
export declare const normalizeFileViewerPrintStamp: (stamp: Partial<FileViewerPrintStamp> | null | undefined) => FileViewerPrintStamp | null;
export declare const normalizeFileViewerPrintMaskOptions: (mask?: FileViewerPrintMaskOptions | null) => FileViewerPrintMaskOptions | null;
export declare const buildFileViewerPrintMaskOverlayHtml: (mask?: FileViewerPrintMaskOptions | null, pageScoped?: boolean) => string;
export declare const FILE_VIEWER_PRINT_MASK_STYLE = "\n .viewer-export-print-mask{position:absolute;inset:0;z-index:15;pointer-events:none;print-color-adjust:exact;-webkit-print-color-adjust:exact;}\n .viewer-export-print-mask--page{z-index:2147483647;}\n .viewer-export-print-mask-block{position:absolute;box-sizing:border-box;print-color-adjust:exact;-webkit-print-color-adjust:exact;}\n [data-viewer-print-page-index]{position:relative!important;isolation:isolate;}\n";
export declare const FILE_VIEWER_PRINT_MASK_STYLE = "\n .viewer-export-print-mask{position:absolute;inset:0;z-index:15;pointer-events:none;print-color-adjust:exact;-webkit-print-color-adjust:exact;}\n .viewer-export-print-mask--page{z-index:2147483647;}\n .viewer-export-print-mask-block{position:absolute;box-sizing:border-box;print-color-adjust:exact;-webkit-print-color-adjust:exact;}\n .viewer-export-print-stamp{position:absolute;display:block;object-fit:contain;transform-origin:center center;print-color-adjust:exact;-webkit-print-color-adjust:exact;}\n [data-viewer-print-page-index]{position:relative!important;isolation:isolate;}\n";
export declare const applyFileViewerPagePrintMasksToHtml: (contentHtml: string, mask?: FileViewerPrintMaskOptions | null) => string;

@@ -26,29 +26,79 @@ const clampPercent = (value) => Math.max(0, Math.min(100, value));

};
const normalizeStampSource = (value) => {
if (typeof value !== 'string') {
return '';
}
const source = value.trim();
if (/^data:image\/(?:png|jpe?g|webp|gif|svg\+xml);/i.test(source) ||
/^(?:blob:|https?:\/\/|\/|\.\.?\/)/i.test(source)) {
return source;
}
return '';
};
const clampOpacity = (value) => {
const opacity = Number(value);
return Number.isFinite(opacity) ? Math.max(0, Math.min(1, opacity)) : 1;
};
const normalizeRotation = (value) => {
const rotation = Number(value);
if (!Number.isFinite(rotation)) {
return 0;
}
return ((rotation % 360) + 360) % 360;
};
export const normalizeFileViewerPrintStamp = (stamp) => {
const region = normalizeFileViewerPrintMaskRegion(stamp);
const src = normalizeStampSource(stamp === null || stamp === void 0 ? void 0 : stamp.src);
if (!region || !src) {
return null;
}
return {
...region,
src,
opacity: clampOpacity(stamp === null || stamp === void 0 ? void 0 : stamp.opacity),
rotate: normalizeRotation(stamp === null || stamp === void 0 ? void 0 : stamp.rotate),
...(typeof (stamp === null || stamp === void 0 ? void 0 : stamp.alt) === 'string' && stamp.alt.trim()
? { alt: stamp.alt.trim() }
: {}),
};
};
export const normalizeFileViewerPrintMaskOptions = (mask) => {
if (!mask || !Array.isArray(mask.regions) || !mask.regions.length) {
if (!mask) {
return null;
}
const regions = mask.regions
const regions = (mask.regions || [])
.map(region => normalizeFileViewerPrintMaskRegion(region))
.filter((region) => !!region);
if (!regions.length) {
const stamps = (mask.stamps || [])
.map(stamp => normalizeFileViewerPrintStamp(stamp))
.filter((stamp) => !!stamp);
if (!regions.length && !stamps.length) {
return null;
}
return {
regions,
...(regions.length ? { regions } : {}),
...(stamps.length ? { stamps } : {}),
color: mask.color || '#000000',
};
};
const escapeHtmlAttribute = (value) => value
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
export const buildFileViewerPrintMaskOverlayHtml = (mask, pageScoped = false) => {
var _a;
const normalized = normalizeFileViewerPrintMaskOptions(mask);
if (!((_a = normalized === null || normalized === void 0 ? void 0 : normalized.regions) === null || _a === void 0 ? void 0 : _a.length)) {
if (!normalized) {
return '';
}
const color = normalized.color || '#000000';
const blocks = normalized.regions.map(region => (`<div class="viewer-export-print-mask-block" style="left:${region.left}%;top:${region.top}%;width:${region.width}%;height:${region.height}%;background:${color};"></div>`)).join('');
const blocks = (normalized.regions || []).map(region => (`<div class="viewer-export-print-mask-block" style="left:${region.left}%;top:${region.top}%;width:${region.width}%;height:${region.height}%;background:${color};"></div>`)).join('');
const stamps = (normalized.stamps || []).map(stamp => {
var _a, _b;
return (`<img class="viewer-export-print-stamp" src="${escapeHtmlAttribute(stamp.src)}" alt="${escapeHtmlAttribute(stamp.alt || '')}" draggable="false" style="left:${stamp.left}%;top:${stamp.top}%;width:${stamp.width}%;height:${stamp.height}%;opacity:${(_a = stamp.opacity) !== null && _a !== void 0 ? _a : 1};transform:rotate(${(_b = stamp.rotate) !== null && _b !== void 0 ? _b : 0}deg);" />`);
}).join('');
const className = pageScoped
? 'viewer-export-print-mask viewer-export-print-mask--page'
: 'viewer-export-print-mask';
return `<div class="${className}" aria-hidden="true">${blocks}</div>`;
return `<div class="${className}" aria-hidden="true">${blocks}${stamps}</div>`;
};

@@ -59,6 +109,7 @@ export const FILE_VIEWER_PRINT_MASK_STYLE = `

.viewer-export-print-mask-block{position:absolute;box-sizing:border-box;print-color-adjust:exact;-webkit-print-color-adjust:exact;}
.viewer-export-print-stamp{position:absolute;display:block;object-fit:contain;transform-origin:center center;print-color-adjust:exact;-webkit-print-color-adjust:exact;}
[data-viewer-print-page-index]{position:relative!important;isolation:isolate;}
`;
export const applyFileViewerPagePrintMasksToHtml = (contentHtml, mask) => {
var _a;
var _a, _b;
const normalized = normalizeFileViewerPrintMaskOptions(mask);

@@ -69,2 +120,3 @@ if (!normalized) {

const regionsByPage = new Map();
const stampsByPage = new Map();
(_a = normalized.regions) === null || _a === void 0 ? void 0 : _a.forEach(region => {

@@ -78,3 +130,11 @@ if (region.pageIndex === undefined) {

});
if (!regionsByPage.size) {
(_b = normalized.stamps) === null || _b === void 0 ? void 0 : _b.forEach(stamp => {
if (stamp.pageIndex === undefined) {
return;
}
const pageStamps = stampsByPage.get(stamp.pageIndex) || [];
pageStamps.push(stamp);
stampsByPage.set(stamp.pageIndex, pageStamps);
});
if (!regionsByPage.size && !stampsByPage.size) {
return contentHtml;

@@ -84,7 +144,9 @@ }

const pageRegions = regionsByPage.get(Number(rawPageIndex));
if (!(pageRegions === null || pageRegions === void 0 ? void 0 : pageRegions.length)) {
const pageStamps = stampsByPage.get(Number(rawPageIndex));
if (!(pageRegions === null || pageRegions === void 0 ? void 0 : pageRegions.length) && !(pageStamps === null || pageStamps === void 0 ? void 0 : pageStamps.length)) {
return match;
}
return `${openingTag}${buildFileViewerPrintMaskOverlayHtml({
regions: pageRegions,
regions: pageRegions || [],
stamps: pageStamps || [],
color: normalized.color,

@@ -91,0 +153,0 @@ }, true)}`;

@@ -1,2 +0,2 @@

import type { FileViewerPrintMaskOptions, FileViewerPrintMaskRegion } from '../contracts/types';
import type { FileViewerPrintMaskOptions, FileViewerPrintMaskRegion, FileViewerPrintStamp } from '../contracts/types';
import { type FileViewerI18nInput } from '../i18n/messages';

@@ -9,2 +9,3 @@ export interface OpenFileViewerPrintMaskDesignerOptions {

initialRegions?: FileViewerPrintMaskRegion[];
initialStamps?: FileViewerPrintStamp[];
}

@@ -11,0 +12,0 @@ export interface FileViewerPrintMaskDesignerResult {

import { createFileViewerTranslator } from '../i18n/messages.js';
import { normalizeFileViewerPrintMaskRegion } from './printMask.js';
import { normalizeFileViewerPrintMaskRegion, normalizeFileViewerPrintStamp, } from './printMask.js';
const DESIGNER_STYLE = `

@@ -9,2 +9,6 @@ .fv-print-mask-layer{position:absolute;inset:0;z-index:2147483000;pointer-events:none;}

.fv-print-mask-block-remove{position:absolute;right:-8px;top:-8px;width:18px;height:18px;border:0;border-radius:999px;background:#111;color:#fff;font:700 12px/18px system-ui,sans-serif;cursor:pointer;padding:0;}
.fv-print-stamp{position:absolute;box-sizing:border-box;border:1px dashed rgba(22,119,76,.7);border-radius:4px;pointer-events:auto;touch-action:none;cursor:move;transform-origin:center center;}
.fv-print-stamp img{display:block;width:100%;height:100%;object-fit:contain;pointer-events:none;user-select:none;}
.fv-print-stamp-resize{position:absolute;right:-7px;bottom:-7px;width:15px;height:15px;border:2px solid #fff;border-radius:4px;background:#16774c;box-shadow:0 1px 5px rgba(15,23,42,.22);cursor:nwse-resize;touch-action:none;}
.fv-print-stamp-input{display:none!important;}
.fv-print-mask-toolbar{position:absolute;left:50%;bottom:16px;transform:translateX(-50%);z-index:2147483001;display:inline-flex;align-items:center;gap:6px;padding:6px 8px;border:1px solid rgba(20,35,53,.12);border-radius:999px;background:rgba(255,255,255,.94);box-shadow:0 12px 28px rgba(15,23,42,.16);pointer-events:auto;max-width:calc(100% - 24px);flex-wrap:wrap;justify-content:center;}

@@ -56,2 +60,20 @@ .fv-print-mask-toolbar span{font:600 12px/1.2 system-ui,sans-serif;color:#40546a;white-space:nowrap;}

};
const MAX_PRINT_STAMP_BYTES = 10 * 1024 * 1024;
const readStampFileAsDataUrl = (file, windowRef) => new Promise((resolve, reject) => {
if (!/^image\/(?:png|jpe?g|webp|gif|svg\+xml)$/i.test(file.type) || file.size > MAX_PRINT_STAMP_BYTES) {
reject(new Error('Unsupported print stamp image'));
return;
}
const Reader = (windowRef === null || windowRef === void 0 ? void 0 : windowRef.FileReader) || globalThis.FileReader;
const reader = new Reader();
reader.addEventListener('load', () => {
if (typeof reader.result === 'string' && reader.result.startsWith('data:image/')) {
resolve(reader.result);
return;
}
reject(new Error('Invalid print stamp image'));
});
reader.addEventListener('error', () => reject(reader.error || new Error('Failed to read print stamp image')));
reader.readAsDataURL(file);
});
/**

@@ -69,2 +91,5 @@ * Opens a page-aware print-mask designer. Browsing remains the default mode;

.filter((region) => !!region);
const stamps = [...(options.initialStamps || [])]
.map(stamp => normalizeFileViewerPrintStamp(stamp))
.filter((stamp) => !!stamp);
const providedPages = Array.from(new Set(options.pages || []))

@@ -110,3 +135,4 @@ .filter(page => page === root || root.contains(page));

!surfaces.some(surface => surface.element === root) &&
regions.some(region => region.pageIndex === undefined)
(regions.some(region => region.pageIndex === undefined) ||
stamps.some(stamp => stamp.pageIndex === undefined))
? createSurface(root)

@@ -124,2 +150,10 @@ : null;

addButton.textContent = t('toolbar.printMaskAdd');
const stampInput = documentRef.createElement('input');
stampInput.type = 'file';
stampInput.accept = 'image/png,image/jpeg,image/webp,image/gif,image/svg+xml';
stampInput.className = 'fv-print-stamp-input';
stampInput.setAttribute('data-viewer-print-stamp-input', 'true');
const stampButton = documentRef.createElement('button');
stampButton.type = 'button';
stampButton.textContent = t('toolbar.printStampUpload');
const clearButton = documentRef.createElement('button');

@@ -135,4 +169,4 @@ clearButton.type = 'button';

confirmButton.textContent = t('toolbar.printMaskConfirm');
toolbar.append(hint, addButton, clearButton, cancelButton, confirmButton);
layer.append(toolbar);
toolbar.append(hint, addButton, stampButton, clearButton, cancelButton, confirmButton);
layer.append(stampInput, toolbar);
root.appendChild(layer);

@@ -166,7 +200,7 @@ const disarm = () => {

};
const surfaceForRegion = (region) => {
if (region.pageIndex === undefined) {
const surfaceForItem = (item) => {
if (item.pageIndex === undefined) {
return legacySurface || surfaces[0];
}
return surfaces.find(surface => surface.pageIndex === region.pageIndex) || null;
return surfaces.find(surface => surface.pageIndex === item.pageIndex) || null;
};

@@ -176,3 +210,3 @@ const renderRegions = () => {

regions.forEach((region, index) => {
const surface = surfaceForRegion(region);
const surface = surfaceForItem(region);
if (!surface) {

@@ -203,2 +237,101 @@ return;

});
stamps.forEach((stamp, index) => {
const surface = surfaceForItem(stamp);
if (!surface) {
return;
}
const stampElement = documentRef.createElement('div');
stampElement.className = 'fv-print-stamp';
stampElement.setAttribute('data-viewer-print-stamp', String(index));
const applyStampStyle = () => {
var _a, _b;
stampElement.style.left = `${stamp.left}%`;
stampElement.style.top = `${stamp.top}%`;
stampElement.style.width = `${stamp.width}%`;
stampElement.style.height = `${stamp.height}%`;
stampElement.style.opacity = String((_a = stamp.opacity) !== null && _a !== void 0 ? _a : 1);
stampElement.style.transform = `rotate(${(_b = stamp.rotate) !== null && _b !== void 0 ? _b : 0}deg)`;
};
applyStampStyle();
const image = documentRef.createElement('img');
image.src = stamp.src;
image.alt = stamp.alt || '';
image.draggable = false;
const remove = documentRef.createElement('button');
remove.type = 'button';
remove.className = 'fv-print-mask-block-remove';
remove.title = t('toolbar.printStampRemove');
remove.setAttribute('aria-label', t('toolbar.printStampRemove'));
remove.textContent = '−';
remove.addEventListener('pointerdown', event => event.stopPropagation());
remove.addEventListener('click', event => {
event.preventDefault();
event.stopPropagation();
stamps.splice(index, 1);
renderRegions();
});
const resize = documentRef.createElement('span');
resize.className = 'fv-print-stamp-resize';
resize.setAttribute('role', 'button');
resize.setAttribute('aria-label', t('toolbar.printStampResize'));
resize.title = t('toolbar.printStampResize');
let interaction = null;
stampElement.addEventListener('pointerdown', event => {
var _a;
if (event.button !== 0 || event.target.closest('button')) {
return;
}
event.preventDefault();
event.stopPropagation();
interaction = {
pointerId: event.pointerId,
mode: event.target === resize ? 'resize' : 'move',
startX: event.clientX,
startY: event.clientY,
left: stamp.left,
top: stamp.top,
width: stamp.width,
height: stamp.height,
};
(_a = stampElement.setPointerCapture) === null || _a === void 0 ? void 0 : _a.call(stampElement, event.pointerId);
});
stampElement.addEventListener('pointermove', event => {
if (!interaction || interaction.pointerId !== event.pointerId) {
return;
}
event.preventDefault();
const bounds = surface.canvas.getBoundingClientRect();
if (!bounds.width || !bounds.height) {
return;
}
const deltaX = ((event.clientX - interaction.startX) / bounds.width) * 100;
const deltaY = ((event.clientY - interaction.startY) / bounds.height) * 100;
if (interaction.mode === 'move') {
stamp.left = Math.max(0, Math.min(100 - stamp.width, interaction.left + deltaX));
stamp.top = Math.max(0, Math.min(100 - stamp.height, interaction.top + deltaY));
}
else {
stamp.width = Math.max(4, Math.min(100 - stamp.left, interaction.width + deltaX));
stamp.height = Math.max(4, Math.min(100 - stamp.top, interaction.height + deltaY));
}
applyStampStyle();
});
const endInteraction = (event) => {
var _a;
if (!interaction || interaction.pointerId !== event.pointerId) {
return;
}
try {
(_a = stampElement.releasePointerCapture) === null || _a === void 0 ? void 0 : _a.call(stampElement, interaction.pointerId);
}
catch {
// Pointer capture may already be released by the browser.
}
interaction = null;
};
stampElement.addEventListener('pointerup', endInteraction);
stampElement.addEventListener('pointercancel', endInteraction);
stampElement.append(image, remove, resize);
surface.canvas.appendChild(stampElement);
});
};

@@ -269,14 +402,53 @@ const pointFromEvent = (event, canvas) => {

});
addButton.addEventListener('click', () => {
const getActiveSurface = () => {
var _a;
disarm();
const viewport = root.getBoundingClientRect();
const activeSurface = ((_a = surfaces
return ((_a = surfaces
.map(surface => ({ surface, area: visibleArea(surface.element, viewport) }))
.sort((left, right) => right.area - left.area)[0]) === null || _a === void 0 ? void 0 : _a.surface) || surfaces[0];
};
addButton.addEventListener('click', () => {
disarm();
const activeSurface = getActiveSurface();
activeSurface === null || activeSurface === void 0 ? void 0 : activeSurface.canvas.classList.add('is-armed');
addButton.classList.toggle('is-active', Boolean(activeSurface));
});
stampButton.addEventListener('click', () => {
disarm();
stampInput.click();
});
stampInput.addEventListener('change', async () => {
var _a;
const file = (_a = stampInput.files) === null || _a === void 0 ? void 0 : _a[0];
stampInput.value = '';
if (!file) {
return;
}
try {
const src = await readStampFileAsDataUrl(file, documentRef.defaultView);
const activeSurface = getActiveSurface();
if (!activeSurface) {
return;
}
const stamp = normalizeFileViewerPrintStamp({
src,
alt: file.name,
left: 38,
top: 38,
width: 24,
height: 18,
pageIndex: activeSurface.pageIndex,
});
if (stamp) {
stamps.push(stamp);
renderRegions();
}
}
catch {
// Unsupported or unreadable images are ignored; the document stays untouched.
}
});
clearButton.addEventListener('click', () => {
regions.splice(0, regions.length);
stamps.splice(0, stamps.length);
disarm();

@@ -287,3 +459,3 @@ renderRegions();

confirmButton.addEventListener('click', () => {
if (!regions.length) {
if (!regions.length && !stamps.length) {
finish(null);

@@ -294,3 +466,4 @@ return;

mask: {
regions: regions.map(region => ({ ...region })),
...(regions.length ? { regions: regions.map(region => ({ ...region })) } : {}),
...(stamps.length ? { stamps: stamps.map(stamp => ({ ...stamp })) } : {}),
color,

@@ -297,0 +470,0 @@ },

@@ -6,2 +6,4 @@ export { DEFAULT_FILE_VIEWER_ARCHIVE_WORKER_PATH, DEFAULT_FILE_VIEWER_ARCHIVE_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_DWF_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_LIBREDWG_SCRIPT_PATH, DEFAULT_FILE_VIEWER_CAD_LIBREDWG_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_CAD_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_WORKER_PATH, DEFAULT_FILE_VIEWER_DATA_SQL_WASM_URL, DEFAULT_FILE_VIEWER_DOCX_WORKER_JSZIP_PATH, DEFAULT_FILE_VIEWER_DOCX_WORKER_PATH, DEFAULT_FILE_VIEWER_DOCX_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_PPT_FONT_PATH, DEFAULT_FILE_VIEWER_PPT_FRAME_CACHE_PATH, DEFAULT_FILE_VIEWER_PPT_MODULE_PATH, DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH, DEFAULT_FILE_VIEWER_PPT_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_PPT_WASM_PATH, DEFAULT_FILE_VIEWER_PPT_WORKER_PATH, DEFAULT_FILE_VIEWER_PRESENTATION_WORKER_PATH, DEFAULT_FILE_VIEWER_RENDERER_ASSET_MANIFESTS, DEFAULT_FILE_VIEWER_SPREADSHEET_WORKER_PATH, DEFAULT_FILE_VIEWER_TYPST_COMPILER_WASM_URL, DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_PACKAGE_PATH, DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_URL, getFileViewerRendererAssetManifest, listFileViewerRendererAssetManifests, resolveFileViewerArchiveWasmUrl, resolveFileViewerArchiveWorkerUrl, resolveFileViewerAssetUrl, resolveFileViewerCadAssetUrls, resolveFileViewerDataSqlWasmUrl, resolveFileViewerDocxWorkerJsZipUrl, resolveFileViewerDocxWorkerUrl, resolveFileViewerDrawioViewerScriptUrl, resolveFileViewerPresentationWorkerUrl, resolveFileViewerRendererAssets, resolveFileViewerSpreadsheetWorkerUrl, resolveFileViewerTypstCompilerWasmUrl, resolveFileViewerTypstRendererWasmUrl, } from './assets';

export { ARCHIVE_EXTENSIONS, DEFAULT_RENDERER_DEFINITIONS, DEFAULT_SUPPORTED_EXTENSIONS, IMAGE_EXTENSIONS, MODEL_EXTENSIONS, TEXT_EXTENSIONS, } from './registry/formats';
export { precheckFileViewerSource } from './source/precheck';
export type { FileViewerPrecheckOptions, FileViewerPrecheckReason, FileViewerPrecheckResult, FileViewerPrecheckStatus, } from './source/precheck';
export { FILE_VIEWER_BEFORE_OPERATION_ERROR_PREFIX, DEFAULT_FILE_VIEWER_TOOLBAR_ORDER, FILE_VIEWER_LIFECYCLE_HOOK_ERROR_MESSAGE_PREFIX, FILE_VIEWER_LIFECYCLE_HOOKS, FILE_VIEWER_OPERATION_LABELS, buildFileViewerLifecycleContext, buildFileViewerLifecycleContextFromNormalizedSource, buildFileViewerOperationContext, buildFileViewerOperationContextFromLifecycleState, cloneFileViewerOperationAvailability, createFileViewerLifecycleActions, createFileViewerLifecycleStateController, createFileViewerPublicApi, createFileViewerToolbarActions, createFileViewerToolbarControllerActionHandlers, createFileViewerToolbarZoomSyncSnapshot, DEFAULT_FILE_VIEWER_LIFECYCLE_HOOK_ERROR_LOGGER, DEFAULT_FILE_VIEWER_OPERATION_ERROR_LOGGER, dispatchFileViewerLifecycleEvent, dispatchFileViewerOperationAvailabilityChange, dispatchFileViewerOperationContextEvent, dispatchFileViewerZoomChange, emitFileViewerComponentLifecycleEvent, getFileViewerBeforeOperationHooks, getFileViewerLifecycleHookName, hasVisibleFileViewerToolbarActions, isFileViewerToolbarOperationPermitted, isFileViewerZoomButtonDisabled, normalizeFileViewerToolbar, reportFileViewerLifecycleHookError, reportFileViewerOperationError, resolveFileViewerBeforeOperationErrorMessage, resolveFileViewerLifecycleFallbackSource, resolveFileViewerLifecycleHookErrorMessage, resolveFileViewerOperationAvailability, resolveFileViewerToolbarPosition, resolveFileViewerToolbarOrder, resolveFileViewerToolbarState, resolveVisibleFileViewerToolbar, runFileViewerActiveUnloadComplete, runFileViewerActiveUnloadStart, runFileViewerBeforeOperation, runFileViewerLifecycleHook, runFileViewerToolbarAvailabilitySync, runFileViewerToolbarZoomSync, serializeFileViewerContext, } from './lifecycle/operations';

@@ -28,2 +30,2 @@ export { FILE_VIEWER_BUILTIN_MESSAGES, FILE_VIEWER_DEFAULT_LOCALE, FILE_VIEWER_FALLBACK_LOCALE, FILE_VIEWER_SUPPORTED_LOCALES, createFileViewerTranslator, formatFileViewerMessage, normalizeFileViewerLocale, resolveFileViewerLocale, translateFileViewerMessage, } from './i18n/messages';

export type { FileViewerWatermarkPresentationState, FileViewerWatermarkStyle, } from './features/watermark';
export type { FileRenderContext, FileRenderExportAdapter, FileRenderExportMode, FileRenderExportOptions, FileRenderHandler, FileRenderHandlerComposite, FileViewerBuiltinRendererPreset, FileViewerAiOptions, FileViewerArchiveEntryActionContext, FileViewerArchiveEntryActionPolicy, FileViewerArchiveEntryActionsOptions, FileViewerArchiveOptions, FileViewerApplyViewStateOptions, FileViewerBeforeOperation, FileViewerCadDwfLineWeightMode, FileViewerCadOptions, FileViewerCadRenderer, FileViewerComponentEmits, FileViewerComponentEventMap, FileViewerComponentProps, FileViewerDocumentAnchor, FileViewerDocumentChunk, FileViewerDocxOptions, FileViewerDrawingOptions, FileViewerDownloadOptions, FileViewerEvent, FileViewerEventHandler, FileViewerEventType, FileViewerExportHtmlOptions, FileViewerFileRef, FileViewerFitMode, FileViewerFitOptions, FileViewerFitRequest, FileViewerFitResize, FileViewerFitResult, FileViewerGeoOptions, FileViewerInstance, FileViewerLifecycleContext, FileViewerLifecycleHooks, FileViewerLifecyclePhase, FileViewerI18nOptions, FileViewerLocale, FileViewerMessageKey, FileViewerMessageParams, FileViewerMessageResolver, FileViewerMessages, FileViewerNavigationState, FileViewerOperationAvailability, FileViewerOperationContext, FileViewerOperationType, FileViewerOptions, FileViewerPdfOptions, FileViewerPresentationOptions, FileViewerPrintOptions, FileViewerPublicApi, FileViewerRenderStateKind, FileViewerRenderedInstance, FileViewerRendererCategory, FileViewerSearchMatch, FileViewerSearchOptions, FileViewerSearchProvider, FileViewerSearchState, FileViewerSource, FileViewerSourceKind, FileViewerSpreadsheetOptions, FileViewerStateDescriptor, FileViewerStateTheme, FileViewerTextOptions, FileViewerResolvedThemeMode, FileViewerThemeMode, FileViewerToolbarActionMap, FileViewerToolbarItem, FileViewerToolbarOptions, FileViewerToolbarPosition, FileViewerResolvedToolbarItem, FileViewerUiDensity, FileViewerUiOptions, FileViewerTypstOptions, FileViewerViewScrollState, FileViewerViewState, FileViewerViewStateChange, FileViewerViewStateChangeAction, FileViewerViewStateChangeSource, FileViewerViewStateProvider, FileViewerWatermarkOptions, FileViewerZoomProvider, FileViewerZoomState, NormalizedFileViewerSource, RenderSurface, RendererCapability, RendererDefinition, RendererLoadContext, RendererLoader, RendererPlugin, RendererRegistry, RendererSession, ViewerCapabilityState, ViewerLifecycleContext, ViewerOperationContext, } from './contracts/types';
export type { FileRenderContext, FileRenderExportAdapter, FileRenderExportMode, FileRenderExportOptions, FileRenderHandler, FileRenderHandlerComposite, FileViewerBuiltinRendererPreset, FileViewerAiOptions, FileViewerArchiveEntryActionContext, FileViewerArchiveEntryActionPolicy, FileViewerArchiveEntryActionsOptions, FileViewerArchiveOptions, FileViewerApplyViewStateOptions, FileViewerBeforeOperation, FileViewerCadDwfLineWeightMode, FileViewerCadOptions, FileViewerCadRenderer, FileViewerComponentEmits, FileViewerComponentEventMap, FileViewerComponentProps, FileViewerDocumentAnchor, FileViewerDocumentChunk, FileViewerDocxOptions, FileViewerDrawingOptions, FileViewerDownloadOptions, FileViewerEvent, FileViewerEventHandler, FileViewerEventType, FileViewerExportHtmlOptions, FileViewerFileRef, FileViewerFitMode, FileViewerFitOptions, FileViewerFitRequest, FileViewerFitResize, FileViewerFitResult, FileViewerGeoOptions, FileViewerInstance, FileViewerLifecycleContext, FileViewerLifecycleHooks, FileViewerLifecyclePhase, FileViewerI18nOptions, FileViewerLocale, FileViewerMessageKey, FileViewerMessageParams, FileViewerMessageResolver, FileViewerMessages, FileViewerNavigationState, FileViewerOperationAvailability, FileViewerOperationContext, FileViewerOperationType, FileViewerOptions, FileViewerPdfBoundingBox, FileViewerPdfBoundingBoxOrigin, FileViewerPdfBoundingBoxUnit, FileViewerPdfOptions, FileViewerPresentationOptions, FileViewerPrintMaskOptions, FileViewerPrintMaskRegion, FileViewerPrintOptions, FileViewerPrintStamp, FileViewerPublicApi, FileViewerRenderStateKind, FileViewerRenderedInstance, FileViewerRendererCategory, FileViewerSearchMatch, FileViewerSearchOptions, FileViewerSearchProvider, FileViewerSearchState, FileViewerSource, FileViewerSourceKind, FileViewerSpreadsheetOptions, FileViewerStateDescriptor, FileViewerStateTheme, FileViewerTextOptions, FileViewerResolvedThemeMode, FileViewerThemeMode, FileViewerToolbarActionMap, FileViewerToolbarItem, FileViewerToolbarOptions, FileViewerToolbarPosition, FileViewerResolvedToolbarItem, FileViewerUiDensity, FileViewerUiOptions, FileViewerTypstOptions, FileViewerViewScrollState, FileViewerViewState, FileViewerViewStateChange, FileViewerViewStateChangeAction, FileViewerViewStateChangeSource, FileViewerViewStateProvider, FileViewerWatermarkOptions, FileViewerZoomProvider, FileViewerZoomState, NormalizedFileViewerSource, RenderSurface, RendererCapability, RendererDefinition, RendererLoadContext, RendererLoader, RendererPlugin, RendererRegistry, RendererSession, ViewerCapabilityState, ViewerLifecycleContext, ViewerOperationContext, } from './contracts/types';

@@ -10,2 +10,3 @@ // Headless API surface for adapters and non-DOM orchestration.

export { ARCHIVE_EXTENSIONS, DEFAULT_RENDERER_DEFINITIONS, DEFAULT_SUPPORTED_EXTENSIONS, IMAGE_EXTENSIONS, MODEL_EXTENSIONS, TEXT_EXTENSIONS, } from './registry/formats.js';
export { precheckFileViewerSource } from './source/precheck.js';
export { FILE_VIEWER_BEFORE_OPERATION_ERROR_PREFIX, DEFAULT_FILE_VIEWER_TOOLBAR_ORDER, FILE_VIEWER_LIFECYCLE_HOOK_ERROR_MESSAGE_PREFIX, FILE_VIEWER_LIFECYCLE_HOOKS, FILE_VIEWER_OPERATION_LABELS, buildFileViewerLifecycleContext, buildFileViewerLifecycleContextFromNormalizedSource, buildFileViewerOperationContext, buildFileViewerOperationContextFromLifecycleState, cloneFileViewerOperationAvailability, createFileViewerLifecycleActions, createFileViewerLifecycleStateController, createFileViewerPublicApi, createFileViewerToolbarActions, createFileViewerToolbarControllerActionHandlers, createFileViewerToolbarZoomSyncSnapshot, DEFAULT_FILE_VIEWER_LIFECYCLE_HOOK_ERROR_LOGGER, DEFAULT_FILE_VIEWER_OPERATION_ERROR_LOGGER, dispatchFileViewerLifecycleEvent, dispatchFileViewerOperationAvailabilityChange, dispatchFileViewerOperationContextEvent, dispatchFileViewerZoomChange, emitFileViewerComponentLifecycleEvent, getFileViewerBeforeOperationHooks, getFileViewerLifecycleHookName, hasVisibleFileViewerToolbarActions, isFileViewerToolbarOperationPermitted, isFileViewerZoomButtonDisabled, normalizeFileViewerToolbar, reportFileViewerLifecycleHookError, reportFileViewerOperationError, resolveFileViewerBeforeOperationErrorMessage, resolveFileViewerLifecycleFallbackSource, resolveFileViewerLifecycleHookErrorMessage, resolveFileViewerOperationAvailability, resolveFileViewerToolbarPosition, resolveFileViewerToolbarOrder, resolveFileViewerToolbarState, resolveVisibleFileViewerToolbar, runFileViewerActiveUnloadComplete, runFileViewerActiveUnloadStart, runFileViewerBeforeOperation, runFileViewerLifecycleHook, runFileViewerToolbarAvailabilitySync, runFileViewerToolbarZoomSync, serializeFileViewerContext, } from './lifecycle/operations.js';

@@ -12,0 +13,0 @@ export { FILE_VIEWER_BUILTIN_MESSAGES, FILE_VIEWER_DEFAULT_LOCALE, FILE_VIEWER_FALLBACK_LOCALE, FILE_VIEWER_SUPPORTED_LOCALES, createFileViewerTranslator, formatFileViewerMessage, normalizeFileViewerLocale, resolveFileViewerLocale, translateFileViewerMessage, } from './i18n/messages.js';

@@ -16,4 +16,4 @@ /**

'toolbar.printDirect': '直接印刷',
'toolbar.printMask': 'マスクして印刷',
'toolbar.printMaskTitle': '機密領域を隠してから印刷',
'toolbar.printMask': 'マスク・印章付き印刷',
'toolbar.printMaskTitle': '機密領域を隠すか印章を追加してから印刷',
'toolbar.printMaskAdd': 'マスクを追加',

@@ -23,3 +23,6 @@ 'toolbar.printMaskClear': 'クリア',

'toolbar.printMaskConfirm': '印刷を確定',
'toolbar.printMaskHint': 'ドラッグして黒いマスクを描画します。削除して再調整できます。',
'toolbar.printMaskHint': 'マスクを描画するか、印章をアップロードして移動・サイズ変更します。',
'toolbar.printStampUpload': '印章をアップロード',
'toolbar.printStampRemove': '印章を削除',
'toolbar.printStampResize': '印章のサイズ変更',
'toolbar.exportHtml': 'HTML',

@@ -337,2 +340,5 @@ 'toolbar.exportHtmlTitle': '現在のレンダリング結果を HTML として書き出す',

'image.alt': '画像',
'image.toolbar.rotation': '画像の回転',
'image.toolbar.rotateLeft': '画像を左に回転',
'image.toolbar.rotateRight': '画像を右に回転',
'image.lightbox.alt': '画像プレビュー',

@@ -339,0 +345,0 @@ 'image.lightbox.close': '画像プレビューを閉じる',

@@ -15,4 +15,4 @@ import { JA_JP_MESSAGES } from './messages.ja.js';

'toolbar.printDirect': '直接打印',
'toolbar.printMask': '掩膜打印',
'toolbar.printMaskTitle': '遮盖敏感区域后再打印',
'toolbar.printMask': '遮罩/盖章打印',
'toolbar.printMaskTitle': '遮盖敏感区域或上传印章后再打印',
'toolbar.printMaskAdd': '添加掩膜',

@@ -22,3 +22,6 @@ 'toolbar.printMaskClear': '清空',

'toolbar.printMaskConfirm': '确认打印',
'toolbar.printMaskHint': '拖拽绘制黑色遮盖块,可删除后继续调整',
'toolbar.printMaskHint': '绘制遮盖块,或上传印章后拖动和缩放',
'toolbar.printStampUpload': '上传印章',
'toolbar.printStampRemove': '删除印章',
'toolbar.printStampResize': '缩放印章',
'toolbar.exportHtml': 'HTML',

@@ -336,2 +339,5 @@ 'toolbar.exportHtmlTitle': '导出当前渲染后的 HTML',

'image.alt': '图片',
'image.toolbar.rotation': '图片旋转',
'image.toolbar.rotateLeft': '向左旋转图片',
'image.toolbar.rotateRight': '向右旋转图片',
'image.lightbox.alt': '图片预览',

@@ -442,4 +448,4 @@ 'image.lightbox.close': '关闭图片预览',

'toolbar.printDirect': 'Print now',
'toolbar.printMask': 'Mask & print',
'toolbar.printMaskTitle': 'Cover sensitive areas before printing',
'toolbar.printMask': 'Mask / stamp & print',
'toolbar.printMaskTitle': 'Cover sensitive areas or add a stamp before printing',
'toolbar.printMaskAdd': 'Add mask',

@@ -449,3 +455,6 @@ 'toolbar.printMaskClear': 'Clear',

'toolbar.printMaskConfirm': 'Print',
'toolbar.printMaskHint': 'Drag to draw black cover blocks. Delete and adjust as needed.',
'toolbar.printMaskHint': 'Draw cover blocks, or upload a stamp and drag or resize it.',
'toolbar.printStampUpload': 'Upload stamp',
'toolbar.printStampRemove': 'Remove stamp',
'toolbar.printStampResize': 'Resize stamp',
'toolbar.exportHtml': 'HTML',

@@ -763,2 +772,5 @@ 'toolbar.exportHtmlTitle': 'Export the rendered HTML',

'image.alt': 'Image',
'image.toolbar.rotation': 'Image rotation',
'image.toolbar.rotateLeft': 'Rotate image left',
'image.toolbar.rotateRight': 'Rotate image right',
'image.lightbox.alt': 'Image preview',

@@ -765,0 +777,0 @@ 'image.lightbox.close': 'Close image preview',

import type { FileRenderContext, FileViewerRenderedInstance } from './contracts/types';
export { DEFAULT_FILE_VIEWER_ARCHIVE_WORKER_PATH, DEFAULT_FILE_VIEWER_ARCHIVE_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_DWF_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_LIBREDWG_SCRIPT_PATH, DEFAULT_FILE_VIEWER_CAD_LIBREDWG_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_CAD_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_WORKER_PATH, DEFAULT_FILE_VIEWER_DATA_SQL_WASM_URL, DEFAULT_FILE_VIEWER_MODEL_RUNTIME_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_RUNTIME_URL, DEFAULT_FILE_VIEWER_MODEL_IMPORT_LICENSE_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_IMPORT_LICENSE_URL, DEFAULT_FILE_VIEWER_MODEL_OCCT_LICENSE_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_OCCT_LICENSE_URL, DEFAULT_FILE_VIEWER_MODEL_WASM_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_WASM_URL, DEFAULT_FILE_VIEWER_MODEL_WORKER_URL, DEFAULT_FILE_VIEWER_DOCX_WORKER_JSZIP_PATH, DEFAULT_FILE_VIEWER_DOCX_WORKER_PATH, DEFAULT_FILE_VIEWER_DOCX_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_PDF_CMAP_PATH, DEFAULT_FILE_VIEWER_PDF_STANDARD_FONT_PATH, DEFAULT_FILE_VIEWER_PDF_WASM_PATH, DEFAULT_FILE_VIEWER_PDF_WORKER_PATH, DEFAULT_FILE_VIEWER_PPT_FONT_PATH, DEFAULT_FILE_VIEWER_PPT_FRAME_CACHE_PATH, DEFAULT_FILE_VIEWER_PPT_MODULE_PATH, DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH, DEFAULT_FILE_VIEWER_PPT_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_PPT_WASM_PATH, DEFAULT_FILE_VIEWER_PPT_WORKER_PATH, DEFAULT_FILE_VIEWER_PRESENTATION_WORKER_PATH, DEFAULT_FILE_VIEWER_RENDERER_ASSET_MANIFESTS, DEFAULT_FILE_VIEWER_SPREADSHEET_WORKER_PATH, DEFAULT_FILE_VIEWER_TYPST_COMPILER_WASM_URL, DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_URL, DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_PACKAGE_PATH, getDefaultFileViewerAssetBaseUrl, getFileViewerRendererAssetManifest, listFileViewerRendererAssetManifests, normalizeFileViewerAssetBaseUrl, resetDefaultFileViewerAssetBaseUrl, resolveFileViewerArchiveWasmUrl, resolveFileViewerArchiveWorkerUrl, resolveFileViewerAssetUrl, resolveFileViewerCadAssetUrls, resolveFileViewerDataSqlWasmUrl, resolveFileViewerDocxWorkerJsZipUrl, resolveFileViewerDocxWorkerUrl, resolveFileViewerDrawioViewerScriptUrl, resolveFileViewerModelAssetUrls, resolveFileViewerPdfAssetUrls, resolveFileViewerPresentationWorkerUrl, resolveFileViewerRendererAssets, resolveFileViewerRuntimeAssetBaseUrl, resolveFileViewerSpreadsheetWorkerUrl, resolveFileViewerTypstCompilerWasmUrl, resolveFileViewerTypstRendererWasmUrl, setDefaultFileViewerAssetBaseUrl, } from './assets';
export { ARCHIVE_EXTENSIONS, DEFAULT_RENDERER_DEFINITIONS, DEFAULT_SUPPORTED_EXTENSIONS, IMAGE_EXTENSIONS, MODEL_EXTENSIONS, TEXT_EXTENSIONS, } from './registry/formats';
export { precheckFileViewerSource } from './source/precheck';
export type { FileViewerPrecheckOptions, FileViewerPrecheckReason, FileViewerPrecheckResult, FileViewerPrecheckStatus, } from './source/precheck';
export { DEFAULT_FILE_VIEWER_TEXT_CHUNK_OVERLAP, DEFAULT_FILE_VIEWER_TEXT_CHUNK_SIZE, DEFAULT_FILE_VIEWER_ZOOM_SCALE, buildFileViewerDocumentTextChunks, createEmptyFileViewerSearchState, createFileViewerZoomState, normalizeFileViewerAiOptions, normalizeFileViewerSearchOptions, } from './features/document/model';

@@ -70,3 +72,3 @@ export { DEFAULT_FILE_VIEWER_SEARCH_ACTIVE_CLASS, DEFAULT_FILE_VIEWER_SEARCH_MATCH_CLASS, DEFAULT_FILE_VIEWER_SEARCH_MAX_MATCHES, applyFileViewerSearchState, cloneFileViewerSearchState, createFileViewerDomSearchController, createFileViewerDomSearchControllerActionHandlers, destroyFileViewerDomSearchController, observeFileViewerDomSearchController, runFileViewerDomSearchControllerAction, syncFileViewerDomSearchControllerState, } from './features/document/search';

export type { FileViewerWatermarkPresentationState, FileViewerWatermarkStyle, } from './features/watermark';
export { buildFileViewerPrintMaskOverlayHtml, applyFileViewerPagePrintMasksToHtml, normalizeFileViewerPrintMaskOptions, normalizeFileViewerPrintMaskRegion, FILE_VIEWER_PRINT_MASK_STYLE, } from './features/printMask';
export { buildFileViewerPrintMaskOverlayHtml, applyFileViewerPagePrintMasksToHtml, normalizeFileViewerPrintMaskOptions, normalizeFileViewerPrintMaskRegion, normalizeFileViewerPrintStamp, FILE_VIEWER_PRINT_MASK_STYLE, } from './features/printMask';
export { openFileViewerPrintMaskDesignerAsync, } from './features/printMaskLoader';

@@ -92,2 +94,2 @@ export type { FileViewerPrintMaskDesignerResult, OpenFileViewerPrintMaskDesignerOptions, } from './features/printMaskDesigner';

export type { CreateFileViewerWorkerControllerOptions, FileViewerWorkerContext, FileViewerWorkerController, FileViewerWorkerErrorHook, FileViewerWorkerEventHandler, FileViewerWorkerFactory, FileViewerWorkerMessageHook, WorkerProvider, WorkerRef, } from './platform/worker';
export type { FileViewerAiOptions, FileViewerArchiveEntryActionContext, FileViewerArchiveEntryActionPolicy, FileViewerArchiveEntryActionsOptions, FileViewerArchivePasswordRequestContext, FileViewerArchivePasswordRequestReason, FileViewerArchiveOptions, FileViewerApplyViewStateOptions, FileViewerBeforeOperation, FileViewerCadDwfLineWeightMode, FileViewerCadOptions, FileViewerCadRenderer, FileViewerModelLinearUnit, FileViewerModelOptions, FileViewerComponentEmits, FileViewerComponentEventMap, FileViewerComponentProps, FileViewerDocumentAnchor, FileViewerDocumentChunk, FileViewerDownloadOptions, FileViewerDocxOptions, FileViewerDrawingOptions, FileViewerEvent, FileViewerEventHandler, FileViewerEventType, FileViewerExportHtmlOptions, FileViewerFileRef, FileViewerFitMode, FileViewerFitOptions, FileViewerFitRequest, FileViewerFitResize, FileViewerFitResult, FileViewerGeoBasemapOptions, FileViewerGeoBasemapPreset, FileViewerGeoOptions, FileRenderContext, FileRenderExportAdapter, FileRenderThumbnailAdapter, FileRenderExportMode, FileRenderExportOptions, FileRenderHandler, FileRenderHandlerComposite, FileViewerBuiltinRendererPreset, FileViewerInstance, FileViewerLoadOptions, FileViewerLifecycleContext, FileViewerLifecycleHooks, FileViewerLifecyclePhase, FileViewerI18nOptions, FileViewerLocale, FileViewerMessageKey, FileViewerMessageParams, FileViewerMessageResolver, FileViewerMessages, FileViewerNavigationState, FileViewerOperationAvailability, FileViewerOperationContext, FileViewerOperationType, FileViewerOptions, FileViewerPdfOptions, FileViewerPresentationOptions, FileViewerPrintOptions, FileViewerPublicApi, FileViewerRenderedInstance, FileViewerRendererMode, FileViewerRendererPluginAssetKind, FileViewerRendererPluginAssetManifest, FileViewerRendererPluginAssetEntry, FileViewerRenderStateKind, FileViewerRenderPurpose, FileViewerRendererCategory, FileViewerRendererHandlerRegistration, FileViewerRendererInstallContext, FileViewerRendererPlugin, FileViewerRendererPluginInput, FileViewerRendererPresetInput, FileViewerRendererPresetName, FileViewerRendererPreset, FileViewerSearchMatch, FileViewerSearchOptions, FileViewerSearchProvider, FileViewerSearchState, FileViewerSource, FileViewerSourceKind, FileViewerThumbnailCaptureOptions, FileViewerThumbnailFit, FileViewerThumbnailFormat, FileViewerSpreadsheetOptions, FileViewerStateDescriptor, FileViewerStateTheme, FileViewerStyleIsolation, FileViewerTextOptions, FileViewerResolvedThemeMode, FileViewerThemeMode, FileViewerToolbarActionMap, FileViewerToolbarItem, FileViewerToolbarOptions, FileViewerToolbarPosition, FileViewerResolvedToolbarItem, FileViewerUiDensity, FileViewerUiOptions, FileViewerTypstOptions, FileViewerViewScrollState, FileViewerViewState, FileViewerViewStateChange, FileViewerViewStateChangeAction, FileViewerViewStateChangeSource, FileViewerViewStateProvider, FileViewerWatermarkOptions, FileViewerZoomProvider, FileViewerZoomState, NormalizedFileViewerSource, RendererCapability, RendererDefinition, RendererPlugin, RendererLoadContext, RendererLoader, RendererRegistry, RendererSession, RenderSurface, ViewerCapabilityState, ViewerLifecycleContext, ViewerOperationContext, } from './contracts/types';
export type { FileViewerAiOptions, FileViewerArchiveEntryActionContext, FileViewerArchiveEntryActionPolicy, FileViewerArchiveEntryActionsOptions, FileViewerArchivePasswordRequestContext, FileViewerArchivePasswordRequestReason, FileViewerArchiveOptions, FileViewerApplyViewStateOptions, FileViewerBeforeOperation, FileViewerCadDwfLineWeightMode, FileViewerCadOptions, FileViewerCadRenderer, FileViewerModelLinearUnit, FileViewerModelOptions, FileViewerComponentEmits, FileViewerComponentEventMap, FileViewerComponentProps, FileViewerDocumentAnchor, FileViewerDocumentChunk, FileViewerDownloadOptions, FileViewerDocxOptions, FileViewerDrawingOptions, FileViewerEvent, FileViewerEventHandler, FileViewerEventType, FileViewerExportHtmlOptions, FileViewerFileRef, FileViewerFitMode, FileViewerFitOptions, FileViewerFitRequest, FileViewerFitResize, FileViewerFitResult, FileViewerGeoBasemapOptions, FileViewerGeoBasemapPreset, FileViewerGeoOptions, FileViewerTiandituMapStyle, FileRenderContext, FileRenderExportAdapter, FileRenderThumbnailAdapter, FileRenderExportMode, FileRenderExportOptions, FileRenderHandler, FileRenderHandlerComposite, FileViewerBuiltinRendererPreset, FileViewerInstance, FileViewerLoadOptions, FileViewerLifecycleContext, FileViewerLifecycleHooks, FileViewerLifecyclePhase, FileViewerI18nOptions, FileViewerLocale, FileViewerMessageKey, FileViewerMessageParams, FileViewerMessageResolver, FileViewerMessages, FileViewerNavigationState, FileViewerOperationAvailability, FileViewerOperationContext, FileViewerOperationType, FileViewerOptions, FileViewerPdfBoundingBox, FileViewerPdfBoundingBoxOrigin, FileViewerPdfBoundingBoxUnit, FileViewerPdfOptions, FileViewerPresentationOptions, FileViewerPrintOptions, FileViewerPrintMaskOptions, FileViewerPrintMaskRegion, FileViewerPrintStamp, FileViewerPublicApi, FileViewerRenderedInstance, FileViewerRendererMode, FileViewerRendererPluginAssetKind, FileViewerRendererPluginAssetManifest, FileViewerRendererPluginAssetEntry, FileViewerRenderStateKind, FileViewerRenderPurpose, FileViewerRendererCategory, FileViewerRendererHandlerRegistration, FileViewerRendererInstallContext, FileViewerRendererPlugin, FileViewerRendererPluginInput, FileViewerRendererPresetInput, FileViewerRendererPresetName, FileViewerRendererPreset, FileViewerSearchMatch, FileViewerSearchOptions, FileViewerSearchProvider, FileViewerSearchState, FileViewerSource, FileViewerSourceKind, FileViewerThumbnailCaptureOptions, FileViewerThumbnailFit, FileViewerThumbnailFormat, FileViewerSpreadsheetOptions, FileViewerStateDescriptor, FileViewerStateTheme, FileViewerStyleIsolation, FileViewerTextOptions, FileViewerResolvedThemeMode, FileViewerThemeMode, FileViewerToolbarActionMap, FileViewerToolbarItem, FileViewerToolbarOptions, FileViewerToolbarPosition, FileViewerResolvedToolbarItem, FileViewerUiDensity, FileViewerUiOptions, FileViewerTypstOptions, FileViewerViewScrollState, FileViewerViewState, FileViewerViewStateChange, FileViewerViewStateChangeAction, FileViewerViewStateChangeSource, FileViewerViewStateProvider, FileViewerWatermarkOptions, FileViewerZoomProvider, FileViewerZoomState, NormalizedFileViewerSource, RendererCapability, RendererDefinition, RendererPlugin, RendererLoadContext, RendererLoader, RendererRegistry, RendererSession, RenderSurface, ViewerCapabilityState, ViewerLifecycleContext, ViewerOperationContext, } from './contracts/types';
export { DEFAULT_FILE_VIEWER_ARCHIVE_WORKER_PATH, DEFAULT_FILE_VIEWER_ARCHIVE_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_DWF_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_LIBREDWG_SCRIPT_PATH, DEFAULT_FILE_VIEWER_CAD_LIBREDWG_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_CAD_WASM_PATH, DEFAULT_FILE_VIEWER_CAD_WORKER_PATH, DEFAULT_FILE_VIEWER_DATA_SQL_WASM_URL, DEFAULT_FILE_VIEWER_MODEL_RUNTIME_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_RUNTIME_URL, DEFAULT_FILE_VIEWER_MODEL_IMPORT_LICENSE_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_IMPORT_LICENSE_URL, DEFAULT_FILE_VIEWER_MODEL_OCCT_LICENSE_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_OCCT_LICENSE_URL, DEFAULT_FILE_VIEWER_MODEL_WASM_PACKAGE_PATH, DEFAULT_FILE_VIEWER_MODEL_WASM_URL, DEFAULT_FILE_VIEWER_MODEL_WORKER_URL, DEFAULT_FILE_VIEWER_DOCX_WORKER_JSZIP_PATH, DEFAULT_FILE_VIEWER_DOCX_WORKER_PATH, DEFAULT_FILE_VIEWER_DOCX_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_PDF_CMAP_PATH, DEFAULT_FILE_VIEWER_PDF_STANDARD_FONT_PATH, DEFAULT_FILE_VIEWER_PDF_WASM_PATH, DEFAULT_FILE_VIEWER_PDF_WORKER_PATH, DEFAULT_FILE_VIEWER_PPT_FONT_PATH, DEFAULT_FILE_VIEWER_PPT_FRAME_CACHE_PATH, DEFAULT_FILE_VIEWER_PPT_MODULE_PATH, DEFAULT_FILE_VIEWER_PPT_RUNTIME_PATH, DEFAULT_FILE_VIEWER_PPT_RUNTIME_VERSION, DEFAULT_FILE_VIEWER_PPT_WASM_PATH, DEFAULT_FILE_VIEWER_PPT_WORKER_PATH, DEFAULT_FILE_VIEWER_PRESENTATION_WORKER_PATH, DEFAULT_FILE_VIEWER_RENDERER_ASSET_MANIFESTS, DEFAULT_FILE_VIEWER_SPREADSHEET_WORKER_PATH, DEFAULT_FILE_VIEWER_TYPST_COMPILER_WASM_URL, DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_URL, DEFAULT_FILE_VIEWER_TYPST_RENDERER_WASM_PACKAGE_PATH, getDefaultFileViewerAssetBaseUrl, getFileViewerRendererAssetManifest, listFileViewerRendererAssetManifests, normalizeFileViewerAssetBaseUrl, resetDefaultFileViewerAssetBaseUrl, resolveFileViewerArchiveWasmUrl, resolveFileViewerArchiveWorkerUrl, resolveFileViewerAssetUrl, resolveFileViewerCadAssetUrls, resolveFileViewerDataSqlWasmUrl, resolveFileViewerDocxWorkerJsZipUrl, resolveFileViewerDocxWorkerUrl, resolveFileViewerDrawioViewerScriptUrl, resolveFileViewerModelAssetUrls, resolveFileViewerPdfAssetUrls, resolveFileViewerPresentationWorkerUrl, resolveFileViewerRendererAssets, resolveFileViewerRuntimeAssetBaseUrl, resolveFileViewerSpreadsheetWorkerUrl, resolveFileViewerTypstCompilerWasmUrl, resolveFileViewerTypstRendererWasmUrl, setDefaultFileViewerAssetBaseUrl, } from './assets.js';
export { ARCHIVE_EXTENSIONS, DEFAULT_RENDERER_DEFINITIONS, DEFAULT_SUPPORTED_EXTENSIONS, IMAGE_EXTENSIONS, MODEL_EXTENSIONS, TEXT_EXTENSIONS, } from './registry/formats.js';
export { precheckFileViewerSource } from './source/precheck.js';
export { DEFAULT_FILE_VIEWER_TEXT_CHUNK_OVERLAP, DEFAULT_FILE_VIEWER_TEXT_CHUNK_SIZE, DEFAULT_FILE_VIEWER_ZOOM_SCALE, buildFileViewerDocumentTextChunks, createEmptyFileViewerSearchState, createFileViewerZoomState, normalizeFileViewerAiOptions, normalizeFileViewerSearchOptions, } from './features/document/model.js';

@@ -176,3 +177,3 @@ export { DEFAULT_FILE_VIEWER_SEARCH_ACTIVE_CLASS, DEFAULT_FILE_VIEWER_SEARCH_MATCH_CLASS, DEFAULT_FILE_VIEWER_SEARCH_MAX_MATCHES, applyFileViewerSearchState, cloneFileViewerSearchState, createFileViewerDomSearchController, createFileViewerDomSearchControllerActionHandlers, destroyFileViewerDomSearchController, observeFileViewerDomSearchController, runFileViewerDomSearchControllerAction, syncFileViewerDomSearchControllerState, } from './features/document/search.js';

export { buildFileViewerWatermarkBackgroundImage, buildFileViewerWatermarkInlineStyle, buildFileViewerWatermarkStyle, buildFileViewerWatermarkSvg, normalizeFileViewerWatermark, resolveFileViewerWatermarkPresentationState, } from './features/watermark.js';
export { buildFileViewerPrintMaskOverlayHtml, applyFileViewerPagePrintMasksToHtml, normalizeFileViewerPrintMaskOptions, normalizeFileViewerPrintMaskRegion, FILE_VIEWER_PRINT_MASK_STYLE, } from './features/printMask.js';
export { buildFileViewerPrintMaskOverlayHtml, applyFileViewerPagePrintMasksToHtml, normalizeFileViewerPrintMaskOptions, normalizeFileViewerPrintMaskRegion, normalizeFileViewerPrintStamp, FILE_VIEWER_PRINT_MASK_STYLE, } from './features/printMask.js';
export { openFileViewerPrintMaskDesignerAsync, } from './features/printMaskLoader.js';

@@ -179,0 +180,0 @@ export { cancelFileViewerPreviewRequest, DEFAULT_FILE_VIEWER_STREAMING_PDF_FILENAME, DEFAULT_FILE_VIEWER_PREVIEW_LOAD_ERROR_LOGGER, DEFAULT_PDF_RANGE_CHUNK_SIZE, FILE_VIEWER_PREVIEW_LOAD_ERROR_PREFIXES, FILE_VIEWER_REMOTE_MISSING_DATA_ERROR_MESSAGE, applyFileViewerEmptyPreviewState, applyFileViewerPreviewFilenameState, applyFileViewerPreviewSourceUrlState, applyFileViewerReadPreviewState, applyFileViewerRenderReadinessState, applyFileViewerPreviewRequestResetState, commitFileViewerEmptyPreviewResetState, commitFileViewerLoadStartState, commitFileViewerPreviewRequestStartState, commitFileViewerRenderCompleteState, commitFileViewerRemoteDownloadState, createFileViewerEmptyPreviewState, createFileViewerLoadStartState, createFileViewerPreviewStateTarget, createFileViewerSourceLoadingActionHandlers, createFileViewerReadPreviewState, createFileViewerPreviewRequestResetState, createFileViewerRenderCompleteState, createFileViewerRequestController, createFileViewerRequestScope, createFileViewerStreamingPdfPlaceholderFile, finalizeFileViewerPreviewLoadState, hasFileViewerPreviewSource, isFileViewerAbortError, isSameOriginUrl, normalizeFileViewerSourceUrl, normalizePdfStreamingMode, resolveFileViewerFileRefSourcePlan, resolveFileViewerLoadStartMessage, resolveFileViewerMissingRemoteDataErrorMessage, resolveFileViewerPreviewLoadErrorMessage, resolveFileViewerPreviewRequestReason, resolveFileViewerRemoteSourcePlan, resolveFileViewerPageHref, reportFileViewerMissingRemoteData, reportFileViewerPreviewLoadError, runFileViewerLocalFilePreview, runFileViewerPreviewComponentUnmount, runFileViewerPreviewRequest, runFileViewerPreviewSourceChange, runFileViewerRemoteFilePreview, runFileViewerReadAndRenderFile, runFileViewerStreamingPdfPreview, shouldStreamPdfUrl, } from './source/loading.js';

@@ -292,3 +292,3 @@ import { applyFileViewerPagePrintMasksToHtml, buildFileViewerPrintMaskOverlayHtml, FILE_VIEWER_PRINT_MASK_STYLE, normalizeFileViewerPrintMaskOptions, } from '../features/printMask.js';

export const buildExportHtmlDocument = ({ contentHtml, includeDocumentStyles = true, printStyle = '', title, watermarkInlineStyle = '', mask = null, }) => {
var _a;
var _a, _b;
const watermark = watermarkInlineStyle

@@ -302,2 +302,3 @@ ? `<div class="viewer-export-watermark" style="${watermarkInlineStyle}"></div>`

regions: (_a = normalizedMask.regions) === null || _a === void 0 ? void 0 : _a.filter(region => region.pageIndex === undefined),
stamps: (_b = normalizedMask.stamps) === null || _b === void 0 ? void 0 : _b.filter(stamp => stamp.pageIndex === undefined),
}

@@ -304,0 +305,0 @@ : null;

@@ -25,9 +25,14 @@ import { registerFileViewerZoomProvider, unregisterFileViewerZoomProvider, } from '../features/document/dom/index.js';

.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}
.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}
.image-lightbox[hidden]{display:none}
.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}
.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)}
.image-stage img:focus-visible{outline:3px solid #2563eb;outline-offset:4px}
.image-lightbox{position:absolute;inset:0;z-index:40;display:flex;align-items:center;justify-content:center;padding:40px;background:rgba(15,23,42,.9);box-sizing:border-box;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .18s ease,visibility 0s linear .18s}
.image-lightbox[data-open='true']{opacity:1;visibility:visible;pointer-events:auto;transition-delay:0s}
.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:default;transform:scale(.985);transition:transform .18s ease}
.image-lightbox[data-open='true'] img{transform:scale(1)}
.image-lightbox button{position:absolute;top:16px;right:16px;display:grid;width:40px;height:40px;place-items:center;padding:0;border:1px solid rgba(255,255,255,.7);border-radius:999px;background:rgba(255,255,255,.96);color:#172033;font:400 27px/1 Arial,sans-serif;cursor:pointer;box-shadow:0 12px 28px rgba(0,0,0,.24);transition:background-color .14s ease,transform .14s ease}
.image-lightbox button:hover{background:#fff;transform:scale(1.04)}
.image-lightbox button:focus-visible{outline:3px solid #60a5fa;outline-offset:2px}
[data-viewer-theme='dark'] .image-viewer{background:var(--file-viewer-render-surface-background,#101820)}
@media (prefers-color-scheme:dark){[data-viewer-theme='system'] .image-viewer{background:var(--file-viewer-render-surface-background,#101820)}}
@media (max-width:767px){.image-stage{padding:12px}.image-lightbox{padding:16px}.image-lightbox button{top:12px;right:12px}}
@media (prefers-reduced-motion:reduce){.image-lightbox,.image-lightbox img,.image-lightbox button{transition:none}}
`;

@@ -72,5 +77,6 @@ const createStyle = (documentRef) => {

lightbox.className = 'image-lightbox';
lightbox.hidden = true;
lightbox.dataset.open = 'false';
lightbox.setAttribute('role', 'dialog');
lightbox.setAttribute('aria-modal', 'true');
lightbox.setAttribute('aria-hidden', 'true');
const image = documentRef.createElement('img');

@@ -82,8 +88,21 @@ image.alt = t('image.lightbox.alt');

closeButton.setAttribute('aria-label', t('image.lightbox.close'));
closeButton.textContent = 'x';
closeButton.textContent = '×';
let previousFocus = null;
const close = () => {
lightbox.hidden = true;
if (lightbox.dataset.open !== 'true')
return;
lightbox.dataset.open = 'false';
lightbox.setAttribute('aria-hidden', 'true');
if (previousFocus === null || previousFocus === void 0 ? void 0 : previousFocus.isConnected) {
previousFocus.focus({ preventScroll: true });
}
previousFocus = null;
};
const onKeyDown = (event) => {
if (event.key === 'Escape' && lightbox.dataset.open === 'true') {
event.preventDefault();
close();
}
};
closeButton.addEventListener('click', close);
image.addEventListener('click', close);
lightbox.addEventListener('click', event => {

@@ -94,11 +113,17 @@ if (event.target === lightbox) {

});
documentRef.addEventListener('keydown', onKeyDown);
lightbox.append(image, closeButton);
return {
element: lightbox,
open() {
lightbox.hidden = false;
open(invoker) {
previousFocus =
invoker ||
(documentRef.activeElement instanceof HTMLElement ? documentRef.activeElement : null);
lightbox.dataset.open = 'true';
lightbox.setAttribute('aria-hidden', 'false');
closeButton.focus({ preventScroll: true });
},
destroy() {
closeButton.removeEventListener('click', close);
image.removeEventListener('click', close);
documentRef.removeEventListener('keydown', onKeyDown);
lightbox.remove();

@@ -129,7 +154,17 @@ },

image.src = src;
image.tabIndex = 0;
image.setAttribute('role', 'button');
image.setAttribute('aria-haspopup', 'dialog');
stage.append(image);
root.append(stage);
const lightbox = createLightbox(documentRef, src, t);
const openLightbox = () => lightbox.open();
const openLightbox = () => lightbox.open(image);
const openLightboxFromKeyboard = (event) => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
lightbox.open(image);
}
};
image.addEventListener('click', openLightbox);
image.addEventListener('keydown', openLightboxFromKeyboard);
const getMinScale = () => Math.min(0.1, fitScale || 0.1);

@@ -258,2 +293,3 @@ const clampScale = (value) => {

image.removeEventListener('click', openLightbox);
image.removeEventListener('keydown', openLightboxFromKeyboard);
lightbox.destroy();

@@ -260,0 +296,0 @@ target.replaceChildren();

@@ -639,3 +639,3 @@ // Imperative viewer composition root.

async printWithMask(printOptions = {}) {
var _a, _b, _c, _d;
var _a, _b, _c, _d, _e;
const result = await openFileViewerPrintMaskDesignerAsync({

@@ -647,2 +647,3 @@ root: container,

initialRegions: (_d = printOptions.mask) === null || _d === void 0 ? void 0 : _d.regions,
initialStamps: (_e = printOptions.mask) === null || _e === void 0 ? void 0 : _e.stamps,
});

@@ -649,0 +650,0 @@ if (!(result === null || result === void 0 ? void 0 : result.mask)) {

@@ -265,3 +265,3 @@ import { buildFileViewerRenderedHtmlDocument, triggerFileViewerBlobDownload, triggerFileViewerUrlDownload, waitForFileViewerPrintWindowReady, } from '../output/export.js';

async printWithMask(options = {}) {
var _a, _b, _c, _d, _e, _f, _g;
var _a, _b, _c, _d, _e, _f, _g, _h;
try {

@@ -280,2 +280,3 @@ const source = getRenderedSource();

initialRegions: (_d = options.mask) === null || _d === void 0 ? void 0 : _d.regions,
initialStamps: (_e = options.mask) === null || _e === void 0 ? void 0 : _e.stamps,
});

@@ -288,5 +289,5 @@ if (!(result === null || result === void 0 ? void 0 : result.mask)) {

...options,
watermarkInlineStyle: (_f = (_e = options.watermarkInlineStyle) !== null && _e !== void 0 ? _e : getWatermarkInlineStyle === null || getWatermarkInlineStyle === void 0 ? void 0 : getWatermarkInlineStyle()) !== null && _f !== void 0 ? _f : undefined,
watermarkInlineStyle: (_g = (_f = options.watermarkInlineStyle) !== null && _f !== void 0 ? _f : getWatermarkInlineStyle === null || getWatermarkInlineStyle === void 0 ? void 0 : getWatermarkInlineStyle()) !== null && _g !== void 0 ? _g : undefined,
mask: result.mask,
printAvailable: (_g = getPrintAvailable === null || getPrintAvailable === void 0 ? void 0 : getPrintAvailable()) !== null && _g !== void 0 ? _g : true,
printAvailable: (_h = getPrintAvailable === null || getPrintAvailable === void 0 ? void 0 : getPrintAvailable()) !== null && _h !== void 0 ? _h : true,
});

@@ -293,0 +294,0 @@ }

{
"name": "@file-viewer/core",
"version": "2.2.4",
"version": "2.2.5",
"private": false,

@@ -5,0 +5,0 @@ "type": "module",

@@ -17,2 +17,19 @@ # @file-viewer/core

## Preflight Before Rendering
`precheckFileViewerSource()` does not create a viewer or load a heavy renderer. It checks whether the extension is available and validates known PDF, OpenXML / OpenDocument, legacy OLE Office, and RTF signatures or package parts. `valid: null` explicitly means capability-only detection, not a full parse; the real renderer remains the final authority for malformed content.
```ts
import { precheckFileViewerSource } from '@file-viewer/core/headless'
const result = await precheckFileViewerSource(file, {
// Restrict this to the extensions actually installed by this product.
supportedExtensions: ['pdf', 'docx', 'xlsx', 'pptx']
})
if (!result.previewable) {
console.warn(result.reason, result.missingParts)
}
```
## Entry points

@@ -19,0 +36,0 @@

@@ -17,2 +17,19 @@ # @file-viewer/core

## 渲染前预检
`precheckFileViewerSource()` 不会创建 viewer,也不会加载重型 renderer。它先检查当前扩展名是否在能力范围内,并对 PDF、OpenXML / OpenDocument、旧版 OLE Office、RTF 等格式执行签名或包结构检查。`valid: null` 明确表示该格式只有能力检查、没有做完整解析;真实 renderer 仍是畸形文件的最终判断者。
```ts
import { precheckFileViewerSource } from '@file-viewer/core/headless'
const result = await precheckFileViewerSource(file, {
// 可传当前产品实际安装的扩展名列表,避免把未装 preset 的格式报成可预览
supportedExtensions: ['pdf', 'docx', 'xlsx', 'pptx']
})
if (!result.previewable) {
console.warn(result.reason, result.missingParts)
}
```
## Entry points

@@ -19,0 +36,0 @@