{"_id":"@aiden0z/pptx-renderer","_rev":"12-a94c6e07bd4292c1d35a3416143ea0f7","name":"@aiden0z/pptx-renderer","dist-tags":{"latest":"1.3.0"},"versions":{"1.0.0":{"name":"@aiden0z/pptx-renderer","version":"1.0.0","keywords":["pptx","powerpoint","renderer","ooxml","slides"],"license":"Apache-2.0","_id":"@aiden0z/pptx-renderer@1.0.0","maintainers":[{"name":"aiden0xz","email":"aiden0xz@gmail.com"}],"homepage":"https://github.com/aiden0z/pptx-renderer#readme","bugs":{"url":"https://github.com/aiden0z/pptx-renderer/issues"},"dist":{"shasum":"0363be0892d2ba7745b220824318fbf640461fe9","tarball":"https://registry.npmjs.org/@aiden0z/pptx-renderer/-/pptx-renderer-1.0.0.tgz","fileCount":45,"integrity":"sha512-wyK2TiGh1UVaanpl5onrBZVFf/2RFP1Evqscdbex3fGUI1aJm/sZBJ8+r8dNKdQwO0SmgwKvOAoYpq1OU0BK4A==","signatures":[{"sig":"MEQCIB1mFA8bYTBvnxAx8oSH+z5Fif+fUKKB/RVHIR7gND8iAiByhUchVnkQKmbIKJPsNRGks6LUgXD25bEPODnFgShpXA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":9886840},"main":"./dist/aiden0z-pptx-renderer.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/aiden0z-pptx-renderer.es.js","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/aiden0z-pptx-renderer.es.js"},"require":{"types":"./dist/types/index.d.cts","default":"./dist/aiden0z-pptx-renderer.cjs"}}},"gitHead":"8c920a1f913e8ee312acd1227e831d67554e0851","scripts":{"dev":"vite","knip":"knip","lint":"eslint src/","size":"size-limit","test":"vitest run","build":"rm -rf dist && vite build && tsc --emitDeclarationOnly --declarationMap false --outDir dist/types && cp dist/types/index.d.ts dist/types/index.d.cts","format":"prettier --write 'src/**/*.ts'","dev:api":"cd test/e2e && .venv/bin/python server.py","dev:e2e":"bash ./scripts/dev-e2e.sh","prepare":"husky","preview":"vite preview","publint":"publint","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","build:demo":"vite build --config vite.config.demo.ts","test:watch":"vitest","format:check":"prettier --check 'src/**/*.ts'","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"aiden0xz","email":"aiden0xz@gmail.com"},"repository":{"url":"git+https://github.com/aiden0z/pptx-renderer.git","type":"git"},"size-limit":[{"gzip":true,"path":"dist/aiden0z-pptx-renderer.es.js","limit":"1400 kB"}],"_npmVersion":"11.4.2","description":"Parse and render PPTX files in the browser with a TypeScript-first engine.","directories":{},"lint-staged":{"src/**/*.ts":["eslint --fix","prettier --write"],"*.{json,md,html,css}":["prettier --write"]},"sideEffects":false,"_nodeVersion":"24.3.0","dependencies":{"jszip":"^3.10.1","echarts":"^6.0.0","pdfjs-dist":"^5.4.624"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"knip":"^5.85.0","vite":"^6.0.0","husky":"^9.1.7","jsdom":"^26.0.0","pngjs":"^7.0.0","canvas":"^3.2.1","eslint":"^10.0.2","vitest":"^3.0.0","publint":"^0.3.17","prettier":"^3.8.1","@eslint/js":"^10.0.1","pixelmatch":"^7.1.0","size-limit":"^12.0.0","typescript":"^5.7.0","lint-staged":"^16.2.7","@commitlint/cli":"^20.4.2","@size-limit/file":"^12.0.0","typescript-eslint":"^8.56.1","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^10.1.8","@commitlint/config-conventional":"^20.4.2"},"_npmOperationalInternal":{"tmp":"tmp/pptx-renderer_1.0.0_1772289503258_0.9844863268006132","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@aiden0z/pptx-renderer","version":"1.0.1","keywords":["pptx","powerpoint","renderer","ooxml","slides"],"license":"Apache-2.0","_id":"@aiden0z/pptx-renderer@1.0.1","maintainers":[{"name":"aiden0xz","email":"aiden0xz@gmail.com"}],"homepage":"https://github.com/aiden0z/pptx-renderer#readme","bugs":{"url":"https://github.com/aiden0z/pptx-renderer/issues"},"dist":{"shasum":"62626fa9a49154d1e35f3452a3f3c2ef2dcb3795","tarball":"https://registry.npmjs.org/@aiden0z/pptx-renderer/-/pptx-renderer-1.0.1.tgz","fileCount":46,"integrity":"sha512-3ALt9XaqRXlsjvaZfGcgjozcB7dfRPrkkKPPrPEsuMsmBUVj3NPrB+trRKJWswQ5/V6TMb1q1BvYk1JHyMd2RA==","signatures":[{"sig":"MEQCIEDZL2O+pyeuK9GbbAaqmyr8aDohJz/Rsmi1aIhpnuUYAiBvvEkwg0H4tP8hZfzyCIjE+UBCAWPoCkEnzDh6K39LJw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4646687},"main":"./dist/aiden0z-pptx-renderer.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/aiden0z-pptx-renderer.es.js","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/aiden0z-pptx-renderer.es.js"},"require":{"types":"./dist/types/index.d.cts","default":"./dist/aiden0z-pptx-renderer.cjs"}}},"gitHead":"dc7366f0a3555e25b6fbb809ecd46913f11668a4","scripts":{"dev":"vite","knip":"knip","lint":"eslint src/","size":"size-limit","test":"vitest run","build":"rm -rf dist && vite build && tsc --emitDeclarationOnly --declarationMap false --outDir dist/types && cp dist/types/index.d.ts dist/types/index.d.cts","format":"prettier --write 'src/**/*.ts'","dev:api":"cd test/e2e && .venv/bin/python server.py","dev:e2e":"bash ./scripts/dev-e2e.sh","prepare":"husky","preview":"vite preview","publint":"publint","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","build:demo":"vite build --config vite.config.demo.ts","test:watch":"vitest","format:check":"prettier --check 'src/**/*.ts'","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"aiden0xz","email":"aiden0xz@gmail.com"},"repository":{"url":"git+https://github.com/aiden0z/pptx-renderer.git","type":"git"},"size-limit":[{"gzip":true,"path":"dist/aiden0z-pptx-renderer.es.js","limit":"1400 kB"}],"_npmVersion":"11.4.2","description":"Parse and render PPTX files in the browser with a TypeScript-first engine.","directories":{},"lint-staged":{"src/**/*.ts":["eslint --fix","prettier --write"],"*.{json,md,html,css}":["prettier --write"]},"sideEffects":false,"_nodeVersion":"24.3.0","dependencies":{"jszip":"^3.10.1","echarts":"^6.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"knip":"^5.85.0","vite":"^6.0.0","husky":"^9.1.7","jsdom":"^26.0.0","pngjs":"^7.0.0","canvas":"^3.2.1","eslint":"^10.0.2","vitest":"^3.0.0","publint":"^0.3.17","prettier":"^3.8.1","@eslint/js":"^10.0.1","pixelmatch":"^7.1.0","size-limit":"^12.0.0","typescript":"^5.7.0","lint-staged":"^16.2.7","@commitlint/cli":"^20.4.2","@size-limit/file":"^12.0.0","typescript-eslint":"^8.56.1","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^10.1.8","@commitlint/config-conventional":"^20.4.2"},"peerDependencies":{"pdfjs-dist":"^5.0.0"},"peerDependenciesMeta":{"pdfjs-dist":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pptx-renderer_1.0.1_1772364025674_0.3740296608168261","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@aiden0z/pptx-renderer","version":"1.0.2","keywords":["pptx","powerpoint","renderer","ooxml","slides"],"license":"Apache-2.0","_id":"@aiden0z/pptx-renderer@1.0.2","maintainers":[{"name":"aiden0xz","email":"aiden0xz@gmail.com"}],"homepage":"https://github.com/aiden0z/pptx-renderer#readme","bugs":{"url":"https://github.com/aiden0z/pptx-renderer/issues"},"dist":{"shasum":"23a003e11f25d8bff499b46c5cf43b3cd002c4e4","tarball":"https://registry.npmjs.org/@aiden0z/pptx-renderer/-/pptx-renderer-1.0.2.tgz","fileCount":46,"integrity":"sha512-8VRqkH0AzHsZXYStA+j/7/Al8KsZohdrszSMxGvOXn4fXf8GT8d2KQlhCDCBWWlr35aTq56zItbqGckI1imLIQ==","signatures":[{"sig":"MEQCICNl9EBwmYomP3TgI/2XrQSXAOfbw7sMM89LZHkL3iQFAiB009dzjPPEGyMaw9fZKq2dSobdsUO7p6ryoJn61Ig1Zg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4704347},"main":"./dist/aiden0z-pptx-renderer.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/aiden0z-pptx-renderer.es.js","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/aiden0z-pptx-renderer.es.js"},"require":{"types":"./dist/types/index.d.cts","default":"./dist/aiden0z-pptx-renderer.cjs"}}},"gitHead":"e6200e85e3fafa392cc5ae34415c4c83c405e603","scripts":{"dev":"vite","knip":"knip","lint":"eslint src/","size":"size-limit","test":"vitest run","build":"rm -rf dist && vite build && tsc --emitDeclarationOnly --declarationMap false --outDir dist/types && cp dist/types/index.d.ts dist/types/index.d.cts","format":"prettier --write 'src/**/*.ts'","dev:api":"cd test/e2e && .venv/bin/python server.py","dev:e2e":"bash ./scripts/dev-e2e.sh","prepare":"husky","preview":"vite preview","publint":"publint","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","build:demo":"vite build --config vite.config.demo.ts","test:watch":"vitest","format:check":"prettier --check 'src/**/*.ts'","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"aiden0xz","email":"aiden0xz@gmail.com"},"repository":{"url":"git+https://github.com/aiden0z/pptx-renderer.git","type":"git"},"size-limit":[{"gzip":true,"path":"dist/aiden0z-pptx-renderer.es.js","limit":"1400 kB"}],"_npmVersion":"11.4.2","description":"Parse and render PPTX files in the browser with a TypeScript-first engine.","directories":{},"lint-staged":{"src/**/*.ts":["eslint --fix","prettier --write"],"*.{json,md,html,css}":["prettier --write"]},"sideEffects":false,"_nodeVersion":"24.3.0","dependencies":{"jszip":"^3.10.1","echarts":"^6.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"knip":"^5.85.0","vite":"^6.0.0","husky":"^9.1.7","jsdom":"^26.0.0","pngjs":"^7.0.0","canvas":"^3.2.1","eslint":"^10.0.2","vitest":"^3.0.0","publint":"^0.3.17","prettier":"^3.8.1","@eslint/js":"^10.0.1","pixelmatch":"^7.1.0","size-limit":"^12.0.0","typescript":"^5.7.0","lint-staged":"^16.2.7","@commitlint/cli":"^20.4.2","@size-limit/file":"^12.0.0","typescript-eslint":"^8.56.1","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^10.1.8","@commitlint/config-conventional":"^20.4.2"},"peerDependencies":{"pdfjs-dist":"^5.0.0"},"peerDependenciesMeta":{"pdfjs-dist":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pptx-renderer_1.0.2_1773041995653_0.4718842225987765","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@aiden0z/pptx-renderer","version":"1.0.3","keywords":["pptx","powerpoint","renderer","ooxml","slides"],"license":"Apache-2.0","_id":"@aiden0z/pptx-renderer@1.0.3","maintainers":[{"name":"aiden0xz","email":"aiden0xz@gmail.com"}],"homepage":"https://github.com/aiden0z/pptx-renderer#readme","bugs":{"url":"https://github.com/aiden0z/pptx-renderer/issues"},"dist":{"shasum":"3b7b9ca1de39680a2048b49fc742624c2baf0a41","tarball":"https://registry.npmjs.org/@aiden0z/pptx-renderer/-/pptx-renderer-1.0.3.tgz","fileCount":48,"integrity":"sha512-Vs/5T7HXmcpfu3K+qj9x1Y528GP6pUCilzJ6GEnC9p5493byVHRNBoSxcnB6045qVObNavmb15lxLnpUYzcRjA==","signatures":[{"sig":"MEUCIAgWKz6wox0Uwl3QHbKxEBVdz7pNRX9CDiWqALTinr4EAiEAyEMqq0LpUF0Bclh4WQrOVny97JyNV4Gh6/6jSUqMbl8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":4759256},"main":"./dist/aiden0z-pptx-renderer.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/aiden0z-pptx-renderer.es.js","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/aiden0z-pptx-renderer.es.js"},"require":{"types":"./dist/types/index.d.cts","default":"./dist/aiden0z-pptx-renderer.cjs"}}},"gitHead":"d1ba2caa2162b7d19c4537e1dde8af1f3e2a355e","scripts":{"dev":"vite","knip":"knip","lint":"eslint src/","size":"size-limit","test":"vitest run","build":"rm -rf dist && vite build && tsc --emitDeclarationOnly --declarationMap false --outDir dist/types && cp dist/types/index.d.ts dist/types/index.d.cts","format":"prettier --write 'src/**/*.ts'","dev:api":"cd test/e2e && .venv/bin/python server.py","dev:e2e":"bash ./scripts/dev-e2e.sh","prepare":"husky","preview":"vite preview","publint":"publint","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","build:demo":"vite build --config vite.config.demo.ts","test:watch":"vitest","format:check":"prettier --check 'src/**/*.ts'","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"aiden0xz","email":"aiden0xz@gmail.com"},"repository":{"url":"git+https://github.com/aiden0z/pptx-renderer.git","type":"git"},"size-limit":[{"gzip":true,"path":"dist/aiden0z-pptx-renderer.es.js","limit":"1400 kB"}],"_npmVersion":"11.12.1","description":"Parse and render PPTX files in the browser with a TypeScript-first engine.","directories":{},"lint-staged":{"src/**/*.ts":["eslint --fix","prettier --write"],"*.{json,md,html,css}":["prettier --write"]},"sideEffects":false,"_nodeVersion":"25.9.0","dependencies":{"jszip":"^3.10.1","echarts":"^6.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"knip":"^5.85.0","vite":"^6.0.0","husky":"^9.1.7","jsdom":"^26.0.0","pngjs":"^7.0.0","canvas":"^3.2.1","eslint":"^10.0.2","vitest":"^3.0.0","publint":"^0.3.17","prettier":"^3.8.1","@eslint/js":"^10.0.1","pixelmatch":"^7.1.0","size-limit":"^12.0.0","typescript":"^5.7.0","lint-staged":"^16.2.7","@commitlint/cli":"^20.4.2","@size-limit/file":"^12.0.0","typescript-eslint":"^8.56.1","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^10.1.8","@commitlint/config-conventional":"^20.4.2"},"peerDependencies":{"pdfjs-dist":"^5.0.0"},"peerDependenciesMeta":{"pdfjs-dist":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pptx-renderer_1.0.3_1779791965119_0.45419900732212515","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@aiden0z/pptx-renderer","version":"1.0.4","keywords":["pptx","powerpoint","renderer","ooxml","slides"],"license":"Apache-2.0","_id":"@aiden0z/pptx-renderer@1.0.4","maintainers":[{"name":"aiden0xz","email":"aiden0xz@gmail.com"}],"homepage":"https://github.com/aiden0z/pptx-renderer#readme","bugs":{"url":"https://github.com/aiden0z/pptx-renderer/issues"},"dist":{"shasum":"581553210e34ad4098bbdc2027391907a1830a67","tarball":"https://registry.npmjs.org/@aiden0z/pptx-renderer/-/pptx-renderer-1.0.4.tgz","fileCount":49,"integrity":"sha512-/52azUlq1C6ozq9nrpalyTXIYUxNQA3WYZiC9fPQyGzukCzfyTYSbJN4XmVZipguNYWm0eI+U5FiTQXnfzuOgw==","signatures":[{"sig":"MEQCIFl4nOrKyXIwDASUruhVtD3/JVLOqCPZgYoXe4vUl6mlAiBTXPsK7IE1fZ/mvLU1sOWYeD5ZAeQxwijZodVqcrIG9Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3676642},"main":"./dist/aiden0z-pptx-renderer.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/aiden0z-pptx-renderer.es.js","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/aiden0z-pptx-renderer.es.js"},"require":{"types":"./dist/types/index.d.cts","default":"./dist/aiden0z-pptx-renderer.cjs"}}},"gitHead":"6c76e847d1d889531342fb729d54f17f0c210a8f","scripts":{"dev":"vite","knip":"knip","lint":"eslint src/","size":"size-limit","test":"vitest run","build":"rm -rf dist && vite build && tsc --emitDeclarationOnly --declarationMap false --outDir dist/types && cp dist/types/index.d.ts dist/types/index.d.cts","format":"prettier --write 'src/**/*.ts'","dev:api":"cd test/e2e && .venv/bin/python server.py","dev:e2e":"bash ./scripts/dev-e2e.sh","prepare":"husky","preview":"vite preview","publint":"publint","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","build:demo":"vite build --config vite.config.demo.ts","test:watch":"vitest","format:check":"prettier --check 'src/**/*.ts'","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"aiden0xz","email":"aiden0xz@gmail.com"},"repository":{"url":"git+https://github.com/aiden0z/pptx-renderer.git","type":"git"},"size-limit":[{"gzip":true,"path":"dist/aiden0z-pptx-renderer.es.js","limit":"1400 kB"}],"_npmVersion":"11.12.1","description":"Parse and render PPTX files in the browser with a TypeScript-first engine.","directories":{},"lint-staged":{"src/**/*.ts":["eslint --fix","prettier --write"],"*.{json,md,html,css}":["prettier --write"]},"sideEffects":false,"_nodeVersion":"25.9.0","dependencies":{"jszip":"^3.10.1","echarts":"^6.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"knip":"^5.85.0","vite":"^6.0.0","husky":"^9.1.7","jsdom":"^26.0.0","pngjs":"^7.0.0","canvas":"^3.2.1","eslint":"^10.0.2","vitest":"^3.0.0","publint":"^0.3.17","prettier":"^3.8.1","@eslint/js":"^10.0.1","pixelmatch":"^7.1.0","size-limit":"^12.0.0","typescript":"^5.7.0","lint-staged":"^16.2.7","@commitlint/cli":"^20.4.2","@size-limit/file":"^12.0.0","typescript-eslint":"^8.56.1","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^10.1.8","@commitlint/config-conventional":"^20.4.2"},"peerDependencies":{"pdfjs-dist":"^5.0.0"},"peerDependenciesMeta":{"pdfjs-dist":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pptx-renderer_1.0.4_1780407645489_0.981607837114393","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@aiden0z/pptx-renderer","version":"1.1.0","keywords":["pptx","powerpoint","renderer","ooxml","slides"],"license":"Apache-2.0","_id":"@aiden0z/pptx-renderer@1.1.0","maintainers":[{"name":"aiden0xz","email":"aiden0xz@gmail.com"}],"homepage":"https://github.com/aiden0z/pptx-renderer#readme","bugs":{"url":"https://github.com/aiden0z/pptx-renderer/issues"},"dist":{"shasum":"a7f2ce1609c3db38eb6073d4c6d2f33fb8c746a8","tarball":"https://registry.npmjs.org/@aiden0z/pptx-renderer/-/pptx-renderer-1.1.0.tgz","fileCount":50,"integrity":"sha512-MSyCz1wSHXJJiL+6dtTsekNXT0bF6GoeoXDkGSxnzXMWSGVTdJlf3+nY2ysREQ2Tkv/5ihylPMFmNUWpk4GUHg==","signatures":[{"sig":"MEYCIQDW0eFJ+IMIKw+mU/4yzRJcv4SdSNsZvTlAFv7uEiaRVwIhAM32K/LzPrkwPf0lYVlg0NaoXvqWOY2dzrGV1YalhrtY","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3703328},"main":"./dist/aiden0z-pptx-renderer.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/aiden0z-pptx-renderer.es.js","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/aiden0z-pptx-renderer.es.js"},"require":{"types":"./dist/types/index.d.cts","default":"./dist/aiden0z-pptx-renderer.cjs"}}},"gitHead":"84d221bb3d193991550d034502a02240eeecd5d7","scripts":{"dev":"vite","knip":"knip","lint":"eslint src/","size":"size-limit","test":"vitest run","build":"rm -rf dist && vite build && tsc --emitDeclarationOnly --declarationMap false --outDir dist/types && cp dist/types/index.d.ts dist/types/index.d.cts","format":"prettier --write 'src/**/*.ts'","dev:api":"cd test/e2e && .venv/bin/python server.py","dev:e2e":"bash ./scripts/dev-e2e.sh","prepare":"husky","preview":"vite preview","publint":"publint","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","build:demo":"vite build --config vite.config.demo.ts","test:watch":"vitest","format:check":"prettier --check 'src/**/*.ts'","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"aiden0xz","email":"aiden0xz@gmail.com"},"repository":{"url":"git+https://github.com/aiden0z/pptx-renderer.git","type":"git"},"size-limit":[{"gzip":true,"path":"dist/aiden0z-pptx-renderer.es.js","limit":"1400 kB"}],"_npmVersion":"11.12.1","description":"Parse and render PPTX files in the browser with a TypeScript-first engine.","directories":{},"lint-staged":{"src/**/*.ts":["eslint --fix","prettier --write"],"*.{json,md,html,css}":["prettier --write"]},"sideEffects":false,"_nodeVersion":"25.9.0","dependencies":{"jszip":"^3.10.1","echarts":"^6.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"knip":"^5.85.0","vite":"^6.0.0","husky":"^9.1.7","jsdom":"^26.0.0","pngjs":"^7.0.0","canvas":"^3.2.1","eslint":"^10.0.2","vitest":"^3.0.0","publint":"^0.3.17","prettier":"^3.8.1","@eslint/js":"^10.0.1","pixelmatch":"^7.1.0","size-limit":"^12.0.0","typescript":"^5.7.0","lint-staged":"^16.2.7","@commitlint/cli":"^20.4.2","@size-limit/file":"^12.0.0","typescript-eslint":"^8.56.1","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^10.1.8","@commitlint/config-conventional":"^20.4.2"},"peerDependencies":{"pdfjs-dist":"^5.0.0"},"peerDependenciesMeta":{"pdfjs-dist":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pptx-renderer_1.1.0_1780650608338_0.03480043977889591","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@aiden0z/pptx-renderer","version":"1.2.0","keywords":["pptx","powerpoint","renderer","ooxml","slides"],"license":"Apache-2.0","_id":"@aiden0z/pptx-renderer@1.2.0","maintainers":[{"name":"aiden0xz","email":"aiden0xz@gmail.com"}],"homepage":"https://github.com/aiden0z/pptx-renderer#readme","bugs":{"url":"https://github.com/aiden0z/pptx-renderer/issues"},"dist":{"shasum":"165478303ff19a2b02da379f16e603dd7ff30a83","tarball":"https://registry.npmjs.org/@aiden0z/pptx-renderer/-/pptx-renderer-1.2.0.tgz","fileCount":68,"integrity":"sha512-G2NrcnXkJv9mfXDhzEXjaDVoX89Jb408Dioj0MCL3DYZnhXmAphTdvUg2AYhOX+SVCx4yp0aiLB4dtFy1ypFmA==","signatures":[{"sig":"MEUCIQDWyajY5C4Qr8FH2Y0pFa6QAeJdVeChnLJVdoojhUXnwAIgPYzEfiZw9k0UULKk8OecjFHP6f9bh0J4JDG2PIxNnNE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3812963},"main":"./dist/aiden0z-pptx-renderer.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/aiden0z-pptx-renderer.es.js","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/aiden0z-pptx-renderer.es.js"},"require":{"types":"./dist/types/index.d.cts","default":"./dist/aiden0z-pptx-renderer.cjs"}}},"gitHead":"96991f1528fc5625015aeba51528950971eb6a86","scripts":{"dev":"vite","knip":"knip","lint":"eslint src/","size":"size-limit","test":"vitest run","build":"rm -rf dist && vite build && tsc --emitDeclarationOnly --declarationMap false --outDir dist/types && cp dist/types/index.d.ts dist/types/index.d.cts","format":"prettier --write 'src/**/*.ts'","dev:api":"cd test/e2e && .venv/bin/python server.py","dev:e2e":"bash ./scripts/dev-e2e.sh","prepare":"husky","preview":"vite preview","publint":"publint","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","build:demo":"vite build --config vite.config.demo.ts","test:watch":"vitest","format:check":"prettier --check 'src/**/*.ts'","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"aiden0xz","email":"aiden0xz@gmail.com"},"repository":{"url":"git+https://github.com/aiden0z/pptx-renderer.git","type":"git"},"size-limit":[{"gzip":true,"path":"dist/aiden0z-pptx-renderer.es.js","limit":"1400 kB"}],"_npmVersion":"11.12.1","description":"Parse and render PPTX files in the browser with a TypeScript-first engine.","directories":{},"lint-staged":{"src/**/*.ts":["eslint --fix","prettier --write"],"*.{json,md,html,css}":["prettier --write"]},"sideEffects":false,"_nodeVersion":"25.9.0","dependencies":{"jszip":"^3.10.1","echarts":"^6.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"knip":"^5.85.0","vite":"^6.0.0","husky":"^9.1.7","jsdom":"^26.0.0","pngjs":"^7.0.0","canvas":"^3.2.1","eslint":"^10.0.2","vitest":"^3.0.0","publint":"^0.3.17","prettier":"^3.8.1","@eslint/js":"^10.0.1","pixelmatch":"^7.1.0","size-limit":"^12.0.0","typescript":"^5.7.0","lint-staged":"^16.2.7","@commitlint/cli":"^20.4.2","@size-limit/file":"^12.0.0","typescript-eslint":"^8.56.1","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^10.1.8","@commitlint/config-conventional":"^20.4.2"},"peerDependencies":{"pdfjs-dist":"^5.0.0"},"peerDependenciesMeta":{"pdfjs-dist":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pptx-renderer_1.2.0_1781608416533_0.26211461330589225","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@aiden0z/pptx-renderer","version":"1.2.1","keywords":["pptx","powerpoint","renderer","ooxml","slides"],"license":"Apache-2.0","_id":"@aiden0z/pptx-renderer@1.2.1","maintainers":[{"name":"aiden0xz","email":"aiden0xz@gmail.com"}],"homepage":"https://github.com/aiden0z/pptx-renderer#readme","bugs":{"url":"https://github.com/aiden0z/pptx-renderer/issues"},"dist":{"shasum":"1c673d4fd68455201619f238639121208b134c77","tarball":"https://registry.npmjs.org/@aiden0z/pptx-renderer/-/pptx-renderer-1.2.1.tgz","fileCount":68,"integrity":"sha512-cvIaoPguJ07NnFMbndgpJs6eckbLoRnom3hAx+d4V50UDk/p+21SS0jY+DzgtzPMeswBn7X7vmO1HZTpjjDEXQ==","signatures":[{"sig":"MEQCICGwrpG4MRAchPnTeaXfpZUPuTi+NIhuov61KYq30vTbAiBXn/+DTnzoeOV983rLRVFqShoWq2QcsIBYzuSSYuhbUA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3823883},"main":"./dist/aiden0z-pptx-renderer.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/aiden0z-pptx-renderer.es.js","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/aiden0z-pptx-renderer.es.js"},"require":{"types":"./dist/types/index.d.cts","default":"./dist/aiden0z-pptx-renderer.cjs"}}},"gitHead":"0b6fb05c38688fb76a3762ed1522bf4d5f489c2e","scripts":{"dev":"vite","knip":"knip","lint":"eslint src/","size":"size-limit","test":"vitest run","build":"rm -rf dist && vite build && tsc --emitDeclarationOnly --declarationMap false --outDir dist/types && cp dist/types/index.d.ts dist/types/index.d.cts","format":"prettier --write 'src/**/*.ts'","dev:api":"cd test/e2e && .venv/bin/python server.py","dev:e2e":"bash ./scripts/dev-e2e.sh","prepare":"husky","preview":"vite preview","publint":"publint","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","build:demo":"vite build --config vite.config.demo.ts","test:watch":"vitest","format:check":"prettier --check 'src/**/*.ts'","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"aiden0xz","email":"aiden0xz@gmail.com"},"repository":{"url":"git+https://github.com/aiden0z/pptx-renderer.git","type":"git"},"size-limit":[{"gzip":true,"path":"dist/aiden0z-pptx-renderer.es.js","limit":"1400 kB"}],"_npmVersion":"11.12.1","description":"Parse and render PPTX files in the browser with a TypeScript-first engine.","directories":{},"lint-staged":{"src/**/*.ts":["eslint --fix","prettier --write"],"*.{json,md,html,css}":["prettier --write"]},"sideEffects":false,"_nodeVersion":"25.9.0","dependencies":{"jszip":"^3.10.1","echarts":"^6.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"knip":"^5.85.0","vite":"^6.0.0","husky":"^9.1.7","jsdom":"^26.0.0","pngjs":"^7.0.0","canvas":"^3.2.1","eslint":"^10.0.2","vitest":"^3.0.0","publint":"^0.3.17","prettier":"^3.8.1","@eslint/js":"^10.0.1","pixelmatch":"^7.1.0","size-limit":"^12.0.0","typescript":"^5.7.0","lint-staged":"^16.2.7","@commitlint/cli":"^20.4.2","@size-limit/file":"^12.0.0","typescript-eslint":"^8.56.1","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^10.1.8","@commitlint/config-conventional":"^20.4.2"},"peerDependencies":{"pdfjs-dist":"^5.0.0"},"peerDependenciesMeta":{"pdfjs-dist":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pptx-renderer_1.2.1_1782349100411_0.35542450417532256","host":"s3://npm-registry-packages-npm-production"}},"1.2.2":{"name":"@aiden0z/pptx-renderer","version":"1.2.2","keywords":["pptx","powerpoint","renderer","ooxml","slides"],"license":"Apache-2.0","_id":"@aiden0z/pptx-renderer@1.2.2","maintainers":[{"name":"aiden0xz","email":"aiden0xz@gmail.com"}],"homepage":"https://github.com/aiden0z/pptx-renderer#readme","bugs":{"url":"https://github.com/aiden0z/pptx-renderer/issues"},"dist":{"shasum":"64a2736ee0ad99ddb05a9b557a3089eaf09c853a","tarball":"https://registry.npmjs.org/@aiden0z/pptx-renderer/-/pptx-renderer-1.2.2.tgz","fileCount":68,"integrity":"sha512-UKiV0JGz34OXZfE4UfKNkSx8flSAh9b3Lc2qFZlbwJ7UdQdz55pSz7MqWsx5CLU+BpFfzNlo5CN4ZSoSRWM6lw==","signatures":[{"sig":"MEYCIQD8Tl23MigHWOn6Xclfq8BF5a8cy+AHN8fot7wU42peVwIhAJYUrW5cbOlLY3t4850jOAbsxLFimJztk5r2Y2tUiGKl","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3872846},"main":"./dist/aiden0z-pptx-renderer.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/aiden0z-pptx-renderer.es.js","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/aiden0z-pptx-renderer.es.js"},"require":{"types":"./dist/types/index.d.cts","default":"./dist/aiden0z-pptx-renderer.cjs"}}},"gitHead":"739cc3c96733425de9502a0c0442a863baa8f063","scripts":{"dev":"vite","knip":"knip","lint":"eslint src/","size":"size-limit","test":"vitest run","build":"rm -rf dist && vite build && tsc --emitDeclarationOnly --declarationMap false --outDir dist/types && cp dist/types/index.d.ts dist/types/index.d.cts","format":"prettier --write 'src/**/*.ts'","dev:api":"cd test/e2e && .venv/bin/python server.py","dev:e2e":"bash ./scripts/dev-e2e.sh","prepare":"husky","preview":"vite preview","publint":"publint","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","build:demo":"vite build --config vite.config.demo.ts","test:watch":"vitest","format:check":"prettier --check 'src/**/*.ts'","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"aiden0xz","email":"aiden0xz@gmail.com"},"repository":{"url":"git+https://github.com/aiden0z/pptx-renderer.git","type":"git"},"size-limit":[{"gzip":true,"path":"dist/aiden0z-pptx-renderer.es.js","limit":"1400 kB"}],"_npmVersion":"11.12.1","description":"Parse and render PPTX files in the browser with a TypeScript-first engine.","directories":{},"lint-staged":{"src/**/*.ts":["eslint --fix","prettier --write"],"*.{json,md,html,css}":["prettier --write"]},"sideEffects":false,"_nodeVersion":"25.9.0","dependencies":{"jszip":"^3.10.1","echarts":"^6.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"knip":"^5.85.0","vite":"^6.0.0","husky":"^9.1.7","jsdom":"^26.0.0","pngjs":"^7.0.0","canvas":"^3.2.1","eslint":"^10.0.2","vitest":"^3.0.0","publint":"^0.3.17","prettier":"^3.8.1","@eslint/js":"^10.0.1","pixelmatch":"^7.1.0","size-limit":"^12.0.0","typescript":"^5.7.0","lint-staged":"^16.2.7","@commitlint/cli":"^20.4.2","@size-limit/file":"^12.0.0","typescript-eslint":"^8.56.1","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^10.1.8","@commitlint/config-conventional":"^20.4.2"},"peerDependencies":{"pdfjs-dist":"^5.0.0"},"peerDependenciesMeta":{"pdfjs-dist":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pptx-renderer_1.2.2_1782646983409_0.722761433774104","host":"s3://npm-registry-packages-npm-production"}},"1.2.3":{"name":"@aiden0z/pptx-renderer","version":"1.2.3","keywords":["pptx","powerpoint","renderer","ooxml","slides"],"license":"Apache-2.0","_id":"@aiden0z/pptx-renderer@1.2.3","maintainers":[{"name":"aiden0xz","email":"aiden0xz@gmail.com"}],"homepage":"https://github.com/aiden0z/pptx-renderer#readme","bugs":{"url":"https://github.com/aiden0z/pptx-renderer/issues"},"dist":{"shasum":"7c2bb301e1d100ffeeab540ff3ebd175744362d0","tarball":"https://registry.npmjs.org/@aiden0z/pptx-renderer/-/pptx-renderer-1.2.3.tgz","fileCount":68,"integrity":"sha512-ACA9b8Dh2XInUZjWpdsD2IB9ObPrTou0TzFe9wrLgOiNPHUzPNNxME7okE09XrV6rJ40MI2B3a1YVVlCz4/awA==","signatures":[{"sig":"MEQCIFQLVQNDd/EeCtNHFiv2oXmknIoYKpCLYQDgqatTfXs/AiAvDqB1tA70NyL4NToPuRYxFaltUgkwDUNIGmwO51Er0w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3886843},"main":"./dist/aiden0z-pptx-renderer.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/aiden0z-pptx-renderer.es.js","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/aiden0z-pptx-renderer.es.js"},"require":{"types":"./dist/types/index.d.cts","default":"./dist/aiden0z-pptx-renderer.cjs"}}},"gitHead":"0e78127203dc7756eee5677663a2ffa8ff1a5b29","scripts":{"dev":"vite","knip":"knip","lint":"eslint src/","size":"size-limit","test":"vitest run","build":"rm -rf dist && vite build && tsc --emitDeclarationOnly --declarationMap false --outDir dist/types && cp dist/types/index.d.ts dist/types/index.d.cts","format":"prettier --write 'src/**/*.ts'","dev:api":"cd test/e2e && .venv/bin/python server.py","dev:e2e":"bash ./scripts/dev-e2e.sh","prepare":"husky","preview":"vite preview","publint":"publint","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","build:demo":"vite build --config vite.config.demo.ts","test:watch":"vitest","format:check":"prettier --check 'src/**/*.ts'","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"aiden0xz","email":"aiden0xz@gmail.com"},"repository":{"url":"git+https://github.com/aiden0z/pptx-renderer.git","type":"git"},"size-limit":[{"gzip":true,"path":"dist/aiden0z-pptx-renderer.es.js","limit":"1400 kB"}],"_npmVersion":"11.12.1","description":"Parse and render PPTX files in the browser with a TypeScript-first engine.","directories":{},"lint-staged":{"src/**/*.ts":["eslint --fix","prettier --write"],"*.{json,md,html,css}":["prettier --write"]},"sideEffects":false,"_nodeVersion":"25.9.0","dependencies":{"jszip":"^3.10.1","echarts":"^6.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"knip":"^5.85.0","vite":"^6.0.0","husky":"^9.1.7","jsdom":"^26.0.0","pngjs":"^7.0.0","canvas":"^3.2.1","eslint":"^10.0.2","vitest":"^3.0.0","publint":"^0.3.17","prettier":"^3.8.1","@eslint/js":"^10.0.1","pixelmatch":"^7.1.0","size-limit":"^12.0.0","typescript":"^5.7.0","lint-staged":"^16.2.7","@commitlint/cli":"^20.4.2","@size-limit/file":"^12.0.0","typescript-eslint":"^8.56.1","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^10.1.8","@commitlint/config-conventional":"^20.4.2"},"peerDependencies":{"pdfjs-dist":"^5.0.0"},"peerDependenciesMeta":{"pdfjs-dist":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pptx-renderer_1.2.3_1782915451264_0.9604850611666018","host":"s3://npm-registry-packages-npm-production"}},"1.2.4":{"name":"@aiden0z/pptx-renderer","version":"1.2.4","keywords":["pptx","powerpoint","renderer","ooxml","slides"],"license":"Apache-2.0","_id":"@aiden0z/pptx-renderer@1.2.4","maintainers":[{"name":"aiden0xz","email":"aiden0xz@gmail.com"}],"homepage":"https://github.com/aiden0z/pptx-renderer#readme","bugs":{"url":"https://github.com/aiden0z/pptx-renderer/issues"},"dist":{"shasum":"f5f1fcd260ab5107aa8c1fd6f9567656856af0f0","tarball":"https://registry.npmjs.org/@aiden0z/pptx-renderer/-/pptx-renderer-1.2.4.tgz","fileCount":72,"integrity":"sha512-/4X/BApiknc/JM4nAWQRp5zrnA2GKSMv5r1u3XLsMvySw9DTQjyXIKRtltRsmIYfoN32tHGFnrSlGok7nFS60w==","signatures":[{"sig":"MEUCIQCDCU8PNL0jt/zbWD+pSWhktvKJRrJL04ZTrRdaVd9B9gIgVj8cWO7bO2SMwfHm3987DUz+za7ZpX0FGFbbk2GyH20=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2620215},"main":"./dist/aiden0z-pptx-renderer.cjs","type":"module","types":"./dist/types/index.d.ts","module":"./dist/aiden0z-pptx-renderer.es.js","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/aiden0z-pptx-renderer.es.js"},"require":{"types":"./dist/types/index.d.cts","default":"./dist/aiden0z-pptx-renderer.cjs"}},"./browser":{"types":"./dist/types/index.d.ts","import":"./dist/aiden0z-pptx-renderer.browser.es.js","default":"./dist/aiden0z-pptx-renderer.browser.es.js"}},"gitHead":"b28ab6326ba058138b662714be15335e5ca1f1a8","scripts":{"dev":"vite","knip":"knip","lint":"eslint src/","size":"size-limit","test":"vitest run","build":"node scripts/build.mjs","format":"prettier --write 'src/**/*.ts'","dev:api":"cd test/e2e && .venv/bin/python server.py","dev:e2e":"bash ./scripts/dev-e2e.sh","prepare":"husky","preview":"vite preview","publint":"publint","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","build:demo":"vite build --config vite.config.demo.ts","test:watch":"vitest","format:check":"prettier --check 'src/**/*.ts'","test:browser":"playwright test --config test/browser/playwright.config.ts","test:package":"node scripts/verify-package.mjs","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build","test:pdfjs-contract":"node scripts/verify-pdfjs-contract.mjs"},"_npmUser":{"name":"aiden0xz","email":"aiden0xz@gmail.com"},"repository":{"url":"git+https://github.com/aiden0z/pptx-renderer.git","type":"git"},"size-limit":[{"gzip":true,"path":"dist/aiden0z-pptx-renderer.es.js","limit":"1400 kB"},{"gzip":true,"path":"dist/aiden0z-pptx-renderer.browser.es.js","limit":"500 kB"}],"_npmVersion":"11.12.1","description":"Parse and render PPTX files in the browser with a TypeScript-first engine.","directories":{},"lint-staged":{"src/**/*.ts":["eslint --fix","prettier --write"],"*.{json,md,html,css}":["prettier --write"]},"sideEffects":["./src/renderer/chart/echartsRuntime.ts","./dist/aiden0z-pptx-renderer.es.js","./dist/aiden0z-pptx-renderer.cjs","./dist/aiden0z-pptx-renderer.browser.es.js"],"_nodeVersion":"25.9.0","dependencies":{"jszip":"^3.10.1","echarts":"^6.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@9.15.9","devDependencies":{"knip":"^5.85.0","vite":"^6.0.0","husky":"^9.1.7","jsdom":"^26.0.0","pngjs":"^7.0.0","canvas":"^3.2.1","eslint":"^10.0.2","vitest":"^3.0.0","publint":"^0.3.17","prettier":"^3.8.1","@eslint/js":"^10.0.1","pdfjs-dist":"^5.4.624","pixelmatch":"^7.1.0","size-limit":"^12.0.0","typescript":"^5.7.0","lint-staged":"^16.2.7","@commitlint/cli":"^20.4.2","@playwright/test":"^1.61.1","@size-limit/file":"^12.0.0","typescript-eslint":"^8.56.1","@vitest/coverage-v8":"^3.2.4","eslint-config-prettier":"^10.1.8","@commitlint/config-conventional":"^20.4.2"},"peerDependencies":{"pdfjs-dist":">=5 <7"},"peerDependenciesMeta":{"pdfjs-dist":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pptx-renderer_1.2.4_1783661665099_0.5942812474963335","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@aiden0z/pptx-renderer","version":"1.3.0","packageManager":"pnpm@9.15.9","description":"Parse and render PPTX files in the browser with a TypeScript-first engine.","license":"Apache-2.0","homepage":"https://github.com/aiden0z/pptx-renderer#readme","repository":{"type":"git","url":"git+https://github.com/aiden0z/pptx-renderer.git"},"bugs":{"url":"https://github.com/aiden0z/pptx-renderer/issues"},"keywords":["pptx","powerpoint","renderer","ooxml","slides"],"type":"module","main":"./dist/aiden0z-pptx-renderer.cjs","module":"./dist/aiden0z-pptx-renderer.es.js","types":"./dist/types/index.d.ts","exports":{".":{"import":{"types":"./dist/types/index.d.ts","default":"./dist/aiden0z-pptx-renderer.es.js"},"require":{"types":"./dist/types/index.d.cts","default":"./dist/aiden0z-pptx-renderer.cjs"}},"./browser":{"types":"./dist/types/index.d.ts","import":"./dist/aiden0z-pptx-renderer.browser.es.js","default":"./dist/aiden0z-pptx-renderer.browser.es.js"}},"sideEffects":["./src/renderer/chart/echartsRuntime.ts","./dist/aiden0z-pptx-renderer.es.js","./dist/aiden0z-pptx-renderer.cjs","./dist/aiden0z-pptx-renderer.browser.es.js"],"publishConfig":{"access":"public"},"scripts":{"dev":"vite","dev:api":"cd test/e2e && .venv/bin/python server.py","dev:e2e":"bash ./scripts/dev-e2e.sh","build":"node scripts/build.mjs","build:demo":"vite build --config vite.config.demo.ts","preview":"vite preview","test":"vitest run","test:package":"node scripts/verify-package.mjs","test:browser":"playwright test --config test/browser/playwright.config.ts","test:pdfjs-contract":"node scripts/verify-pdfjs-contract.mjs","test:coverage":"vitest run --coverage","test:watch":"vitest","geometry:generate":"node scripts/ooxml-geometry/generate.mjs","geometry:check":"node scripts/ooxml-geometry/generate.mjs --check","capability:check":"node scripts/run-python.mjs test/e2e/scripts/run_capability_loop.py validate","capability:inventory":"node scripts/run-python.mjs test/e2e/scripts/run_capability_loop.py inventory","verify:plan":"node scripts/run-python.mjs test/e2e/scripts/verify_affected.py","verify:affected":"node scripts/run-python.mjs test/e2e/scripts/verify_affected.py --run-fast","lint":"eslint src/","lint:fix":"eslint src/ --fix","format":"prettier --write 'src/**/*.ts'","format:check":"prettier --check 'src/**/*.ts'","typecheck":"tsc --noEmit","publint":"publint","knip":"knip","size":"size-limit","prepublishOnly":"npm run build","prepare":"husky"},"size-limit":[{"path":"dist/aiden0z-pptx-renderer.es.js","limit":"1400 kB","gzip":true},{"path":"dist/aiden0z-pptx-renderer.browser.es.js","limit":"500 kB","gzip":true}],"lint-staged":{"src/**/*.ts":["eslint --fix","prettier --write"],"*.{json,md,html,css}":["prettier --write"]},"dependencies":{"echarts":"^6.0.0","jszip":"^3.10.1","mtx-decompressor":"^1.4.2"},"peerDependencies":{"pdfjs-dist":">=5 <7"},"peerDependenciesMeta":{"pdfjs-dist":{"optional":true}},"devDependencies":{"@commitlint/cli":"^20.4.2","@commitlint/config-conventional":"^20.4.2","@eslint/js":"^10.0.1","@playwright/test":"^1.61.1","@size-limit/file":"^12.0.0","@vitest/coverage-v8":"^3.2.4","canvas":"^3.2.1","eslint":"^10.0.2","eslint-config-prettier":"^10.1.8","husky":"^9.1.7","jsdom":"^26.0.0","knip":"^5.85.0","lint-staged":"^16.2.7","pdfjs-dist":"^5.4.624","pixelmatch":"^7.1.0","pngjs":"^7.0.0","prettier":"^3.8.1","publint":"^0.3.17","size-limit":"^12.0.0","typescript":"^5.7.0","typescript-eslint":"^8.56.1","vite":"^6.0.0","vitest":"^3.0.0"},"gitHead":"0cf5c194b4db2cf9f2531b6a7e24a61338caabf1","_id":"@aiden0z/pptx-renderer@1.3.0","_nodeVersion":"25.9.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-VEXSn2vmdgTwWaw96bhsEyZiSxlrhF5O5dONI+dSBXmg1WH2XM9O1eyY2LFQ68J1SY+iZnE5BVgFGGX6iox9Og==","shasum":"e0c23493dec4f6c5d5d3d7d62ec5c90cee484809","tarball":"https://registry.npmjs.org/@aiden0z/pptx-renderer/-/pptx-renderer-1.3.0.tgz","fileCount":90,"unpackedSize":3534629,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCF7W+9fG6+ixRqrBdhh/DFltrPKLo+YEAMfN1P4/lYKAIgfDoj8uEZMCHv5rPXZJrOA3T6GeC5WR1r5+p+tydLD54="}]},"_npmUser":{"name":"aiden0xz","email":"aiden0xz@gmail.com"},"directories":{},"maintainers":[{"name":"aiden0xz","email":"aiden0xz@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pptx-renderer_1.3.0_1789354589296_0.1873821464598191"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-28T14:38:23.175Z","modified":"2026-09-14T02:56:29.650Z","1.0.0":"2026-02-28T14:38:23.552Z","1.0.1":"2026-03-01T11:20:25.910Z","1.0.2":"2026-03-09T07:39:55.867Z","1.0.3":"2026-05-26T10:39:25.367Z","1.0.4":"2026-06-02T13:40:45.750Z","1.1.0":"2026-06-05T09:10:08.584Z","1.2.0":"2026-06-16T11:13:36.766Z","1.2.1":"2026-06-25T00:58:20.671Z","1.2.2":"2026-06-28T11:43:03.568Z","1.2.3":"2026-07-01T14:17:31.455Z","1.2.4":"2026-07-10T05:34:25.258Z","1.3.0":"2026-09-14T02:56:29.462Z"},"bugs":{"url":"https://github.com/aiden0z/pptx-renderer/issues"},"license":"Apache-2.0","homepage":"https://github.com/aiden0z/pptx-renderer#readme","keywords":["pptx","powerpoint","renderer","ooxml","slides"],"repository":{"type":"git","url":"git+https://github.com/aiden0z/pptx-renderer.git"},"description":"Parse and render PPTX files in the browser with a TypeScript-first engine.","maintainers":[{"name":"aiden0xz","email":"aiden0xz@gmail.com"}],"readme":"# pptx-renderer\n\n[![CI](https://github.com/aiden0z/pptx-renderer/actions/workflows/ci.yml/badge.svg)](https://github.com/aiden0z/pptx-renderer/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/aiden0z/pptx-renderer/graph/badge.svg)](https://codecov.io/gh/aiden0z/pptx-renderer) [![npm](https://img.shields.io/npm/v/@aiden0z/pptx-renderer)](https://www.npmjs.com/package/@aiden0z/pptx-renderer) [![License](https://img.shields.io/github/license/aiden0z/pptx-renderer)](https://github.com/aiden0z/pptx-renderer/blob/main/LICENSE) [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/) [![Node](https://img.shields.io/badge/Node.js-≥20-339933?logo=node.js&logoColor=white)](https://nodejs.org/) [![Demo](https://img.shields.io/badge/Demo-GitHub%20Pages-brightgreen)](https://aiden0z.github.io/pptx-renderer/)\n\nA high-fidelity, browser-native PPTX renderer that parses Office Open XML (`.pptx`) files and renders slides as HTML/SVG DOM.\n\nSupports shapes, text, images, tables, charts, SmartArt, bounded OMML equations, groups, backgrounds, gradients, pattern fills, bounded ordinary-shape outer shadows and reflections, bounded static DrawingML 3D, and OOXML color inheritance. Rendering fidelity depends on the source features and available preview data; see the support boundaries below.\n\n## Rendering Example\n\nA complex slide with charts, text styles, shapes, and SmartArt — PowerPoint ground truth vs browser-rendered output:\n\n<table>\n<tr>\n<th>PowerPoint (Ground Truth)</th>\n<th>pptx-renderer (Browser)</th>\n</tr>\n<tr>\n<td><img src=\"docs/example/1-chart-and-complex/slides/Slide1.png\" alt=\"PowerPoint ground truth\" width=\"480\" /></td>\n<td><img src=\"docs/example/1-chart-and-complex/rendered-result.png\" alt=\"pptx-renderer output\" width=\"480\" /></td>\n</tr>\n</table>\n\n## Visual Regression Testing\n\nVisual regression suites compare selected shape, SmartArt, fill/stroke, text, table, and chart cases against PowerPoint output. Each API evaluation records the renderer revision, browser, optional font profile, and SHA-256 fingerprints of its PPTX and ground truth so results can be compared against the same inputs. Eligible single-chart Cartesian slides also expose plot-bound, data-ink, series-color, and region diagnostics so page whitespace cannot hide a missing or displaced series. A passing aggregate or local score does not establish semantic correctness or full PowerPoint parity; structural assertions and targeted browser/native inspection complement the metrics.\n\n<img src=\"docs/example/e2e-test-page.png\" alt=\"E2E evaluation dashboard\" width=\"800\" />\n\n<sup>E2E evaluation dashboard: side-by-side ground truth vs rendered output with SSIM, color histogram, and IoU metrics per slide.</sup>\n\n> Ground truth binaries (PPTX/PDF/PNG) stay in the ignored `test/e2e/testdata/` tree. Tracked case definitions and coverage metadata keep that local corpus reproducible. Generate shape/SmartArt corpora with `scripts/one_shot_full_ground_truth.py` or focused text/table/chart/composite cases with `scripts/generate_pypptx_cases.py`; both macOS and Windows PowerPoint are supported. See [`docs/TESTING.md`](docs/TESTING.md).\n\nOn macOS, native exports use one fixed ignored `oracle-runtime` directory and target the requested\npresentation by its exact full path. Keep the interactive PowerPoint session available and inspect\npending dialogs when automation fails. This lets local oracle runs coexist with other open\npresentations without treating the active window as the export target.\n\n## Install\n\n```bash\nnpm install @aiden0z/pptx-renderer\n# or\npnpm add @aiden0z/pptx-renderer\n\n# Optional: only needed for SmartArt / EMF files with embedded PDF fallback previews\npnpm add pdfjs-dist\n```\n\nRequires Node.js 20+ for development. Runtime is browser-only.\n\n## Quick Start\n\nFor bundlers and npm-based apps:\n\n```ts\nimport { PptxViewer, RECOMMENDED_ZIP_LIMITS } from '@aiden0z/pptx-renderer';\n\nconst container = document.getElementById('pptx-container')!;\nconst resp = await fetch('/slides/demo.pptx');\n\n// One-liner: parse, build model, and render\nconst viewer = await PptxViewer.open(await resp.arrayBuffer(), container, {\n  zipLimits: RECOMMENDED_ZIP_LIMITS,\n  listOptions: { windowed: true },\n});\n```\n\nFor direct browser usage without a bundler, import the standalone browser ESM build. This\nentry bundles JSZip and ECharts, and replaces Node-style `process.env` checks at build time.\nPDF.js remains optional and is only needed for EMF-embedded PDF fallback previews:\n\n```html\n<script type=\"module\">\n  import {\n    PptxViewer,\n    RECOMMENDED_ZIP_LIMITS,\n  } from '/vendor/pptx-renderer/aiden0z-pptx-renderer.browser.es.js';\n\n  const container = document.getElementById('pptx-container');\n  const resp = await fetch('/slides/demo.pptx');\n  await PptxViewer.open(await resp.arrayBuffer(), container, {\n    zipLimits: RECOMMENDED_ZIP_LIMITS,\n  });\n</script>\n```\n\nCopy the standalone artifact from the published package into your application's versioned\nstatic assets. The entry bundles JSZip and the ECharts chart types supported by this\nrenderer; PDF.js remains an optional external asset. A pinned CDN URL can also be used,\nbut the project does not depend on or deploy through a CDN provider.\n\nFor large decks, combine windowed mounting with on-demand slide parsing and media decoding:\n\n```ts\nconst viewer = await PptxViewer.open(buffer, container, {\n  zipLimits: RECOMMENDED_ZIP_LIMITS,\n  lazySlides: true,\n  lazyMedia: true,\n  listOptions: { windowed: true, initialSlides: 4, batchSize: 4 },\n});\n```\n\n### Optional PDF.js Fallback for SmartArt/EMF Preview Images\n\nPowerPoint often stores SmartArt or pasted vector artwork as EMF fallback images. This\nlibrary does **not** implement a full EMF/WMF vector renderer. It can render the common\nOffice fallback cases where an EMF contains an embedded PDF preview or bitmap preview.\n\nFor EMF files with embedded PDF previews, install `pdfjs-dist` and pass explicit asset\nURLs. This keeps PDF.js optional and avoids forcing every consumer bundle to include it.\nThis is only needed for EMF-PDF fallback previews; ordinary PPTX rendering does not\nrequire any code changes.\n\n```ts\nimport { PptxViewer } from '@aiden0z/pptx-renderer';\n\nconst pdfjs = {\n  moduleUrl: new URL('pdfjs-dist/build/pdf.min.mjs', import.meta.url).toString(),\n  workerUrl: new URL('pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url).toString(),\n};\n\nconst viewer = await PptxViewer.open(buffer, container, {\n  pdfjs,\n});\n```\n\nIf your app uses a CDN or pre-copied assets, point those fields at your hosted files.\nSet `pdfjs: false` to disable EMF-PDF fallback rendering entirely. With no `pdfjs`\nconfiguration, the renderer attempts only a best-effort automatic resolution and\notherwise degrades gracefully.\n\n```ts\ntype PdfjsConfig =\n  | {\n      moduleUrl?: string;\n      workerUrl?: string;\n    }\n  | false;\n```\n\nFor a no-bundler deployment, copy the two PDF.js files into your application's static\nassets and pass absolute self-hosted URLs:\n\n```ts\nconst pdfjs = {\n  moduleUrl: '/vendor/pdfjs/pdf.min.mjs',\n  workerUrl: '/vendor/pdfjs/pdf.worker.min.mjs',\n};\n```\n\nThe PDF fallback uses short-lived blob Workers. A restrictive Content Security Policy\nmust allow the chosen asset origin and `blob:` Workers, for example:\n\n```text\nscript-src 'self';\nworker-src 'self' blob:;\nimg-src 'self' data: blob:;\n```\n\nIf a CDN is used instead, pin exact package versions and add only that origin to the\nrelevant CSP directives.\n\nOr with more control over each step:\n\n```ts\nimport {\n  PptxViewer,\n  parseZip,\n  buildPresentation,\n  RECOMMENDED_ZIP_LIMITS,\n} from '@aiden0z/pptx-renderer';\n\nconst container = document.getElementById('pptx-container')!;\nconst viewer = new PptxViewer(container, { fitMode: 'contain' });\n\nconst files = await parseZip(arrayBuffer, RECOMMENDED_ZIP_LIMITS);\nconst presentation = buildPresentation(files);\nviewer.load(presentation);\nawait viewer.renderList({ windowed: true, batchSize: 8 });\n```\n\nTo delay both media decompression and slide node parsing until rendered slides actually need\nthem, use `parseZipLazyMedia()` and pass `{ lazySlides: true }` to `buildPresentation()`:\n\n```ts\nimport {\n  PptxViewer,\n  parseZipLazyMedia,\n  buildPresentation,\n  RECOMMENDED_ZIP_LIMITS,\n} from '@aiden0z/pptx-renderer';\n\nconst files = await parseZipLazyMedia(arrayBuffer, RECOMMENDED_ZIP_LIMITS);\nconst presentation = buildPresentation(files, { lazySlides: true });\n\nconst viewer = new PptxViewer(container);\nviewer.load(presentation);\nawait viewer.renderList({ windowed: true, initialSlides: 4 });\n```\n\n## API\n\n### `PptxViewer` (primary, extends `EventTarget`)\n\n#### `PptxViewer.open(input, container, options?)` — Static Factory\n\nParse, build, and render in one call. Returns a `Promise<PptxViewer>`.\n\n```ts\nconst viewer = await PptxViewer.open(buffer, container, {\n  renderMode: 'list', // 'list' (default) | 'slide'\n  zipLimits: RECOMMENDED_ZIP_LIMITS,\n  listOptions: { windowed: true, batchSize: 8 },\n  signal: abortController.signal, // optional AbortSignal\n  // ...ViewerOptions\n});\n```\n\n#### `new PptxViewer(container, options?)`\n\n| Option               | Type                        | Default       | Description                                                                                                       |\n| -------------------- | --------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------- |\n| `width`              | `number`                    | --            | Container width hint (omit for auto-detect)                                                                       |\n| `fitMode`            | `'contain' \\| 'none'`       | `'contain'`   | Responsive fit or fixed size                                                                                      |\n| `zoomPercent`        | `number`                    | `100`         | Zoom level (10–400)                                                                                               |\n| `scrollContainer`    | `HTMLElement`               | --            | Scroll container for IntersectionObserver root                                                                    |\n| `zipLimits`          | `ZipParseLimits`            | --            | Security limits for ZIP parsing (used by `.open()`). Use `RECOMMENDED_ZIP_LIMITS` for untrusted input.            |\n| `lazyMedia`          | `boolean`                   | `false`       | Decode embedded media on demand instead of during ZIP parsing. Best for large decks with windowed list rendering. |\n| `lazySlides`         | `boolean`                   | `false`       | Parse slide shape/table/chart nodes on demand. Best for large decks with windowed list rendering.                 |\n| `pdfjs`              | `PdfjsConfig`               | --            | Optional PDF.js URLs for EMF-embedded PDF fallback rendering, or `false` to disable it.                           |\n| `embeddedFontLimits` | `EmbeddedFontLimits`        | safe defaults | Optional embedded-font resource limit overrides. Omitted fields retain the built-in defaults.                     |\n| `fontFaces`          | `readonly FontFaceConfig[]` | --            | Host-provided font faces for typefaces referenced by the PPTX but not embedded in it.                             |\n| `onSlideChange`      | `(index) => void`           | --            | Shorthand for `slidechange` event                                                                                 |\n| `onSlideRendered`    | `(index, element) => void`  | --            | Shorthand for `sliderendered` event                                                                               |\n| `onSlideError`       | `(index, error) => void`    | --            | Shorthand for `slideerror` event                                                                                  |\n| `onSlideUnmounted`   | `(index) => void`           | --            | Shorthand for `slideunmounted` event                                                                              |\n| `onNodeError`        | `(nodeId, error) => void`   | --            | Shorthand for `nodeerror` event                                                                                   |\n| `onRenderStart`      | `() => void`                | --            | Shorthand for `renderstart` event                                                                                 |\n| `onRenderComplete`   | `() => void`                | --            | Shorthand for `rendercomplete` event                                                                              |\n\nAll shorthand callbacks are also available as `EventTarget` events (e.g. `viewer.addEventListener('slidechange', ...)`).\n\nEmbedded font decompression is bounded by default. Trusted applications can provide partial\n`embeddedFontLimits` overrides; see the [performance guide](docs/PERFORMANCE.md#embedded-font-limits)\nfor defaults, examples, and the soft processing-time boundary.\n\nFor decks that reference fonts unavailable in the browser, provide regular/bold faces before\nlayout through `fontFaces`. Sources follow the browser `FontFace` API and can be font bytes or a\nCSS `url(...)` source (subject to the host page's CSP and CORS policy):\n\n```ts\nconst [regular, bold] = await Promise.all([\n  fetch('/fonts/brand-sans-regular.woff2').then((response) => response.arrayBuffer()),\n  fetch('/fonts/brand-sans-bold.woff2').then((response) => response.arrayBuffer()),\n]);\n\nconst viewer = new PptxViewer(container, {\n  fontFaces: [\n    { family: 'Brand Sans', source: regular, descriptors: { weight: '400' } },\n    { family: 'Brand Sans', source: bold, descriptors: { weight: '700' } },\n  ],\n});\n```\n\n#### Instance Methods\n\n```ts\nviewer.load(presentation);                              // Load a PresentationData model (no render)\nawait viewer.renderList({ windowed: true });             // Render all slides in scrollable list\nawait viewer.renderSlide(0);                             // Render a single slide (no built-in nav UI)\n\n// Load from binary input (parse → build → render). Cleans up previous state on re-open.\nawait viewer.open(buffer, { renderMode: 'list', signal: abortController.signal });\n\nawait viewer.goToSlide(index);                           // Jump to slide (0-based), returns Promise<void>\nawait viewer.goToSlide(index, { behavior: 'instant' }); // Custom ScrollIntoViewOptions (list mode)\nawait viewer.setZoom(150);                               // Runtime zoom (10–400)\nawait viewer.setFitMode('none');                         // Switch fit mode\nconst matches = viewer.searchText('GPU');                 // Search parsed model text\nconst hit = await viewer.highlightSearchResult(matches[0]); // Default node overlay highlight\nhit?.dispose();\nviewer.clearSearchHighlights();                          // Remove active search overlays\n\n// Render a single slide into an external container (React/Vue integration, thumbnails).\n// Returns a SlideHandle; caller owns it and must call handle.dispose() when done.\nconst handle = viewer.renderSlideToContainer(index, container, scale?);\nhandle.dispose();                                        // Clean up slide-specific resources\n\n// Render a lightweight scaled slide preview into an external container.\n// This preserves the original slide layout and uses transform scaling; it is\n// not a bitmap thumbnail generator, so use lazy/windowed mounting for decks.\nconst thumb = viewer.renderThumbnailToContainer(index, sidebarItem, { width: 180 });\nawait thumb?.ready;\nthumb?.dispose();\n\n// Query which slides are currently mounted in the DOM\nviewer.isSlideMounted(index);   // boolean\nviewer.getMountedSlides();      // number[] (sorted)\n\n// Typed event helpers (return `this` for chaining)\nviewer.on('slidechange', (e) => console.log(e.detail.index));\nviewer.off('slidechange', listener);\n\nviewer.destroy();               // Cleanup blob URLs, observers, and DOM\nviewer[Symbol.dispose]();       // TC39 Explicit Resource Management (calls destroy)\n```\n\n#### Text Search\n\n`PptxViewer.searchText(query, options?)` searches the parsed `PresentationData` model,\nnot the rendered DOM. This keeps search available before or after a slide is mounted and\navoids mutating renderer-generated text runs.\n\nString queries are case-insensitive by default. Pass `matchCase: true` when you need\nexact casing. RegExp queries keep their own flags, so `/GPU/` remains case-sensitive\nand `/GPU/i` remains case-insensitive.\n\n```ts\nimport type { TextSearchResult } from '@aiden0z/pptx-renderer';\n\nconst matches: TextSearchResult[] = viewer.searchText('GPU', {\n  matchCase: false,\n  wholeWord: true,\n  snippetRadius: 48,\n});\n\nconst exactMatches = viewer.searchText('GPU', { matchCase: true });\nconst regexMatches = viewer.searchText(/GPU|CPU/i);\n\nfor (const match of matches) {\n  await viewer.goToSlide(match.slideIndex, { behavior: 'smooth', block: 'center' });\n  // Use match.bounds for node-level highlight overlays in your own UI.\n}\n```\n\nEach `TextSearchResult` includes `slideIndex`, `nodeId`, `nodePath`, `nodeType`,\n`textKind`, full `text`, `matchStart`, `matchEnd`, `snippet`, and `bounds`.\n`bounds` is the matched shape or table bounds in intrinsic slide coordinates, so\napplication code can draw node-level highlight overlays on top of a rendered slide.\n\nThe renderer intentionally does not rewrite text nodes for character-level text highlighting.\nCharacter-level text highlighting would require mapping match offsets back to shaped Office\ntext runs and line layout, which is a separate, higher-risk renderer feature. Today the\nstable API boundary is model-level search plus node-level bounds.\n\nFor the common UI case, `highlightSearchResult(result, options?)` draws a node-level\noverlay using a default highlight style. Pass `SearchHighlightOptions` for custom colors,\nspacing, shadows, and class names:\n\n```ts\nconst hit = await viewer.highlightSearchResult(matches[0], {\n  className: 'my-search-hit',\n  borderColor: '#22c55e',\n  backgroundColor: 'rgba(34, 197, 94, 0.18)',\n  borderRadius: 6,\n  borderWidth: 2,\n  boxShadow: '0 0 0 2px rgba(15, 23, 42, 0.35)',\n  padding: 3,\n});\n\n// The caller owns returned highlight handles.\nhit?.dispose();\nviewer.clearSearchHighlights();\n```\n\n#### Scaled Slide Previews\n\n`PptxViewer.renderThumbnailToContainer(index, container, options?)` renders a slide at\nits intrinsic layout size and applies CSS transform scaling inside a clipped wrapper.\nThis avoids the layout drift that can happen if a PPTX slide is rendered directly into a\nsmall thumbnail-sized container.\n\n```ts\nconst thumb = viewer.renderThumbnailToContainer(slideIndex, thumbnailEl, { width: 96 });\nawait thumb?.ready;\n\n// The caller owns externally rendered previews.\nthumb?.dispose();\n```\n\nThis is not a bitmap thumbnail generator: it still creates a scaled DOM/SVG slide\npreview, so large decks should mount previews lazily with `IntersectionObserver` or a\nwindowed list and dispose handles when they scroll out of view.\n\n#### `ListRenderOptions`\n\n| Option             | Type      | Default | Description                        |\n| ------------------ | --------- | ------- | ---------------------------------- |\n| `windowed`         | `boolean` | `false` | Use IntersectionObserver windowing |\n| `batchSize`        | `number`  | `12`    | Slides per render batch            |\n| `initialSlides`    | `number`  | `4`     | Initial slides to mount (windowed) |\n| `overscanViewport` | `number`  | `1.5`   | Viewport overscan multiplier       |\n\n#### `ZipParseLimits` and Resource Safety\n\n`parseZip(buffer)` defaults to no ZIP limits for backward compatibility. For files from users or other untrusted sources, pass `RECOMMENDED_ZIP_LIMITS` or stricter values:\n\n| Limit                       | Recommended value | What it protects                            |\n| --------------------------- | ----------------- | ------------------------------------------- |\n| `maxEntries`                | `4000`            | Archives with excessive file counts         |\n| `maxEntryUncompressedBytes` | `32 MiB`          | A single oversized XML/media entry          |\n| `maxTotalUncompressedBytes` | `256 MiB`         | Total decompressed archive size             |\n| `maxMediaBytes`             | `192 MiB`         | Total media payload size under `ppt/media/` |\n| `maxConcurrency`            | `8`               | Parallel ZIP entry reads                    |\n\nWhen ZIP metadata does not expose a reliable uncompressed size, the parser falls back to the actual decoded entry size before accepting the entry. This keeps `maxEntryUncompressedBytes`, `maxTotalUncompressedBytes`, and `maxMediaBytes` effective for XML/text entries and media entries alike.\n\nRenderer-level guards also apply after ZIP parsing:\n\n- Chart caches do not allocate from oversized `c:ptCount`; chart point indexes are capped at `10,000` per cache.\n- EMF bitmap previews are rejected when decoded size exceeds `16,777,216` pixels, dimensions exceed `8192x8192`, or pixel payload is shorter than the declared bitmap.\n- External audio/video relationships only render for safe `http`/`https` URLs with `TargetMode=\"External\"` and are created with `preload=\"none\"`.\n\n#### Events (`PptxViewerEventMap`)\n\n```ts\nviewer.addEventListener('renderstart', () => {\n  /* render cycle began */\n});\nviewer.addEventListener('rendercomplete', () => {\n  /* render cycle finished (fires even on error) */\n});\nviewer.addEventListener('slidechange', (e) => console.log(e.detail.index));\nviewer.addEventListener('sliderendered', (e) => console.log(e.detail.index, e.detail.element));\nviewer.addEventListener('slideerror', (e) => console.error(e.detail.index, e.detail.error));\nviewer.addEventListener('slideunmounted', (e) => console.log(e.detail.index));\nviewer.addEventListener('nodeerror', (e) => console.warn(e.detail.nodeId, e.detail.error));\n```\n\n`slidechange` fires both on `goToSlide()` navigation and after each render cycle (initial render included). `renderstart`/`rendercomplete` bracket every render cycle (renderList, renderSlide, setZoom, setFitMode). When calls overlap, the newer render request supersedes older queued or batched work, so stale list batches stop before appending more DOM.\n\n#### Instance Properties (read-only)\n\n```ts\nviewer.presentationData; // PresentationData | null — the parsed model, null before load()\nviewer.slideCount; // number — total slides (0 if not loaded)\nviewer.slideWidth; // number — intrinsic slide width in px\nviewer.slideHeight; // number — intrinsic slide height in px\nviewer.currentSlideIndex; // number — currently active slide (0-based)\nviewer.isRendering; // boolean — true between renderstart and rendercomplete\nviewer.zoomPercent; // number — current zoom level (e.g. 100, 200)\nviewer.fitMode; // FitMode — current fit mode ('contain' | 'none')\n```\n\n### `PptxRenderer` (deprecated v1 compat)\n\n`PptxRenderer` extends `PptxViewer` and provides the legacy `preview(input)` API with built-in nav buttons in slide mode. Migrate to `PptxViewer` for new code.\n\n```ts\nimport { PptxRenderer } from '@aiden0z/pptx-renderer';\n\nconst renderer = new PptxRenderer(container, { mode: 'list', listMountStrategy: 'windowed' });\nawait renderer.preview(buffer); // deprecated — use PptxViewer.open() instead\n```\n\n`PptxRenderer` accepts the same optional `lazyMedia`, `lazySlides`, and `pdfjs`\nconfiguration as `PptxViewer`, so legacy users can enable performance options or\nEMF-PDF fallback rendering without changing APIs.\n\n### Utility Exports\n\n```ts\nimport {\n  parseZip,\n  parseZipLazyMedia,\n  buildPresentation,\n  materializeAllSlideNodes,\n  serializePresentation,\n  buildTextIndex,\n  searchText,\n  searchPresentation,\n  RECOMMENDED_ZIP_LIMITS,\n} from '@aiden0z/pptx-renderer';\n\nconst files = await parseZip(arrayBuffer, RECOMMENDED_ZIP_LIMITS); // PptxFiles\nconst lazyFiles = await parseZipLazyMedia(arrayBuffer, RECOMMENDED_ZIP_LIMITS); // media resolves on demand\nconst presentation = buildPresentation(files); // PresentationData\nconst lazyPresentation = buildPresentation(lazyFiles, { lazySlides: true }); // slide nodes parse on demand\nmaterializeAllSlideNodes(lazyPresentation); // optional: force full model materialization\nconst json = serializePresentation(presentation); // SerializedPresentation (JSON-safe)\nconst index = buildTextIndex(presentation); // TextIndexEntry[]\nconst matches = searchText(index, '算力'); // TextSearchResult[]\nconst directMatches = searchPresentation(presentation, /GPU|CPU/i); // TextSearchResult[]\n```\n\n#### Headless Slide Rendering\n\nFor advanced use cases (server-side screenshot, custom rendering pipeline):\n\n```ts\nimport { renderSlide } from '@aiden0z/pptx-renderer';\nimport type { SlideHandle } from '@aiden0z/pptx-renderer';\n\nconst handle = renderSlide(presentation, presentation.slides[0], {\n  onNodeError: (nodeId, err) => console.warn(nodeId, err),\n  mediaUrlCache: new Map(), // optional shared cache for blob URLs\n  pdfjs, // optional, only for EMF-embedded PDF fallback rendering\n  fontFaces, // optional host-provided FontFaceConfig[]\n});\ndocument.body.appendChild(handle.element);\n\n// Await async media such as EMF-PDF fallback previews before screenshots/exports.\nawait handle.ready;\n\n// Cancels pending PDF fallbacks and disposes charts + owned blob URLs.\nhandle.dispose();\n```\n\n#### Model Types\n\nAll model types are exported for consumers building custom tooling:\n\n```ts\nimport type {\n  PresentationData,\n  BuildPresentationOptions,\n  SlideData,\n  SlideNode,\n  ThemeData,\n  BaseNodeData,\n  ShapeNodeData,\n  PicNodeData,\n  TableNodeData,\n  GroupNodeData,\n  ChartNodeData,\n  TextBody,\n  TextParagraph,\n  TextRun,\n  Position,\n  Size,\n  NodeType,\n  SerializedPresentation,\n  SerializedSlide,\n  SerializedNode,\n  PptxFiles,\n  ZipParseLimits,\n  FitMode,\n  PreviewInput,\n  ViewerOptions,\n  FontFaceConfig,\n  ListRenderOptions,\n  ThumbnailRenderOptions,\n  SearchHighlightHandle,\n  SearchHighlightOptions,\n  PptxViewerEventMap,\n  SlideHandle,\n  PdfjsOptions,\n  PdfjsConfig,\n  TextBounds,\n  TextIndexEntry,\n  TextIndexOptions,\n  TextSearchOptions,\n  TextSearchResult,\n} from '@aiden0z/pptx-renderer';\n```\n\n## Rendering Capabilities\n\n### Shapes and geometry\n\nThe renderer covers the commonly used DrawingML preset families and numeric custom geometry,\nincluding multi-path shapes, connectors, arrows, callouts, action buttons, and flowcharts.\nThe spec-compiled runtime currently contains 29 definitions: all 28 zero-adjustment flowcharts plus\n`donut`, whose OOXML default is `adj=25000` with a supported `0..50000` adjustment range. Other\npresets continue to use their handwritten implementations. Arbitrary symbolic guides in custom\ngeometry are not yet supported.\n\n### Text\n\nText rendering follows the master, layout, placeholder, shape, paragraph, and run cascade. It\nsupports theme fonts, CJK text, bullets, hyperlinks, vertical text, superscript/subscript, Office\npercentage spacing, common wrap/overflow combinations, and selected `spAutoFit` growth. Font\navailability remains part of visual-test provenance.\n\n### Tables\n\nThe common table path supports built-in and document table styles, first/last/banded options,\nvariable row and column sizes, horizontal and vertical merges, cell margins and anchors, CJK/mixed\ntext, conditional and merged borders, explicit border clearing, and direct cell overrides. The\nclaim is bounded by an eight-case native PowerPoint matrix; uncommon producer quirks, diagonal\nborders, and arbitrary style combinations may still differ.\n\n### Charts\n\n[ECharts](https://echarts.apache.org/) renders bar/column, line, area, pie, doughnut, radar, scatter,\nbubble, stock/candlestick, supported combo charts, and secondary axes. Sparse and literal sources,\nexplicit zeros, common labels, legends, markers, and number formats are supported. Chart rendering\nremains approximate because Office plot-area, axis, label, and legend layout can differ. OOXML 3D\ncharts fall back to a 2D representation where possible.\n\n### Equations\n\nA bounded OMML subset renders as browser-native Presentation MathML: runs, bar/no-bar/skewed/linear\nfractions, radicals, subscript/superscript, delimiters, n-ary operators, matrices, and functions.\nThe direct path is selected only when the complete math subtree is recognized; otherwise the\npackage-authored MCE fallback shape or graphic frame is used. Per-token rich formula styling and\nunknown OMML constructs remain outside the direct subset. No formula-specific runtime dependency is\nrequired.\n\n### Effects and static 3D\n\nOrdinary-shape outer shadows and reflections have native-validated lanes for the combinations in\nthe tracked effect matrices. Other effect combinations use the existing approximation or flat\nfallback.\n\nThe static DrawingML 3D path parses scene, camera, lighting, bevel, contour, and material properties.\nNative-validated rendering covers selected top-bevel silhouettes, zero-depth camera planes, cropped\npictures, live text, one custom-geometry family, one two-picture group, and selected edge-on bottom\nbevel material values. It uses SVG, Canvas, and projection math rather than a mesh engine. General\nextrusion, arbitrary cameras and lighting, arbitrary group scenes, 3D charts, and embedded Office 3D\nmodels are not supported.\n\n### SmartArt, media, groups, and compatible content\n\n- **SmartArt**: renders available diagram fallback data; layout fidelity varies.\n- **Images**: raster and SVG previews, crop and geometry clipping, common image effects, and browser-supported audio/video.\n- **OLE/EMF previews**: uses package-provided bitmap or embedded-PDF previews when available; PDF previews require optional `pdfjs-dist`.\n- **Groups**: recursively remaps child coordinates and preserves supported transforms.\n- **Compatible content**: selects one supported `mc:Choice`, otherwise its `mc:Fallback`, while preserving branch order.\n- **Backgrounds and color**: resolves slide/layout/master backgrounds, theme colors, color maps, and common modifiers.\n\n## Architecture\n\nThree-layer pipeline: **Parse -> Model -> Render**\n\n```\nArrayBuffer (.pptx)\n  -> ZipParser (jszip extraction)\n  -> XmlParser (DOMParser + SafeXmlNode null-safe wrapper)\n  -> buildPresentation() (assembles slides/layouts/masters/themes with relationship chains)\n  -> SlideRenderer (background -> master shapes -> layout shapes -> slide shapes -> DOM)\n```\n\nKey design decisions:\n\n- **SafeXmlNode**: Null-safe XML traversal — returns empty nodes instead of null, enabling deep chaining without null checks.\n- **Lazy slide parsing**: Optional `lazySlides` mode keeps per-slide nodes deferred until render, search, serialization, or explicit materialization.\n- **Lazy group parsing**: Group children stored as raw XML, parsed during rendering to avoid deep recursion in model layer.\n- **Error isolation**: Per-node try/catch. A failed shape renders as a dashed-red placeholder; the slide continues.\n- **No external CSS**: All styles inline. The library outputs self-contained HTML fragments.\n- **Blob URL lifecycle**: Created for images/media, tracked in `mediaUrlCache`, revoked on `destroy()`.\n\n## Performance\n\nThe default behavior stays eager for compatibility: parse the package, build the full\nmodel, and render according to the selected mode. For large or media-heavy decks, opt\ninto the lazy/windowed path so the first visible slides can render without materializing\nevery slide and every media entry up front.\n\nUse this preset for interactive viewers:\n\n```ts\nconst viewer = await PptxViewer.open(buffer, container, {\n  zipLimits: RECOMMENDED_ZIP_LIMITS,\n  lazySlides: true,\n  lazyMedia: true,\n  listOptions: {\n    windowed: true,\n    batchSize: 8,\n    initialSlides: 4,\n    overscanViewport: 1.5,\n  },\n});\n```\n\nRecommended choices:\n\n| Scenario                              | Recommended options                                     | Main benefit                                 |\n| ------------------------------------- | ------------------------------------------------------- | -------------------------------------------- |\n| User-uploaded PPTX                    | `zipLimits: RECOMMENDED_ZIP_LIMITS`                     | Bounds ZIP parsing work and decoded payloads |\n| Long scrollable viewer                | `listOptions.windowed: true`                            | Keeps off-screen slides out of the DOM       |\n| Large decks with many slide elements  | `lazySlides: true` plus windowed list rendering         | Defers per-slide node parsing until needed   |\n| Media-heavy decks                     | `lazyMedia: true` plus windowed list rendering          | Defers image/audio/video byte decoding       |\n| Export, print, or full comparison job | Eager defaults, or explicitly materialize before export | Ensures all slides are ready in one pass     |\n\nIn local benchmarks, `lazySlides` reduced model build time by roughly 52-66% on medium\nand large decks, and lowered first-window parse + build + render time by roughly 16-22%.\nFor media-heavy windowed viewers, `lazyMedia` reduced initially decompressed media bytes\nby about 72-97%, depending on deck content. These options preserve rendering semantics;\nthey mainly move work from initial load to the moment a slide or media item is actually\nneeded.\n\nManual pipelines can use the same building blocks:\n\n```ts\nconst files = await parseZipLazyMedia(buffer, RECOMMENDED_ZIP_LIMITS);\nconst presentation = buildPresentation(files, { lazySlides: true });\n\nconst viewer = new PptxViewer(container);\nviewer.load(presentation);\nawait viewer.renderList({ windowed: true, initialSlides: 4 });\n```\n\nDetails: [`docs/PERFORMANCE.md`](docs/PERFORMANCE.md)\n\n## Security\n\n- Treat PPTX input as untrusted. Start with `RECOMMENDED_ZIP_LIMITS`, then tighten for your deployment.\n- External hyperlinks are protocol-filtered (no `javascript:`, `data:`, etc.).\n- Reporting: [`docs/SECURITY.md`](docs/SECURITY.md)\n\n## Development\n\n```bash\npnpm install\npnpm dev          # Vite dev server\npnpm test         # Unit tests (vitest)\npnpm test:coverage # Coverage report → coverage/\npnpm build        # Production build\npnpm test:package # Verify package entries, packlist boundaries, and notice links\npnpm test:browser # Real Chromium checks for standalone, charts, and PDF.js\npnpm dev:e2e      # Dev server + Python E2E API server\npnpm geometry:check # Verify pinned OOXML geometry compile/evaluate/emit output\npnpm lint         # ESLint\npnpm typecheck    # tsc --noEmit\npnpm knip         # Dead code / unused exports detection\n```\n\nDev pages at `http://127.0.0.1:5173`:\n\n| Page                            | Purpose                                   |\n| ------------------------------- | ----------------------------------------- |\n| `/test/pages/index.html`        | Upload preview with search and thumbnails |\n| `/test/pages/render-slide.html` | Single slide at native resolution         |\n| `/test/pages/e2e-compare.html`  | Side-by-side PDF vs HTML with SSIM scores |\n| `/test/pages/export.html`       | Model JSON tree viewer                    |\n\n## Documentation\n\n| Doc                                       | Content                                                                |\n| ----------------------------------------- | ---------------------------------------------------------------------- |\n| [`ARCHITECTURE.md`](docs/ARCHITECTURE.md) | Parse/model/render pipeline design                                     |\n| [`PERFORMANCE.md`](docs/PERFORMANCE.md)   | Tuning options and presets                                             |\n| [`TESTING.md`](docs/TESTING.md)           | Unit/E2E strategy, two-layer metric system, visual regression workflow |\n| [`CONTRIBUTING.md`](docs/CONTRIBUTING.md) | PR checklist, code quality tools, and workflow                         |\n| [`SECURITY.md`](docs/SECURITY.md)         | Vulnerability reporting                                                |\n\n## What's Not Yet Supported\n\nThe renderer does not provide general DrawingML extrusion, true 3D charts, embedded Office 3D\nmodels, animation playback or transitions, a complete OMML engine, arbitrary EMF/WMF vector\nrendering, executable/editable OLE objects, or slide-note rendering. Unsupported 3D and effect\ncombinations retain a flat or approximate rendering path. Package-provided OLE, equation, and EMF\npreviews may still render when a compatible fallback is available. Exact bounded scopes are recorded\nin `test/e2e/oracle/capabilities.json`.\n\n## FAQ\n\n**Does this run on Node.js?**\nNo. Rendering depends on browser DOM APIs.\n\n**Why is my PPTX rendering incomplete?**\nOOXML is a vast spec. Please open a compatibility issue with a minimal PPTX sample — the visual regression pipeline makes it straightforward to add coverage for new cases.\n\n**How do I render 100+ slide decks efficiently?**\nUse `windowed: true` in `listOptions`, and enable `lazySlides: true`. For media-heavy\ndecks, also enable `lazyMedia: true`.\n\n## License\n\nApache License 2.0. See `LICENSE`.\n","readmeFilename":"README.md"}