@papyrus-sdk/engine-epub 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +66 -5
- package/dist/index.d.ts +66 -5
- package/dist/index.js +1259 -80
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1256 -77
- package/dist/index.mjs.map +1 -1
- package/package.json +50 -50
- package/LICENSE +0 -21
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts"],"sourcesContent":["import ePub from 'epubjs';\r\nimport { BaseDocumentEngine } from '@papyrus-sdk/core';\r\nimport { DocumentLoadInput, DocumentLoadRequest, DocumentSource, DocumentType, TextItem, OutlineItem, FileLike, TextSelection, PageDestination } from '@papyrus-sdk/types';\r\n\r\nexport class EPUBEngine extends BaseDocumentEngine {\r\n private book: any = null;\r\n private spineItems: any[] = [];\r\n private renditions = new Map<string, any>();\r\n private renditionTargets = new Map<string, HTMLElement>();\r\n private pageSizes = new Map<number, { width: number; height: number }>();\r\n private currentPage: number = 1;\r\n private zoom: number = 1.0;\r\n private rotation: number = 0;\r\n\r\n getRenderTargetType(): 'element' { return 'element'; }\r\n\r\n async load(input: DocumentLoadInput): Promise<void> {\r\n try {\r\n const { source, type } = this.normalizeLoadInput(input);\r\n if (type && type !== 'epub') {\r\n throw new Error(`[EPUBEngine] Tipo de documento não suportado: ${type}`);\r\n }\r\n\r\n const data = await this.resolveSource(source);\r\n\r\n this.book = ePub(data);\r\n await this.book.ready;\r\n this.spineItems = this.book.spine?.items ?? [];\r\n this.currentPage = 1;\r\n this.renditions.forEach((rendition) => rendition?.destroy?.());\r\n this.renditions.clear();\r\n this.renditionTargets.clear();\r\n this.pageSizes.clear();\r\n } catch (error) {\r\n console.error('[EPUBEngine] Erro ao carregar:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n getPageCount(): number { return this.spineItems.length; }\r\n getCurrentPage(): number { return this.currentPage; }\r\n goToPage(page: number): void {\r\n if (page >= 1 && page <= this.getPageCount()) this.currentPage = page;\r\n }\r\n setZoom(zoom: number): void {\r\n this.zoom = Math.max(0.5, Math.min(3.0, zoom));\r\n this.renditions.forEach((rendition) => this.applyRenditionTheme(rendition));\r\n }\r\n getZoom(): number { return this.zoom; }\r\n\r\n rotate(direction: 'clockwise' | 'counterclockwise'): void {\r\n if (direction === 'clockwise') this.rotation = (this.rotation + 90) % 360;\r\n else { this.rotation = (this.rotation - 90) % 360; if (this.rotation < 0) this.rotation += 360; }\r\n }\r\n\r\n getRotation(): number { return this.rotation; }\r\n\r\n async getPageDimensions(pageIndex: number): Promise<{ width: number; height: number }> {\r\n const size = this.pageSizes.get(pageIndex);\r\n if (size) return size;\r\n return { width: 0, height: 0 };\r\n }\r\n\r\n async selectText(\r\n pageIndex: number,\r\n rect: { x: number; y: number; width: number; height: number }\r\n ): Promise<TextSelection | null> {\r\n void pageIndex;\r\n void rect;\r\n return null;\r\n }\r\n\r\n async renderPage(pageIndex: number, target: any, scale: number): Promise<void> {\r\n const scaleKey = Math.round(scale * 1000);\r\n const element = target as HTMLElement;\r\n if (!this.book || !element) return;\r\n\r\n const spineItem = this.spineItems[pageIndex];\r\n if (!spineItem) return;\r\n\r\n const width = element.clientWidth > 0 ? element.clientWidth : 640;\r\n const height = element.clientHeight > 0 ? element.clientHeight : 900;\r\n element.style.width = `${width}px`;\r\n element.style.height = `${height}px`;\r\n if (width >= 320 && height >= 480) this.pageSizes.set(pageIndex, { width, height });\r\n\r\n const renditionKey = `${pageIndex}:${scaleKey}`;\r\n let rendition = this.renditions.get(renditionKey);\r\n const currentTarget = this.renditionTargets.get(renditionKey);\r\n if (!rendition || currentTarget !== element) {\r\n if (rendition?.destroy) rendition.destroy();\r\n element.innerHTML = '';\r\n rendition = this.book.renderTo(element, {\r\n width,\r\n height,\r\n flow: 'paginated',\r\n spread: 'none',\r\n });\r\n this.renditions.set(renditionKey, rendition);\r\n this.renditionTargets.set(renditionKey, element);\r\n if (rendition?.hooks?.content?.register) {\r\n rendition.hooks.content.register((contents: any) => {\r\n const frame = contents?.document?.defaultView?.frameElement as HTMLIFrameElement | null;\r\n if (frame) {\r\n frame.setAttribute('sandbox', 'allow-scripts allow-same-origin');\r\n }\r\n });\r\n }\r\n } else if (typeof rendition.resize === 'function') {\r\n rendition.resize(width, height);\r\n }\r\n\r\n if (rendition) {\r\n this.applyRenditionTheme(rendition);\r\n const targetRef = spineItem.href || spineItem.idref || spineItem.cfiBase || pageIndex;\r\n await rendition.display(targetRef);\r\n }\r\n }\r\n\r\n async renderTextLayer(pageIndex: number, container: any, scale: number): Promise<void> {\r\n void pageIndex;\r\n void scale;\r\n const element = container as HTMLElement;\r\n if (element) element.innerHTML = '';\r\n }\r\n\r\n async getTextContent(pageIndex: number): Promise<TextItem[]> {\r\n if (!this.book) return [];\r\n const spineItem = this.spineItems[pageIndex];\r\n if (!spineItem) return [];\r\n\r\n try {\r\n const section = this.book.spine.get(spineItem.idref || spineItem.href);\r\n const text = typeof section?.text === 'function' ? await section.text() : '';\r\n if (!text) return [];\r\n return [{\r\n str: text,\r\n dir: 'ltr',\r\n width: 0,\r\n height: 0,\r\n transform: [1, 0, 0, 1, 0, 0],\r\n fontName: 'default',\r\n }];\r\n } catch {\r\n return [];\r\n }\r\n }\r\n\r\n async getOutline(): Promise<OutlineItem[]> {\r\n if (!this.book) return [];\r\n const nav = await this.book.loaded?.navigation;\r\n const toc = nav?.toc ?? [];\r\n if (!toc.length) return [];\r\n\r\n const mapItem = (item: any): OutlineItem => {\r\n const title = item.label || item.title || '';\r\n const pageIndex = this.getSpineIndexByHref(item.href || '');\r\n const children = Array.isArray(item.subitems) ? item.subitems.map(mapItem) : [];\r\n const outlineItem: OutlineItem = { title, pageIndex };\r\n if (children.length > 0) outlineItem.children = children;\r\n return outlineItem;\r\n };\r\n\r\n return toc.map(mapItem);\r\n }\r\n\r\n async getPageIndex(dest: PageDestination): Promise<number | null> {\r\n if (!dest) return null;\r\n if (typeof dest === 'string') return this.getSpineIndexByHref(dest);\r\n if (dest.kind === 'href') return this.getSpineIndexByHref(dest.value);\r\n if (dest.kind === 'pageIndex') return dest.value;\r\n if (dest.kind === 'pageNumber') return Math.max(0, dest.value - 1);\r\n return null;\r\n }\r\n\r\n destroy(): void {\r\n this.renditions.forEach((rendition) => rendition?.destroy?.());\r\n this.renditions.clear();\r\n this.renditionTargets.clear();\r\n this.pageSizes.clear();\r\n if (this.book?.destroy) this.book.destroy();\r\n this.book = null;\r\n this.spineItems = [];\r\n }\r\n\r\n private applyRenditionTheme(rendition: any): void {\r\n if (!rendition) return;\r\n const fontSize = `${Math.round(this.zoom * 100)}%`;\r\n if (rendition.themes?.fontSize) {\r\n rendition.themes.fontSize(fontSize);\r\n } else if (rendition.themes?.override) {\r\n rendition.themes.override('font-size', fontSize);\r\n }\r\n }\r\n\r\n private getSpineIndexByHref(href: string): number {\r\n const normalized = this.normalizeHref(href);\r\n if (!normalized) return -1;\r\n const index = this.spineItems.findIndex((item) => this.normalizeHref(item.href) === normalized);\r\n return index;\r\n }\r\n\r\n private normalizeHref(href: string): string {\r\n return href.split('#')[0];\r\n }\r\n\r\n private isUriSource(source: DocumentSource): source is { uri: string } {\r\n return typeof source === 'object' && source !== null && 'uri' in source;\r\n }\r\n\r\n private isDataSource(source: DocumentSource): source is { data: ArrayBuffer | Uint8Array } {\r\n return typeof source === 'object' && source !== null && 'data' in source;\r\n }\r\n\r\n private isFileLike(source: DocumentSource): source is FileLike {\r\n return typeof source === 'object' && source !== null && typeof (source as FileLike).arrayBuffer === 'function';\r\n }\r\n\r\n private normalizeLoadInput(input: DocumentLoadInput): { source: DocumentSource; type?: DocumentType } {\r\n if (this.isLoadRequest(input)) {\r\n return { source: input.source, type: input.type };\r\n }\r\n return { source: input };\r\n }\r\n\r\n private isLoadRequest(input: DocumentLoadInput): input is DocumentLoadRequest {\r\n return typeof input === 'object' && input !== null && 'source' in input && 'type' in input;\r\n }\r\n\r\n private async resolveSource(source: DocumentSource): Promise<any> {\r\n if (typeof source === 'string') {\r\n const dataUri = this.parseDataUri(source);\r\n if (dataUri) {\r\n return dataUri.isBase64 ? this.decodeBase64(dataUri.data) : dataUri.data;\r\n }\r\n if (this.looksLikeUri(source)) {\r\n return source;\r\n }\r\n if (this.isLikelyBase64(source)) {\r\n return this.decodeBase64(source);\r\n }\r\n return source;\r\n }\r\n if (this.isUriSource(source)) return source.uri;\r\n if (this.isDataSource(source)) return source.data;\r\n if (this.isFileLike(source)) return await source.arrayBuffer();\r\n return source;\r\n }\r\n\r\n private parseDataUri(value: string): { isBase64: boolean; data: string } | null {\r\n const match = /^data:([^;,]+)?(;base64)?,(.*)$/.exec(value);\r\n if (!match) return null;\r\n const isBase64 = Boolean(match[2]);\r\n const data = match[3] ?? '';\r\n return { isBase64, data };\r\n }\r\n\r\n private decodeBase64(value: string): Uint8Array {\r\n const clean = value.replace(/\\s/g, '');\r\n if (typeof atob !== 'function') {\r\n throw new Error('[EPUBEngine] atob não está disponível para decodificar base64.');\r\n }\r\n const binary = atob(clean);\r\n const len = binary.length;\r\n const bytes = new Uint8Array(len);\r\n for (let i = 0; i < len; i += 1) {\r\n bytes[i] = binary.charCodeAt(i);\r\n }\r\n return bytes;\r\n }\r\n\r\n private looksLikeUri(value: string): boolean {\r\n return (\r\n value.startsWith('http://') ||\r\n value.startsWith('https://') ||\r\n value.startsWith('/') ||\r\n value.startsWith('./') ||\r\n value.startsWith('../') ||\r\n value.startsWith('file://')\r\n );\r\n }\r\n\r\n private isLikelyBase64(value: string): boolean {\r\n if (this.looksLikeUri(value)) return false;\r\n if (value.includes('.')) return false;\r\n if (value.length < 16) return false;\r\n return /^[A-Za-z0-9+/=]+$/.test(value);\r\n }\r\n}\r\n"],"mappings":"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","names":["ePub"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts"],"sourcesContent":["import ePub from \"epubjs\";\nimport { BaseDocumentEngine } from \"@papyrus-sdk/core\";\nimport {\n DocumentLoadInput,\n DocumentLoadRequest,\n DocumentSource,\n DocumentType,\n TextItem,\n OutlineItem,\n FileLike,\n TextSelection,\n PageDestination,\n} from \"@papyrus-sdk/types\";\n\nexport class EPUBEngine extends BaseDocumentEngine {\n private book: any = null;\n private spineItems: any[] = [];\n private coverUrl: string | null = null;\n private readerRendition: any = null;\n private readerTarget: HTMLElement | null = null;\n private pageSizes = new Map<number, { width: number; height: number }>();\n private currentPage: number = 1;\n private zoom: number = 1.0;\n private rotation: number = 0;\n private heightSyncVersion = 0;\n private renderVersion = 0;\n private renderLock: Promise<void> = Promise.resolve();\n private pendingHrefDestination: string | null = null;\n private destinationSequence: Array<{ href: string; pageIndex: number }> = [];\n private destinationCursor = -1;\n private lastDestinationNavTime = 0;\n private lastDestinationPageIndex: number | null = null;\n private lastDestinationHref: string | null = null;\n private static readonly A4_RATIO = 1.4142;\n private static readonly USE_INTERNAL_IFRAME_SCROLL = true;\n private static readonly MOBILE_VIEWPORT_MAX_WIDTH_PX = 768;\n private static readonly MOBILE_SHORT_VIEWPORT_MAX_HEIGHT_PX = 500;\n private static readonly INTERNAL_VIEWPORT_PADDING_PX = 10;\n private static readonly MAX_SECTION_HEIGHT = 1_000_000;\n private static readonly HEIGHT_PADDING = 24;\n\n getRenderTargetType(): \"element\" {\n return \"element\";\n }\n\n async load(input: DocumentLoadInput): Promise<void> {\n try {\n const { source, type } = this.normalizeLoadInput(input);\n if (type && type !== \"epub\") {\n throw new Error(\n `[EPUBEngine] Tipo de documento não suportado: ${type}`\n );\n }\n\n this.renderVersion += 1;\n this.renderLock = Promise.resolve();\n this.disposeReader();\n this.pageSizes.clear();\n this.spineItems = [];\n this.coverUrl = null;\n this.destinationSequence = [];\n this.destinationCursor = -1;\n this.lastDestinationNavTime = 0;\n this.lastDestinationPageIndex = null;\n this.lastDestinationHref = null;\n if (this.book?.destroy) this.book.destroy();\n\n const data = await this.resolveSource(source);\n\n this.book = ePub(data);\n if (this.book?.opened) {\n await this.book.opened;\n }\n await this.book.ready;\n const packaging =\n (this.book as any)?.package ?? (this.book as any)?.packaging ?? null;\n if (!packaging) {\n throw new Error(\"[EPUBEngine] packaging indisponivel.\");\n }\n if (!(this.book as any).package) {\n (this.book as any).package = packaging;\n }\n if (!(this.book as any).packaging) {\n (this.book as any).packaging = packaging;\n }\n if (this.book?.loaded?.navigation) {\n await this.book.loaded.navigation;\n }\n this.spineItems = this.getLinearSpineItems(this.book.spine?.items ?? []);\n if (typeof this.book.coverUrl === \"function\") {\n try {\n const resolvedCover = await this.book.coverUrl();\n if (typeof resolvedCover === \"string\" && resolvedCover.length > 0) {\n this.coverUrl = resolvedCover;\n }\n } catch {\n this.coverUrl = null;\n }\n }\n this.currentPage = 1;\n } catch (error) {\n console.error(\"[EPUBEngine] Erro ao carregar:\", error);\n throw error;\n }\n }\n\n getPageCount(): number {\n return this.spineItems.length + (this.hasCoverPage() ? 1 : 0);\n }\n getCurrentPage(): number {\n return this.currentPage;\n }\n goToPage(page: number): void {\n if (page < 1 || page > this.getPageCount()) return;\n this.currentPage = page;\n this.pendingHrefDestination = null;\n\n if (this.destinationSequence.length) {\n const destinationIndex = this.findNearestDestinationIndexByPage(page - 1);\n if (destinationIndex >= 0) this.destinationCursor = destinationIndex;\n }\n }\n\n async goToDestination(dest: PageDestination): Promise<number | null> {\n const href = this.extractHrefDestination(dest);\n if (!href) {\n const pageIndex = await this.getPageIndex(dest);\n if (pageIndex != null) this.goToPage(pageIndex + 1);\n return pageIndex;\n }\n\n // If the rendition already shows this exact base file and we're just\n // re-navigating to it without a different anchor, short-circuit.\n const baseHref = this.normalizeHref(href);\n const currentBaseHref = this.lastDestinationHref\n ? this.normalizeHref(this.lastDestinationHref)\n : null;\n const hasAnchor = href.includes(\"#\");\n if (\n !hasAnchor &&\n currentBaseHref &&\n baseHref === currentBaseHref &&\n this.readerRendition\n ) {\n this.debugLog(\"goToDestination:skip-same-base\", {\n href,\n currentBaseHref,\n });\n const pageIndex = await this.resolvePageIndexFromHref(href);\n return pageIndex;\n }\n\n let releaseCurrent: (() => void) | null = null;\n const previousRender = this.renderLock;\n this.renderLock = new Promise<void>((resolve) => {\n releaseCurrent = resolve;\n });\n await previousRender;\n\n try {\n this.pendingHrefDestination = href;\n let pageIndex = await this.resolvePageIndexFromHref(href);\n if (pageIndex != null) this.currentPage = pageIndex + 1;\n this.debugLog(\"goToDestination:start\", {\n href,\n pageIndex,\n currentPage: this.currentPage,\n });\n\n const rendition = this.readerRendition;\n let displayFailed = false;\n if (rendition) {\n try {\n const didDisplay = await this.displayDestinationWithRetry(\n rendition,\n href\n );\n if (!didDisplay)\n throw new Error(\"Destination display retry exhausted\");\n if (pageIndex == null) {\n const locationPageIndex =\n this.getPageIndexFromRenditionLocation(rendition);\n if (locationPageIndex != null) {\n pageIndex = locationPageIndex;\n this.currentPage = locationPageIndex + 1;\n }\n }\n this.debugLog(\"goToDestination:displayed\", {\n href,\n pageIndex,\n currentPage: this.currentPage,\n });\n this.updateDestinationCursor(href, pageIndex);\n this.pendingHrefDestination = null;\n this.lastDestinationNavTime = Date.now();\n this.lastDestinationPageIndex = pageIndex;\n this.lastDestinationHref = href;\n return pageIndex;\n } catch {\n displayFailed = true;\n this.debugLog(\"goToDestination:display-failed\", { href, pageIndex });\n // Rendition may be rebuilding; keep destination pending for renderPage.\n }\n }\n\n if (\n displayFailed &&\n pageIndex != null &&\n this.readerTarget &&\n typeof this.readerTarget.isConnected === \"boolean\" &&\n this.readerTarget.isConnected\n ) {\n // Same-spine anchor jumps may need one more render cycle to settle.\n void this.renderPage(pageIndex, this.readerTarget, 1).catch(() => {\n // Keep pending destination for next cycle if this retry also races.\n });\n }\n\n this.debugLog(\"goToDestination:no-rendition\", {\n href,\n pageIndex,\n currentPage: this.currentPage,\n });\n this.updateDestinationCursor(href, pageIndex);\n return pageIndex;\n } finally {\n releaseCurrent?.();\n }\n }\n\n async goToAdjacentDestination(delta: number): Promise<number | null> {\n if (!Number.isFinite(delta) || delta === 0) return this.currentPage - 1;\n await this.ensureDestinationSequence();\n if (!this.destinationSequence.length) {\n const basePageIndex = Math.max(0, this.currentPage - 1);\n const nextPageIndex = Math.max(\n 0,\n Math.min(this.getPageCount() - 1, basePageIndex + (delta > 0 ? 1 : -1))\n );\n if (nextPageIndex === basePageIndex) return basePageIndex;\n this.goToPage(nextPageIndex + 1);\n return nextPageIndex;\n }\n\n if (this.destinationCursor < 0) {\n const inferred = this.findNearestDestinationIndexByPage(\n this.currentPage - 1\n );\n this.destinationCursor = inferred >= 0 ? inferred : 0;\n }\n\n // Find the base href of the current position so we can skip entries\n // that share the same spine file (multiple TOC entries in one .xhtml).\n const currentEntry = this.destinationSequence[this.destinationCursor];\n const currentBaseHref = currentEntry\n ? this.normalizeHref(currentEntry.href)\n : null;\n\n this.debugLog(\"goToAdjacentDestination:start\", {\n delta,\n cursor: this.destinationCursor,\n total: this.destinationSequence.length,\n currentPage: this.currentPage,\n currentBaseHref,\n });\n\n // Walk in the delta direction, skipping entries that share the same\n // base href (spine file) as the current position.\n const step = delta > 0 ? 1 : -1;\n let nextIndex = this.destinationCursor;\n const limit = delta > 0 ? this.destinationSequence.length - 1 : 0;\n while (true) {\n const candidate = nextIndex + step;\n if (candidate < 0 || candidate > this.destinationSequence.length - 1)\n break;\n nextIndex = candidate;\n const candidateBaseHref = this.normalizeHref(\n this.destinationSequence[nextIndex].href\n );\n if (!currentBaseHref || candidateBaseHref !== currentBaseHref) break;\n }\n if (nextIndex === this.destinationCursor) {\n this.debugLog(\"goToAdjacentDestination:at-boundary\", {\n delta,\n cursor: this.destinationCursor,\n });\n const current = this.destinationSequence[this.destinationCursor];\n return current?.pageIndex ?? this.currentPage - 1;\n }\n\n const target = this.destinationSequence[nextIndex];\n if (!target) return null;\n\n // Always advance the cursor before calling goToDestination to prevent\n // stale cursor from causing infinite same-page navigation loops.\n this.destinationCursor = nextIndex;\n\n const resolved = await this.goToDestination({\n kind: \"href\",\n value: target.href,\n });\n if (resolved != null) {\n this.debugLog(\"goToAdjacentDestination:resolved\", {\n delta,\n nextIndex,\n href: target.href,\n resolved,\n });\n return resolved;\n }\n\n // Revert cursor if navigation failed.\n this.destinationCursor = nextIndex - step;\n this.debugLog(\"goToAdjacentDestination:failed\", {\n delta,\n nextIndex,\n href: target.href,\n });\n return null;\n }\n\n getDestinationNavigationState(): { hasPrev: boolean; hasNext: boolean } {\n const total = this.destinationSequence.length;\n if (!total) {\n return {\n hasPrev: this.currentPage > 1,\n hasNext: this.currentPage < this.getPageCount(),\n };\n }\n\n const cursor =\n this.destinationCursor >= 0\n ? this.destinationCursor\n : this.findNearestDestinationIndexByPage(this.currentPage - 1);\n return {\n hasPrev: cursor > 0,\n hasNext: cursor >= 0 && cursor < total - 1,\n };\n }\n setZoom(zoom: number): void {\n this.zoom = Math.max(0.5, Math.min(3.0, zoom));\n }\n getZoom(): number {\n return this.zoom;\n }\n\n rotate(direction: \"clockwise\" | \"counterclockwise\"): void {\n if (direction === \"clockwise\") this.rotation = (this.rotation + 90) % 360;\n else {\n this.rotation = (this.rotation - 90) % 360;\n if (this.rotation < 0) this.rotation += 360;\n }\n }\n\n getRotation(): number {\n return this.rotation;\n }\n\n async getPageDimensions(\n pageIndex: number\n ): Promise<{ width: number; height: number }> {\n const size = this.pageSizes.get(pageIndex);\n if (size) return size;\n return { width: 0, height: 0 };\n }\n\n async selectText(\n pageIndex: number,\n rect: { x: number; y: number; width: number; height: number }\n ): Promise<TextSelection | null> {\n void pageIndex;\n void rect;\n return null;\n }\n\n async renderPage(\n pageIndex: number,\n target: any,\n scale: number\n ): Promise<void> {\n let releaseCurrent: (() => void) | null = null;\n const previousRender = this.renderLock;\n this.renderLock = new Promise<void>((resolve) => {\n releaseCurrent = resolve;\n });\n await previousRender;\n\n try {\n void scale;\n const pageCount = this.getPageCount();\n if (pageCount <= 0) return;\n const safePageIndex = Math.max(0, Math.min(pageCount - 1, pageIndex));\n const renderVersion = ++this.renderVersion;\n const element = target as HTMLElement;\n if (!this.book || !element) return;\n\n const width = element.clientWidth > 0 ? element.clientWidth : 640;\n const viewportHeightHint = EPUBEngine.USE_INTERNAL_IFRAME_SCROLL\n ? this.getViewportHeightHint(element)\n : null;\n // Avoid carrying an oversized height from a previous long section.\n const rawHeight =\n viewportHeightHint ??\n (element.clientHeight > 0 ? element.clientHeight : 900);\n const normalizedHeight = EPUBEngine.USE_INTERNAL_IFRAME_SCROLL\n ? Math.max(360, Math.min(4000, rawHeight))\n : Math.max(480, Math.min(1400, rawHeight));\n const minA4Height = EPUBEngine.USE_INTERNAL_IFRAME_SCROLL\n ? 0\n : this.getA4MinHeight(width);\n const seedHeight = EPUBEngine.USE_INTERNAL_IFRAME_SCROLL\n ? normalizedHeight\n : Math.max(minA4Height, normalizedHeight);\n if (this.isCoverPage(safePageIndex)) {\n this.renderCoverPage(element, width, seedHeight, safePageIndex);\n if (renderVersion === this.renderVersion) {\n this.currentPage = safePageIndex + 1;\n }\n return;\n }\n\n const spineItem = this.getSpineItemForPage(safePageIndex);\n if (!spineItem) return;\n const displayTargets = [...this.getDisplayTargetsForSpineItem(spineItem)];\n if (!displayTargets.length) return;\n const defaultSectionIndex =\n typeof spineItem.index === \"number\" ? spineItem.index : null;\n const pendingHrefDestination = this.pendingHrefDestination;\n let consumedPendingHref = false;\n if (pendingHrefDestination) {\n const pendingPageIndex = await this.resolvePageIndexFromHref(\n pendingHrefDestination\n );\n const pendingMatchesCurrentPage =\n pendingPageIndex === safePageIndex ||\n this.isHrefMatchingSpineItem(pendingHrefDestination, spineItem);\n if (pendingMatchesCurrentPage) {\n consumedPendingHref = true;\n displayTargets.unshift(\n pendingHrefDestination,\n this.decodeHref(pendingHrefDestination)\n );\n }\n }\n const uniqueTargets = this.uniqueDisplayTargets(displayTargets);\n if (!uniqueTargets.length) return;\n\n element.style.width = `${width}px`;\n element.style.height = `${seedHeight}px`;\n if (width >= 320 && seedHeight >= 480)\n this.pageSizes.set(safePageIndex, { width, height: seedHeight });\n\n let rendition = this.readerRendition;\n if (!rendition || this.readerTarget !== element) {\n this.disposeReader();\n element.innerHTML = \"\";\n rendition = this.createRendition(element, width, seedHeight);\n this.readerRendition = rendition;\n this.readerTarget = element;\n } else if (\n typeof rendition.resize === \"function\" &&\n (rendition as any).manager?.resize\n ) {\n try {\n rendition.resize(width, seedHeight);\n } catch (error) {\n this.disposeReader();\n element.innerHTML = \"\";\n rendition = this.createRendition(element, width, seedHeight);\n this.readerRendition = rendition;\n this.readerTarget = element;\n }\n }\n\n if (rendition) {\n const syncVersion = ++this.heightSyncVersion;\n this.applyRenditionTheme(rendition);\n if (renderVersion !== this.renderVersion) return;\n\n // If goToDestination just navigated to this exact page, skip re-display.\n // The rendition already shows the correct content; re-displaying via\n // spine-item targets would overwrite the href-specific destination.\n const recentDestNav =\n Date.now() - this.lastDestinationNavTime < 200 &&\n this.lastDestinationPageIndex === safePageIndex;\n if (recentDestNav) {\n this.debugLog(\"renderPage:skip-recent-dest-nav\", {\n safePageIndex,\n msSince: Date.now() - this.lastDestinationNavTime,\n });\n // Run height sync without rendition.resize() to avoid resetting\n // the section that goToDestination just displayed.\n await this.syncSectionHeight(\n rendition,\n element,\n safePageIndex,\n width,\n seedHeight,\n defaultSectionIndex,\n true\n );\n if (renderVersion !== this.renderVersion) return;\n // Schedule deferred re-measurements so progressively-rendered\n // content gets its full height even after the initial sync.\n this.scheduleHeightSync(\n syncVersion,\n rendition,\n element,\n safePageIndex,\n width,\n seedHeight,\n defaultSectionIndex,\n true\n );\n if (renderVersion === this.renderVersion) {\n this.currentPage = safePageIndex + 1;\n }\n } else {\n const sectionIndex = await this.displayWithFallback(\n rendition,\n uniqueTargets,\n () => renderVersion !== this.renderVersion\n );\n if (sectionIndex === undefined) return;\n if (renderVersion !== this.renderVersion) return;\n if (\n consumedPendingHref &&\n pendingHrefDestination &&\n pendingHrefDestination.includes(\"#\")\n ) {\n const anchored = await this.displayDestinationWithRetry(\n rendition,\n pendingHrefDestination\n );\n this.debugLog(\"renderPage:anchor-second-pass\", {\n href: pendingHrefDestination,\n anchored,\n });\n if (renderVersion !== this.renderVersion) return;\n }\n await this.syncSectionHeight(\n rendition,\n element,\n safePageIndex,\n width,\n seedHeight,\n sectionIndex ?? defaultSectionIndex\n );\n if (renderVersion !== this.renderVersion) return;\n this.scheduleHeightSync(\n syncVersion,\n rendition,\n element,\n safePageIndex,\n width,\n seedHeight,\n sectionIndex ?? defaultSectionIndex\n );\n if (renderVersion === this.renderVersion) {\n if (consumedPendingHref) this.pendingHrefDestination = null;\n this.currentPage = safePageIndex + 1;\n }\n }\n }\n } finally {\n releaseCurrent?.();\n }\n }\n\n async renderTextLayer(\n pageIndex: number,\n container: any,\n scale: number\n ): Promise<void> {\n void pageIndex;\n void scale;\n const element = container as HTMLElement;\n if (element) element.innerHTML = \"\";\n }\n\n async getTextContent(pageIndex: number): Promise<TextItem[]> {\n if (!this.book) return [];\n if (this.isCoverPage(pageIndex)) return [];\n const spineIndex = this.toSpineIndex(pageIndex);\n if (spineIndex < 0) return [];\n const spineItem = this.spineItems[spineIndex];\n if (!spineItem) return [];\n\n try {\n const section = this.book.spine.get(spineItem.idref || spineItem.href);\n const text =\n typeof section?.text === \"function\" ? await section.text() : \"\";\n if (!text) return [];\n return [\n {\n str: text,\n dir: \"ltr\",\n width: 0,\n height: 0,\n transform: [1, 0, 0, 1, 0, 0],\n fontName: \"default\",\n },\n ];\n } catch {\n return [];\n }\n }\n\n async getOutline(): Promise<OutlineItem[]> {\n if (!this.book) return [];\n const nav = await this.book.loaded?.navigation;\n const toc = nav?.toc ?? [];\n if (!toc.length) return [];\n await this.ensureDestinationSequence();\n\n const mapItem = async (item: any): Promise<OutlineItem> => {\n const title = item.label || item.title || \"\";\n const href = item.href || \"\";\n const resolvedIndex = await this.resolvePageIndexFromHref(href);\n const pageIndex = resolvedIndex ?? -1;\n const children = Array.isArray(item.subitems)\n ? await Promise.all(item.subitems.map(mapItem))\n : [];\n const outlineItem: OutlineItem = { title, pageIndex };\n if (href) {\n outlineItem.dest = { kind: \"href\", value: href };\n }\n if (children.length > 0) outlineItem.children = children;\n return outlineItem;\n };\n\n return await Promise.all(toc.map(mapItem));\n }\n\n async getPageIndex(dest: PageDestination): Promise<number | null> {\n if (!dest) return null;\n if (typeof dest === \"string\")\n return await this.resolvePageIndexFromHref(dest);\n if (dest.kind === \"href\")\n return await this.resolvePageIndexFromHref(dest.value);\n if (dest.kind === \"pageIndex\")\n return Math.max(0, Math.min(this.getPageCount() - 1, dest.value));\n if (dest.kind === \"pageNumber\")\n return Math.max(0, Math.min(this.getPageCount() - 1, dest.value - 1));\n return null;\n }\n\n destroy(): void {\n this.renderVersion += 1;\n this.renderLock = Promise.resolve();\n this.pendingHrefDestination = null;\n this.destinationSequence = [];\n this.destinationCursor = -1;\n this.lastDestinationNavTime = 0;\n this.lastDestinationPageIndex = null;\n this.lastDestinationHref = null;\n this.disposeReader();\n this.pageSizes.clear();\n if (this.book?.destroy) this.book.destroy();\n this.book = null;\n this.spineItems = [];\n this.coverUrl = null;\n }\n\n private applyRenditionTheme(rendition: any): void {\n if (!rendition) return;\n const fontSize = \"100%\";\n if (rendition.themes?.fontSize) {\n rendition.themes.fontSize(fontSize);\n } else if (rendition.themes?.override) {\n rendition.themes.override(\"font-size\", fontSize);\n }\n }\n\n private getSpineIndexByHref(href: string): number {\n const normalized = this.normalizeHref(href);\n const decoded = this.decodeHref(normalized);\n if (!normalized) return -1;\n const candidates = new Set<string>([normalized, decoded].filter(Boolean));\n const exactIndex = this.spineItems.findIndex((item) => {\n const itemHref = this.normalizeHref(item.href);\n const itemDecoded = this.decodeHref(itemHref);\n return candidates.has(itemHref) || candidates.has(itemDecoded);\n });\n if (exactIndex >= 0) return exactIndex;\n\n return this.spineItems.findIndex((item) => {\n const itemHref = this.normalizeHref(item.href);\n if (!itemHref) return false;\n const itemDecoded = this.decodeHref(itemHref);\n for (const candidate of candidates) {\n if (\n itemHref.endsWith(candidate) ||\n candidate.endsWith(itemHref) ||\n itemDecoded.endsWith(candidate) ||\n candidate.endsWith(itemDecoded)\n ) {\n return true;\n }\n }\n return false;\n });\n }\n\n private normalizeHref(href: string): string {\n if (!href) return \"\";\n return href.split(\"#\")[0];\n }\n\n private decodeHref(href: string): string {\n if (!href) return \"\";\n try {\n return decodeURIComponent(href);\n } catch {\n return href;\n }\n }\n\n private getSectionFromHref(href: string): any | null {\n const normalized = this.normalizeHref(href);\n if (!normalized || !this.book?.spine?.get) return null;\n const decoded = this.decodeHref(normalized);\n const candidates = [normalized, decoded];\n\n for (const candidate of candidates) {\n if (!candidate) continue;\n try {\n const section = this.book.spine.get(candidate);\n if (section) return section;\n } catch {\n // Try next candidate.\n }\n }\n\n return null;\n }\n\n private getSpineItemForPage(pageIndex: number): any | null {\n const spineIndex = this.toSpineIndex(pageIndex);\n if (spineIndex < 0 || spineIndex >= this.spineItems.length) return null;\n return this.spineItems[spineIndex] ?? null;\n }\n\n private getSpineIndexForSection(section: any): number {\n if (!section) return -1;\n\n const sectionIdRef =\n typeof section?.idref === \"string\" ? section.idref.trim() : \"\";\n if (sectionIdRef) {\n const idrefIndex = this.spineItems.findIndex(\n (item) =>\n typeof item?.idref === \"string\" && item.idref.trim() === sectionIdRef\n );\n if (idrefIndex >= 0) return idrefIndex;\n }\n\n const sectionHref =\n typeof section?.href === \"string\" ? this.normalizeHref(section.href) : \"\";\n if (sectionHref) {\n const hrefIndex = this.getSpineIndexByHref(sectionHref);\n if (hrefIndex >= 0) return hrefIndex;\n }\n\n if (typeof section?.index === \"number\" && section.index >= 0) {\n const directItem = this.spineItems[section.index];\n if (directItem) {\n const directHref = this.normalizeHref(directItem?.href ?? \"\");\n const directIdRef =\n typeof directItem?.idref === \"string\" ? directItem.idref.trim() : \"\";\n const hasSameHref = Boolean(sectionHref && directHref === sectionHref);\n const hasSameIdRef = Boolean(\n sectionIdRef && directIdRef && directIdRef === sectionIdRef\n );\n if (hasSameHref || hasSameIdRef) return section.index;\n }\n }\n\n return -1;\n }\n\n private getPageIndexFromSection(section: any): number | null {\n const spineIndex = this.getSpineIndexForSection(section);\n if (spineIndex < 0) return null;\n return this.toPageIndexFromSpine(spineIndex);\n }\n\n private isHrefMatchingSpineItem(href: string, spineItem: any): boolean {\n const normalizedCandidate = this.normalizeHref(href);\n if (!normalizedCandidate) return false;\n const decodedCandidate = this.decodeHref(normalizedCandidate);\n const itemHref = this.normalizeHref(spineItem?.href ?? \"\");\n if (!itemHref) return false;\n const itemDecoded = this.decodeHref(itemHref);\n\n for (const candidate of [normalizedCandidate, decodedCandidate]) {\n if (!candidate) continue;\n if (\n itemHref === candidate ||\n itemDecoded === candidate ||\n itemHref.endsWith(candidate) ||\n candidate.endsWith(itemHref) ||\n itemDecoded.endsWith(candidate) ||\n candidate.endsWith(itemDecoded)\n ) {\n return true;\n }\n }\n\n return false;\n }\n\n private uniqueDisplayTargets(\n targets: Array<string | number>\n ): Array<string | number> {\n const deduped: Array<string | number> = [];\n const seen = new Set<string>();\n for (const target of targets) {\n if (typeof target !== \"string\" && typeof target !== \"number\") continue;\n const normalized =\n typeof target === \"string\" ? target.trim() : String(target).trim();\n if (!normalized) continue;\n const key = `${typeof target}:${normalized}`;\n if (seen.has(key)) continue;\n seen.add(key);\n deduped.push(target);\n }\n return deduped;\n }\n\n private getDisplayTargetsForSpineItem(\n spineItem: any\n ): Array<string | number> {\n const targets: Array<string | number> = [];\n const seen = new Set<string>();\n\n const pushTarget = (value: unknown) => {\n if (typeof value !== \"string\" && typeof value !== \"number\") return;\n const normalized =\n typeof value === \"string\" ? value.trim() : String(value).trim();\n if (!normalized) return;\n const key = `${typeof value}:${normalized}`;\n if (seen.has(key)) return;\n seen.add(key);\n targets.push(value);\n };\n\n pushTarget(spineItem?.href);\n pushTarget(this.decodeHref(spineItem?.href ?? \"\"));\n pushTarget(spineItem?.idref);\n pushTarget(spineItem?.cfiBase);\n if (typeof spineItem?.index === \"number\") pushTarget(spineItem.index);\n\n const sectionFromHref = this.getSectionFromHref(spineItem?.href ?? \"\");\n if (sectionFromHref) {\n pushTarget(sectionFromHref.href);\n pushTarget(sectionFromHref.idref);\n pushTarget(sectionFromHref.cfiBase);\n if (typeof sectionFromHref.index === \"number\")\n pushTarget(sectionFromHref.index);\n }\n\n return targets;\n }\n\n private normalizeDestinationKey(href: string): string {\n if (!href) return \"\";\n const trimmed = href.trim();\n if (!trimmed) return \"\";\n return this.decodeHref(trimmed).toLowerCase();\n }\n\n private findDestinationIndexByHref(href: string): number {\n const candidate = this.normalizeDestinationKey(href);\n if (!candidate || !this.destinationSequence.length) return -1;\n\n const exact = this.destinationSequence.findIndex(\n (entry) => this.normalizeDestinationKey(entry.href) === candidate\n );\n if (exact >= 0) return exact;\n\n return this.destinationSequence.findIndex((entry) => {\n const key = this.normalizeDestinationKey(entry.href);\n return (\n key === candidate || key.endsWith(candidate) || candidate.endsWith(key)\n );\n });\n }\n\n private findNearestDestinationIndexByPage(pageIndex: number): number {\n if (!this.destinationSequence.length) return -1;\n const candidates = this.destinationSequence\n .map((entry, idx) => ({ idx, pageIndex: entry.pageIndex }))\n .filter((entry) => entry.pageIndex <= pageIndex);\n if (candidates.length) return candidates[candidates.length - 1].idx;\n\n const firstNext = this.destinationSequence.findIndex(\n (entry) => entry.pageIndex >= pageIndex\n );\n return firstNext >= 0 ? firstNext : this.destinationSequence.length - 1;\n }\n\n private async ensureDestinationSequence(): Promise<void> {\n if (this.destinationSequence.length) return;\n if (!this.book?.loaded?.navigation) return;\n\n const nav = await this.book.loaded.navigation;\n const toc = nav?.toc ?? [];\n if (!Array.isArray(toc) || !toc.length) return;\n\n const hrefs: string[] = [];\n const walk = (items: any[]) => {\n for (const item of items) {\n const href = typeof item?.href === \"string\" ? item.href.trim() : \"\";\n if (href) hrefs.push(href);\n if (Array.isArray(item?.subitems) && item.subitems.length) {\n walk(item.subitems);\n }\n }\n };\n walk(toc);\n\n if (!hrefs.length) return;\n\n const deduped: string[] = [];\n const seen = new Set<string>();\n for (const href of hrefs) {\n const key = this.normalizeDestinationKey(href);\n if (!key || seen.has(key)) continue;\n seen.add(key);\n deduped.push(href);\n }\n\n const sequence: Array<{ href: string; pageIndex: number }> = [];\n for (const href of deduped) {\n const pageIndex = await this.resolvePageIndexFromHref(href);\n if (pageIndex == null) continue;\n sequence.push({ href, pageIndex });\n }\n\n this.destinationSequence = sequence;\n if (this.destinationCursor < 0 && sequence.length) {\n this.destinationCursor = this.findNearestDestinationIndexByPage(\n this.currentPage - 1\n );\n }\n }\n\n private updateDestinationCursor(\n href: string,\n pageIndex: number | null | undefined\n ): void {\n if (!this.destinationSequence.length) {\n void this.ensureDestinationSequence().then(() => {\n if (!this.destinationSequence.length) return;\n this.updateDestinationCursor(href, pageIndex);\n });\n return;\n }\n\n const byHref = this.findDestinationIndexByHref(href);\n if (byHref >= 0) {\n this.destinationCursor = byHref;\n return;\n }\n\n if (typeof pageIndex === \"number\" && pageIndex >= 0) {\n const byPage = this.findNearestDestinationIndexByPage(pageIndex);\n if (byPage >= 0) this.destinationCursor = byPage;\n }\n }\n\n private getSectionFromTarget(target: string | number): any | null {\n if (!this.book?.spine?.get) return null;\n try {\n const section = this.book.spine.get(target);\n if (section) return section;\n } catch {\n // Try fallback by href parsing.\n }\n\n if (typeof target === \"string\") {\n return this.getSectionFromHref(target);\n }\n return null;\n }\n\n private getPageIndexFromRenditionLocation(rendition: any): number | null {\n const location = rendition?.currentLocation?.();\n if (!location) return null;\n\n const starts = Array.isArray(location)\n ? location.map((entry) => entry?.start).filter(Boolean)\n : [location?.start];\n for (const start of starts) {\n if (!start) continue;\n\n const href =\n typeof start?.href === \"string\" ? this.normalizeHref(start.href) : \"\";\n if (href) {\n const hrefIndex = this.getSpineIndexByHref(href);\n if (hrefIndex >= 0) return this.toPageIndexFromSpine(hrefIndex);\n }\n\n if (typeof start?.index === \"number\" && start.index >= 0) {\n const section = this.getSectionFromTarget(start.index);\n const sectionPageIndex = this.getPageIndexFromSection(section);\n if (sectionPageIndex != null) return sectionPageIndex;\n }\n }\n\n return null;\n }\n\n private isNoSectionError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") return false;\n const message =\n \"message\" in error && typeof (error as any).message === \"string\"\n ? ((error as any).message as string)\n : \"\";\n return message.includes(\"No Section Found\");\n }\n\n private isTransientDisplayError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") return false;\n const message =\n \"message\" in error && typeof (error as any).message === \"string\"\n ? ((error as any).message as string)\n : \"\";\n if (!message) return false;\n const normalized = message.toLowerCase();\n return (\n normalized.includes(\"cannot read properties of undefined\") ||\n normalized.includes(\"cannot read properties of null\") ||\n normalized.includes(\"reading 'package'\") ||\n normalized.includes('reading \"package\"')\n );\n }\n\n private async displayWithFallback(\n rendition: any,\n targets: Array<string | number>,\n isCancelled: () => boolean\n ): Promise<number | null | undefined> {\n for (const target of targets) {\n if (isCancelled()) return null;\n try {\n await rendition.display(target);\n if (isCancelled()) return null;\n const section = this.getSectionFromTarget(target);\n return typeof section?.index === \"number\" ? section.index : null;\n } catch (error) {\n if (\n this.isNoSectionError(error) ||\n this.isTransientDisplayError(error)\n ) {\n continue;\n }\n throw error;\n }\n }\n\n return undefined;\n }\n\n private async displayDestinationWithRetry(\n rendition: any,\n href: string\n ): Promise<boolean> {\n const targets = this.uniqueDisplayTargets([href, this.decodeHref(href)]);\n if (!targets.length) return false;\n const hasAnchor = href.includes(\"#\");\n\n for (let attempt = 0; attempt < 3; attempt += 1) {\n try {\n const firstPass = await this.displayWithFallback(\n rendition,\n targets,\n () => false\n );\n if (firstPass === undefined) {\n this.debugLog(\"displayDestinationWithRetry:first-pass-miss\", {\n href,\n attempt,\n });\n continue;\n }\n\n if (!hasAnchor) return true;\n\n // Anchor destinations can require a second pass in EPUB.js when the\n // first pass stabilizes section context and the second applies hash.\n await new Promise((resolve) => setTimeout(resolve, 0));\n const secondPass = await this.displayWithFallback(\n rendition,\n targets,\n () => false\n );\n if (secondPass !== undefined) return true;\n this.debugLog(\"displayDestinationWithRetry:second-pass-miss\", {\n href,\n attempt,\n });\n } catch {\n // Retry for transient rendition lifecycle races.\n this.debugLog(\"displayDestinationWithRetry:error\", { href, attempt });\n }\n await new Promise((resolve) => setTimeout(resolve, 40 * (attempt + 1)));\n }\n\n return false;\n }\n\n private isDebugEnabled(): boolean {\n try {\n const globalFlag = Boolean((globalThis as any)?.__PAPYRUS_EPUB_DEBUG__);\n if (globalFlag) return true;\n\n const localStorageRef = (globalThis as any)?.localStorage;\n if (!localStorageRef) return false;\n const persisted = localStorageRef.getItem(\"papyrus:epubDebug\");\n return persisted === \"1\" || persisted === \"true\";\n } catch {\n return false;\n }\n }\n\n private debugLog(message: string, payload?: unknown): void {\n if (!this.isDebugEnabled()) return;\n if (payload === undefined) {\n console.log(\"[EPUBEngine]\", message);\n return;\n }\n console.log(\"[EPUBEngine]\", message, payload);\n }\n\n private async syncSectionHeight(\n rendition: any,\n element: HTMLElement,\n pageIndex: number,\n width: number,\n seedHeight: number,\n targetSectionIndex: number | null,\n skipResize = false\n ): Promise<void> {\n if (EPUBEngine.USE_INTERNAL_IFRAME_SCROLL) {\n const fallbackHeight = Math.max(360, Math.ceil(seedHeight));\n element.style.height = `${fallbackHeight}px`;\n this.pageSizes.set(pageIndex, { width, height: fallbackHeight });\n\n if (\n !skipResize &&\n typeof rendition?.resize === \"function\" &&\n (rendition as any).manager?.resize\n ) {\n try {\n rendition.resize(width, fallbackHeight);\n } catch {\n // Ignore resize race for manager lifecycle edge cases.\n }\n }\n return;\n }\n\n const measureElementHeight = (\n elementToMeasure: Element | null | undefined\n ): number => {\n const measuredElement = elementToMeasure as\n | HTMLElement\n | null\n | undefined;\n if (!measuredElement) return 0;\n const rectHeight =\n typeof measuredElement.getBoundingClientRect === \"function\"\n ? measuredElement.getBoundingClientRect().height\n : 0;\n return Math.max(\n measuredElement.scrollHeight ?? 0,\n measuredElement.offsetHeight ?? 0,\n measuredElement.clientHeight ?? 0,\n Number.isFinite(rectHeight) ? rectHeight : 0\n );\n };\n\n const measureDocumentHeight = (\n doc: Document | null | undefined\n ): number => {\n if (!doc) return 0;\n return Math.max(\n measureElementHeight(doc.documentElement),\n measureElementHeight(doc.body)\n );\n };\n\n const measureContentHeight = (strictTarget: boolean): number => {\n let measured = 0;\n const contents =\n typeof rendition?.getContents === \"function\"\n ? rendition.getContents()\n : [];\n\n if (Array.isArray(contents)) {\n for (const content of contents) {\n if (\n strictTarget &&\n targetSectionIndex !== null &&\n typeof content?.sectionIndex === \"number\" &&\n content.sectionIndex !== targetSectionIndex\n ) {\n continue;\n }\n const doc = content?.document;\n if (!doc) continue;\n measured = Math.max(measured, measureDocumentHeight(doc));\n }\n }\n\n if (measured > 0) return measured;\n\n const frameSelector =\n strictTarget && targetSectionIndex !== null\n ? `.epub-view[ref=\"${targetSectionIndex}\"] iframe`\n : \"iframe\";\n const frame = element.querySelector(\n frameSelector\n ) as HTMLIFrameElement | null;\n const fallbackFrame =\n frame ??\n ((strictTarget && targetSectionIndex !== null\n ? element.querySelector(\"iframe\")\n : null) as HTMLIFrameElement | null);\n const selectedFrame = fallbackFrame ?? frame;\n const frameDoc = selectedFrame?.contentDocument;\n if (!frameDoc) return 0;\n return measureDocumentHeight(frameDoc);\n };\n\n let contentHeight = measureContentHeight(true);\n if (contentHeight <= 0 && targetSectionIndex !== null) {\n // Fallback when section index tagging differs from loaded content views.\n contentHeight = measureContentHeight(false);\n }\n if (contentHeight <= 0) {\n await new Promise((resolve) => setTimeout(resolve, 0));\n contentHeight = measureContentHeight(true);\n if (contentHeight <= 0 && targetSectionIndex !== null) {\n contentHeight = measureContentHeight(false);\n }\n }\n\n const measuredTarget =\n contentHeight > 0\n ? Math.ceil(contentHeight + EPUBEngine.HEIGHT_PADDING)\n : Math.ceil(seedHeight);\n const minA4Height = this.getA4MinHeight(width);\n const unclampedTarget = Math.max(minA4Height, measuredTarget);\n const targetHeight = Math.max(\n minA4Height,\n Math.min(EPUBEngine.MAX_SECTION_HEIGHT, unclampedTarget)\n );\n if (targetHeight !== unclampedTarget) {\n this.debugLog(\"syncSectionHeight:clamped\", {\n pageIndex,\n measuredTarget,\n max: EPUBEngine.MAX_SECTION_HEIGHT,\n });\n }\n if (targetHeight <= 0) return;\n\n element.style.height = `${targetHeight}px`;\n this.pageSizes.set(pageIndex, { width, height: targetHeight });\n\n if (\n !skipResize &&\n typeof rendition?.resize === \"function\" &&\n (rendition as any).manager?.resize\n ) {\n try {\n rendition.resize(width, targetHeight);\n } catch {\n // Ignore resize race for manager lifecycle edge cases.\n }\n }\n }\n\n private async resolvePageIndexFromHref(href: string): Promise<number | null> {\n const normalizedHref = href.trim();\n if (!normalizedHref) return null;\n\n const section = this.getSectionFromHref(normalizedHref);\n const sectionPageIndex = this.getPageIndexFromSection(section);\n if (sectionPageIndex != null) return sectionPageIndex;\n\n const spineIndex = this.getSpineIndexByHref(\n this.normalizeHref(normalizedHref)\n );\n return spineIndex >= 0 ? this.toPageIndexFromSpine(spineIndex) : null;\n }\n\n private extractHrefDestination(dest: PageDestination): string | null {\n if (typeof dest === \"string\") return dest;\n if (dest?.kind === \"href\" && typeof dest.value === \"string\") {\n return dest.value;\n }\n return null;\n }\n\n private isUriSource(source: DocumentSource): source is { uri: string } {\n return typeof source === \"object\" && source !== null && \"uri\" in source;\n }\n\n private isDataSource(\n source: DocumentSource\n ): source is { data: ArrayBuffer | Uint8Array } {\n return typeof source === \"object\" && source !== null && \"data\" in source;\n }\n\n private isFileLike(source: DocumentSource): source is FileLike {\n return (\n typeof source === \"object\" &&\n source !== null &&\n typeof (source as FileLike).arrayBuffer === \"function\"\n );\n }\n\n private normalizeLoadInput(input: DocumentLoadInput): {\n source: DocumentSource;\n type?: DocumentType;\n } {\n if (this.isLoadRequest(input)) {\n return { source: input.source, type: input.type };\n }\n return { source: input };\n }\n\n private isLoadRequest(\n input: DocumentLoadInput\n ): input is DocumentLoadRequest {\n return (\n typeof input === \"object\" &&\n input !== null &&\n \"source\" in input &&\n \"type\" in input\n );\n }\n\n private async resolveSource(source: DocumentSource): Promise<any> {\n if (typeof source === \"string\") {\n const dataUri = this.parseDataUri(source);\n if (dataUri) {\n return dataUri.isBase64\n ? this.decodeBase64(dataUri.data)\n : dataUri.data;\n }\n if (this.looksLikeUri(source)) {\n return source;\n }\n if (this.isLikelyBase64(source)) {\n return this.decodeBase64(source);\n }\n return source;\n }\n if (this.isUriSource(source)) return source.uri;\n if (this.isDataSource(source)) return source.data;\n if (this.isFileLike(source)) return await source.arrayBuffer();\n return source;\n }\n\n private parseDataUri(\n value: string\n ): { isBase64: boolean; data: string } | null {\n const match = /^data:([^;,]+)?(;base64)?,(.*)$/.exec(value);\n if (!match) return null;\n const isBase64 = Boolean(match[2]);\n const data = match[3] ?? \"\";\n return { isBase64, data };\n }\n\n private decodeBase64(value: string): Uint8Array {\n const clean = value.replace(/\\s/g, \"\");\n if (typeof atob !== \"function\") {\n throw new Error(\n \"[EPUBEngine] atob não está disponível para decodificar base64.\"\n );\n }\n const binary = atob(clean);\n const len = binary.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i += 1) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n }\n\n private looksLikeUri(value: string): boolean {\n return (\n value.startsWith(\"http://\") ||\n value.startsWith(\"https://\") ||\n value.startsWith(\"/\") ||\n value.startsWith(\"./\") ||\n value.startsWith(\"../\") ||\n value.startsWith(\"file://\")\n );\n }\n\n private isLikelyBase64(value: string): boolean {\n if (this.looksLikeUri(value)) return false;\n if (value.includes(\".\")) return false;\n if (value.length < 16) return false;\n return /^[A-Za-z0-9+/=]+$/.test(value);\n }\n\n private createRendition(\n element: HTMLElement,\n width: number,\n height: number\n ): any {\n const rendition = this.book.renderTo(element, {\n width,\n height,\n flow: \"scrolled-doc\",\n spread: \"none\",\n method: \"write\",\n overflow: EPUBEngine.USE_INTERNAL_IFRAME_SCROLL ? \"auto\" : \"hidden\",\n });\n this.registerContentHook(rendition);\n return rendition;\n }\n\n private disposeReader(): void {\n const rendition = this.readerRendition;\n if (!rendition) return;\n try {\n rendition?.manager?.destroy?.();\n } catch {\n // Ignore teardown failures to keep navigation resilient.\n }\n this.readerRendition = null;\n this.readerTarget = null;\n this.heightSyncVersion += 1;\n }\n\n private registerContentHook(rendition: any): void {\n if (!rendition?.hooks?.content?.register) return;\n rendition.hooks.content.register((contents: any) => {\n try {\n const setImportantStyle = (\n node: HTMLElement | null | undefined,\n property: string,\n value: string\n ) => {\n if (!node) return;\n node.style.setProperty(property, value, \"important\");\n };\n const useInternalScroll = EPUBEngine.USE_INTERNAL_IFRAME_SCROLL;\n const managerContainer = rendition?.manager?.container as\n | HTMLElement\n | undefined;\n const viewsContainer = rendition?.manager?.views?.container as\n | HTMLElement\n | undefined;\n if (managerContainer) {\n managerContainer.classList.add(\"papyrus-epub-scroll-host\");\n managerContainer.style.overflow = useInternalScroll\n ? \"auto\"\n : \"hidden\";\n managerContainer.style.overflowY = useInternalScroll\n ? \"auto\"\n : \"hidden\";\n managerContainer.style.overflowX = \"hidden\";\n managerContainer.style.height = \"100%\";\n managerContainer.style.maxHeight = \"100%\";\n managerContainer.style.scrollbarWidth = useInternalScroll\n ? \"thin\"\n : \"none\";\n managerContainer.style.setProperty(\n \"-webkit-overflow-scrolling\",\n \"touch\"\n );\n managerContainer.style.setProperty(\"overscroll-behavior\", \"contain\");\n }\n if (viewsContainer) {\n viewsContainer.style.overflow = useInternalScroll\n ? \"visible\"\n : \"hidden\";\n viewsContainer.style.overflowY = useInternalScroll\n ? \"visible\"\n : \"hidden\";\n viewsContainer.style.overflowX = \"hidden\";\n viewsContainer.style.minHeight = \"100%\";\n viewsContainer.style.scrollbarWidth = useInternalScroll\n ? \"auto\"\n : \"none\";\n }\n\n const frame = contents?.window\n ?.frameElement as HTMLIFrameElement | null;\n const mobileProbe = (managerContainer ??\n frame ??\n (contents?.document?.body as\n | HTMLElement\n | undefined)) as HTMLElement | null;\n const mobileWidthHint = Math.max(\n managerContainer?.clientWidth ?? 0,\n frame?.clientWidth ?? 0,\n mobileProbe?.clientWidth ?? 0\n );\n const isMobileInternalScroll = Boolean(\n useInternalScroll &&\n mobileProbe &&\n this.isMobileViewport(mobileProbe, mobileWidthHint)\n );\n const contentOverflow = useInternalScroll ? \"hidden\" : \"visible\";\n const doc = contents?.document;\n const root = doc?.documentElement as HTMLElement | undefined;\n const body = doc?.body as HTMLElement | undefined;\n contents?.overflow?.(contentOverflow);\n contents?.overflowX?.(\"hidden\");\n contents?.overflowY?.(contentOverflow);\n contents?.css?.(\"overflow\", contentOverflow, true);\n contents?.css?.(\"overflow-y\", contentOverflow, true);\n contents?.css?.(\"overflow-x\", \"hidden\", true);\n contents?.css?.(\"height\", \"auto\", true);\n contents?.css?.(\"max-height\", \"none\", true);\n contents?.css?.(\"min-height\", \"100%\", true);\n\n if (root) {\n setImportantStyle(root, \"overflow\", contentOverflow);\n setImportantStyle(root, \"overflow-y\", contentOverflow);\n setImportantStyle(root, \"overflow-x\", \"hidden\");\n setImportantStyle(root, \"height\", \"auto\");\n setImportantStyle(root, \"min-height\", \"100%\");\n setImportantStyle(root, \"max-height\", \"none\");\n setImportantStyle(root, \"scrollbar-width\", \"none\");\n setImportantStyle(root, \"overscroll-behavior\", \"none\");\n }\n if (body) {\n setImportantStyle(body, \"overflow\", contentOverflow);\n setImportantStyle(body, \"overflow-y\", contentOverflow);\n setImportantStyle(body, \"overflow-x\", \"hidden\");\n setImportantStyle(body, \"height\", \"auto\");\n setImportantStyle(body, \"min-height\", \"100%\");\n setImportantStyle(body, \"max-height\", \"none\");\n setImportantStyle(body, \"scrollbar-width\", \"none\");\n setImportantStyle(body, \"overscroll-behavior\", \"none\");\n if (isMobileInternalScroll) {\n setImportantStyle(body, \"margin\", \"0\");\n setImportantStyle(body, \"padding\", \"0\");\n }\n }\n\n if (useInternalScroll && managerContainer && doc && root) {\n const proxyMarker = \"data-papyrus-scroll-proxy\";\n if (!root.hasAttribute(proxyMarker)) {\n root.setAttribute(proxyMarker, \"1\");\n const scrollHost = managerContainer;\n\n const onWheel = (event: WheelEvent) => {\n if (event.defaultPrevented) return;\n if (event.ctrlKey || event.metaKey) return;\n const deltaY = Number(event.deltaY) || 0;\n const deltaX = Number(event.deltaX) || 0;\n if (!deltaY && !deltaX) return;\n\n const previousTop = scrollHost.scrollTop;\n const previousLeft = scrollHost.scrollLeft;\n scrollHost.scrollTop += deltaY;\n scrollHost.scrollLeft += deltaX;\n\n const moved =\n scrollHost.scrollTop !== previousTop ||\n scrollHost.scrollLeft !== previousLeft;\n if (moved && event.cancelable) event.preventDefault();\n };\n\n let lastTouchY: number | null = null;\n let lastTouchX: number | null = null;\n\n const onTouchStart = (event: TouchEvent) => {\n if (event.touches.length !== 1) return;\n lastTouchY = event.touches[0].clientY;\n lastTouchX = event.touches[0].clientX;\n };\n\n const onTouchMove = (event: TouchEvent) => {\n if (event.touches.length !== 1) return;\n const touch = event.touches[0];\n if (lastTouchY == null || lastTouchX == null) {\n lastTouchY = touch.clientY;\n lastTouchX = touch.clientX;\n return;\n }\n\n const deltaY = lastTouchY - touch.clientY;\n const deltaX = lastTouchX - touch.clientX;\n\n const previousTop = scrollHost.scrollTop;\n const previousLeft = scrollHost.scrollLeft;\n if (deltaY || deltaX) {\n scrollHost.scrollTop += deltaY;\n scrollHost.scrollLeft += deltaX;\n }\n\n const moved =\n scrollHost.scrollTop !== previousTop ||\n scrollHost.scrollLeft !== previousLeft;\n if (moved && event.cancelable) event.preventDefault();\n\n lastTouchY = touch.clientY;\n lastTouchX = touch.clientX;\n };\n\n const onTouchEnd = () => {\n lastTouchY = null;\n lastTouchX = null;\n };\n\n doc.addEventListener(\"wheel\", onWheel, { passive: false });\n doc.addEventListener(\"touchstart\", onTouchStart, {\n passive: true,\n });\n doc.addEventListener(\"touchmove\", onTouchMove, {\n passive: false,\n });\n doc.addEventListener(\"touchend\", onTouchEnd, { passive: true });\n doc.addEventListener(\"touchcancel\", onTouchEnd, {\n passive: true,\n });\n }\n }\n\n if (isMobileInternalScroll && doc?.body) {\n const singleImage = this.getSingleImageForMobileLayout(doc);\n if (singleImage) {\n doc.body.style.display = \"flex\";\n doc.body.style.justifyContent = \"center\";\n doc.body.style.alignItems = \"flex-start\";\n singleImage.style.width = \"100%\";\n singleImage.style.maxWidth = \"100%\";\n singleImage.style.height = \"auto\";\n singleImage.style.maxHeight = \"100%\";\n singleImage.style.display = \"block\";\n singleImage.style.objectFit = \"contain\";\n }\n }\n if (frame) {\n if (useInternalScroll) {\n frame.setAttribute(\"scrolling\", \"no\");\n setImportantStyle(frame, \"overflow\", \"hidden\");\n setImportantStyle(frame, \"overflow-y\", \"hidden\");\n setImportantStyle(frame, \"overflow-x\", \"hidden\");\n setImportantStyle(frame, \"height\", \"auto\");\n setImportantStyle(frame, \"min-height\", \"100%\");\n setImportantStyle(frame, \"max-height\", \"none\");\n setImportantStyle(frame, \"width\", \"100%\");\n setImportantStyle(frame, \"max-width\", \"100%\");\n setImportantStyle(frame, \"display\", \"block\");\n setImportantStyle(frame, \"border\", \"0\");\n } else {\n frame.setAttribute(\"scrolling\", \"no\");\n setImportantStyle(frame, \"overflow\", \"hidden\");\n setImportantStyle(frame, \"height\", \"auto\");\n }\n }\n } catch {\n // Keep reader functional even if some EPUB content blocks style updates.\n }\n });\n }\n\n private scheduleHeightSync(\n syncVersion: number,\n rendition: any,\n element: HTMLElement,\n pageIndex: number,\n width: number,\n fallbackHeight: number,\n targetSectionIndex: number | null,\n skipResize = false\n ): void {\n const run = () => {\n if (syncVersion !== this.heightSyncVersion) return;\n if (this.readerRendition !== rendition) return;\n if (this.readerTarget !== element) return;\n void this.syncSectionHeight(\n rendition,\n element,\n pageIndex,\n width,\n fallbackHeight,\n targetSectionIndex,\n skipResize\n );\n };\n\n setTimeout(run, 80);\n setTimeout(run, 260);\n setTimeout(run, 620);\n setTimeout(run, 1200);\n }\n\n private getViewportHeightHint(element: HTMLElement): number | null {\n const viewerRoot = element.closest(\".papyrus-viewer\") as HTMLElement | null;\n const hostParent = element.parentElement;\n const measured = Math.max(\n viewerRoot?.clientHeight ?? 0,\n hostParent?.clientHeight ?? 0,\n element.clientHeight ?? 0\n );\n if (measured <= 0) return null;\n\n const viewportWidth = Math.max(\n viewerRoot?.clientWidth ?? 0,\n (globalThis as any)?.visualViewport?.width ?? 0,\n (globalThis as any)?.innerWidth ?? 0\n );\n const isMobileViewport =\n viewportWidth > 0 &&\n viewportWidth <= EPUBEngine.MOBILE_VIEWPORT_MAX_WIDTH_PX;\n if (!isMobileViewport) return null;\n\n let topbarOffset = 0;\n const shell = viewerRoot?.parentElement\n ?.parentElement as HTMLElement | null;\n if (shell) {\n const shellHeight = shell.getBoundingClientRect().height;\n const topbar = Array.from(shell.children).find((child) =>\n (child as HTMLElement).classList?.contains(\"papyrus-topbar\")\n ) as HTMLElement | undefined;\n const topbarHeight = topbar?.getBoundingClientRect().height ?? 0;\n const viewerLikelyIncludesTopbar =\n topbarHeight > 0 && shellHeight > 0 && measured >= shellHeight - 2;\n if (viewerLikelyIncludesTopbar) {\n topbarOffset = Math.ceil(topbarHeight);\n }\n }\n\n const adjusted =\n measured - topbarOffset - EPUBEngine.INTERNAL_VIEWPORT_PADDING_PX;\n return Math.max(280, Math.floor(adjusted));\n }\n\n private getLinearSpineItems(items: any[]): any[] {\n const linearItems = items.filter((item) => item?.linear !== \"no\");\n if (!linearItems.length) return items;\n\n const deduped: any[] = [];\n for (const item of linearItems) {\n const prev = deduped[deduped.length - 1];\n const prevHref = this.normalizeHref(prev?.href ?? \"\");\n const currentHref = this.normalizeHref(item?.href ?? \"\");\n if (prevHref && currentHref && prevHref === currentHref) continue;\n deduped.push(item);\n }\n\n return deduped.length ? deduped : linearItems;\n }\n\n private hasCoverPage(): boolean {\n return Boolean(this.coverUrl);\n }\n\n private isCoverPage(pageIndex: number): boolean {\n return this.hasCoverPage() && pageIndex === 0;\n }\n\n private toSpineIndex(pageIndex: number): number {\n return pageIndex - (this.hasCoverPage() ? 1 : 0);\n }\n\n private toPageIndexFromSpine(spineIndex: number): number {\n return spineIndex + (this.hasCoverPage() ? 1 : 0);\n }\n\n private getA4MinHeight(width: number): number {\n if (!Number.isFinite(width) || width <= 0) return 900;\n return Math.max(480, Math.ceil(width * EPUBEngine.A4_RATIO));\n }\n\n private renderCoverPage(\n element: HTMLElement,\n width: number,\n height: number,\n pageIndex: number\n ): void {\n this.disposeReader();\n element.innerHTML = \"\";\n element.style.width = `${width}px`;\n element.style.height = `${height}px`;\n const isMobileViewport = this.isMobileViewport(element, width);\n const isLandscapeViewport = width > height;\n\n const wrapper = document.createElement(\"div\");\n wrapper.style.width = \"100%\";\n wrapper.style.minHeight = `${height}px`;\n wrapper.style.display = \"flex\";\n wrapper.style.alignItems = \"center\";\n wrapper.style.justifyContent = \"center\";\n wrapper.style.background = \"#fff\";\n wrapper.style.padding = isMobileViewport ? \"0\" : \"16px\";\n wrapper.style.boxSizing = \"border-box\";\n if (isMobileViewport) {\n wrapper.style.overflow = \"hidden\";\n }\n\n const img = document.createElement(\"img\");\n img.src = this.coverUrl ?? \"\";\n img.alt = \"Capa\";\n img.style.maxWidth = \"100%\";\n img.style.maxHeight = \"100%\";\n img.style.width = isMobileViewport ? \"100%\" : \"auto\";\n img.style.height = isMobileViewport ? \"100%\" : \"auto\";\n img.style.display = \"block\";\n img.style.objectFit =\n isMobileViewport && !isLandscapeViewport ? \"cover\" : \"contain\";\n img.style.boxShadow = isMobileViewport\n ? \"none\"\n : \"0 16px 32px rgba(0,0,0,0.15)\";\n img.style.borderRadius = isMobileViewport ? \"0\" : \"8px\";\n\n img.onload = () => {\n if (isMobileViewport) {\n const targetHeight = Math.max(280, Math.floor(height));\n wrapper.style.minHeight = `${targetHeight}px`;\n element.style.height = `${targetHeight}px`;\n this.pageSizes.set(pageIndex, { width, height: targetHeight });\n return;\n }\n\n const naturalWidth = img.naturalWidth || width;\n const naturalHeight = img.naturalHeight || height;\n if (naturalWidth <= 0 || naturalHeight <= 0) return;\n const displayedWidth = Math.min(naturalWidth, Math.max(1, width - 32));\n const scaledHeight = Math.round(\n (naturalHeight / naturalWidth) * displayedWidth\n );\n const targetHeight = Math.max(height, scaledHeight + 32);\n wrapper.style.minHeight = `${targetHeight}px`;\n element.style.height = `${targetHeight}px`;\n this.pageSizes.set(pageIndex, { width, height: targetHeight });\n };\n\n wrapper.appendChild(img);\n element.appendChild(wrapper);\n this.pageSizes.set(pageIndex, { width, height });\n }\n\n private isMobileViewport(element: HTMLElement, widthHint: number): boolean {\n const viewerRoot = element.closest(\".papyrus-viewer\") as HTMLElement | null;\n const viewportWidth = Math.max(\n widthHint,\n viewerRoot?.clientWidth ?? 0,\n (globalThis as any)?.visualViewport?.width ?? 0,\n (globalThis as any)?.innerWidth ?? 0\n );\n const viewportHeight = Math.max(\n viewerRoot?.clientHeight ?? 0,\n (globalThis as any)?.visualViewport?.height ?? 0,\n (globalThis as any)?.innerHeight ?? 0\n );\n const isShortLandscape =\n viewportHeight > 0 &&\n viewportHeight <= EPUBEngine.MOBILE_SHORT_VIEWPORT_MAX_HEIGHT_PX &&\n viewportWidth > viewportHeight;\n return Boolean(\n viewportWidth > 0 &&\n (viewportWidth <= EPUBEngine.MOBILE_VIEWPORT_MAX_WIDTH_PX ||\n isShortLandscape)\n );\n }\n\n private getSingleImageForMobileLayout(\n doc: Document\n ): HTMLImageElement | null {\n const body = doc.body;\n if (!body) return null;\n const images = Array.from(\n body.querySelectorAll(\"img\")\n ) as HTMLImageElement[];\n if (images.length !== 1) return null;\n const textLength = (body.textContent ?? \"\").replace(/\\s+/g, \"\").length;\n if (textLength > 48) return null;\n return images[0] ?? null;\n }\n}\n"],"mappings":"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","names":["ePub","targetHeight"]}
|