@office-open/pptx
Advanced tools
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"parse-Cn_n-WuO.mjs","names":[],"sources":["../src/parts/descriptors/slide.ts","../src/parse.ts"],"sourcesContent":["/**\n * Slide (p:sld) descriptor for PPTX.\n *\n * @module\n */\n\nimport type { CustomDescriptor, WriteContext } from \"@office-open/core/descriptor\";\nimport { attr, attrNum, findChild } from \"@office-open/xml\";\nimport type { Element as XmlElement } from \"@office-open/xml\";\nimport type { SlideChild as LegacySlideChild } from \"@parts/slide/slide-child\";\nimport { SP_TREE_HEADER } from \"@shared/constants\";\n\nimport { timingDesc } from \"./animation\";\nimport { parseChild } from \"./bridge\";\nimport { shapeDesc, pictureDesc } from \"./shape\";\nimport type {\n ShapeDescriptorOptions,\n PictureDescriptorOptions,\n TextBodyDescriptorOptions,\n} from \"./shape\";\n\n// ── Types ──\n\nexport interface HeaderFooterDescriptorOptions {\n slideNumber?: boolean;\n dateTime?: boolean;\n footer?: boolean;\n header?: boolean;\n}\n\nexport interface AnimationDescriptorOptions {\n shapeId: number;\n options: unknown;\n}\n\nexport interface SlideDescriptorOptions {\n children?: SlideChild[];\n background?: BackgroundDescriptorOptions;\n transition?: TransitionDescriptorOptions;\n showMasterSp?: boolean;\n showMasterPhAnim?: boolean;\n controls?: ControlDescriptorOptions[];\n customerData?: { rId: string }[];\n headerFooter?: HeaderFooterDescriptorOptions;\n animations?: AnimationDescriptorOptions[];\n /** Hidden slide — excluded from slideshow (emits p:sld/@show=\"0\"). */\n hidden?: boolean;\n}\n\n/** Discriminated union for slide children (JSON-friendly). */\nexport type SlideChild =\n | { shape: ShapeDescriptorOptions }\n | { picture: PictureDescriptorOptions }\n | { text: TextBodyDescriptorOptions }\n | { contentPart: { rId: string } };\n\nexport interface BackgroundDescriptorOptions {\n color?: string;\n transparency?: number;\n}\n\nexport interface TransitionDescriptorOptions {\n type?:\n | \"none\"\n | \"fade\"\n | \"push\"\n | \"wipe\"\n | \"split\"\n | \"cover\"\n | \"pull\"\n | \"dissolve\"\n | \"wheel\"\n | \"random\";\n speed?: \"slow\" | \"medium\" | \"fast\";\n advanceOnClick?: boolean;\n advanceAfterMs?: number;\n}\n\nexport interface ControlDescriptorOptions {\n shapeId?: number;\n name?: string;\n showAsIcon?: boolean;\n rId?: string;\n imageWidth?: number;\n imageHeight?: number;\n}\n\n// ── Slide (p:sld) descriptor ──\n\nexport const slideDesc: CustomDescriptor<SlideDescriptorOptions> = {\n kind: \"custom\",\n\n stringify(opts, ctx) {\n const parts: string[] = [];\n\n // Opening tag with namespace declarations\n const sldAttrs: string[] = [];\n if (opts.showMasterSp === false) sldAttrs.push(' showMasterSp=\"0\"');\n if (opts.showMasterPhAnim === false) sldAttrs.push(' showMasterPhAnim=\"0\"');\n if (opts.hidden) sldAttrs.push(' show=\"0\"');\n parts.push(\n `<p:sld xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\"${sldAttrs.join(\"\")}>`,\n );\n\n // p:cSld — common slide data\n parts.push(\"<p:cSld>\");\n\n if (opts.background) {\n parts.push(stringifyBackground(opts.background));\n }\n\n // p:spTree — shape tree\n parts.push(\"<p:spTree>\");\n parts.push(SP_TREE_HEADER);\n\n if (opts.children) {\n for (const child of opts.children) {\n const xml = stringifySlideChild(child, ctx);\n if (xml) parts.push(xml);\n }\n }\n\n parts.push(\"</p:spTree>\");\n\n // custDataLst\n if (opts.customerData && opts.customerData.length > 0) {\n const cdItems = opts.customerData.map((d) => `<p:custData r:id=\"${d.rId}\"/>`).join(\"\");\n parts.push(`<p:custDataLst>${cdItems}</p:custDataLst>`);\n }\n\n // controls\n if (opts.controls && opts.controls.length > 0) {\n const ctrlItems = opts.controls\n .map((c) => {\n const attrs: string[] = [];\n if (c.shapeId !== undefined) attrs.push(`spid=\"${c.shapeId}\"`);\n if (c.name) attrs.push(`name=\"${c.name}\"`);\n if (c.showAsIcon) attrs.push('showAsIcon=\"1\"');\n if (c.rId) attrs.push(`r:id=\"${c.rId}\"`);\n if (c.imageWidth !== undefined) attrs.push(`imgW=\"${c.imageWidth}\"`);\n if (c.imageHeight !== undefined) attrs.push(`imgH=\"${c.imageHeight}\"`);\n return `<p:control ${attrs.join(\" \")}/>`;\n })\n .join(\"\");\n parts.push(`<p:controls>${ctrlItems}</p:controls>`);\n }\n\n // Header/Footer (p:hf)\n if (opts.headerFooter) {\n const hf = opts.headerFooter;\n const hfChildren: string[] = [];\n if (hf.slideNumber) hfChildren.push(\"<p:sldNum/>\");\n if (hf.dateTime) hfChildren.push(\"<p:dt/>\");\n if (hf.footer) hfChildren.push(\"<p:ftr/>\");\n if (hf.header) hfChildren.push(\"<p:hdr/>\");\n if (hfChildren.length > 0) parts.push(`<p:hf>${hfChildren.join(\"\")}</p:hf>`);\n }\n\n parts.push(\"</p:cSld>\");\n\n // p:clrMapOvr\n parts.push(\"<p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr>\");\n\n // p:transition (optional)\n if (opts.transition) {\n parts.push(stringifyTransition(opts.transition));\n }\n\n parts.push(\"</p:sld>\");\n return parts.join(\"\");\n },\n\n parse(el, _ctx) {\n const result: Record<string, unknown> = {};\n\n // Root attributes\n if (el.attributes) {\n if (el.attributes[\"showMasterSp\"] !== undefined)\n result.showMasterSp = el.attributes[\"showMasterSp\"] !== \"0\";\n if (el.attributes[\"showMasterPhAnim\"] !== undefined)\n result.showMasterPhAnim = el.attributes[\"showMasterPhAnim\"] !== \"0\";\n if (el.attributes[\"show\"] === \"0\") result.hidden = true;\n }\n\n // p:cSld\n const cSld = findChild(el, \"p:cSld\");\n if (cSld) {\n // Background\n const bg = findChild(cSld, \"p:bg\");\n if (bg) result.background = readBackground(bg);\n\n // Shape tree\n const spTree = findChild(cSld, \"p:spTree\");\n if (spTree) {\n const children: LegacySlideChild[] = [];\n if (spTree.elements) {\n for (const child of spTree.elements) {\n // Skip tree container structure\n if (child.name === \"p:nvGrpSpPr\" || child.name === \"p:grpSpPr\") continue;\n const parsed = parseChild(child, _ctx);\n if (parsed !== undefined) children.push(parsed);\n }\n }\n if (children.length > 0) result.children = children;\n }\n\n // Header/Footer (p:hf)\n const hf = findChild(cSld, \"p:hf\");\n if (hf) {\n const hfOpts: HeaderFooterDescriptorOptions = {};\n if (findChild(hf, \"p:sldNum\")) hfOpts.slideNumber = true;\n if (findChild(hf, \"p:dt\")) hfOpts.dateTime = true;\n if (findChild(hf, \"p:ftr\")) hfOpts.footer = true;\n if (findChild(hf, \"p:hdr\")) hfOpts.header = true;\n if (hfOpts.slideNumber || hfOpts.dateTime || hfOpts.footer || hfOpts.header)\n result.headerFooter = hfOpts;\n }\n }\n\n // p:transition\n const transition = findChild(el, \"p:transition\");\n if (transition) result.transition = readTransition(transition);\n\n // p:timing → animations\n const timing = findChild(el, \"p:timing\");\n if (timing) {\n const timingOpts = timingDesc.parse(timing, _ctx);\n if (timingOpts.entries && timingOpts.entries.length > 0) {\n const animations: AnimationDescriptorOptions[] = [];\n for (const entry of timingOpts.entries) {\n animations.push({ shapeId: entry.spid, options: entry.options });\n }\n result.animations = animations;\n }\n }\n\n // custDataLst\n const custDataLst = findChild(el, \"p:custDataLst\");\n if (custDataLst) {\n const items: { rId: string }[] = [];\n for (const cd of custDataLst.elements ?? []) {\n if (cd.name === \"p:custData\") {\n const rId = attr(cd, \"r:id\");\n if (rId) items.push({ rId });\n }\n }\n if (items.length > 0) result.customerData = items;\n }\n\n // controls\n const controls = findChild(el, \"p:controls\");\n if (controls) {\n const items: ControlDescriptorOptions[] = [];\n for (const ctrl of controls.elements ?? []) {\n if (ctrl.name !== \"p:control\") continue;\n const item: ControlDescriptorOptions = {};\n const spid = attrNum(ctrl, \"spid\");\n if (spid !== undefined) item.shapeId = spid;\n const name = attr(ctrl, \"name\");\n if (name) item.name = name;\n if (attr(ctrl, \"showAsIcon\") === \"1\") item.showAsIcon = true;\n const rId = attr(ctrl, \"r:id\");\n if (rId) item.rId = rId;\n const imgW = attrNum(ctrl, \"imgW\");\n if (imgW !== undefined) item.imageWidth = imgW;\n const imgH = attrNum(ctrl, \"imgH\");\n if (imgH !== undefined) item.imageHeight = imgH;\n items.push(item);\n }\n if (items.length > 0) result.controls = items;\n }\n\n return result as unknown as SlideDescriptorOptions;\n },\n};\n\n// ── Child serializer ──\n\nfunction stringifySlideChild(child: SlideChild, ctx: WriteContext): string | undefined {\n if (\"shape\" in child) return shapeDesc.stringify(child.shape, ctx);\n if (\"picture\" in child) return pictureDesc.stringify(child.picture, ctx);\n if (\"contentPart\" in child) return `<p:contentPart r:id=\"${child.contentPart.rId}\"/>`;\n return undefined;\n}\n\n// ── Background helpers ──\n\nfunction stringifyBackground(opts: BackgroundDescriptorOptions): string {\n if (opts.color) {\n const alphaAttr =\n opts.transparency !== undefined\n ? `><a:srgbClr val=\"${opts.color.replace(\"#\", \"\")}\"><a:alpha val=\"${Math.round((100 - opts.transparency) * 1000)}\"/></a:srgbClr></p:bgPr`\n : `><a:solidFill><a:srgbClr val=\"${opts.color.replace(\"#\", \"\")}\"/></a:solidFill></p:bgPr`;\n return `<p:bg><p:bgPr${alphaAttr}></p:bg>`;\n }\n return \"<p:bg/>\";\n}\n\nfunction readBackground(bg: XmlElement): BackgroundDescriptorOptions {\n const result: BackgroundDescriptorOptions = {};\n const bgPr = findChild(bg, \"p:bgPr\");\n if (bgPr) {\n const solidFill = findChild(bgPr, \"a:solidFill\");\n if (solidFill) {\n const srgbClr = findChild(solidFill, \"a:srgbClr\");\n if (srgbClr?.attributes?.[\"val\"]) {\n result.color = String(srgbClr.attributes[\"val\"]);\n const alpha = findChild(srgbClr, \"a:alpha\");\n if (alpha?.attributes?.[\"val\"]) {\n result.transparency = 100 - Number(alpha.attributes[\"val\"]) / 1000;\n }\n }\n }\n }\n return result;\n}\n\n// ── Transition helpers ──\n\nfunction stringifyTransition(opts: TransitionDescriptorOptions): string {\n const parts: string[] = [];\n\n if (opts.type === \"none\") return \"\";\n if (opts.type === \"fade\") parts.push(\"<p:fade/>\");\n else if (opts.type === \"push\") parts.push('<p:push dir=\"l\"/>');\n else if (opts.type === \"wipe\") parts.push('<p:wipe dir=\"d\"/>');\n else if (opts.type === \"split\") parts.push('<p:split orient=\"horz\"/>');\n else if (opts.type === \"cover\") parts.push('<p:cover dir=\"l\"/>');\n else if (opts.type === \"pull\") parts.push('<p:pull dir=\"l\"/>');\n else if (opts.type === \"dissolve\") parts.push(\"<p:dissolve/>\");\n else if (opts.type === \"wheel\") parts.push('<p:wheel spokes=\"4\"/>');\n else if (opts.type === \"random\") parts.push(\"<p:random/>\");\n\n const attrs: string[] = [];\n if (opts.speed) attrs.push(`spd=\"${opts.speed}\"`);\n if (opts.advanceOnClick !== undefined) attrs.push(`advClick=\"${opts.advanceOnClick ? 1 : 0}\"`);\n if (opts.advanceAfterMs !== undefined) attrs.push(`advTm=\"${opts.advanceAfterMs}\"`);\n\n const attrStr = attrs.length ? \" \" + attrs.join(\" \") : \"\";\n const body = parts.join(\"\");\n return body ? `<p:transition${attrStr}>${body}</p:transition>` : `<p:transition${attrStr}/>`;\n}\n\nfunction readTransition(el: XmlElement): TransitionDescriptorOptions {\n const result: TransitionDescriptorOptions = {};\n\n if (el.attributes) {\n if (el.attributes[\"spd\"] !== undefined)\n result.speed = el.attributes[\"spd\"] as \"slow\" | \"medium\" | \"fast\";\n if (el.attributes[\"advClick\"] !== undefined)\n result.advanceOnClick = el.attributes[\"advClick\"] === \"1\";\n if (el.attributes[\"advTm\"] !== undefined)\n result.advanceAfterMs = Number(el.attributes[\"advTm\"]);\n }\n\n // Detect transition type from child elements\n if (findChild(el, \"p:fade\")) result.type = \"fade\";\n else if (findChild(el, \"p:push\")) result.type = \"push\";\n else if (findChild(el, \"p:wipe\")) result.type = \"wipe\";\n else if (findChild(el, \"p:split\")) result.type = \"split\";\n else if (findChild(el, \"p:cover\")) result.type = \"cover\";\n else if (findChild(el, \"p:pull\")) result.type = \"pull\";\n else if (findChild(el, \"p:dissolve\")) result.type = \"dissolve\";\n else if (findChild(el, \"p:wheel\")) result.type = \"wheel\";\n else if (findChild(el, \"p:random\")) result.type = \"random\";\n\n return result;\n}\n","import type { ParsedArchive } from \"@office-open/core\";\nimport {\n appPropertiesDesc,\n customPropertiesDesc,\n parseArchive,\n parseCorePropsElement,\n} from \"@office-open/core\";\nimport type { DataType } from \"@office-open/core\";\nimport { toUint8Array } from \"@office-open/core\";\nimport type { ReadContext } from \"@office-open/core/descriptor\";\nimport { themeDesc } from \"@office-open/core/theme\";\nimport type { Element } from \"@office-open/xml\";\nimport { attr, attrNum, findChild } from \"@office-open/xml\";\n\nimport { PptxReadContext, ParseContext } from \"./context\";\nimport { backgroundDesc } from \"./parts/descriptors/background\";\nimport { parseChild } from \"./parts/descriptors/bridge\";\nimport { commentAuthorsDesc, slideCommentsDesc } from \"./parts/descriptors/comments\";\nimport { notesMasterDesc } from \"./parts/descriptors/notes-master\";\nimport { notesSlideDesc } from \"./parts/descriptors/notes-slide\";\nimport { presPropsDesc } from \"./parts/descriptors/presentation-properties\";\nimport { slideDesc } from \"./parts/descriptors/slide\";\nimport { slideLayoutDesc } from \"./parts/descriptors/slide-layout\";\nimport { tableStylesDesc } from \"./parts/descriptors/table-styles\";\nimport { viewPropsDesc } from \"./parts/descriptors/view-properties\";\nimport type { SlideChild } from \"./parts/slide/slide-child\";\n\nexport { parseArchive };\n\nimport type { SlideLayoutType } from \"./parts/slide-layout\";\nimport type {\n LayoutDefinition,\n MasterChild,\n MasterDefinition,\n SlideOptions,\n SlideCommentOptions,\n PresentationOptions,\n} from \"./shared/file\";\n\n/**\n * All part paths extracted from the PPTX package.\n * Field names correspond directly to the OOXML directory structure.\n */\nexport interface PptxPartRefs {\n /** ppt/theme/themeN.xml */\n themes: string[];\n /** ppt/notesMasters/notesMasterN.xml */\n notesMasters: string[];\n /** ppt/commentAuthors.xml */\n commentAuthors?: string;\n /** ppt/comments/commentN.xml (from slide rels) */\n comments: string[];\n /** ppt/charts/chartN.xml (from slide rels) */\n charts: string[];\n /** ppt/diagrams/dataN.xml (from slide rels) */\n diagramData: string[];\n /** ppt/media/* (all media files) */\n media: string[];\n}\n\nexport interface PptxDocument {\n doc: ParsedArchive;\n /** ppt/presentation.xml root element (p:presentation) */\n presentation?: Element;\n /** ppt/slides/slideN.xml */\n slides: string[];\n /** ppt/slideMasters/slideMasterN.xml */\n slideMasters: string[];\n /** ppt/slideLayouts/slideLayoutN.xml */\n slideLayouts: string[];\n /** ppt/notesSlides/notesSlideN.xml */\n notesSlides: string[];\n partRefs: PptxPartRefs;\n /** ppt/presProps.xml */\n presProps?: string;\n /** ppt/viewProps.xml */\n viewProps?: string;\n /** ppt/tableStyles.xml */\n tableStyles?: string;\n /** docProps/core.xml */\n coreProps?: string;\n /** docProps/app.xml */\n appProps?: string;\n /** docProps/custom.xml */\n customProps?: string;\n}\n\nfunction resolveRelsPath(target: string): string {\n if (target.startsWith(\"/\")) return target.slice(1);\n if (target.startsWith(\"../\")) return target.replace(\"../\", \"ppt/\");\n return `ppt/${target}`;\n}\n\nfunction sortByNumber(paths: string[]): string[] {\n return paths.sort((a, b) => {\n const numA = parseInt(a.match(/(\\d+)/)?.[1] ?? \"0\", 10);\n const numB = parseInt(b.match(/(\\d+)/)?.[1] ?? \"0\", 10);\n return numA - numB;\n });\n}\n\nfunction xmlKeys(keys: string[]): string[] {\n return keys.filter((k) => k.endsWith(\".xml\"));\n}\n\nfunction parseRootRels(doc: ParsedArchive): {\n coreProps?: string;\n appProps?: string;\n customProps?: string;\n} {\n const relsEl = doc.get(\"_rels/.rels\");\n if (!relsEl) return {};\n\n let coreProps: string | undefined;\n let appProps: string | undefined;\n let customProps: string | undefined;\n\n for (const child of relsEl.elements ?? []) {\n if (child.name !== \"Relationship\") continue;\n const type = attr(child, \"Type\") ?? \"\";\n const target = attr(child, \"Target\") ?? \"\";\n if (!target) continue;\n\n const path = target.startsWith(\"/\") ? target.slice(1) : target;\n\n if (type.includes(\"/core-properties\")) {\n coreProps = path;\n } else if (type.includes(\"/extended-properties\")) {\n appProps = path;\n } else if (type.includes(\"/custom-properties\")) {\n customProps = path;\n }\n }\n\n return { coreProps, appProps, customProps };\n}\n\nfunction parseSlideRels(doc: ParsedArchive, slidePaths: string[], refs: PptxPartRefs): void {\n const commentsSet = new Set(refs.comments);\n const chartsSet = new Set(refs.charts);\n const diagramDataSet = new Set(refs.diagramData);\n const mediaSet = new Set(refs.media);\n\n for (const slidePath of slidePaths) {\n const parts = slidePath.split(\"/\");\n const fileName = parts.pop()!;\n const relsPath = `${parts.join(\"/\")}/_rels/${fileName}.rels`;\n\n const relsEl = doc.get(relsPath);\n if (!relsEl) continue;\n\n for (const child of relsEl.elements ?? []) {\n if (child.name !== \"Relationship\") continue;\n const type = attr(child, \"Type\") ?? \"\";\n const target = attr(child, \"Target\") ?? \"\";\n if (!target) continue;\n\n const path = resolveRelsPath(target);\n\n if (type.includes(\"/comments\") && !type.includes(\"commentAuthors\")) {\n commentsSet.add(path);\n } else if (type.includes(\"/chart\")) {\n chartsSet.add(path);\n } else if (type.includes(\"/diagramData\")) {\n diagramDataSet.add(path);\n } else if (type.includes(\"/image\") || type.includes(\"/video\") || type.includes(\"/media\")) {\n mediaSet.add(path);\n }\n }\n }\n\n refs.comments = [...commentsSet];\n refs.charts = [...chartsSet];\n refs.diagramData = [...diagramDataSet];\n refs.media = [...mediaSet];\n}\n\nexport function parsePptx(data: DataType): PptxDocument {\n const uint8 = toUint8Array(data);\n const doc = parseArchive(uint8);\n\n const presentation = doc.get(\"ppt/presentation.xml\");\n\n const relsXml = doc.get(\"ppt/_rels/presentation.xml.rels\");\n const slides: string[] = [];\n const slideMasters: string[] = [];\n const themes: string[] = [];\n const notesMasters: string[] = [];\n let presProps: string | undefined;\n let viewProps: string | undefined;\n let tableStyles: string | undefined;\n let commentAuthors: string | undefined;\n\n if (relsXml) {\n for (const child of relsXml.elements ?? []) {\n if (child.name !== \"Relationship\") continue;\n const type = attr(child, \"Type\") ?? \"\";\n const target = attr(child, \"Target\") ?? \"\";\n if (!target) continue;\n\n const path = resolveRelsPath(target);\n\n if (type.includes(\"/slideMaster\")) {\n slideMasters.push(path);\n } else if (\n type.includes(\"/slide\") &&\n !type.includes(\"slideLayout\") &&\n !type.includes(\"slideMaster\")\n ) {\n slides.push(path);\n } else if (type.includes(\"/theme\")) {\n themes.push(path);\n } else if (type.includes(\"/notesMaster\")) {\n notesMasters.push(path);\n } else if (type.includes(\"/presProps\")) {\n presProps = path;\n } else if (type.includes(\"/viewProps\")) {\n viewProps = path;\n } else if (type.includes(\"/tableStyles\")) {\n tableStyles = path;\n } else if (type.includes(\"/commentAuthors\")) {\n commentAuthors = path;\n }\n }\n }\n\n sortByNumber(slides);\n sortByNumber(slideMasters);\n sortByNumber(themes);\n sortByNumber(notesMasters);\n\n const slideLayouts = sortByNumber(xmlKeys(doc.keys(\"ppt/slideLayouts/\")));\n const notesSlides = sortByNumber(xmlKeys(doc.keys(\"ppt/notesSlides/\")));\n\n const partRefs: PptxPartRefs = {\n themes,\n notesMasters,\n commentAuthors,\n comments: [],\n charts: [],\n diagramData: [],\n media: doc.keys(\"ppt/media/\"),\n };\n\n parseSlideRels(doc, slides, partRefs);\n sortByNumber(partRefs.comments);\n sortByNumber(partRefs.charts);\n sortByNumber(partRefs.diagramData);\n\n const { coreProps, appProps, customProps } = parseRootRels(doc);\n\n return {\n doc,\n presentation,\n slides,\n slideMasters,\n slideLayouts,\n notesSlides,\n partRefs,\n presProps,\n viewProps,\n tableStyles,\n coreProps,\n appProps,\n customProps,\n };\n}\n\n/**\n * Parse a single slide's relationship file into a Map<rId, path>.\n */\nfunction parseSlideRelMap(doc: ParsedArchive, slidePath: string): Map<string, string> {\n const rels = new Map<string, string>();\n const parts = slidePath.split(\"/\");\n const fileName = parts.pop()!;\n const relsPath = `${parts.join(\"/\")}/_rels/${fileName}.rels`;\n\n const relsEl = doc.get(relsPath);\n if (!relsEl) return rels;\n\n for (const child of relsEl.elements ?? []) {\n if (child.name !== \"Relationship\") continue;\n const id = attr(child, \"Id\") ?? \"\";\n const target = attr(child, \"Target\") ?? \"\";\n if (!id || !target) continue;\n // External links (hyperlinks) keep their original URL target\n if (attr(child, \"TargetMode\") === \"External\") {\n rels.set(id, target);\n } else {\n rels.set(id, resolveRelsPath(target));\n }\n }\n\n return rels;\n}\n\n/**\n * Build a map from each path to the rel target matching a predicate.\n */\nfunction resolveRelTargets(\n doc: ParsedArchive,\n paths: string[],\n predicate: (target: string) => boolean,\n): Map<string, string> {\n const map = new Map<string, string>();\n for (const path of paths) {\n for (const target of parseSlideRelMap(doc, path).values()) {\n if (predicate(target)) map.set(path, target);\n }\n }\n return map;\n}\n\n/**\n * Parse p14:sectionLst from presentation.xml and map each slide path to its\n * section name. Bridges p14:sldId (by slide id) -> p:sldIdLst (slide id ->\n * rId) -> presentation rels (rId -> path).\n */\nfunction parseSlideSections(\n presentation: Element | undefined,\n doc: ParsedArchive,\n): Map<string, string> {\n const pathToSection = new Map<string, string>();\n if (!presentation) return pathToSection;\n\n const extLst = findChild(presentation, \"p:extLst\");\n if (!extLst) return pathToSection;\n\n let sectionLst: Element | undefined;\n for (const ext of extLst.elements ?? []) {\n if (ext.name !== \"p:ext\") continue;\n if (attr(ext, \"uri\") !== \"{521415D9-36F7-43E2-AB2F-B90AF26B5E84}\") continue;\n sectionLst = findChild(ext, \"p14:sectionLst\");\n if (sectionLst) break;\n }\n if (!sectionLst) return pathToSection;\n\n // slideId -> sectionName\n const sectionBySlideId = new Map<number, string>();\n for (const section of sectionLst.elements ?? []) {\n if (section.name !== \"p14:section\") continue;\n const name = attr(section, \"name\");\n if (!name) continue;\n const sldIdLst = findChild(section, \"p14:sldIdLst\");\n for (const sldId of sldIdLst?.elements ?? []) {\n if (sldId.name !== \"p14:sldId\") continue;\n const id = attrNum(sldId, \"id\");\n if (id !== undefined) sectionBySlideId.set(id, name);\n }\n }\n if (sectionBySlideId.size === 0) return pathToSection;\n\n // slideId -> rId (from p:sldIdLst)\n const sldIdLst = findChild(presentation, \"p:sldIdLst\");\n const rIdBySlideId = new Map<number, string>();\n for (const sldId of sldIdLst?.elements ?? []) {\n if (sldId.name !== \"p:sldId\") continue;\n const id = attrNum(sldId, \"id\");\n const rId = attr(sldId, \"r:id\");\n if (id !== undefined && rId) rIdBySlideId.set(id, rId);\n }\n\n // rId -> path (from presentation.xml.rels)\n const relsEl = doc.get(\"ppt/_rels/presentation.xml.rels\");\n const pathByRId = new Map<string, string>();\n for (const child of relsEl?.elements ?? []) {\n if (child.name !== \"Relationship\") continue;\n const id = attr(child, \"Id\");\n const target = attr(child, \"Target\");\n if (id && target) pathByRId.set(id, resolveRelsPath(target));\n }\n\n for (const [slideId, name] of sectionBySlideId) {\n const rId = rIdBySlideId.get(slideId);\n if (!rId) continue;\n const path = pathByRId.get(rId);\n if (path) pathToSection.set(path, name);\n }\n\n return pathToSection;\n}\n\n/**\n * Parse a .pptx file and convert it into PresentationOptions.\n *\n * This is the main public API for parsing PPTX files.\n * The returned options can be passed directly to `new Presentation(parsed)`\n * to recreate the presentation.\n *\n * @param data - Raw bytes of a .pptx file\n * @returns Parsed presentation options\n */\nexport function parsePresentation(data: DataType): PresentationOptions {\n const pptx = parsePptx(data);\n const opts: Partial<PresentationOptions> = {};\n const sectionBySlidePath = parseSlideSections(pptx.presentation, pptx.doc);\n\n // 1. Parse slide size from p:sldSz\n if (pptx.presentation) {\n const sldSz = findChild(pptx.presentation, \"p:sldSz\");\n if (sldSz) {\n const cx = attrNum(sldSz, \"cx\");\n const cy = attrNum(sldSz, \"cy\");\n if (cx === 12192000 && cy === 6858000) {\n opts.size = \"16:9\";\n } else if (cx === 9144000 && cy === 6858000) {\n opts.size = \"4:3\";\n } else if (cx && cy) {\n opts.size = { width: cx, height: cy };\n }\n }\n }\n\n // 2. Parse core properties\n if (pptx.coreProps) {\n const corePropsEl = pptx.doc.get(pptx.coreProps);\n if (corePropsEl) {\n const cp = parseCorePropsElement(corePropsEl);\n if (cp.title) opts.title = cp.title;\n if (cp.subject) opts.subject = cp.subject;\n if (cp.creator) opts.creator = cp.creator;\n if (cp.keywords) opts.keywords = cp.keywords;\n if (cp.description) opts.description = cp.description;\n if (cp.lastModifiedBy) opts.lastModifiedBy = cp.lastModifiedBy;\n if (cp.revision !== undefined) opts.revision = cp.revision;\n if (cp.lastPrinted) opts.lastPrinted = cp.lastPrinted;\n if (cp.created) opts.created = cp.created;\n if (cp.modified) opts.modified = cp.modified;\n }\n }\n\n // 2b. Parse extended (app) properties\n if (pptx.appProps) {\n const appPropsEl = pptx.doc.get(pptx.appProps);\n if (appPropsEl) {\n const ap = appPropertiesDesc.parse(appPropsEl, {} as ReadContext);\n if (ap && Object.keys(ap).length > 0) opts.appProperties = ap;\n }\n }\n\n // 2c. Parse custom properties\n if (pptx.customProps) {\n const customPropsEl = pptx.doc.get(pptx.customProps);\n if (customPropsEl) {\n const cp = customPropertiesDesc.parse(customPropsEl, {} as ReadContext);\n if (cp.properties?.length) opts.customProperties = cp.properties;\n }\n }\n\n // 3. Parse show options from presProps\n if (pptx.presProps) {\n const presPropsEl = pptx.doc.get(pptx.presProps);\n if (presPropsEl) {\n const presPropsOpts = presPropsDesc.parse(presPropsEl, {} as ReadContext);\n if (presPropsOpts.show) opts.show = presPropsOpts.show;\n }\n }\n\n // 3b. Parse view properties\n if (pptx.viewProps) {\n const viewPropsEl = pptx.doc.get(pptx.viewProps);\n if (viewPropsEl) {\n const viewOpts = viewPropsDesc.parse(viewPropsEl, {} as ReadContext);\n if (viewOpts.lastView || viewOpts.showComments !== undefined || viewOpts.gridSpacing) {\n opts.view = viewOpts;\n }\n }\n }\n\n // 3c. Parse table styles\n if (pptx.tableStyles) {\n const tableStylesEl = pptx.doc.get(pptx.tableStyles);\n if (tableStylesEl) {\n const tableStylesResult = tableStylesDesc.parse(tableStylesEl, {} as ReadContext);\n if (tableStylesResult.opts) opts.tableStyles = tableStylesResult.opts;\n }\n }\n\n // 4. Build relationship maps\n const masterThemePaths = resolveRelTargets(pptx.doc, pptx.slideMasters, (t) =>\n t.includes(\"/theme\"),\n );\n const layoutMasterPaths = resolveRelTargets(pptx.doc, pptx.slideLayouts, (t) =>\n t.includes(\"/slideMaster\"),\n );\n const slideLayoutPaths = resolveRelTargets(pptx.doc, pptx.slides, (t) =>\n t.includes(\"/slideLayout\"),\n );\n\n // 5. Parse masters\n const masterCount = pptx.slideMasters.length;\n const masterDefs: MasterDefinition[] = [];\n const masterReadCtx = new PptxReadContext(new ParseContext(pptx, new Map()));\n for (let mi = 0; mi < masterCount; mi++) {\n const masterPath = pptx.slideMasters[mi];\n const masterEl = pptx.doc.get(masterPath);\n if (!masterEl) continue;\n\n // Theme\n const themePath = masterThemePaths.get(masterPath);\n const themeEl = themePath ? pptx.doc.get(themePath) : undefined;\n const themeOptions = themeEl ? themeDesc.parse(themeEl, masterReadCtx) : undefined;\n\n // Background (inline: findChild → backgroundDesc.parse)\n const cSld = findChild(masterEl, \"p:cSld\");\n const bg = cSld ? findChild(cSld, \"p:bg\") : undefined;\n const masterBackground = bg ? backgroundDesc.parse(bg, masterReadCtx) : undefined;\n const hasBackground = masterBackground && Object.keys(masterBackground).length > 0;\n\n // Children: extract non-placeholder shapes from spTree\n const spTree = cSld ? findChild(cSld, \"p:spTree\") : undefined;\n const masterChildren: SlideChild[] = [];\n if (spTree) {\n for (const child of spTree.elements ?? []) {\n // Skip nvGrpSpPr/grpSpPr (tree container structure, not shapes)\n if (child.name === \"p:nvGrpSpPr\" || child.name === \"p:grpSpPr\") continue;\n // Skip placeholder shapes (generated by DefaultSlideMaster template)\n if (child.name === \"p:sp\") {\n const nvSpPr = findChild(child, \"p:nvSpPr\");\n const nvPr = nvSpPr ? findChild(nvSpPr, \"p:nvPr\") : undefined;\n if (nvPr && findChild(nvPr, \"p:ph\")) continue;\n }\n const parsed = parseChild(child, masterReadCtx);\n if (parsed !== undefined) masterChildren.push(parsed);\n }\n }\n\n // Layouts belonging to this master\n const masterLayouts: LayoutDefinition[] = [];\n for (const layoutPath of pptx.slideLayouts) {\n if (layoutMasterPaths.get(layoutPath) !== masterPath) continue;\n const layoutEl = pptx.doc.get(layoutPath);\n if (layoutEl) {\n const layoutOpts = slideLayoutDesc.parse(layoutEl, masterReadCtx);\n const layoutDef: LayoutDefinition = {\n type: (layoutOpts.type ?? \"blank\") as SlideLayoutType,\n };\n if (layoutOpts.placeholders) layoutDef.placeholders = layoutOpts.placeholders;\n masterLayouts.push(layoutDef);\n }\n }\n\n const masterName = themeOptions?.name ?? `master${mi + 1}`;\n const masterDef: Partial<MasterDefinition> = {};\n masterDef.name = masterName;\n if (themeOptions) masterDef.theme = themeOptions;\n if (hasBackground) masterDef.background = masterBackground;\n // MasterChild (shared) declares only { shape }; parse yields the full\n // SlideChild union (parts-layer). The shared/parts split prevents unifying\n // them (SlideChild cannot move to shared — circular dep), so the cast stays\n // local to this known impedance.\n if (masterChildren.length > 0) masterDef.children = masterChildren as unknown as MasterChild[];\n if (masterLayouts.length > 0) masterDef.layouts = masterLayouts;\n masterDefs.push(masterDef as MasterDefinition);\n }\n\n // Only set masters if there's more than one (single master is auto-created)\n if (masterCount > 1) {\n opts.masters = masterDefs;\n }\n\n // 5b. Parse notes masters\n for (const nmPath of pptx.partRefs.notesMasters) {\n const nmEl = pptx.doc.get(nmPath);\n if (nmEl) {\n const nmOpts = notesMasterDesc.parse(nmEl, masterReadCtx);\n if (nmOpts.options) {\n opts.includeNotesMaster = true;\n opts.notesMasterOptions = nmOpts.options;\n }\n }\n }\n\n // 5c. Parse handout masters (no separate handling needed, just mark inclusion)\n // Handout masters are referenced from presentation.xml rels but not stored in PptxDocument currently\n\n // 6. Parse comment authors\n const commentAuthors = new Map<number, { name: string; initials: string }>();\n if (pptx.partRefs.commentAuthors) {\n const authorsEl = pptx.doc.get(pptx.partRefs.commentAuthors);\n if (authorsEl) {\n const authors = commentAuthorsDesc.parse(authorsEl, masterReadCtx);\n for (const a of authors) {\n commentAuthors.set(a.id, { name: a.name, initials: a.initials });\n }\n }\n }\n\n // 7. Parse slides with layout and master references\n const result: SlideOptions[] = [];\n for (let si = 0; si < pptx.slides.length; si++) {\n const slidePath = pptx.slides[si];\n const slideEl = pptx.doc.get(slidePath);\n if (!slideEl) continue;\n\n const slideRels = parseSlideRelMap(pptx.doc, slidePath);\n const ctx = new ParseContext(pptx, slideRels);\n const readCtx = new PptxReadContext(ctx);\n // slideDesc.parse returns SlideDescriptorOptions (internal descriptor type:\n // 4-variant SlideChild, no layout/master/comments/notes/section). We enrich\n // it with those public-API fields below and coerce to SlideOptions at push.\n // Record bridges this descriptor/public impedance — slide.ts itself is a\n // known stringify≠parse split, so the wrapper stays until that is resolved.\n const slideOpts = slideDesc.parse(slideEl, readCtx) as Record<string, unknown>;\n\n // Resolve layout → master\n const layoutPath = slideLayoutPaths.get(slidePath);\n if (layoutPath) {\n const layoutEl = pptx.doc.get(layoutPath);\n if (layoutEl) {\n const layoutOpts = slideLayoutDesc.parse(layoutEl, readCtx);\n slideOpts.layout = (layoutOpts.type ?? \"blank\") as SlideLayoutType;\n }\n\n const resolvedMasterPath = layoutMasterPaths.get(layoutPath);\n if (resolvedMasterPath) {\n const masterIdx = pptx.slideMasters.indexOf(resolvedMasterPath);\n if (masterIdx >= 0 && masterDefs[masterIdx]) {\n slideOpts.master = masterDefs[masterIdx].name;\n }\n }\n }\n\n // Comments via slide rels\n for (const [, relPath] of slideRels) {\n if (!relPath.includes(\"/comments/\")) continue;\n const commentsEl = pptx.doc.get(relPath);\n if (!commentsEl) continue;\n\n const parsedComments = slideCommentsDesc.parse(commentsEl, readCtx);\n if (parsedComments.length > 0) {\n const comments: Partial<SlideCommentOptions>[] = [];\n for (const cm of parsedComments) {\n const entry: Partial<SlideCommentOptions> = { x: cm.x, y: cm.y };\n if (cm.text) entry.text = cm.text;\n if (cm.date) entry.date = cm.date;\n if (cm.modified !== undefined) entry.modified = cm.modified;\n const author = commentAuthors.get(cm.authorId);\n if (author) {\n entry.author = author.name;\n if (author.initials) entry.initials = author.initials;\n }\n comments.push(entry);\n }\n if (comments.length > 0) slideOpts.comments = comments as SlideCommentOptions[];\n }\n break;\n }\n\n // Notes slide via slide rels\n for (const [, relPath] of slideRels) {\n if (!relPath.includes(\"/notesSlides/\")) continue;\n const notesEl = pptx.doc.get(relPath);\n if (!notesEl) continue;\n const notesData = notesSlideDesc.parse(notesEl, readCtx);\n if (notesData.text) slideOpts.notes = notesData.text;\n break;\n }\n\n // Section (p14:sectionLst) — bridged via slide id -> rId -> path\n const sectionName = sectionBySlidePath.get(slidePath);\n if (sectionName) slideOpts.section = sectionName;\n\n result.push(slideOpts as SlideOptions);\n }\n\n opts.slides = result;\n return opts as PresentationOptions;\n}\n"],"mappings":"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"} | ||
| {"version":3,"file":"parse-Cn_n-WuO.mjs","names":[],"sources":["../src/parts/descriptors/slide.ts","../src/parse.ts"],"sourcesContent":["/**\n * Slide (p:sld) descriptor for PPTX.\n *\n * @module\n */\n\nimport type { CustomDescriptor, WriteContext } from \"@office-open/core/descriptor\";\nimport { attr, attrNum, findChild } from \"@office-open/xml\";\nimport type { Element as XmlElement } from \"@office-open/xml\";\nimport type { SlideChild as LegacySlideChild } from \"@parts/slide/slide-child\";\nimport { SP_TREE_HEADER } from \"@shared/constants\";\n\nimport { timingDesc } from \"./animation\";\nimport { parseChild } from \"./bridge\";\nimport { shapeDesc, pictureDesc } from \"./shape\";\nimport type {\n ShapeDescriptorOptions,\n PictureDescriptorOptions,\n TextBodyDescriptorOptions,\n} from \"./shape\";\n\n// ── Types ──\n\nexport interface HeaderFooterDescriptorOptions {\n slideNumber?: boolean;\n dateTime?: boolean;\n footer?: boolean;\n header?: boolean;\n}\n\nexport interface AnimationDescriptorOptions {\n shapeId: number;\n options: unknown;\n}\n\nexport interface SlideDescriptorOptions {\n children?: SlideChild[];\n background?: BackgroundDescriptorOptions;\n transition?: TransitionDescriptorOptions;\n showMasterSp?: boolean;\n showMasterPhAnim?: boolean;\n controls?: ControlDescriptorOptions[];\n customerData?: { rId: string }[];\n headerFooter?: HeaderFooterDescriptorOptions;\n animations?: AnimationDescriptorOptions[];\n /** Hidden slide — excluded from slideshow (emits p:sld/@show=\"0\"). */\n hidden?: boolean;\n}\n\n/** Discriminated union for slide children (JSON-friendly). */\nexport type SlideChild =\n | { shape: ShapeDescriptorOptions }\n | { picture: PictureDescriptorOptions }\n | { text: TextBodyDescriptorOptions }\n | { contentPart: { rId: string } };\n\nexport interface BackgroundDescriptorOptions {\n color?: string;\n transparency?: number;\n}\n\nexport interface TransitionDescriptorOptions {\n type?:\n | \"none\"\n | \"fade\"\n | \"push\"\n | \"wipe\"\n | \"split\"\n | \"cover\"\n | \"pull\"\n | \"dissolve\"\n | \"wheel\"\n | \"random\";\n speed?: \"slow\" | \"medium\" | \"fast\";\n advanceOnClick?: boolean;\n advanceAfterMs?: number;\n}\n\nexport interface ControlDescriptorOptions {\n shapeId?: number;\n name?: string;\n showAsIcon?: boolean;\n rId?: string;\n imageWidth?: number;\n imageHeight?: number;\n}\n\n// ── Slide (p:sld) descriptor ──\n\nexport const slideDesc: CustomDescriptor<SlideDescriptorOptions> = {\n kind: \"custom\",\n\n stringify(opts, ctx) {\n const parts: string[] = [];\n\n // Opening tag with namespace declarations\n const sldAttrs: string[] = [];\n if (opts.showMasterSp === false) sldAttrs.push(' showMasterSp=\"0\"');\n if (opts.showMasterPhAnim === false) sldAttrs.push(' showMasterPhAnim=\"0\"');\n if (opts.hidden) sldAttrs.push(' show=\"0\"');\n parts.push(\n `<p:sld xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\"${sldAttrs.join(\"\")}>`,\n );\n\n // p:cSld — common slide data\n parts.push(\"<p:cSld>\");\n\n if (opts.background) {\n parts.push(stringifyBackground(opts.background));\n }\n\n // p:spTree — shape tree\n parts.push(\"<p:spTree>\");\n parts.push(SP_TREE_HEADER);\n\n if (opts.children) {\n for (const child of opts.children) {\n const xml = stringifySlideChild(child, ctx);\n if (xml) parts.push(xml);\n }\n }\n\n parts.push(\"</p:spTree>\");\n\n // custDataLst\n if (opts.customerData && opts.customerData.length > 0) {\n const cdItems = opts.customerData.map((d) => `<p:custData r:id=\"${d.rId}\"/>`).join(\"\");\n parts.push(`<p:custDataLst>${cdItems}</p:custDataLst>`);\n }\n\n // controls\n if (opts.controls && opts.controls.length > 0) {\n const ctrlItems = opts.controls\n .map((c) => {\n const attrs: string[] = [];\n if (c.shapeId !== undefined) attrs.push(`spid=\"${c.shapeId}\"`);\n if (c.name) attrs.push(`name=\"${c.name}\"`);\n if (c.showAsIcon) attrs.push('showAsIcon=\"1\"');\n if (c.rId) attrs.push(`r:id=\"${c.rId}\"`);\n if (c.imageWidth !== undefined) attrs.push(`imgW=\"${c.imageWidth}\"`);\n if (c.imageHeight !== undefined) attrs.push(`imgH=\"${c.imageHeight}\"`);\n return `<p:control ${attrs.join(\" \")}/>`;\n })\n .join(\"\");\n parts.push(`<p:controls>${ctrlItems}</p:controls>`);\n }\n\n // Header/Footer (p:hf)\n if (opts.headerFooter) {\n const hf = opts.headerFooter;\n const hfChildren: string[] = [];\n if (hf.slideNumber) hfChildren.push(\"<p:sldNum/>\");\n if (hf.dateTime) hfChildren.push(\"<p:dt/>\");\n if (hf.footer) hfChildren.push(\"<p:ftr/>\");\n if (hf.header) hfChildren.push(\"<p:hdr/>\");\n if (hfChildren.length > 0) parts.push(`<p:hf>${hfChildren.join(\"\")}</p:hf>`);\n }\n\n parts.push(\"</p:cSld>\");\n\n // p:clrMapOvr\n parts.push(\"<p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr>\");\n\n // p:transition (optional)\n if (opts.transition) {\n parts.push(stringifyTransition(opts.transition));\n }\n\n parts.push(\"</p:sld>\");\n return parts.join(\"\");\n },\n\n parse(el, _ctx) {\n const result: Record<string, unknown> = {};\n\n // Root attributes\n if (el.attributes) {\n if (el.attributes[\"showMasterSp\"] !== undefined)\n result.showMasterSp = el.attributes[\"showMasterSp\"] !== \"0\";\n if (el.attributes[\"showMasterPhAnim\"] !== undefined)\n result.showMasterPhAnim = el.attributes[\"showMasterPhAnim\"] !== \"0\";\n if (el.attributes[\"show\"] === \"0\") result.hidden = true;\n }\n\n // p:cSld\n const cSld = findChild(el, \"p:cSld\");\n if (cSld) {\n // Background\n const bg = findChild(cSld, \"p:bg\");\n if (bg) result.background = readBackground(bg);\n\n // Shape tree\n const spTree = findChild(cSld, \"p:spTree\");\n if (spTree) {\n const children: LegacySlideChild[] = [];\n if (spTree.elements) {\n for (const child of spTree.elements) {\n // Skip tree container structure\n if (child.name === \"p:nvGrpSpPr\" || child.name === \"p:grpSpPr\") continue;\n const parsed = parseChild(child, _ctx);\n if (parsed !== undefined) children.push(parsed);\n }\n }\n if (children.length > 0) result.children = children;\n }\n\n // Header/Footer (p:hf)\n const hf = findChild(cSld, \"p:hf\");\n if (hf) {\n const hfOpts: HeaderFooterDescriptorOptions = {};\n if (findChild(hf, \"p:sldNum\")) hfOpts.slideNumber = true;\n if (findChild(hf, \"p:dt\")) hfOpts.dateTime = true;\n if (findChild(hf, \"p:ftr\")) hfOpts.footer = true;\n if (findChild(hf, \"p:hdr\")) hfOpts.header = true;\n if (hfOpts.slideNumber || hfOpts.dateTime || hfOpts.footer || hfOpts.header)\n result.headerFooter = hfOpts;\n }\n }\n\n // p:transition\n const transition = findChild(el, \"p:transition\");\n if (transition) result.transition = readTransition(transition);\n\n // p:timing → animations\n const timing = findChild(el, \"p:timing\");\n if (timing) {\n const timingOpts = timingDesc.parse(timing, _ctx);\n if (timingOpts.entries && timingOpts.entries.length > 0) {\n const animations: AnimationDescriptorOptions[] = [];\n for (const entry of timingOpts.entries) {\n animations.push({ shapeId: entry.spid, options: entry.options });\n }\n result.animations = animations;\n }\n }\n\n // custDataLst\n const custDataLst = findChild(el, \"p:custDataLst\");\n if (custDataLst) {\n const items: { rId: string }[] = [];\n for (const cd of custDataLst.elements ?? []) {\n if (cd.name === \"p:custData\") {\n const rId = attr(cd, \"r:id\");\n if (rId) items.push({ rId });\n }\n }\n if (items.length > 0) result.customerData = items;\n }\n\n // controls\n const controls = findChild(el, \"p:controls\");\n if (controls) {\n const items: ControlDescriptorOptions[] = [];\n for (const ctrl of controls.elements ?? []) {\n if (ctrl.name !== \"p:control\") continue;\n const item: ControlDescriptorOptions = {};\n const spid = attrNum(ctrl, \"spid\");\n if (spid !== undefined) item.shapeId = spid;\n const name = attr(ctrl, \"name\");\n if (name) item.name = name;\n if (attr(ctrl, \"showAsIcon\") === \"1\") item.showAsIcon = true;\n const rId = attr(ctrl, \"r:id\");\n if (rId) item.rId = rId;\n const imgW = attrNum(ctrl, \"imgW\");\n if (imgW !== undefined) item.imageWidth = imgW;\n const imgH = attrNum(ctrl, \"imgH\");\n if (imgH !== undefined) item.imageHeight = imgH;\n items.push(item);\n }\n if (items.length > 0) result.controls = items;\n }\n\n return result as unknown as SlideDescriptorOptions;\n },\n};\n\n// ── Child serializer ──\n\nfunction stringifySlideChild(child: SlideChild, ctx: WriteContext): string | undefined {\n if (\"shape\" in child) return shapeDesc.stringify(child.shape, ctx);\n if (\"picture\" in child) return pictureDesc.stringify(child.picture, ctx);\n if (\"contentPart\" in child) return `<p:contentPart r:id=\"${child.contentPart.rId}\"/>`;\n return undefined;\n}\n\n// ── Background helpers ──\n\nfunction stringifyBackground(opts: BackgroundDescriptorOptions): string {\n if (opts.color) {\n const alphaAttr =\n opts.transparency !== undefined\n ? `><a:srgbClr val=\"${opts.color.replace(\"#\", \"\")}\"><a:alpha val=\"${Math.round((100 - opts.transparency) * 1000)}\"/></a:srgbClr></p:bgPr`\n : `><a:solidFill><a:srgbClr val=\"${opts.color.replace(\"#\", \"\")}\"/></a:solidFill></p:bgPr`;\n return `<p:bg><p:bgPr${alphaAttr}></p:bg>`;\n }\n return \"<p:bg/>\";\n}\n\nfunction readBackground(bg: XmlElement): BackgroundDescriptorOptions {\n const result: BackgroundDescriptorOptions = {};\n const bgPr = findChild(bg, \"p:bgPr\");\n if (bgPr) {\n const solidFill = findChild(bgPr, \"a:solidFill\");\n if (solidFill) {\n const srgbClr = findChild(solidFill, \"a:srgbClr\");\n if (srgbClr?.attributes?.[\"val\"]) {\n result.color = String(srgbClr.attributes[\"val\"]);\n const alpha = findChild(srgbClr, \"a:alpha\");\n if (alpha?.attributes?.[\"val\"]) {\n result.transparency = 100 - Number(alpha.attributes[\"val\"]) / 1000;\n }\n }\n }\n }\n return result;\n}\n\n// ── Transition helpers ──\n\nfunction stringifyTransition(opts: TransitionDescriptorOptions): string {\n const parts: string[] = [];\n\n if (opts.type === \"none\") return \"\";\n if (opts.type === \"fade\") parts.push(\"<p:fade/>\");\n else if (opts.type === \"push\") parts.push('<p:push dir=\"l\"/>');\n else if (opts.type === \"wipe\") parts.push('<p:wipe dir=\"d\"/>');\n else if (opts.type === \"split\") parts.push('<p:split orient=\"horz\"/>');\n else if (opts.type === \"cover\") parts.push('<p:cover dir=\"l\"/>');\n else if (opts.type === \"pull\") parts.push('<p:pull dir=\"l\"/>');\n else if (opts.type === \"dissolve\") parts.push(\"<p:dissolve/>\");\n else if (opts.type === \"wheel\") parts.push('<p:wheel spokes=\"4\"/>');\n else if (opts.type === \"random\") parts.push(\"<p:random/>\");\n\n const attrs: string[] = [];\n if (opts.speed) attrs.push(`spd=\"${opts.speed}\"`);\n if (opts.advanceOnClick !== undefined) attrs.push(`advClick=\"${opts.advanceOnClick ? 1 : 0}\"`);\n if (opts.advanceAfterMs !== undefined) attrs.push(`advTm=\"${opts.advanceAfterMs}\"`);\n\n const attrStr = attrs.length ? \" \" + attrs.join(\" \") : \"\";\n const body = parts.join(\"\");\n return body ? `<p:transition${attrStr}>${body}</p:transition>` : `<p:transition${attrStr}/>`;\n}\n\nfunction readTransition(el: XmlElement): TransitionDescriptorOptions {\n const result: TransitionDescriptorOptions = {};\n\n if (el.attributes) {\n if (el.attributes[\"spd\"] !== undefined)\n result.speed = el.attributes[\"spd\"] as \"slow\" | \"medium\" | \"fast\";\n if (el.attributes[\"advClick\"] !== undefined)\n result.advanceOnClick = el.attributes[\"advClick\"] === \"1\";\n if (el.attributes[\"advTm\"] !== undefined)\n result.advanceAfterMs = Number(el.attributes[\"advTm\"]);\n }\n\n // Detect transition type from child elements\n if (findChild(el, \"p:fade\")) result.type = \"fade\";\n else if (findChild(el, \"p:push\")) result.type = \"push\";\n else if (findChild(el, \"p:wipe\")) result.type = \"wipe\";\n else if (findChild(el, \"p:split\")) result.type = \"split\";\n else if (findChild(el, \"p:cover\")) result.type = \"cover\";\n else if (findChild(el, \"p:pull\")) result.type = \"pull\";\n else if (findChild(el, \"p:dissolve\")) result.type = \"dissolve\";\n else if (findChild(el, \"p:wheel\")) result.type = \"wheel\";\n else if (findChild(el, \"p:random\")) result.type = \"random\";\n\n return result;\n}\n","import type { ParsedArchive } from \"@office-open/core\";\nimport {\n appPropertiesDesc,\n customPropertiesDesc,\n parseArchive,\n parseCorePropsElement,\n} from \"@office-open/core\";\nimport type { DataType } from \"@office-open/core\";\nimport { toUint8Array } from \"@office-open/core\";\nimport type { ReadContext } from \"@office-open/core/descriptor\";\nimport { themeDesc } from \"@office-open/core/theme\";\nimport type { Element } from \"@office-open/xml\";\nimport { attr, attrNum, findChild } from \"@office-open/xml\";\n\nimport { PptxReadContext, ParseContext } from \"./context\";\nimport { backgroundDesc } from \"./parts/descriptors/background\";\nimport { parseChild } from \"./parts/descriptors/bridge\";\nimport { commentAuthorsDesc, slideCommentsDesc } from \"./parts/descriptors/comments\";\nimport { notesMasterDesc } from \"./parts/descriptors/notes-master\";\nimport { notesSlideDesc } from \"./parts/descriptors/notes-slide\";\nimport { presPropsDesc } from \"./parts/descriptors/presentation-properties\";\nimport { slideDesc } from \"./parts/descriptors/slide\";\nimport { slideLayoutDesc } from \"./parts/descriptors/slide-layout\";\nimport { tableStylesDesc } from \"./parts/descriptors/table-styles\";\nimport { viewPropsDesc } from \"./parts/descriptors/view-properties\";\nimport type { SlideChild } from \"./parts/slide/slide-child\";\n\nexport { parseArchive };\n\nimport type { SlideLayoutType } from \"./parts/slide-layout\";\nimport type {\n LayoutDefinition,\n MasterChild,\n MasterDefinition,\n SlideOptions,\n SlideCommentOptions,\n PresentationOptions,\n} from \"./shared/file\";\n\n/**\n * All part paths extracted from the PPTX package.\n * Field names correspond directly to the OOXML directory structure.\n */\nexport interface PptxPartRefs {\n /** ppt/theme/themeN.xml */\n themes: string[];\n /** ppt/notesMasters/notesMasterN.xml */\n notesMasters: string[];\n /** ppt/commentAuthors.xml */\n commentAuthors?: string;\n /** ppt/comments/commentN.xml (from slide rels) */\n comments: string[];\n /** ppt/charts/chartN.xml (from slide rels) */\n charts: string[];\n /** ppt/diagrams/dataN.xml (from slide rels) */\n diagramData: string[];\n /** ppt/media/* (all media files) */\n media: string[];\n}\n\nexport interface PptxDocument {\n doc: ParsedArchive;\n /** ppt/presentation.xml root element (p:presentation) */\n presentation?: Element;\n /** ppt/slides/slideN.xml */\n slides: string[];\n /** ppt/slideMasters/slideMasterN.xml */\n slideMasters: string[];\n /** ppt/slideLayouts/slideLayoutN.xml */\n slideLayouts: string[];\n /** ppt/notesSlides/notesSlideN.xml */\n notesSlides: string[];\n partRefs: PptxPartRefs;\n /** ppt/presProps.xml */\n presProps?: string;\n /** ppt/viewProps.xml */\n viewProps?: string;\n /** ppt/tableStyles.xml */\n tableStyles?: string;\n /** docProps/core.xml */\n coreProps?: string;\n /** docProps/app.xml */\n appProps?: string;\n /** docProps/custom.xml */\n customProps?: string;\n}\n\nfunction resolveRelsPath(target: string): string {\n if (target.startsWith(\"/\")) return target.slice(1);\n if (target.startsWith(\"../\")) return target.replace(\"../\", \"ppt/\");\n return `ppt/${target}`;\n}\n\nfunction sortByNumber(paths: string[]): string[] {\n return paths.sort((a, b) => {\n const numA = parseInt(a.match(/(\\d+)/)?.[1] ?? \"0\", 10);\n const numB = parseInt(b.match(/(\\d+)/)?.[1] ?? \"0\", 10);\n return numA - numB;\n });\n}\n\nfunction xmlKeys(keys: string[]): string[] {\n return keys.filter((k) => k.endsWith(\".xml\"));\n}\n\nfunction parseRootRels(doc: ParsedArchive): {\n coreProps?: string;\n appProps?: string;\n customProps?: string;\n} {\n const relsEl = doc.get(\"_rels/.rels\");\n if (!relsEl) return {};\n\n let coreProps: string | undefined;\n let appProps: string | undefined;\n let customProps: string | undefined;\n\n for (const child of relsEl.elements ?? []) {\n if (child.name !== \"Relationship\") continue;\n const type = attr(child, \"Type\") ?? \"\";\n const target = attr(child, \"Target\") ?? \"\";\n if (!target) continue;\n\n const path = target.startsWith(\"/\") ? target.slice(1) : target;\n\n if (type.includes(\"/core-properties\")) {\n coreProps = path;\n } else if (type.includes(\"/extended-properties\")) {\n appProps = path;\n } else if (type.includes(\"/custom-properties\")) {\n customProps = path;\n }\n }\n\n return { coreProps, appProps, customProps };\n}\n\nfunction parseSlideRels(doc: ParsedArchive, slidePaths: string[], refs: PptxPartRefs): void {\n const commentsSet = new Set(refs.comments);\n const chartsSet = new Set(refs.charts);\n const diagramDataSet = new Set(refs.diagramData);\n const mediaSet = new Set(refs.media);\n\n for (const slidePath of slidePaths) {\n const parts = slidePath.split(\"/\");\n const fileName = parts.pop()!;\n const relsPath = `${parts.join(\"/\")}/_rels/${fileName}.rels`;\n\n const relsEl = doc.get(relsPath);\n if (!relsEl) continue;\n\n for (const child of relsEl.elements ?? []) {\n if (child.name !== \"Relationship\") continue;\n const type = attr(child, \"Type\") ?? \"\";\n const target = attr(child, \"Target\") ?? \"\";\n if (!target) continue;\n\n const path = resolveRelsPath(target);\n\n if (type.includes(\"/comments\") && !type.includes(\"commentAuthors\")) {\n commentsSet.add(path);\n } else if (type.includes(\"/chart\")) {\n chartsSet.add(path);\n } else if (type.includes(\"/diagramData\")) {\n diagramDataSet.add(path);\n } else if (type.includes(\"/image\") || type.includes(\"/video\") || type.includes(\"/media\")) {\n mediaSet.add(path);\n }\n }\n }\n\n refs.comments = [...commentsSet];\n refs.charts = [...chartsSet];\n refs.diagramData = [...diagramDataSet];\n refs.media = [...mediaSet];\n}\n\nexport function parsePptx(data: DataType): PptxDocument {\n const uint8 = toUint8Array(data);\n const doc = parseArchive(uint8);\n\n const presentation = doc.get(\"ppt/presentation.xml\");\n\n const relsXml = doc.get(\"ppt/_rels/presentation.xml.rels\");\n const slides: string[] = [];\n const slideMasters: string[] = [];\n const themes: string[] = [];\n const notesMasters: string[] = [];\n let presProps: string | undefined;\n let viewProps: string | undefined;\n let tableStyles: string | undefined;\n let commentAuthors: string | undefined;\n\n if (relsXml) {\n for (const child of relsXml.elements ?? []) {\n if (child.name !== \"Relationship\") continue;\n const type = attr(child, \"Type\") ?? \"\";\n const target = attr(child, \"Target\") ?? \"\";\n if (!target) continue;\n\n const path = resolveRelsPath(target);\n\n if (type.includes(\"/slideMaster\")) {\n slideMasters.push(path);\n } else if (\n type.includes(\"/slide\") &&\n !type.includes(\"slideLayout\") &&\n !type.includes(\"slideMaster\")\n ) {\n slides.push(path);\n } else if (type.includes(\"/theme\")) {\n themes.push(path);\n } else if (type.includes(\"/notesMaster\")) {\n notesMasters.push(path);\n } else if (type.includes(\"/presProps\")) {\n presProps = path;\n } else if (type.includes(\"/viewProps\")) {\n viewProps = path;\n } else if (type.includes(\"/tableStyles\")) {\n tableStyles = path;\n } else if (type.includes(\"/commentAuthors\")) {\n commentAuthors = path;\n }\n }\n }\n\n sortByNumber(slides);\n sortByNumber(slideMasters);\n sortByNumber(themes);\n sortByNumber(notesMasters);\n\n const slideLayouts = sortByNumber(xmlKeys(doc.keys(\"ppt/slideLayouts/\")));\n const notesSlides = sortByNumber(xmlKeys(doc.keys(\"ppt/notesSlides/\")));\n\n const partRefs: PptxPartRefs = {\n themes,\n notesMasters,\n commentAuthors,\n comments: [],\n charts: [],\n diagramData: [],\n media: doc.keys(\"ppt/media/\"),\n };\n\n parseSlideRels(doc, slides, partRefs);\n sortByNumber(partRefs.comments);\n sortByNumber(partRefs.charts);\n sortByNumber(partRefs.diagramData);\n\n const { coreProps, appProps, customProps } = parseRootRels(doc);\n\n return {\n doc,\n presentation,\n slides,\n slideMasters,\n slideLayouts,\n notesSlides,\n partRefs,\n presProps,\n viewProps,\n tableStyles,\n coreProps,\n appProps,\n customProps,\n };\n}\n\n/**\n * Parse a single slide's relationship file into a Map<rId, path>.\n */\nfunction parseSlideRelMap(doc: ParsedArchive, slidePath: string): Map<string, string> {\n const rels = new Map<string, string>();\n const parts = slidePath.split(\"/\");\n const fileName = parts.pop()!;\n const relsPath = `${parts.join(\"/\")}/_rels/${fileName}.rels`;\n\n const relsEl = doc.get(relsPath);\n if (!relsEl) return rels;\n\n for (const child of relsEl.elements ?? []) {\n if (child.name !== \"Relationship\") continue;\n const id = attr(child, \"Id\") ?? \"\";\n const target = attr(child, \"Target\") ?? \"\";\n if (!id || !target) continue;\n // External links (hyperlinks) keep their original URL target\n if (attr(child, \"TargetMode\") === \"External\") {\n rels.set(id, target);\n } else {\n rels.set(id, resolveRelsPath(target));\n }\n }\n\n return rels;\n}\n\n/**\n * Build a map from each path to the rel target matching a predicate.\n */\nfunction resolveRelTargets(\n doc: ParsedArchive,\n paths: string[],\n predicate: (target: string) => boolean,\n): Map<string, string> {\n const map = new Map<string, string>();\n for (const path of paths) {\n for (const target of parseSlideRelMap(doc, path).values()) {\n if (predicate(target)) map.set(path, target);\n }\n }\n return map;\n}\n\n/**\n * Parse p14:sectionLst from presentation.xml and map each slide path to its\n * section name. Bridges p14:sldId (by slide id) -> p:sldIdLst (slide id ->\n * rId) -> presentation rels (rId -> path).\n */\nfunction parseSlideSections(\n presentation: Element | undefined,\n doc: ParsedArchive,\n): Map<string, string> {\n const pathToSection = new Map<string, string>();\n if (!presentation) return pathToSection;\n\n const extLst = findChild(presentation, \"p:extLst\");\n if (!extLst) return pathToSection;\n\n let sectionLst: Element | undefined;\n for (const ext of extLst.elements ?? []) {\n if (ext.name !== \"p:ext\") continue;\n if (attr(ext, \"uri\") !== \"{521415D9-36F7-43E2-AB2F-B90AF26B5E84}\") continue;\n sectionLst = findChild(ext, \"p14:sectionLst\");\n if (sectionLst) break;\n }\n if (!sectionLst) return pathToSection;\n\n // slideId -> sectionName\n const sectionBySlideId = new Map<number, string>();\n for (const section of sectionLst.elements ?? []) {\n if (section.name !== \"p14:section\") continue;\n const name = attr(section, \"name\");\n if (!name) continue;\n const sldIdLst = findChild(section, \"p14:sldIdLst\");\n for (const sldId of sldIdLst?.elements ?? []) {\n if (sldId.name !== \"p14:sldId\") continue;\n const id = attrNum(sldId, \"id\");\n if (id !== undefined) sectionBySlideId.set(id, name);\n }\n }\n if (sectionBySlideId.size === 0) return pathToSection;\n\n // slideId -> rId (from p:sldIdLst)\n const sldIdLst = findChild(presentation, \"p:sldIdLst\");\n const rIdBySlideId = new Map<number, string>();\n for (const sldId of sldIdLst?.elements ?? []) {\n if (sldId.name !== \"p:sldId\") continue;\n const id = attrNum(sldId, \"id\");\n const rId = attr(sldId, \"r:id\");\n if (id !== undefined && rId) rIdBySlideId.set(id, rId);\n }\n\n // rId -> path (from presentation.xml.rels)\n const relsEl = doc.get(\"ppt/_rels/presentation.xml.rels\");\n const pathByRId = new Map<string, string>();\n for (const child of relsEl?.elements ?? []) {\n if (child.name !== \"Relationship\") continue;\n const id = attr(child, \"Id\");\n const target = attr(child, \"Target\");\n if (id && target) pathByRId.set(id, resolveRelsPath(target));\n }\n\n for (const [slideId, name] of sectionBySlideId) {\n const rId = rIdBySlideId.get(slideId);\n if (!rId) continue;\n const path = pathByRId.get(rId);\n if (path) pathToSection.set(path, name);\n }\n\n return pathToSection;\n}\n\n/**\n * Parse a .pptx file and convert it into PresentationOptions.\n *\n * This is the main public API for parsing PPTX files.\n * The returned options can be passed directly to `new Presentation(parsed)`\n * to recreate the presentation.\n *\n * @param data - Raw bytes of a .pptx file\n * @returns Parsed presentation options\n */\nexport function parsePresentation(data: DataType): PresentationOptions {\n const pptx = parsePptx(data);\n const opts: Partial<PresentationOptions> = {};\n const sectionBySlidePath = parseSlideSections(pptx.presentation, pptx.doc);\n\n // 1. Parse slide size from p:sldSz\n if (pptx.presentation) {\n const sldSz = findChild(pptx.presentation, \"p:sldSz\");\n if (sldSz) {\n const cx = attrNum(sldSz, \"cx\");\n const cy = attrNum(sldSz, \"cy\");\n if (cx === 12192000 && cy === 6858000) {\n opts.size = \"16:9\";\n } else if (cx === 9144000 && cy === 6858000) {\n opts.size = \"4:3\";\n } else if (cx && cy) {\n opts.size = { width: cx, height: cy };\n }\n }\n }\n\n // 2. Parse core properties\n if (pptx.coreProps) {\n const corePropsEl = pptx.doc.get(pptx.coreProps);\n if (corePropsEl) {\n const cp = parseCorePropsElement(corePropsEl);\n if (cp.title) opts.title = cp.title;\n if (cp.subject) opts.subject = cp.subject;\n if (cp.creator) opts.creator = cp.creator;\n if (cp.keywords) opts.keywords = cp.keywords;\n if (cp.description) opts.description = cp.description;\n if (cp.lastModifiedBy) opts.lastModifiedBy = cp.lastModifiedBy;\n if (cp.revision !== undefined) opts.revision = cp.revision;\n if (cp.lastPrinted) opts.lastPrinted = cp.lastPrinted;\n if (cp.created) opts.created = cp.created;\n if (cp.modified) opts.modified = cp.modified;\n }\n }\n\n // 2b. Parse extended (app) properties\n if (pptx.appProps) {\n const appPropsEl = pptx.doc.get(pptx.appProps);\n if (appPropsEl) {\n const ap = appPropertiesDesc.parse(appPropsEl, {} as ReadContext);\n if (ap && Object.keys(ap).length > 0) opts.appProperties = ap;\n }\n }\n\n // 2c. Parse custom properties\n if (pptx.customProps) {\n const customPropsEl = pptx.doc.get(pptx.customProps);\n if (customPropsEl) {\n const cp = customPropertiesDesc.parse(customPropsEl, {} as ReadContext);\n if (cp.properties?.length) opts.customProperties = cp.properties;\n }\n }\n\n // 3. Parse show options from presProps\n if (pptx.presProps) {\n const presPropsEl = pptx.doc.get(pptx.presProps);\n if (presPropsEl) {\n const presPropsOpts = presPropsDesc.parse(presPropsEl, {} as ReadContext);\n if (presPropsOpts.show) opts.show = presPropsOpts.show;\n }\n }\n\n // 3b. Parse view properties\n if (pptx.viewProps) {\n const viewPropsEl = pptx.doc.get(pptx.viewProps);\n if (viewPropsEl) {\n const viewOpts = viewPropsDesc.parse(viewPropsEl, {} as ReadContext);\n if (viewOpts.lastView || viewOpts.showComments !== undefined || viewOpts.gridSpacing) {\n opts.view = viewOpts;\n }\n }\n }\n\n // 3c. Parse table styles\n if (pptx.tableStyles) {\n const tableStylesEl = pptx.doc.get(pptx.tableStyles);\n if (tableStylesEl) {\n const tableStylesResult = tableStylesDesc.parse(tableStylesEl, {} as ReadContext);\n if (tableStylesResult.opts) opts.tableStyles = tableStylesResult.opts;\n }\n }\n\n // 4. Build relationship maps\n const masterThemePaths = resolveRelTargets(pptx.doc, pptx.slideMasters, (t) =>\n t.includes(\"/theme\"),\n );\n const layoutMasterPaths = resolveRelTargets(pptx.doc, pptx.slideLayouts, (t) =>\n t.includes(\"/slideMaster\"),\n );\n const slideLayoutPaths = resolveRelTargets(pptx.doc, pptx.slides, (t) =>\n t.includes(\"/slideLayout\"),\n );\n\n // 5. Parse masters\n const masterCount = pptx.slideMasters.length;\n const masterDefs: MasterDefinition[] = [];\n const masterReadCtx = new PptxReadContext(new ParseContext(pptx, new Map()));\n for (let mi = 0; mi < masterCount; mi++) {\n const masterPath = pptx.slideMasters[mi];\n const masterEl = pptx.doc.get(masterPath);\n if (!masterEl) continue;\n\n // Theme\n const themePath = masterThemePaths.get(masterPath);\n const themeEl = themePath ? pptx.doc.get(themePath) : undefined;\n const themeOptions = themeEl ? themeDesc.parse(themeEl, masterReadCtx) : undefined;\n\n // Background (inline: findChild → backgroundDesc.parse)\n const cSld = findChild(masterEl, \"p:cSld\");\n const bg = cSld ? findChild(cSld, \"p:bg\") : undefined;\n const masterBackground = bg ? backgroundDesc.parse(bg, masterReadCtx) : undefined;\n const hasBackground = masterBackground && Object.keys(masterBackground).length > 0;\n\n // Children: extract non-placeholder shapes from spTree\n const spTree = cSld ? findChild(cSld, \"p:spTree\") : undefined;\n const masterChildren: SlideChild[] = [];\n if (spTree) {\n for (const child of spTree.elements ?? []) {\n // Skip nvGrpSpPr/grpSpPr (tree container structure, not shapes)\n if (child.name === \"p:nvGrpSpPr\" || child.name === \"p:grpSpPr\") continue;\n // Skip placeholder shapes (generated by DefaultSlideMaster template)\n if (child.name === \"p:sp\") {\n const nvSpPr = findChild(child, \"p:nvSpPr\");\n const nvPr = nvSpPr ? findChild(nvSpPr, \"p:nvPr\") : undefined;\n if (nvPr && findChild(nvPr, \"p:ph\")) continue;\n }\n const parsed = parseChild(child, masterReadCtx);\n if (parsed !== undefined) masterChildren.push(parsed);\n }\n }\n\n // Layouts belonging to this master\n const masterLayouts: LayoutDefinition[] = [];\n for (const layoutPath of pptx.slideLayouts) {\n if (layoutMasterPaths.get(layoutPath) !== masterPath) continue;\n const layoutEl = pptx.doc.get(layoutPath);\n if (layoutEl) {\n const layoutOpts = slideLayoutDesc.parse(layoutEl, masterReadCtx);\n const layoutDef: LayoutDefinition = {\n type: (layoutOpts.type ?? \"blank\") as SlideLayoutType,\n };\n if (layoutOpts.placeholders) layoutDef.placeholders = layoutOpts.placeholders;\n masterLayouts.push(layoutDef);\n }\n }\n\n const masterName = themeOptions?.name ?? `master${mi + 1}`;\n const masterDef: Partial<MasterDefinition> = {};\n masterDef.name = masterName;\n if (themeOptions) masterDef.theme = themeOptions;\n if (hasBackground) masterDef.background = masterBackground;\n // MasterChild (shared) declares only { shape }; parse yields the full\n // SlideChild union (parts-layer). The shared/parts split prevents unifying\n // them (SlideChild cannot move to shared — circular dep), so the cast stays\n // local to this known impedance.\n if (masterChildren.length > 0) masterDef.children = masterChildren as unknown as MasterChild[];\n if (masterLayouts.length > 0) masterDef.layouts = masterLayouts;\n masterDefs.push(masterDef as MasterDefinition);\n }\n\n // Only set masters if there's more than one (single master is auto-created)\n if (masterCount > 1) {\n opts.masters = masterDefs;\n }\n\n // 5b. Parse notes masters\n for (const nmPath of pptx.partRefs.notesMasters) {\n const nmEl = pptx.doc.get(nmPath);\n if (nmEl) {\n const nmOpts = notesMasterDesc.parse(nmEl, masterReadCtx);\n if (nmOpts.options) {\n opts.includeNotesMaster = true;\n opts.notesMasterOptions = nmOpts.options;\n }\n }\n }\n\n // 5c. Parse handout masters (no separate handling needed, just mark inclusion)\n // Handout masters are referenced from presentation.xml rels but not stored in PptxDocument currently\n\n // 6. Parse comment authors\n const commentAuthors = new Map<number, { name: string; initials: string }>();\n if (pptx.partRefs.commentAuthors) {\n const authorsEl = pptx.doc.get(pptx.partRefs.commentAuthors);\n if (authorsEl) {\n const authors = commentAuthorsDesc.parse(authorsEl, masterReadCtx);\n for (const a of authors) {\n commentAuthors.set(a.id, { name: a.name, initials: a.initials });\n }\n }\n }\n\n // 7. Parse slides with layout and master references\n const result: SlideOptions[] = [];\n for (let si = 0; si < pptx.slides.length; si++) {\n const slidePath = pptx.slides[si];\n const slideEl = pptx.doc.get(slidePath);\n if (!slideEl) continue;\n\n const slideRels = parseSlideRelMap(pptx.doc, slidePath);\n const ctx = new ParseContext(pptx, slideRels);\n const readCtx = new PptxReadContext(ctx);\n // slideDesc.parse returns SlideDescriptorOptions (internal descriptor type:\n // 4-variant SlideChild, no layout/master/comments/notes/section). We enrich\n // it with those public-API fields below and coerce to SlideOptions at push.\n // Record bridges this descriptor/public impedance — slide.ts itself is a\n // known stringify≠parse split, so the wrapper stays until that is resolved.\n const slideOpts = slideDesc.parse(slideEl, readCtx) as Record<string, unknown>;\n\n // Resolve layout → master\n const layoutPath = slideLayoutPaths.get(slidePath);\n if (layoutPath) {\n const layoutEl = pptx.doc.get(layoutPath);\n if (layoutEl) {\n const layoutOpts = slideLayoutDesc.parse(layoutEl, readCtx);\n slideOpts.layout = (layoutOpts.type ?? \"blank\") as SlideLayoutType;\n }\n\n const resolvedMasterPath = layoutMasterPaths.get(layoutPath);\n if (resolvedMasterPath) {\n const masterIdx = pptx.slideMasters.indexOf(resolvedMasterPath);\n if (masterIdx >= 0 && masterDefs[masterIdx]) {\n slideOpts.master = masterDefs[masterIdx].name;\n }\n }\n }\n\n // Comments via slide rels\n for (const [, relPath] of slideRels) {\n if (!relPath.includes(\"/comments/\")) continue;\n const commentsEl = pptx.doc.get(relPath);\n if (!commentsEl) continue;\n\n const parsedComments = slideCommentsDesc.parse(commentsEl, readCtx);\n if (parsedComments.length > 0) {\n const comments: Partial<SlideCommentOptions>[] = [];\n for (const cm of parsedComments) {\n const entry: Partial<SlideCommentOptions> = { x: cm.x, y: cm.y };\n if (cm.text) entry.text = cm.text;\n if (cm.date) entry.date = cm.date;\n if (cm.modified !== undefined) entry.modified = cm.modified;\n const author = commentAuthors.get(cm.authorId);\n if (author) {\n entry.author = author.name;\n if (author.initials) entry.initials = author.initials;\n }\n comments.push(entry);\n }\n if (comments.length > 0) slideOpts.comments = comments as SlideCommentOptions[];\n }\n break;\n }\n\n // Notes slide via slide rels\n for (const [, relPath] of slideRels) {\n if (!relPath.includes(\"/notesSlides/\")) continue;\n const notesEl = pptx.doc.get(relPath);\n if (!notesEl) continue;\n const notesData = notesSlideDesc.parse(notesEl, readCtx);\n if (notesData.text) slideOpts.notes = notesData.text;\n break;\n }\n\n // Section (p14:sectionLst) — bridged via slide id -> rId -> path\n const sectionName = sectionBySlidePath.get(slidePath);\n if (sectionName) slideOpts.section = sectionName;\n\n result.push(slideOpts as SlideOptions);\n }\n\n opts.slides = result;\n return opts as PresentationOptions;\n}\n"],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"patch.mjs","names":[],"sources":["../src/patch.ts"],"sourcesContent":["import {\n PPTX_NS,\n OoxmlMimeType,\n appendOverride,\n appendRelationship,\n applyCorePropertiesOverride,\n collectPlaceholderKeys,\n createReplacer,\n getNextRelationshipIndex,\n nextNumericId,\n replaceHyperlinkPlaceholders,\n strFromU8,\n toJson,\n unzipSync,\n zipAndConvert,\n} from \"@office-open/core\";\nimport type {\n BasePatchOptions,\n CorePropertiesOptions,\n OutputByType,\n OutputType,\n} from \"@office-open/core\";\nimport { toUint8Array } from \"@office-open/core\";\nimport type { ReadContext } from \"@office-open/core/descriptor\";\nimport { findChild, js2xml, xml2js } from \"@office-open/xml\";\nimport type { Element } from \"@office-open/xml\";\nimport type { AuthorEntry, CommentEntry } from \"@parts/comment\";\nimport { commentAuthorsDesc, slideCommentsDesc } from \"@parts/descriptors/comments\";\nimport { textRunDesc } from \"@parts/descriptors/text\";\nimport type { SlideCommentOptions, SlideOptions } from \"@shared/file\";\nimport type { RunOptions } from \"@shared/shape/paragraph/run\";\n\nimport { buildCommentData, stringifySlide } from \"./compiler\";\nimport { PptxWriteContext } from \"./context\";\n\n/** Reusable TextEncoder (stateless, safe to share). */\nconst encoder = new TextEncoder();\n\n/**\n * Parts scanned for text replacement: slides, slide masters, slide layouts,\n * and notes slides. Replacing text in a master/layout propagates to every\n * dependent slide — intended for template branding.\n */\nconst TARGET_RE =\n /^ppt\\/(?:slides\\/slide\\d+|slideMasters\\/slideMaster\\d+|slideLayouts\\/slideLayout\\d+|notesSlides\\/notesSlide\\d+)\\.xml$/;\nconst HYPERLINK_REL_TYPE =\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink\";\nconst SLIDE_PART_CONTENT_TYPE =\n \"application/vnd.openxmlformats-officedocument.presentationml.slide+xml\";\nconst SLIDE_REL_TYPE = \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide\";\nconst SLIDE_LAYOUT_REL_TYPE =\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout\";\nconst COMMENTS_REL_TYPE =\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments\";\nconst COMMENT_AUTHORS_REL_TYPE =\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors\";\nconst COMMENTS_CONTENT_TYPE =\n \"application/vnd.openxmlformats-officedocument.presentationml.comments+xml\";\nconst COMMENT_AUTHORS_CONTENT_TYPE =\n \"application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml\";\n\n/**\n * Inline run-level patch content. Reuses the generate vocabulary: a\n * {@link RunOptions} (or an array of them), or a plain string shorthand\n * for `{ text: \"…\" }`.\n */\nexport type Patch = RunOptions | RunOptions[] | string;\n\nexport interface PatchPresentationOptions<\n T extends OutputType = OutputType,\n> extends BasePatchOptions<T> {\n /** Placeholder substitutions: `{{key}}` (per delimiters) → run content. */\n placeholders?: Readonly<Record<string, Patch>>;\n /** Literal find/replace: the find string → run content (no delimiters added). */\n findReplace?: Readonly<Record<string, Patch>>;\n /** Core-properties metadata override (merged over the existing docProps/core.xml). */\n coreProperties?: Partial<CorePropertiesOptions>;\n /**\n * Slide collection edits. Appended slides inherit the template's first slide\n * layout; replaced slides keep their existing identity (sldId/rId/rels).\n */\n slides?: {\n /** Replace slides keyed by 0-based index in the slide list (sldIdLst order). */\n replace?: Readonly<Record<number, SlideOptions>>;\n /** Append slides after the last existing slide. */\n append?: Readonly<SlideOptions[]>;\n };\n /**\n * Comments to append per slide, keyed by 0-based slide index (sldIdLst order).\n * Authors are merged into commentAuthors.xml (deduped by name, ids continued);\n * per-slide comments are merged into ppt/comments/commentN.xml.\n */\n comments?: Readonly<Record<number, SlideCommentOptions[]>>;\n keepOriginalStyles?: boolean;\n}\n\n/** Write context for the current patch operation — accumulates hyperlinks. */\nlet currentPatchCtx: PptxWriteContext;\n\n/**\n * Patch replacer. Serializes each run via {@link textRunDesc} so the full\n * RunProperties vocabulary (color, fill, outline, shadow, font, hyperlinks, …)\n * is supported — no hand-rolled `<a:r>` builder.\n */\nconst pptxReplacer = createReplacer({\n ns: PPTX_NS,\n formatChild: (child: unknown): Element[] => {\n const runOpts = (typeof child === \"string\" ? { text: child } : child) as RunOptions;\n const xmlStr = textRunDesc.stringify(runOpts, currentPatchCtx) ?? \"<a:r/>\";\n return [xml2js(xmlStr, { captureSpacesBetweenElements: true }).elements![0]];\n },\n preserveSpace: false,\n});\n\n/**\n * Normalize a user patch value into the replacer's `{ type, children }`\n * envelope. PPTX patches are always inline run-level (`type: \"paragraph\"`).\n */\nconst toReplacerPatch = (patch: Patch): { type: \"paragraph\"; children: RunOptions[] } =>\n typeof patch === \"string\"\n ? { type: \"paragraph\", children: [{ text: patch }] }\n : { type: \"paragraph\", children: Array.isArray(patch) ? patch : [patch] };\n\nconst createRelationshipFile = (): Element => ({\n declaration: {\n attributes: { encoding: \"UTF-8\", standalone: \"yes\", version: \"1.0\" },\n },\n elements: [\n {\n attributes: { xmlns: \"http://schemas.openxmlformats.org/package/2006/relationships\" },\n elements: [],\n name: \"Relationships\",\n type: \"element\",\n },\n ],\n});\n\n/** Build a bare OOXML element node. */\nconst makeElement = (name: string, attributes: Record<string, string> = {}): Element => ({\n type: \"element\",\n name,\n attributes,\n elements: [],\n});\n\n/**\n * Locate the document root element by tag. A parsed XML part is wrapped as\n * `{ declaration, elements: [<root>] }`, so named children live one level down.\n */\nconst rootElement = (doc: Element | undefined, name: string): Element | undefined =>\n doc?.elements?.find((e) => e.name === name);\n\n/** Next 1-based slide file number given the existing slide parts. */\nconst nextSlideNumber = (xmlMap: Map<string, Element>): number => {\n let maxN = 0;\n for (const key of xmlMap.keys()) {\n const m = key.match(/^ppt\\/slides\\/slide(\\d+)\\.xml$/);\n if (m) maxN = Math.max(maxN, Number(m[1]));\n }\n return maxN + 1;\n};\n\n/** Next id for an appended `<p:sldId>` (255 floor → ≥256). */\nconst nextSldId = (sldIdLst: Element | undefined): number =>\n nextNumericId(sldIdLst, \"p:sldId\", \"id\", 255);\n\n/** Resolve a relationship `r:id` to its Target via a rels part. */\nconst resolveRelTarget = (\n rels: Element | undefined,\n rId: string | number | undefined,\n): string | undefined => {\n if (rId === undefined) return undefined;\n const needle = String(rId);\n const relationshipsRoot = rootElement(rels, \"Relationships\");\n for (const child of relationshipsRoot?.elements ?? []) {\n if (child.name === \"Relationship\" && String(child.attributes?.[\"Id\"]) === needle) {\n const target = child.attributes?.[\"Target\"];\n return target !== undefined ? String(target) : undefined;\n }\n }\n return undefined;\n};\n\n/**\n * Append a slide: serialize it, then wire sldIdLst + presentation rels +\n * content types + a slide rels pointing at the first slide layout (which must\n * already exist in the template). The appended slide inherits the template's\n * layout/master; it cannot reference styles or media not already present.\n */\nconst appendSlideToMap = (\n xmlMap: Map<string, Element>,\n slideOpts: SlideOptions,\n ctx: PptxWriteContext,\n): void => {\n const newN = nextSlideNumber(xmlMap);\n const slidePath = `ppt/slides/slide${newN}.xml`;\n\n // Slide part — no XML declaration, matching generated slide parts.\n xmlMap.set(slidePath, toJson(stringifySlide(slideOpts, ctx)));\n\n // presentation.xml sldIdLst + presentation.xml.rels (the new rId ties them)\n const presRoot = rootElement(xmlMap.get(\"ppt/presentation.xml\"), \"p:presentation\");\n const presRels = xmlMap.get(\"ppt/_rels/presentation.xml.rels\") ?? createRelationshipFile();\n xmlMap.set(\"ppt/_rels/presentation.xml.rels\", presRels);\n const newRId = getNextRelationshipIndex(presRels);\n\n const sldIdLst = findChild(presRoot, \"p:sldIdLst\");\n if (sldIdLst) {\n const els = sldIdLst.elements ?? (sldIdLst.elements = []);\n els.push(makeElement(\"p:sldId\", { id: String(nextSldId(sldIdLst)), \"r:id\": `rId${newRId}` }));\n }\n appendRelationship(presRels, newRId, SLIDE_REL_TYPE, `slides/slide${newN}.xml`);\n\n // [Content_Types].xml Override\n const contentTypes = xmlMap.get(\"[Content_Types].xml\");\n if (contentTypes) {\n appendOverride(contentTypes, `/${slidePath}`, SLIDE_PART_CONTENT_TYPE);\n }\n\n // Slide rels → first slide layout (template must already provide it)\n const slideRels = createRelationshipFile();\n appendRelationship(slideRels, 1, SLIDE_LAYOUT_REL_TYPE, \"../slideLayouts/slideLayout1.xml\");\n xmlMap.set(`ppt/slides/_rels/slide${newN}.xml.rels`, slideRels);\n};\n\n/** Resolve a 0-based sldIdLst index to its slide part path (ppt/slides/slideN.xml). */\nconst resolveSlidePath = (xmlMap: Map<string, Element>, index: number): string => {\n const presRoot = rootElement(xmlMap.get(\"ppt/presentation.xml\"), \"p:presentation\");\n const sldIdLst = findChild(presRoot, \"p:sldIdLst\");\n const sldIds = (sldIdLst?.elements ?? []).filter((e) => e.name === \"p:sldId\");\n const entry = sldIds[index];\n if (!entry?.attributes?.[\"r:id\"]) {\n throw new Error(`patchPresentation: no slide at index ${index}`);\n }\n const target = resolveRelTarget(\n xmlMap.get(\"ppt/_rels/presentation.xml.rels\"),\n entry.attributes[\"r:id\"],\n );\n if (!target) {\n throw new Error(`patchPresentation: slide ${index} relationship target not found`);\n }\n return `ppt/${target}`;\n};\n\n/**\n * Replace a slide in place by sldIdLst index: resolve the index to its slide\n * path via presentation rels, then rewrite only that part's content. sldId,\n * rId, content types, and slide rels are left untouched.\n */\nconst replaceSlideInMap = (\n xmlMap: Map<string, Element>,\n index: number,\n slideOpts: SlideOptions,\n ctx: PptxWriteContext,\n): void => {\n const slidePath = resolveSlidePath(xmlMap, index);\n xmlMap.set(slidePath, toJson(stringifySlide(slideOpts, ctx)));\n};\n\n/** Build the rels part path for a given part path (…/_rels/<file>.rels). */\nconst relsKeyFor = (partPath: string): string => {\n const slash = partPath.lastIndexOf(\"/\");\n return `${partPath.substring(0, slash)}/_rels/${partPath.substring(slash + 1)}.rels`;\n};\n\n/** Find an existing relationship of a type in a Relationships root. */\nconst findRelByType = (\n rels: Element | undefined,\n type: string,\n): { id: string; target: string } | undefined => {\n const relationshipsRoot = rootElement(rels, \"Relationships\");\n for (const child of relationshipsRoot?.elements ?? []) {\n if (child.name === \"Relationship\" && String(child.attributes?.[\"Type\"]) === type) {\n const target = child.attributes?.[\"Target\"];\n if (target !== undefined) {\n return { id: String(child.attributes?.[\"Id\"]), target: String(target) };\n }\n }\n }\n return undefined;\n};\n\n/** Noop ReadContext: comment-author/comment-list parse touches no relationships/parts/raw media. */\nconst STUB_READ_CTX: ReadContext = {\n resolveRelationship: () => undefined,\n getPart: () => undefined,\n getRaw: () => undefined,\n};\n\n/**\n * Append comments to a slide, merging authors into commentAuthors.xml and the\n * per-slide list into ppt/comments/commentN.xml. Wires presentation rels\n * (commentAuthors) + slide rels (comments) + content types when newly introduced.\n */\nconst appendCommentsToMap = (\n xmlMap: Map<string, Element>,\n index: number,\n slideComments: SlideCommentOptions[],\n ctx: PptxWriteContext,\n): void => {\n const slidePath = resolveSlidePath(xmlMap, index);\n const slideNMatch = slidePath.match(/slide(\\d+)\\.xml$/);\n const slideN = slideNMatch ? Number(slideNMatch[1]) : index + 1;\n const commentPath = `ppt/comments/comment${slideN}.xml`;\n\n // Parse existing authors + per-slide comments (merge targets).\n const existingAuthorsRoot = rootElement(xmlMap.get(\"ppt/commentAuthors.xml\"), \"p:cmAuthorLst\");\n const existingAuthors: AuthorEntry[] = existingAuthorsRoot\n ? commentAuthorsDesc.parse(existingAuthorsRoot, STUB_READ_CTX)\n : [];\n const existingEntriesRoot = rootElement(xmlMap.get(commentPath), \"p:cmLst\");\n const existingEntries: CommentEntry[] = existingEntriesRoot\n ? slideCommentsDesc.parse(existingEntriesRoot, STUB_READ_CTX)\n : [];\n\n // buildCommentData continues author ids + per-author idx from existing authors.\n const { authors, perSlide } = buildCommentData(\n [{ comments: slideComments }] as unknown as SlideOptions[],\n existingAuthors,\n );\n const mergedEntries = [...existingEntries, ...(perSlide[0] ?? [])];\n const mergedAuthors = authors ?? existingAuthors;\n\n // commentAuthors.xml (global) — written when any authors exist.\n if (mergedAuthors.length > 0) {\n xmlMap.set(\n \"ppt/commentAuthors.xml\",\n toJson(\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>${commentAuthorsDesc.stringify(mergedAuthors, ctx)}`,\n ),\n );\n const presRels = xmlMap.get(\"ppt/_rels/presentation.xml.rels\") ?? createRelationshipFile();\n xmlMap.set(\"ppt/_rels/presentation.xml.rels\", presRels);\n if (!findRelByType(presRels, COMMENT_AUTHORS_REL_TYPE)) {\n const n = getNextRelationshipIndex(presRels);\n appendRelationship(presRels, n, COMMENT_AUTHORS_REL_TYPE, \"commentAuthors.xml\");\n }\n }\n\n // commentN.xml (per slide).\n xmlMap.set(\n commentPath,\n toJson(\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>${slideCommentsDesc.stringify(mergedEntries, ctx)}`,\n ),\n );\n const slideRelsKey = relsKeyFor(slidePath);\n const slideRels = xmlMap.get(slideRelsKey) ?? createRelationshipFile();\n xmlMap.set(slideRelsKey, slideRels);\n if (!findRelByType(slideRels, COMMENTS_REL_TYPE)) {\n const n = getNextRelationshipIndex(slideRels);\n appendRelationship(slideRels, n, COMMENTS_REL_TYPE, `../comments/comment${slideN}.xml`);\n }\n\n // Content types — commentAuthors + commentN Overrides (deduped).\n const contentTypes = xmlMap.get(\"[Content_Types].xml\");\n if (contentTypes) {\n if (mergedAuthors.length > 0) {\n appendOverride(contentTypes, \"/ppt/commentAuthors.xml\", COMMENT_AUTHORS_CONTENT_TYPE);\n }\n appendOverride(contentTypes, `/${commentPath}`, COMMENTS_CONTENT_TYPE);\n }\n};\n\n/**\n * Patches an existing .pptx presentation by replacing placeholders with run content.\n *\n * Patch content reuses the generate {@link RunOptions} vocabulary (serialized\n * via the same descriptor), so color, fonts, fills, and hyperlinks are all\n * supported. Hyperlinks introduced by patch runs are registered into each\n * slide's relationship part.\n *\n * @publicApi\n */\nexport const patchPresentation = async <T extends OutputType = OutputType>({\n outputType,\n data,\n placeholders,\n findReplace,\n coreProperties,\n slides,\n comments,\n keepOriginalStyles = true,\n placeholderDelimiters = { end: \"}}\", start: \"{{\" } as const,\n}: PatchPresentationOptions<T>): Promise<OutputByType[T]> => {\n const { start, end } = placeholderDelimiters;\n if (!start.trim() || !end.trim()) {\n throw new Error(\"Both start and end delimiters must be non-empty strings.\");\n }\n\n const zipContent = unzipSync(toUint8Array(data));\n\n const xmlMap = new Map<string, Element>();\n const binaryMap = new Map<string, Uint8Array>();\n\n // Separate XML files from binary files\n for (const [key, value] of Object.entries(zipContent)) {\n if (key.endsWith(\".xml\") || key.endsWith(\".rels\")) {\n xmlMap.set(key, toJson(strFromU8(value)));\n } else {\n binaryMap.set(key, value);\n }\n }\n\n // Build (find-text → patch envelope) entries. Placeholders wrap the key in\n // delimiters; findReplace uses the literal key. Both share the same engine.\n const entries: Array<{\n find: string;\n patch: { type: \"paragraph\"; children: RunOptions[] };\n }> = [];\n if (placeholders) {\n for (const [key, value] of Object.entries(placeholders)) {\n entries.push({ find: `${start}${key}${end}`, patch: toReplacerPatch(value) });\n }\n }\n if (findReplace) {\n for (const [key, value] of Object.entries(findReplace)) {\n entries.push({ find: key, patch: toReplacerPatch(value) });\n }\n }\n\n // Target parts: slides + masters + layouts + notes (deterministic order)\n const targetPaths = Object.keys(zipContent)\n .filter((k) => TARGET_RE.test(k))\n .sort();\n\n currentPatchCtx = new PptxWriteContext();\n const context = {};\n\n // Process text replacement on each target part\n for (const targetPath of targetPaths) {\n const json = xmlMap.get(targetPath);\n if (!json) continue;\n\n for (const { find, patch } of entries) {\n pptxReplacer({\n context,\n json,\n keepOriginalStyles,\n patch,\n patchText: find,\n });\n }\n }\n\n // Resolve hyperlink placeholders registered by patch runs into each part's rels\n const hlinkByKey = new Map(currentPatchCtx.hyperlinks.map((h) => [h.key, h]));\n for (const targetPath of targetPaths) {\n const targetEl = xmlMap.get(targetPath);\n if (!targetEl) continue;\n\n const targetXml = js2xml(targetEl);\n const hlinkKeys = collectPlaceholderKeys(targetXml, \"hlink:\");\n if (hlinkKeys.length === 0) continue;\n\n const targetHlinks = hlinkKeys\n .map((k) => hlinkByKey.get(k))\n .filter((h): h is NonNullable<typeof h> => h !== undefined);\n if (targetHlinks.length === 0) continue;\n\n // Generalized rels path: ppt/<dir>/_rels/<file>.rels\n const lastSlash = targetPath.lastIndexOf(\"/\");\n const relsKey = `${targetPath.substring(0, lastSlash)}/_rels/${targetPath.substring(lastSlash + 1)}.rels`;\n const relsJson = xmlMap.get(relsKey) ?? createRelationshipFile();\n xmlMap.set(relsKey, relsJson);\n const offset = getNextRelationshipIndex(relsJson);\n\n const resolved = replaceHyperlinkPlaceholders(targetXml, targetHlinks, offset);\n xmlMap.set(targetPath, toJson(resolved));\n\n for (let i = 0; i < targetHlinks.length; i++) {\n appendRelationship(relsJson, offset + i, HYPERLINK_REL_TYPE, targetHlinks[i].url, \"External\");\n }\n }\n\n // Slide collection edits — reuse the slide stringifier (no compiler re-run)\n if (slides) {\n if (slides.replace) {\n for (const [index, slideOpts] of Object.entries(slides.replace)) {\n replaceSlideInMap(xmlMap, Number(index), slideOpts, currentPatchCtx);\n }\n }\n if (slides.append) {\n for (const slideOpts of slides.append) {\n appendSlideToMap(xmlMap, slideOpts, currentPatchCtx);\n }\n }\n }\n\n // Slide comments — append per slide, merging authors + per-slide comment lists.\n if (comments) {\n for (const [indexStr, slideComments] of Object.entries(comments)) {\n appendCommentsToMap(xmlMap, Number(indexStr), slideComments, currentPatchCtx);\n }\n }\n\n // Rebuild ZIP\n const files: Record<string, Uint8Array> = {};\n const XML_DECL = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>';\n\n for (const [key, value] of xmlMap) {\n files[key] =\n key === \"docProps/core.xml\" && coreProperties\n ? encoder.encode(XML_DECL + applyCorePropertiesOverride(value, coreProperties))\n : encoder.encode(js2xml(value));\n }\n\n for (const [key, value] of binaryMap) {\n files[key] = value;\n }\n\n return await zipAndConvert(files, outputType, OoxmlMimeType.PPTX);\n};\n"],"mappings":"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"} | ||
| {"version":3,"file":"patch.mjs","names":[],"sources":["../src/patch.ts"],"sourcesContent":["import {\n PPTX_NS,\n OoxmlMimeType,\n appendOverride,\n appendRelationship,\n applyCorePropertiesOverride,\n collectPlaceholderKeys,\n createReplacer,\n getNextRelationshipIndex,\n nextNumericId,\n replaceHyperlinkPlaceholders,\n strFromU8,\n toJson,\n unzipSync,\n zipAndConvert,\n} from \"@office-open/core\";\nimport type {\n BasePatchOptions,\n CorePropertiesOptions,\n OutputByType,\n OutputType,\n} from \"@office-open/core\";\nimport { toUint8Array } from \"@office-open/core\";\nimport type { ReadContext } from \"@office-open/core/descriptor\";\nimport { findChild, js2xml, xml2js } from \"@office-open/xml\";\nimport type { Element } from \"@office-open/xml\";\nimport type { AuthorEntry, CommentEntry } from \"@parts/comment\";\nimport { commentAuthorsDesc, slideCommentsDesc } from \"@parts/descriptors/comments\";\nimport { textRunDesc } from \"@parts/descriptors/text\";\nimport type { SlideCommentOptions, SlideOptions } from \"@shared/file\";\nimport type { RunOptions } from \"@shared/shape/paragraph/run\";\n\nimport { buildCommentData, stringifySlide } from \"./compiler\";\nimport { PptxWriteContext } from \"./context\";\n\n/** Reusable TextEncoder (stateless, safe to share). */\nconst encoder = new TextEncoder();\n\n/**\n * Parts scanned for text replacement: slides, slide masters, slide layouts,\n * and notes slides. Replacing text in a master/layout propagates to every\n * dependent slide — intended for template branding.\n */\nconst TARGET_RE =\n /^ppt\\/(?:slides\\/slide\\d+|slideMasters\\/slideMaster\\d+|slideLayouts\\/slideLayout\\d+|notesSlides\\/notesSlide\\d+)\\.xml$/;\nconst HYPERLINK_REL_TYPE =\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink\";\nconst SLIDE_PART_CONTENT_TYPE =\n \"application/vnd.openxmlformats-officedocument.presentationml.slide+xml\";\nconst SLIDE_REL_TYPE = \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide\";\nconst SLIDE_LAYOUT_REL_TYPE =\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout\";\nconst COMMENTS_REL_TYPE =\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments\";\nconst COMMENT_AUTHORS_REL_TYPE =\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors\";\nconst COMMENTS_CONTENT_TYPE =\n \"application/vnd.openxmlformats-officedocument.presentationml.comments+xml\";\nconst COMMENT_AUTHORS_CONTENT_TYPE =\n \"application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml\";\n\n/**\n * Inline run-level patch content. Reuses the generate vocabulary: a\n * {@link RunOptions} (or an array of them), or a plain string shorthand\n * for `{ text: \"…\" }`.\n */\nexport type Patch = RunOptions | RunOptions[] | string;\n\nexport interface PatchPresentationOptions<\n T extends OutputType = OutputType,\n> extends BasePatchOptions<T> {\n /** Placeholder substitutions: `{{key}}` (per delimiters) → run content. */\n placeholders?: Readonly<Record<string, Patch>>;\n /** Literal find/replace: the find string → run content (no delimiters added). */\n findReplace?: Readonly<Record<string, Patch>>;\n /** Core-properties metadata override (merged over the existing docProps/core.xml). */\n coreProperties?: Partial<CorePropertiesOptions>;\n /**\n * Slide collection edits. Appended slides inherit the template's first slide\n * layout; replaced slides keep their existing identity (sldId/rId/rels).\n */\n slides?: {\n /** Replace slides keyed by 0-based index in the slide list (sldIdLst order). */\n replace?: Readonly<Record<number, SlideOptions>>;\n /** Append slides after the last existing slide. */\n append?: Readonly<SlideOptions[]>;\n };\n /**\n * Comments to append per slide, keyed by 0-based slide index (sldIdLst order).\n * Authors are merged into commentAuthors.xml (deduped by name, ids continued);\n * per-slide comments are merged into ppt/comments/commentN.xml.\n */\n comments?: Readonly<Record<number, SlideCommentOptions[]>>;\n keepOriginalStyles?: boolean;\n}\n\n/** Write context for the current patch operation — accumulates hyperlinks. */\nlet currentPatchCtx: PptxWriteContext;\n\n/**\n * Patch replacer. Serializes each run via {@link textRunDesc} so the full\n * RunProperties vocabulary (color, fill, outline, shadow, font, hyperlinks, …)\n * is supported — no hand-rolled `<a:r>` builder.\n */\nconst pptxReplacer = createReplacer({\n ns: PPTX_NS,\n formatChild: (child: unknown): Element[] => {\n const runOpts = (typeof child === \"string\" ? { text: child } : child) as RunOptions;\n const xmlStr = textRunDesc.stringify(runOpts, currentPatchCtx) ?? \"<a:r/>\";\n return [xml2js(xmlStr, { captureSpacesBetweenElements: true }).elements![0]];\n },\n preserveSpace: false,\n});\n\n/**\n * Normalize a user patch value into the replacer's `{ type, children }`\n * envelope. PPTX patches are always inline run-level (`type: \"paragraph\"`).\n */\nconst toReplacerPatch = (patch: Patch): { type: \"paragraph\"; children: RunOptions[] } =>\n typeof patch === \"string\"\n ? { type: \"paragraph\", children: [{ text: patch }] }\n : { type: \"paragraph\", children: Array.isArray(patch) ? patch : [patch] };\n\nconst createRelationshipFile = (): Element => ({\n declaration: {\n attributes: { encoding: \"UTF-8\", standalone: \"yes\", version: \"1.0\" },\n },\n elements: [\n {\n attributes: { xmlns: \"http://schemas.openxmlformats.org/package/2006/relationships\" },\n elements: [],\n name: \"Relationships\",\n type: \"element\",\n },\n ],\n});\n\n/** Build a bare OOXML element node. */\nconst makeElement = (name: string, attributes: Record<string, string> = {}): Element => ({\n type: \"element\",\n name,\n attributes,\n elements: [],\n});\n\n/**\n * Locate the document root element by tag. A parsed XML part is wrapped as\n * `{ declaration, elements: [<root>] }`, so named children live one level down.\n */\nconst rootElement = (doc: Element | undefined, name: string): Element | undefined =>\n doc?.elements?.find((e) => e.name === name);\n\n/** Next 1-based slide file number given the existing slide parts. */\nconst nextSlideNumber = (xmlMap: Map<string, Element>): number => {\n let maxN = 0;\n for (const key of xmlMap.keys()) {\n const m = key.match(/^ppt\\/slides\\/slide(\\d+)\\.xml$/);\n if (m) maxN = Math.max(maxN, Number(m[1]));\n }\n return maxN + 1;\n};\n\n/** Next id for an appended `<p:sldId>` (255 floor → ≥256). */\nconst nextSldId = (sldIdLst: Element | undefined): number =>\n nextNumericId(sldIdLst, \"p:sldId\", \"id\", 255);\n\n/** Resolve a relationship `r:id` to its Target via a rels part. */\nconst resolveRelTarget = (\n rels: Element | undefined,\n rId: string | number | undefined,\n): string | undefined => {\n if (rId === undefined) return undefined;\n const needle = String(rId);\n const relationshipsRoot = rootElement(rels, \"Relationships\");\n for (const child of relationshipsRoot?.elements ?? []) {\n if (child.name === \"Relationship\" && String(child.attributes?.[\"Id\"]) === needle) {\n const target = child.attributes?.[\"Target\"];\n return target !== undefined ? String(target) : undefined;\n }\n }\n return undefined;\n};\n\n/**\n * Append a slide: serialize it, then wire sldIdLst + presentation rels +\n * content types + a slide rels pointing at the first slide layout (which must\n * already exist in the template). The appended slide inherits the template's\n * layout/master; it cannot reference styles or media not already present.\n */\nconst appendSlideToMap = (\n xmlMap: Map<string, Element>,\n slideOpts: SlideOptions,\n ctx: PptxWriteContext,\n): void => {\n const newN = nextSlideNumber(xmlMap);\n const slidePath = `ppt/slides/slide${newN}.xml`;\n\n // Slide part — no XML declaration, matching generated slide parts.\n xmlMap.set(slidePath, toJson(stringifySlide(slideOpts, ctx)));\n\n // presentation.xml sldIdLst + presentation.xml.rels (the new rId ties them)\n const presRoot = rootElement(xmlMap.get(\"ppt/presentation.xml\"), \"p:presentation\");\n const presRels = xmlMap.get(\"ppt/_rels/presentation.xml.rels\") ?? createRelationshipFile();\n xmlMap.set(\"ppt/_rels/presentation.xml.rels\", presRels);\n const newRId = getNextRelationshipIndex(presRels);\n\n const sldIdLst = findChild(presRoot, \"p:sldIdLst\");\n if (sldIdLst) {\n const els = sldIdLst.elements ?? (sldIdLst.elements = []);\n els.push(makeElement(\"p:sldId\", { id: String(nextSldId(sldIdLst)), \"r:id\": `rId${newRId}` }));\n }\n appendRelationship(presRels, newRId, SLIDE_REL_TYPE, `slides/slide${newN}.xml`);\n\n // [Content_Types].xml Override\n const contentTypes = xmlMap.get(\"[Content_Types].xml\");\n if (contentTypes) {\n appendOverride(contentTypes, `/${slidePath}`, SLIDE_PART_CONTENT_TYPE);\n }\n\n // Slide rels → first slide layout (template must already provide it)\n const slideRels = createRelationshipFile();\n appendRelationship(slideRels, 1, SLIDE_LAYOUT_REL_TYPE, \"../slideLayouts/slideLayout1.xml\");\n xmlMap.set(`ppt/slides/_rels/slide${newN}.xml.rels`, slideRels);\n};\n\n/** Resolve a 0-based sldIdLst index to its slide part path (ppt/slides/slideN.xml). */\nconst resolveSlidePath = (xmlMap: Map<string, Element>, index: number): string => {\n const presRoot = rootElement(xmlMap.get(\"ppt/presentation.xml\"), \"p:presentation\");\n const sldIdLst = findChild(presRoot, \"p:sldIdLst\");\n const sldIds = (sldIdLst?.elements ?? []).filter((e) => e.name === \"p:sldId\");\n const entry = sldIds[index];\n if (!entry?.attributes?.[\"r:id\"]) {\n throw new Error(`patchPresentation: no slide at index ${index}`);\n }\n const target = resolveRelTarget(\n xmlMap.get(\"ppt/_rels/presentation.xml.rels\"),\n entry.attributes[\"r:id\"],\n );\n if (!target) {\n throw new Error(`patchPresentation: slide ${index} relationship target not found`);\n }\n return `ppt/${target}`;\n};\n\n/**\n * Replace a slide in place by sldIdLst index: resolve the index to its slide\n * path via presentation rels, then rewrite only that part's content. sldId,\n * rId, content types, and slide rels are left untouched.\n */\nconst replaceSlideInMap = (\n xmlMap: Map<string, Element>,\n index: number,\n slideOpts: SlideOptions,\n ctx: PptxWriteContext,\n): void => {\n const slidePath = resolveSlidePath(xmlMap, index);\n xmlMap.set(slidePath, toJson(stringifySlide(slideOpts, ctx)));\n};\n\n/** Build the rels part path for a given part path (…/_rels/<file>.rels). */\nconst relsKeyFor = (partPath: string): string => {\n const slash = partPath.lastIndexOf(\"/\");\n return `${partPath.substring(0, slash)}/_rels/${partPath.substring(slash + 1)}.rels`;\n};\n\n/** Find an existing relationship of a type in a Relationships root. */\nconst findRelByType = (\n rels: Element | undefined,\n type: string,\n): { id: string; target: string } | undefined => {\n const relationshipsRoot = rootElement(rels, \"Relationships\");\n for (const child of relationshipsRoot?.elements ?? []) {\n if (child.name === \"Relationship\" && String(child.attributes?.[\"Type\"]) === type) {\n const target = child.attributes?.[\"Target\"];\n if (target !== undefined) {\n return { id: String(child.attributes?.[\"Id\"]), target: String(target) };\n }\n }\n }\n return undefined;\n};\n\n/** Noop ReadContext: comment-author/comment-list parse touches no relationships/parts/raw media. */\nconst STUB_READ_CTX: ReadContext = {\n resolveRelationship: () => undefined,\n getPart: () => undefined,\n getRaw: () => undefined,\n};\n\n/**\n * Append comments to a slide, merging authors into commentAuthors.xml and the\n * per-slide list into ppt/comments/commentN.xml. Wires presentation rels\n * (commentAuthors) + slide rels (comments) + content types when newly introduced.\n */\nconst appendCommentsToMap = (\n xmlMap: Map<string, Element>,\n index: number,\n slideComments: SlideCommentOptions[],\n ctx: PptxWriteContext,\n): void => {\n const slidePath = resolveSlidePath(xmlMap, index);\n const slideNMatch = slidePath.match(/slide(\\d+)\\.xml$/);\n const slideN = slideNMatch ? Number(slideNMatch[1]) : index + 1;\n const commentPath = `ppt/comments/comment${slideN}.xml`;\n\n // Parse existing authors + per-slide comments (merge targets).\n const existingAuthorsRoot = rootElement(xmlMap.get(\"ppt/commentAuthors.xml\"), \"p:cmAuthorLst\");\n const existingAuthors: AuthorEntry[] = existingAuthorsRoot\n ? commentAuthorsDesc.parse(existingAuthorsRoot, STUB_READ_CTX)\n : [];\n const existingEntriesRoot = rootElement(xmlMap.get(commentPath), \"p:cmLst\");\n const existingEntries: CommentEntry[] = existingEntriesRoot\n ? slideCommentsDesc.parse(existingEntriesRoot, STUB_READ_CTX)\n : [];\n\n // buildCommentData continues author ids + per-author idx from existing authors.\n const { authors, perSlide } = buildCommentData(\n [{ comments: slideComments }] as unknown as SlideOptions[],\n existingAuthors,\n );\n const mergedEntries = [...existingEntries, ...(perSlide[0] ?? [])];\n const mergedAuthors = authors ?? existingAuthors;\n\n // commentAuthors.xml (global) — written when any authors exist.\n if (mergedAuthors.length > 0) {\n xmlMap.set(\n \"ppt/commentAuthors.xml\",\n toJson(\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>${commentAuthorsDesc.stringify(mergedAuthors, ctx)}`,\n ),\n );\n const presRels = xmlMap.get(\"ppt/_rels/presentation.xml.rels\") ?? createRelationshipFile();\n xmlMap.set(\"ppt/_rels/presentation.xml.rels\", presRels);\n if (!findRelByType(presRels, COMMENT_AUTHORS_REL_TYPE)) {\n const n = getNextRelationshipIndex(presRels);\n appendRelationship(presRels, n, COMMENT_AUTHORS_REL_TYPE, \"commentAuthors.xml\");\n }\n }\n\n // commentN.xml (per slide).\n xmlMap.set(\n commentPath,\n toJson(\n `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>${slideCommentsDesc.stringify(mergedEntries, ctx)}`,\n ),\n );\n const slideRelsKey = relsKeyFor(slidePath);\n const slideRels = xmlMap.get(slideRelsKey) ?? createRelationshipFile();\n xmlMap.set(slideRelsKey, slideRels);\n if (!findRelByType(slideRels, COMMENTS_REL_TYPE)) {\n const n = getNextRelationshipIndex(slideRels);\n appendRelationship(slideRels, n, COMMENTS_REL_TYPE, `../comments/comment${slideN}.xml`);\n }\n\n // Content types — commentAuthors + commentN Overrides (deduped).\n const contentTypes = xmlMap.get(\"[Content_Types].xml\");\n if (contentTypes) {\n if (mergedAuthors.length > 0) {\n appendOverride(contentTypes, \"/ppt/commentAuthors.xml\", COMMENT_AUTHORS_CONTENT_TYPE);\n }\n appendOverride(contentTypes, `/${commentPath}`, COMMENTS_CONTENT_TYPE);\n }\n};\n\n/**\n * Patches an existing .pptx presentation by replacing placeholders with run content.\n *\n * Patch content reuses the generate {@link RunOptions} vocabulary (serialized\n * via the same descriptor), so color, fonts, fills, and hyperlinks are all\n * supported. Hyperlinks introduced by patch runs are registered into each\n * slide's relationship part.\n *\n * @publicApi\n */\nexport const patchPresentation = async <T extends OutputType = OutputType>({\n outputType,\n data,\n placeholders,\n findReplace,\n coreProperties,\n slides,\n comments,\n keepOriginalStyles = true,\n placeholderDelimiters = { end: \"}}\", start: \"{{\" } as const,\n}: PatchPresentationOptions<T>): Promise<OutputByType[T]> => {\n const { start, end } = placeholderDelimiters;\n if (!start.trim() || !end.trim()) {\n throw new Error(\"Both start and end delimiters must be non-empty strings.\");\n }\n\n const zipContent = unzipSync(toUint8Array(data));\n\n const xmlMap = new Map<string, Element>();\n const binaryMap = new Map<string, Uint8Array>();\n\n // Separate XML files from binary files\n for (const [key, value] of Object.entries(zipContent)) {\n if (key.endsWith(\".xml\") || key.endsWith(\".rels\")) {\n xmlMap.set(key, toJson(strFromU8(value)));\n } else {\n binaryMap.set(key, value);\n }\n }\n\n // Build (find-text → patch envelope) entries. Placeholders wrap the key in\n // delimiters; findReplace uses the literal key. Both share the same engine.\n const entries: Array<{\n find: string;\n patch: { type: \"paragraph\"; children: RunOptions[] };\n }> = [];\n if (placeholders) {\n for (const [key, value] of Object.entries(placeholders)) {\n entries.push({ find: `${start}${key}${end}`, patch: toReplacerPatch(value) });\n }\n }\n if (findReplace) {\n for (const [key, value] of Object.entries(findReplace)) {\n entries.push({ find: key, patch: toReplacerPatch(value) });\n }\n }\n\n // Target parts: slides + masters + layouts + notes (deterministic order)\n const targetPaths = Object.keys(zipContent)\n .filter((k) => TARGET_RE.test(k))\n .sort();\n\n currentPatchCtx = new PptxWriteContext();\n const context = {};\n\n // Process text replacement on each target part\n for (const targetPath of targetPaths) {\n const json = xmlMap.get(targetPath);\n if (!json) continue;\n\n for (const { find, patch } of entries) {\n pptxReplacer({\n context,\n json,\n keepOriginalStyles,\n patch,\n patchText: find,\n });\n }\n }\n\n // Resolve hyperlink placeholders registered by patch runs into each part's rels\n const hlinkByKey = new Map(currentPatchCtx.hyperlinks.map((h) => [h.key, h]));\n for (const targetPath of targetPaths) {\n const targetEl = xmlMap.get(targetPath);\n if (!targetEl) continue;\n\n const targetXml = js2xml(targetEl);\n const hlinkKeys = collectPlaceholderKeys(targetXml, \"hlink:\");\n if (hlinkKeys.length === 0) continue;\n\n const targetHlinks = hlinkKeys\n .map((k) => hlinkByKey.get(k))\n .filter((h): h is NonNullable<typeof h> => h !== undefined);\n if (targetHlinks.length === 0) continue;\n\n // Generalized rels path: ppt/<dir>/_rels/<file>.rels\n const lastSlash = targetPath.lastIndexOf(\"/\");\n const relsKey = `${targetPath.substring(0, lastSlash)}/_rels/${targetPath.substring(lastSlash + 1)}.rels`;\n const relsJson = xmlMap.get(relsKey) ?? createRelationshipFile();\n xmlMap.set(relsKey, relsJson);\n const offset = getNextRelationshipIndex(relsJson);\n\n const resolved = replaceHyperlinkPlaceholders(targetXml, targetHlinks, offset);\n xmlMap.set(targetPath, toJson(resolved));\n\n for (let i = 0; i < targetHlinks.length; i++) {\n appendRelationship(relsJson, offset + i, HYPERLINK_REL_TYPE, targetHlinks[i].url, \"External\");\n }\n }\n\n // Slide collection edits — reuse the slide stringifier (no compiler re-run)\n if (slides) {\n if (slides.replace) {\n for (const [index, slideOpts] of Object.entries(slides.replace)) {\n replaceSlideInMap(xmlMap, Number(index), slideOpts, currentPatchCtx);\n }\n }\n if (slides.append) {\n for (const slideOpts of slides.append) {\n appendSlideToMap(xmlMap, slideOpts, currentPatchCtx);\n }\n }\n }\n\n // Slide comments — append per slide, merging authors + per-slide comment lists.\n if (comments) {\n for (const [indexStr, slideComments] of Object.entries(comments)) {\n appendCommentsToMap(xmlMap, Number(indexStr), slideComments, currentPatchCtx);\n }\n }\n\n // Rebuild ZIP\n const files: Record<string, Uint8Array> = {};\n const XML_DECL = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>';\n\n for (const [key, value] of xmlMap) {\n files[key] =\n key === \"docProps/core.xml\" && coreProperties\n ? encoder.encode(XML_DECL + applyCorePropertiesOverride(value, coreProperties))\n : encoder.encode(js2xml(value));\n }\n\n for (const [key, value] of binaryMap) {\n files[key] = value;\n }\n\n return await zipAndConvert(files, outputType, OoxmlMimeType.PPTX);\n};\n"],"mappings":"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"} |
+3
-3
| { | ||
| "name": "@office-open/pptx", | ||
| "version": "0.10.6", | ||
| "version": "0.10.7", | ||
| "description": "Generate, parse, and patch .pptx presentations with a declarative TypeScript API", | ||
@@ -51,4 +51,4 @@ "keywords": [ | ||
| "dependencies": { | ||
| "@office-open/core": "0.10.6", | ||
| "@office-open/xml": "0.10.6" | ||
| "@office-open/core": "0.10.7", | ||
| "@office-open/xml": "0.10.7" | ||
| }, | ||
@@ -55,0 +55,0 @@ "scripts": { |
+9
-9
@@ -104,6 +104,6 @@ # @office-open/pptx | ||
| | ------------------ | -----------: | ------------: | -------------: | --------------: | ----------------: | --------------: | | ||
| | Simple (2 shapes) | 1,684 ops/s | 773 ops/s | 6,061 ops/s | 5,249 ops/s | 181 ops/s | 185 ops/s | | ||
| | Styled shapes (20) | 1,497 ops/s | 745 ops/s | 5,154 ops/s | 4,958 ops/s | 168 ops/s | 170 ops/s | | ||
| | Table (10x5) | 1,657 ops/s | 729 ops/s | 7,252 ops/s | 6,797 ops/s | 889 ops/s | 999 ops/s | | ||
| | Full featured | 1,635 ops/s | 714 ops/s | 4,816 ops/s | 4,321 ops/s | 96 ops/s | 94 ops/s | | ||
| | Simple (2 shapes) | 1,391 ops/s | 693 ops/s | 4,055 ops/s | 4,148 ops/s | 182 ops/s | 187 ops/s | | ||
| | Styled shapes (20) | 1,302 ops/s | 661 ops/s | 4,387 ops/s | 4,030 ops/s | 188 ops/s | 183 ops/s | | ||
| | Table (10x5) | 1,694 ops/s | 802 ops/s | 7,787 ops/s | 7,891 ops/s | 857 ops/s | 937 ops/s | | ||
| | Full featured | 1,155 ops/s | 627 ops/s | 2,873 ops/s | 2,821 ops/s | 97 ops/s | 98 ops/s | | ||
@@ -114,6 +114,6 @@ **Large Files — Create + toBuffer** | ||
| | --------------------- | -----------: | ------------: | -------------: | --------------: | ----------------: | --------------: | | ||
| | 30 slides x 20 shapes | 253 ops/s | 139 ops/s | 500 ops/s | 490 ops/s | 119 ops/s | 123 ops/s | | ||
| | 30 slides x 10 images | 320 ops/s | 160 ops/s | 793 ops/s | 795 ops/s | 0.26 ops/s | 0.30 ops/s | | ||
| | 100x10 table | 641 ops/s | 460 ops/s | 954 ops/s | 891 ops/s | 120 ops/s | 126 ops/s | | ||
| | 50 slides full | 169 ops/s | 87 ops/s | 326 ops/s | 317 ops/s | 0.90 ops/s | 0.90 ops/s | | ||
| | 30 slides x 20 shapes | 271 ops/s | 144 ops/s | 571 ops/s | 577 ops/s | 119 ops/s | 120 ops/s | | ||
| | 30 slides x 10 images | 130 ops/s | 87.4 ops/s | 173 ops/s | 168 ops/s | 0.32 ops/s | 0.32 ops/s | | ||
| | 100x10 table | 618 ops/s | 453 ops/s | 1,082 ops/s | 1,039 ops/s | 128 ops/s | 123 ops/s | | ||
| | 50 slides full | 89.2 ops/s | 60.5 ops/s | 131 ops/s | 129 ops/s | 0.95 ops/s | 0.95 ops/s | | ||
@@ -126,3 +126,3 @@ **Large File (~100MB) — Mixed Content** | ||
| | --------------- | -----------: | ------------: | -------------: | --------------: | ----------------: | --------------: | | ||
| | 40 slides mixed | 227 ops/s | 124 ops/s | 708 ops/s | 721 ops/s | 0.23 ops/s | 0.22 ops/s | | ||
| | 40 slides mixed | 24.5 ops/s | 22.1 ops/s | 26.3 ops/s | 26.5 ops/s | 0.22 ops/s | 0.23 ops/s | | ||
@@ -129,0 +129,0 @@ ## Examples |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
1001920
0.07%+ Added
+ Added
- Removed
- Removed
Updated
Updated