@cerefox/memory 1.20.0 → 1.21.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.
@@ -0,0 +1,2 @@
1
+ import{n as e,r as t,t as n}from"./index-Dd1nIOAB.js";function r(r){let a=t(r,{extensions:[n()],mdastExtensions:[e()]});return i(a),a}function i(e){let t=new Map,n=e=>{if(e.type===`definition`&&!t.has(e.identifier.toLowerCase())&&t.set(e.identifier.toLowerCase(),e.url),`children`in e)for(let t of e.children)n(t)};n(e);let r=e=>{if(!(`children`in e))return;let n=e.children;n.forEach((e,i)=>{e.type===`linkReference`?n[i]={type:`link`,url:t.get(e.identifier.toLowerCase())??``,children:e.children}:e.type===`imageReference`&&(n[i]={type:`image`,url:t.get(e.identifier.toLowerCase())??``,alt:e.alt}),r(n[i])})};r(e)}function a(e){return/^(https?:|mailto:)/i.test(e.trim())?e.trim():null}function o(e,t){return`${e.replace(/\.(md|markdown|txt)$/i,``)||`document`}.${t}`}export{a as exportableUrl,r as parseMarkdown,o as withExtension};
2
+ //# sourceMappingURL=markdown-CsTKTR78.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-CsTKTR78.js","names":["gfmFromMarkdown","fromMarkdown","gfm","parseMarkdown","root","markdown","resolveReferences","urls","collect","node","child","rewrite","children","exportableUrl","url","withExtension","filename","ext"],"sources":["../../src/lib/export/markdown.ts"],"sourcesContent":["/**\n * Markdown → syntax tree, shared by the Word and PDF exports.\n *\n * The same parser family the page renders with (react-markdown + remark-gfm),\n * so a document exports with the structure it shows: GFM tables, task lists,\n * strikethrough, autolinks. Raw HTML is kept as text, never interpreted.\n */\n\nimport type { Nodes, Root } from \"mdast\";\nimport { fromMarkdown } from \"mdast-util-from-markdown\";\nimport { gfmFromMarkdown } from \"mdast-util-gfm\";\nimport { gfm } from \"micromark-extension-gfm\";\n\nexport function parseMarkdown(markdown: string): Root {\n const root = fromMarkdown(markdown, {\n extensions: [gfm()],\n mdastExtensions: [gfmFromMarkdown()],\n });\n resolveReferences(root);\n return root;\n}\n\n/**\n * Turn reference-style links and images (`[text][id]`, `![alt][id]` with a\n * `[id]: url` definition elsewhere) into plain links and images, so the\n * converters handle one form and neither the target nor the alt text is lost.\n */\nfunction resolveReferences(root: Root): void {\n const urls = new Map<string, string>();\n const collect = (node: Nodes) => {\n // The first definition of a label wins, as in CommonMark.\n if (node.type === \"definition\" && !urls.has(node.identifier.toLowerCase())) {\n urls.set(node.identifier.toLowerCase(), node.url);\n }\n if (\"children\" in node) for (const child of node.children) collect(child);\n };\n collect(root);\n\n const rewrite = (node: Nodes) => {\n if (!(\"children\" in node)) return;\n const children = node.children as Nodes[];\n children.forEach((child, i) => {\n if (child.type === \"linkReference\") {\n children[i] = { type: \"link\", url: urls.get(child.identifier.toLowerCase()) ?? \"\", children: child.children };\n } else if (child.type === \"imageReference\") {\n children[i] = { type: \"image\", url: urls.get(child.identifier.toLowerCase()) ?? \"\", alt: child.alt };\n }\n rewrite(children[i]);\n });\n };\n rewrite(root);\n}\n\n/**\n * The link targets an export may keep: absolute web and mail links. A relative\n * link (an `/api/v1/…` path, a `#anchor`) points at nothing once the file\n * leaves this server, and a `javascript:` link has no business in a document.\n */\nexport function exportableUrl(url: string): string | null {\n return /^(https?:|mailto:)/i.test(url.trim()) ? url.trim() : null;\n}\n\n/** `notes.md` → `notes.docx`; a name with no extension gets one. */\nexport function withExtension(filename: string, ext: string): string {\n const stem = filename.replace(/\\.(md|markdown|txt)$/i, \"\");\n return `${stem || \"document\"}.${ext}`;\n}\n"],"mappings":"A,sDAaA,SAAgBG,EAAc,EAAwB,CACpD,IAAMC,EAAOH,EAAaI,EAAU,CAClC,WAAY,CAACH,EAAI,CAAC,EAClB,gBAAiB,CAACF,EAAgB,CAAC,CACrC,CAAC,EAED,OADAM,EAAkBF,CAAI,EACfA,CACT,CAOA,SAASE,EAAkB,EAAkB,CAC3C,IAAMC,EAAO,IAAI,IACXC,EAAW,GAAgB,CAK/B,GAHIC,EAAK,OAAS,cAAgB,CAACF,EAAK,IAAIE,EAAK,WAAW,YAAY,CAAC,GACvEF,EAAK,IAAIE,EAAK,WAAW,YAAY,EAAGA,EAAK,GAAG,EAE9C,aAAcA,EAAM,IAAK,IAAMC,KAASD,EAAK,SAAUD,EAAQE,CAAK,CAC1E,EACAF,EAAQJ,CAAI,EAEZ,IAAMO,EAAW,GAAgB,CAC/B,GAAI,EAAE,aAAcF,GAAO,OAC3B,IAAMG,EAAWH,EAAK,SACtBG,EAAS,SAAS,EAAO,IAAM,CACzBF,EAAM,OAAS,gBACjB,EAAS,GAAK,CAAE,KAAM,OAAQ,IAAKH,EAAK,IAAIG,EAAM,WAAW,YAAY,CAAC,GAAK,GAAI,SAAUA,EAAM,QAAS,EACnGA,EAAM,OAAS,mBACxB,EAAS,GAAK,CAAE,KAAM,QAAS,IAAKH,EAAK,IAAIG,EAAM,WAAW,YAAY,CAAC,GAAK,GAAI,IAAKA,EAAM,GAAI,GAErGC,EAAQC,EAAS,EAAE,CACrB,CAAC,CACH,EACAD,EAAQP,CAAI,CACd,CAOA,SAAgBS,EAAc,EAA4B,CACxD,MAAO,sBAAsB,KAAKC,EAAI,KAAK,CAAC,EAAIA,EAAI,KAAK,EAAI,IAC/D,CAGA,SAAgBC,EAAc,EAAkB,EAAqB,CAEnE,MAAO,GADMC,EAAS,QAAQ,wBAAyB,EAC7C,GAAQ,WAAW,GAAGC,GAClC,C"}
@@ -0,0 +1,7 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/pdfmake-L7DGtDcB.js","assets/rolldown-runtime-COiEfhsA.js","assets/vfs_fonts-D9BViC6C.js","assets/Courier-BRJ-B_ND.js"])))=>i.map(i=>d[i]);
2
+ import{i as e}from"./rolldown-runtime-COiEfhsA.js";import{i as t}from"./index-Dd1nIOAB.js";import{exportableUrl as n,parseMarkdown as r}from"./markdown-CsTKTR78.js";var i=`#f2f2f2`,a=515,o=16,s=24;function c(e,t){let n=499-t;return Math.max(16,Math.floor(n/(u(e).font?5.5:7.8)))}function l(e,t){return e.split(`
3
+ `).map(e=>{let n=Array.from(e);if(n.length<=t)return e;let r=[];for(let e=0;e<n.length;e+=t)r.push(n.slice(e,e+t).join(``));return r.join(`
4
+ `)}).join(`
5
+ `)}function u(e){return/^[\t\n\r\x20-\x7e\xa0-\xff]*$/.test(e)?{font:`Courier`}:{}}var d=`#bbbbbb`;function f(e,t={}){let r=[];for(let a of e)switch(a.type){case`text`:r.push({text:a.value.replace(/\n/g,` `),...t});break;case`strong`:r.push(...f(a.children,{...t,bold:!0}));break;case`emphasis`:r.push(...f(a.children,{...t,italics:!0}));break;case`delete`:r.push(...f(a.children,{...t,decoration:`lineThrough`}));break;case`inlineCode`:r.push({text:a.value,...t,...u(a.value),background:i,fontSize:9.5,preserveLeadingSpaces:!0});break;case`break`:r.push({text:`
6
+ `});break;case`link`:{let e=n(a.url),i=f(a.children,t);e?r.push({text:i.length?i:e,link:e,color:`#1a5fb4`,decoration:`underline`}):r.push(...i);break}case`image`:r.push({text:`[image${a.alt?`: ${a.alt}`:``}]`,...t,italics:!0});break;case`html`:r.push({text:a.value,...t});break;case`footnoteReference`:r.push({text:`[^${a.identifier}]`,...t,sup:!0});break;default:`children`in a?r.push(...f(a.children,t)):`value`in a&&r.push({text:String(a.value),...t})}return r}function p(e,t=0){let n=[];for(let r of e)switch(r.type){case`heading`:n.push({text:f(r.children),style:`h${r.depth}`});break;case`paragraph`:n.push({text:f(r.children),style:`p`});break;case`blockquote`:n.push({table:{widths:[`*`],body:[[{stack:p(r.children,t+o),italics:!0,color:`#555555`}]]},layout:{hLineWidth:()=>0,vLineWidth:e=>e===0?2:0,vLineColor:()=>d,paddingLeft:()=>10},margin:[0,2,0,8]});break;case`code`:n.push({table:{widths:[`*`],body:[[{text:l(r.value,c(r.value,t)),...u(r.value),fontSize:9,preserveLeadingSpaces:!0,lineHeight:1.3}]]},layout:{hLineWidth:()=>0,vLineWidth:()=>0,fillColor:()=>i,paddingLeft:()=>8,paddingRight:()=>8,paddingTop:()=>6,paddingBottom:()=>6},margin:[0,2,0,8]});break;case`list`:n.push(m(r,t));break;case`table`:n.push(h(r));break;case`thematicBreak`:n.push({canvas:[{type:`line`,x1:0,y1:0,x2:a-t,y2:0,lineWidth:.5,lineColor:d}],margin:[0,6,0,10]});break;case`html`:n.push({text:r.value,style:`p`,fontSize:9,preserveLeadingSpaces:!0});break;case`footnoteDefinition`:n.push({stack:[{text:`[^${r.identifier}]`,sup:!0},...p(r.children,t)],fontSize:9})}return n}function m(e,t){let n=e.children.map(e=>{let n=e.checked===!0?`[x] `:e.checked===!1?`[ ] `:``,[r,...i]=e.children,a=r&&r.type===`paragraph`?{text:[n,...f(r.children)],margin:[0,0,0,2]}:{text:n},o=t+s,c=r&&r.type===`paragraph`?p(i,o):p(e.children,o);return c.length?{stack:[a,...c]}:a});return e.ordered?{ol:n,start:e.start??1,margin:[0,0,0,8]}:{ul:n,margin:[0,0,0,8]}}function h(e){let t=Math.max(1,...e.children.map(e=>e.children.length)),n=e.align??[],r=e=>n[e]===`center`?`center`:n[e]===`right`?`right`:`left`;return{table:{headerRows:1,widths:Array.from({length:t},()=>`*`),body:e.children.map((e,n)=>Array.from({length:t},(t,i)=>{let a=e.children[i];return{text:a?f(a.children,n===0?{bold:!0}:{}):``,alignment:r(i),fillColor:n===0?`#ededed`:void 0}}))},layout:`lightHorizontalLines`,margin:[0,2,0,10]}}function g(e,t){let n=p(r(e).children);return{info:{title:t,creator:`Cerefox`,producer:`Cerefox`},pageSize:`A4`,pageMargins:[40,48,40,48],content:n.length?n:[{text:``}],defaultStyle:{font:`Roboto`,fontSize:10.5,lineHeight:1.25},styles:{p:{margin:[0,0,0,7]},h1:{fontSize:20,bold:!0,margin:[0,10,0,8]},h2:{fontSize:16,bold:!0,margin:[0,10,0,6]},h3:{fontSize:13.5,bold:!0,margin:[0,8,0,5]},h4:{fontSize:12,bold:!0,margin:[0,6,0,4]},h5:{fontSize:11,bold:!0,margin:[0,6,0,4]},h6:{fontSize:10.5,bold:!0,italics:!0,margin:[0,6,0,4]}},footer:(e,t)=>({text:`${e} / ${t}`,alignment:`center`,fontSize:8,color:`#888888`,margin:[0,16,0,0]})}}async function _(n,r){let[{default:i},{default:a},{default:o}]=await Promise.all([t(()=>import(`./pdfmake-L7DGtDcB.js`).then(t=>e(t.default,1)),__vite__mapDeps([0,1])),t(()=>import(`./vfs_fonts-D9BViC6C.js`).then(t=>e(t.default,1)),__vite__mapDeps([2,1])),t(()=>import(`./Courier-BRJ-B_ND.js`).then(t=>e(t.default,1)),__vite__mapDeps([3,1]))]);return i.addVirtualFileSystem(a),i.addFontContainer(o),i.setFonts({Roboto:{normal:`Roboto-Regular.ttf`,bold:`Roboto-Medium.ttf`,italics:`Roboto-Italic.ttf`,bolditalics:`Roboto-MediumItalic.ttf`},Courier:{normal:`Courier`,bold:`Courier-Bold`,italics:`Courier-Oblique`,bolditalics:`Courier-BoldOblique`}}),i.createPdf(g(n,r)).getBlob()}export{_ as markdownToPdf};
7
+ //# sourceMappingURL=pdf-CkRjSAWX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"mappings":"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","names":["CODE_FILL","CONTENT_WIDTH","QUOTE_INSET","LIST_INSET","codeColumns","width","inset","codeFont","text","wrapCode","chars","line","columns","parts","i","RULE","inline","out","node","nodes","marks","url","exportableUrl","children","blocks","list","table","items","marker","item","first","rest","head","nested","tail","row","align","alignment","cell","r","markdownToPdfDefinition","content","parseMarkdown","markdown","page","pages","markdownToPdf","pdfMake","vfs","courier","__vitePreload","__toESM","m","title"],"ignoreList":[],"sources":["../../src/lib/export/pdf.ts"],"sourcesContent":["/**\n * Markdown → PDF, in the browser, with pdfmake.\n *\n * Loaded on demand (`api/documents.ts` imports it dynamically): pdfmake and its\n * embedded Roboto font are about 2 MB, which the app does not pay on first\n * load. The definition builder ({@link markdownToPdfDefinition}) is a pure\n * function, tested without a browser; only {@link markdownToPdf} needs pdfmake.\n *\n * Roboto covers Latin, Greek and Cyrillic. Characters outside it (CJK, emoji)\n * print as blanks: the Word export keeps them, since Word picks its own fonts.\n * Code is set in Courier, one of the PDF standard fonts (nothing embedded),\n * when it fits Courier's Latin-1 range; anything else stays in Roboto, so a\n * Greek comment or an arrow in a code block still prints.\n */\n\nimport type { Content, ContentText, TDocumentDefinitions } from \"pdfmake/interfaces\";\nimport type { List, PhrasingContent, RootContent, Table as MdTable } from \"mdast\";\n\nimport { exportableUrl, parseMarkdown } from \"./markdown\";\n\nconst CODE_FILL = \"#f2f2f2\";\n\n/** A4 width minus the page margins, in points. */\nconst CONTENT_WIDTH = 515;\n/** What a blockquote's bar and padding take from the width inside it. */\nconst QUOTE_INSET = 16;\n/** What a list's marker column takes from the width of its nested blocks. */\nconst LIST_INSET = 24;\n\n/**\n * How many characters of 9 pt code fit on a line `inset` points in from the\n * margin: Courier is 5.4 pt per character (5.5 for slack); for Roboto, 7.8 is\n * about its widest common glyph, so the wrap is conservative, never short.\n */\nexport function codeColumns(text: string, inset: number): number {\n const width = CONTENT_WIDTH - 16 - inset; // 16: the code block's own padding\n return Math.max(16, Math.floor(width / (codeFont(text).font ? 5.5 : 7.8)));\n}\n\n/**\n * Hard-wrap code lines that cannot fit. pdfmake breaks lines only at spaces,\n * so a long unbroken token (a hash, a URL, minified code) ran off the page\n * and was clipped; {@link codeColumns} gives the width at that nesting depth.\n */\nexport function wrapCode(text: string, columns: number): string {\n return text\n .split(\"\\n\")\n .map((line) => {\n const chars = Array.from(line);\n if (chars.length <= columns) return line;\n const parts: string[] = [];\n for (let i = 0; i < chars.length; i += columns) parts.push(chars.slice(i, i + columns).join(\"\"));\n return parts.join(\"\\n\");\n })\n .join(\"\\n\");\n}\n\n/** Courier when every character is in its Latin-1 range; otherwise Roboto. */\nexport function codeFont(text: string): { font?: string } {\n return /^[\\t\\n\\r\\x20-\\x7e\\xa0-\\xff]*$/.test(text) ? { font: \"Courier\" } : {};\n}\nconst RULE = \"#bbbbbb\";\n\ninterface Marks {\n bold?: boolean;\n italics?: boolean;\n decoration?: \"lineThrough\";\n}\n\ntype Inline = string | ContentText;\n\nfunction inline(nodes: PhrasingContent[], marks: Marks = {}): Inline[] {\n const out: Inline[] = [];\n for (const node of nodes) {\n switch (node.type) {\n case \"text\":\n // A newline inside a paragraph is a soft break: a space, not a new line.\n out.push({ text: node.value.replace(/\\n/g, \" \"), ...marks });\n break;\n case \"strong\":\n out.push(...inline(node.children, { ...marks, bold: true }));\n break;\n case \"emphasis\":\n out.push(...inline(node.children, { ...marks, italics: true }));\n break;\n case \"delete\":\n out.push(...inline(node.children, { ...marks, decoration: \"lineThrough\" }));\n break;\n case \"inlineCode\":\n out.push({ text: node.value, ...marks, ...codeFont(node.value), background: CODE_FILL, fontSize: 9.5, preserveLeadingSpaces: true });\n break;\n case \"break\":\n out.push({ text: \"\\n\" });\n break;\n case \"link\": {\n const url = exportableUrl(node.url);\n const children = inline(node.children, marks);\n if (url) {\n out.push({ text: children.length ? children : url, link: url, color: \"#1a5fb4\", decoration: \"underline\" });\n } else {\n out.push(...children);\n }\n break;\n }\n case \"image\":\n out.push({ text: `[image${node.alt ? `: ${node.alt}` : \"\"}]`, ...marks, italics: true });\n break;\n case \"html\":\n out.push({ text: node.value, ...marks });\n break;\n case \"footnoteReference\":\n out.push({ text: `[^${node.identifier}]`, ...marks, sup: true });\n break;\n default:\n if (\"children\" in node) out.push(...inline(node.children as PhrasingContent[], marks));\n else if (\"value\" in node) out.push({ text: String(node.value), ...marks });\n }\n }\n return out;\n}\n\n/** `inset`: points already taken from the left by enclosing quotes and lists. */\nfunction blocks(nodes: RootContent[], inset = 0): Content[] {\n const out: Content[] = [];\n for (const node of nodes) {\n switch (node.type) {\n case \"heading\":\n out.push({ text: inline(node.children), style: `h${node.depth}` });\n break;\n case \"paragraph\":\n out.push({ text: inline(node.children), style: \"p\" });\n break;\n case \"blockquote\":\n out.push({\n table: {\n widths: [\"*\"],\n body: [[{ stack: blocks(node.children, inset + QUOTE_INSET), italics: true, color: \"#555555\" }]],\n },\n layout: {\n hLineWidth: () => 0,\n vLineWidth: (i: number) => (i === 0 ? 2 : 0),\n vLineColor: () => RULE,\n paddingLeft: () => 10,\n },\n margin: [0, 2, 0, 8],\n });\n break;\n case \"code\":\n out.push({\n table: {\n widths: [\"*\"],\n body: [\n [\n {\n text: wrapCode(node.value, codeColumns(node.value, inset)),\n ...codeFont(node.value),\n fontSize: 9,\n preserveLeadingSpaces: true,\n lineHeight: 1.3,\n },\n ],\n ],\n },\n layout: {\n hLineWidth: () => 0,\n vLineWidth: () => 0,\n fillColor: () => CODE_FILL,\n paddingLeft: () => 8,\n paddingRight: () => 8,\n paddingTop: () => 6,\n paddingBottom: () => 6,\n },\n margin: [0, 2, 0, 8],\n });\n break;\n case \"list\":\n out.push(list(node, inset));\n break;\n case \"table\":\n out.push(table(node));\n break;\n case \"thematicBreak\":\n out.push({\n canvas: [{ type: \"line\", x1: 0, y1: 0, x2: CONTENT_WIDTH - inset, y2: 0, lineWidth: 0.5, lineColor: RULE }],\n margin: [0, 6, 0, 10],\n });\n break;\n case \"html\":\n out.push({ text: node.value, style: \"p\", fontSize: 9, preserveLeadingSpaces: true });\n break;\n case \"footnoteDefinition\":\n out.push({ stack: [{ text: `[^${node.identifier}]`, sup: true }, ...blocks(node.children, inset)], fontSize: 9 });\n break;\n default:\n break;\n }\n }\n return out;\n}\n\nfunction list(node: List, inset: number): Content {\n const items: Content[] = node.children.map((item) => {\n const marker = item.checked === true ? \"[x] \" : item.checked === false ? \"[ ] \" : \"\";\n const [first, ...rest] = item.children;\n const head: Content =\n first && first.type === \"paragraph\"\n ? { text: [marker, ...inline(first.children)], margin: [0, 0, 0, 2] }\n : { text: marker };\n const nested = inset + LIST_INSET;\n const tail = first && first.type === \"paragraph\" ? blocks(rest, nested) : blocks(item.children, nested);\n return tail.length ? { stack: [head, ...tail] } : head;\n });\n return node.ordered\n ? { ol: items, start: node.start ?? 1, margin: [0, 0, 0, 8] }\n : { ul: items, margin: [0, 0, 0, 8] };\n}\n\nfunction table(node: MdTable): Content {\n const columns = Math.max(1, ...node.children.map((row) => row.children.length));\n const align = node.align ?? [];\n const alignment = (i: number) => (align[i] === \"center\" ? \"center\" : align[i] === \"right\" ? \"right\" : \"left\");\n return {\n table: {\n headerRows: 1,\n widths: Array.from({ length: columns }, () => \"*\"),\n body: node.children.map((row, r) =>\n Array.from({ length: columns }, (_, i) => {\n const cell = row.children[i];\n return {\n text: cell ? inline(cell.children, r === 0 ? { bold: true } : {}) : \"\",\n alignment: alignment(i),\n fillColor: r === 0 ? \"#ededed\" : undefined,\n };\n }),\n ),\n },\n layout: \"lightHorizontalLines\",\n margin: [0, 2, 0, 10],\n };\n}\n\nexport function markdownToPdfDefinition(markdown: string, title: string): TDocumentDefinitions {\n const content = blocks(parseMarkdown(markdown).children);\n return {\n info: { title, creator: \"Cerefox\", producer: \"Cerefox\" },\n pageSize: \"A4\",\n pageMargins: [40, 48, 40, 48],\n content: content.length ? content : [{ text: \"\" }],\n defaultStyle: { font: \"Roboto\", fontSize: 10.5, lineHeight: 1.25 },\n styles: {\n p: { margin: [0, 0, 0, 7] },\n h1: { fontSize: 20, bold: true, margin: [0, 10, 0, 8] },\n h2: { fontSize: 16, bold: true, margin: [0, 10, 0, 6] },\n h3: { fontSize: 13.5, bold: true, margin: [0, 8, 0, 5] },\n h4: { fontSize: 12, bold: true, margin: [0, 6, 0, 4] },\n h5: { fontSize: 11, bold: true, margin: [0, 6, 0, 4] },\n h6: { fontSize: 10.5, bold: true, italics: true, margin: [0, 6, 0, 4] },\n },\n footer: (page: number, pages: number) => ({\n text: `${page} / ${pages}`,\n alignment: \"center\",\n fontSize: 8,\n color: \"#888888\",\n margin: [0, 16, 0, 0],\n }),\n };\n}\n\nexport async function markdownToPdf(markdown: string, title: string): Promise<Blob> {\n const [{ default: pdfMake }, { default: vfs }, { default: courier }] = await Promise.all([\n import(\"pdfmake/build/pdfmake\"),\n import(\"pdfmake/build/vfs_fonts\"),\n import(\"pdfmake/build/standard-fonts/Courier\"),\n ]);\n pdfMake.addVirtualFileSystem(vfs);\n pdfMake.addFontContainer(courier);\n pdfMake.setFonts({\n Roboto: {\n normal: \"Roboto-Regular.ttf\",\n bold: \"Roboto-Medium.ttf\",\n italics: \"Roboto-Italic.ttf\",\n bolditalics: \"Roboto-MediumItalic.ttf\",\n },\n Courier: {\n normal: \"Courier\",\n bold: \"Courier-Bold\",\n italics: \"Courier-Oblique\",\n bolditalics: \"Courier-BoldOblique\",\n },\n });\n return pdfMake.createPdf(markdownToPdfDefinition(markdown, title)).getBlob();\n}\n"],"file":"pdf-CkRjSAWX.js"}