@prose-reader/streamer 1.109.0 → 1.111.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/report.ts","../src/generators/resources/hooks/calibreFixHook.ts","../src/generators/resources/hooks/cssFixHook.ts","../src/archives/getArchiveOpfInfo.ts","../src/parsers/nav.ts","../src/parsers/kobo.ts","../src/epub/getSpineItemFilesFromArchive.ts","../src/generators/manifest/hooks/epub.ts","../src/generators/resources/hooks/defaultHook.ts","../src/generators/resources/hooks/selfClosingTagsFixHook.ts","../src/generators/resources/index.ts","../src/generators/manifest/hooks/default.ts","../src/generators/manifest/hooks/comicInfo.ts","../src/generators/manifest/hooks/epubOptimizer.ts","../src/utils/sortByTitleComparator.ts","../src/generators/manifest/hooks/navigationFallback.ts","../src/generators/manifest/index.ts","../src/utils/uri.ts","../src/archives/createArchiveFromUrls.ts","../src/utils/blobToBAse64.ts","../src/archives/createArchiveFromText.ts","../src/archives/createArchiveFromJszip.ts","../src/archives/createArchiveFromLibArchive.ts","../src/archives/createArchiveFromArrayBufferList.ts","../src/configure.ts","../src/archives/archiveLoader.ts","../src/Streamer.ts","../src/ServiceWorkerStreamer.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nlet enabled = false\n\nexport const Report = {\n enable: (enable: boolean) => {\n enabled = enable\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n log: (...data: any[]) => {\n if (enabled) {\n // eslint-disable-next-line no-console\n console.log(`[prose-reader-streamer]`, ...data)\n }\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n warn: (...data: any[]) => {\n if (enabled) {\n // eslint-disable-next-line no-console\n console.warn(`[prose-reader-streamer]`, ...data)\n }\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error: (...data: any[]) => {\n // eslint-disable-next-line no-console\n console.error(...data)\n },\n time: (label?: string | undefined) => {\n if (enabled) {\n // eslint-disable-next-line no-console\n console.time(`[prose-reader-streamer] [metric] ${label}`)\n }\n },\n timeEnd: (label?: string | undefined) => {\n if (enabled) {\n // eslint-disable-next-line no-console\n console.timeEnd(`[prose-reader-streamer] [metric] ${label}`)\n }\n },\n metric: (\n performanceEntry: { name: string; duration: number },\n targetDuration = Infinity,\n ) => {\n const duration =\n typeof performanceEntry === `number`\n ? performanceEntry\n : performanceEntry.duration\n if (enabled) {\n if (performanceEntry.duration <= targetDuration) {\n // eslint-disable-next-line no-console\n console.log(\n `[prose-reader-streamer] [metric] `,\n `${performanceEntry.name} took ${duration}ms`,\n )\n } else {\n // eslint-disable-next-line no-console\n console.warn(\n `[prose-reader-streamer] [metric] `,\n `${performanceEntry.name} took ${performanceEntry.duration}ms which is above the ${targetDuration}ms target for this function`,\n )\n }\n }\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n measurePerformance: <F extends (...args: any[]) => any>(\n name: string,\n targetDuration = 10,\n functionToMeasure: F,\n ) => {\n return (...args: Parameters<F>): ReturnType<F> => {\n const t0 = performance.now()\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const response = functionToMeasure(...(args as any))\n\n if (response && response.then) {\n return response.then((res: any) => {\n const t1 = performance.now()\n Report.metric({ name, duration: t1 - t0 }, targetDuration)\n return res\n })\n }\n\n const t1 = performance.now()\n\n Report.metric({ name, duration: t1 - t0 }, targetDuration)\n\n return response\n }\n },\n}\n","import { XmlDocument } from \"xmldoc\"\nimport { Archive } from \"../../../archives/types\"\nimport { HookResource } from \"./types\"\n\nconst hasCalibreCoverMeta = (doc: XmlDocument) => {\n const metaElm = doc\n .descendantWithPath(\"head\")\n ?.childrenNamed(\"meta\")\n .find((node) => node.attr.name === \"calibre:cover\")\n\n return !!(metaElm && metaElm.attr.name === \"calibre:cover\")\n}\n\nconst getBuggyCoverSvg = (doc: XmlDocument) => {\n return doc\n .descendantWithPath(\"body\")\n ?.descendantWithPath(\"div\")\n ?.childrenNamed(\"svg\")\n ?.find(\n (node) =>\n node.attr.width === \"100%\" && node.attr.preserveAspectRatio === \"none\",\n )\n}\n\nconst fixBuggyCover =\n ({ archive, resourcePath }: { archive: Archive; resourcePath: string }) =>\n async (resource: HookResource): Promise<HookResource> => {\n const file = Object.values(archive.files).find(\n (file) => file.uri === resourcePath,\n )\n\n if (file?.basename.endsWith(`.xhtml`)) {\n const bodyToParse = resource.body ?? (await file.string())\n\n const opfXmlDoc = new XmlDocument(bodyToParse)\n\n if (hasCalibreCoverMeta(opfXmlDoc)) {\n const buggySvg = getBuggyCoverSvg(opfXmlDoc)\n\n if (buggySvg) {\n delete buggySvg.attr.preserveAspectRatio\n }\n\n return {\n ...resource,\n body: opfXmlDoc?.toString(),\n }\n }\n }\n\n return resource\n }\n\nexport const calibreFixHook =\n ({ archive, resourcePath }: { archive: Archive; resourcePath: string }) =>\n async (resource: HookResource): Promise<HookResource> => {\n return fixBuggyCover({ archive, resourcePath })(resource)\n }\n","import { Archive } from \"../../../archives/types\"\nimport { HookResource } from \"./types\"\n\nexport const cssFixHook =\n ({ archive, resourcePath }: { archive: Archive; resourcePath: string }) =>\n async (resource: HookResource): Promise<HookResource> => {\n const file = Object.values(archive.files).find(\n (file) => file.uri === resourcePath,\n )\n\n if (file?.basename.endsWith(`.css`)) {\n const bodyToParse = resource.body ?? (await file.string())\n\n /**\n * Fix the potentially invalid writing mode present on some vertical book.\n * This has the benefit of making it compatible with firefox as well.\n */\n const newBody = bodyToParse.replaceAll(\n `-webkit-writing-mode`,\n `writing-mode`,\n )\n\n return {\n ...resource,\n body: newBody,\n }\n }\n\n return resource\n }\n","import { Archive } from \"./types\"\n\nexport const getArchiveOpfInfo = (archive: Archive) => {\n const filesAsArray = Object.values(archive.files).filter((file) => !file.dir)\n const file = filesAsArray.find((file) => file.uri.endsWith(`.opf`))\n\n return {\n data: file,\n basePath: file?.uri.substring(0, file.uri.lastIndexOf(`/`)) || ``,\n }\n}\n","import xmldoc, { XmlElement } from \"xmldoc\"\nimport type { Manifest } from \"@prose-reader/shared\"\nimport { Archive, getArchiveOpfInfo } from \"..\"\nimport { urlJoin } from \"@prose-reader/shared\"\n\ntype Toc = NonNullable<Manifest[`nav`]>[`toc`]\ntype TocItem = NonNullable<Manifest[`nav`]>[`toc`][number]\n\nconst extractNavChapter = (\n li: XmlElement,\n { opfBasePath, baseUrl }: { opfBasePath: string; baseUrl: string },\n) => {\n const chp: TocItem = {\n contents: [],\n path: ``,\n href: ``,\n title: ``,\n }\n let contentNode = li.childNamed(`span`) || li.childNamed(`a`)\n chp.title = contentNode?.attr.title || contentNode?.val.trim() || chp.title\n let node = contentNode?.name\n if (node !== `a`) {\n contentNode = li.descendantWithPath(`${node}.a`)\n if (contentNode) {\n node = contentNode.name.toLowerCase()\n }\n }\n if (node === `a` && contentNode?.attr.href) {\n chp.path = urlJoin(opfBasePath, contentNode.attr.href)\n chp.href = urlJoin(baseUrl, opfBasePath, contentNode.attr.href)\n }\n const sublistNode = li.childNamed(`ol`)\n if (sublistNode) {\n const children = sublistNode.childrenNamed(`li`)\n if (children && children.length > 0) {\n chp.contents = children.map((child) =>\n extractNavChapter(child, { opfBasePath, baseUrl }),\n )\n }\n }\n\n return chp\n}\n\nconst buildTOCFromNav = (\n doc: xmldoc.XmlDocument,\n { opfBasePath, baseUrl }: { opfBasePath: string; baseUrl: string },\n) => {\n const toc: Toc = []\n\n let navDataChildren\n if (doc.descendantWithPath(`body.nav.ol`)) {\n navDataChildren = doc.descendantWithPath(`body.nav.ol`)?.children\n } else if (doc.descendantWithPath(`body.section.nav.ol`)) {\n navDataChildren = doc.descendantWithPath(`body.section.nav.ol`)?.children\n }\n\n if (navDataChildren && navDataChildren.length > 0) {\n navDataChildren\n .filter((li) => (li as XmlElement).name === `li`)\n .forEach((li) =>\n toc.push(extractNavChapter(li as XmlElement, { opfBasePath, baseUrl })),\n )\n }\n\n return toc\n}\n\nconst parseTocFromNavPath = async (\n opfXmlDoc: xmldoc.XmlDocument,\n archive: Archive,\n { opfBasePath, baseUrl }: { opfBasePath: string; baseUrl: string },\n) => {\n // Try to detect if there is a nav item\n const navItem = opfXmlDoc\n .childNamed(`manifest`)\n ?.childrenNamed(`item`)\n .find((child) => child.attr.properties === `nav`)\n\n if (navItem) {\n const tocFile = Object.values(archive.files).find((item) =>\n item.uri.endsWith(navItem.attr.href || ``),\n )\n if (tocFile) {\n const doc = new xmldoc.XmlDocument(await tocFile.string())\n return buildTOCFromNav(doc, { opfBasePath, baseUrl })\n }\n }\n}\n\nconst mapNcxChapter = (\n point: xmldoc.XmlElement,\n {\n opfBasePath,\n baseUrl,\n prefix,\n }: { opfBasePath: string; baseUrl: string; prefix: string },\n) => {\n const src = point?.childNamed(`${prefix}content`)?.attr.src || ``\n\n const out: TocItem = {\n title:\n point?.descendantWithPath(`${prefix}navLabel.${prefix}text`)?.val || ``,\n path: urlJoin(opfBasePath, src),\n href: urlJoin(baseUrl, opfBasePath, src),\n contents: [],\n }\n const children = point.childrenNamed(`${prefix}navPoint`)\n if (children && children.length > 0) {\n out.contents = children.map((pt) =>\n mapNcxChapter(pt, { opfBasePath, baseUrl, prefix }),\n )\n }\n\n return out\n}\n\nconst buildTOCFromNCX = (\n ncxData: xmldoc.XmlDocument,\n { opfBasePath, baseUrl }: { opfBasePath: string; baseUrl: string },\n) => {\n const toc: NonNullable<Manifest[`nav`]>[`toc`] = []\n\n const rootTagName = ncxData.name\n let prefix = ``\n if (rootTagName.indexOf(`:`) !== -1) {\n prefix = rootTagName.split(`:`)[0] + `:`\n }\n\n ncxData\n .childNamed(`${prefix}navMap`)\n ?.childrenNamed(`${prefix}navPoint`)\n .forEach((point) =>\n toc.push(mapNcxChapter(point, { opfBasePath, baseUrl, prefix })),\n )\n\n return toc\n}\n\nconst parseTocFromNcx = async ({\n opfData,\n opfBasePath,\n baseUrl,\n archive,\n}: {\n opfData: xmldoc.XmlDocument\n opfBasePath: string\n archive: Archive\n baseUrl: string\n}) => {\n const spine = opfData.childNamed(`spine`)\n const ncxId = spine && spine.attr.toc\n\n if (ncxId) {\n const ncxItem = opfData\n .childNamed(`manifest`)\n ?.childrenNamed(`item`)\n .find((item) => item.attr.id === ncxId)\n\n if (ncxItem) {\n const ncxPath = `${opfBasePath}${opfBasePath === `` ? `` : `/`}${ncxItem.attr.href}`\n\n const file = Object.values(archive.files).find((item) =>\n item.uri.endsWith(ncxPath),\n )\n\n if (file) {\n const ncxData = new xmldoc.XmlDocument(await file.string())\n\n return buildTOCFromNCX(ncxData, { opfBasePath, baseUrl })\n }\n }\n }\n}\n\nexport const parseToc = async (\n opfXmlDoc: xmldoc.XmlDocument,\n archive: Archive,\n { baseUrl }: { baseUrl: string },\n) => {\n const { basePath: opfBasePath } = getArchiveOpfInfo(archive) || {}\n\n const tocFromNcx = await parseTocFromNcx({\n opfData: opfXmlDoc,\n opfBasePath,\n archive,\n baseUrl,\n })\n\n if (tocFromNcx) {\n return tocFromNcx\n }\n\n return await parseTocFromNavPath(opfXmlDoc, archive, { opfBasePath, baseUrl })\n}\n","import xmldoc from \"xmldoc\"\nimport { Archive } from \"..\"\n\ntype KoboInformation = {\n renditionLayout?: `reflowable` | `pre-paginated` | undefined\n}\n\nexport const extractKoboInformationFromArchive = async (archive: Archive) => {\n const koboInformation: KoboInformation = {\n renditionLayout: undefined,\n }\n\n await Promise.all(\n archive.files.map(async (file) => {\n if (file.uri.endsWith(`com.kobobooks.display-options.xml`)) {\n const opfXmlDoc = new xmldoc.XmlDocument(await file.string())\n const optionElement = opfXmlDoc\n .childNamed(`platform`)\n ?.childNamed(`option`)\n if (\n optionElement?.attr?.name === `fixed-layout` &&\n optionElement.val === `true`\n ) {\n koboInformation.renditionLayout = `pre-paginated`\n }\n }\n }),\n )\n\n return koboInformation\n}\n","import xmldoc from \"xmldoc\"\nimport { getArchiveOpfInfo } from \"../archives/getArchiveOpfInfo\"\nimport { Archive } from \"../archives/types\"\n\nexport const getSpineItemFilesFromArchive = async ({\n archive,\n}: {\n archive: Archive\n}) => {\n const { data: opsFile, basePath: opfBasePath } =\n getArchiveOpfInfo(archive) || {}\n\n const data = await opsFile?.string()\n\n if (!data) return []\n\n const _opfXmlDoc = new xmldoc.XmlDocument(data)\n\n const manifestElm = _opfXmlDoc.childNamed(`manifest`)\n const spineElm = _opfXmlDoc.childNamed(`spine`)\n\n const spineItemIds = spineElm\n ?.childrenNamed(`itemref`)\n .map((item) => item.attr.idref) as string[]\n const manifestItemsFromSpine =\n manifestElm\n ?.childrenNamed(`item`)\n .filter((item) => spineItemIds.includes(item.attr.id || ``)) || []\n\n const archiveSpineItems = archive.files.filter((file) => {\n return manifestItemsFromSpine.find((item) => {\n if (!opfBasePath) return `${item.attr.href}` === file.uri\n return `${opfBasePath}/${item.attr.href}` === file.uri\n })\n })\n\n return archiveSpineItems\n}\n","import xmldoc from \"xmldoc\"\nimport { parseToc } from \"../../../parsers/nav\"\nimport type { Manifest } from \"@prose-reader/shared\"\nimport { extractKoboInformationFromArchive } from \"../../../parsers/kobo\"\nimport { Report } from \"../../../report\"\nimport { Archive } from \"../../../archives/types\"\nimport { getArchiveOpfInfo } from \"../../../archives/getArchiveOpfInfo\"\nimport { getSpineItemFilesFromArchive } from \"../../../epub/getSpineItemFilesFromArchive\"\n\ntype SpineItemProperties =\n | `rendition:layout-reflowable`\n | `page-spread-left`\n | `page-spread-right`\n\nexport const getItemsFromDoc = (doc: xmldoc.XmlDocument) => {\n const manifestElm = doc.childNamed(`manifest`)\n\n return (\n manifestElm?.childrenNamed(`item`)?.map((el) => ({\n href: el.attr.href || ``,\n id: el.attr.id || ``,\n mediaType: el.attr[`media-type`],\n })) || []\n )\n}\n\nexport const epubHook =\n ({ archive, baseUrl }: { archive: Archive; baseUrl: string }) =>\n async (manifest: Manifest): Promise<Manifest> => {\n const { data: opsFile, basePath: opfBasePath } =\n getArchiveOpfInfo(archive) || {}\n const koboInformation = await extractKoboInformationFromArchive(archive)\n\n if (!opsFile) {\n return manifest\n }\n\n const data = await opsFile.string()\n\n Report.log(data, koboInformation)\n\n const opfXmlDoc = new xmldoc.XmlDocument(data)\n\n const toc = (await parseToc(opfXmlDoc, archive, { baseUrl })) || []\n\n const metadataElm = opfXmlDoc.childNamed(`metadata`)\n const manifestElm = opfXmlDoc.childNamed(`manifest`)\n const spineElm = opfXmlDoc.childNamed(`spine`)\n const guideElm = opfXmlDoc.childNamed(`guide`)\n const titleElm = metadataElm?.childNamed(`dc:title`)\n const metaElmChildren = metadataElm?.childrenNamed(`meta`) || []\n const metaElmWithRendition = metaElmChildren.find(\n (meta) => meta.attr.property === `rendition:layout`,\n )\n const metaElmWithRenditionFlow = metaElmChildren.find(\n (meta) => meta.attr.property === `rendition:flow`,\n )\n const metaElmWithRenditionSpread = metaElmChildren.find(\n (meta) => meta.attr.property === `rendition:spread`,\n )\n\n const publisherRenditionLayout = metaElmWithRendition?.val as\n | `reflowable`\n | `pre-paginated`\n | undefined\n const publisherRenditionFlow = metaElmWithRenditionFlow?.val as\n | `scrolled-continuous`\n | `scrolled-doc`\n | `paginated`\n | `auto`\n | undefined\n const renditionSpread = metaElmWithRenditionSpread?.val as\n | `auto`\n | undefined\n\n const title =\n titleElm?.val || archive.files.find(({ dir }) => dir)?.basename || ``\n const pageProgressionDirection = spineElm?.attr[\n `page-progression-direction`\n ] as `ltr` | `rtl` | undefined\n\n const archiveSpineItems = await getSpineItemFilesFromArchive({ archive })\n\n const totalSize = archiveSpineItems.reduce(\n (size, file) => file.size + size,\n 0,\n )\n\n return {\n filename: archive.filename,\n nav: {\n toc,\n },\n renditionLayout:\n publisherRenditionLayout ||\n koboInformation.renditionLayout ||\n `reflowable`,\n renditionFlow: publisherRenditionFlow || `auto`,\n renditionSpread,\n title,\n readingDirection: pageProgressionDirection || `ltr`,\n spineItems:\n spineElm?.childrenNamed(`itemref`).map((itemrefElm) => {\n const manifestItem = manifestElm\n ?.childrenNamed(`item`)\n .find((item) => item.attr.id === itemrefElm?.attr.idref)\n const href = manifestItem?.attr.href || ``\n const properties = (itemrefElm?.attr.properties?.split(` `) ||\n []) as SpineItemProperties[]\n const itemSize =\n archive.files.find((file) => file.uri.endsWith(href))?.size || 0\n\n // we use base url or nothing (and stay relative)\n const hrefBaseUri = baseUrl ?? \"\"\n\n return {\n id: manifestItem?.attr.id || ``,\n href: manifestItem?.attr.href?.startsWith(`https://`)\n ? manifestItem?.attr.href\n : opfBasePath\n ? `${hrefBaseUri}${opfBasePath}/${manifestItem?.attr.href}`\n : `${hrefBaseUri}${manifestItem?.attr.href}`,\n renditionLayout: publisherRenditionLayout || `reflowable`,\n ...(properties.find(\n (property) => property === `rendition:layout-reflowable`,\n ) && {\n renditionLayout: `reflowable`,\n }),\n progressionWeight: itemSize / totalSize,\n pageSpreadLeft:\n properties.some((property) => property === `page-spread-left`) ||\n undefined,\n pageSpreadRight:\n properties.some((property) => property === `page-spread-right`) ||\n undefined,\n // size: itemSize\n mediaType: manifestItem?.attr[`media-type`],\n }\n }) || [],\n items: getItemsFromDoc(opfXmlDoc),\n guide: guideElm?.childrenNamed(`reference`).map((elm) => {\n return {\n href: elm.attr.href || ``,\n title: elm.attr.title || ``,\n type: elm.attr.type as NonNullable<Manifest[`guide`]>[number][`type`],\n }\n }),\n }\n }\n","import { getArchiveOpfInfo } from \"../../../archives/getArchiveOpfInfo\"\nimport { Archive } from \"../../../archives/types\"\nimport { getItemsFromDoc } from \"../../manifest/hooks/epub\"\nimport xmldoc from \"xmldoc\"\nimport { HookResource } from \"./types\"\n\nconst getMetadata = async (archive: Archive, resourcePath: string) => {\n const opfInfo = getArchiveOpfInfo(archive)\n const data = await opfInfo.data?.string()\n\n if (data) {\n const opfXmlDoc = new xmldoc.XmlDocument(data)\n const items = getItemsFromDoc(opfXmlDoc)\n\n return {\n mediaType: items.find((item) => resourcePath.endsWith(item.href))\n ?.mediaType,\n }\n }\n\n return {\n mediaType: getContentTypeFromExtension(resourcePath),\n }\n}\n\nconst getContentTypeFromExtension = (uri: string) => {\n if (uri.endsWith(`.css`)) {\n return `text/css; charset=UTF-8`\n }\n if (uri.endsWith(`.jpg`)) {\n return `image/jpg`\n }\n if (uri.endsWith(`.xhtml`)) {\n return `application/xhtml+xml`\n }\n if (uri.endsWith(`.mp4`)) {\n return `video/mp4`\n }\n if (uri.endsWith(`.svg`)) {\n return `image/svg+xml`\n }\n}\n\nexport const defaultHook =\n ({ archive, resourcePath }: { archive: Archive; resourcePath: string }) =>\n async (resource: HookResource): Promise<HookResource> => {\n const file = Object.values(archive.files).find(\n (file) => file.uri === resourcePath,\n )\n\n if (!file) return resource\n\n // if (file.stream) {\n // const stream = file.stream()\n\n // console.log(file, stream)\n // stream.on(`data`, data => {\n // console.log(`data`, data)\n // })\n // stream.on(`error`, data => {\n // console.error(`error`, data)\n // })\n // stream.on(`end`, () => {\n // console.log(`end`)\n // })\n\n // }\n\n // const stream = file.stream!()\n\n // const readableStream = new ReadableStream({\n // start(controller) {\n // function push() {\n // stream.on(`data`, data => {\n // controller.enqueue(data)\n // })\n // stream.on(`error`, data => {\n // console.error(`error`, data)\n // })\n // stream.on(`end`, () => {\n // controller.close()\n // })\n\n // stream.resume()\n // }\n\n // push();\n // }\n // })\n\n const metadata = await getMetadata(archive, resourcePath)\n\n return {\n ...resource,\n params: {\n ...resource.params,\n ...(file?.encodingFormat && {\n contentType: file.encodingFormat,\n }),\n ...(metadata.mediaType && {\n contentType: metadata.mediaType,\n }),\n },\n }\n }\n","import { Archive } from \"../../../archives/types\"\nimport { HookResource } from \"./types\"\n\nconst invalidSelfClosingTags = [\n \"div\",\n \"span\",\n \"p\",\n \"a\",\n \"li\",\n \"ul\",\n \"ol\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"table\",\n \"tr\",\n \"td\",\n \"th\",\n \"thead\",\n \"tbody\",\n \"tfoot\",\n \"section\",\n \"article\",\n \"header\",\n \"footer\",\n \"nav\",\n \"aside\",\n \"main\",\n \"figure\",\n \"figcaption\",\n \"blockquote\",\n \"pre\",\n \"code\",\n \"form\",\n \"textarea\",\n \"select\",\n \"option\",\n \"button\",\n \"label\",\n \"fieldset\",\n \"legend\",\n \"caption\",\n \"dl\",\n \"dt\",\n \"dd\",\n \"iframe\",\n \"video\",\n \"audio\",\n \"canvas\",\n \"script\",\n \"style\",\n]\n\n/**\n * Some books uses xhtml files but also includes wrong self closin tags. This happens\n * a lot with kobo epub which have a lot of self closing <script ... />. This breaks on some\n * browser such as webkit. We use a regex to replace and fix them. There\n * is a first lighter regex which check if any such tag exist in the first place before running\n * the full replace regex empty.\n */\nexport const selfClosingTagsFixHook =\n ({ archive, resourcePath }: { archive: Archive; resourcePath: string }) =>\n async (resource: HookResource): Promise<HookResource> => {\n const file = Object.values(archive.files).find(\n (file) => file.uri === resourcePath,\n )\n\n if (file?.basename.endsWith(`.xhtml`)) {\n const bodyToParse = resource.body ?? (await file.string())\n\n const tagCheckPattern = new RegExp(\n `<(${invalidSelfClosingTags.join(\"|\")})[\\\\s/>]`,\n \"i\",\n )\n if (!tagCheckPattern.test(bodyToParse)) {\n return resource\n }\n\n const tagPattern = new RegExp(\n `<(${invalidSelfClosingTags.join(\"|\")})(\\\\s[^>]*)?\\\\s*/>`,\n \"gi\",\n )\n\n const fixedBody = bodyToParse.replace(\n tagPattern,\n (match, tagName, attributes = \"\") => {\n // Convert to an opening and closing tag\n return `<${tagName} ${attributes.trim()}></${tagName}>`\n },\n )\n\n return {\n ...resource,\n body: fixedBody,\n }\n }\n\n return resource\n }\n","import { Archive } from \"../..\"\nimport { Report } from \"../../report\"\nimport { calibreFixHook } from \"./hooks/calibreFixHook\"\nimport { cssFixHook } from \"./hooks/cssFixHook\"\nimport { defaultHook } from \"./hooks/defaultHook\"\nimport { HookResource } from \"./hooks/types\"\nimport { selfClosingTagsFixHook } from \"./hooks/selfClosingTagsFixHook\"\n\nexport const generateResourceFromArchive = async (\n archive: Archive,\n resourcePath: string,\n) => {\n const file = Object.values(archive.files).find(\n (file) => file.uri === resourcePath,\n )\n\n if (!file) {\n throw new Error(`no file found`)\n }\n\n const defaultResource: HookResource = {\n params: {},\n }\n\n const hooks = [\n defaultHook({ archive, resourcePath }),\n selfClosingTagsFixHook({ archive, resourcePath }),\n cssFixHook({ archive, resourcePath }),\n calibreFixHook({ archive, resourcePath }),\n ]\n\n try {\n const resource = await hooks.reduce(async (manifest, gen) => {\n return await gen(await manifest)\n }, Promise.resolve(defaultResource))\n\n Report.log(\"Generated resource\", resourcePath, resource)\n\n return {\n ...resource,\n body: resource.body ?? (await file.blob()),\n }\n } catch (e) {\n Report.error(e)\n\n throw e\n }\n}\n","import { Manifest } from \"@prose-reader/shared\"\nimport { Archive } from \"../../../archives/types\"\n\nexport const defaultHook =\n ({ archive, baseUrl }: { archive: Archive; baseUrl: string }) =>\n async (): Promise<Manifest> => {\n const files = Object.values(archive.files).filter((file) => !file.dir)\n\n return {\n filename: archive.filename,\n title:\n archive.files.find(({ dir }) => dir)?.basename.replace(/\\/$/, ``) || ``,\n renditionLayout: `pre-paginated`,\n renditionSpread: `auto`,\n readingDirection: `ltr`,\n spineItems: files\n .filter((file) => !file.basename.endsWith(`.db`))\n .map((file, index) => ({\n // some books such as cbz can have same basename inside different sub folder\n // we need to make sure to have unique index\n // /chap01/01.png, /chap02/01.png, etc\n id: `${index}.${file.basename}`,\n href: encodeURI(`${baseUrl}${file.uri}`),\n renditionLayout: `pre-paginated`,\n progressionWeight: 1 / files.length,\n pageSpreadLeft: undefined,\n pageSpreadRight: undefined,\n mediaType: file.encodingFormat,\n })),\n items: files.map((file, index) => ({\n id: `${index}.${file.basename}`,\n href: `${baseUrl}${file.uri}`,\n })),\n }\n }\n","import { Manifest } from \"@prose-reader/shared\"\nimport xmldoc from \"xmldoc\"\nimport { Archive } from \"../../../archives/types\"\n\n/**\n * Handle archive which contains ComicInfo.xml. This is a meta file\n * used to define cbz, etc. I believe it comes from some sites or apps.\n */\nexport const comicInfoHook =\n ({ archive }: { archive: Archive; baseUrl: string }) =>\n async (manifest: Manifest): Promise<Manifest> => {\n const comicInfoFile = archive.files.find(\n (file) => file.basename.toLowerCase() === `comicinfo.xml`,\n )\n\n if (!comicInfoFile) {\n return manifest\n }\n\n const manifestWithoutComicInfo = {\n ...manifest,\n spineItems: manifest.spineItems\n .filter((item) => !item.id.toLowerCase().endsWith(`comicinfo.xml`))\n .map((item, _, items) => ({\n ...item,\n progressionWeight: 1 / items.length,\n })),\n }\n\n // @todo handle more meta\n const content = await comicInfoFile.string()\n\n try {\n const xmlDoc = new xmldoc.XmlDocument(content)\n\n const mangaVal =\n (xmlDoc.childNamed(`Manga`)?.val as `YesAndRightToLeft`) || `unknown`\n\n return {\n ...manifestWithoutComicInfo,\n readingDirection: mangaVal === `YesAndRightToLeft` ? `rtl` : `ltr`,\n }\n } catch (e) {\n console.error(\"Unable to parse comicinfo.xml for content\\n\", content)\n console.error(e)\n\n return manifestWithoutComicInfo\n }\n }\n","import { isXmlBasedMimeType, Manifest } from \"@prose-reader/shared\"\nimport xmldoc from \"xmldoc\"\nimport { Archive } from \"../../../archives/types\"\nimport { getSpineItemFilesFromArchive } from \"../../../epub/getSpineItemFilesFromArchive\"\n\nconst hasDocMetaViewport = (doc: xmldoc.XmlDocument) => {\n const metaElm = doc\n .descendantWithPath(\"head\")\n ?.childrenNamed(\"meta\")\n .find((node) => node.attr.name === \"viewport\")\n\n return !!(metaElm && metaElm.attr.name === \"viewport\")\n}\n\nconst allFilesHaveViewportMeta = (files: Archive[\"files\"]) =>\n files.reduce(async (result, current) => {\n const _result = await result\n\n if (!_result) return false\n\n if (\n !isXmlBasedMimeType({\n mimeType: current.encodingFormat,\n uri: current.uri,\n })\n ) {\n return false\n }\n\n const file = await current.string()\n\n if (!file) return false\n\n return hasDocMetaViewport(new xmldoc.XmlDocument(file))\n }, Promise.resolve(true))\n\nexport const epubOptimizerHook =\n ({ archive }: { archive: Archive; baseUrl: string }) =>\n async (manifest: Manifest): Promise<Manifest> => {\n const bookIsFullReflowable =\n manifest.renditionLayout === \"reflowable\" &&\n manifest.spineItems.every((item) => item.renditionLayout === \"reflowable\")\n\n if (bookIsFullReflowable) {\n const files = await getSpineItemFilesFromArchive({ archive })\n\n const hasAllViewport = await allFilesHaveViewportMeta(files)\n\n if (hasAllViewport) {\n return {\n ...manifest,\n spineItems: manifest.spineItems.map((item) => ({\n ...item,\n renditionLayout: \"pre-paginated\",\n })),\n renditionLayout: \"pre-paginated\",\n }\n }\n }\n\n return manifest\n }\n","export const sortByTitleComparator = (a: string, b: string) => {\n const alist = a.split(/(\\d+)/)\n const blist = b.split(/(\\d+)/)\n\n for (let i = 0, len = alist.length; i < len; i++) {\n if (alist[i] !== blist[i]) {\n if (alist[i]?.match(/\\d/)) {\n return +(alist[i] || ``) - +(blist[i] || ``)\n } else {\n return (alist[i] || ``).localeCompare(blist[i] || ``)\n }\n }\n }\n\n return 1\n}\n","import { Manifest, urlJoin } from \"@prose-reader/shared\"\nimport { Archive } from \"../../../archives/types\"\nimport { sortByTitleComparator } from \"../../../utils/sortByTitleComparator\"\n\n/**\n * In case no navigation was generated prior to this hook, we will try\n * to generate something based on the structure of the archive.\n *\n * We use folders as chapters.\n */\nexport const navigationFallbackHook =\n ({ archive, baseUrl }: { archive: Archive; baseUrl: string }) =>\n async (manifest: Manifest): Promise<Manifest> => {\n if (manifest.nav) return manifest\n\n const filesSortedByAlpha = [...archive.files].sort((a, b) =>\n sortByTitleComparator(a.uri, b.uri),\n )\n\n const toc: NonNullable<Manifest[\"nav\"]>[\"toc\"] = Object.values(\n filesSortedByAlpha,\n ).reduce(\n (acc, file) => {\n const parts = file.uri.split(\"/\")\n\n // we have a file that is\n const isFileUnderFolder = !file.dir && parts.length > 1\n\n if (isFileUnderFolder) {\n parts.forEach((part, level) => {\n const partIsFileName = level === parts.length - 1\n\n if (partIsFileName) return\n\n const existingTocItem = acc.find(({ title }) => title === part)\n\n if (existingTocItem) {\n // @todo\n } else {\n acc.push({\n contents: [],\n href: urlJoin(baseUrl, encodeURI(file.uri)).replace(/\\/$/, \"\"),\n path: file.uri.replace(/\\/$/, \"\"),\n title: parts[0] ?? \"\",\n })\n }\n })\n }\n\n return acc\n },\n [] as NonNullable<Manifest[\"nav\"]>[\"toc\"],\n )\n\n if (toc.length === 0) return manifest\n\n return {\n ...manifest,\n nav: {\n toc,\n },\n }\n }\n","import type { Manifest } from \"@prose-reader/shared\"\nimport { Report } from \"../../report\"\nimport { Archive } from \"../../archives/types\"\nimport { defaultHook } from \"./hooks/default\"\nimport { epubHook } from \"./hooks/epub\"\nimport { comicInfoHook } from \"./hooks/comicInfo\"\nimport { epubOptimizerHook } from \"./hooks/epubOptimizer\"\nimport { navigationFallbackHook } from \"./hooks/navigationFallback\"\n\nconst baseManifest: Manifest = {\n filename: ``,\n items: [],\n nav: {\n toc: [],\n },\n readingDirection: `ltr`,\n renditionLayout: `pre-paginated`,\n renditionSpread: `auto`,\n spineItems: [],\n title: ``,\n}\n\nexport const generateManifestFromArchive = async (\n archive: Archive,\n { baseUrl = `` }: { baseUrl?: string } = {},\n) => {\n const hooks = [\n defaultHook({ archive, baseUrl }),\n epubHook({ archive, baseUrl }),\n epubOptimizerHook({ archive, baseUrl }),\n comicInfoHook({ archive, baseUrl }),\n navigationFallbackHook({ archive, baseUrl }),\n ]\n\n try {\n const manifest = await hooks.reduce(async (manifest, gen) => {\n return await gen(await manifest)\n }, Promise.resolve(baseManifest))\n\n Report.log(\"Generated manifest\", manifest)\n\n return manifest\n } catch (e) {\n Report.error(e)\n\n throw e\n }\n}\n","export const getUriBasename = (uri: string) =>\n uri.substring(uri.lastIndexOf(`/`) + 1) || uri\n\nexport const removeTrailingSlash = (uri: string) =>\n uri.endsWith(\"/\") ? uri.slice(0, -1) : uri\n","import { detectMimeTypeFromName } from \"@prose-reader/shared\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { Archive } from \"./types\"\n\n/**\n * @important\n * Make sure the urls are on the same origin or the cors header is set otherwise\n * the resource cannot be consumed as it is on the web.\n */\nexport const createArchiveFromUrls = async (\n urls: string[],\n options?: { useRenditionFlow: boolean },\n): Promise<Archive> => {\n const opfFileData = `\n <?xml version=\"1.0\" encoding=\"UTF-8\"?><package xmlns=\"http://www.idpf.org/2007/opf\" version=\"2.0\" unique-identifier=\"bookid\">\n <metadata>\n <meta property=\"rendition:layout\">${options?.useRenditionFlow ? `reflowable` : `pre-paginated`}</meta>\n ${options?.useRenditionFlow ? `<meta property=\"rendition:flow\">scrolled-continuous</meta>` : ``}\n </metadata>\n <manifest>\n ${urls\n .map(\n (url) =>\n `<item id=\"${getUriBasename(url)}\" href=\"${url}\" media-type=\"${detectMimeTypeFromName(url)}\"/>`,\n )\n .join(`\\n`)}\n </manifest>\n <spine>\n ${urls.map((url) => `<itemref idref=\"${getUriBasename(url)}\" />`).join(`\\n`)}\n </spine>\n </package>\n `\n\n const filesFromUrl: Archive[`files`] = urls.map((url) => ({\n dir: false,\n basename: getUriBasename(url),\n encodingFormat: detectMimeTypeFromName(url),\n uri: url,\n size: 100 / urls.length,\n base64: async () => ``,\n blob: async () => new Blob(),\n string: async () => ``,\n }))\n\n const opfFile: Archive[`files`][number] = {\n dir: false,\n basename: `content.opf`,\n uri: `content.opf`,\n size: 0,\n base64: async () => opfFileData,\n blob: async () => new Blob(),\n string: async () => opfFileData,\n }\n\n return {\n filename: ``,\n files: [opfFile, ...filesFromUrl],\n close: () => Promise.resolve(),\n }\n}\n","export const blobToBase64 = async (blob: Blob) =>\n new Promise<string>((resolve) => {\n const reader = new FileReader()\n reader.readAsDataURL(blob)\n reader.onloadend = function () {\n const base64data = reader.result as string\n resolve(base64data)\n }\n })\n","import { blobToBase64 } from \"../utils/blobToBAse64\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { Archive } from \"./types\"\n\n/**\n * Useful to create archive from txt content\n */\nexport const createArchiveFromText = async (\n content: string | Blob,\n {\n mimeType,\n direction,\n }: {\n direction?: `ltr` | `rtl`\n mimeType?: string\n } = { mimeType: \"text/plain\" },\n) => {\n const txtOpfContent = `\n <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <package xmlns=\"http://www.idpf.org/2007/opf\" version=\"3.0\" xml:lang=\"ja\" prefix=\"rendition: http://www.idpf.org/vocab/rendition/#\"\n unique-identifier=\"ootuya-id\">\n <metadata xmlns:opf=\"http://www.idpf.org/2007/opf\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n xmlns:dcterms=\"http://purl.org/dc/terms/\">\n <meta property=\"rendition:layout\">reflowable</meta>\n </metadata>\n <manifest>\n <item id=\"p01\" href=\"p01.txt\" media-type=\"text/plain\"/>\n </manifest>\n <spine page-progression-direction=\"${direction ?? `ltr`}\">\n <itemref idref=\"p01\" />\n </spine>\n </package>\n `\n\n const archive: Archive = {\n filename: `content.txt`,\n files: [\n {\n dir: false,\n basename: getUriBasename(`generated.opf`),\n uri: `generated.opf`,\n blob: async () => new Blob([txtOpfContent]),\n string: async () => txtOpfContent,\n base64: async () => btoa(txtOpfContent),\n size: 0,\n },\n {\n dir: false,\n basename: getUriBasename(`p01.txt`),\n uri: `p01.txt`,\n blob: async () => {\n if (typeof content === `string`) return new Blob([content])\n return content\n },\n string: async () => {\n if (typeof content === `string`) return content\n return content.text()\n },\n base64: async () => {\n if (typeof content === `string`) return btoa(content)\n return blobToBase64(content)\n },\n size: typeof content === `string` ? content.length : content.size,\n encodingFormat: mimeType,\n },\n ],\n close: () => Promise.resolve(),\n }\n\n return archive\n}\n","import { Report } from \"../report\"\nimport { sortByTitleComparator } from \"../utils/sortByTitleComparator\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { Archive, StreamResult } from \"./types\"\n\ninterface OutputByType {\n base64: string\n string: string\n text: string\n binarystring: string\n array: number[]\n uint8array: Uint8Array\n arraybuffer: ArrayBuffer\n blob: Blob\n nodebuffer: Buffer\n}\n\ntype OutputType = keyof OutputByType\ninterface JSZipObject {\n name: string\n dir: boolean\n date: Date\n comment: string\n unixPermissions: number | string | null\n dosPermissions: number | null\n async<T extends OutputType>(type: T): Promise<OutputByType[T]>\n // nodeStream(type?: `nodebuffer`): NodeJS.ReadableStream;\n internalStream?: (type?: `uint8array`) => StreamResult\n}\n\ninterface JSZip {\n files: { [key: string]: JSZipObject }\n}\n\nexport const createArchiveFromJszip = async (\n jszip: JSZip,\n { orderByAlpha, name }: { orderByAlpha?: boolean; name?: string } = {},\n): Promise<Archive> => {\n let files = Object.values(jszip.files)\n\n if (orderByAlpha) {\n files = files.slice().sort((a, b) => sortByTitleComparator(a.name, b.name))\n }\n\n const archive = {\n filename: name || ``,\n files: files.map((file) => ({\n dir: file.dir,\n basename: getUriBasename(file.name),\n uri: file.name,\n blob: () => file.async(`blob`),\n string: () => file.async(`string`),\n base64: () => file.async(`base64`),\n ...(file.internalStream && {\n stream: file.internalStream,\n }),\n // this is private API\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n size: file._data.uncompressedSize,\n })),\n close: () => Promise.resolve(),\n }\n\n Report.log(\"Generated archive\", archive)\n\n return archive\n}\n","/**\n * @see https://github.com/nika-begiashvili/libarchivejs.\n *\n * Does not work in service worker due to usage of web worker.\n */\n/* eslint-disable @typescript-eslint/ban-types */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Report } from \"../report\"\nimport { Archive } from \"./types\"\n\ninterface ArchiveReader {\n getFilesArray(): Promise<any[]>\n /**\n * Terminate worker to free up memory\n */\n close(): Promise<void>\n}\n\n/**\n * Represents compressed file before extraction\n */\ninterface CompressedFile {\n /**\n * File name\n */\n get name(): string\n /**\n * File size\n */\n get size(): number\n get lastModified(): number\n /**\n * Extract file from archive\n * @returns {Promise<File>} extracted file\n */\n extract(): any\n}\n\nexport const createArchiveFromLibArchive = async (\n libArchive: ArchiveReader,\n { name }: { orderByAlpha?: boolean; name?: string } = {},\n): Promise<Archive> => {\n const objArray = await libArchive.getFilesArray()\n\n const archive: Archive = {\n close: () => libArchive.close(),\n filename: name ?? ``,\n files: objArray.map((item: { file: CompressedFile; path: string }) => ({\n dir: false,\n basename: item.file.name,\n size: item.file.size,\n uri: `${item.path}${item.file.name}`,\n base64: async () => {\n return ``\n },\n blob: async () => {\n const file = await (item.file.extract() as Promise<File>)\n\n return file\n },\n string: async () => {\n const file = await (item.file.extract() as Promise<File>)\n\n return file.text()\n },\n })),\n }\n\n Report.log(\"Generated archive\", archive)\n\n return archive\n}\n","import { sortByTitleComparator } from \"../utils/sortByTitleComparator\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { Archive } from \"./types\"\n\nexport const createArchiveFromArrayBufferList = async (\n list: {\n isDir: boolean\n name: string\n size: number\n data: () => Promise<ArrayBuffer>\n }[],\n { orderByAlpha, name }: { orderByAlpha?: boolean; name?: string } = {},\n): Promise<Archive> => {\n let files = list\n\n if (orderByAlpha) {\n files = files.slice().sort((a, b) => sortByTitleComparator(a.name, b.name))\n }\n\n return {\n filename: name || ``,\n files: files.map((file) => ({\n dir: file.isDir,\n basename: getUriBasename(file.name),\n uri: file.name,\n blob: async () => new Blob([await file.data()]),\n string: async () => {\n const data = await file.data()\n return String.fromCharCode.apply(\n null,\n Array.from(new Uint16Array(data)),\n )\n },\n base64: async () => {\n // @todo not used for now, lets implement it later if needed\n return ``\n },\n size: file.size,\n })),\n close: () => Promise.resolve(),\n }\n}\n","import { Report } from \"./report\"\n\nexport const configure = ({\n enableReport,\n}: { enableReport?: boolean } = {}) => {\n Report.enable(!!enableReport)\n}\n","import {\n BehaviorSubject,\n catchError,\n distinctUntilChanged,\n EMPTY,\n filter,\n first,\n from,\n ignoreElements,\n map,\n merge,\n mergeMap,\n NEVER,\n of,\n shareReplay,\n startWith,\n Subject,\n switchMap,\n takeUntil,\n tap,\n timer,\n withLatestFrom,\n} from \"rxjs\"\nimport { Archive } from \"./types\"\n\ntype ArchiveEntry = {\n status: \"idle\" | \"loading\" | \"success\" | \"error\"\n error: unknown\n archive: undefined | Archive\n locks: number\n}\n\nexport const createArchiveLoader = ({\n getArchive,\n cleanArchiveAfter,\n}: {\n getArchive: (key: string) => Promise<Archive>\n cleanArchiveAfter: number\n}) => {\n const loadSubject = new Subject<string>()\n const destroySubject = new Subject<void>()\n const purgeSubject = new Subject<void>()\n const archives: Record<string, BehaviorSubject<ArchiveEntry>> = {}\n\n const archiveLoaded$ = loadSubject.pipe(\n mergeMap((key) => {\n const archiveEntry = archives[key]\n\n if (!archiveEntry || archiveEntry.getValue().status !== \"idle\")\n return EMPTY\n\n archiveEntry.next({\n ...archiveEntry.getValue(),\n status: \"loading\",\n })\n\n return from(getArchive(key)).pipe(\n map((archive) => {\n archiveEntry.next({\n ...archiveEntry.getValue(),\n archive,\n status: \"success\",\n })\n\n return { key, archiveEntry }\n }),\n catchError((error) => {\n archiveEntry.next({\n ...archiveEntry.getValue(),\n status: \"error\",\n error,\n })\n\n return EMPTY\n }),\n )\n }),\n shareReplay(),\n )\n\n const cleanup$ = archiveLoaded$.pipe(\n switchMap(({ archiveEntry, key }) => {\n const locks$ = archiveEntry.pipe(map(({ locks }) => locks))\n const isPurged$ = purgeSubject.pipe(\n map(() => true),\n startWith(false),\n shareReplay(),\n )\n const isUnlocked$ = locks$.pipe(\n map((locks) => locks <= 0),\n distinctUntilChanged(),\n )\n\n return isUnlocked$.pipe(\n withLatestFrom(isPurged$),\n switchMap(([isUnlocked, isPurged]) =>\n !isUnlocked ? NEVER : !isPurged ? timer(cleanArchiveAfter) : of(null),\n ),\n tap(() => {\n delete archives[key]\n\n archiveEntry.getValue().archive?.close()\n }),\n )\n }),\n )\n\n const access = (key: string) => {\n let releaseCalled = false\n\n const archiveEntry =\n archives[key] ??\n new BehaviorSubject<ArchiveEntry>({\n archive: undefined,\n status: \"idle\",\n locks: 0,\n error: undefined,\n })\n\n archives[key] = archiveEntry\n\n archiveEntry.next({\n ...archiveEntry.getValue(),\n locks: archiveEntry.getValue().locks + 1,\n })\n\n const release = () => {\n if (releaseCalled) return\n\n releaseCalled = true\n\n archiveEntry.next({\n ...archiveEntry.getValue(),\n locks: archiveEntry.getValue().locks - 1,\n })\n }\n\n loadSubject.next(key)\n\n const archive$ = archiveEntry.pipe(\n map(({ archive }) => archive),\n filter((archive) => !!archive),\n )\n\n const error$ = archiveEntry.pipe(\n tap(({ error }) => {\n if (error) {\n throw error\n }\n }),\n ignoreElements(),\n )\n\n return merge(archive$, error$).pipe(\n first(),\n map((archive) => ({ archive, release })),\n catchError((error) => {\n release()\n\n throw error\n }),\n )\n }\n\n /**\n * Will purge immediatly archives as soon as they are released\n */\n const purge = () => {\n // make sure we don't access anymore\n Object.keys(archives).forEach((key) => {\n delete archives[key]\n })\n\n purgeSubject.next()\n }\n\n merge(cleanup$, archiveLoaded$).pipe(takeUntil(destroySubject)).subscribe()\n\n return {\n access,\n purge,\n }\n}\n","import {\n catchError,\n finalize,\n from,\n lastValueFrom,\n map,\n mergeMap,\n Observable,\n of,\n switchMap,\n} from \"rxjs\"\nimport { createArchiveLoader } from \"./archives/archiveLoader\"\nimport { Manifest } from \"@prose-reader/shared\"\nimport { generateManifestFromArchive } from \"./generators/manifest\"\nimport { generateResourceFromArchive } from \"./generators/resources\"\nimport { Archive } from \"./archives/types\"\n\ntype OnError = (error: unknown) => Response\ntype OnManifestSuccess = (params: {\n manifest: Manifest\n archive: Archive\n}) => Observable<Manifest> | Promise<Manifest>\n\nexport class Streamer {\n protected epubLoader: ReturnType<typeof createArchiveLoader>\n protected onError: OnError = (error) => {\n return new Response(String(error), { status: 500 })\n }\n protected onManifestSuccess: OnManifestSuccess\n protected lastAccessedKey: string | undefined\n\n constructor({\n onError,\n onManifestSuccess,\n ...rest\n }: Parameters<typeof createArchiveLoader>[0] & {\n onError?: OnError\n onManifestSuccess?: OnManifestSuccess\n }) {\n this.epubLoader = createArchiveLoader(rest)\n\n this.onManifestSuccess =\n onManifestSuccess ?? (({ manifest }) => Promise.resolve(manifest))\n this.onError = onError ?? this.onError\n }\n\n protected accessArchive(key: string) {\n if (this.lastAccessedKey !== key) {\n this.epubLoader.purge()\n }\n\n this.lastAccessedKey = key\n\n return this.epubLoader.access(key)\n }\n\n public fetchManifest({ key, baseUrl }: { key: string; baseUrl?: string }) {\n const response$ = this.accessArchive(key).pipe(\n mergeMap(({ archive, release }) => {\n const manifest$ = from(\n generateManifestFromArchive(archive, { baseUrl }),\n )\n\n return manifest$.pipe(\n switchMap((manifest) =>\n from(this.onManifestSuccess({ manifest, archive })),\n ),\n map(\n (manifest) =>\n new Response(JSON.stringify(manifest satisfies Manifest), {\n status: 200,\n }),\n ),\n finalize(() => {\n release()\n }),\n )\n }),\n catchError((error) => {\n return of(this.onError(error))\n }),\n )\n\n return lastValueFrom(response$)\n }\n\n public fetchResource({\n key,\n resourcePath,\n }: {\n key: string\n resourcePath: string\n }) {\n const response$ = this.accessArchive(key).pipe(\n mergeMap(({ archive, release }) => {\n const manifest$ = from(\n generateResourceFromArchive(archive, resourcePath),\n )\n\n return manifest$.pipe(\n map(\n (resource) =>\n new Response(resource.body, {\n status: 200,\n headers: {\n ...(resource.params.contentType && {\n \"Content-Type\": resource.params.contentType,\n }),\n },\n }),\n ),\n finalize(() => {\n release()\n }),\n )\n }),\n catchError((error) => {\n return of(this.onError(error))\n }),\n )\n\n return lastValueFrom(response$)\n }\n}\n","import { Streamer } from \"./Streamer\"\nimport { removeTrailingSlash } from \"./utils/uri\"\n\ntype ConflictFreeWebWorkerFetchEvent = {\n readonly request: Request\n /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FetchEvent/respondWith) */\n respondWith(r: Response | PromiseLike<Response>): void\n}\n\nexport class ServiceWorkerStreamer extends Streamer {\n protected getUriInfo: (event: ConflictFreeWebWorkerFetchEvent) =>\n | {\n baseUrl: string\n }\n | undefined\n\n constructor({\n getUriInfo,\n ...rest\n }: ConstructorParameters<typeof Streamer>[0] & {\n getUriInfo: (event: ConflictFreeWebWorkerFetchEvent) =>\n | {\n baseUrl: string\n }\n | undefined\n }) {\n super(rest)\n\n this.getUriInfo = getUriInfo\n this.fetchEventListener = this.fetchEventListener.bind(this)\n }\n\n fetchEventListener(event: ConflictFreeWebWorkerFetchEvent) {\n try {\n const uriInfo = this.getUriInfo(event)\n\n if (!uriInfo) return\n\n const baseUrl = removeTrailingSlash(uriInfo.baseUrl)\n const streamerPath = event.request.url.substring(\n baseUrl.length + `/`.length,\n )\n const [key = ``] = streamerPath.split(\"/\")\n const resourcePath = decodeURIComponent(\n removeTrailingSlash(streamerPath.substring(key.length + `/`.length)),\n )\n\n if (streamerPath.endsWith(`/manifest`)) {\n event.respondWith(\n this.fetchManifest({ key, baseUrl: `${baseUrl}/${key}/` }),\n )\n } else {\n event.respondWith(this.fetchResource({ key, resourcePath }))\n }\n } catch (e) {\n event.respondWith(new Response(String(e), { status: 500 }))\n }\n }\n}\n"],"names":["enabled","Report","enable","data","label","performanceEntry","targetDuration","duration","name","functionToMeasure","args","t0","response","res","t1","hasCalibreCoverMeta","doc","metaElm","_a","node","getBuggyCoverSvg","_c","_b","fixBuggyCover","archive","resourcePath","resource","file","bodyToParse","opfXmlDoc","XmlDocument","buggySvg","calibreFixHook","cssFixHook","newBody","getArchiveOpfInfo","extractNavChapter","li","opfBasePath","baseUrl","chp","contentNode","urlJoin","sublistNode","children","child","buildTOCFromNav","toc","navDataChildren","parseTocFromNavPath","navItem","tocFile","item","xmldoc","mapNcxChapter","point","prefix","src","out","pt","buildTOCFromNCX","ncxData","rootTagName","parseTocFromNcx","opfData","spine","ncxId","ncxItem","ncxPath","parseToc","tocFromNcx","extractKoboInformationFromArchive","koboInformation","optionElement","getSpineItemFilesFromArchive","opsFile","_opfXmlDoc","manifestElm","spineElm","spineItemIds","manifestItemsFromSpine","getItemsFromDoc","el","epubHook","manifest","metadataElm","guideElm","titleElm","metaElmChildren","metaElmWithRendition","meta","metaElmWithRenditionFlow","metaElmWithRenditionSpread","publisherRenditionLayout","publisherRenditionFlow","renditionSpread","title","dir","pageProgressionDirection","totalSize","size","itemrefElm","manifestItem","href","properties","itemSize","hrefBaseUri","property","elm","getMetadata","getContentTypeFromExtension","uri","defaultHook","metadata","invalidSelfClosingTags","selfClosingTagsFixHook","tagPattern","fixedBody","match","tagName","attributes","generateResourceFromArchive","defaultResource","hooks","gen","e","files","index","comicInfoHook","comicInfoFile","manifestWithoutComicInfo","_","items","content","mangaVal","hasDocMetaViewport","allFilesHaveViewportMeta","result","current","isXmlBasedMimeType","epubOptimizerHook","sortByTitleComparator","a","b","alist","blist","i","len","navigationFallbackHook","filesSortedByAlpha","acc","parts","part","level","baseManifest","generateManifestFromArchive","getUriBasename","removeTrailingSlash","createArchiveFromUrls","urls","options","opfFileData","url","detectMimeTypeFromName","filesFromUrl","blobToBase64","blob","resolve","reader","base64data","createArchiveFromText","mimeType","direction","txtOpfContent","createArchiveFromJszip","jszip","orderByAlpha","createArchiveFromLibArchive","libArchive","objArray","createArchiveFromArrayBufferList","list","configure","enableReport","createArchiveLoader","getArchive","cleanArchiveAfter","loadSubject","Subject","destroySubject","purgeSubject","archives","archiveLoaded$","mergeMap","key","archiveEntry","EMPTY","from","map","catchError","error","shareReplay","cleanup$","switchMap","locks$","locks","isPurged$","startWith","distinctUntilChanged","withLatestFrom","isUnlocked","isPurged","of","timer","NEVER","tap","access","releaseCalled","BehaviorSubject","release","archive$","filter","error$","ignoreElements","merge","first","purge","takeUntil","Streamer","onError","onManifestSuccess","rest","response$","finalize","lastValueFrom","ServiceWorkerStreamer","getUriInfo","event","uriInfo","streamerPath"],"mappings":";;;AACA,IAAIA,IAAU;AAEP,MAAMC,IAAS;AAAA,EACpB,QAAQ,CAACC,MAAoB;AACjB,IAAAF,IAAAE;AAAA,EACZ;AAAA;AAAA,EAEA,KAAK,IAAIC,MAAgB;AACvB,IAAIH,KAEM,QAAA,IAAI,2BAA2B,GAAGG,CAAI;AAAA,EAElD;AAAA;AAAA,EAEA,MAAM,IAAIA,MAAgB;AACxB,IAAIH,KAEM,QAAA,KAAK,2BAA2B,GAAGG,CAAI;AAAA,EAEnD;AAAA;AAAA,EAEA,OAAO,IAAIA,MAAgB;AAEjB,YAAA,MAAM,GAAGA,CAAI;AAAA,EACvB;AAAA,EACA,MAAM,CAACC,MAA+B;AACpC,IAAIJ,KAEM,QAAA,KAAK,oCAAoCI,CAAK,EAAE;AAAA,EAE5D;AAAA,EACA,SAAS,CAACA,MAA+B;AACvC,IAAIJ,KAEM,QAAA,QAAQ,oCAAoCI,CAAK,EAAE;AAAA,EAE/D;AAAA,EACA,QAAQ,CACNC,GACAC,IAAiB,UACd;AACH,UAAMC,IACJ,OAAOF,KAAqB,WACxBA,IACAA,EAAiB;AACvB,IAAIL,MACEK,EAAiB,YAAYC,IAEvB,QAAA;AAAA,MACN;AAAA,MACA,GAAGD,EAAiB,IAAI,SAASE,CAAQ;AAAA,IAAA,IAInC,QAAA;AAAA,MACN;AAAA,MACA,GAAGF,EAAiB,IAAI,SAASA,EAAiB,QAAQ,yBAAyBC,CAAc;AAAA,IAAA;AAAA,EAIzG;AAAA;AAAA,EAEA,oBAAoB,CAClBE,GACAF,IAAiB,IACjBG,MAEO,IAAIC,MAAuC;AAC1C,UAAAC,IAAK,YAAY,OAGjBC,IAAWH,EAAkB,GAAIC,CAAY;AAE/C,QAAAE,KAAYA,EAAS;AAChB,aAAAA,EAAS,KAAK,CAACC,MAAa;AAC3BC,cAAAA,IAAK,YAAY;AACvB,eAAAb,EAAO,OAAO,EAAE,MAAAO,GAAM,UAAUM,IAAKH,EAAA,GAAML,CAAc,GAClDO;AAAA,MAAA,CACR;AAGG,UAAAC,IAAK,YAAY;AAEvB,WAAAb,EAAO,OAAO,EAAE,MAAAO,GAAM,UAAUM,IAAKH,EAAA,GAAML,CAAc,GAElDM;AAAA,EAAA;AAGb,GCrFMG,KAAsB,CAACC,MAAqB;;AAChD,QAAMC,KAAUC,IAAAF,EACb,mBAAmB,MAAM,MADZ,gBAAAE,EAEZ,cAAc,QACf,KAAK,CAACC,MAASA,EAAK,KAAK,SAAS;AAErC,SAAO,CAAC,EAAEF,KAAWA,EAAQ,KAAK,SAAS;AAC7C,GAEMG,KAAmB,CAACJ,MAAqB;;AACtC,UAAAK,KAAAC,KAAAJ,IAAAF,EACJ,mBAAmB,MAAM,MADrB,gBAAAE,EAEH,mBAAmB,WAFhB,gBAAAI,EAGH,cAAc,WAHX,gBAAAD,EAIH;AAAA,IACA,CAACF,MACCA,EAAK,KAAK,UAAU,UAAUA,EAAK,KAAK,wBAAwB;AAAA;AAExE,GAEMI,KACJ,CAAC,EAAE,SAAAC,GAAS,cAAAC,EAAa,MACzB,OAAOC,MAAkD;AACvD,QAAMC,IAAO,OAAO,OAAOH,EAAQ,KAAK,EAAE;AAAA,IACxC,CAACG,MAASA,EAAK,QAAQF;AAAA,EAAA;AAGzB,MAAIE,KAAA,QAAAA,EAAM,SAAS,SAAS,WAAW;AACrC,UAAMC,IAAcF,EAAS,QAAS,MAAMC,EAAK,OAAO,GAElDE,IAAY,IAAIC,GAAYF,CAAW;AAEzC,QAAAb,GAAoBc,CAAS,GAAG;AAC5B,YAAAE,IAAWX,GAAiBS,CAAS;AAE3C,aAAIE,KACF,OAAOA,EAAS,KAAK,qBAGhB;AAAA,QACL,GAAGL;AAAA,QACH,MAAMG,KAAA,gBAAAA,EAAW;AAAA,MAAS;AAAA,IAE9B;AAAA,EACF;AAEO,SAAAH;AACT,GAEWM,KACX,CAAC,EAAE,SAAAR,GAAS,cAAAC,EAAa,MACzB,OAAOC,MACEH,GAAc,EAAE,SAAAC,GAAS,cAAAC,EAAa,CAAC,EAAEC,CAAQ,GCrD/CO,KACX,CAAC,EAAE,SAAAT,GAAS,cAAAC,EAAa,MACzB,OAAOC,MAAkD;AACvD,QAAMC,IAAO,OAAO,OAAOH,EAAQ,KAAK,EAAE;AAAA,IACxC,CAACG,MAASA,EAAK,QAAQF;AAAA,EAAA;AAGzB,MAAIE,KAAA,QAAAA,EAAM,SAAS,SAAS,SAAS;AAOnC,UAAMO,KANcR,EAAS,QAAS,MAAMC,EAAK,OAAO,GAM5B;AAAA,MAC1B;AAAA,MACA;AAAA,IAAA;AAGK,WAAA;AAAA,MACL,GAAGD;AAAA,MACH,MAAMQ;AAAA,IAAA;AAAA,EAEV;AAEO,SAAAR;AACT,GC3BWS,IAAoB,CAACX,MAAqB;AAE/C,QAAAG,IADe,OAAO,OAAOH,EAAQ,KAAK,EAAE,OAAO,CAACG,MAAS,CAACA,EAAK,GAAG,EAClD,KAAK,CAACA,MAASA,EAAK,IAAI,SAAS,MAAM,CAAC;AAE3D,SAAA;AAAA,IACL,MAAMA;AAAA,IACN,WAAUA,KAAA,gBAAAA,EAAM,IAAI,UAAU,GAAGA,EAAK,IAAI,YAAY,GAAG,OAAM;AAAA,EAAA;AAEnE,GCFMS,IAAoB,CACxBC,GACA,EAAE,aAAAC,GAAa,SAAAC,QACZ;AACH,QAAMC,IAAe;AAAA,IACnB,UAAU,CAAC;AAAA,IACX,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,EAAA;AAET,MAAIC,IAAcJ,EAAG,WAAW,MAAM,KAAKA,EAAG,WAAW,GAAG;AACxD,EAAAG,EAAA,SAAQC,KAAA,gBAAAA,EAAa,KAAK,WAASA,KAAA,gBAAAA,EAAa,IAAI,WAAUD,EAAI;AACtE,MAAIrB,IAAOsB,KAAA,gBAAAA,EAAa;AACxB,EAAItB,MAAS,QACXsB,IAAcJ,EAAG,mBAAmB,GAAGlB,CAAI,IAAI,GAC3CsB,MACKtB,IAAAsB,EAAY,KAAK,iBAGxBtB,MAAS,QAAOsB,KAAA,QAAAA,EAAa,KAAK,UACpCD,EAAI,OAAOE,EAAQJ,GAAaG,EAAY,KAAK,IAAI,GACrDD,EAAI,OAAOE,EAAQH,GAASD,GAAaG,EAAY,KAAK,IAAI;AAE1D,QAAAE,IAAcN,EAAG,WAAW,IAAI;AACtC,MAAIM,GAAa;AACT,UAAAC,IAAWD,EAAY,cAAc,IAAI;AAC3C,IAAAC,KAAYA,EAAS,SAAS,MAChCJ,EAAI,WAAWI,EAAS;AAAA,MAAI,CAACC,MAC3BT,EAAkBS,GAAO,EAAE,aAAAP,GAAa,SAAAC,GAAS;AAAA,IAAA;AAAA,EAGvD;AAEO,SAAAC;AACT,GAEMM,KAAkB,CACtB9B,GACA,EAAE,aAAAsB,GAAa,SAAAC,QACZ;;AACH,QAAMQ,IAAW,CAAA;AAEb,MAAAC;AACA,SAAAhC,EAAI,mBAAmB,aAAa,IACpBgC,KAAA9B,IAAAF,EAAI,mBAAmB,aAAa,MAApC,gBAAAE,EAAuC,WAChDF,EAAI,mBAAmB,qBAAqB,MACnCgC,KAAA1B,IAAAN,EAAI,mBAAmB,qBAAqB,MAA5C,gBAAAM,EAA+C,WAG/D0B,KAAmBA,EAAgB,SAAS,KAC9CA,EACG,OAAO,CAACX,MAAQA,EAAkB,SAAS,IAAI,EAC/C;AAAA,IAAQ,CAACA,MACRU,EAAI,KAAKX,EAAkBC,GAAkB,EAAE,aAAAC,GAAa,SAAAC,EAAQ,CAAC,CAAC;AAAA,EAAA,GAIrEQ;AACT,GAEME,KAAsB,OAC1BpB,GACAL,GACA,EAAE,aAAAc,GAAa,SAAAC,QACZ;;AAEH,QAAMW,KAAUhC,IAAAW,EACb,WAAW,UAAU,MADR,gBAAAX,EAEZ,cAAc,QACf,KAAK,CAAC2B,MAAUA,EAAM,KAAK,eAAe;AAE7C,MAAIK,GAAS;AACX,UAAMC,IAAU,OAAO,OAAO3B,EAAQ,KAAK,EAAE;AAAA,MAAK,CAAC4B,MACjDA,EAAK,IAAI,SAASF,EAAQ,KAAK,QAAQ,EAAE;AAAA,IAAA;AAE3C,QAAIC,GAAS;AACX,YAAMnC,IAAM,IAAIqC,EAAO,YAAY,MAAMF,EAAQ,QAAQ;AACzD,aAAOL,GAAgB9B,GAAK,EAAE,aAAAsB,GAAa,SAAAC,EAAS,CAAA;AAAA,IACtD;AAAA,EACF;AACF,GAEMe,IAAgB,CACpBC,GACA;AAAA,EACE,aAAAjB;AAAA,EACA,SAAAC;AAAA,EACA,QAAAiB;AACF,MACG;;AACG,QAAAC,MAAMvC,IAAAqC,KAAA,gBAAAA,EAAO,WAAW,GAAGC,CAAM,eAA3B,gBAAAtC,EAAuC,KAAK,QAAO,IAEzDwC,IAAe;AAAA,IACnB,SACEpC,IAAAiC,KAAA,gBAAAA,EAAO,mBAAmB,GAAGC,CAAM,YAAYA,CAAM,YAArD,gBAAAlC,EAA8D,QAAO;AAAA,IACvE,MAAMoB,EAAQJ,GAAamB,CAAG;AAAA,IAC9B,MAAMf,EAAQH,GAASD,GAAamB,CAAG;AAAA,IACvC,UAAU,CAAC;AAAA,EAAA,GAEPb,IAAWW,EAAM,cAAc,GAAGC,CAAM,UAAU;AACpD,SAAAZ,KAAYA,EAAS,SAAS,MAChCc,EAAI,WAAWd,EAAS;AAAA,IAAI,CAACe,MAC3BL,EAAcK,GAAI,EAAE,aAAArB,GAAa,SAAAC,GAAS,QAAAiB,GAAQ;AAAA,EAAA,IAI/CE;AACT,GAEME,KAAkB,CACtBC,GACA,EAAE,aAAAvB,GAAa,SAAAC,QACZ;;AACH,QAAMQ,IAA2C,CAAA,GAE3Ce,IAAcD,EAAQ;AAC5B,MAAIL,IAAS;AACb,SAAIM,EAAY,QAAQ,GAAG,MAAM,OAC/BN,IAASM,EAAY,MAAM,GAAG,EAAE,CAAC,IAAI,OAIpC5C,IAAA2C,EAAA,WAAW,GAAGL,CAAM,QAAQ,MAA5B,QAAAtC,EACC,cAAc,GAAGsC,CAAM,YACxB;AAAA,IAAQ,CAACD,MACRR,EAAI,KAAKO,EAAcC,GAAO,EAAE,aAAAjB,GAAa,SAAAC,GAAS,QAAAiB,EAAO,CAAC,CAAC;AAAA,KAG5DT;AACT,GAEMgB,KAAkB,OAAO;AAAA,EAC7B,SAAAC;AAAA,EACA,aAAA1B;AAAA,EACA,SAAAC;AAAA,EACA,SAAAf;AACF,MAKM;;AACE,QAAAyC,IAAQD,EAAQ,WAAW,OAAO,GAClCE,IAAQD,KAASA,EAAM,KAAK;AAElC,MAAIC,GAAO;AACT,UAAMC,KAAUjD,IAAA8C,EACb,WAAW,UAAU,MADR,gBAAA9C,EAEZ,cAAc,QACf,KAAK,CAACkC,MAASA,EAAK,KAAK,OAAOc;AAEnC,QAAIC,GAAS;AACL,YAAAC,IAAU,GAAG9B,CAAW,GAAGA,MAAgB,KAAK,KAAK,GAAG,GAAG6B,EAAQ,KAAK,IAAI,IAE5ExC,IAAO,OAAO,OAAOH,EAAQ,KAAK,EAAE;AAAA,QAAK,CAAC4B,MAC9CA,EAAK,IAAI,SAASgB,CAAO;AAAA,MAAA;AAG3B,UAAIzC,GAAM;AACR,cAAMkC,IAAU,IAAIR,EAAO,YAAY,MAAM1B,EAAK,QAAQ;AAE1D,eAAOiC,GAAgBC,GAAS,EAAE,aAAAvB,GAAa,SAAAC,EAAS,CAAA;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AACF,GAEa8B,KAAW,OACtBxC,GACAL,GACA,EAAE,SAAAe,QACC;AACH,QAAM,EAAE,UAAUD,EAAA,IAAgBH,EAAkBX,CAAO,KAAK,IAE1D8C,IAAa,MAAMP,GAAgB;AAAA,IACvC,SAASlC;AAAA,IACT,aAAAS;AAAA,IACA,SAAAd;AAAA,IACA,SAAAe;AAAA,EAAA,CACD;AAED,SAAI+B,KAIG,MAAMrB,GAAoBpB,GAAWL,GAAS,EAAE,aAAAc,GAAa,SAAAC,GAAS;AAC/E,GC3LagC,KAAoC,OAAO/C,MAAqB;AAC3E,QAAMgD,IAAmC;AAAA,IACvC,iBAAiB;AAAA,EAAA;AAGnB,eAAM,QAAQ;AAAA,IACZhD,EAAQ,MAAM,IAAI,OAAOG,MAAS;;AAChC,UAAIA,EAAK,IAAI,SAAS,mCAAmC,GAAG;AAE1D,cAAM8C,KAAgBvD,IADJ,IAAImC,EAAO,YAAY,MAAM1B,EAAK,QAAQ,EAEzD,WAAW,UAAU,MADF,gBAAAT,EAElB,WAAW;AACf,UACEI,IAAAmD,KAAA,gBAAAA,EAAe,SAAf,gBAAAnD,EAAqB,UAAS,kBAC9BmD,EAAc,QAAQ,WAEtBD,EAAgB,kBAAkB;AAAA,MAEtC;AAAA,IAAA,CACD;AAAA,EAAA,GAGIA;AACT,GC1BaE,IAA+B,OAAO;AAAA,EACjD,SAAAlD;AACF,MAEM;AACE,QAAA,EAAE,MAAMmD,GAAS,UAAUrC,MAC/BH,EAAkBX,CAAO,KAAK,IAE1BrB,IAAO,OAAMwE,KAAA,gBAAAA,EAAS;AAExB,MAAA,CAACxE,EAAM,QAAO;AAElB,QAAMyE,IAAa,IAAIvB,EAAO,YAAYlD,CAAI,GAExC0E,IAAcD,EAAW,WAAW,UAAU,GAC9CE,IAAWF,EAAW,WAAW,OAAO,GAExCG,IAAeD,KAAA,gBAAAA,EACjB,cAAc,WACf,IAAI,CAAC1B,MAASA,EAAK,KAAK,QACrB4B,KACJH,KAAA,gBAAAA,EACI,cAAc,QACf,OAAO,CAACzB,MAAS2B,EAAa,SAAS3B,EAAK,KAAK,MAAM,EAAE,OAAM;AAS7D,SAPmB5B,EAAQ,MAAM,OAAO,CAACG,MACvCqD,EAAuB,KAAK,CAAC5B,MAC7Bd,IACE,GAAGA,CAAW,IAAIc,EAAK,KAAK,IAAI,OAAOzB,EAAK,MAD1B,GAAGyB,EAAK,KAAK,IAAI,OAAOzB,EAAK,GAEvD,CACF;AAGH,GCvBasD,KAAkB,CAACjE,MAA4B;;AACpD,QAAA6D,IAAc7D,EAAI,WAAW,UAAU;AAE7C,WACEE,IAAA2D,KAAA,gBAAAA,EAAa,cAAc,YAA3B,gBAAA3D,EAAoC,IAAI,CAACgE,OAAQ;AAAA,IAC/C,MAAMA,EAAG,KAAK,QAAQ;AAAA,IACtB,IAAIA,EAAG,KAAK,MAAM;AAAA,IAClB,WAAWA,EAAG,KAAK,YAAY;AAAA,EAAA,QAC1B,CAAA;AAEX,GAEaC,KACX,CAAC,EAAE,SAAA3D,GAAS,SAAAe,EAAQ,MACpB,OAAO6C,MAA0C;;AACzC,QAAA,EAAE,MAAMT,GAAS,UAAUrC,MAC/BH,EAAkBX,CAAO,KAAK,IAC1BgD,IAAkB,MAAMD,GAAkC/C,CAAO;AAEvE,MAAI,CAACmD;AACI,WAAAS;AAGH,QAAAjF,IAAO,MAAMwE,EAAQ;AAEpB,EAAA1E,EAAA,IAAIE,GAAMqE,CAAe;AAEhC,QAAM3C,IAAY,IAAIwB,EAAO,YAAYlD,CAAI,GAEvC4C,IAAO,MAAMsB,GAASxC,GAAWL,GAAS,EAAE,SAAAe,EAAA,CAAS,KAAM,IAE3D8C,IAAcxD,EAAU,WAAW,UAAU,GAC7CgD,IAAchD,EAAU,WAAW,UAAU,GAC7CiD,IAAWjD,EAAU,WAAW,OAAO,GACvCyD,IAAWzD,EAAU,WAAW,OAAO,GACvC0D,IAAWF,KAAA,gBAAAA,EAAa,WAAW,aACnCG,KAAkBH,KAAA,gBAAAA,EAAa,cAAc,YAAW,IACxDI,IAAuBD,EAAgB;AAAA,IAC3C,CAACE,MAASA,EAAK,KAAK,aAAa;AAAA,EAAA,GAE7BC,IAA2BH,EAAgB;AAAA,IAC/C,CAACE,MAASA,EAAK,KAAK,aAAa;AAAA,EAAA,GAE7BE,IAA6BJ,EAAgB;AAAA,IACjD,CAACE,MAASA,EAAK,KAAK,aAAa;AAAA,EAAA,GAG7BG,IAA2BJ,KAAA,gBAAAA,EAAsB,KAIjDK,KAAyBH,KAAA,gBAAAA,EAA0B,KAMnDI,KAAkBH,KAAA,gBAAAA,EAA4B,KAI9CI,MACJT,KAAA,gBAAAA,EAAU,UAAOrE,IAAAM,EAAQ,MAAM,KAAK,CAAC,EAAE,KAAAyE,EAAI,MAAMA,CAAG,MAAnC,gBAAA/E,EAAsC,aAAY,IAC/DgF,KAA2BpB,KAAA,gBAAAA,EAAU,KACzC,+BAKIqB,MAFoB,MAAMzB,EAA6B,EAAE,SAAAlD,EAAS,CAAA,GAEpC;AAAA,IAClC,CAAC4E,GAAMzE,MAASA,EAAK,OAAOyE;AAAA,IAC5B;AAAA,EAAA;AAGK,SAAA;AAAA,IACL,UAAU5E,EAAQ;AAAA,IAClB,KAAK;AAAA,MACH,KAAAuB;AAAA,IACF;AAAA,IACA,iBACE8C,KACArB,EAAgB,mBAChB;AAAA,IACF,eAAesB,MAA0B;AAAA,IACzC,iBAAAC;AAAA,IACA,OAAAC;AAAA,IACA,kBAAkBE,MAA4B;AAAA,IAC9C,aACEpB,KAAA,gBAAAA,EAAU,cAAc,WAAW,IAAI,CAACuB,MAAe;;AACrD,YAAMC,IAAezB,KAAA,gBAAAA,EACjB,cAAc,QACf,KAAK,CAACzB,MAASA,EAAK,KAAK,QAAOiD,KAAA,gBAAAA,EAAY,KAAK,SAC9CE,MAAOD,KAAA,gBAAAA,EAAc,KAAK,SAAQ,IAClCE,MAActF,IAAAmF,KAAA,gBAAAA,EAAY,KAAK,eAAjB,gBAAAnF,EAA6B,MAAM,SACrD,IACIuF,OACJnF,IAAAE,EAAQ,MAAM,KAAK,CAACG,MAASA,EAAK,IAAI,SAAS4E,EAAI,CAAC,MAApD,gBAAAjF,EAAuD,SAAQ,GAG3DoF,IAAcnE,KAAW;AAExB,aAAA;AAAA,QACL,KAAI+D,KAAA,gBAAAA,EAAc,KAAK,OAAM;AAAA,QAC7B,OAAMjF,IAAAiF,KAAA,gBAAAA,EAAc,KAAK,SAAnB,QAAAjF,EAAyB,WAAW,cACtCiF,KAAA,gBAAAA,EAAc,KAAK,OACnBhE,IACE,GAAGoE,CAAW,GAAGpE,CAAW,IAAIgE,KAAA,gBAAAA,EAAc,KAAK,IAAI,KACvD,GAAGI,CAAW,GAAGJ,KAAA,gBAAAA,EAAc,KAAK,IAAI;AAAA,QAC9C,iBAAiBT,KAA4B;AAAA,QAC7C,GAAIW,EAAW;AAAA,UACb,CAACG,MAAaA,MAAa;AAAA,QAAA,KACxB;AAAA,UACH,iBAAiB;AAAA,QACnB;AAAA,QACA,mBAAmBF,KAAWN;AAAA,QAC9B,gBACEK,EAAW,KAAK,CAACG,MAAaA,MAAa,kBAAkB,KAC7D;AAAA,QACF,iBACEH,EAAW,KAAK,CAACG,MAAaA,MAAa,mBAAmB,KAC9D;AAAA;AAAA,QAEF,WAAWL,KAAA,gBAAAA,EAAc,KAAK;AAAA,MAAY;AAAA,IAE7C,OAAK,CAAC;AAAA,IACT,OAAOrB,GAAgBpD,CAAS;AAAA,IAChC,OAAOyD,KAAA,gBAAAA,EAAU,cAAc,aAAa,IAAI,CAACsB,OACxC;AAAA,MACL,MAAMA,EAAI,KAAK,QAAQ;AAAA,MACvB,OAAOA,EAAI,KAAK,SAAS;AAAA,MACzB,MAAMA,EAAI,KAAK;AAAA,IAAA;AAAA,EAElB;AAEL,GC9IIC,KAAc,OAAOrF,GAAkBC,MAAyB;;AAEpE,QAAMtB,IAAO,QAAMe,IADHiB,EAAkBX,CAAO,EACd,SAAR,gBAAAN,EAAc;AAEjC,MAAIf,GAAM;AACR,UAAM0B,IAAY,IAAIwB,EAAO,YAAYlD,CAAI;AAGtC,WAAA;AAAA,MACL,YAAWmB,IAHC2D,GAAgBpD,CAAS,EAGpB,KAAK,CAACuB,MAAS3B,EAAa,SAAS2B,EAAK,IAAI,CAAC,MAArD,gBAAA9B,EACP;AAAA,IAAA;AAAA,EAER;AAEO,SAAA;AAAA,IACL,WAAWwF,GAA4BrF,CAAY;AAAA,EAAA;AAEvD,GAEMqF,KAA8B,CAACC,MAAgB;AAC/C,MAAAA,EAAI,SAAS,MAAM;AACd,WAAA;AAEL,MAAAA,EAAI,SAAS,MAAM;AACd,WAAA;AAEL,MAAAA,EAAI,SAAS,QAAQ;AAChB,WAAA;AAEL,MAAAA,EAAI,SAAS,MAAM;AACd,WAAA;AAEL,MAAAA,EAAI,SAAS,MAAM;AACd,WAAA;AAEX,GAEaC,KACX,CAAC,EAAE,SAAAxF,GAAS,cAAAC,EAAa,MACzB,OAAOC,MAAkD;AACvD,QAAMC,IAAO,OAAO,OAAOH,EAAQ,KAAK,EAAE;AAAA,IACxC,CAACG,MAASA,EAAK,QAAQF;AAAA,EAAA;AAGrB,MAAA,CAACE,EAAa,QAAAD;AAwClB,QAAMuF,IAAW,MAAMJ,GAAYrF,GAASC,CAAY;AAEjD,SAAA;AAAA,IACL,GAAGC;AAAA,IACH,QAAQ;AAAA,MACN,GAAGA,EAAS;AAAA,MACZ,IAAIC,KAAA,gBAAAA,EAAM,mBAAkB;AAAA,QAC1B,aAAaA,EAAK;AAAA,MACpB;AAAA,MACA,GAAIsF,EAAS,aAAa;AAAA,QACxB,aAAaA,EAAS;AAAA,MACxB;AAAA,IACF;AAAA,EAAA;AAEJ,GCrGIC,IAAyB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GASaC,KACX,CAAC,EAAE,SAAA3F,GAAS,cAAAC,EAAa,MACzB,OAAOC,MAAkD;AACvD,QAAMC,IAAO,OAAO,OAAOH,EAAQ,KAAK,EAAE;AAAA,IACxC,CAACG,MAASA,EAAK,QAAQF;AAAA,EAAA;AAGzB,MAAIE,KAAA,QAAAA,EAAM,SAAS,SAAS,WAAW;AACrC,UAAMC,IAAcF,EAAS,QAAS,MAAMC,EAAK,OAAO;AAMxD,QAAI,CAJoB,IAAI;AAAA,MAC1B,KAAKuF,EAAuB,KAAK,GAAG,CAAC;AAAA,MACrC;AAAA,IAAA,EAEmB,KAAKtF,CAAW;AAC5B,aAAAF;AAGT,UAAM0F,IAAa,IAAI;AAAA,MACrB,KAAKF,EAAuB,KAAK,GAAG,CAAC;AAAA,MACrC;AAAA,IAAA,GAGIG,IAAYzF,EAAY;AAAA,MAC5BwF;AAAA,MACA,CAACE,GAAOC,GAASC,IAAa,OAErB,IAAID,CAAO,IAAIC,EAAW,KAAK,CAAC,MAAMD,CAAO;AAAA,IACtD;AAGK,WAAA;AAAA,MACL,GAAG7F;AAAA,MACH,MAAM2F;AAAA,IAAA;AAAA,EAEV;AAEO,SAAA3F;AACT,GC7FW+F,KAA8B,OACzCjG,GACAC,MACG;AACH,QAAME,IAAO,OAAO,OAAOH,EAAQ,KAAK,EAAE;AAAA,IACxC,CAACG,MAASA,EAAK,QAAQF;AAAA,EAAA;AAGzB,MAAI,CAACE;AACG,UAAA,IAAI,MAAM,eAAe;AAGjC,QAAM+F,IAAgC;AAAA,IACpC,QAAQ,CAAC;AAAA,EAAA,GAGLC,IAAQ;AAAA,IACZX,GAAY,EAAE,SAAAxF,GAAS,cAAAC,GAAc;AAAA,IACrC0F,GAAuB,EAAE,SAAA3F,GAAS,cAAAC,GAAc;AAAA,IAChDQ,GAAW,EAAE,SAAAT,GAAS,cAAAC,GAAc;AAAA,IACpCO,GAAe,EAAE,SAAAR,GAAS,cAAAC,GAAc;AAAA,EAAA;AAGtC,MAAA;AACF,UAAMC,IAAW,MAAMiG,EAAM,OAAO,OAAOvC,GAAUwC,MAC5C,MAAMA,EAAI,MAAMxC,CAAQ,GAC9B,QAAQ,QAAQsC,CAAe,CAAC;AAE5B,WAAAzH,EAAA,IAAI,sBAAsBwB,GAAcC,CAAQ,GAEhD;AAAA,MACL,GAAGA;AAAA,MACH,MAAMA,EAAS,QAAS,MAAMC,EAAK,KAAK;AAAA,IAAA;AAAA,WAEnCkG,GAAG;AACV,UAAA5H,EAAO,MAAM4H,CAAC,GAERA;AAAA,EACR;AACF,GC5Cab,KACX,CAAC,EAAE,SAAAxF,GAAS,SAAAe,QACZ,YAA+B;;AACvB,QAAAuF,IAAQ,OAAO,OAAOtG,EAAQ,KAAK,EAAE,OAAO,CAACG,MAAS,CAACA,EAAK,GAAG;AAE9D,SAAA;AAAA,IACL,UAAUH,EAAQ;AAAA,IAClB,SACEN,IAAAM,EAAQ,MAAM,KAAK,CAAC,EAAE,KAAAyE,EAAU,MAAAA,CAAG,MAAnC,gBAAA/E,EAAsC,SAAS,QAAQ,OAAO,QAAO;AAAA,IACvE,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,YAAY4G,EACT,OAAO,CAACnG,MAAS,CAACA,EAAK,SAAS,SAAS,KAAK,CAAC,EAC/C,IAAI,CAACA,GAAMoG,OAAW;AAAA;AAAA;AAAA;AAAA,MAIrB,IAAI,GAAGA,CAAK,IAAIpG,EAAK,QAAQ;AAAA,MAC7B,MAAM,UAAU,GAAGY,CAAO,GAAGZ,EAAK,GAAG,EAAE;AAAA,MACvC,iBAAiB;AAAA,MACjB,mBAAmB,IAAImG,EAAM;AAAA,MAC7B,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,WAAWnG,EAAK;AAAA,IAAA,EAChB;AAAA,IACJ,OAAOmG,EAAM,IAAI,CAACnG,GAAMoG,OAAW;AAAA,MACjC,IAAI,GAAGA,CAAK,IAAIpG,EAAK,QAAQ;AAAA,MAC7B,MAAM,GAAGY,CAAO,GAAGZ,EAAK,GAAG;AAAA,IAAA,EAC3B;AAAA,EAAA;AAEN,GC1BWqG,KACX,CAAC,EAAE,SAAAxG,EAAQ,MACX,OAAO4D,MAA0C;;AACzC,QAAA6C,IAAgBzG,EAAQ,MAAM;AAAA,IAClC,CAACG,MAASA,EAAK,SAAS,YAAkB,MAAA;AAAA,EAAA;AAG5C,MAAI,CAACsG;AACI,WAAA7C;AAGT,QAAM8C,IAA2B;AAAA,IAC/B,GAAG9C;AAAA,IACH,YAAYA,EAAS,WAClB,OAAO,CAAChC,MAAS,CAACA,EAAK,GAAG,YAAc,EAAA,SAAS,eAAe,CAAC,EACjE,IAAI,CAACA,GAAM+E,GAAGC,OAAW;AAAA,MACxB,GAAGhF;AAAA,MACH,mBAAmB,IAAIgF,EAAM;AAAA,IAAA,EAC7B;AAAA,EAAA,GAIAC,IAAU,MAAMJ,EAAc;AAEhC,MAAA;AAGF,UAAMK,MACHpH,IAHY,IAAImC,EAAO,YAAYgF,CAAO,EAGnC,WAAW,OAAO,MAAzB,gBAAAnH,EAA4B,QAA+B;AAEvD,WAAA;AAAA,MACL,GAAGgH;AAAA,MACH,kBAAkBI,MAAa,sBAAsB,QAAQ;AAAA,IAAA;AAAA,WAExDT,GAAG;AACF,mBAAA,MAAM;AAAA,GAA+CQ,CAAO,GACpE,QAAQ,MAAMR,CAAC,GAERK;AAAA,EACT;AACF,GC3CIK,KAAqB,CAACvH,MAA4B;;AACtD,QAAMC,KAAUC,IAAAF,EACb,mBAAmB,MAAM,MADZ,gBAAAE,EAEZ,cAAc,QACf,KAAK,CAACC,MAASA,EAAK,KAAK,SAAS;AAErC,SAAO,CAAC,EAAEF,KAAWA,EAAQ,KAAK,SAAS;AAC7C,GAEMuH,KAA2B,CAACV,MAChCA,EAAM,OAAO,OAAOW,GAAQC,MAAY;AAKtC,MAFI,CAFY,MAAMD,KAKpB,CAACE,GAAmB;AAAA,IAClB,UAAUD,EAAQ;AAAA,IAClB,KAAKA,EAAQ;AAAA,EAAA,CACd;AAEM,WAAA;AAGH,QAAA/G,IAAO,MAAM+G,EAAQ;AAEvB,SAAC/G,IAEE4G,GAAmB,IAAIlF,EAAO,YAAY1B,CAAI,CAAC,IAFpC;AAGpB,GAAG,QAAQ,QAAQ,EAAI,CAAC,GAEbiH,KACX,CAAC,EAAE,SAAApH,EAAQ,MACX,OAAO4D,MAA0C;AAK/C,MAHEA,EAAS,oBAAoB,gBAC7BA,EAAS,WAAW,MAAM,CAAChC,MAASA,EAAK,oBAAoB,YAAY,GAEjD;AACxB,UAAM0E,IAAQ,MAAMpD,EAA6B,EAAE,SAAAlD,EAAS,CAAA;AAI5D,QAFuB,MAAMgH,GAAyBV,CAAK;AAGlD,aAAA;AAAA,QACL,GAAG1C;AAAA,QACH,YAAYA,EAAS,WAAW,IAAI,CAAChC,OAAU;AAAA,UAC7C,GAAGA;AAAA,UACH,iBAAiB;AAAA,QAAA,EACjB;AAAA,QACF,iBAAiB;AAAA,MAAA;AAAA,EAGvB;AAEO,SAAAgC;AACT,GC7DWyD,IAAwB,CAACC,GAAWC,MAAc;;AACvD,QAAAC,IAAQF,EAAE,MAAM,OAAO,GACvBG,IAAQF,EAAE,MAAM,OAAO;AAE7B,WAASG,IAAI,GAAGC,IAAMH,EAAM,QAAQE,IAAIC,GAAKD;AAC3C,QAAIF,EAAME,CAAC,MAAMD,EAAMC,CAAC;AACtB,cAAIhI,IAAA8H,EAAME,CAAC,MAAP,QAAAhI,EAAU,MAAM,QACX,EAAE8H,EAAME,CAAC,KAAK,MAAM,EAAED,EAAMC,CAAC,KAAK,OAEjCF,EAAME,CAAC,KAAK,IAAI,cAAcD,EAAMC,CAAC,KAAK,EAAE;AAKnD,SAAA;AACT,GCLaE,KACX,CAAC,EAAE,SAAA5H,GAAS,SAAAe,EAAQ,MACpB,OAAO6C,MAA0C;AAC3C,MAAAA,EAAS,IAAY,QAAAA;AAEzB,QAAMiE,IAAqB,CAAC,GAAG7H,EAAQ,KAAK,EAAE;AAAA,IAAK,CAAC,GAAGuH,MACrDF,EAAsB,EAAE,KAAKE,EAAE,GAAG;AAAA,EAAA,GAG9BhG,IAA2C,OAAO;AAAA,IACtDsG;AAAA,EAAA,EACA;AAAA,IACA,CAACC,GAAK3H,MAAS;AACb,YAAM4H,IAAQ5H,EAAK,IAAI,MAAM,GAAG;AAKhC,aAF0B,CAACA,EAAK,OAAO4H,EAAM,SAAS,KAG9CA,EAAA,QAAQ,CAACC,GAAMC,MAAU;AAG7B,YAFuBA,MAAUF,EAAM,SAAS,EAE5B;AAIpB,QAFwBD,EAAI,KAAK,CAAC,EAAE,OAAAtD,QAAYA,MAAUwD,CAAI,KAK5DF,EAAI,KAAK;AAAA,UACP,UAAU,CAAC;AAAA,UACX,MAAM5G,EAAQH,GAAS,UAAUZ,EAAK,GAAG,CAAC,EAAE,QAAQ,OAAO,EAAE;AAAA,UAC7D,MAAMA,EAAK,IAAI,QAAQ,OAAO,EAAE;AAAA,UAChC,OAAO4H,EAAM,CAAC,KAAK;AAAA,QAAA,CACpB;AAAA,MACH,CACD,GAGID;AAAA,IACT;AAAA,IACA,CAAC;AAAA,EAAA;AAGC,SAAAvG,EAAI,WAAW,IAAUqC,IAEtB;AAAA,IACL,GAAGA;AAAA,IACH,KAAK;AAAA,MACH,KAAArC;AAAA,IACF;AAAA,EAAA;AAEJ,GCrDI2G,KAAyB;AAAA,EAC7B,UAAU;AAAA,EACV,OAAO,CAAC;AAAA,EACR,KAAK;AAAA,IACH,KAAK,CAAC;AAAA,EACR;AAAA,EACA,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,YAAY,CAAC;AAAA,EACb,OAAO;AACT,GAEaC,KAA8B,OACzCnI,GACA,EAAE,SAAAe,IAAU,GAAG,IAA0B,OACtC;AACH,QAAMoF,IAAQ;AAAA,IACZX,GAAY,EAAE,SAAAxF,GAAS,SAAAe,GAAS;AAAA,IAChC4C,GAAS,EAAE,SAAA3D,GAAS,SAAAe,GAAS;AAAA,IAC7BqG,GAAkB,EAAE,SAAApH,GAAS,SAAAe,GAAS;AAAA,IACtCyF,GAAc,EAAE,SAAAxG,GAAS,SAAAe,GAAS;AAAA,IAClC6G,GAAuB,EAAE,SAAA5H,GAAS,SAAAe,GAAS;AAAA,EAAA;AAGzC,MAAA;AACF,UAAM6C,IAAW,MAAMuC,EAAM,OAAO,OAAOvC,GAAUwC,MAC5C,MAAMA,EAAI,MAAMxC,CAAQ,GAC9B,QAAQ,QAAQsE,EAAY,CAAC;AAEzB,WAAAzJ,EAAA,IAAI,sBAAsBmF,CAAQ,GAElCA;AAAA,WACAyC,GAAG;AACV,UAAA5H,EAAO,MAAM4H,CAAC,GAERA;AAAA,EACR;AACF,GC/Ca+B,IAAiB,CAAC7C,MAC7BA,EAAI,UAAUA,EAAI,YAAY,GAAG,IAAI,CAAC,KAAKA,GAEhC8C,IAAsB,CAAC9C,MAClCA,EAAI,SAAS,GAAG,IAAIA,EAAI,MAAM,GAAG,EAAE,IAAIA,GCK5B+C,KAAwB,OACnCC,GACAC,MACqB;AACrB,QAAMC,IAAc;AAAA;AAAA;AAAA,4CAGsBD,KAAA,QAAAA,EAAS,mBAAmB,eAAe,eAAe;AAAA,UAC5FA,KAAA,QAAAA,EAAS,mBAAmB,+DAA+D,EAAE;AAAA;AAAA;AAAA,UAG7FD,EACC;AAAA,IACC,CAACG,MACC,aAAaN,EAAeM,CAAG,CAAC,WAAWA,CAAG,iBAAiBC,EAAuBD,CAAG,CAAC;AAAA,IAE7F,KAAK;AAAA,CAAI,CAAC;AAAA;AAAA;AAAA,UAGXH,EAAK,IAAI,CAACG,MAAQ,mBAAmBN,EAAeM,CAAG,CAAC,MAAM,EAAE,KAAK;AAAA,CAAI,CAAC;AAAA;AAAA;AAAA,KAK5EE,IAAiCL,EAAK,IAAI,CAACG,OAAS;AAAA,IACxD,KAAK;AAAA,IACL,UAAUN,EAAeM,CAAG;AAAA,IAC5B,gBAAgBC,EAAuBD,CAAG;AAAA,IAC1C,KAAKA;AAAA,IACL,MAAM,MAAMH,EAAK;AAAA,IACjB,QAAQ,YAAY;AAAA,IACpB,MAAM,YAAY,IAAI,KAAK;AAAA,IAC3B,QAAQ,YAAY;AAAA,EACpB,EAAA;AAYK,SAAA;AAAA,IACL,UAAU;AAAA,IACV,OAAO,CAZiC;AAAA,MACxC,KAAK;AAAA,MACL,UAAU;AAAA,MACV,KAAK;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,YAAYE;AAAA,MACpB,MAAM,YAAY,IAAI,KAAK;AAAA,MAC3B,QAAQ,YAAYA;AAAA,IAAA,GAKH,GAAGG,CAAY;AAAA,IAChC,OAAO,MAAM,QAAQ,QAAQ;AAAA,EAAA;AAEjC,GC3DaC,KAAe,OAAOC,MACjC,IAAI,QAAgB,CAACC,MAAY;AACzB,QAAAC,IAAS,IAAI;AACnB,EAAAA,EAAO,cAAcF,CAAI,GACzBE,EAAO,YAAY,WAAY;AAC7B,UAAMC,IAAaD,EAAO;AAC1B,IAAAD,EAAQE,CAAU;AAAA,EAAA;AAEtB,CAAC,GCDUC,KAAwB,OACnCrC,GACA;AAAA,EACE,UAAAsC;AAAA,EACA,WAAAC;AACF,IAGI,EAAE,UAAU,mBACb;AACH,QAAMC,IAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6CAWqBD,KAAa,KAAK;AAAA;AAAA;AAAA;AAAA;AAyCtD,SAnCkB;AAAA,IACvB,UAAU;AAAA,IACV,OAAO;AAAA,MACL;AAAA,QACE,KAAK;AAAA,QACL,UAAUhB,EAAe,eAAe;AAAA,QACxC,KAAK;AAAA,QACL,MAAM,YAAY,IAAI,KAAK,CAACiB,CAAa,CAAC;AAAA,QAC1C,QAAQ,YAAYA;AAAA,QACpB,QAAQ,YAAY,KAAKA,CAAa;AAAA,QACtC,MAAM;AAAA,MACR;AAAA,MACA;AAAA,QACE,KAAK;AAAA,QACL,UAAUjB,EAAe,SAAS;AAAA,QAClC,KAAK;AAAA,QACL,MAAM,YACA,OAAOvB,KAAY,WAAiB,IAAI,KAAK,CAACA,CAAO,CAAC,IACnDA;AAAA,QAET,QAAQ,YACF,OAAOA,KAAY,WAAiBA,IACjCA,EAAQ;QAEjB,QAAQ,YACF,OAAOA,KAAY,WAAiB,KAAKA,CAAO,IAC7CgC,GAAahC,CAAO;AAAA,QAE7B,MAAM,OAAOA,KAAY,WAAWA,EAAQ,SAASA,EAAQ;AAAA,QAC7D,gBAAgBsC;AAAA,MAClB;AAAA,IACF;AAAA,IACA,OAAO,MAAM,QAAQ,QAAQ;AAAA,EAAA;AAIjC,GCpCaG,KAAyB,OACpCC,GACA,EAAE,cAAAC,GAAc,MAAAxK,EAAK,IAA+C,CAAA,MAC/C;AACrB,MAAIsH,IAAQ,OAAO,OAAOiD,EAAM,KAAK;AAErC,EAAIC,MACFlD,IAAQA,EAAM,QAAQ,KAAK,CAAC,GAAGiB,MAAMF,EAAsB,EAAE,MAAME,EAAE,IAAI,CAAC;AAG5E,QAAMvH,IAAU;AAAA,IACd,UAAUhB,KAAQ;AAAA,IAClB,OAAOsH,EAAM,IAAI,CAACnG,OAAU;AAAA,MAC1B,KAAKA,EAAK;AAAA,MACV,UAAUiI,EAAejI,EAAK,IAAI;AAAA,MAClC,KAAKA,EAAK;AAAA,MACV,MAAM,MAAMA,EAAK,MAAM,MAAM;AAAA,MAC7B,QAAQ,MAAMA,EAAK,MAAM,QAAQ;AAAA,MACjC,QAAQ,MAAMA,EAAK,MAAM,QAAQ;AAAA,MACjC,GAAIA,EAAK,kBAAkB;AAAA,QACzB,QAAQA,EAAK;AAAA,MACf;AAAA;AAAA;AAAA;AAAA,MAIA,MAAMA,EAAK,MAAM;AAAA,IAAA,EACjB;AAAA,IACF,OAAO,MAAM,QAAQ,QAAQ;AAAA,EAAA;AAGxB,SAAA1B,EAAA,IAAI,qBAAqBuB,CAAO,GAEhCA;AACT,GC7BayJ,KAA8B,OACzCC,GACA,EAAE,MAAA1K,EAAK,IAA+C,CAAA,MACjC;AACf,QAAA2K,IAAW,MAAMD,EAAW,iBAE5B1J,IAAmB;AAAA,IACvB,OAAO,MAAM0J,EAAW,MAAM;AAAA,IAC9B,UAAU1K,KAAQ;AAAA,IAClB,OAAO2K,EAAS,IAAI,CAAC/H,OAAkD;AAAA,MACrE,KAAK;AAAA,MACL,UAAUA,EAAK,KAAK;AAAA,MACpB,MAAMA,EAAK,KAAK;AAAA,MAChB,KAAK,GAAGA,EAAK,IAAI,GAAGA,EAAK,KAAK,IAAI;AAAA,MAClC,QAAQ,YACC;AAAA,MAET,MAAM,YACS,MAAOA,EAAK,KAAK,QAAQ;AAAA,MAIxC,QAAQ,aACO,MAAOA,EAAK,KAAK,QAAQ,GAE1B;IACd,EACA;AAAA,EAAA;AAGG,SAAAnD,EAAA,IAAI,qBAAqBuB,CAAO,GAEhCA;AACT,GCnEa4J,KAAmC,OAC9CC,GAMA,EAAE,cAAAL,GAAc,MAAAxK,EAAK,IAA+C,CAAA,MAC/C;AACrB,MAAIsH,IAAQuD;AAEZ,SAAIL,MACFlD,IAAQA,EAAM,QAAQ,KAAK,CAACgB,GAAGC,MAAMF,EAAsBC,EAAE,MAAMC,EAAE,IAAI,CAAC,IAGrE;AAAA,IACL,UAAUvI,KAAQ;AAAA,IAClB,OAAOsH,EAAM,IAAI,CAACnG,OAAU;AAAA,MAC1B,KAAKA,EAAK;AAAA,MACV,UAAUiI,EAAejI,EAAK,IAAI;AAAA,MAClC,KAAKA,EAAK;AAAA,MACV,MAAM,YAAY,IAAI,KAAK,CAAC,MAAMA,EAAK,KAAK,CAAC,CAAC;AAAA,MAC9C,QAAQ,YAAY;AACZ,cAAAxB,IAAO,MAAMwB,EAAK;AACxB,eAAO,OAAO,aAAa;AAAA,UACzB;AAAA,UACA,MAAM,KAAK,IAAI,YAAYxB,CAAI,CAAC;AAAA,QAAA;AAAA,MAEpC;AAAA,MACA,QAAQ,YAEC;AAAA,MAET,MAAMwB,EAAK;AAAA,IAAA,EACX;AAAA,IACF,OAAO,MAAM,QAAQ,QAAQ;AAAA,EAAA;AAEjC,GCvCa2J,KAAY,CAAC;AAAA,EACxB,cAAAC;AACF,IAAgC,OAAO;AAC9B,EAAAtL,EAAA,OAAO,CAAC,CAACsL,CAAY;AAC9B,GC0BaC,KAAsB,CAAC;AAAA,EAClC,YAAAC;AAAA,EACA,mBAAAC;AACF,MAGM;AACE,QAAAC,IAAc,IAAIC,KAClBC,IAAiB,IAAID,KACrBE,IAAe,IAAIF,KACnBG,IAA0D,CAAA,GAE1DC,IAAiBL,EAAY;AAAA,IACjCM,EAAS,CAACC,MAAQ;AACV,YAAAC,IAAeJ,EAASG,CAAG;AAEjC,aAAI,CAACC,KAAgBA,EAAa,WAAW,WAAW,SAC/CC,KAETD,EAAa,KAAK;AAAA,QAChB,GAAGA,EAAa,SAAS;AAAA,QACzB,QAAQ;AAAA,MAAA,CACT,GAEME,EAAKZ,EAAWS,CAAG,CAAC,EAAE;AAAA,QAC3BI,EAAI,CAAC9K,OACH2K,EAAa,KAAK;AAAA,UAChB,GAAGA,EAAa,SAAS;AAAA,UACzB,SAAA3K;AAAA,UACA,QAAQ;AAAA,QAAA,CACT,GAEM,EAAE,KAAA0K,GAAK,cAAAC,IACf;AAAA,QACDI,EAAW,CAACC,OACVL,EAAa,KAAK;AAAA,UAChB,GAAGA,EAAa,SAAS;AAAA,UACzB,QAAQ;AAAA,UACR,OAAAK;AAAA,QAAA,CACD,GAEMJ,EACR;AAAA,MAAA;AAAA,IACH,CACD;AAAA,IACDK,EAAY;AAAA,EAAA,GAGRC,IAAWV,EAAe;AAAA,IAC9BW,EAAU,CAAC,EAAE,cAAAR,GAAc,KAAAD,QAAU;AAC7B,YAAAU,IAAST,EAAa,KAAKG,EAAI,CAAC,EAAE,OAAAO,EAAA,MAAYA,CAAK,CAAC,GACpDC,IAAYhB,EAAa;AAAA,QAC7BQ,EAAI,MAAM,EAAI;AAAA,QACdS,GAAU,EAAK;AAAA,QACfN,EAAY;AAAA,MAAA;AAOd,aALoBG,EAAO;AAAA,QACzBN,EAAI,CAACO,MAAUA,KAAS,CAAC;AAAA,QACzBG,GAAqB;AAAA,MAAA,EAGJ;AAAA,QACjBC,GAAeH,CAAS;AAAA,QACxBH;AAAA,UAAU,CAAC,CAACO,GAAYC,CAAQ,MAC7BD,IAAsBC,IAAsCC,EAAG,IAAI,IAAlCC,GAAM3B,CAAiB,IAA3C4B;AAAA,QAChB;AAAA,QACAC,EAAI,MAAM;;AACR,iBAAOxB,EAASG,CAAG,IAENhL,IAAAiL,EAAA,SAAA,EAAW,YAAX,QAAAjL,EAAoB;AAAA,QAAM,CACxC;AAAA,MAAA;AAAA,IACH,CACD;AAAA,EAAA,GAGGsM,IAAS,CAACtB,MAAgB;AAC9B,QAAIuB,IAAgB;AAEpB,UAAMtB,IACJJ,EAASG,CAAG,KACZ,IAAIwB,GAA8B;AAAA,MAChC,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,OAAO;AAAA,IAAA,CACR;AAEH,IAAA3B,EAASG,CAAG,IAAIC,GAEhBA,EAAa,KAAK;AAAA,MAChB,GAAGA,EAAa,SAAS;AAAA,MACzB,OAAOA,EAAa,SAAS,EAAE,QAAQ;AAAA,IAAA,CACxC;AAED,UAAMwB,IAAU,MAAM;AACpB,MAAIF,MAEYA,IAAA,IAEhBtB,EAAa,KAAK;AAAA,QAChB,GAAGA,EAAa,SAAS;AAAA,QACzB,OAAOA,EAAa,SAAS,EAAE,QAAQ;AAAA,MAAA,CACxC;AAAA,IAAA;AAGH,IAAAR,EAAY,KAAKO,CAAG;AAEpB,UAAM0B,IAAWzB,EAAa;AAAA,MAC5BG,EAAI,CAAC,EAAE,SAAA9K,QAAcA,CAAO;AAAA,MAC5BqM,GAAO,CAACrM,MAAY,CAAC,CAACA,CAAO;AAAA,IAAA,GAGzBsM,IAAS3B,EAAa;AAAA,MAC1BoB,EAAI,CAAC,EAAE,OAAAf,QAAY;AACjB,YAAIA;AACI,gBAAAA;AAAA,MACR,CACD;AAAA,MACDuB,GAAe;AAAA,IAAA;AAGV,WAAAC,EAAMJ,GAAUE,CAAM,EAAE;AAAA,MAC7BG,GAAM;AAAA,MACN3B,EAAI,CAAC9K,OAAa,EAAE,SAAAA,GAAS,SAAAmM,EAAU,EAAA;AAAA,MACvCpB,EAAW,CAACC,MAAU;AACZ,cAAAmB,KAEFnB;AAAA,MAAA,CACP;AAAA,IAAA;AAAA,EACH,GAMI0B,IAAQ,MAAM;AAElB,WAAO,KAAKnC,CAAQ,EAAE,QAAQ,CAACG,MAAQ;AACrC,aAAOH,EAASG,CAAG;AAAA,IAAA,CACpB,GAEDJ,EAAa,KAAK;AAAA,EAAA;AAGd,SAAAkC,EAAAtB,GAAUV,CAAc,EAAE,KAAKmC,GAAUtC,CAAc,CAAC,EAAE,aAEzD;AAAA,IACL,QAAA2B;AAAA,IACA,OAAAU;AAAA,EAAA;AAEJ;AC/JO,MAAME,GAAS;AAAA,EAQpB,YAAY;AAAA,IACV,SAAAC;AAAA,IACA,mBAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAIF;AAbO,SAAA,UAAmB,CAAC/B,MACrB,IAAI,SAAS,OAAOA,CAAK,GAAG,EAAE,QAAQ,KAAK,GAa7C,KAAA,aAAahB,GAAoB+C,CAAI,GAErC,KAAA,oBACHD,MAAsB,CAAC,EAAE,UAAAlJ,EAAe,MAAA,QAAQ,QAAQA,CAAQ,IAC7D,KAAA,UAAUiJ,KAAW,KAAK;AAAA,EACjC;AAAA,EAEU,cAAcnC,GAAa;AAC/B,WAAA,KAAK,oBAAoBA,KAC3B,KAAK,WAAW,SAGlB,KAAK,kBAAkBA,GAEhB,KAAK,WAAW,OAAOA,CAAG;AAAA,EACnC;AAAA,EAEO,cAAc,EAAE,KAAAA,GAAK,SAAA3J,KAA8C;AACxE,UAAMiM,IAAY,KAAK,cAActC,CAAG,EAAE;AAAA,MACxCD,EAAS,CAAC,EAAE,SAAAzK,GAAS,SAAAmM,QACDtB;AAAA,QAChB1C,GAA4BnI,GAAS,EAAE,SAAAe,GAAS;AAAA,MAAA,EAGjC;AAAA,QACfoK;AAAA,UAAU,CAACvH,MACTiH,EAAK,KAAK,kBAAkB,EAAE,UAAAjH,GAAU,SAAA5D,EAAQ,CAAC,CAAC;AAAA,QACpD;AAAA,QACA8K;AAAA,UACE,CAAClH,MACC,IAAI,SAAS,KAAK,UAAUA,CAA2B,GAAG;AAAA,YACxD,QAAQ;AAAA,UAAA,CACT;AAAA,QACL;AAAA,QACAqJ,EAAS,MAAM;AACL,UAAAd;QAAA,CACT;AAAA,MAAA,CAEJ;AAAA,MACDpB,EAAW,CAACC,MACHY,EAAG,KAAK,QAAQZ,CAAK,CAAC,CAC9B;AAAA,IAAA;AAGH,WAAOkC,EAAcF,CAAS;AAAA,EAChC;AAAA,EAEO,cAAc;AAAA,IACnB,KAAAtC;AAAA,IACA,cAAAzK;AAAA,EAAA,GAIC;AACD,UAAM+M,IAAY,KAAK,cAActC,CAAG,EAAE;AAAA,MACxCD,EAAS,CAAC,EAAE,SAAAzK,GAAS,SAAAmM,QACDtB;AAAA,QAChB5E,GAA4BjG,GAASC,CAAY;AAAA,MAAA,EAGlC;AAAA,QACf6K;AAAA,UACE,CAAC5K,MACC,IAAI,SAASA,EAAS,MAAM;AAAA,YAC1B,QAAQ;AAAA,YACR,SAAS;AAAA,cACP,GAAIA,EAAS,OAAO,eAAe;AAAA,gBACjC,gBAAgBA,EAAS,OAAO;AAAA,cAClC;AAAA,YACF;AAAA,UAAA,CACD;AAAA,QACL;AAAA,QACA+M,EAAS,MAAM;AACL,UAAAd;QAAA,CACT;AAAA,MAAA,CAEJ;AAAA,MACDpB,EAAW,CAACC,MACHY,EAAG,KAAK,QAAQZ,CAAK,CAAC,CAC9B;AAAA,IAAA;AAGH,WAAOkC,EAAcF,CAAS;AAAA,EAChC;AACF;AClHO,MAAMG,WAA8BP,GAAS;AAAA,EAOlD,YAAY;AAAA,IACV,YAAAQ;AAAA,IACA,GAAGL;AAAA,EAAA,GAOF;AACD,UAAMA,CAAI,GAEV,KAAK,aAAaK,GAClB,KAAK,qBAAqB,KAAK,mBAAmB,KAAK,IAAI;AAAA,EAC7D;AAAA,EAEA,mBAAmBC,GAAwC;AACrD,QAAA;AACI,YAAAC,IAAU,KAAK,WAAWD,CAAK;AAErC,UAAI,CAACC,EAAS;AAER,YAAAvM,IAAUsH,EAAoBiF,EAAQ,OAAO,GAC7CC,IAAeF,EAAM,QAAQ,IAAI;AAAA,QACrCtM,EAAQ,SAAS;AAAA,MAAI,GAEjB,CAAC2J,IAAM,EAAE,IAAI6C,EAAa,MAAM,GAAG,GACnCtN,IAAe;AAAA,QACnBoI,EAAoBkF,EAAa,UAAU7C,EAAI,SAAS,CAAU,CAAC;AAAA,MAAA;AAGjE,MAAA6C,EAAa,SAAS,WAAW,IAC7BF,EAAA;AAAA,QACJ,KAAK,cAAc,EAAE,KAAA3C,GAAK,SAAS,GAAG3J,CAAO,IAAI2J,CAAG,KAAK;AAAA,MAAA,IAG3D2C,EAAM,YAAY,KAAK,cAAc,EAAE,KAAA3C,GAAK,cAAAzK,EAAc,CAAA,CAAC;AAAA,aAEtDoG,GAAG;AACJ,MAAAgH,EAAA,YAAY,IAAI,SAAS,OAAOhH,CAAC,GAAG,EAAE,QAAQ,IAAK,CAAA,CAAC;AAAA,IAC5D;AAAA,EACF;AACF;"}
1
+ {"version":3,"file":"index.js","sources":["../src/report.ts","../src/generators/resources/hooks/calibreFixHook.ts","../src/generators/resources/hooks/cssFixHook.ts","../src/archives/getArchiveOpfInfo.ts","../src/parsers/nav.ts","../src/parsers/kobo.ts","../src/epub/getSpineItemFilesFromArchive.ts","../src/generators/manifest/hooks/epub.ts","../src/generators/resources/hooks/defaultHook.ts","../src/generators/resources/hooks/selfClosingTagsFixHook.ts","../src/generators/resources/index.ts","../src/generators/manifest/hooks/default.ts","../src/generators/manifest/hooks/comicInfo.ts","../src/generators/manifest/hooks/epubOptimizer.ts","../src/utils/sortByTitleComparator.ts","../src/generators/manifest/hooks/navigationFallback.ts","../src/generators/manifest/index.ts","../src/utils/uri.ts","../src/archives/createArchiveFromUrls.ts","../src/utils/blobToBAse64.ts","../src/archives/createArchiveFromText.ts","../src/archives/createArchiveFromJszip.ts","../src/archives/createArchiveFromLibArchive.ts","../src/archives/createArchiveFromArrayBufferList.ts","../src/configure.ts","../src/archives/archiveLoader.ts","../src/Streamer.ts","../src/ServiceWorkerStreamer.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nlet enabled = false\n\nexport const Report = {\n enable: (enable: boolean) => {\n enabled = enable\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n log: (...data: any[]) => {\n if (enabled) {\n // eslint-disable-next-line no-console\n console.log(`[prose-reader-streamer]`, ...data)\n }\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n warn: (...data: any[]) => {\n if (enabled) {\n // eslint-disable-next-line no-console\n console.warn(`[prose-reader-streamer]`, ...data)\n }\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error: (...data: any[]) => {\n // eslint-disable-next-line no-console\n console.error(...data)\n },\n time: (label?: string | undefined) => {\n if (enabled) {\n // eslint-disable-next-line no-console\n console.time(`[prose-reader-streamer] [metric] ${label}`)\n }\n },\n timeEnd: (label?: string | undefined) => {\n if (enabled) {\n // eslint-disable-next-line no-console\n console.timeEnd(`[prose-reader-streamer] [metric] ${label}`)\n }\n },\n metric: (\n performanceEntry: { name: string; duration: number },\n targetDuration = Infinity,\n ) => {\n const duration =\n typeof performanceEntry === `number`\n ? performanceEntry\n : performanceEntry.duration\n if (enabled) {\n if (performanceEntry.duration <= targetDuration) {\n // eslint-disable-next-line no-console\n console.log(\n `[prose-reader-streamer] [metric] `,\n `${performanceEntry.name} took ${duration}ms`,\n )\n } else {\n // eslint-disable-next-line no-console\n console.warn(\n `[prose-reader-streamer] [metric] `,\n `${performanceEntry.name} took ${performanceEntry.duration}ms which is above the ${targetDuration}ms target for this function`,\n )\n }\n }\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n measurePerformance: <F extends (...args: any[]) => any>(\n name: string,\n targetDuration = 10,\n functionToMeasure: F,\n ) => {\n return (...args: Parameters<F>): ReturnType<F> => {\n const t0 = performance.now()\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const response = functionToMeasure(...(args as any))\n\n if (response && response.then) {\n return response.then((res: any) => {\n const t1 = performance.now()\n Report.metric({ name, duration: t1 - t0 }, targetDuration)\n return res\n })\n }\n\n const t1 = performance.now()\n\n Report.metric({ name, duration: t1 - t0 }, targetDuration)\n\n return response\n }\n },\n}\n","import { XmlDocument } from \"xmldoc\"\nimport { Archive } from \"../../../archives/types\"\nimport { HookResource } from \"./types\"\n\nconst hasCalibreCoverMeta = (doc: XmlDocument) => {\n const metaElm = doc\n .descendantWithPath(\"head\")\n ?.childrenNamed(\"meta\")\n .find((node) => node.attr.name === \"calibre:cover\")\n\n return !!(metaElm && metaElm.attr.name === \"calibre:cover\")\n}\n\nconst getBuggyCoverSvg = (doc: XmlDocument) => {\n return doc\n .descendantWithPath(\"body\")\n ?.descendantWithPath(\"div\")\n ?.childrenNamed(\"svg\")\n ?.find(\n (node) =>\n node.attr.width === \"100%\" && node.attr.preserveAspectRatio === \"none\",\n )\n}\n\nconst fixBuggyCover =\n ({ archive, resourcePath }: { archive: Archive; resourcePath: string }) =>\n async (resource: HookResource): Promise<HookResource> => {\n const file = Object.values(archive.files).find(\n (file) => file.uri === resourcePath,\n )\n\n if (file?.basename.endsWith(`.xhtml`)) {\n const bodyToParse = resource.body ?? (await file.string())\n\n const opfXmlDoc = new XmlDocument(bodyToParse)\n\n if (hasCalibreCoverMeta(opfXmlDoc)) {\n const buggySvg = getBuggyCoverSvg(opfXmlDoc)\n\n if (buggySvg) {\n delete buggySvg.attr.preserveAspectRatio\n }\n\n return {\n ...resource,\n body: opfXmlDoc?.toString(),\n }\n }\n }\n\n return resource\n }\n\nexport const calibreFixHook =\n ({ archive, resourcePath }: { archive: Archive; resourcePath: string }) =>\n async (resource: HookResource): Promise<HookResource> => {\n return fixBuggyCover({ archive, resourcePath })(resource)\n }\n","import { Archive } from \"../../../archives/types\"\nimport { HookResource } from \"./types\"\n\nexport const cssFixHook =\n ({ archive, resourcePath }: { archive: Archive; resourcePath: string }) =>\n async (resource: HookResource): Promise<HookResource> => {\n const file = Object.values(archive.files).find(\n (file) => file.uri === resourcePath,\n )\n\n if (file?.basename.endsWith(`.css`)) {\n const bodyToParse = resource.body ?? (await file.string())\n\n /**\n * Fix the potentially invalid writing mode present on some vertical book.\n * This has the benefit of making it compatible with firefox as well.\n */\n const newBody = bodyToParse.replaceAll(\n `-webkit-writing-mode`,\n `writing-mode`,\n )\n\n return {\n ...resource,\n body: newBody,\n }\n }\n\n return resource\n }\n","import { Archive } from \"./types\"\n\nexport const getArchiveOpfInfo = (archive: Archive) => {\n const filesAsArray = Object.values(archive.files).filter((file) => !file.dir)\n const file = filesAsArray.find((file) => file.uri.endsWith(`.opf`))\n\n return {\n data: file,\n basePath: file?.uri.substring(0, file.uri.lastIndexOf(`/`)) || ``,\n }\n}\n","import xmldoc, { XmlElement } from \"xmldoc\"\nimport type { Manifest } from \"@prose-reader/shared\"\nimport { Archive, getArchiveOpfInfo } from \"..\"\nimport { urlJoin } from \"@prose-reader/shared\"\n\ntype Toc = NonNullable<Manifest[`nav`]>[`toc`]\ntype TocItem = NonNullable<Manifest[`nav`]>[`toc`][number]\n\nconst extractNavChapter = (\n li: XmlElement,\n { opfBasePath, baseUrl }: { opfBasePath: string; baseUrl: string },\n) => {\n const chp: TocItem = {\n contents: [],\n path: ``,\n href: ``,\n title: ``,\n }\n let contentNode = li.childNamed(`span`) || li.childNamed(`a`)\n chp.title = contentNode?.attr.title || contentNode?.val.trim() || chp.title\n let node = contentNode?.name\n if (node !== `a`) {\n contentNode = li.descendantWithPath(`${node}.a`)\n if (contentNode) {\n node = contentNode.name.toLowerCase()\n }\n }\n if (node === `a` && contentNode?.attr.href) {\n chp.path = urlJoin(opfBasePath, contentNode.attr.href)\n chp.href = urlJoin(baseUrl, opfBasePath, contentNode.attr.href)\n }\n const sublistNode = li.childNamed(`ol`)\n if (sublistNode) {\n const children = sublistNode.childrenNamed(`li`)\n if (children && children.length > 0) {\n chp.contents = children.map((child) =>\n extractNavChapter(child, { opfBasePath, baseUrl }),\n )\n }\n }\n\n return chp\n}\n\nconst buildTOCFromNav = (\n doc: xmldoc.XmlDocument,\n { opfBasePath, baseUrl }: { opfBasePath: string; baseUrl: string },\n) => {\n const toc: Toc = []\n\n let navDataChildren\n if (doc.descendantWithPath(`body.nav.ol`)) {\n navDataChildren = doc.descendantWithPath(`body.nav.ol`)?.children\n } else if (doc.descendantWithPath(`body.section.nav.ol`)) {\n navDataChildren = doc.descendantWithPath(`body.section.nav.ol`)?.children\n }\n\n if (navDataChildren && navDataChildren.length > 0) {\n navDataChildren\n .filter((li) => (li as XmlElement).name === `li`)\n .forEach((li) =>\n toc.push(extractNavChapter(li as XmlElement, { opfBasePath, baseUrl })),\n )\n }\n\n return toc\n}\n\nconst parseTocFromNavPath = async (\n opfXmlDoc: xmldoc.XmlDocument,\n archive: Archive,\n { opfBasePath, baseUrl }: { opfBasePath: string; baseUrl: string },\n) => {\n // Try to detect if there is a nav item\n const navItem = opfXmlDoc\n .childNamed(`manifest`)\n ?.childrenNamed(`item`)\n .find((child) => child.attr.properties === `nav`)\n\n if (navItem) {\n const tocFile = Object.values(archive.files).find((item) =>\n item.uri.endsWith(navItem.attr.href || ``),\n )\n if (tocFile) {\n const doc = new xmldoc.XmlDocument(await tocFile.string())\n return buildTOCFromNav(doc, { opfBasePath, baseUrl })\n }\n }\n}\n\nconst mapNcxChapter = (\n point: xmldoc.XmlElement,\n {\n opfBasePath,\n baseUrl,\n prefix,\n }: { opfBasePath: string; baseUrl: string; prefix: string },\n) => {\n const src = point?.childNamed(`${prefix}content`)?.attr.src || ``\n\n const out: TocItem = {\n title:\n point?.descendantWithPath(`${prefix}navLabel.${prefix}text`)?.val || ``,\n path: urlJoin(opfBasePath, src),\n href: urlJoin(baseUrl, opfBasePath, src),\n contents: [],\n }\n const children = point.childrenNamed(`${prefix}navPoint`)\n if (children && children.length > 0) {\n out.contents = children.map((pt) =>\n mapNcxChapter(pt, { opfBasePath, baseUrl, prefix }),\n )\n }\n\n return out\n}\n\nconst buildTOCFromNCX = (\n ncxData: xmldoc.XmlDocument,\n { opfBasePath, baseUrl }: { opfBasePath: string; baseUrl: string },\n) => {\n const toc: NonNullable<Manifest[`nav`]>[`toc`] = []\n\n const rootTagName = ncxData.name\n let prefix = ``\n if (rootTagName.indexOf(`:`) !== -1) {\n prefix = rootTagName.split(`:`)[0] + `:`\n }\n\n ncxData\n .childNamed(`${prefix}navMap`)\n ?.childrenNamed(`${prefix}navPoint`)\n .forEach((point) =>\n toc.push(mapNcxChapter(point, { opfBasePath, baseUrl, prefix })),\n )\n\n return toc\n}\n\nconst parseTocFromNcx = async ({\n opfData,\n opfBasePath,\n baseUrl,\n archive,\n}: {\n opfData: xmldoc.XmlDocument\n opfBasePath: string\n archive: Archive\n baseUrl: string\n}) => {\n const spine = opfData.childNamed(`spine`)\n const ncxId = spine && spine.attr.toc\n\n if (ncxId) {\n const ncxItem = opfData\n .childNamed(`manifest`)\n ?.childrenNamed(`item`)\n .find((item) => item.attr.id === ncxId)\n\n if (ncxItem) {\n const ncxPath = `${opfBasePath}${opfBasePath === `` ? `` : `/`}${ncxItem.attr.href}`\n\n const file = Object.values(archive.files).find((item) =>\n item.uri.endsWith(ncxPath),\n )\n\n if (file) {\n const ncxData = new xmldoc.XmlDocument(await file.string())\n\n return buildTOCFromNCX(ncxData, { opfBasePath, baseUrl })\n }\n }\n }\n}\n\nexport const parseToc = async (\n opfXmlDoc: xmldoc.XmlDocument,\n archive: Archive,\n { baseUrl }: { baseUrl: string },\n) => {\n const { basePath: opfBasePath } = getArchiveOpfInfo(archive) || {}\n\n const tocFromNcx = await parseTocFromNcx({\n opfData: opfXmlDoc,\n opfBasePath,\n archive,\n baseUrl,\n })\n\n if (tocFromNcx) {\n return tocFromNcx\n }\n\n return await parseTocFromNavPath(opfXmlDoc, archive, { opfBasePath, baseUrl })\n}\n","import xmldoc from \"xmldoc\"\nimport { Archive } from \"..\"\n\ntype KoboInformation = {\n renditionLayout?: `reflowable` | `pre-paginated` | undefined\n}\n\nexport const extractKoboInformationFromArchive = async (archive: Archive) => {\n const koboInformation: KoboInformation = {\n renditionLayout: undefined,\n }\n\n await Promise.all(\n archive.files.map(async (file) => {\n if (file.uri.endsWith(`com.kobobooks.display-options.xml`)) {\n const opfXmlDoc = new xmldoc.XmlDocument(await file.string())\n const optionElement = opfXmlDoc\n .childNamed(`platform`)\n ?.childNamed(`option`)\n if (\n optionElement?.attr?.name === `fixed-layout` &&\n optionElement.val === `true`\n ) {\n koboInformation.renditionLayout = `pre-paginated`\n }\n }\n }),\n )\n\n return koboInformation\n}\n","import xmldoc from \"xmldoc\"\nimport { getArchiveOpfInfo } from \"../archives/getArchiveOpfInfo\"\nimport { Archive } from \"../archives/types\"\n\nexport const getSpineItemFilesFromArchive = async ({\n archive,\n}: {\n archive: Archive\n}) => {\n const { data: opsFile, basePath: opfBasePath } =\n getArchiveOpfInfo(archive) || {}\n\n const data = await opsFile?.string()\n\n if (!data) return []\n\n const _opfXmlDoc = new xmldoc.XmlDocument(data)\n\n const manifestElm = _opfXmlDoc.childNamed(`manifest`)\n const spineElm = _opfXmlDoc.childNamed(`spine`)\n\n const spineItemIds = spineElm\n ?.childrenNamed(`itemref`)\n .map((item) => item.attr.idref) as string[]\n const manifestItemsFromSpine =\n manifestElm\n ?.childrenNamed(`item`)\n .filter((item) => spineItemIds.includes(item.attr.id || ``)) || []\n\n const archiveSpineItems = archive.files.filter((file) => {\n return manifestItemsFromSpine.find((item) => {\n if (!opfBasePath) return `${item.attr.href}` === file.uri\n return `${opfBasePath}/${item.attr.href}` === file.uri\n })\n })\n\n return archiveSpineItems\n}\n","import xmldoc from \"xmldoc\"\nimport { parseToc } from \"../../../parsers/nav\"\nimport type { Manifest } from \"@prose-reader/shared\"\nimport { extractKoboInformationFromArchive } from \"../../../parsers/kobo\"\nimport { Report } from \"../../../report\"\nimport { Archive } from \"../../../archives/types\"\nimport { getArchiveOpfInfo } from \"../../../archives/getArchiveOpfInfo\"\nimport { getSpineItemFilesFromArchive } from \"../../../epub/getSpineItemFilesFromArchive\"\n\ntype SpineItemProperties =\n | `rendition:layout-reflowable`\n | `page-spread-left`\n | `page-spread-right`\n\nexport const getItemsFromDoc = (doc: xmldoc.XmlDocument) => {\n const manifestElm = doc.childNamed(`manifest`)\n\n return (\n manifestElm?.childrenNamed(`item`)?.map((el) => ({\n href: el.attr.href || ``,\n id: el.attr.id || ``,\n mediaType: el.attr[`media-type`],\n })) || []\n )\n}\n\nexport const epubHook =\n ({ archive, baseUrl }: { archive: Archive; baseUrl: string }) =>\n async (manifest: Manifest): Promise<Manifest> => {\n const { data: opsFile, basePath: opfBasePath } =\n getArchiveOpfInfo(archive) || {}\n const koboInformation = await extractKoboInformationFromArchive(archive)\n\n if (!opsFile) {\n return manifest\n }\n\n const data = await opsFile.string()\n\n Report.log(data, koboInformation)\n\n const opfXmlDoc = new xmldoc.XmlDocument(data)\n\n const toc = (await parseToc(opfXmlDoc, archive, { baseUrl })) || []\n\n const metadataElm = opfXmlDoc.childNamed(`metadata`)\n const manifestElm = opfXmlDoc.childNamed(`manifest`)\n const spineElm = opfXmlDoc.childNamed(`spine`)\n const guideElm = opfXmlDoc.childNamed(`guide`)\n const titleElm = metadataElm?.childNamed(`dc:title`)\n const metaElmChildren = metadataElm?.childrenNamed(`meta`) || []\n const metaElmWithRendition = metaElmChildren.find(\n (meta) => meta.attr.property === `rendition:layout`,\n )\n const metaElmWithRenditionFlow = metaElmChildren.find(\n (meta) => meta.attr.property === `rendition:flow`,\n )\n const metaElmWithRenditionSpread = metaElmChildren.find(\n (meta) => meta.attr.property === `rendition:spread`,\n )\n\n const publisherRenditionLayout = metaElmWithRendition?.val as\n | `reflowable`\n | `pre-paginated`\n | undefined\n const publisherRenditionFlow = metaElmWithRenditionFlow?.val as\n | `scrolled-continuous`\n | `scrolled-doc`\n | `paginated`\n | `auto`\n | undefined\n const renditionSpread = metaElmWithRenditionSpread?.val as\n | `auto`\n | undefined\n\n const title =\n titleElm?.val || archive.files.find(({ dir }) => dir)?.basename || ``\n const pageProgressionDirection = spineElm?.attr[\n `page-progression-direction`\n ] as `ltr` | `rtl` | undefined\n\n const archiveSpineItems = await getSpineItemFilesFromArchive({ archive })\n\n const totalSize = archiveSpineItems.reduce(\n (size, file) => file.size + size,\n 0,\n )\n\n return {\n filename: archive.filename,\n nav: {\n toc,\n },\n renditionLayout:\n publisherRenditionLayout ||\n koboInformation.renditionLayout ||\n `reflowable`,\n renditionFlow: publisherRenditionFlow || `auto`,\n renditionSpread,\n title,\n readingDirection: pageProgressionDirection || `ltr`,\n spineItems:\n spineElm?.childrenNamed(`itemref`).map((itemrefElm) => {\n const manifestItem = manifestElm\n ?.childrenNamed(`item`)\n .find((item) => item.attr.id === itemrefElm?.attr.idref)\n const href = manifestItem?.attr.href || ``\n const properties = (itemrefElm?.attr.properties?.split(` `) ||\n []) as SpineItemProperties[]\n const itemSize =\n archive.files.find((file) => file.uri.endsWith(href))?.size || 0\n\n // we use base url or nothing (and stay relative)\n const hrefBaseUri = baseUrl ?? \"\"\n\n return {\n id: manifestItem?.attr.id || ``,\n href: manifestItem?.attr.href?.startsWith(`https://`)\n ? manifestItem?.attr.href\n : opfBasePath\n ? `${hrefBaseUri}${opfBasePath}/${manifestItem?.attr.href}`\n : `${hrefBaseUri}${manifestItem?.attr.href}`,\n renditionLayout: publisherRenditionLayout || `reflowable`,\n ...(properties.find(\n (property) => property === `rendition:layout-reflowable`,\n ) && {\n renditionLayout: `reflowable`,\n }),\n progressionWeight: itemSize / totalSize,\n pageSpreadLeft:\n properties.some((property) => property === `page-spread-left`) ||\n undefined,\n pageSpreadRight:\n properties.some((property) => property === `page-spread-right`) ||\n undefined,\n // size: itemSize\n mediaType: manifestItem?.attr[`media-type`],\n }\n }) || [],\n items: getItemsFromDoc(opfXmlDoc),\n guide: guideElm?.childrenNamed(`reference`).map((elm) => {\n return {\n href: elm.attr.href || ``,\n title: elm.attr.title || ``,\n type: elm.attr.type as NonNullable<Manifest[`guide`]>[number][`type`],\n }\n }),\n }\n }\n","import { getArchiveOpfInfo } from \"../../../archives/getArchiveOpfInfo\"\nimport { Archive } from \"../../../archives/types\"\nimport { getItemsFromDoc } from \"../../manifest/hooks/epub\"\nimport xmldoc from \"xmldoc\"\nimport { HookResource } from \"./types\"\n\nconst getMetadata = async (archive: Archive, resourcePath: string) => {\n const opfInfo = getArchiveOpfInfo(archive)\n const data = await opfInfo.data?.string()\n\n if (data) {\n const opfXmlDoc = new xmldoc.XmlDocument(data)\n const items = getItemsFromDoc(opfXmlDoc)\n\n return {\n mediaType: items.find((item) => resourcePath.endsWith(item.href))\n ?.mediaType,\n }\n }\n\n return {\n mediaType: getContentTypeFromExtension(resourcePath),\n }\n}\n\nconst getContentTypeFromExtension = (uri: string) => {\n if (uri.endsWith(`.css`)) {\n return `text/css; charset=UTF-8`\n }\n if (uri.endsWith(`.jpg`)) {\n return `image/jpg`\n }\n if (uri.endsWith(`.xhtml`)) {\n return `application/xhtml+xml`\n }\n if (uri.endsWith(`.mp4`)) {\n return `video/mp4`\n }\n if (uri.endsWith(`.svg`)) {\n return `image/svg+xml`\n }\n}\n\nexport const defaultHook =\n ({ archive, resourcePath }: { archive: Archive; resourcePath: string }) =>\n async (resource: HookResource): Promise<HookResource> => {\n const file = Object.values(archive.files).find(\n (file) => file.uri === resourcePath,\n )\n\n if (!file) return resource\n\n // if (file.stream) {\n // const stream = file.stream()\n\n // console.log(file, stream)\n // stream.on(`data`, data => {\n // console.log(`data`, data)\n // })\n // stream.on(`error`, data => {\n // console.error(`error`, data)\n // })\n // stream.on(`end`, () => {\n // console.log(`end`)\n // })\n\n // }\n\n // const stream = file.stream!()\n\n // const readableStream = new ReadableStream({\n // start(controller) {\n // function push() {\n // stream.on(`data`, data => {\n // controller.enqueue(data)\n // })\n // stream.on(`error`, data => {\n // console.error(`error`, data)\n // })\n // stream.on(`end`, () => {\n // controller.close()\n // })\n\n // stream.resume()\n // }\n\n // push();\n // }\n // })\n\n const metadata = await getMetadata(archive, resourcePath)\n\n return {\n ...resource,\n params: {\n ...resource.params,\n ...(file?.encodingFormat && {\n contentType: file.encodingFormat,\n }),\n ...(metadata.mediaType && {\n contentType: metadata.mediaType,\n }),\n },\n }\n }\n","import { Archive } from \"../../../archives/types\"\nimport { HookResource } from \"./types\"\n\nconst invalidSelfClosingTags = [\n \"div\",\n \"span\",\n \"p\",\n \"a\",\n \"li\",\n \"ul\",\n \"ol\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"table\",\n \"tr\",\n \"td\",\n \"th\",\n \"thead\",\n \"tbody\",\n \"tfoot\",\n \"section\",\n \"article\",\n \"header\",\n \"footer\",\n \"nav\",\n \"aside\",\n \"main\",\n \"figure\",\n \"figcaption\",\n \"blockquote\",\n \"pre\",\n \"code\",\n \"form\",\n \"textarea\",\n \"select\",\n \"option\",\n \"button\",\n \"label\",\n \"fieldset\",\n \"legend\",\n \"caption\",\n \"dl\",\n \"dt\",\n \"dd\",\n \"iframe\",\n \"video\",\n \"audio\",\n \"canvas\",\n \"script\",\n \"style\",\n]\n\n/**\n * Some books uses xhtml files but also includes wrong self closin tags. This happens\n * a lot with kobo epub which have a lot of self closing <script ... />. This breaks on some\n * browser such as webkit. We use a regex to replace and fix them. There\n * is a first lighter regex which check if any such tag exist in the first place before running\n * the full replace regex empty.\n */\nexport const selfClosingTagsFixHook =\n ({ archive, resourcePath }: { archive: Archive; resourcePath: string }) =>\n async (resource: HookResource): Promise<HookResource> => {\n const file = Object.values(archive.files).find(\n (file) => file.uri === resourcePath,\n )\n\n if (file?.basename.endsWith(`.xhtml`)) {\n const bodyToParse = resource.body ?? (await file.string())\n\n const tagCheckPattern = new RegExp(\n `<(${invalidSelfClosingTags.join(\"|\")})[\\\\s/>]`,\n \"i\",\n )\n if (!tagCheckPattern.test(bodyToParse)) {\n return resource\n }\n\n const tagPattern = new RegExp(\n `<(${invalidSelfClosingTags.join(\"|\")})(\\\\s[^>]*)?\\\\s*/>`,\n \"gi\",\n )\n\n const fixedBody = bodyToParse.replace(\n tagPattern,\n (match, tagName, attributes = \"\") => {\n // Convert to an opening and closing tag\n return `<${tagName} ${attributes.trim()}></${tagName}>`\n },\n )\n\n return {\n ...resource,\n body: fixedBody,\n }\n }\n\n return resource\n }\n","import { Archive } from \"../..\"\nimport { Report } from \"../../report\"\nimport { calibreFixHook } from \"./hooks/calibreFixHook\"\nimport { cssFixHook } from \"./hooks/cssFixHook\"\nimport { defaultHook } from \"./hooks/defaultHook\"\nimport { HookResource } from \"./hooks/types\"\nimport { selfClosingTagsFixHook } from \"./hooks/selfClosingTagsFixHook\"\n\nexport const generateResourceFromArchive = async (\n archive: Archive,\n resourcePath: string,\n) => {\n const file = Object.values(archive.files).find(\n (file) => file.uri === resourcePath,\n )\n\n if (!file) {\n throw new Error(`no file found`)\n }\n\n const defaultResource: HookResource = {\n params: {},\n }\n\n const hooks = [\n defaultHook({ archive, resourcePath }),\n selfClosingTagsFixHook({ archive, resourcePath }),\n cssFixHook({ archive, resourcePath }),\n calibreFixHook({ archive, resourcePath }),\n ]\n\n try {\n const resource = await hooks.reduce(async (manifest, gen) => {\n return await gen(await manifest)\n }, Promise.resolve(defaultResource))\n\n Report.log(\"Generated resource\", resourcePath, resource)\n\n return {\n ...resource,\n body: resource.body ?? (await file.blob()),\n }\n } catch (e) {\n Report.error(e)\n\n throw e\n }\n}\n","import { Manifest } from \"@prose-reader/shared\"\nimport { Archive } from \"../../../archives/types\"\n\nexport const defaultHook =\n ({ archive, baseUrl }: { archive: Archive; baseUrl: string }) =>\n async (): Promise<Manifest> => {\n const files = Object.values(archive.files).filter((file) => !file.dir)\n\n return {\n filename: archive.filename,\n title:\n archive.files.find(({ dir }) => dir)?.basename.replace(/\\/$/, ``) || ``,\n renditionLayout: `pre-paginated`,\n renditionSpread: `auto`,\n readingDirection: `ltr`,\n spineItems: files\n .filter((file) => !file.basename.endsWith(`.db`))\n .map((file, index) => ({\n // some books such as cbz can have same basename inside different sub folder\n // we need to make sure to have unique index\n // /chap01/01.png, /chap02/01.png, etc\n id: `${index}.${file.basename}`,\n href: encodeURI(`${baseUrl}${file.uri}`),\n renditionLayout: `pre-paginated`,\n progressionWeight: 1 / files.length,\n pageSpreadLeft: undefined,\n pageSpreadRight: undefined,\n mediaType: file.encodingFormat,\n })),\n items: files.map((file, index) => ({\n id: `${index}.${file.basename}`,\n href: `${baseUrl}${file.uri}`,\n })),\n }\n }\n","import { Manifest } from \"@prose-reader/shared\"\nimport xmldoc from \"xmldoc\"\nimport { Archive } from \"../../../archives/types\"\n\n/**\n * Handle archive which contains ComicInfo.xml. This is a meta file\n * used to define cbz, etc. I believe it comes from some sites or apps.\n */\nexport const comicInfoHook =\n ({ archive }: { archive: Archive; baseUrl: string }) =>\n async (manifest: Manifest): Promise<Manifest> => {\n const comicInfoFile = archive.files.find(\n (file) => file.basename.toLowerCase() === `comicinfo.xml`,\n )\n\n if (!comicInfoFile) {\n return manifest\n }\n\n const manifestWithoutComicInfo = {\n ...manifest,\n spineItems: manifest.spineItems\n .filter((item) => !item.id.toLowerCase().endsWith(`comicinfo.xml`))\n .map((item, _, items) => ({\n ...item,\n progressionWeight: 1 / items.length,\n })),\n }\n\n // @todo handle more meta\n const content = await comicInfoFile.string()\n\n try {\n const xmlDoc = new xmldoc.XmlDocument(content)\n\n const mangaVal =\n (xmlDoc.childNamed(`Manga`)?.val as `YesAndRightToLeft`) || `unknown`\n\n return {\n ...manifestWithoutComicInfo,\n readingDirection: mangaVal === `YesAndRightToLeft` ? `rtl` : `ltr`,\n }\n } catch (e) {\n console.error(\"Unable to parse comicinfo.xml for content\\n\", content)\n console.error(e)\n\n return manifestWithoutComicInfo\n }\n }\n","import { isXmlBasedMimeType, Manifest } from \"@prose-reader/shared\"\nimport xmldoc from \"xmldoc\"\nimport { Archive } from \"../../../archives/types\"\nimport { getSpineItemFilesFromArchive } from \"../../../epub/getSpineItemFilesFromArchive\"\n\nconst hasDocMetaViewport = (doc: xmldoc.XmlDocument) => {\n const metaElm = doc\n .descendantWithPath(\"head\")\n ?.childrenNamed(\"meta\")\n .find((node) => node.attr.name === \"viewport\")\n\n return !!(metaElm && metaElm.attr.name === \"viewport\")\n}\n\nconst allFilesHaveViewportMeta = (files: Archive[\"files\"]) =>\n files.reduce(async (result, current) => {\n const _result = await result\n\n if (!_result) return false\n\n if (\n !isXmlBasedMimeType({\n mimeType: current.encodingFormat,\n uri: current.uri,\n })\n ) {\n return false\n }\n\n const file = await current.string()\n\n if (!file) return false\n\n return hasDocMetaViewport(new xmldoc.XmlDocument(file))\n }, Promise.resolve(true))\n\nexport const epubOptimizerHook =\n ({ archive }: { archive: Archive; baseUrl: string }) =>\n async (manifest: Manifest): Promise<Manifest> => {\n const bookIsFullReflowable =\n manifest.renditionLayout === \"reflowable\" &&\n manifest.spineItems.every((item) => item.renditionLayout === \"reflowable\")\n\n if (bookIsFullReflowable) {\n const files = await getSpineItemFilesFromArchive({ archive })\n\n const hasAllViewport = await allFilesHaveViewportMeta(files)\n\n if (hasAllViewport) {\n return {\n ...manifest,\n spineItems: manifest.spineItems.map((item) => ({\n ...item,\n renditionLayout: \"pre-paginated\",\n })),\n renditionLayout: \"pre-paginated\",\n }\n }\n }\n\n return manifest\n }\n","export const sortByTitleComparator = (a: string, b: string) => {\n const alist = a.split(/(\\d+)/)\n const blist = b.split(/(\\d+)/)\n\n for (let i = 0, len = alist.length; i < len; i++) {\n if (alist[i] !== blist[i]) {\n if (alist[i]?.match(/\\d/)) {\n return +(alist[i] || ``) - +(blist[i] || ``)\n } else {\n return (alist[i] || ``).localeCompare(blist[i] || ``)\n }\n }\n }\n\n return 1\n}\n","import { Manifest, TocItem, urlJoin } from \"@prose-reader/shared\"\nimport { Archive } from \"../../../archives/types\"\nimport { sortByTitleComparator } from \"../../../utils/sortByTitleComparator\"\n\n/**\n * In case no navigation was generated prior to this hook, we will try\n * to generate something based on the structure of the archive.\n *\n * We use folders as chapters.\n */\nexport const navigationFallbackHook =\n ({ archive, baseUrl }: { archive: Archive; baseUrl: string }) =>\n async (manifest: Manifest): Promise<Manifest> => {\n if (manifest.nav) return manifest\n\n const filesSortedByAlpha = [...archive.files].sort((a, b) =>\n sortByTitleComparator(a.uri, b.uri),\n )\n\n const filesSortedAlpha = Object.values(filesSortedByAlpha)\n\n const combineWith = (\n toc: TocItem[],\n folder: string,\n subFolders: string[],\n href: string,\n path: string,\n ): TocItem[] => {\n const foundEntry = toc.find((entry) => entry.title === folder)\n const [nextFolderCursor, ...nextSubFolders] = subFolders\n\n if (foundEntry) {\n if (nextFolderCursor) {\n return [\n ...toc.filter((entry) => entry != foundEntry),\n {\n ...foundEntry,\n contents: [\n ...foundEntry.contents,\n ...combineWith(\n foundEntry.contents,\n nextFolderCursor,\n nextSubFolders,\n href,\n path,\n ),\n ],\n } satisfies TocItem,\n ]\n }\n\n // we have an exact match for current folder\n // try to see if the path is better than previously registered\n const previousRegisteredPathWasLonger =\n foundEntry.path.split(\"/\").length > path.split(\"/\").length\n\n if (previousRegisteredPathWasLonger) {\n return [\n ...toc.filter((entry) => entry != foundEntry),\n {\n ...foundEntry,\n path,\n href,\n } satisfies TocItem,\n ]\n }\n\n return toc\n }\n\n if (nextFolderCursor) {\n return [\n ...toc,\n {\n contents: combineWith(\n [],\n nextFolderCursor,\n nextSubFolders,\n href,\n path,\n ),\n href,\n path,\n title: folder,\n },\n ]\n }\n\n return [\n ...toc,\n {\n contents: [],\n href,\n path,\n title: folder,\n },\n ]\n }\n\n const toc: NonNullable<Manifest[\"nav\"]>[\"toc\"] = filesSortedAlpha.reduce(\n (acc, file) => {\n if (file.dir) return acc\n\n const parts = file.uri.split(\"/\")\n\n // we have a file that is\n const folders = parts.slice(0, -1)\n const [firstFolder, ...restFolders] = folders\n\n if (firstFolder) {\n const href = urlJoin(baseUrl, encodeURI(file.uri)).replace(/\\/$/, \"\")\n const path = file.uri.replace(/\\/$/, \"\")\n\n return combineWith(acc, firstFolder, restFolders, href, path)\n }\n\n return acc\n },\n [] as NonNullable<Manifest[\"nav\"]>[\"toc\"],\n )\n\n if (toc.length === 0) return manifest\n\n return {\n ...manifest,\n nav: {\n toc,\n },\n }\n }\n","import type { Manifest } from \"@prose-reader/shared\"\nimport { Report } from \"../../report\"\nimport { Archive } from \"../../archives/types\"\nimport { defaultHook } from \"./hooks/default\"\nimport { epubHook } from \"./hooks/epub\"\nimport { comicInfoHook } from \"./hooks/comicInfo\"\nimport { epubOptimizerHook } from \"./hooks/epubOptimizer\"\nimport { navigationFallbackHook } from \"./hooks/navigationFallback\"\n\nconst baseManifest: Manifest = {\n filename: ``,\n items: [],\n nav: {\n toc: [],\n },\n readingDirection: `ltr`,\n renditionLayout: `pre-paginated`,\n renditionSpread: `auto`,\n spineItems: [],\n title: ``,\n}\n\nexport const generateManifestFromArchive = async (\n archive: Archive,\n { baseUrl = `` }: { baseUrl?: string } = {},\n) => {\n const hooks = [\n defaultHook({ archive, baseUrl }),\n epubHook({ archive, baseUrl }),\n epubOptimizerHook({ archive, baseUrl }),\n comicInfoHook({ archive, baseUrl }),\n navigationFallbackHook({ archive, baseUrl }),\n ]\n\n try {\n const manifest = await hooks.reduce(async (manifest, gen) => {\n return await gen(await manifest)\n }, Promise.resolve(baseManifest))\n\n Report.log(\"Generated manifest\", manifest)\n\n return manifest\n } catch (e) {\n Report.error(e)\n\n throw e\n }\n}\n","export const getUriBasename = (uri: string) =>\n uri.substring(uri.lastIndexOf(`/`) + 1) || uri\n\nexport const removeTrailingSlash = (uri: string) =>\n uri.endsWith(\"/\") ? uri.slice(0, -1) : uri\n","import { detectMimeTypeFromName } from \"@prose-reader/shared\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { Archive } from \"./types\"\n\n/**\n * @important\n * Make sure the urls are on the same origin or the cors header is set otherwise\n * the resource cannot be consumed as it is on the web.\n */\nexport const createArchiveFromUrls = async (\n urls: string[],\n options?: { useRenditionFlow: boolean },\n): Promise<Archive> => {\n const opfFileData = `\n <?xml version=\"1.0\" encoding=\"UTF-8\"?><package xmlns=\"http://www.idpf.org/2007/opf\" version=\"2.0\" unique-identifier=\"bookid\">\n <metadata>\n <meta property=\"rendition:layout\">${options?.useRenditionFlow ? `reflowable` : `pre-paginated`}</meta>\n ${options?.useRenditionFlow ? `<meta property=\"rendition:flow\">scrolled-continuous</meta>` : ``}\n </metadata>\n <manifest>\n ${urls\n .map(\n (url) =>\n `<item id=\"${getUriBasename(url)}\" href=\"${url}\" media-type=\"${detectMimeTypeFromName(url)}\"/>`,\n )\n .join(`\\n`)}\n </manifest>\n <spine>\n ${urls.map((url) => `<itemref idref=\"${getUriBasename(url)}\" />`).join(`\\n`)}\n </spine>\n </package>\n `\n\n const filesFromUrl: Archive[`files`] = urls.map((url) => ({\n dir: false,\n basename: getUriBasename(url),\n encodingFormat: detectMimeTypeFromName(url),\n uri: url,\n size: 100 / urls.length,\n base64: async () => ``,\n blob: async () => new Blob(),\n string: async () => ``,\n }))\n\n const opfFile: Archive[`files`][number] = {\n dir: false,\n basename: `content.opf`,\n uri: `content.opf`,\n size: 0,\n base64: async () => opfFileData,\n blob: async () => new Blob(),\n string: async () => opfFileData,\n }\n\n return {\n filename: ``,\n files: [opfFile, ...filesFromUrl],\n close: () => Promise.resolve(),\n }\n}\n","export const blobToBase64 = async (blob: Blob) =>\n new Promise<string>((resolve) => {\n const reader = new FileReader()\n reader.readAsDataURL(blob)\n reader.onloadend = function () {\n const base64data = reader.result as string\n resolve(base64data)\n }\n })\n","import { blobToBase64 } from \"../utils/blobToBAse64\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { Archive } from \"./types\"\n\n/**\n * Useful to create archive from txt content\n */\nexport const createArchiveFromText = async (\n content: string | Blob,\n {\n mimeType,\n direction,\n }: {\n direction?: `ltr` | `rtl`\n mimeType?: string\n } = { mimeType: \"text/plain\" },\n) => {\n const txtOpfContent = `\n <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <package xmlns=\"http://www.idpf.org/2007/opf\" version=\"3.0\" xml:lang=\"ja\" prefix=\"rendition: http://www.idpf.org/vocab/rendition/#\"\n unique-identifier=\"ootuya-id\">\n <metadata xmlns:opf=\"http://www.idpf.org/2007/opf\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n xmlns:dcterms=\"http://purl.org/dc/terms/\">\n <meta property=\"rendition:layout\">reflowable</meta>\n </metadata>\n <manifest>\n <item id=\"p01\" href=\"p01.txt\" media-type=\"text/plain\"/>\n </manifest>\n <spine page-progression-direction=\"${direction ?? `ltr`}\">\n <itemref idref=\"p01\" />\n </spine>\n </package>\n `\n\n const archive: Archive = {\n filename: `content.txt`,\n files: [\n {\n dir: false,\n basename: getUriBasename(`generated.opf`),\n uri: `generated.opf`,\n blob: async () => new Blob([txtOpfContent]),\n string: async () => txtOpfContent,\n base64: async () => btoa(txtOpfContent),\n size: 0,\n },\n {\n dir: false,\n basename: getUriBasename(`p01.txt`),\n uri: `p01.txt`,\n blob: async () => {\n if (typeof content === `string`) return new Blob([content])\n return content\n },\n string: async () => {\n if (typeof content === `string`) return content\n return content.text()\n },\n base64: async () => {\n if (typeof content === `string`) return btoa(content)\n return blobToBase64(content)\n },\n size: typeof content === `string` ? content.length : content.size,\n encodingFormat: mimeType,\n },\n ],\n close: () => Promise.resolve(),\n }\n\n return archive\n}\n","import { Report } from \"../report\"\nimport { sortByTitleComparator } from \"../utils/sortByTitleComparator\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { Archive, StreamResult } from \"./types\"\n\ninterface OutputByType {\n base64: string\n string: string\n text: string\n binarystring: string\n array: number[]\n uint8array: Uint8Array\n arraybuffer: ArrayBuffer\n blob: Blob\n nodebuffer: Buffer\n}\n\ntype OutputType = keyof OutputByType\ninterface JSZipObject {\n name: string\n dir: boolean\n date: Date\n comment: string\n unixPermissions: number | string | null\n dosPermissions: number | null\n async<T extends OutputType>(type: T): Promise<OutputByType[T]>\n // nodeStream(type?: `nodebuffer`): NodeJS.ReadableStream;\n internalStream?: (type?: `uint8array`) => StreamResult\n}\n\ninterface JSZip {\n files: { [key: string]: JSZipObject }\n}\n\nexport const createArchiveFromJszip = async (\n jszip: JSZip,\n { orderByAlpha, name }: { orderByAlpha?: boolean; name?: string } = {},\n): Promise<Archive> => {\n let files = Object.values(jszip.files)\n\n if (orderByAlpha) {\n files = files.slice().sort((a, b) => sortByTitleComparator(a.name, b.name))\n }\n\n const archive = {\n filename: name || ``,\n files: files.map((file) => ({\n dir: file.dir,\n basename: getUriBasename(file.name),\n uri: file.name,\n blob: () => file.async(`blob`),\n string: () => file.async(`string`),\n base64: () => file.async(`base64`),\n ...(file.internalStream && {\n stream: file.internalStream,\n }),\n // this is private API\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n size: file._data.uncompressedSize,\n })),\n close: () => Promise.resolve(),\n }\n\n Report.log(\"Generated archive\", archive)\n\n return archive\n}\n","/**\n * @see https://github.com/nika-begiashvili/libarchivejs.\n *\n * Does not work in service worker due to usage of web worker.\n */\n/* eslint-disable @typescript-eslint/ban-types */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Report } from \"../report\"\nimport { Archive } from \"./types\"\n\ninterface ArchiveReader {\n getFilesArray(): Promise<any[]>\n /**\n * Terminate worker to free up memory\n */\n close(): Promise<void>\n}\n\n/**\n * Represents compressed file before extraction\n */\ninterface CompressedFile {\n /**\n * File name\n */\n get name(): string\n /**\n * File size\n */\n get size(): number\n get lastModified(): number\n /**\n * Extract file from archive\n * @returns {Promise<File>} extracted file\n */\n extract(): any\n}\n\nexport const createArchiveFromLibArchive = async (\n libArchive: ArchiveReader,\n { name }: { orderByAlpha?: boolean; name?: string } = {},\n): Promise<Archive> => {\n const objArray = await libArchive.getFilesArray()\n\n const archive: Archive = {\n close: () => libArchive.close(),\n filename: name ?? ``,\n files: objArray.map((item: { file: CompressedFile; path: string }) => ({\n dir: false,\n basename: item.file.name,\n size: item.file.size,\n uri: `${item.path}${item.file.name}`,\n base64: async () => {\n return ``\n },\n blob: async () => {\n const file = await (item.file.extract() as Promise<File>)\n\n return file\n },\n string: async () => {\n const file = await (item.file.extract() as Promise<File>)\n\n return file.text()\n },\n })),\n }\n\n Report.log(\"Generated archive\", archive)\n\n return archive\n}\n","import { sortByTitleComparator } from \"../utils/sortByTitleComparator\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { Archive } from \"./types\"\n\nexport const createArchiveFromArrayBufferList = async (\n list: {\n isDir: boolean\n name: string\n size: number\n data: () => Promise<ArrayBuffer>\n }[],\n { orderByAlpha, name }: { orderByAlpha?: boolean; name?: string } = {},\n): Promise<Archive> => {\n let files = list\n\n if (orderByAlpha) {\n files = files.slice().sort((a, b) => sortByTitleComparator(a.name, b.name))\n }\n\n return {\n filename: name || ``,\n files: files.map((file) => ({\n dir: file.isDir,\n basename: getUriBasename(file.name),\n uri: file.name,\n blob: async () => new Blob([await file.data()]),\n string: async () => {\n const data = await file.data()\n return String.fromCharCode.apply(\n null,\n Array.from(new Uint16Array(data)),\n )\n },\n base64: async () => {\n // @todo not used for now, lets implement it later if needed\n return ``\n },\n size: file.size,\n })),\n close: () => Promise.resolve(),\n }\n}\n","import { Report } from \"./report\"\n\nexport const configure = ({\n enableReport,\n}: { enableReport?: boolean } = {}) => {\n Report.enable(!!enableReport)\n}\n","import {\n BehaviorSubject,\n catchError,\n distinctUntilChanged,\n EMPTY,\n filter,\n first,\n from,\n ignoreElements,\n map,\n merge,\n mergeMap,\n NEVER,\n of,\n shareReplay,\n startWith,\n Subject,\n switchMap,\n takeUntil,\n tap,\n timer,\n withLatestFrom,\n} from \"rxjs\"\nimport { Archive } from \"./types\"\n\ntype ArchiveEntry = {\n status: \"idle\" | \"loading\" | \"success\" | \"error\"\n error: unknown\n archive: undefined | Archive\n locks: number\n}\n\nexport const createArchiveLoader = ({\n getArchive,\n cleanArchiveAfter,\n}: {\n getArchive: (key: string) => Promise<Archive>\n cleanArchiveAfter: number\n}) => {\n const loadSubject = new Subject<string>()\n const destroySubject = new Subject<void>()\n const purgeSubject = new Subject<void>()\n const archives: Record<string, BehaviorSubject<ArchiveEntry>> = {}\n\n const archiveLoaded$ = loadSubject.pipe(\n mergeMap((key) => {\n const archiveEntry = archives[key]\n\n if (!archiveEntry || archiveEntry.getValue().status !== \"idle\")\n return EMPTY\n\n archiveEntry.next({\n ...archiveEntry.getValue(),\n status: \"loading\",\n })\n\n return from(getArchive(key)).pipe(\n map((archive) => {\n archiveEntry.next({\n ...archiveEntry.getValue(),\n archive,\n status: \"success\",\n })\n\n return { key, archiveEntry }\n }),\n catchError((error) => {\n archiveEntry.next({\n ...archiveEntry.getValue(),\n status: \"error\",\n error,\n })\n\n return EMPTY\n }),\n )\n }),\n shareReplay(),\n )\n\n const cleanup$ = archiveLoaded$.pipe(\n switchMap(({ archiveEntry, key }) => {\n const locks$ = archiveEntry.pipe(map(({ locks }) => locks))\n const isPurged$ = purgeSubject.pipe(\n map(() => true),\n startWith(false),\n shareReplay(),\n )\n const isUnlocked$ = locks$.pipe(\n map((locks) => locks <= 0),\n distinctUntilChanged(),\n )\n\n return isUnlocked$.pipe(\n withLatestFrom(isPurged$),\n switchMap(([isUnlocked, isPurged]) =>\n !isUnlocked ? NEVER : !isPurged ? timer(cleanArchiveAfter) : of(null),\n ),\n tap(() => {\n delete archives[key]\n\n archiveEntry.getValue().archive?.close()\n }),\n )\n }),\n )\n\n const access = (key: string) => {\n let releaseCalled = false\n\n const archiveEntry =\n archives[key] ??\n new BehaviorSubject<ArchiveEntry>({\n archive: undefined,\n status: \"idle\",\n locks: 0,\n error: undefined,\n })\n\n archives[key] = archiveEntry\n\n archiveEntry.next({\n ...archiveEntry.getValue(),\n locks: archiveEntry.getValue().locks + 1,\n })\n\n const release = () => {\n if (releaseCalled) return\n\n releaseCalled = true\n\n archiveEntry.next({\n ...archiveEntry.getValue(),\n locks: archiveEntry.getValue().locks - 1,\n })\n }\n\n loadSubject.next(key)\n\n const archive$ = archiveEntry.pipe(\n map(({ archive }) => archive),\n filter((archive) => !!archive),\n )\n\n const error$ = archiveEntry.pipe(\n tap(({ error }) => {\n if (error) {\n throw error\n }\n }),\n ignoreElements(),\n )\n\n return merge(archive$, error$).pipe(\n first(),\n map((archive) => ({ archive, release })),\n catchError((error) => {\n release()\n\n throw error\n }),\n )\n }\n\n /**\n * Will purge immediatly archives as soon as they are released\n */\n const purge = () => {\n // make sure we don't access anymore\n Object.keys(archives).forEach((key) => {\n delete archives[key]\n })\n\n purgeSubject.next()\n }\n\n merge(cleanup$, archiveLoaded$).pipe(takeUntil(destroySubject)).subscribe()\n\n return {\n access,\n purge,\n }\n}\n","import {\n catchError,\n finalize,\n from,\n lastValueFrom,\n map,\n mergeMap,\n Observable,\n of,\n switchMap,\n} from \"rxjs\"\nimport { createArchiveLoader } from \"./archives/archiveLoader\"\nimport { Manifest } from \"@prose-reader/shared\"\nimport { generateManifestFromArchive } from \"./generators/manifest\"\nimport { generateResourceFromArchive } from \"./generators/resources\"\nimport { Archive } from \"./archives/types\"\n\ntype OnError = (error: unknown) => Response\ntype OnManifestSuccess = (params: {\n manifest: Manifest\n archive: Archive\n}) => Observable<Manifest> | Promise<Manifest>\n\nexport class Streamer {\n protected epubLoader: ReturnType<typeof createArchiveLoader>\n protected onError: OnError = (error) => {\n return new Response(String(error), { status: 500 })\n }\n protected onManifestSuccess: OnManifestSuccess\n protected lastAccessedKey: string | undefined\n\n constructor({\n onError,\n onManifestSuccess,\n ...rest\n }: Parameters<typeof createArchiveLoader>[0] & {\n onError?: OnError\n onManifestSuccess?: OnManifestSuccess\n }) {\n this.epubLoader = createArchiveLoader(rest)\n\n this.onManifestSuccess =\n onManifestSuccess ?? (({ manifest }) => Promise.resolve(manifest))\n this.onError = onError ?? this.onError\n }\n\n protected accessArchive(key: string) {\n if (this.lastAccessedKey !== key) {\n this.epubLoader.purge()\n }\n\n this.lastAccessedKey = key\n\n return this.epubLoader.access(key)\n }\n\n public fetchManifest({ key, baseUrl }: { key: string; baseUrl?: string }) {\n const response$ = this.accessArchive(key).pipe(\n mergeMap(({ archive, release }) => {\n const manifest$ = from(\n generateManifestFromArchive(archive, { baseUrl }),\n )\n\n return manifest$.pipe(\n switchMap((manifest) =>\n from(this.onManifestSuccess({ manifest, archive })),\n ),\n map(\n (manifest) =>\n new Response(JSON.stringify(manifest satisfies Manifest), {\n status: 200,\n }),\n ),\n finalize(() => {\n release()\n }),\n )\n }),\n catchError((error) => {\n return of(this.onError(error))\n }),\n )\n\n return lastValueFrom(response$)\n }\n\n public fetchResource({\n key,\n resourcePath,\n }: {\n key: string\n resourcePath: string\n }) {\n const response$ = this.accessArchive(key).pipe(\n mergeMap(({ archive, release }) => {\n const manifest$ = from(\n generateResourceFromArchive(archive, resourcePath),\n )\n\n return manifest$.pipe(\n map(\n (resource) =>\n new Response(resource.body, {\n status: 200,\n headers: {\n ...(resource.params.contentType && {\n \"Content-Type\": resource.params.contentType,\n }),\n },\n }),\n ),\n finalize(() => {\n release()\n }),\n )\n }),\n catchError((error) => {\n return of(this.onError(error))\n }),\n )\n\n return lastValueFrom(response$)\n }\n}\n","import { Streamer } from \"./Streamer\"\nimport { removeTrailingSlash } from \"./utils/uri\"\n\ntype ConflictFreeWebWorkerFetchEvent = {\n readonly request: Request\n /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FetchEvent/respondWith) */\n respondWith(r: Response | PromiseLike<Response>): void\n}\n\nexport class ServiceWorkerStreamer extends Streamer {\n protected getUriInfo: (event: ConflictFreeWebWorkerFetchEvent) =>\n | {\n baseUrl: string\n }\n | undefined\n\n constructor({\n getUriInfo,\n ...rest\n }: ConstructorParameters<typeof Streamer>[0] & {\n getUriInfo: (event: ConflictFreeWebWorkerFetchEvent) =>\n | {\n baseUrl: string\n }\n | undefined\n }) {\n super(rest)\n\n this.getUriInfo = getUriInfo\n this.fetchEventListener = this.fetchEventListener.bind(this)\n }\n\n fetchEventListener(event: ConflictFreeWebWorkerFetchEvent) {\n try {\n const uriInfo = this.getUriInfo(event)\n\n if (!uriInfo) return\n\n const baseUrl = removeTrailingSlash(uriInfo.baseUrl)\n const streamerPath = event.request.url.substring(\n baseUrl.length + `/`.length,\n )\n const [key = ``] = streamerPath.split(\"/\")\n const resourcePath = decodeURIComponent(\n removeTrailingSlash(streamerPath.substring(key.length + `/`.length)),\n )\n\n if (streamerPath.endsWith(`/manifest`)) {\n event.respondWith(\n this.fetchManifest({ key, baseUrl: `${baseUrl}/${key}/` }),\n )\n } else {\n event.respondWith(this.fetchResource({ key, resourcePath }))\n }\n } catch (e) {\n event.respondWith(new Response(String(e), { status: 500 }))\n }\n }\n}\n"],"names":["enabled","Report","enable","data","label","performanceEntry","targetDuration","duration","name","functionToMeasure","args","t0","response","res","t1","hasCalibreCoverMeta","doc","metaElm","_a","node","getBuggyCoverSvg","_c","_b","fixBuggyCover","archive","resourcePath","resource","file","bodyToParse","opfXmlDoc","XmlDocument","buggySvg","calibreFixHook","cssFixHook","newBody","getArchiveOpfInfo","extractNavChapter","li","opfBasePath","baseUrl","chp","contentNode","urlJoin","sublistNode","children","child","buildTOCFromNav","toc","navDataChildren","parseTocFromNavPath","navItem","tocFile","item","xmldoc","mapNcxChapter","point","prefix","src","out","pt","buildTOCFromNCX","ncxData","rootTagName","parseTocFromNcx","opfData","spine","ncxId","ncxItem","ncxPath","parseToc","tocFromNcx","extractKoboInformationFromArchive","koboInformation","optionElement","getSpineItemFilesFromArchive","opsFile","_opfXmlDoc","manifestElm","spineElm","spineItemIds","manifestItemsFromSpine","getItemsFromDoc","el","epubHook","manifest","metadataElm","guideElm","titleElm","metaElmChildren","metaElmWithRendition","meta","metaElmWithRenditionFlow","metaElmWithRenditionSpread","publisherRenditionLayout","publisherRenditionFlow","renditionSpread","title","dir","pageProgressionDirection","totalSize","size","itemrefElm","manifestItem","href","properties","itemSize","hrefBaseUri","property","elm","getMetadata","getContentTypeFromExtension","uri","defaultHook","metadata","invalidSelfClosingTags","selfClosingTagsFixHook","tagPattern","fixedBody","match","tagName","attributes","generateResourceFromArchive","defaultResource","hooks","gen","e","files","index","comicInfoHook","comicInfoFile","manifestWithoutComicInfo","_","items","content","mangaVal","hasDocMetaViewport","allFilesHaveViewportMeta","result","current","isXmlBasedMimeType","epubOptimizerHook","sortByTitleComparator","a","b","alist","blist","i","len","navigationFallbackHook","filesSortedByAlpha","filesSortedAlpha","combineWith","folder","subFolders","path","foundEntry","entry","nextFolderCursor","nextSubFolders","acc","folders","firstFolder","restFolders","baseManifest","generateManifestFromArchive","getUriBasename","removeTrailingSlash","createArchiveFromUrls","urls","options","opfFileData","url","detectMimeTypeFromName","filesFromUrl","blobToBase64","blob","resolve","reader","base64data","createArchiveFromText","mimeType","direction","txtOpfContent","createArchiveFromJszip","jszip","orderByAlpha","createArchiveFromLibArchive","libArchive","objArray","createArchiveFromArrayBufferList","list","configure","enableReport","createArchiveLoader","getArchive","cleanArchiveAfter","loadSubject","Subject","destroySubject","purgeSubject","archives","archiveLoaded$","mergeMap","key","archiveEntry","EMPTY","from","map","catchError","error","shareReplay","cleanup$","switchMap","locks$","locks","isPurged$","startWith","distinctUntilChanged","withLatestFrom","isUnlocked","isPurged","of","timer","NEVER","tap","access","releaseCalled","BehaviorSubject","release","archive$","filter","error$","ignoreElements","merge","first","purge","takeUntil","Streamer","onError","onManifestSuccess","rest","response$","finalize","lastValueFrom","ServiceWorkerStreamer","getUriInfo","event","uriInfo","streamerPath"],"mappings":"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"}
@@ -1,20 +1,20 @@
1
- (function(h,w){typeof exports=="object"&&typeof module<"u"?w(exports,require("xmldoc"),require("@prose-reader/shared"),require("rxjs")):typeof define=="function"&&define.amd?define(["exports","xmldoc","@prose-reader/shared","rxjs"],w):(h=typeof globalThis<"u"?globalThis:h||self,w(h["prose-streamer"]={},h.xmldoc,h.shared,h.rxjs))})(this,function(h,w,T,c){"use strict";let A=!1;const v={enable:e=>{A=e},log:(...e)=>{A&&console.log("[prose-reader-streamer]",...e)},warn:(...e)=>{A&&console.warn("[prose-reader-streamer]",...e)},error:(...e)=>{console.error(...e)},time:e=>{A&&console.time(`[prose-reader-streamer] [metric] ${e}`)},timeEnd:e=>{A&&console.timeEnd(`[prose-reader-streamer] [metric] ${e}`)},metric:(e,n=1/0)=>{const i=typeof e=="number"?e:e.duration;A&&(e.duration<=n?console.log("[prose-reader-streamer] [metric] ",`${e.name} took ${i}ms`):console.warn("[prose-reader-streamer] [metric] ",`${e.name} took ${e.duration}ms which is above the ${n}ms target for this function`))},measurePerformance:(e,n=10,i)=>(...r)=>{const t=performance.now(),a=i(...r);if(a&&a.then)return a.then(s=>{const f=performance.now();return v.metric({name:e,duration:f-t},n),s});const o=performance.now();return v.metric({name:e,duration:o-t},n),a}},_=e=>{var i;const n=(i=e.descendantWithPath("head"))==null?void 0:i.childrenNamed("meta").find(r=>r.attr.name==="calibre:cover");return!!(n&&n.attr.name==="calibre:cover")},G=e=>{var n,i,r;return(r=(i=(n=e.descendantWithPath("body"))==null?void 0:n.descendantWithPath("div"))==null?void 0:i.childrenNamed("svg"))==null?void 0:r.find(t=>t.attr.width==="100%"&&t.attr.preserveAspectRatio==="none")},K=({archive:e,resourcePath:n})=>async i=>{const r=Object.values(e.files).find(t=>t.uri===n);if(r!=null&&r.basename.endsWith(".xhtml")){const t=i.body??await r.string(),a=new w.XmlDocument(t);if(_(a)){const o=G(a);return o&&delete o.attr.preserveAspectRatio,{...i,body:a==null?void 0:a.toString()}}}return i},Y=({archive:e,resourcePath:n})=>async i=>K({archive:e,resourcePath:n})(i),E=({archive:e,resourcePath:n})=>async i=>{const r=Object.values(e.files).find(t=>t.uri===n);if(r!=null&&r.basename.endsWith(".css")){const a=(i.body??await r.string()).replaceAll("-webkit-writing-mode","writing-mode");return{...i,body:a}}return i},k=e=>{const i=Object.values(e.files).filter(r=>!r.dir).find(r=>r.uri.endsWith(".opf"));return{data:i,basePath:(i==null?void 0:i.uri.substring(0,i.uri.lastIndexOf("/")))||""}},I=(e,{opfBasePath:n,baseUrl:i})=>{const r={contents:[],path:"",href:"",title:""};let t=e.childNamed("span")||e.childNamed("a");r.title=(t==null?void 0:t.attr.title)||(t==null?void 0:t.val.trim())||r.title;let a=t==null?void 0:t.name;a!=="a"&&(t=e.descendantWithPath(`${a}.a`),t&&(a=t.name.toLowerCase())),a==="a"&&(t!=null&&t.attr.href)&&(r.path=T.urlJoin(n,t.attr.href),r.href=T.urlJoin(i,n,t.attr.href));const o=e.childNamed("ol");if(o){const s=o.childrenNamed("li");s&&s.length>0&&(r.contents=s.map(f=>I(f,{opfBasePath:n,baseUrl:i})))}return r},Q=(e,{opfBasePath:n,baseUrl:i})=>{var a,o;const r=[];let t;return e.descendantWithPath("body.nav.ol")?t=(a=e.descendantWithPath("body.nav.ol"))==null?void 0:a.children:e.descendantWithPath("body.section.nav.ol")&&(t=(o=e.descendantWithPath("body.section.nav.ol"))==null?void 0:o.children),t&&t.length>0&&t.filter(s=>s.name==="li").forEach(s=>r.push(I(s,{opfBasePath:n,baseUrl:i}))),r},Z=async(e,n,{opfBasePath:i,baseUrl:r})=>{var a;const t=(a=e.childNamed("manifest"))==null?void 0:a.childrenNamed("item").find(o=>o.attr.properties==="nav");if(t){const o=Object.values(n.files).find(s=>s.uri.endsWith(t.attr.href||""));if(o){const s=new w.XmlDocument(await o.string());return Q(s,{opfBasePath:i,baseUrl:r})}}},C=(e,{opfBasePath:n,baseUrl:i,prefix:r})=>{var s,f;const t=((s=e==null?void 0:e.childNamed(`${r}content`))==null?void 0:s.attr.src)||"",a={title:((f=e==null?void 0:e.descendantWithPath(`${r}navLabel.${r}text`))==null?void 0:f.val)||"",path:T.urlJoin(n,t),href:T.urlJoin(i,n,t),contents:[]},o=e.childrenNamed(`${r}navPoint`);return o&&o.length>0&&(a.contents=o.map(g=>C(g,{opfBasePath:n,baseUrl:i,prefix:r}))),a},j=(e,{opfBasePath:n,baseUrl:i})=>{var o;const r=[],t=e.name;let a="";return t.indexOf(":")!==-1&&(a=t.split(":")[0]+":"),(o=e.childNamed(`${a}navMap`))==null||o.childrenNamed(`${a}navPoint`).forEach(s=>r.push(C(s,{opfBasePath:n,baseUrl:i,prefix:a}))),r},ee=async({opfData:e,opfBasePath:n,baseUrl:i,archive:r})=>{var o;const t=e.childNamed("spine"),a=t&&t.attr.toc;if(a){const s=(o=e.childNamed("manifest"))==null?void 0:o.childrenNamed("item").find(f=>f.attr.id===a);if(s){const f=`${n}${n===""?"":"/"}${s.attr.href}`,g=Object.values(r.files).find(d=>d.uri.endsWith(f));if(g){const d=new w.XmlDocument(await g.string());return j(d,{opfBasePath:n,baseUrl:i})}}}},te=async(e,n,{baseUrl:i})=>{const{basePath:r}=k(n)||{},t=await ee({opfData:e,opfBasePath:r,archive:n,baseUrl:i});return t||await Z(e,n,{opfBasePath:r,baseUrl:i})},ne=async e=>{const n={renditionLayout:void 0};return await Promise.all(e.files.map(async i=>{var r,t;if(i.uri.endsWith("com.kobobooks.display-options.xml")){const o=(r=new w.XmlDocument(await i.string()).childNamed("platform"))==null?void 0:r.childNamed("option");((t=o==null?void 0:o.attr)==null?void 0:t.name)==="fixed-layout"&&o.val==="true"&&(n.renditionLayout="pre-paginated")}})),n},R=async({archive:e})=>{const{data:n,basePath:i}=k(e)||{},r=await(n==null?void 0:n.string());if(!r)return[];const t=new w.XmlDocument(r),a=t.childNamed("manifest"),o=t.childNamed("spine"),s=o==null?void 0:o.childrenNamed("itemref").map(d=>d.attr.idref),f=(a==null?void 0:a.childrenNamed("item").filter(d=>s.includes(d.attr.id||"")))||[];return e.files.filter(d=>f.find(l=>i?`${i}/${l.attr.href}`===d.uri:`${l.attr.href}`===d.uri))},M=e=>{var i;const n=e.childNamed("manifest");return((i=n==null?void 0:n.childrenNamed("item"))==null?void 0:i.map(r=>({href:r.attr.href||"",id:r.attr.id||"",mediaType:r.attr["media-type"]})))||[]},re=({archive:e,baseUrl:n})=>async i=>{var X;const{data:r,basePath:t}=k(e)||{},a=await ne(e);if(!r)return i;const o=await r.string();v.log(o,a);const s=new w.XmlDocument(o),f=await te(s,e,{baseUrl:n})||[],g=s.childNamed("metadata"),d=s.childNamed("manifest"),l=s.childNamed("spine"),m=s.childNamed("guide"),$=g==null?void 0:g.childNamed("dc:title"),N=(g==null?void 0:g.childrenNamed("meta"))||[],b=N.find(u=>u.attr.property==="rendition:layout"),y=N.find(u=>u.attr.property==="rendition:flow"),L=N.find(u=>u.attr.property==="rendition:spread"),B=b==null?void 0:b.val,Se=y==null?void 0:y.val,Ae=L==null?void 0:L.val,Ne=($==null?void 0:$.val)||((X=e.files.find(({dir:u})=>u))==null?void 0:X.basename)||"",ke=l==null?void 0:l.attr["page-progression-direction"],We=(await R({archive:e})).reduce((u,p)=>p.size+u,0);return{filename:e.filename,nav:{toc:f},renditionLayout:B||a.renditionLayout||"reflowable",renditionFlow:Se||"auto",renditionSpread:Ae,title:Ne,readingDirection:ke||"ltr",spineItems:(l==null?void 0:l.childrenNamed("itemref").map(u=>{var J,q,x;const p=d==null?void 0:d.childrenNamed("item").find(F=>F.attr.id===(u==null?void 0:u.attr.idref)),Le=(p==null?void 0:p.attr.href)||"",P=((J=u==null?void 0:u.attr.properties)==null?void 0:J.split(" "))||[],Pe=((q=e.files.find(F=>F.uri.endsWith(Le)))==null?void 0:q.size)||0,H=n??"";return{id:(p==null?void 0:p.attr.id)||"",href:(x=p==null?void 0:p.attr.href)!=null&&x.startsWith("https://")?p==null?void 0:p.attr.href:t?`${H}${t}/${p==null?void 0:p.attr.href}`:`${H}${p==null?void 0:p.attr.href}`,renditionLayout:B||"reflowable",...P.find(F=>F==="rendition:layout-reflowable")&&{renditionLayout:"reflowable"},progressionWeight:Pe/We,pageSpreadLeft:P.some(F=>F==="page-spread-left")||void 0,pageSpreadRight:P.some(F=>F==="page-spread-right")||void 0,mediaType:p==null?void 0:p.attr["media-type"]}}))||[],items:M(s),guide:m==null?void 0:m.childrenNamed("reference").map(u=>({href:u.attr.href||"",title:u.attr.title||"",type:u.attr.type}))}},ae=async(e,n)=>{var t,a;const r=await((t=k(e).data)==null?void 0:t.string());if(r){const o=new w.XmlDocument(r);return{mediaType:(a=M(o).find(f=>n.endsWith(f.href)))==null?void 0:a.mediaType}}return{mediaType:ie(n)}},ie=e=>{if(e.endsWith(".css"))return"text/css; charset=UTF-8";if(e.endsWith(".jpg"))return"image/jpg";if(e.endsWith(".xhtml"))return"application/xhtml+xml";if(e.endsWith(".mp4"))return"video/mp4";if(e.endsWith(".svg"))return"image/svg+xml"},oe=({archive:e,resourcePath:n})=>async i=>{const r=Object.values(e.files).find(a=>a.uri===n);if(!r)return i;const t=await ae(e,n);return{...i,params:{...i.params,...(r==null?void 0:r.encodingFormat)&&{contentType:r.encodingFormat},...t.mediaType&&{contentType:t.mediaType}}}},D=["div","span","p","a","li","ul","ol","h1","h2","h3","h4","h5","h6","table","tr","td","th","thead","tbody","tfoot","section","article","header","footer","nav","aside","main","figure","figcaption","blockquote","pre","code","form","textarea","select","option","button","label","fieldset","legend","caption","dl","dt","dd","iframe","video","audio","canvas","script","style"],se=({archive:e,resourcePath:n})=>async i=>{const r=Object.values(e.files).find(t=>t.uri===n);if(r!=null&&r.basename.endsWith(".xhtml")){const t=i.body??await r.string();if(!new RegExp(`<(${D.join("|")})[\\s/>]`,"i").test(t))return i;const o=new RegExp(`<(${D.join("|")})(\\s[^>]*)?\\s*/>`,"gi"),s=t.replace(o,(f,g,d="")=>`<${g} ${d.trim()}></${g}>`);return{...i,body:s}}return i},O=async(e,n)=>{const i=Object.values(e.files).find(a=>a.uri===n);if(!i)throw new Error("no file found");const r={params:{}},t=[oe({archive:e,resourcePath:n}),se({archive:e,resourcePath:n}),E({archive:e,resourcePath:n}),Y({archive:e,resourcePath:n})];try{const a=await t.reduce(async(o,s)=>await s(await o),Promise.resolve(r));return v.log("Generated resource",n,a),{...a,body:a.body??await i.blob()}}catch(a){throw v.error(a),a}},ce=({archive:e,baseUrl:n})=>async()=>{var r;const i=Object.values(e.files).filter(t=>!t.dir);return{filename:e.filename,title:((r=e.files.find(({dir:t})=>t))==null?void 0:r.basename.replace(/\/$/,""))||"",renditionLayout:"pre-paginated",renditionSpread:"auto",readingDirection:"ltr",spineItems:i.filter(t=>!t.basename.endsWith(".db")).map((t,a)=>({id:`${a}.${t.basename}`,href:encodeURI(`${n}${t.uri}`),renditionLayout:"pre-paginated",progressionWeight:1/i.length,pageSpreadLeft:void 0,pageSpreadRight:void 0,mediaType:t.encodingFormat})),items:i.map((t,a)=>({id:`${a}.${t.basename}`,href:`${n}${t.uri}`}))}},de=({archive:e})=>async n=>{var a;const i=e.files.find(o=>o.basename.toLowerCase()==="comicinfo.xml");if(!i)return n;const r={...n,spineItems:n.spineItems.filter(o=>!o.id.toLowerCase().endsWith("comicinfo.xml")).map((o,s,f)=>({...o,progressionWeight:1/f.length}))},t=await i.string();try{const s=((a=new w.XmlDocument(t).childNamed("Manga"))==null?void 0:a.val)||"unknown";return{...r,readingDirection:s==="YesAndRightToLeft"?"rtl":"ltr"}}catch(o){return console.error(`Unable to parse comicinfo.xml for content
2
- `,t),console.error(o),r}},le=e=>{var i;const n=(i=e.descendantWithPath("head"))==null?void 0:i.childrenNamed("meta").find(r=>r.attr.name==="viewport");return!!(n&&n.attr.name==="viewport")},pe=e=>e.reduce(async(n,i)=>{if(!await n||!T.isXmlBasedMimeType({mimeType:i.encodingFormat,uri:i.uri}))return!1;const t=await i.string();return t?le(new w.XmlDocument(t)):!1},Promise.resolve(!0)),fe=({archive:e})=>async n=>{if(n.renditionLayout==="reflowable"&&n.spineItems.every(r=>r.renditionLayout==="reflowable")){const r=await R({archive:e});if(await pe(r))return{...n,spineItems:n.spineItems.map(a=>({...a,renditionLayout:"pre-paginated"})),renditionLayout:"pre-paginated"}}return n},W=(e,n)=>{var t;const i=e.split(/(\d+)/),r=n.split(/(\d+)/);for(let a=0,o=i.length;a<o;a++)if(i[a]!==r[a])return(t=i[a])!=null&&t.match(/\d/)?+(i[a]||"")-+(r[a]||""):(i[a]||"").localeCompare(r[a]||"");return 1},me=({archive:e,baseUrl:n})=>async i=>{if(i.nav)return i;const r=[...e.files].sort((a,o)=>W(a.uri,o.uri)),t=Object.values(r).reduce((a,o)=>{const s=o.uri.split("/");return!o.dir&&s.length>1&&s.forEach((g,d)=>{if(d===s.length-1)return;a.find(({title:$})=>$===g)||a.push({contents:[],href:T.urlJoin(n,encodeURI(o.uri)).replace(/\/$/,""),path:o.uri.replace(/\/$/,""),title:s[0]??""})}),a},[]);return t.length===0?i:{...i,nav:{toc:t}}},ue={filename:"",items:[],nav:{toc:[]},readingDirection:"ltr",renditionLayout:"pre-paginated",renditionSpread:"auto",spineItems:[],title:""},z=async(e,{baseUrl:n=""}={})=>{const i=[ce({archive:e,baseUrl:n}),re({archive:e,baseUrl:n}),fe({archive:e,baseUrl:n}),de({archive:e,baseUrl:n}),me({archive:e,baseUrl:n})];try{const r=await i.reduce(async(t,a)=>await a(await t),Promise.resolve(ue));return v.log("Generated manifest",r),r}catch(r){throw v.error(r),r}},S=e=>e.substring(e.lastIndexOf("/")+1)||e,V=e=>e.endsWith("/")?e.slice(0,-1):e,he=async(e,n)=>{const i=`
1
+ (function(y,v){typeof exports=="object"&&typeof module<"u"?v(exports,require("xmldoc"),require("@prose-reader/shared"),require("rxjs")):typeof define=="function"&&define.amd?define(["exports","xmldoc","@prose-reader/shared","rxjs"],v):(y=typeof globalThis<"u"?globalThis:y||self,v(y["prose-streamer"]={},y.xmldoc,y.shared,y.rxjs))})(this,function(y,v,T,c){"use strict";let N=!1;const F={enable:e=>{N=e},log:(...e)=>{N&&console.log("[prose-reader-streamer]",...e)},warn:(...e)=>{N&&console.warn("[prose-reader-streamer]",...e)},error:(...e)=>{console.error(...e)},time:e=>{N&&console.time(`[prose-reader-streamer] [metric] ${e}`)},timeEnd:e=>{N&&console.timeEnd(`[prose-reader-streamer] [metric] ${e}`)},metric:(e,n=1/0)=>{const a=typeof e=="number"?e:e.duration;N&&(e.duration<=n?console.log("[prose-reader-streamer] [metric] ",`${e.name} took ${a}ms`):console.warn("[prose-reader-streamer] [metric] ",`${e.name} took ${e.duration}ms which is above the ${n}ms target for this function`))},measurePerformance:(e,n=10,a)=>(...r)=>{const t=performance.now(),i=a(...r);if(i&&i.then)return i.then(s=>{const f=performance.now();return F.metric({name:e,duration:f-t},n),s});const o=performance.now();return F.metric({name:e,duration:o-t},n),i}},_=e=>{var a;const n=(a=e.descendantWithPath("head"))==null?void 0:a.childrenNamed("meta").find(r=>r.attr.name==="calibre:cover");return!!(n&&n.attr.name==="calibre:cover")},G=e=>{var n,a,r;return(r=(a=(n=e.descendantWithPath("body"))==null?void 0:n.descendantWithPath("div"))==null?void 0:a.childrenNamed("svg"))==null?void 0:r.find(t=>t.attr.width==="100%"&&t.attr.preserveAspectRatio==="none")},K=({archive:e,resourcePath:n})=>async a=>{const r=Object.values(e.files).find(t=>t.uri===n);if(r!=null&&r.basename.endsWith(".xhtml")){const t=a.body??await r.string(),i=new v.XmlDocument(t);if(_(i)){const o=G(i);return o&&delete o.attr.preserveAspectRatio,{...a,body:i==null?void 0:i.toString()}}}return a},Y=({archive:e,resourcePath:n})=>async a=>K({archive:e,resourcePath:n})(a),E=({archive:e,resourcePath:n})=>async a=>{const r=Object.values(e.files).find(t=>t.uri===n);if(r!=null&&r.basename.endsWith(".css")){const i=(a.body??await r.string()).replaceAll("-webkit-writing-mode","writing-mode");return{...a,body:i}}return a},W=e=>{const a=Object.values(e.files).filter(r=>!r.dir).find(r=>r.uri.endsWith(".opf"));return{data:a,basePath:(a==null?void 0:a.uri.substring(0,a.uri.lastIndexOf("/")))||""}},C=(e,{opfBasePath:n,baseUrl:a})=>{const r={contents:[],path:"",href:"",title:""};let t=e.childNamed("span")||e.childNamed("a");r.title=(t==null?void 0:t.attr.title)||(t==null?void 0:t.val.trim())||r.title;let i=t==null?void 0:t.name;i!=="a"&&(t=e.descendantWithPath(`${i}.a`),t&&(i=t.name.toLowerCase())),i==="a"&&(t!=null&&t.attr.href)&&(r.path=T.urlJoin(n,t.attr.href),r.href=T.urlJoin(a,n,t.attr.href));const o=e.childNamed("ol");if(o){const s=o.childrenNamed("li");s&&s.length>0&&(r.contents=s.map(f=>C(f,{opfBasePath:n,baseUrl:a})))}return r},Q=(e,{opfBasePath:n,baseUrl:a})=>{var i,o;const r=[];let t;return e.descendantWithPath("body.nav.ol")?t=(i=e.descendantWithPath("body.nav.ol"))==null?void 0:i.children:e.descendantWithPath("body.section.nav.ol")&&(t=(o=e.descendantWithPath("body.section.nav.ol"))==null?void 0:o.children),t&&t.length>0&&t.filter(s=>s.name==="li").forEach(s=>r.push(C(s,{opfBasePath:n,baseUrl:a}))),r},Z=async(e,n,{opfBasePath:a,baseUrl:r})=>{var i;const t=(i=e.childNamed("manifest"))==null?void 0:i.childrenNamed("item").find(o=>o.attr.properties==="nav");if(t){const o=Object.values(n.files).find(s=>s.uri.endsWith(t.attr.href||""));if(o){const s=new v.XmlDocument(await o.string());return Q(s,{opfBasePath:a,baseUrl:r})}}},R=(e,{opfBasePath:n,baseUrl:a,prefix:r})=>{var s,f;const t=((s=e==null?void 0:e.childNamed(`${r}content`))==null?void 0:s.attr.src)||"",i={title:((f=e==null?void 0:e.descendantWithPath(`${r}navLabel.${r}text`))==null?void 0:f.val)||"",path:T.urlJoin(n,t),href:T.urlJoin(a,n,t),contents:[]},o=e.childrenNamed(`${r}navPoint`);return o&&o.length>0&&(i.contents=o.map(m=>R(m,{opfBasePath:n,baseUrl:a,prefix:r}))),i},j=(e,{opfBasePath:n,baseUrl:a})=>{var o;const r=[],t=e.name;let i="";return t.indexOf(":")!==-1&&(i=t.split(":")[0]+":"),(o=e.childNamed(`${i}navMap`))==null||o.childrenNamed(`${i}navPoint`).forEach(s=>r.push(R(s,{opfBasePath:n,baseUrl:a,prefix:i}))),r},ee=async({opfData:e,opfBasePath:n,baseUrl:a,archive:r})=>{var o;const t=e.childNamed("spine"),i=t&&t.attr.toc;if(i){const s=(o=e.childNamed("manifest"))==null?void 0:o.childrenNamed("item").find(f=>f.attr.id===i);if(s){const f=`${n}${n===""?"":"/"}${s.attr.href}`,m=Object.values(r.files).find(d=>d.uri.endsWith(f));if(m){const d=new v.XmlDocument(await m.string());return j(d,{opfBasePath:n,baseUrl:a})}}}},te=async(e,n,{baseUrl:a})=>{const{basePath:r}=W(n)||{},t=await ee({opfData:e,opfBasePath:r,archive:n,baseUrl:a});return t||await Z(e,n,{opfBasePath:r,baseUrl:a})},ne=async e=>{const n={renditionLayout:void 0};return await Promise.all(e.files.map(async a=>{var r,t;if(a.uri.endsWith("com.kobobooks.display-options.xml")){const o=(r=new v.XmlDocument(await a.string()).childNamed("platform"))==null?void 0:r.childNamed("option");((t=o==null?void 0:o.attr)==null?void 0:t.name)==="fixed-layout"&&o.val==="true"&&(n.renditionLayout="pre-paginated")}})),n},I=async({archive:e})=>{const{data:n,basePath:a}=W(e)||{},r=await(n==null?void 0:n.string());if(!r)return[];const t=new v.XmlDocument(r),i=t.childNamed("manifest"),o=t.childNamed("spine"),s=o==null?void 0:o.childrenNamed("itemref").map(d=>d.attr.idref),f=(i==null?void 0:i.childrenNamed("item").filter(d=>s.includes(d.attr.id||"")))||[];return e.files.filter(d=>f.find(l=>a?`${a}/${l.attr.href}`===d.uri:`${l.attr.href}`===d.uri))},M=e=>{var a;const n=e.childNamed("manifest");return((a=n==null?void 0:n.childrenNamed("item"))==null?void 0:a.map(r=>({href:r.attr.href||"",id:r.attr.id||"",mediaType:r.attr["media-type"]})))||[]},re=({archive:e,baseUrl:n})=>async a=>{var X;const{data:r,basePath:t}=W(e)||{},i=await ne(e);if(!r)return a;const o=await r.string();F.log(o,i);const s=new v.XmlDocument(o),f=await te(s,e,{baseUrl:n})||[],m=s.childNamed("metadata"),d=s.childNamed("manifest"),l=s.childNamed("spine"),p=s.childNamed("guide"),w=m==null?void 0:m.childNamed("dc:title"),$=(m==null?void 0:m.childrenNamed("meta"))||[],b=$.find(g=>g.attr.property==="rendition:layout"),h=$.find(g=>g.attr.property==="rendition:flow"),L=$.find(g=>g.attr.property==="rendition:spread"),U=b==null?void 0:b.val,Te=h==null?void 0:h.val,Ae=L==null?void 0:L.val,Ne=(w==null?void 0:w.val)||((X=e.files.find(({dir:g})=>g))==null?void 0:X.basename)||"",We=l==null?void 0:l.attr["page-progression-direction"],ke=(await I({archive:e})).reduce((g,u)=>u.size+g,0);return{filename:e.filename,nav:{toc:f},renditionLayout:U||i.renditionLayout||"reflowable",renditionFlow:Te||"auto",renditionSpread:Ae,title:Ne,readingDirection:We||"ltr",spineItems:(l==null?void 0:l.childrenNamed("itemref").map(g=>{var J,q,x;const u=d==null?void 0:d.childrenNamed("item").find(S=>S.attr.id===(g==null?void 0:g.attr.idref)),Le=(u==null?void 0:u.attr.href)||"",P=((J=g==null?void 0:g.attr.properties)==null?void 0:J.split(" "))||[],Pe=((q=e.files.find(S=>S.uri.endsWith(Le)))==null?void 0:q.size)||0,H=n??"";return{id:(u==null?void 0:u.attr.id)||"",href:(x=u==null?void 0:u.attr.href)!=null&&x.startsWith("https://")?u==null?void 0:u.attr.href:t?`${H}${t}/${u==null?void 0:u.attr.href}`:`${H}${u==null?void 0:u.attr.href}`,renditionLayout:U||"reflowable",...P.find(S=>S==="rendition:layout-reflowable")&&{renditionLayout:"reflowable"},progressionWeight:Pe/ke,pageSpreadLeft:P.some(S=>S==="page-spread-left")||void 0,pageSpreadRight:P.some(S=>S==="page-spread-right")||void 0,mediaType:u==null?void 0:u.attr["media-type"]}}))||[],items:M(s),guide:p==null?void 0:p.childrenNamed("reference").map(g=>({href:g.attr.href||"",title:g.attr.title||"",type:g.attr.type}))}},ie=async(e,n)=>{var t,i;const r=await((t=W(e).data)==null?void 0:t.string());if(r){const o=new v.XmlDocument(r);return{mediaType:(i=M(o).find(f=>n.endsWith(f.href)))==null?void 0:i.mediaType}}return{mediaType:ae(n)}},ae=e=>{if(e.endsWith(".css"))return"text/css; charset=UTF-8";if(e.endsWith(".jpg"))return"image/jpg";if(e.endsWith(".xhtml"))return"application/xhtml+xml";if(e.endsWith(".mp4"))return"video/mp4";if(e.endsWith(".svg"))return"image/svg+xml"},oe=({archive:e,resourcePath:n})=>async a=>{const r=Object.values(e.files).find(i=>i.uri===n);if(!r)return a;const t=await ie(e,n);return{...a,params:{...a.params,...(r==null?void 0:r.encodingFormat)&&{contentType:r.encodingFormat},...t.mediaType&&{contentType:t.mediaType}}}},D=["div","span","p","a","li","ul","ol","h1","h2","h3","h4","h5","h6","table","tr","td","th","thead","tbody","tfoot","section","article","header","footer","nav","aside","main","figure","figcaption","blockquote","pre","code","form","textarea","select","option","button","label","fieldset","legend","caption","dl","dt","dd","iframe","video","audio","canvas","script","style"],se=({archive:e,resourcePath:n})=>async a=>{const r=Object.values(e.files).find(t=>t.uri===n);if(r!=null&&r.basename.endsWith(".xhtml")){const t=a.body??await r.string();if(!new RegExp(`<(${D.join("|")})[\\s/>]`,"i").test(t))return a;const o=new RegExp(`<(${D.join("|")})(\\s[^>]*)?\\s*/>`,"gi"),s=t.replace(o,(f,m,d="")=>`<${m} ${d.trim()}></${m}>`);return{...a,body:s}}return a},O=async(e,n)=>{const a=Object.values(e.files).find(i=>i.uri===n);if(!a)throw new Error("no file found");const r={params:{}},t=[oe({archive:e,resourcePath:n}),se({archive:e,resourcePath:n}),E({archive:e,resourcePath:n}),Y({archive:e,resourcePath:n})];try{const i=await t.reduce(async(o,s)=>await s(await o),Promise.resolve(r));return F.log("Generated resource",n,i),{...i,body:i.body??await a.blob()}}catch(i){throw F.error(i),i}},ce=({archive:e,baseUrl:n})=>async()=>{var r;const a=Object.values(e.files).filter(t=>!t.dir);return{filename:e.filename,title:((r=e.files.find(({dir:t})=>t))==null?void 0:r.basename.replace(/\/$/,""))||"",renditionLayout:"pre-paginated",renditionSpread:"auto",readingDirection:"ltr",spineItems:a.filter(t=>!t.basename.endsWith(".db")).map((t,i)=>({id:`${i}.${t.basename}`,href:encodeURI(`${n}${t.uri}`),renditionLayout:"pre-paginated",progressionWeight:1/a.length,pageSpreadLeft:void 0,pageSpreadRight:void 0,mediaType:t.encodingFormat})),items:a.map((t,i)=>({id:`${i}.${t.basename}`,href:`${n}${t.uri}`}))}},de=({archive:e})=>async n=>{var i;const a=e.files.find(o=>o.basename.toLowerCase()==="comicinfo.xml");if(!a)return n;const r={...n,spineItems:n.spineItems.filter(o=>!o.id.toLowerCase().endsWith("comicinfo.xml")).map((o,s,f)=>({...o,progressionWeight:1/f.length}))},t=await a.string();try{const s=((i=new v.XmlDocument(t).childNamed("Manga"))==null?void 0:i.val)||"unknown";return{...r,readingDirection:s==="YesAndRightToLeft"?"rtl":"ltr"}}catch(o){return console.error(`Unable to parse comicinfo.xml for content
2
+ `,t),console.error(o),r}},le=e=>{var a;const n=(a=e.descendantWithPath("head"))==null?void 0:a.childrenNamed("meta").find(r=>r.attr.name==="viewport");return!!(n&&n.attr.name==="viewport")},fe=e=>e.reduce(async(n,a)=>{if(!await n||!T.isXmlBasedMimeType({mimeType:a.encodingFormat,uri:a.uri}))return!1;const t=await a.string();return t?le(new v.XmlDocument(t)):!1},Promise.resolve(!0)),pe=({archive:e})=>async n=>{if(n.renditionLayout==="reflowable"&&n.spineItems.every(r=>r.renditionLayout==="reflowable")){const r=await I({archive:e});if(await fe(r))return{...n,spineItems:n.spineItems.map(i=>({...i,renditionLayout:"pre-paginated"})),renditionLayout:"pre-paginated"}}return n},k=(e,n)=>{var t;const a=e.split(/(\d+)/),r=n.split(/(\d+)/);for(let i=0,o=a.length;i<o;i++)if(a[i]!==r[i])return(t=a[i])!=null&&t.match(/\d/)?+(a[i]||"")-+(r[i]||""):(a[i]||"").localeCompare(r[i]||"");return 1},ue=({archive:e,baseUrl:n})=>async a=>{if(a.nav)return a;const r=[...e.files].sort((s,f)=>k(s.uri,f.uri)),t=Object.values(r),i=(s,f,m,d,l)=>{const p=s.find(b=>b.title===f),[w,...$]=m;return p?w?[...s.filter(h=>h!=p),{...p,contents:[...p.contents,...i(p.contents,w,$,d,l)]}]:p.path.split("/").length>l.split("/").length?[...s.filter(h=>h!=p),{...p,path:l,href:d}]:s:w?[...s,{contents:i([],w,$,d,l),href:d,path:l,title:f}]:[...s,{contents:[],href:d,path:l,title:f}]},o=t.reduce((s,f)=>{if(f.dir)return s;const d=f.uri.split("/").slice(0,-1),[l,...p]=d;if(l){const w=T.urlJoin(n,encodeURI(f.uri)).replace(/\/$/,""),$=f.uri.replace(/\/$/,"");return i(s,l,p,w,$)}return s},[]);return o.length===0?a:{...a,nav:{toc:o}}},me={filename:"",items:[],nav:{toc:[]},readingDirection:"ltr",renditionLayout:"pre-paginated",renditionSpread:"auto",spineItems:[],title:""},z=async(e,{baseUrl:n=""}={})=>{const a=[ce({archive:e,baseUrl:n}),re({archive:e,baseUrl:n}),pe({archive:e,baseUrl:n}),de({archive:e,baseUrl:n}),ue({archive:e,baseUrl:n})];try{const r=await a.reduce(async(t,i)=>await i(await t),Promise.resolve(me));return F.log("Generated manifest",r),r}catch(r){throw F.error(r),r}},A=e=>e.substring(e.lastIndexOf("/")+1)||e,V=e=>e.endsWith("/")?e.slice(0,-1):e,he=async(e,n)=>{const a=`
3
3
  <?xml version="1.0" encoding="UTF-8"?><package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="bookid">
4
4
  <metadata>
5
5
  <meta property="rendition:layout">${n!=null&&n.useRenditionFlow?"reflowable":"pre-paginated"}</meta>
6
6
  ${n!=null&&n.useRenditionFlow?'<meta property="rendition:flow">scrolled-continuous</meta>':""}
7
7
  </metadata>
8
8
  <manifest>
9
- ${e.map(a=>`<item id="${S(a)}" href="${a}" media-type="${T.detectMimeTypeFromName(a)}"/>`).join(`
9
+ ${e.map(i=>`<item id="${A(i)}" href="${i}" media-type="${T.detectMimeTypeFromName(i)}"/>`).join(`
10
10
  `)}
11
11
  </manifest>
12
12
  <spine>
13
- ${e.map(a=>`<itemref idref="${S(a)}" />`).join(`
13
+ ${e.map(i=>`<itemref idref="${A(i)}" />`).join(`
14
14
  `)}
15
15
  </spine>
16
16
  </package>
17
- `,r=e.map(a=>({dir:!1,basename:S(a),encodingFormat:T.detectMimeTypeFromName(a),uri:a,size:100/e.length,base64:async()=>"",blob:async()=>new Blob,string:async()=>""}));return{filename:"",files:[{dir:!1,basename:"content.opf",uri:"content.opf",size:0,base64:async()=>i,blob:async()=>new Blob,string:async()=>i},...r],close:()=>Promise.resolve()}},ge=async e=>new Promise(n=>{const i=new FileReader;i.readAsDataURL(e),i.onloadend=function(){const r=i.result;n(r)}}),ye=async(e,{mimeType:n,direction:i}={mimeType:"text/plain"})=>{const r=`
17
+ `,r=e.map(i=>({dir:!1,basename:A(i),encodingFormat:T.detectMimeTypeFromName(i),uri:i,size:100/e.length,base64:async()=>"",blob:async()=>new Blob,string:async()=>""}));return{filename:"",files:[{dir:!1,basename:"content.opf",uri:"content.opf",size:0,base64:async()=>a,blob:async()=>new Blob,string:async()=>a},...r],close:()=>Promise.resolve()}},ge=async e=>new Promise(n=>{const a=new FileReader;a.readAsDataURL(e),a.onloadend=function(){const r=a.result;n(r)}}),ye=async(e,{mimeType:n,direction:a}={mimeType:"text/plain"})=>{const r=`
18
18
  <?xml version="1.0" encoding="UTF-8"?>
19
19
  <package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="ja" prefix="rendition: http://www.idpf.org/vocab/rendition/#"
20
20
  unique-identifier="ootuya-id">
@@ -25,9 +25,9 @@
25
25
  <manifest>
26
26
  <item id="p01" href="p01.txt" media-type="text/plain"/>
27
27
  </manifest>
28
- <spine page-progression-direction="${i??"ltr"}">
28
+ <spine page-progression-direction="${a??"ltr"}">
29
29
  <itemref idref="p01" />
30
30
  </spine>
31
31
  </package>
32
- `;return{filename:"content.txt",files:[{dir:!1,basename:S("generated.opf"),uri:"generated.opf",blob:async()=>new Blob([r]),string:async()=>r,base64:async()=>btoa(r),size:0},{dir:!1,basename:S("p01.txt"),uri:"p01.txt",blob:async()=>typeof e=="string"?new Blob([e]):e,string:async()=>typeof e=="string"?e:e.text(),base64:async()=>typeof e=="string"?btoa(e):ge(e),size:typeof e=="string"?e.length:e.size,encodingFormat:n}],close:()=>Promise.resolve()}},be=async(e,{orderByAlpha:n,name:i}={})=>{let r=Object.values(e.files);n&&(r=r.slice().sort((a,o)=>W(a.name,o.name)));const t={filename:i||"",files:r.map(a=>({dir:a.dir,basename:S(a.name),uri:a.name,blob:()=>a.async("blob"),string:()=>a.async("string"),base64:()=>a.async("base64"),...a.internalStream&&{stream:a.internalStream},size:a._data.uncompressedSize})),close:()=>Promise.resolve()};return v.log("Generated archive",t),t},we=async(e,{name:n}={})=>{const i=await e.getFilesArray(),r={close:()=>e.close(),filename:n??"",files:i.map(t=>({dir:!1,basename:t.file.name,size:t.file.size,uri:`${t.path}${t.file.name}`,base64:async()=>"",blob:async()=>await t.file.extract(),string:async()=>(await t.file.extract()).text()}))};return v.log("Generated archive",r),r},ve=async(e,{orderByAlpha:n,name:i}={})=>{let r=e;return n&&(r=r.slice().sort((t,a)=>W(t.name,a.name))),{filename:i||"",files:r.map(t=>({dir:t.isDir,basename:S(t.name),uri:t.name,blob:async()=>new Blob([await t.data()]),string:async()=>{const a=await t.data();return String.fromCharCode.apply(null,Array.from(new Uint16Array(a)))},base64:async()=>"",size:t.size})),close:()=>Promise.resolve()}},$e=({enableReport:e}={})=>{v.enable(!!e)},Fe=({getArchive:e,cleanArchiveAfter:n})=>{const i=new c.Subject,r=new c.Subject,t=new c.Subject,a={},o=i.pipe(c.mergeMap(d=>{const l=a[d];return!l||l.getValue().status!=="idle"?c.EMPTY:(l.next({...l.getValue(),status:"loading"}),c.from(e(d)).pipe(c.map(m=>(l.next({...l.getValue(),archive:m,status:"success"}),{key:d,archiveEntry:l})),c.catchError(m=>(l.next({...l.getValue(),status:"error",error:m}),c.EMPTY))))}),c.shareReplay()),s=o.pipe(c.switchMap(({archiveEntry:d,key:l})=>{const m=d.pipe(c.map(({locks:b})=>b)),$=t.pipe(c.map(()=>!0),c.startWith(!1),c.shareReplay());return m.pipe(c.map(b=>b<=0),c.distinctUntilChanged()).pipe(c.withLatestFrom($),c.switchMap(([b,y])=>b?y?c.of(null):c.timer(n):c.NEVER),c.tap(()=>{var b;delete a[l],(b=d.getValue().archive)==null||b.close()}))})),f=d=>{let l=!1;const m=a[d]??new c.BehaviorSubject({archive:void 0,status:"idle",locks:0,error:void 0});a[d]=m,m.next({...m.getValue(),locks:m.getValue().locks+1});const $=()=>{l||(l=!0,m.next({...m.getValue(),locks:m.getValue().locks-1}))};i.next(d);const N=m.pipe(c.map(({archive:y})=>y),c.filter(y=>!!y)),b=m.pipe(c.tap(({error:y})=>{if(y)throw y}),c.ignoreElements());return c.merge(N,b).pipe(c.first(),c.map(y=>({archive:y,release:$})),c.catchError(y=>{throw $(),y}))},g=()=>{Object.keys(a).forEach(d=>{delete a[d]}),t.next()};return c.merge(s,o).pipe(c.takeUntil(r)).subscribe(),{access:f,purge:g}};class U{constructor({onError:n,onManifestSuccess:i,...r}){this.onError=t=>new Response(String(t),{status:500}),this.epubLoader=Fe(r),this.onManifestSuccess=i??(({manifest:t})=>Promise.resolve(t)),this.onError=n??this.onError}accessArchive(n){return this.lastAccessedKey!==n&&this.epubLoader.purge(),this.lastAccessedKey=n,this.epubLoader.access(n)}fetchManifest({key:n,baseUrl:i}){const r=this.accessArchive(n).pipe(c.mergeMap(({archive:t,release:a})=>c.from(z(t,{baseUrl:i})).pipe(c.switchMap(s=>c.from(this.onManifestSuccess({manifest:s,archive:t}))),c.map(s=>new Response(JSON.stringify(s),{status:200})),c.finalize(()=>{a()}))),c.catchError(t=>c.of(this.onError(t))));return c.lastValueFrom(r)}fetchResource({key:n,resourcePath:i}){const r=this.accessArchive(n).pipe(c.mergeMap(({archive:t,release:a})=>c.from(O(t,i)).pipe(c.map(s=>new Response(s.body,{status:200,headers:{...s.params.contentType&&{"Content-Type":s.params.contentType}}})),c.finalize(()=>{a()}))),c.catchError(t=>c.of(this.onError(t))));return c.lastValueFrom(r)}}class Te extends U{constructor({getUriInfo:n,...i}){super(i),this.getUriInfo=n,this.fetchEventListener=this.fetchEventListener.bind(this)}fetchEventListener(n){try{const i=this.getUriInfo(n);if(!i)return;const r=V(i.baseUrl),t=n.request.url.substring(r.length+1),[a=""]=t.split("/"),o=decodeURIComponent(V(t.substring(a.length+1)));t.endsWith("/manifest")?n.respondWith(this.fetchManifest({key:a,baseUrl:`${r}/${a}/`})):n.respondWith(this.fetchResource({key:a,resourcePath:o}))}catch(i){n.respondWith(new Response(String(i),{status:500}))}}}h.ServiceWorkerStreamer=Te,h.Streamer=U,h.configure=$e,h.createArchiveFromArrayBufferList=ve,h.createArchiveFromJszip=be,h.createArchiveFromLibArchive=we,h.createArchiveFromText=ye,h.createArchiveFromUrls=he,h.generateManifestFromArchive=z,h.generateResourceFromArchive=O,h.getArchiveOpfInfo=k,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})});
32
+ `;return{filename:"content.txt",files:[{dir:!1,basename:A("generated.opf"),uri:"generated.opf",blob:async()=>new Blob([r]),string:async()=>r,base64:async()=>btoa(r),size:0},{dir:!1,basename:A("p01.txt"),uri:"p01.txt",blob:async()=>typeof e=="string"?new Blob([e]):e,string:async()=>typeof e=="string"?e:e.text(),base64:async()=>typeof e=="string"?btoa(e):ge(e),size:typeof e=="string"?e.length:e.size,encodingFormat:n}],close:()=>Promise.resolve()}},be=async(e,{orderByAlpha:n,name:a}={})=>{let r=Object.values(e.files);n&&(r=r.slice().sort((i,o)=>k(i.name,o.name)));const t={filename:a||"",files:r.map(i=>({dir:i.dir,basename:A(i.name),uri:i.name,blob:()=>i.async("blob"),string:()=>i.async("string"),base64:()=>i.async("base64"),...i.internalStream&&{stream:i.internalStream},size:i._data.uncompressedSize})),close:()=>Promise.resolve()};return F.log("Generated archive",t),t},we=async(e,{name:n}={})=>{const a=await e.getFilesArray(),r={close:()=>e.close(),filename:n??"",files:a.map(t=>({dir:!1,basename:t.file.name,size:t.file.size,uri:`${t.path}${t.file.name}`,base64:async()=>"",blob:async()=>await t.file.extract(),string:async()=>(await t.file.extract()).text()}))};return F.log("Generated archive",r),r},ve=async(e,{orderByAlpha:n,name:a}={})=>{let r=e;return n&&(r=r.slice().sort((t,i)=>k(t.name,i.name))),{filename:a||"",files:r.map(t=>({dir:t.isDir,basename:A(t.name),uri:t.name,blob:async()=>new Blob([await t.data()]),string:async()=>{const i=await t.data();return String.fromCharCode.apply(null,Array.from(new Uint16Array(i)))},base64:async()=>"",size:t.size})),close:()=>Promise.resolve()}},$e=({enableReport:e}={})=>{F.enable(!!e)},Fe=({getArchive:e,cleanArchiveAfter:n})=>{const a=new c.Subject,r=new c.Subject,t=new c.Subject,i={},o=a.pipe(c.mergeMap(d=>{const l=i[d];return!l||l.getValue().status!=="idle"?c.EMPTY:(l.next({...l.getValue(),status:"loading"}),c.from(e(d)).pipe(c.map(p=>(l.next({...l.getValue(),archive:p,status:"success"}),{key:d,archiveEntry:l})),c.catchError(p=>(l.next({...l.getValue(),status:"error",error:p}),c.EMPTY))))}),c.shareReplay()),s=o.pipe(c.switchMap(({archiveEntry:d,key:l})=>{const p=d.pipe(c.map(({locks:b})=>b)),w=t.pipe(c.map(()=>!0),c.startWith(!1),c.shareReplay());return p.pipe(c.map(b=>b<=0),c.distinctUntilChanged()).pipe(c.withLatestFrom(w),c.switchMap(([b,h])=>b?h?c.of(null):c.timer(n):c.NEVER),c.tap(()=>{var b;delete i[l],(b=d.getValue().archive)==null||b.close()}))})),f=d=>{let l=!1;const p=i[d]??new c.BehaviorSubject({archive:void 0,status:"idle",locks:0,error:void 0});i[d]=p,p.next({...p.getValue(),locks:p.getValue().locks+1});const w=()=>{l||(l=!0,p.next({...p.getValue(),locks:p.getValue().locks-1}))};a.next(d);const $=p.pipe(c.map(({archive:h})=>h),c.filter(h=>!!h)),b=p.pipe(c.tap(({error:h})=>{if(h)throw h}),c.ignoreElements());return c.merge($,b).pipe(c.first(),c.map(h=>({archive:h,release:w})),c.catchError(h=>{throw w(),h}))},m=()=>{Object.keys(i).forEach(d=>{delete i[d]}),t.next()};return c.merge(s,o).pipe(c.takeUntil(r)).subscribe(),{access:f,purge:m}};class B{constructor({onError:n,onManifestSuccess:a,...r}){this.onError=t=>new Response(String(t),{status:500}),this.epubLoader=Fe(r),this.onManifestSuccess=a??(({manifest:t})=>Promise.resolve(t)),this.onError=n??this.onError}accessArchive(n){return this.lastAccessedKey!==n&&this.epubLoader.purge(),this.lastAccessedKey=n,this.epubLoader.access(n)}fetchManifest({key:n,baseUrl:a}){const r=this.accessArchive(n).pipe(c.mergeMap(({archive:t,release:i})=>c.from(z(t,{baseUrl:a})).pipe(c.switchMap(s=>c.from(this.onManifestSuccess({manifest:s,archive:t}))),c.map(s=>new Response(JSON.stringify(s),{status:200})),c.finalize(()=>{i()}))),c.catchError(t=>c.of(this.onError(t))));return c.lastValueFrom(r)}fetchResource({key:n,resourcePath:a}){const r=this.accessArchive(n).pipe(c.mergeMap(({archive:t,release:i})=>c.from(O(t,a)).pipe(c.map(s=>new Response(s.body,{status:200,headers:{...s.params.contentType&&{"Content-Type":s.params.contentType}}})),c.finalize(()=>{i()}))),c.catchError(t=>c.of(this.onError(t))));return c.lastValueFrom(r)}}class Se extends B{constructor({getUriInfo:n,...a}){super(a),this.getUriInfo=n,this.fetchEventListener=this.fetchEventListener.bind(this)}fetchEventListener(n){try{const a=this.getUriInfo(n);if(!a)return;const r=V(a.baseUrl),t=n.request.url.substring(r.length+1),[i=""]=t.split("/"),o=decodeURIComponent(V(t.substring(i.length+1)));t.endsWith("/manifest")?n.respondWith(this.fetchManifest({key:i,baseUrl:`${r}/${i}/`})):n.respondWith(this.fetchResource({key:i,resourcePath:o}))}catch(a){n.respondWith(new Response(String(a),{status:500}))}}}y.ServiceWorkerStreamer=Se,y.Streamer=B,y.configure=$e,y.createArchiveFromArrayBufferList=ve,y.createArchiveFromJszip=be,y.createArchiveFromLibArchive=we,y.createArchiveFromText=ye,y.createArchiveFromUrls=he,y.generateManifestFromArchive=z,y.generateResourceFromArchive=O,y.getArchiveOpfInfo=W,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"})});
33
33
  //# sourceMappingURL=index.umd.cjs.map