@kitsy/pdf 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/LICENSE +201 -0
  3. package/NOTICE +16 -0
  4. package/README.md +256 -2
  5. package/THIRD_PARTY_NOTICES.md +48 -0
  6. package/dist/chunk-2K5X7L5J.js +43 -0
  7. package/dist/chunk-2K5X7L5J.js.map +1 -0
  8. package/dist/chunk-4EAYBJ6G.js +362 -0
  9. package/dist/chunk-4EAYBJ6G.js.map +1 -0
  10. package/dist/chunk-4LBJTDV5.js +165 -0
  11. package/dist/chunk-4LBJTDV5.js.map +1 -0
  12. package/dist/chunk-4ZEZ2GLD.js +353 -0
  13. package/dist/chunk-4ZEZ2GLD.js.map +1 -0
  14. package/dist/chunk-5OIMR74G.js +273 -0
  15. package/dist/chunk-5OIMR74G.js.map +1 -0
  16. package/dist/chunk-6NFNAKWA.js +257 -0
  17. package/dist/chunk-6NFNAKWA.js.map +1 -0
  18. package/dist/chunk-7MTEMQLL.js +47 -0
  19. package/dist/chunk-7MTEMQLL.js.map +1 -0
  20. package/dist/chunk-7V4SWTUK.js +83 -0
  21. package/dist/chunk-7V4SWTUK.js.map +1 -0
  22. package/dist/chunk-7XH7MFZ4.js +295 -0
  23. package/dist/chunk-7XH7MFZ4.js.map +1 -0
  24. package/dist/chunk-BK3MYSUS.js +61 -0
  25. package/dist/chunk-BK3MYSUS.js.map +1 -0
  26. package/dist/chunk-BLHNKR3S.js +35 -0
  27. package/dist/chunk-BLHNKR3S.js.map +1 -0
  28. package/dist/chunk-CCJ43SIX.js +342 -0
  29. package/dist/chunk-CCJ43SIX.js.map +1 -0
  30. package/dist/chunk-CNEDWATL.js +210 -0
  31. package/dist/chunk-CNEDWATL.js.map +1 -0
  32. package/dist/chunk-CYTWDJE2.js +152 -0
  33. package/dist/chunk-CYTWDJE2.js.map +1 -0
  34. package/dist/chunk-DKVOICYZ.js +45 -0
  35. package/dist/chunk-DKVOICYZ.js.map +1 -0
  36. package/dist/chunk-DPEJU4P6.js +79 -0
  37. package/dist/chunk-DPEJU4P6.js.map +1 -0
  38. package/dist/chunk-DQPABZTU.js +22 -0
  39. package/dist/chunk-DQPABZTU.js.map +1 -0
  40. package/dist/chunk-EKHEY3LI.js +46 -0
  41. package/dist/chunk-EKHEY3LI.js.map +1 -0
  42. package/dist/chunk-FIEYAKPI.js +421 -0
  43. package/dist/chunk-FIEYAKPI.js.map +1 -0
  44. package/dist/chunk-G467LFKC.js +191 -0
  45. package/dist/chunk-G467LFKC.js.map +1 -0
  46. package/dist/chunk-GLYWSVSB.js +250 -0
  47. package/dist/chunk-GLYWSVSB.js.map +1 -0
  48. package/dist/chunk-GXBIMUO7.js +135 -0
  49. package/dist/chunk-GXBIMUO7.js.map +1 -0
  50. package/dist/chunk-H6EERRCR.js +180 -0
  51. package/dist/chunk-H6EERRCR.js.map +1 -0
  52. package/dist/chunk-HDTM3LXD.js +35 -0
  53. package/dist/chunk-HDTM3LXD.js.map +1 -0
  54. package/dist/chunk-IGMX56C3.js +180 -0
  55. package/dist/chunk-IGMX56C3.js.map +1 -0
  56. package/dist/chunk-J4IRICCJ.js +74 -0
  57. package/dist/chunk-J4IRICCJ.js.map +1 -0
  58. package/dist/chunk-JXKQ7S6W.js +331 -0
  59. package/dist/chunk-JXKQ7S6W.js.map +1 -0
  60. package/dist/chunk-KY6DXS6S.js +34 -0
  61. package/dist/chunk-KY6DXS6S.js.map +1 -0
  62. package/dist/chunk-NOFGCYGS.js +22 -0
  63. package/dist/chunk-NOFGCYGS.js.map +1 -0
  64. package/dist/chunk-OSHUJRKD.js +131 -0
  65. package/dist/chunk-OSHUJRKD.js.map +1 -0
  66. package/dist/chunk-PMH7OWPF.js +40 -0
  67. package/dist/chunk-PMH7OWPF.js.map +1 -0
  68. package/dist/chunk-PRBKSX3A.js +299 -0
  69. package/dist/chunk-PRBKSX3A.js.map +1 -0
  70. package/dist/chunk-SVPUX7AM.js +48 -0
  71. package/dist/chunk-SVPUX7AM.js.map +1 -0
  72. package/dist/chunk-TR6HJ4NO.js +659 -0
  73. package/dist/chunk-TR6HJ4NO.js.map +1 -0
  74. package/dist/chunk-TV3E4YUF.js +69 -0
  75. package/dist/chunk-TV3E4YUF.js.map +1 -0
  76. package/dist/chunk-VCTN77K2.js +112 -0
  77. package/dist/chunk-VCTN77K2.js.map +1 -0
  78. package/dist/chunk-WEOPDD3P.js +120 -0
  79. package/dist/chunk-WEOPDD3P.js.map +1 -0
  80. package/dist/chunk-ZBZ7OC6I.js +228 -0
  81. package/dist/chunk-ZBZ7OC6I.js.map +1 -0
  82. package/dist/config-CJYo46X9.d.ts +19 -0
  83. package/dist/index.d.ts +517 -0
  84. package/dist/index.js +23 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/react/certificate-sign.d.ts +5 -0
  87. package/dist/react/certificate-sign.js +14 -0
  88. package/dist/react/certificate-sign.js.map +1 -0
  89. package/dist/react/compress.d.ts +5 -0
  90. package/dist/react/compress.js +8 -0
  91. package/dist/react/compress.js.map +1 -0
  92. package/dist/react/fill-form.d.ts +5 -0
  93. package/dist/react/fill-form.js +8 -0
  94. package/dist/react/fill-form.js.map +1 -0
  95. package/dist/react/images-to-pdf.d.ts +5 -0
  96. package/dist/react/images-to-pdf.js +7 -0
  97. package/dist/react/images-to-pdf.js.map +1 -0
  98. package/dist/react/merge.d.ts +5 -0
  99. package/dist/react/merge.js +8 -0
  100. package/dist/react/merge.js.map +1 -0
  101. package/dist/react/metadata.d.ts +5 -0
  102. package/dist/react/metadata.js +8 -0
  103. package/dist/react/metadata.js.map +1 -0
  104. package/dist/react/organize.d.ts +5 -0
  105. package/dist/react/organize.js +12 -0
  106. package/dist/react/organize.js.map +1 -0
  107. package/dist/react/pdf-to-images.d.ts +5 -0
  108. package/dist/react/pdf-to-images.js +13 -0
  109. package/dist/react/pdf-to-images.js.map +1 -0
  110. package/dist/react/protect.d.ts +5 -0
  111. package/dist/react/protect.js +8 -0
  112. package/dist/react/protect.js.map +1 -0
  113. package/dist/react/sign.d.ts +5 -0
  114. package/dist/react/sign.js +13 -0
  115. package/dist/react/sign.js.map +1 -0
  116. package/dist/react/split.d.ts +5 -0
  117. package/dist/react/split.js +11 -0
  118. package/dist/react/split.js.map +1 -0
  119. package/dist/react/verify-signatures.d.ts +5 -0
  120. package/dist/react/verify-signatures.js +8 -0
  121. package/dist/react/verify-signatures.js.map +1 -0
  122. package/dist/react/watermark.d.ts +5 -0
  123. package/dist/react/watermark.js +10 -0
  124. package/dist/react/watermark.js.map +1 -0
  125. package/dist/react.d.ts +40 -0
  126. package/dist/react.js +40 -0
  127. package/dist/react.js.map +1 -0
  128. package/dist/styles.css +2 -0
  129. package/dist/vite.d.ts +5 -0
  130. package/dist/vite.js +9 -0
  131. package/dist/vite.js.map +1 -0
  132. package/package.json +163 -4
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sign/SignatureCreator.tsx","../src/sign/SignPdf.tsx"],"names":["useState","useEffect","jsxs","jsx","Fragment","useRef","placement","byId"],"mappings":"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","file":"chunk-TR6HJ4NO.js","sourcesContent":["import \"@fontsource/dancing-script/400.css\";\nimport \"@fontsource/great-vibes/400.css\";\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { canvasToBlob } from \"../shared/pdfRender\";\nimport { fieldLabelClass, inputClass, primaryButtonClass, secondaryButtonClass } from \"../shared/ToolLayout\";\nimport { opaqueBounds, whiteToTransparent } from \"./signatureImage\";\n\nconst TABS = [\n { id: \"draw\", label: \"Draw\", icon: \"fa-solid fa-pen-nib\" },\n { id: \"type\", label: \"Type\", icon: \"fa-solid fa-keyboard\" },\n { id: \"upload\", label: \"Upload\", icon: \"fa-solid fa-upload\" },\n];\n\nconst FONTS = [\n { family: \"Dancing Script\", label: \"Handwritten\" },\n { family: \"Great Vibes\", label: \"Elegant\" },\n { family: \"Helvetica, Arial, sans-serif\", label: \"Plain (dates, initials)\" },\n];\n\nconst INKS = [\n { value: \"#0f172a\", label: \"Black\" },\n { value: \"#1d4ed8\", label: \"Blue\" },\n];\n\n/** Crop a canvas to its visible pixels (plus padding) and encode as PNG. */\nasync function trimToPng(canvas, padding = 8) {\n const context = canvas.getContext(\"2d\");\n const { data } = context.getImageData(0, 0, canvas.width, canvas.height);\n const bounds = opaqueBounds(data, canvas.width, canvas.height);\n if (!bounds) return null;\n\n const x = Math.max(0, bounds.x - padding);\n const y = Math.max(0, bounds.y - padding);\n const width = Math.min(canvas.width - x, bounds.width + padding * 2);\n const height = Math.min(canvas.height - y, bounds.height + padding * 2);\n\n const out = document.createElement(\"canvas\");\n out.width = width;\n out.height = height;\n out.getContext(\"2d\").drawImage(canvas, x, y, width, height, 0, 0, width, height);\n const blob = await canvasToBlob(out, \"image/png\");\n return {\n bytes: new Uint8Array(await blob.arrayBuffer()),\n url: URL.createObjectURL(blob),\n aspect: width / height,\n };\n}\n\nfunction DrawPad({ ink, onReady }) {\n const canvasRef = useRef(null);\n const drawing = useRef(false);\n const last = useRef(null);\n const [hasInk, setHasInk] = useState(false);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n const ratio = Math.min(3, window.devicePixelRatio || 1);\n canvas.width = canvas.clientWidth * ratio;\n canvas.height = canvas.clientHeight * ratio;\n const context = canvas.getContext(\"2d\");\n context.scale(ratio, ratio);\n context.lineCap = \"round\";\n context.lineJoin = \"round\";\n }, []);\n\n const point = (event) => {\n const rect = canvasRef.current.getBoundingClientRect();\n return { x: event.clientX - rect.left, y: event.clientY - rect.top };\n };\n\n const start = (event) => {\n event.preventDefault();\n canvasRef.current.setPointerCapture(event.pointerId);\n drawing.current = true;\n last.current = point(event);\n };\n\n const moveTo = (event) => {\n if (!drawing.current) return;\n const context = canvasRef.current.getContext(\"2d\");\n const next = point(event);\n // Slightly thinner strokes when moving fast, like a real pen.\n const distance = Math.hypot(next.x - last.current.x, next.y - last.current.y);\n context.strokeStyle = ink;\n context.lineWidth = Math.max(1.6, 3.2 - distance / 18);\n context.beginPath();\n context.moveTo(last.current.x, last.current.y);\n context.lineTo(next.x, next.y);\n context.stroke();\n last.current = next;\n setHasInk(true);\n };\n\n const stop = () => {\n drawing.current = false;\n };\n\n const clear = () => {\n const canvas = canvasRef.current;\n canvas.getContext(\"2d\").clearRect(0, 0, canvas.width, canvas.height);\n setHasInk(false);\n };\n\n return (\n <>\n <canvas\n ref={canvasRef}\n onPointerDown={start}\n onPointerMove={moveTo}\n onPointerUp={stop}\n onPointerCancel={stop}\n aria-label=\"Signature drawing area\"\n className=\"h-40 w-full touch-none rounded-xl border border-dashed border-slate-300 bg-white dark:border-slate-600\"\n />\n <div className=\"mt-3 flex flex-wrap gap-2\">\n <button type=\"button\" onClick={() => onReady(canvasRef.current)} disabled={!hasInk} className={primaryButtonClass}>\n <i className=\"fa-solid fa-check\" />\n Use signature\n </button>\n <button type=\"button\" onClick={clear} disabled={!hasInk} className={secondaryButtonClass}>\n <i className=\"fa-solid fa-eraser\" />\n Clear\n </button>\n </div>\n </>\n );\n}\n\nfunction TypePad({ ink, onReady }) {\n const [text, setText] = useState(\"\");\n const [font, setFont] = useState(FONTS[0].family);\n\n const render = async () => {\n const size = 120;\n const cssFont = `${size}px ${font.includes(\",\") ? font : `\"${font}\"`}`;\n await document.fonts.load(cssFont, text);\n const canvas = document.createElement(\"canvas\");\n const context = canvas.getContext(\"2d\");\n context.font = cssFont;\n const width = Math.ceil(context.measureText(text).width) + size;\n canvas.width = width;\n canvas.height = Math.ceil(size * 1.8);\n context.font = cssFont;\n context.fillStyle = ink;\n context.textBaseline = \"middle\";\n context.fillText(text, size / 2, canvas.height / 2);\n onReady(canvas);\n };\n\n return (\n <>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <label className={fieldLabelClass}>\n Your name or text\n <input\n type=\"text\"\n value={text}\n maxLength={60}\n onChange={(event) => setText(event.target.value)}\n placeholder=\"Jane Doe\"\n className={`mt-2 ${inputClass}`}\n />\n </label>\n <label className={fieldLabelClass}>\n Style\n <select value={font} onChange={(event) => setFont(event.target.value)} className={`mt-2 ${inputClass}`}>\n {FONTS.map((option) => (\n <option key={option.family} value={option.family}>\n {option.label}\n </option>\n ))}\n </select>\n </label>\n </div>\n <div\n className=\"mt-3 flex h-24 items-center justify-center overflow-hidden rounded-xl border border-dashed border-slate-300 bg-white px-4 text-4xl dark:border-slate-600\"\n style={{ fontFamily: font.includes(\",\") ? font : `\"${font}\"`, color: ink }}\n >\n {text || <span className=\"text-base text-slate-400\">Preview</span>}\n </div>\n <button type=\"button\" onClick={render} disabled={!text.trim()} className={`mt-3 ${primaryButtonClass}`}>\n <i className=\"fa-solid fa-check\" />\n Use signature\n </button>\n </>\n );\n}\n\nfunction UploadPad({ onReady, onError }) {\n const [removeBackground, setRemoveBackground] = useState(true);\n const inputRef = useRef(null);\n\n const handleFile = async (file) => {\n if (!file) return;\n try {\n const bitmap = await createImageBitmap(file);\n const scale = Math.min(1, 1200 / bitmap.width);\n const canvas = document.createElement(\"canvas\");\n canvas.width = Math.round(bitmap.width * scale);\n canvas.height = Math.round(bitmap.height * scale);\n const context = canvas.getContext(\"2d\");\n context.drawImage(bitmap, 0, 0, canvas.width, canvas.height);\n bitmap.close?.();\n if (removeBackground) {\n const image = context.getImageData(0, 0, canvas.width, canvas.height);\n whiteToTransparent(image.data);\n context.putImageData(image, 0, 0);\n }\n onReady(canvas);\n } catch {\n onError(\"That image could not be read. Try a PNG or JPG.\");\n }\n };\n\n return (\n <>\n <input\n ref={inputRef}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/webp\"\n className=\"hidden\"\n onChange={(event) => {\n handleFile(event.target.files?.[0]);\n event.target.value = \"\";\n }}\n />\n <button type=\"button\" onClick={() => inputRef.current?.click()} className={secondaryButtonClass}>\n <i className=\"fa-solid fa-image\" />\n Choose signature image\n </button>\n <label className=\"mt-3 flex items-center gap-3 text-sm text-slate-700 dark:text-slate-300\">\n <input\n type=\"checkbox\"\n checked={removeBackground}\n onChange={(event) => setRemoveBackground(event.target.checked)}\n className=\"h-4 w-4 accent-[#1F8CFF]\"\n />\n Remove white background (for photos or scans of paper)\n </label>\n </>\n );\n}\n\nexport default function SignatureCreator({ onCreate, onError }) {\n const [tab, setTab] = useState(\"draw\");\n const [ink, setInk] = useState(INKS[0].value);\n\n const finish = async (canvas) => {\n const result = await trimToPng(canvas);\n if (!result) {\n onError(\"The signature is empty.\");\n return;\n }\n onCreate(result);\n };\n\n return (\n <div>\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div role=\"tablist\" className=\"inline-flex rounded-xl border border-slate-200 bg-slate-50 p-1 dark:border-slate-700 dark:bg-slate-900\">\n {TABS.map((option) => (\n <button\n key={option.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={tab === option.id}\n onClick={() => setTab(option.id)}\n className={`inline-flex items-center gap-2 rounded-lg px-3 py-1.5 text-xs font-semibold uppercase tracking-[0.12em] transition ${\n tab === option.id\n ? \"bg-white text-slate-900 shadow-sm dark:bg-slate-800 dark:text-slate-100\"\n : \"text-slate-500 hover:text-slate-800 dark:text-slate-400\"\n }`}\n >\n <i className={option.icon} />\n {option.label}\n </button>\n ))}\n </div>\n {tab !== \"upload\" ? (\n <div className=\"flex items-center gap-2\" aria-label=\"Ink colour\">\n {INKS.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => setInk(option.value)}\n aria-label={`${option.label} ink`}\n aria-pressed={ink === option.value}\n className={`h-6 w-6 rounded-full border-2 ${ink === option.value ? \"border-[#1F8CFF]\" : \"border-transparent\"}`}\n style={{ backgroundColor: option.value }}\n />\n ))}\n </div>\n ) : null}\n </div>\n\n <div className=\"mt-4\">\n {tab === \"draw\" ? <DrawPad ink={ink} onReady={finish} /> : null}\n {tab === \"type\" ? <TypePad ink={ink} onReady={finish} /> : null}\n {tab === \"upload\" ? <UploadPad onReady={finish} onError={onError} /> : null}\n </div>\n </div>\n );\n}\n","import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { downloadBlob, formatBytes, toBaseName } from \"../shared/files\";\nimport { canvasToBlob, renderPageToCanvas } from \"../shared/pdfRender\";\nimport {\n BackToPdfTools,\n FileDropzone,\n PdfToolColumns,\n PdfToolPage,\n SelectedPdfCard,\n SideTips,\n StatusBanner,\n cardClass,\n iconButtonClass,\n primaryButtonClass,\n secondaryButtonClass,\n} from \"../shared/ToolLayout\";\nimport { useRenderDocument } from \"../shared/useRenderDocument\";\nimport { useSinglePdf } from \"../shared/useSinglePdf\";\nimport SignatureCreator from \"./SignatureCreator\";\nimport { applySignatures } from \"./signPdfCore\";\n\nconst PREVIEW_WIDTH = 900;\nlet nextId = 0;\n\nconst clamp = (value, min, max) => Math.min(max, Math.max(min, value));\n\nfunction usePagePreview(doc, pageIndex) {\n const [preview, setPreview] = useState(null);\n\n useEffect(() => {\n if (!doc) {\n setPreview(null);\n return undefined;\n }\n let cancelled = false;\n let url = null;\n (async () => {\n const page = await doc.getPage(pageIndex + 1);\n const base = page.getViewport({ scale: 1 });\n const ratio = Math.min(2, window.devicePixelRatio || 1);\n const render = await renderPageToCanvas(doc, pageIndex + 1, {\n scale: (PREVIEW_WIDTH / base.width) * ratio,\n });\n const blob = await canvasToBlob(render.canvas, \"image/jpeg\", 0.85);\n if (cancelled) return;\n url = URL.createObjectURL(blob);\n setPreview({ url, width: render.width, height: render.height });\n })().catch(() => {});\n return () => {\n cancelled = true;\n if (url) URL.revokeObjectURL(url);\n };\n }, [doc, pageIndex]);\n\n return preview;\n}\n\nfunction PlacementBox({ placement, signature, pageAspect, selected, onSelect, onChange, onRemove, containerRef }) {\n const startDrag = (event, mode) => {\n event.preventDefault();\n event.stopPropagation();\n onSelect();\n const rect = containerRef.current.getBoundingClientRect();\n const origin = { x: event.clientX, y: event.clientY, placement };\n\n const handleMove = (moveEvent) => {\n const dx = (moveEvent.clientX - origin.x) / rect.width;\n const dy = (moveEvent.clientY - origin.y) / rect.height;\n const start = origin.placement;\n if (mode === \"move\") {\n onChange({\n x: clamp(start.x + dx, 0, 1 - start.width),\n y: clamp(start.y + dy, 0, 1 - start.height),\n });\n } else {\n // Keep the signature's own aspect ratio while resizing.\n const width = clamp(start.width + dx, 0.04, 1 - start.x);\n const height = (width * pageAspect) / signature.aspect;\n if (start.y + height <= 1) onChange({ width, height });\n }\n };\n const handleUp = () => {\n window.removeEventListener(\"pointermove\", handleMove);\n window.removeEventListener(\"pointerup\", handleUp);\n };\n window.addEventListener(\"pointermove\", handleMove);\n window.addEventListener(\"pointerup\", handleUp);\n };\n\n const nudge = (event) => {\n const step = event.shiftKey ? 0.02 : 0.005;\n const moves = { ArrowLeft: [-step, 0], ArrowRight: [step, 0], ArrowUp: [0, -step], ArrowDown: [0, step] };\n if (event.key === \"Delete\" || event.key === \"Backspace\") {\n event.preventDefault();\n onRemove();\n return;\n }\n const move = moves[event.key];\n if (!move) return;\n event.preventDefault();\n onChange({\n x: clamp(placement.x + move[0], 0, 1 - placement.width),\n y: clamp(placement.y + move[1], 0, 1 - placement.height),\n });\n };\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n aria-label=\"Placed signature. Drag to move, use arrow keys to nudge, Delete to remove.\"\n onPointerDown={(event) => startDrag(event, \"move\")}\n onKeyDown={nudge}\n onFocus={onSelect}\n className={`absolute cursor-move touch-none select-none outline-none ${\n selected ? \"ring-2 ring-[#1F8CFF]\" : \"ring-1 ring-[#1F8CFF]/40 hover:ring-[#1F8CFF]\"\n }`}\n style={{\n left: `${placement.x * 100}%`,\n top: `${placement.y * 100}%`,\n width: `${placement.width * 100}%`,\n height: `${placement.height * 100}%`,\n }}\n >\n <img src={signature.url} alt=\"\" draggable={false} className=\"pointer-events-none h-full w-full\" />\n {selected ? (\n <>\n <button\n type=\"button\"\n onPointerDown={(event) => event.stopPropagation()}\n onClick={onRemove}\n aria-label=\"Remove signature\"\n className=\"absolute -right-3 -top-3 inline-flex h-6 w-6 items-center justify-center rounded-full bg-rose-600 text-[10px] text-white shadow\"\n >\n <i className=\"fa-solid fa-xmark\" />\n </button>\n <span\n onPointerDown={(event) => startDrag(event, \"resize\")}\n aria-hidden=\"true\"\n className=\"absolute -bottom-2 -right-2 h-4 w-4 cursor-nwse-resize rounded-sm border-2 border-white bg-[#1F8CFF] shadow\"\n />\n </>\n ) : null}\n </div>\n );\n}\n\nexport default function SignPdf() {\n const [signatures, setSignatures] = useState([]);\n const [placements, setPlacements] = useState([]);\n const [selectedId, setSelectedId] = useState(null);\n const [pageIndex, setPageIndex] = useState(0);\n const [isSaving, setIsSaving] = useState(false);\n const [status, setStatus] = useState({\n tone: \"info\",\n text: \"Add a PDF, create your signature, then place it on the page.\",\n });\n const containerRef = useRef(null);\n const signaturesRef = useRef(signatures);\n signaturesRef.current = signatures;\n\n useEffect(() => {\n document.title = \"Sign PDF | Apps\";\n return () => signaturesRef.current.forEach((signature) => URL.revokeObjectURL(signature.url));\n }, []);\n\n const onError = useCallback((text) => setStatus({ tone: \"error\", text }), []);\n const onLoaded = useCallback(({ file, pageCount }) => {\n setPlacements([]);\n setPageIndex(0);\n setStatus({\n tone: \"success\",\n text: `${file.name} loaded with ${pageCount} page${pageCount === 1 ? \"\" : \"s\"}. Create a signature to place it.`,\n });\n }, []);\n const pdf = useSinglePdf({ onError, onLoaded });\n const { doc, error: renderError } = useRenderDocument(pdf.bytes);\n const preview = usePagePreview(doc, pageIndex);\n const pageAspect = preview ? preview.width / preview.height : 1 / 1.414;\n\n const placeSignature = (signature, onPage = pageIndex) => {\n const width = 0.3;\n const height = Math.min((width * pageAspect) / signature.aspect, 1);\n // Step each new placement up and left so it does not hide an earlier one.\n const step = placements.filter((placement) => placement.pageIndex === onPage).length % 6;\n const placement = {\n id: `place-${++nextId}`,\n signatureId: signature.id,\n pageIndex: onPage,\n x: clamp(0.6 - width / 2 - step * 0.04, 0, 1 - width),\n y: clamp(0.8 - height / 2 - step * 0.08, 0, 1 - height),\n width,\n height,\n };\n setPlacements((current) => [...current, placement]);\n setSelectedId(placement.id);\n };\n\n const addSignature = (created) => {\n const signature = { id: `sig-${++nextId}`, ...created };\n setSignatures((current) => [...current, signature]);\n if (pdf.pageCount) {\n placeSignature(signature);\n setStatus({ tone: \"success\", text: \"Signature placed. Drag it into position, or resize it from the corner.\" });\n }\n };\n\n const updatePlacement = (id, patch) => {\n setPlacements((current) => current.map((placement) => (placement.id === id ? { ...placement, ...patch } : placement)));\n };\n\n const removePlacement = (id) => {\n setPlacements((current) => current.filter((placement) => placement.id !== id));\n setSelectedId(null);\n };\n\n const removeSignature = (id) => {\n setSignatures((current) => {\n const removed = current.find((signature) => signature.id === id);\n if (removed) URL.revokeObjectURL(removed.url);\n return current.filter((signature) => signature.id !== id);\n });\n setPlacements((current) => current.filter((placement) => placement.signatureId !== id));\n };\n\n const clearFile = () => {\n pdf.clear();\n setPlacements([]);\n };\n\n const handleSave = async () => {\n if (!pdf.bytes || !placements.length) return;\n setIsSaving(true);\n setStatus({ tone: \"info\", text: \"Signing your PDF...\" });\n try {\n const byId = new Map(signatures.map((signature) => [signature.id, signature]));\n const bytes = await applySignatures(\n pdf.bytes,\n placements.map((placement) => ({ ...placement, image: byId.get(placement.signatureId).bytes }))\n );\n const blob = new Blob([bytes as BlobPart], { type: \"application/pdf\" });\n downloadBlob(blob, `${toBaseName(pdf.file.name, \"document\")}-signed.pdf`);\n setStatus({\n tone: \"success\",\n text: `Signed with ${placements.length} signature${placements.length === 1 ? \"\" : \"s\"} (${formatBytes(blob.size)}). Your download has started.`,\n });\n } catch (error) {\n setStatus({ tone: \"error\", text: `Signing failed: ${error?.message || \"Please try again.\"}` });\n } finally {\n setIsSaving(false);\n }\n };\n\n const busy = isSaving || pdf.isReading;\n const pagePlacements = placements.filter((placement) => placement.pageIndex === pageIndex);\n const byId = new Map(signatures.map((signature) => [signature.id, signature]));\n\n return (\n <PdfToolPage\n title=\"Sign PDF\"\n description=\"Draw, type, or upload your signature and place it anywhere on the page. Runs in your browser; your document and signature never leave your device.\"\n stats={[\n { value: pdf.pageCount || \"-\", label: \"Pages\" },\n { value: placements.length || \"-\", label: \"Placed\" },\n ]}\n >\n <PdfToolColumns\n main={\n <>\n {pdf.file ? (\n <SelectedPdfCard\n signed={pdf.signed} file={pdf.file} pageCount={pdf.pageCount} onRemove={clearFile} disabled={isSaving} />\n ) : (\n <FileDropzone\n accept=\".pdf,application/pdf\"\n disabled={busy}\n onFiles={pdf.selectFiles}\n title=\"Drag and drop a PDF here\"\n hint=\"or click to browse from your device\"\n />\n )}\n\n {renderError ? <p className=\"mt-3 text-xs text-rose-700 dark:text-rose-300\">{renderError}</p> : null}\n\n {pdf.pageCount ? (\n <div className=\"mt-5\">\n <div className=\"mb-3 flex flex-wrap items-center justify-between gap-2\">\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setPageIndex((index) => Math.max(0, index - 1))}\n disabled={pageIndex === 0}\n className={iconButtonClass}\n aria-label=\"Previous page\"\n >\n <i className=\"fa-solid fa-chevron-left\" />\n </button>\n <span className=\"text-sm text-slate-700 dark:text-slate-300\">\n Page {pageIndex + 1} of {pdf.pageCount}\n </span>\n <button\n type=\"button\"\n onClick={() => setPageIndex((index) => Math.min(pdf.pageCount - 1, index + 1))}\n disabled={pageIndex === pdf.pageCount - 1}\n className={iconButtonClass}\n aria-label=\"Next page\"\n >\n <i className=\"fa-solid fa-chevron-right\" />\n </button>\n </div>\n <span className=\"text-xs text-slate-500 dark:text-slate-400\">\n {pagePlacements.length} on this page\n </span>\n </div>\n\n <div className=\"flex justify-center rounded-2xl bg-slate-100 p-3 dark:bg-slate-800\">\n <div\n ref={containerRef}\n onPointerDown={() => setSelectedId(null)}\n className=\"relative w-full max-w-[720px] bg-white shadow-md\"\n style={{ aspectRatio: preview ? `${preview.width} / ${preview.height}` : \"1 / 1.414\" }}\n >\n {preview ? (\n <img\n src={preview.url}\n alt={`Page ${pageIndex + 1}`}\n draggable={false}\n className=\"pointer-events-none absolute inset-0 h-full w-full select-none\"\n />\n ) : (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <i className=\"fa-solid fa-spinner fa-spin text-slate-400\" aria-label=\"Rendering page\" />\n </div>\n )}\n {pagePlacements.map((placement) => (\n <PlacementBox\n key={placement.id}\n placement={placement}\n signature={byId.get(placement.signatureId)}\n pageAspect={pageAspect}\n selected={selectedId === placement.id}\n onSelect={() => setSelectedId(placement.id)}\n onChange={(patch) => updatePlacement(placement.id, patch)}\n onRemove={() => removePlacement(placement.id)}\n containerRef={containerRef}\n />\n ))}\n </div>\n </div>\n </div>\n ) : null}\n\n <StatusBanner status={status} />\n\n <div className=\"mt-5 flex flex-wrap gap-3\">\n <button type=\"button\" onClick={handleSave} disabled={busy || !placements.length} className={primaryButtonClass}>\n <i className={`fa-solid ${isSaving ? \"fa-spinner fa-spin\" : \"fa-signature\"}`} />\n {isSaving ? \"Signing...\" : \"Sign & Download\"}\n </button>\n <BackToPdfTools />\n </div>\n </>\n }\n side={\n <>\n <h2 className=\"text-base font-semibold text-slate-900 dark:text-slate-100\">Your signature</h2>\n <div className=\"mt-4\">\n <SignatureCreator onCreate={addSignature} onError={onError} />\n </div>\n\n {signatures.length ? (\n <ul className=\"mt-5 space-y-2\">\n {signatures.map((signature) => (\n <li key={signature.id} className={`${cardClass} !p-2`}>\n <div className=\"flex h-14 items-center justify-center rounded-lg bg-white\">\n <img src={signature.url} alt=\"Saved signature\" className=\"max-h-full max-w-full\" />\n </div>\n <div className=\"mt-2 flex gap-2\">\n <button\n type=\"button\"\n onClick={() => placeSignature(signature)}\n disabled={!pdf.pageCount}\n className={`flex-1 justify-center ${secondaryButtonClass}`}\n >\n <i className=\"fa-solid fa-plus\" />\n Place\n </button>\n <button\n type=\"button\"\n onClick={() => removeSignature(signature.id)}\n className={iconButtonClass}\n aria-label=\"Delete signature\"\n >\n <i className=\"fa-solid fa-trash\" />\n </button>\n </div>\n </li>\n ))}\n </ul>\n ) : null}\n\n <SideTips\n tips={[\n \"Place the same signature on several pages, or add initials with Type → Plain.\",\n \"Select a signature and press Delete to remove it; arrow keys nudge it.\",\n \"This adds a visible signature image. It is not a certificate-based digital signature.\",\n ]}\n />\n </>\n }\n />\n </PdfToolPage>\n );\n}\n"]}
@@ -0,0 +1,69 @@
1
+ import { producerName } from './chunk-DQPABZTU.js';
2
+ import { parsePageSelection, parsePageGroups } from './chunk-BLHNKR3S.js';
3
+ import { loadPdf } from './chunk-EKHEY3LI.js';
4
+ import { PDFDocument } from 'pdf-lib';
5
+
6
+ function rangeLabel(indices) {
7
+ const first = indices[0] + 1;
8
+ const last = indices[indices.length - 1] + 1;
9
+ return indices.length === 1 ? `p${first}` : `p${first}-${last}`;
10
+ }
11
+ function planSplit(pageCount, options) {
12
+ if (pageCount < 1) {
13
+ throw new Error("This PDF has no pages.");
14
+ }
15
+ if (options.mode === "every") {
16
+ const size = Math.floor(Number(options.every));
17
+ if (!Number.isFinite(size) || size < 1) {
18
+ throw new Error("Pages per file must be a whole number of at least 1.");
19
+ }
20
+ const groups = [];
21
+ for (let start = 0; start < pageCount; start += size) {
22
+ groups.push(
23
+ Array.from({ length: Math.min(size, pageCount - start) }, (_, offset) => start + offset)
24
+ );
25
+ }
26
+ return groups;
27
+ }
28
+ if (options.mode === "extract") {
29
+ if (!(options.ranges || "").trim()) {
30
+ throw new Error("Enter the pages to extract, e.g. 1-3, 5.");
31
+ }
32
+ return [parsePageSelection(options.ranges, pageCount)];
33
+ }
34
+ if (!(options.ranges || "").trim()) {
35
+ throw new Error("Enter at least one page range, e.g. 1-3, 4-6.");
36
+ }
37
+ return parsePageGroups(options.ranges, pageCount);
38
+ }
39
+ async function splitPdf(bytes, options) {
40
+ const source = await loadPdf(bytes);
41
+ const groups = planSplit(source.getPageCount(), options);
42
+ const baseName = options.baseName || "document";
43
+ const outputs = [];
44
+ for (const indices of groups) {
45
+ const out = await PDFDocument.create();
46
+ const pages = await out.copyPages(source, indices);
47
+ pages.forEach((page) => out.addPage(page));
48
+ const title = source.getTitle();
49
+ if (title) out.setTitle(title);
50
+ out.setProducer(producerName());
51
+ out.setCreationDate(/* @__PURE__ */ new Date());
52
+ outputs.push({
53
+ name: options.mode === "extract" ? `${baseName}-extracted.pdf` : `${baseName}-${rangeLabel(indices)}.pdf`,
54
+ pageIndices: indices,
55
+ bytes: await out.save()
56
+ });
57
+ }
58
+ const seen = /* @__PURE__ */ new Map();
59
+ for (const output of outputs) {
60
+ const count = (seen.get(output.name) || 0) + 1;
61
+ seen.set(output.name, count);
62
+ if (count > 1) output.name = output.name.replace(/\.pdf$/, `-${count}.pdf`);
63
+ }
64
+ return outputs;
65
+ }
66
+
67
+ export { planSplit, splitPdf };
68
+ //# sourceMappingURL=chunk-TV3E4YUF.js.map
69
+ //# sourceMappingURL=chunk-TV3E4YUF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/split/splitPdfCore.ts"],"names":[],"mappings":"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","file":"chunk-TV3E4YUF.js","sourcesContent":["import { PDFDocument } from \"pdf-lib\";\nimport { loadPdf } from \"../shared/files\";\nimport { parsePageGroups, parsePageSelection } from \"../shared/pageRanges\";\nimport { producerName } from \"../config\";\n\nexport type SplitMode = \"ranges\" | \"every\" | \"extract\";\n\nexport type SplitPdfOptions = {\n mode: SplitMode;\n /** 1-based selection. \"ranges\": one file per comma part. \"extract\": one file. */\n ranges?: string;\n /** \"every\": pages per output file. */\n every?: number;\n baseName?: string;\n};\n\nexport type SplitPdfOutput = { name: string; pageIndices: number[]; bytes: Uint8Array };\n\nfunction rangeLabel(indices: number[]) {\n const first = indices[0] + 1;\n const last = indices[indices.length - 1] + 1;\n return indices.length === 1 ? `p${first}` : `p${first}-${last}`;\n}\n\n/** Work out which pages go into which output file, without touching PDF bytes. */\nexport function planSplit(pageCount: number, options: SplitPdfOptions) {\n if (pageCount < 1) {\n throw new Error(\"This PDF has no pages.\");\n }\n\n if (options.mode === \"every\") {\n const size = Math.floor(Number(options.every));\n if (!Number.isFinite(size) || size < 1) {\n throw new Error(\"Pages per file must be a whole number of at least 1.\");\n }\n const groups: number[][] = [];\n for (let start = 0; start < pageCount; start += size) {\n groups.push(\n Array.from({ length: Math.min(size, pageCount - start) }, (_, offset) => start + offset)\n );\n }\n return groups;\n }\n\n if (options.mode === \"extract\") {\n if (!(options.ranges || \"\").trim()) {\n throw new Error(\"Enter the pages to extract, e.g. 1-3, 5.\");\n }\n return [parsePageSelection(options.ranges, pageCount)];\n }\n\n if (!(options.ranges || \"\").trim()) {\n throw new Error(\"Enter at least one page range, e.g. 1-3, 4-6.\");\n }\n return parsePageGroups(options.ranges, pageCount);\n}\n\nexport async function splitPdf(bytes: ArrayBuffer | Uint8Array, options: SplitPdfOptions) {\n const source = await loadPdf(bytes);\n const groups = planSplit(source.getPageCount(), options);\n const baseName = options.baseName || \"document\";\n const outputs: SplitPdfOutput[] = [];\n\n for (const indices of groups) {\n const out = await PDFDocument.create();\n const pages = await out.copyPages(source, indices);\n pages.forEach((page) => out.addPage(page));\n\n const title = source.getTitle();\n if (title) out.setTitle(title);\n out.setProducer(producerName());\n out.setCreationDate(new Date());\n\n outputs.push({\n name:\n options.mode === \"extract\"\n ? `${baseName}-extracted.pdf`\n : `${baseName}-${rangeLabel(indices)}.pdf`,\n pageIndices: indices,\n bytes: await out.save(),\n });\n }\n\n // Ranges like \"1, 1\" would otherwise produce two files with the same name.\n const seen = new Map<string, number>();\n for (const output of outputs) {\n const count = (seen.get(output.name) || 0) + 1;\n seen.set(output.name, count);\n if (count > 1) output.name = output.name.replace(/\\.pdf$/, `-${count}.pdf`);\n }\n\n return outputs;\n}\n"]}
@@ -0,0 +1,112 @@
1
+ import { visualSize, textOrigin } from './chunk-PMH7OWPF.js';
2
+ import { parsePageSelection } from './chunk-BLHNKR3S.js';
3
+ import { loadPdf } from './chunk-EKHEY3LI.js';
4
+ import { StandardFonts, degrees, rgb } from 'pdf-lib';
5
+
6
+ function hexToRgb(hex, fallback = "#64748b") {
7
+ const value = /^#?[0-9a-f]{6}$/i.test(hex || "") ? hex : fallback;
8
+ const clean = value.replace("#", "");
9
+ return rgb(
10
+ parseInt(clean.slice(0, 2), 16) / 255,
11
+ parseInt(clean.slice(2, 4), 16) / 255,
12
+ parseInt(clean.slice(4, 6), 16) / 255
13
+ );
14
+ }
15
+ function formatPageNumber(format, n, total) {
16
+ return (format || "{n}").replace(/\{n\}/g, String(n)).replace(/\{total\}/g, String(total));
17
+ }
18
+ function measure(font, text, size) {
19
+ try {
20
+ return {
21
+ width: font.widthOfTextAtSize(text, size),
22
+ height: font.heightAtSize(size, { descender: false })
23
+ };
24
+ } catch {
25
+ throw new Error(
26
+ `"${text}" contains characters the standard PDF font cannot draw. Use basic Latin letters, numbers, and punctuation.`
27
+ );
28
+ }
29
+ }
30
+ function drawVisualText(page, font, text, { vx, vy, size, angle = 0, color, opacity = 1 }) {
31
+ const point = textOrigin(page, vx, vy);
32
+ page.drawText(text, {
33
+ x: point.x,
34
+ y: point.y,
35
+ size,
36
+ font,
37
+ color,
38
+ opacity,
39
+ rotate: degrees(point.angle + angle)
40
+ });
41
+ }
42
+ function pageNumberAnchor(position, visualWidth, visualHeight, textWidth, textHeight, margin) {
43
+ const [vertical, horizontal] = position.split("-");
44
+ const vy = vertical === "top" ? visualHeight - margin - textHeight : margin;
45
+ let vx = (visualWidth - textWidth) / 2;
46
+ if (horizontal === "left") vx = margin;
47
+ if (horizontal === "right") vx = visualWidth - margin - textWidth;
48
+ return { vx, vy };
49
+ }
50
+ function planStampedPages(targets, startAt = 1) {
51
+ const unique = [...new Set(targets)].sort((a, b) => a - b);
52
+ const first = Math.floor(Number(startAt)) || 1;
53
+ const total = unique.length + first - 1;
54
+ return unique.map((pageIndex, order) => ({ pageIndex, n: order + first, total }));
55
+ }
56
+ async function stampPdf(bytes, options) {
57
+ const watermark = options.watermark?.text?.trim() ? options.watermark : null;
58
+ const pageNumbers = options.pageNumbers || null;
59
+ if (!watermark && !pageNumbers) {
60
+ throw new Error("Turn on a watermark or page numbers first.");
61
+ }
62
+ const doc = await loadPdf(bytes);
63
+ const pages = doc.getPages();
64
+ const targets = parsePageSelection(options.pages, pages.length);
65
+ const font = await doc.embedFont(StandardFonts.Helvetica);
66
+ const boldFont = await doc.embedFont(StandardFonts.HelveticaBold);
67
+ planStampedPages(targets, pageNumbers?.startAt ?? 1).forEach(({ pageIndex, n, total }) => {
68
+ const page = pages[pageIndex];
69
+ const { visualWidth, visualHeight } = visualSize(page);
70
+ if (watermark) {
71
+ const size = Math.max(6, Number(watermark.fontSize) || 48);
72
+ const text = watermark.text.trim();
73
+ const { width, height } = measure(boldFont, text, size);
74
+ const angle = Number(watermark.rotation ?? 45);
75
+ const radians = angle * Math.PI / 180;
76
+ const vx = visualWidth / 2 - width / 2 * Math.cos(radians) + height / 2 * Math.sin(radians);
77
+ const vy = visualHeight / 2 - width / 2 * Math.sin(radians) - height / 2 * Math.cos(radians);
78
+ drawVisualText(page, boldFont, text, {
79
+ vx,
80
+ vy,
81
+ size,
82
+ angle,
83
+ color: hexToRgb(watermark.color, "#e11d48"),
84
+ opacity: Math.min(1, Math.max(0.05, Number(watermark.opacity ?? 0.2)))
85
+ });
86
+ }
87
+ if (pageNumbers) {
88
+ const size = Math.max(6, Number(pageNumbers.fontSize) || 11);
89
+ const text = formatPageNumber(pageNumbers.format, n, total);
90
+ const { width, height } = measure(font, text, size);
91
+ const { vx, vy } = pageNumberAnchor(
92
+ pageNumbers.position || "bottom-center",
93
+ visualWidth,
94
+ visualHeight,
95
+ width,
96
+ height,
97
+ Math.max(0, Number(pageNumbers.margin ?? 28))
98
+ );
99
+ drawVisualText(page, font, text, {
100
+ vx,
101
+ vy,
102
+ size,
103
+ color: hexToRgb(pageNumbers.color, "#334155")
104
+ });
105
+ }
106
+ });
107
+ return doc.save();
108
+ }
109
+
110
+ export { formatPageNumber, planStampedPages, stampPdf };
111
+ //# sourceMappingURL=chunk-VCTN77K2.js.map
112
+ //# sourceMappingURL=chunk-VCTN77K2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/stamp/stampPdfCore.ts"],"names":[],"mappings":";;;;;AA2CO,SAAS,QAAA,CAAS,GAAA,EAAyB,QAAA,GAAW,SAAA,EAAW;AACtE,EAAA,MAAM,QAAQ,kBAAA,CAAmB,IAAA,CAAK,GAAA,IAAO,EAAE,IAAI,GAAA,GAAM,QAAA;AACzD,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,GAAA,EAAK,EAAE,CAAA;AACnC,EAAA,OAAO,GAAA;AAAA,IACL,SAAS,KAAA,CAAM,KAAA,CAAM,GAAG,CAAC,CAAA,EAAG,EAAE,CAAA,GAAI,GAAA;AAAA,IAClC,SAAS,KAAA,CAAM,KAAA,CAAM,GAAG,CAAC,CAAA,EAAG,EAAE,CAAA,GAAI,GAAA;AAAA,IAClC,SAAS,KAAA,CAAM,KAAA,CAAM,GAAG,CAAC,CAAA,EAAG,EAAE,CAAA,GAAI;AAAA,GACpC;AACF;AAEO,SAAS,gBAAA,CAAiB,MAAA,EAA4B,CAAA,EAAW,KAAA,EAAe;AACrF,EAAA,OAAA,CAAQ,MAAA,IAAU,KAAA,EAAO,OAAA,CAAQ,QAAA,EAAU,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,OAAA,CAAQ,YAAA,EAAc,MAAA,CAAO,KAAK,CAAC,CAAA;AAC3F;AAEA,SAAS,OAAA,CAAQ,IAAA,EAAe,IAAA,EAAc,IAAA,EAAc;AAC1D,EAAA,IAAI;AACF,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,IAAA,CAAK,iBAAA,CAAkB,IAAA,EAAM,IAAI,CAAA;AAAA,MACxC,QAAQ,IAAA,CAAK,YAAA,CAAa,MAAM,EAAE,SAAA,EAAW,OAAO;AAAA,KACtD;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,IAAI,IAAI,CAAA,2GAAA;AAAA,KACV;AAAA,EACF;AACF;AAEA,SAAS,cAAA,CACP,IAAA,EACA,IAAA,EACA,IAAA,EACA,EAAE,EAAA,EAAI,EAAA,EAAI,IAAA,EAAM,KAAA,GAAQ,CAAA,EAAG,KAAA,EAAO,OAAA,GAAU,GAAE,EAC9C;AACA,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,IAAA,EAAM,EAAA,EAAI,EAAE,CAAA;AACrC,EAAA,IAAA,CAAK,SAAS,IAAA,EAAM;AAAA,IAClB,GAAG,KAAA,CAAM,CAAA;AAAA,IACT,GAAG,KAAA,CAAM,CAAA;AAAA,IACT,IAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA,EAAQ,OAAA,CAAQ,KAAA,CAAM,KAAA,GAAQ,KAAK;AAAA,GACpC,CAAA;AACH;AAEO,SAAS,iBACd,QAAA,EACA,WAAA,EACA,YAAA,EACA,SAAA,EACA,YACA,MAAA,EACA;AACA,EAAA,MAAM,CAAC,QAAA,EAAU,UAAU,CAAA,GAAI,QAAA,CAAS,MAAM,GAAG,CAAA;AACjD,EAAA,MAAM,EAAA,GAAK,QAAA,KAAa,KAAA,GAAQ,YAAA,GAAe,SAAS,UAAA,GAAa,MAAA;AACrE,EAAA,IAAI,EAAA,GAAA,CAAM,cAAc,SAAA,IAAa,CAAA;AACrC,EAAA,IAAI,UAAA,KAAe,QAAQ,EAAA,GAAK,MAAA;AAChC,EAAA,IAAI,UAAA,KAAe,OAAA,EAAS,EAAA,GAAK,WAAA,GAAc,MAAA,GAAS,SAAA;AACxD,EAAA,OAAO,EAAE,IAAI,EAAA,EAAG;AAClB;AAMO,SAAS,gBAAA,CAAiB,OAAA,EAAmB,OAAA,GAAU,CAAA,EAAG;AAE/D,EAAA,MAAM,MAAA,GAAS,CAAC,GAAG,IAAI,GAAA,CAAI,OAAO,CAAC,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,IAAI,CAAC,CAAA;AACzD,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,OAAO,CAAC,CAAA,IAAK,CAAA;AAC7C,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,MAAA,GAAS,KAAA,GAAQ,CAAA;AACtC,EAAA,OAAO,MAAA,CAAO,GAAA,CAAI,CAAC,SAAA,EAAW,KAAA,MAAW,EAAE,SAAA,EAAW,CAAA,EAAG,KAAA,GAAQ,KAAA,EAAO,KAAA,EAAM,CAAE,CAAA;AAClF;AAEA,eAAsB,QAAA,CAAS,OAAiC,OAAA,EAA0B;AACxF,EAAA,MAAM,YAAY,OAAA,CAAQ,SAAA,EAAW,MAAM,IAAA,EAAK,GAAI,QAAQ,SAAA,GAAY,IAAA;AACxE,EAAA,MAAM,WAAA,GAAc,QAAQ,WAAA,IAAe,IAAA;AAC3C,EAAA,IAAI,CAAC,SAAA,IAAa,CAAC,WAAA,EAAa;AAC9B,IAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,EAC9D;AAEA,EAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,KAAK,CAAA;AAC/B,EAAA,MAAM,KAAA,GAAQ,IAAI,QAAA,EAAS;AAC3B,EAAA,MAAM,OAAA,GAAU,kBAAA,CAAmB,OAAA,CAAQ,KAAA,EAAO,MAAM,MAAM,CAAA;AAC9D,EAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,SAAA,CAAU,cAAc,SAAS,CAAA;AACxD,EAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,SAAA,CAAU,cAAc,aAAa,CAAA;AAEhE,EAAA,gBAAA,CAAiB,OAAA,EAAS,WAAA,EAAa,OAAA,IAAW,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,EAAE,SAAA,EAAW,CAAA,EAAG,KAAA,EAAM,KAAM;AACxF,IAAA,MAAM,IAAA,GAAO,MAAM,SAAS,CAAA;AAC5B,IAAA,MAAM,EAAE,WAAA,EAAa,YAAA,EAAa,GAAI,WAAW,IAAI,CAAA;AAErD,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,MAAM,IAAA,GAAO,KAAK,GAAA,CAAI,CAAA,EAAG,OAAO,SAAA,CAAU,QAAQ,KAAK,EAAE,CAAA;AACzD,MAAA,MAAM,IAAA,GAAO,SAAA,CAAU,IAAA,CAAK,IAAA,EAAK;AACjC,MAAA,MAAM,EAAE,KAAA,EAAO,MAAA,KAAW,OAAA,CAAQ,QAAA,EAAU,MAAM,IAAI,CAAA;AACtD,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,SAAA,CAAU,QAAA,IAAY,EAAE,CAAA;AAC7C,MAAA,MAAM,OAAA,GAAW,KAAA,GAAQ,IAAA,CAAK,EAAA,GAAM,GAAA;AAEpC,MAAA,MAAM,EAAA,GAAK,WAAA,GAAc,CAAA,GAAK,KAAA,GAAQ,CAAA,GAAK,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA,GAAK,MAAA,GAAS,CAAA,GAAK,IAAA,CAAK,IAAI,OAAO,CAAA;AAC9F,MAAA,MAAM,EAAA,GAAK,YAAA,GAAe,CAAA,GAAK,KAAA,GAAQ,CAAA,GAAK,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA,GAAK,MAAA,GAAS,CAAA,GAAK,IAAA,CAAK,IAAI,OAAO,CAAA;AAC/F,MAAA,cAAA,CAAe,IAAA,EAAM,UAAU,IAAA,EAAM;AAAA,QACnC,EAAA;AAAA,QACA,EAAA;AAAA,QACA,IAAA;AAAA,QACA,KAAA;AAAA,QACA,KAAA,EAAO,QAAA,CAAS,SAAA,CAAU,KAAA,EAAO,SAAS,CAAA;AAAA,QAC1C,OAAA,EAAS,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,MAAA,CAAO,SAAA,CAAU,OAAA,IAAW,GAAG,CAAC,CAAC;AAAA,OACtE,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,MAAM,IAAA,GAAO,KAAK,GAAA,CAAI,CAAA,EAAG,OAAO,WAAA,CAAY,QAAQ,KAAK,EAAE,CAAA;AAC3D,MAAA,MAAM,IAAA,GAAO,gBAAA,CAAiB,WAAA,CAAY,MAAA,EAAQ,GAAG,KAAK,CAAA;AAC1D,MAAA,MAAM,EAAE,KAAA,EAAO,MAAA,KAAW,OAAA,CAAQ,IAAA,EAAM,MAAM,IAAI,CAAA;AAClD,MAAA,MAAM,EAAE,EAAA,EAAI,EAAA,EAAG,GAAI,gBAAA;AAAA,QACjB,YAAY,QAAA,IAAY,eAAA;AAAA,QACxB,WAAA;AAAA,QACA,YAAA;AAAA,QACA,KAAA;AAAA,QACA,MAAA;AAAA,QACA,KAAK,GAAA,CAAI,CAAA,EAAG,OAAO,WAAA,CAAY,MAAA,IAAU,EAAE,CAAC;AAAA,OAC9C;AACA,MAAA,cAAA,CAAe,IAAA,EAAM,MAAM,IAAA,EAAM;AAAA,QAC/B,EAAA;AAAA,QACA,EAAA;AAAA,QACA,IAAA;AAAA,QACA,KAAA,EAAO,QAAA,CAAS,WAAA,CAAY,KAAA,EAAO,SAAS;AAAA,OAC7C,CAAA;AAAA,IACH;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,IAAI,IAAA,EAAK;AAClB","file":"chunk-VCTN77K2.js","sourcesContent":["import { PDFFont, PDFPage, StandardFonts, degrees, rgb } from \"pdf-lib\";\nimport { loadPdf } from \"../shared/files\";\nimport { parsePageSelection } from \"../shared/pageRanges\";\nimport { textOrigin, visualSize } from \"../shared/pageGeometry\";\n\nexport { textOrigin, visualToUser } from \"../shared/pageGeometry\";\n\nexport type NumberPosition =\n | \"bottom-left\"\n | \"bottom-center\"\n | \"bottom-right\"\n | \"top-left\"\n | \"top-center\"\n | \"top-right\";\n\nexport type WatermarkOptions = {\n text: string;\n fontSize?: number;\n /** 0-1 */\n opacity?: number;\n /** Degrees, counter-clockwise, as seen on screen. */\n rotation?: number;\n /** \"#rrggbb\" */\n color?: string;\n};\n\nexport type PageNumberOptions = {\n /** Tokens: {n} page number, {total} numbered page count. */\n format?: string;\n position?: NumberPosition;\n fontSize?: number;\n startAt?: number;\n margin?: number;\n color?: string;\n};\n\nexport type StampPdfOptions = {\n /** 1-based selection of pages to stamp. Empty means all pages. */\n pages?: string;\n watermark?: WatermarkOptions | null;\n pageNumbers?: PageNumberOptions | null;\n};\n\nexport function hexToRgb(hex: string | undefined, fallback = \"#64748b\") {\n const value = /^#?[0-9a-f]{6}$/i.test(hex || \"\") ? hex : fallback;\n const clean = value.replace(\"#\", \"\");\n return rgb(\n parseInt(clean.slice(0, 2), 16) / 255,\n parseInt(clean.slice(2, 4), 16) / 255,\n parseInt(clean.slice(4, 6), 16) / 255\n );\n}\n\nexport function formatPageNumber(format: string | undefined, n: number, total: number) {\n return (format || \"{n}\").replace(/\\{n\\}/g, String(n)).replace(/\\{total\\}/g, String(total));\n}\n\nfunction measure(font: PDFFont, text: string, size: number) {\n try {\n return {\n width: font.widthOfTextAtSize(text, size),\n height: font.heightAtSize(size, { descender: false }),\n };\n } catch {\n throw new Error(\n `\"${text}\" contains characters the standard PDF font cannot draw. Use basic Latin letters, numbers, and punctuation.`\n );\n }\n}\n\nfunction drawVisualText(\n page: PDFPage,\n font: PDFFont,\n text: string,\n { vx, vy, size, angle = 0, color, opacity = 1 }\n) {\n const point = textOrigin(page, vx, vy);\n page.drawText(text, {\n x: point.x,\n y: point.y,\n size,\n font,\n color,\n opacity,\n rotate: degrees(point.angle + angle),\n });\n}\n\nexport function pageNumberAnchor(\n position: NumberPosition,\n visualWidth: number,\n visualHeight: number,\n textWidth: number,\n textHeight: number,\n margin: number\n) {\n const [vertical, horizontal] = position.split(\"-\");\n const vy = vertical === \"top\" ? visualHeight - margin - textHeight : margin;\n let vx = (visualWidth - textWidth) / 2;\n if (horizontal === \"left\") vx = margin;\n if (horizontal === \"right\") vx = visualWidth - margin - textWidth;\n return { vx, vy };\n}\n\n/**\n * Which pages get stamped and the number each one shows. Pages listed twice\n * are stamped once; numbering counts only stamped pages.\n */\nexport function planStampedPages(targets: number[], startAt = 1) {\n // Stamping never reorders pages, so number them in document order.\n const unique = [...new Set(targets)].sort((a, b) => a - b);\n const first = Math.floor(Number(startAt)) || 1;\n const total = unique.length + first - 1;\n return unique.map((pageIndex, order) => ({ pageIndex, n: order + first, total }));\n}\n\nexport async function stampPdf(bytes: ArrayBuffer | Uint8Array, options: StampPdfOptions) {\n const watermark = options.watermark?.text?.trim() ? options.watermark : null;\n const pageNumbers = options.pageNumbers || null;\n if (!watermark && !pageNumbers) {\n throw new Error(\"Turn on a watermark or page numbers first.\");\n }\n\n const doc = await loadPdf(bytes);\n const pages = doc.getPages();\n const targets = parsePageSelection(options.pages, pages.length);\n const font = await doc.embedFont(StandardFonts.Helvetica);\n const boldFont = await doc.embedFont(StandardFonts.HelveticaBold);\n\n planStampedPages(targets, pageNumbers?.startAt ?? 1).forEach(({ pageIndex, n, total }) => {\n const page = pages[pageIndex];\n const { visualWidth, visualHeight } = visualSize(page);\n\n if (watermark) {\n const size = Math.max(6, Number(watermark.fontSize) || 48);\n const text = watermark.text.trim();\n const { width, height } = measure(boldFont, text, size);\n const angle = Number(watermark.rotation ?? 45);\n const radians = (angle * Math.PI) / 180;\n // Start the baseline so the text's centre sits on the page centre.\n const vx = visualWidth / 2 - (width / 2) * Math.cos(radians) + (height / 2) * Math.sin(radians);\n const vy = visualHeight / 2 - (width / 2) * Math.sin(radians) - (height / 2) * Math.cos(radians);\n drawVisualText(page, boldFont, text, {\n vx,\n vy,\n size,\n angle,\n color: hexToRgb(watermark.color, \"#e11d48\"),\n opacity: Math.min(1, Math.max(0.05, Number(watermark.opacity ?? 0.2))),\n });\n }\n\n if (pageNumbers) {\n const size = Math.max(6, Number(pageNumbers.fontSize) || 11);\n const text = formatPageNumber(pageNumbers.format, n, total);\n const { width, height } = measure(font, text, size);\n const { vx, vy } = pageNumberAnchor(\n pageNumbers.position || \"bottom-center\",\n visualWidth,\n visualHeight,\n width,\n height,\n Math.max(0, Number(pageNumbers.margin ?? 28))\n );\n drawVisualText(page, font, text, {\n vx,\n vy,\n size,\n color: hexToRgb(pageNumbers.color, \"#334155\"),\n });\n }\n });\n\n return doc.save();\n}\n"]}
@@ -0,0 +1,120 @@
1
+ import { producerName } from './chunk-DQPABZTU.js';
2
+ import { PDFDocument } from 'pdf-lib';
3
+
4
+ var PAGE_SIZES = {
5
+ a4: [595.28, 841.89],
6
+ letter: [612, 792]
7
+ };
8
+ function detectImageKind(bytes) {
9
+ const view = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
10
+ if (view.length >= 8 && view[0] === 137 && view[1] === 80 && view[2] === 78 && view[3] === 71) {
11
+ return "png";
12
+ }
13
+ if (view.length >= 3 && view[0] === 255 && view[1] === 216 && view[2] === 255) {
14
+ return "jpg";
15
+ }
16
+ return null;
17
+ }
18
+ function getJpegOrientation(bytes) {
19
+ const view = new DataView(
20
+ bytes instanceof Uint8Array ? bytes.buffer : bytes,
21
+ bytes instanceof Uint8Array ? bytes.byteOffset : 0,
22
+ bytes.byteLength
23
+ );
24
+ if (view.byteLength < 4 || view.getUint16(0) !== 65496) return 1;
25
+ let offset = 2;
26
+ while (offset + 4 <= view.byteLength) {
27
+ const marker = view.getUint16(offset);
28
+ if ((marker & 65280) !== 65280 || marker === 65498) break;
29
+ const length = view.getUint16(offset + 2);
30
+ if (marker === 65505 && view.getUint32(offset + 4) === 1165519206) {
31
+ const tiff = offset + 10;
32
+ if (tiff + 8 > view.byteLength) return 1;
33
+ const little = view.getUint16(tiff) === 18761;
34
+ const ifd = tiff + view.getUint32(tiff + 4, little);
35
+ if (ifd + 2 > view.byteLength) return 1;
36
+ const entries = view.getUint16(ifd, little);
37
+ for (let i = 0; i < entries; i += 1) {
38
+ const entry = ifd + 2 + i * 12;
39
+ if (entry + 12 > view.byteLength) return 1;
40
+ if (view.getUint16(entry, little) === 274) {
41
+ const value = view.getUint16(entry + 8, little);
42
+ return value >= 1 && value <= 8 ? value : 1;
43
+ }
44
+ }
45
+ return 1;
46
+ }
47
+ offset += 2 + length;
48
+ }
49
+ return 1;
50
+ }
51
+ function layoutImage(imageWidth, imageHeight, {
52
+ pageSize = "a4",
53
+ orientation = "auto",
54
+ margin = 0
55
+ } = {}) {
56
+ const safeMargin = Math.max(0, margin);
57
+ if (pageSize === "fit") {
58
+ return {
59
+ pageWidth: imageWidth + safeMargin * 2,
60
+ pageHeight: imageHeight + safeMargin * 2,
61
+ x: safeMargin,
62
+ y: safeMargin,
63
+ width: imageWidth,
64
+ height: imageHeight
65
+ };
66
+ }
67
+ const [portraitWidth, portraitHeight] = PAGE_SIZES[pageSize];
68
+ const landscape = orientation === "landscape" || orientation === "auto" && imageWidth > imageHeight;
69
+ const pageWidth = landscape ? portraitHeight : portraitWidth;
70
+ const pageHeight = landscape ? portraitWidth : portraitHeight;
71
+ const boxWidth = Math.max(1, pageWidth - safeMargin * 2);
72
+ const boxHeight = Math.max(1, pageHeight - safeMargin * 2);
73
+ const scale = Math.min(1, boxWidth / imageWidth, boxHeight / imageHeight);
74
+ const width = imageWidth * scale;
75
+ const height = imageHeight * scale;
76
+ return {
77
+ pageWidth,
78
+ pageHeight,
79
+ x: (pageWidth - width) / 2,
80
+ y: (pageHeight - height) / 2,
81
+ width,
82
+ height
83
+ };
84
+ }
85
+ async function imagesToPdf(images, options = {}) {
86
+ if (!images.length) {
87
+ throw new Error("Add at least one image.");
88
+ }
89
+ const doc = await PDFDocument.create();
90
+ for (const image of images) {
91
+ const kind = detectImageKind(image.bytes);
92
+ if (!kind) {
93
+ throw new Error(
94
+ `${image.name}: only PNG and JPG images can be embedded.`
95
+ );
96
+ }
97
+ let embedded;
98
+ try {
99
+ embedded = kind === "png" ? await doc.embedPng(image.bytes) : await doc.embedJpg(image.bytes);
100
+ } catch {
101
+ throw new Error(`${image.name}: this image could not be read.`);
102
+ }
103
+ const box = layoutImage(embedded.width, embedded.height, options);
104
+ const page = doc.addPage([box.pageWidth, box.pageHeight]);
105
+ page.drawImage(embedded, {
106
+ x: box.x,
107
+ y: box.y,
108
+ width: box.width,
109
+ height: box.height
110
+ });
111
+ }
112
+ if (options.title) doc.setTitle(options.title);
113
+ doc.setProducer(producerName());
114
+ doc.setCreationDate(/* @__PURE__ */ new Date());
115
+ return doc.save();
116
+ }
117
+
118
+ export { detectImageKind, getJpegOrientation, imagesToPdf, layoutImage };
119
+ //# sourceMappingURL=chunk-WEOPDD3P.js.map
120
+ //# sourceMappingURL=chunk-WEOPDD3P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/images/imagesToPdfCore.ts"],"names":[],"mappings":"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","file":"chunk-WEOPDD3P.js","sourcesContent":["import { PDFDocument } from \"pdf-lib\";\nimport { producerName } from \"../config\";\n\nexport type ImageKind = \"png\" | \"jpg\";\nexport type PageSizeOption = \"fit\" | \"a4\" | \"letter\";\nexport type OrientationOption = \"auto\" | \"portrait\" | \"landscape\";\n\nexport type ImageSource = { name: string; bytes: ArrayBuffer | Uint8Array };\n\nexport type ImagesToPdfOptions = {\n pageSize?: PageSizeOption;\n orientation?: OrientationOption;\n /** Margin in PDF points (1/72 inch). */\n margin?: number;\n title?: string;\n};\n\n// Portrait width x height in PDF points.\nexport const PAGE_SIZES: Record<\n Exclude<PageSizeOption, \"fit\">,\n [number, number]\n> = {\n a4: [595.28, 841.89],\n letter: [612, 792],\n};\n\nexport function detectImageKind(\n bytes: ArrayBuffer | Uint8Array,\n): ImageKind | null {\n const view = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);\n if (\n view.length >= 8 &&\n view[0] === 0x89 &&\n view[1] === 0x50 &&\n view[2] === 0x4e &&\n view[3] === 0x47\n ) {\n return \"png\";\n }\n if (\n view.length >= 3 &&\n view[0] === 0xff &&\n view[1] === 0xd8 &&\n view[2] === 0xff\n ) {\n return \"jpg\";\n }\n return null;\n}\n\n/**\n * Read the EXIF orientation (1-8) from a JPEG, or 1 when absent. Values other\n * than 1 mean viewers rotate/flip the photo, which pdf-lib does not do.\n */\nexport function getJpegOrientation(bytes: ArrayBuffer | Uint8Array) {\n const view = new DataView(\n bytes instanceof Uint8Array ? bytes.buffer : bytes,\n bytes instanceof Uint8Array ? bytes.byteOffset : 0,\n bytes.byteLength,\n );\n if (view.byteLength < 4 || view.getUint16(0) !== 0xffd8) return 1;\n\n let offset = 2;\n while (offset + 4 <= view.byteLength) {\n const marker = view.getUint16(offset);\n if ((marker & 0xff00) !== 0xff00 || marker === 0xffda) break;\n const length = view.getUint16(offset + 2);\n\n if (marker === 0xffe1 && view.getUint32(offset + 4) === 0x45786966) {\n const tiff = offset + 10;\n if (tiff + 8 > view.byteLength) return 1;\n const little = view.getUint16(tiff) === 0x4949;\n const ifd = tiff + view.getUint32(tiff + 4, little);\n if (ifd + 2 > view.byteLength) return 1;\n const entries = view.getUint16(ifd, little);\n for (let i = 0; i < entries; i += 1) {\n const entry = ifd + 2 + i * 12;\n if (entry + 12 > view.byteLength) return 1;\n if (view.getUint16(entry, little) === 0x0112) {\n const value = view.getUint16(entry + 8, little);\n return value >= 1 && value <= 8 ? value : 1;\n }\n }\n return 1;\n }\n offset += 2 + length;\n }\n return 1;\n}\n\n/**\n * Page size and image placement for one image. For \"fit\" the page wraps the\n * image (plus margin); otherwise the image is scaled down to fit and centred.\n */\nexport function layoutImage(\n imageWidth: number,\n imageHeight: number,\n {\n pageSize = \"a4\",\n orientation = \"auto\",\n margin = 0,\n }: ImagesToPdfOptions = {},\n) {\n const safeMargin = Math.max(0, margin);\n\n if (pageSize === \"fit\") {\n return {\n pageWidth: imageWidth + safeMargin * 2,\n pageHeight: imageHeight + safeMargin * 2,\n x: safeMargin,\n y: safeMargin,\n width: imageWidth,\n height: imageHeight,\n };\n }\n\n const [portraitWidth, portraitHeight] = PAGE_SIZES[pageSize];\n const landscape =\n orientation === \"landscape\" ||\n (orientation === \"auto\" && imageWidth > imageHeight);\n const pageWidth = landscape ? portraitHeight : portraitWidth;\n const pageHeight = landscape ? portraitWidth : portraitHeight;\n\n const boxWidth = Math.max(1, pageWidth - safeMargin * 2);\n const boxHeight = Math.max(1, pageHeight - safeMargin * 2);\n const scale = Math.min(1, boxWidth / imageWidth, boxHeight / imageHeight);\n const width = imageWidth * scale;\n const height = imageHeight * scale;\n\n return {\n pageWidth,\n pageHeight,\n x: (pageWidth - width) / 2,\n y: (pageHeight - height) / 2,\n width,\n height,\n };\n}\n\nexport async function imagesToPdf(\n images: ImageSource[],\n options: ImagesToPdfOptions = {},\n) {\n if (!images.length) {\n throw new Error(\"Add at least one image.\");\n }\n\n const doc = await PDFDocument.create();\n\n for (const image of images) {\n const kind = detectImageKind(image.bytes);\n if (!kind) {\n throw new Error(\n `${image.name}: only PNG and JPG images can be embedded.`,\n );\n }\n\n let embedded;\n try {\n embedded =\n kind === \"png\"\n ? await doc.embedPng(image.bytes)\n : await doc.embedJpg(image.bytes);\n } catch {\n throw new Error(`${image.name}: this image could not be read.`);\n }\n\n const box = layoutImage(embedded.width, embedded.height, options);\n const page = doc.addPage([box.pageWidth, box.pageHeight]);\n page.drawImage(embedded, {\n x: box.x,\n y: box.y,\n width: box.width,\n height: box.height,\n });\n }\n\n if (options.title) doc.setTitle(options.title);\n doc.setProducer(producerName());\n doc.setCreationDate(new Date());\n\n return doc.save();\n}\n"]}