@shad0wz7/nestjs-pdf 3.2.0 → 5.0.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["BrowserType"],"sources":["../src/exceptions/nestjs-pdf.exception.ts","../src/exceptions/browser-installation.exception.ts","../src/exceptions/browser-unavailable.exception.ts","../src/exceptions/engine-not-available.exception.ts","../src/exceptions/pdf-generation.exception.ts","../src/exceptions/signature-dependency.exception.ts","../src/exceptions/signature-placement.exception.ts","../src/exceptions/template-configuration.exception.ts","../src/exceptions/template-render.exception.ts","../src/exceptions/watermark.exception.ts","../src/helpers/getRelativePath.helper.ts","../src/helpers/signature.helper.ts","../src/helpers/watermark.helper.ts","../node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js","../node_modules/.pnpm/p-limit@7.3.2/node_modules/p-limit/index.js","../src/helpers/deepMergePdfparams.ts","../src/helpers/request-guard.helper.ts","../src/helpers/tokens.ts","../src/puppeteer/browser/browser.service.ts","../src/puppeteer/engines/ejs/ejs.service.ts","../src/puppeteer/engines/eta/eta.service.ts","../src/puppeteer/engines/handlebars/handlebars.service.ts","../src/puppeteer/engines/mjml/mjml.service.ts","../src/puppeteer/engines/mustache/mustache.service.ts","../src/puppeteer/engines/nunjucks/nunjucks.service.ts","../src/puppeteer/engines/pug/pug.service.ts","../src/puppeteer/libs/requireService.utils.ts","../src/puppeteer/puppeteer.service.ts","../src/nestjs-pdf.service.ts","../src/puppeteer/puppeteer.module.ts","../src/nestjs-pdf.module.ts"],"sourcesContent":["export enum NestjsPdfErrorCode {\n ENGINE_NOT_AVAILABLE = 'ENGINE_NOT_AVAILABLE',\n TEMPLATE_CONFIGURATION_ERROR = 'TEMPLATE_CONFIGURATION_ERROR',\n TEMPLATE_RENDER_ERROR = 'TEMPLATE_RENDER_ERROR',\n BROWSER_INSTALLATION_ERROR = 'BROWSER_INSTALLATION_ERROR',\n BROWSER_UNAVAILABLE = 'BROWSER_UNAVAILABLE',\n PDF_GENERATION_ERROR = 'PDF_GENERATION_ERROR',\n SIGNATURE_DEPENDENCY_ERROR = 'SIGNATURE_DEPENDENCY_ERROR',\n SIGNATURE_PLACEMENT_ERROR = 'SIGNATURE_PLACEMENT_ERROR',\n WATERMARK_ERROR = 'WATERMARK_ERROR',\n}\n\nexport abstract class NestjsPdfException extends Error {\n abstract readonly code: NestjsPdfErrorCode;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = this.constructor.name;\n }\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class BrowserInstallationException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.BROWSER_INSTALLATION_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class BrowserUnavailableException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.BROWSER_UNAVAILABLE;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class EngineNotAvailableException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.ENGINE_NOT_AVAILABLE;\n\n constructor(engineName: string) {\n super(\n `${engineName} service is not available. If the problem persists, open an issue in the repo.`,\n );\n }\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class PdfGenerationException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.PDF_GENERATION_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class SignatureDependencyException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.SIGNATURE_DEPENDENCY_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class SignaturePlacementException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.SIGNATURE_PLACEMENT_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class TemplateConfigurationException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.TEMPLATE_CONFIGURATION_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class TemplateRenderException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.TEMPLATE_RENDER_ERROR;\n\n constructor(\n public readonly engine: string,\n message: string,\n options?: { cause?: unknown },\n ) {\n super(message, options);\n }\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class WatermarkException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.WATERMARK_ERROR;\n}\n","import { relative, resolve } from 'node:path';\n\n/**\n * Get the relative path to a value from the module directory.\n * @param moduleDir the path of the module, typically __dirname\n * @param relativeToModule the path to the value relative to the module directory\n * @returns the relative path from the current working directory to the value\n * @example\n * getRelativePathToValue(__dirname, './templates/my-template.hbs');\n * // returns 'context/pdf/templates/my-template.hbs' if the current working directory is '/\n */\nexport function getRelativePathToValue(\n moduleDir: string,\n relativeToModule: string,\n): string {\n const fullTemplatePath = resolve(moduleDir, relativeToModule);\n return relative(process.cwd(), fullTemplatePath);\n}\n","import {\n PDFArray,\n PDFDict,\n PDFDocument,\n PDFName,\n PDFNumber,\n PDFString,\n} from 'pdf-lib';\nimport type { TextItem } from 'pdfjs-dist/types/src/display/api';\n\nimport {\n SignatureDependencyException,\n SignaturePlacementException,\n} from '../exceptions';\n\n// eslint-disable-next-line @typescript-eslint/consistent-type-imports\nlet pdfjsPromise: typeof import('pdfjs-dist/legacy/build/pdf.mjs') | undefined;\n\nasync function loadPdfjs() {\n if (!pdfjsPromise) {\n try {\n pdfjsPromise = await import('pdfjs-dist/legacy/build/pdf.mjs');\n } catch (error) {\n pdfjsPromise = undefined;\n /* v8 ignore next -- import() rejections are always Error instances in practice */\n const reason = error instanceof Error ? error.message : String(error);\n throw new SignatureDependencyException(\n [\n 'Failed to load pdfjs-dist.',\n 'If you use anchor-based signature placement in Node.js, make sure @napi-rs/canvas is installed.',\n 'Try: npm install @napi-rs/canvas',\n '',\n `Original error: ${reason}`,\n ].join('\\n'),\n { cause: error },\n );\n }\n }\n return pdfjsPromise;\n}\n\nfunction toU8(input: Uint8Array | Buffer): Uint8Array {\n return new Uint8Array(input);\n}\n\nasync function findAnchorPosition(\n pdfBytes: Uint8Array,\n anchorText: string,\n): Promise<null | {\n pageIndex: number;\n x: number;\n y: number;\n pageWidth: number;\n pageHeight: number;\n}> {\n const pdfjsLib = await loadPdfjs();\n const loadingTask = pdfjsLib.getDocument({ data: pdfBytes });\n\n try {\n const pdf = await loadingTask.promise;\n\n for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\n const page = await pdf.getPage(pageNum);\n const viewport = page.getViewport({ scale: 1 });\n const textContent = await page.getTextContent();\n\n for (const itemRaw of textContent.items) {\n const item = itemRaw as TextItem;\n const str = item.str;\n if (!str?.includes(anchorText)) continue;\n\n const t = pdfjsLib.Util.transform(viewport.transform, item.transform);\n const [_a, _b, _c, _d, e, f] = t as Array<number>;\n\n const x = e;\n const y = viewport.height - f;\n\n return {\n pageIndex: pageNum - 1,\n x,\n y,\n pageWidth: viewport.width,\n pageHeight: viewport.height,\n };\n }\n }\n return null;\n } finally {\n await loadingTask.destroy();\n }\n}\n\nfunction addSignatureFieldAt(\n pdfDoc: PDFDocument,\n pageIndex: number,\n opts: {\n fieldName: string;\n x: number;\n y: number;\n width: number;\n height: number;\n },\n) {\n const { fieldName, x, y, width, height } = opts;\n const context = pdfDoc.context;\n\n const page = pdfDoc.getPages()[pageIndex];\n\n const rectArray = context.obj([\n PDFNumber.of(x),\n PDFNumber.of(y),\n PDFNumber.of(x + width),\n PDFNumber.of(y + height),\n ]);\n\n const widgetDict = context.obj({\n Type: PDFName.of('Annot'),\n Subtype: PDFName.of('Widget'),\n Rect: rectArray,\n F: PDFNumber.of(4),\n P: page.ref,\n });\n const widgetRef = context.register(widgetDict);\n\n const fieldDict = context.obj({\n FT: PDFName.of('Sig'),\n T: PDFString.of(fieldName),\n Ff: PDFNumber.of(0),\n Kids: context.obj([widgetRef]),\n });\n const fieldRef = context.register(fieldDict);\n\n widgetDict.set(PDFName.of('Parent'), fieldRef);\n\n let annots = page.node.lookupMaybe(PDFName.of('Annots'), PDFArray);\n if (!annots) {\n annots = context.obj([]);\n page.node.set(PDFName.of('Annots'), annots);\n }\n annots.push(widgetRef);\n\n let acroForm = pdfDoc.catalog.lookupMaybe(PDFName.of('AcroForm'), PDFDict);\n if (!acroForm) {\n acroForm = context.obj({\n Fields: context.obj([]),\n SigFlags: PDFNumber.of(3),\n });\n const acroFormRef = context.register(acroForm);\n pdfDoc.catalog.set(PDFName.of('AcroForm'), acroFormRef);\n }\n\n let fields = acroForm.lookupMaybe(PDFName.of('Fields'), PDFArray);\n if (!fields) {\n fields = context.obj([]);\n acroForm.set(PDFName.of('Fields'), fields);\n }\n fields.push(fieldRef);\n\n return { fieldRef, widgetRef };\n}\n\nexport async function addSignatureFieldUsingAnchor(\n pdf: Uint8Array | Buffer,\n fieldName = 'SignatureDebtor',\n anchorText = '__SIG_DEBTOR_ANCHOR__',\n) {\n const bytes = toU8(pdf);\n\n const anchor = await findAnchorPosition(bytes.slice(), anchorText);\n\n const pdfDoc = await PDFDocument.load(bytes);\n\n const sigWidth = 240;\n const sigHeight = 50;\n\n if (anchor) {\n const pageIndex = anchor.pageIndex;\n const page = pdfDoc.getPages()[pageIndex];\n if (!page) {\n throw new SignaturePlacementException(`Page ${pageIndex} not found`);\n }\n const { width: pw, height: ph } = page.getSize();\n\n const padX = 40;\n const padY = 7;\n let x = anchor.x - sigWidth / 2 + padX;\n\n let y = anchor.y - sigHeight + padY;\n\n const margin = 10;\n\n x = Math.max(margin, Math.min(x, pw - sigWidth - margin));\n y = Math.max(margin, Math.min(y, ph - sigHeight - margin));\n\n addSignatureFieldAt(pdfDoc, anchor.pageIndex, {\n fieldName,\n x,\n y,\n width: sigWidth,\n height: sigHeight,\n });\n } else {\n const pages = pdfDoc.getPages();\n const pageIndex = pages.length - 1;\n const page = pages.at(-1);\n /* v8 ignore next -- pdf-lib always produces at least one page on save/load; only a hand-crafted, malformed PDF could hit this */\n if (!page) {\n throw new SignaturePlacementException(`Page ${pageIndex} not found`);\n }\n const { width: pageWidth } = page.getSize();\n const x = (pageWidth - sigWidth) / 2;\n const y = 90;\n\n addSignatureFieldAt(pdfDoc, pageIndex, {\n fieldName,\n x,\n y,\n width: sigWidth,\n height: sigHeight,\n });\n }\n\n return await pdfDoc.save();\n}\n\n// Test helper to inject a mocked pdfjs implementation and avoid dynamic import in tests\n// This helper throws outside of tests to avoid exposing a test-only API in production.\nexport function __setPdfjsForTests(p: any) {\n if (process.env.NODE_ENV !== 'test') {\n throw new Error('__setPdfjsForTests is only available in test environment');\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n pdfjsPromise = p;\n}\n","import {\n degrees,\n PDFDocument,\n type PDFImage,\n type PDFPage,\n rgb,\n StandardFonts,\n} from 'pdf-lib';\n\nimport { WatermarkException } from '../exceptions';\n\nexport interface WatermarkOptions {\n /** Text to stamp. At least one of `text` or `image` is required. */\n text?: string;\n /** PNG or JPEG bytes to stamp. At least one of `text` or `image` is required. */\n image?: Uint8Array | Buffer;\n /** Opacity between 0 (invisible) and 1 (opaque). Default: 0.15 */\n opacity?: number;\n /** Counter-clockwise rotation in degrees. Default: 45 */\n rotation?: number;\n /** Text font size in points. Default: 60 */\n fontSize?: number;\n /** One of the PDF standard fonts (WinAnsi characters only). Default: 'HelveticaBold' */\n font?: keyof typeof StandardFonts;\n /** Text color as `#rgb` or `#rrggbb`. Default: '#808080' */\n color?: string;\n /** Rendered image width in points (aspect ratio preserved). Default: 50% of the page width */\n imageWidth?: number;\n /** `center` stamps once per page, `tile` repeats the mark across the page. Default: 'center' */\n position?: 'center' | 'tile';\n /** Gap in points between two marks when `position` is `tile`. Default: 100 */\n tileSpacing?: number;\n /** 1-based page numbers to watermark. Default: all pages */\n pages?: Array<number>;\n}\n\nconst DEFAULT_OPACITY = 0.15;\nconst DEFAULT_ROTATION = 45;\nconst DEFAULT_FONT_SIZE = 60;\nconst DEFAULT_FONT: keyof typeof StandardFonts = 'HelveticaBold';\nconst DEFAULT_COLOR = '#808080';\nconst DEFAULT_TILE_SPACING = 100;\n\ninterface Mark {\n width: number;\n height: number;\n draw: (page: PDFPage, x: number, y: number) => void;\n}\n\nfunction parseHexColor(color: string) {\n const match = /^#([\\da-f]{3}|[\\da-f]{6})$/i.exec(color);\n if (!match) {\n throw new WatermarkException(\n `Invalid watermark color \"${color}\", expected #rgb or #rrggbb`,\n );\n }\n const hex =\n match[1].length === 3 ? [...match[1]].map((c) => c + c).join('') : match[1];\n const channel = (i: number) => Number.parseInt(hex.slice(i, i + 2), 16) / 255;\n return rgb(channel(0), channel(2), channel(4));\n}\n\nfunction embedImage(pdfDoc: PDFDocument, bytes: Uint8Array): Promise<PDFImage> {\n const isPng = bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4e;\n const isJpeg = bytes[0] === 0xff && bytes[1] === 0xd8;\n if (isPng) return pdfDoc.embedPng(bytes);\n if (isJpeg) return pdfDoc.embedJpg(bytes);\n throw new WatermarkException('Watermark image must be a PNG or JPEG');\n}\n\nfunction validate(options: WatermarkOptions) {\n const { text, image, opacity, fontSize, imageWidth, tileSpacing } = options;\n if (!text && !image) {\n throw new WatermarkException(\n 'A watermark requires at least a `text` or an `image`',\n );\n }\n if (opacity !== undefined && !(opacity >= 0 && opacity <= 1)) {\n throw new WatermarkException('Watermark `opacity` must be between 0 and 1');\n }\n if (fontSize !== undefined && !(fontSize > 0)) {\n throw new WatermarkException('Watermark `fontSize` must be greater than 0');\n }\n if (imageWidth !== undefined && !(imageWidth > 0)) {\n throw new WatermarkException(\n 'Watermark `imageWidth` must be greater than 0',\n );\n }\n if (tileSpacing !== undefined && !(tileSpacing >= 0)) {\n throw new WatermarkException('Watermark `tileSpacing` must be at least 0');\n }\n}\n\nfunction resolvePageIndexes(pages: Array<number> | undefined, total: number) {\n if (!pages) {\n return Array.from({ length: total }, (_, i) => i);\n }\n for (const page of pages) {\n if (!Number.isInteger(page) || page < 1 || page > total) {\n throw new WatermarkException(\n `Watermark page ${page} is out of range (the PDF has ${total} page(s))`,\n );\n }\n }\n return [...new Set(pages)].map((page) => page - 1);\n}\n\n/**\n * Centers of the marks for one page, in page coordinates. Tiles follow the\n * rotated axes so rotated marks never overlap each other.\n */\nfunction markCenters(\n pageWidth: number,\n pageHeight: number,\n mark: Mark,\n options: { position: 'center' | 'tile'; rotation: number; spacing: number },\n) {\n const cx = pageWidth / 2;\n const cy = pageHeight / 2;\n if (options.position === 'center') {\n return [{ x: cx, y: cy }];\n }\n\n const theta = (options.rotation * Math.PI) / 180;\n const cos = Math.cos(theta);\n const sin = Math.sin(theta);\n const stepX = mark.width + options.spacing;\n const stepY = mark.height + options.spacing;\n const reach = Math.hypot(mark.width, mark.height) / 2;\n const n = Math.ceil(\n (Math.hypot(pageWidth, pageHeight) / 2 + reach) / Math.min(stepX, stepY),\n );\n\n const centers: Array<{ x: number; y: number }> = [];\n for (let i = -n; i <= n; i++) {\n for (let j = -n; j <= n; j++) {\n const x = cx + i * stepX * cos - j * stepY * sin;\n const y = cy + i * stepX * sin + j * stepY * cos;\n if (\n x >= -reach &&\n x <= pageWidth + reach &&\n y >= -reach &&\n y <= pageHeight + reach\n ) {\n centers.push({ x, y });\n }\n }\n }\n return centers;\n}\n\nasync function buildMark(\n pdfDoc: PDFDocument,\n options: WatermarkOptions,\n pageWidth: number,\n): Promise<Mark> {\n const opacity = options.opacity ?? DEFAULT_OPACITY;\n const rotate = degrees(options.rotation ?? DEFAULT_ROTATION);\n\n if (options.image) {\n const image = await embedImage(pdfDoc, new Uint8Array(options.image));\n const width = options.imageWidth ?? pageWidth / 2;\n const height = (image.height / image.width) * width;\n return {\n width,\n height,\n draw: (page, x, y) =>\n page.drawImage(image, { x, y, width, height, opacity, rotate }),\n };\n }\n\n const font = await pdfDoc.embedFont(\n StandardFonts[options.font ?? DEFAULT_FONT],\n );\n const size = options.fontSize ?? DEFAULT_FONT_SIZE;\n const text = options.text!;\n const color = parseHexColor(options.color ?? DEFAULT_COLOR);\n let width: number;\n try {\n width = font.widthOfTextAtSize(text, size);\n } catch (error) {\n throw new WatermarkException(\n `Watermark text cannot be rendered with the ${options.font ?? DEFAULT_FONT} font (only WinAnsi characters are supported)`,\n { cause: error },\n );\n }\n return {\n width,\n height: font.heightAtSize(size, { descender: false }),\n draw: (page, x, y) =>\n page.drawText(text, { x, y, size, font, color, opacity, rotate }),\n };\n}\n\n/**\n * Stamps a text or image watermark on the pages of an existing PDF.\n */\nexport async function addWatermark(\n pdf: Uint8Array | Buffer,\n options: WatermarkOptions,\n): Promise<Uint8Array> {\n validate(options);\n\n try {\n const pdfDoc = await PDFDocument.load(new Uint8Array(pdf));\n const pages = pdfDoc.getPages();\n const indexes = resolvePageIndexes(options.pages, pages.length);\n\n const position = options.position ?? 'center';\n const rotation = options.rotation ?? DEFAULT_ROTATION;\n const spacing = options.tileSpacing ?? DEFAULT_TILE_SPACING;\n const theta = (rotation * Math.PI) / 180;\n const cos = Math.cos(theta);\n const sin = Math.sin(theta);\n\n // The image width depends on the page width, so marks are cached per width.\n const marks = new Map<number, Mark>();\n\n for (const index of indexes) {\n const page = pages[index];\n const { width: pageWidth, height: pageHeight } = page.getSize();\n\n let mark = marks.get(pageWidth);\n if (!mark) {\n mark = await buildMark(pdfDoc, options, pageWidth);\n marks.set(pageWidth, mark);\n }\n\n for (const center of markCenters(pageWidth, pageHeight, mark, {\n position,\n rotation,\n spacing,\n })) {\n // drawText/drawImage rotate around the bottom-left corner, so shift\n // the origin to make the mark's own center land on `center`.\n mark.draw(\n page,\n center.x - ((mark.width / 2) * cos - (mark.height / 2) * sin),\n center.y - ((mark.width / 2) * sin + (mark.height / 2) * cos),\n );\n }\n }\n\n return await pdfDoc.save();\n } catch (error) {\n if (error instanceof WatermarkException) throw error;\n throw new WatermarkException(\n `Failed to add watermark: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error },\n );\n }\n}\n","/*\nHow it works:\n`this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value.\n*/\n\nclass Node {\n\tvalue;\n\tnext;\n\n\tconstructor(value) {\n\t\tthis.value = value;\n\t}\n}\n\nexport default class Queue {\n\t#head;\n\t#tail;\n\t#size;\n\n\tconstructor() {\n\t\tthis.clear();\n\t}\n\n\tenqueue(value) {\n\t\tconst node = new Node(value);\n\n\t\tif (this.#head) {\n\t\t\tthis.#tail.next = node;\n\t\t\tthis.#tail = node;\n\t\t} else {\n\t\t\tthis.#head = node;\n\t\t\tthis.#tail = node;\n\t\t}\n\n\t\tthis.#size++;\n\t}\n\n\tdequeue() {\n\t\tconst current = this.#head;\n\t\tif (!current) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#head = this.#head.next;\n\t\tthis.#size--;\n\n\t\t// Clean up tail reference when queue becomes empty\n\t\tif (!this.#head) {\n\t\t\tthis.#tail = undefined;\n\t\t}\n\n\t\treturn current.value;\n\t}\n\n\tpeek() {\n\t\tif (!this.#head) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this.#head.value;\n\n\t\t// TODO: Node.js 18.\n\t\t// return this.#head?.value;\n\t}\n\n\tclear() {\n\t\tthis.#head = undefined;\n\t\tthis.#tail = undefined;\n\t\tthis.#size = 0;\n\t}\n\n\tget size() {\n\t\treturn this.#size;\n\t}\n\n\t* [Symbol.iterator]() {\n\t\tlet current = this.#head;\n\n\t\twhile (current) {\n\t\t\tyield current.value;\n\t\t\tcurrent = current.next;\n\t\t}\n\t}\n\n\t* drain() {\n\t\twhile (this.#head) {\n\t\t\tyield this.dequeue();\n\t\t}\n\t}\n}\n","import Queue from 'yocto-queue';\n\nexport default function pLimit(concurrency) {\n\tlet rejectOnClear = false;\n\n\tif (typeof concurrency === 'object') {\n\t\t({concurrency, rejectOnClear = false} = concurrency);\n\t}\n\n\tvalidateConcurrency(concurrency);\n\n\tif (typeof rejectOnClear !== 'boolean') {\n\t\tthrow new TypeError('Expected `rejectOnClear` to be a boolean');\n\t}\n\n\tconst queue = new Queue();\n\tlet activeCount = 0;\n\n\tconst resumeNext = () => {\n\t\t// Process the next queued function if we're under the concurrency limit\n\t\tif (activeCount < concurrency && queue.size > 0) {\n\t\t\tactiveCount++;\n\t\t\tqueue.dequeue().run();\n\t\t}\n\t};\n\n\tconst next = () => {\n\t\tactiveCount--;\n\t\tresumeNext();\n\t};\n\n\tconst run = async (function_, resolve, arguments_) => {\n\t\t// Execute the function and capture the result promise\n\t\tconst result = (async () => function_(...arguments_))();\n\n\t\t// Resolve immediately with the promise (don't wait for completion)\n\t\tresolve(result);\n\n\t\t// Wait for the function to complete (success or failure)\n\t\t// We catch errors here to prevent unhandled rejections,\n\t\t// but the original promise rejection is preserved for the caller\n\t\ttry {\n\t\t\tawait result;\n\t\t} catch {}\n\n\t\t// Decrement active count and process next queued function\n\t\tnext();\n\t};\n\n\tconst enqueue = (function_, resolve, reject, arguments_) => {\n\t\tconst queueItem = {reject};\n\n\t\t// Queue the internal resolve function instead of the run function\n\t\t// to preserve the asynchronous execution context.\n\t\tnew Promise(internalResolve => { // eslint-disable-line promise/param-names\n\t\t\tqueueItem.run = internalResolve;\n\t\t\tqueue.enqueue(queueItem);\n\t\t}).then(run.bind(undefined, function_, resolve, arguments_)); // eslint-disable-line promise/prefer-await-to-then\n\n\t\t// Start processing immediately if we haven't reached the concurrency limit\n\t\tif (activeCount < concurrency) {\n\t\t\tresumeNext();\n\t\t}\n\t};\n\n\tconst generator = (function_, ...arguments_) => new Promise((resolve, reject) => {\n\t\tenqueue(function_, resolve, reject, arguments_);\n\t});\n\n\tObject.defineProperties(generator, {\n\t\tactiveCount: {\n\t\t\tget: () => activeCount,\n\t\t},\n\t\tpendingCount: {\n\t\t\tget: () => queue.size,\n\t\t},\n\t\tclearQueue: {\n\t\t\tvalue() {\n\t\t\t\tif (!rejectOnClear) {\n\t\t\t\t\tqueue.clear();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst abortError = AbortSignal.abort().reason;\n\n\t\t\t\twhile (queue.size > 0) {\n\t\t\t\t\tqueue.dequeue().reject(abortError);\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\tconcurrency: {\n\t\t\tget: () => concurrency,\n\n\t\t\tset(newConcurrency) {\n\t\t\t\tvalidateConcurrency(newConcurrency);\n\t\t\t\tconcurrency = newConcurrency;\n\n\t\t\t\tqueueMicrotask(() => {\n\t\t\t\t\t// eslint-disable-next-line no-unmodified-loop-condition\n\t\t\t\t\twhile (activeCount < concurrency && queue.size > 0) {\n\t\t\t\t\t\tresumeNext();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t},\n\t\tmap: {\n\t\t\tasync value(iterable, function_) {\n\t\t\t\tconst promises = Array.from(iterable, (value, index) => generator(function_, value, index));\n\t\t\t\treturn Promise.all(promises);\n\t\t\t},\n\t\t},\n\t});\n\n\treturn generator;\n}\n\nexport function limitFunction(function_, options) {\n\tconst limit = pLimit(options);\n\n\tconst limitedFunction = (...arguments_) => limit(() => function_(...arguments_));\n\tObject.defineProperty(limitedFunction, 'clearQueue', {\n\t\tvalue: limit.clearQueue,\n\t});\n\n\treturn limitedFunction;\n}\n\nfunction validateConcurrency(concurrency) {\n\tif (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {\n\t\tthrow new TypeError('Expected `concurrency` to be a number from 1 and up');\n\t}\n}\n","import { deepmerge } from 'deepmerge-ts';\n\nimport { type PuppeteerParameters } from '../puppeteer/puppeteer-parameters.interface';\n\nexport function mergePuppeteerParameters(\n defaults: PuppeteerParameters,\n overrides?: PuppeteerParameters,\n): PuppeteerParameters {\n if (!overrides) {\n return { ...defaults };\n }\n\n return deepmerge(defaults, overrides);\n}\n","import { lookup } from 'node:dns/promises';\nimport { promises } from 'node:fs';\nimport { BlockList, isIP } from 'node:net';\nimport {\n basename,\n dirname,\n isAbsolute,\n join,\n relative,\n resolve,\n} from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { Logger } from '@nestjs/common';\nimport {\n type BrowserContext,\n type HTTPRequest,\n type Page,\n TargetType,\n} from 'puppeteer';\n\n/**\n * Filters what the rendered HTML may load (SSRF protection). Disabled unless set:\n * pass `{}` for the defaults (private networks and `file:` blocked).\n */\nexport interface PdfSecurityOptions {\n /**\n * Refuse http(s) requests that resolve to a loopback, private, link-local\n * (cloud metadata included) or otherwise non-public address. Default: true\n */\n blockPrivateNetworks?: boolean;\n /**\n * When set, http(s) requests are only allowed to these hosts (`example.com`\n * or `*.example.com`). Listed hosts are trusted, even on a private address.\n */\n allowedHosts?: Array<string>;\n /**\n * `file:` requests are refused unless the file is inside one of these\n * directories (symbolic links are resolved).\n */\n allowedFileRoots?: Array<string>;\n /** Set to false to disable JavaScript in the rendered page. Default: true */\n javascriptEnabled?: boolean;\n}\n\nconst blockedRanges = new BlockList();\nfor (const [address, prefix] of [\n ['0.0.0.0', 8],\n ['10.0.0.0', 8],\n ['100.64.0.0', 10],\n ['127.0.0.0', 8],\n ['169.254.0.0', 16],\n ['172.16.0.0', 12],\n ['192.0.0.0', 24],\n ['192.168.0.0', 16],\n ['198.18.0.0', 15],\n ['224.0.0.0', 4],\n ['240.0.0.0', 4],\n] as const) {\n blockedRanges.addSubnet(address, prefix, 'ipv4');\n}\nfor (const [address, prefix] of [\n ['::', 128],\n ['::1', 128],\n ['64:ff9b::', 96],\n ['fc00::', 7],\n ['fe80::', 10],\n ['ff00::', 8],\n] as const) {\n blockedRanges.addSubnet(address, prefix, 'ipv6');\n}\n\nconst IPV4_MAPPED_IPV6 = /^::ffff:([\\da-f]{1,4}):([\\da-f]{1,4})$/i;\n\n/** True for addresses that must not be reachable from a rendered document. */\nexport function isPrivateAddress(address: string): boolean {\n const family = isIP(address);\n if (family === 4) {\n return blockedRanges.check(address, 'ipv4');\n }\n if (family === 6) {\n // WHATWG URL serialises ::ffff:127.0.0.1 as ::ffff:7f00:1\n const mapped = IPV4_MAPPED_IPV6.exec(address);\n if (mapped) {\n const high = Number.parseInt(mapped[1], 16);\n const low = Number.parseInt(mapped[2], 16);\n return isPrivateAddress(\n [high >> 8, high & 0xff, low >> 8, low & 0xff].join('.'),\n );\n }\n return blockedRanges.check(address, 'ipv6');\n }\n // Not an IP: unknown format, refuse.\n return true;\n}\n\nfunction hostMatches(hostname: string, pattern: string): boolean {\n const host = hostname.toLowerCase();\n const rule = pattern.toLowerCase();\n if (rule.startsWith('*.')) {\n return host.endsWith(rule.slice(1));\n }\n return host === rule;\n}\n\nfunction isLocalhostName(hostname: string): boolean {\n return hostname === 'localhost' || hostname.endsWith('.localhost');\n}\n\nasync function resolvesToPrivateAddress(hostname: string): Promise<boolean> {\n // IPv6 literals come bracketed from URL.hostname\n const host = hostname.replace(/^\\[|\\]$/g, '');\n if (isIP(host)) {\n return isPrivateAddress(host);\n }\n if (isLocalhostName(host)) {\n return true;\n }\n try {\n const addresses = await lookup(host, { all: true, verbatim: true });\n return addresses.some(({ address }) => isPrivateAddress(address));\n } catch {\n // Unresolvable: the browser would fail too, and we cannot vouch for it.\n return true;\n }\n}\n\nasync function isFileAllowed(url: URL, roots: Array<string>): Promise<boolean> {\n // file://server/share is a network path (SMB), never a local file\n if (\n roots.length === 0 ||\n (url.hostname !== '' && url.hostname !== 'localhost')\n ) {\n return false;\n }\n\n let path: string;\n try {\n path = fileURLToPath(url);\n } catch {\n return false;\n }\n\n // Missing file: nothing to leak, but resolve its closest existing ancestor\n // so symlinks (e.g. macOS /var -> /private/var) match the resolved roots.\n const real = async (candidate: string) => {\n const missing: Array<string> = [];\n let current = resolve(candidate);\n for (;;) {\n try {\n return join(await promises.realpath(current), ...missing);\n } catch {\n const parent = dirname(current);\n if (parent === current) return resolve(candidate);\n missing.unshift(basename(current));\n current = parent;\n }\n }\n };\n\n const target = await real(path);\n for (const root of roots) {\n const rel = relative(await real(root), target);\n if (rel === '' || (!rel.startsWith('..') && !isAbsolute(rel))) {\n return true;\n }\n }\n return false;\n}\n\n/** Decides whether the browser may fetch `rawUrl`. */\nexport async function isRequestAllowed(\n rawUrl: string,\n options: PdfSecurityOptions,\n): Promise<boolean> {\n let url: URL;\n try {\n url = new URL(rawUrl);\n } catch {\n return false;\n }\n\n switch (url.protocol) {\n case 'about:':\n case 'data:':\n case 'blob:':\n return true;\n case 'file:':\n return isFileAllowed(url, options.allowedFileRoots ?? []);\n case 'http:':\n case 'https:': {\n if (options.allowedHosts) {\n return options.allowedHosts.some((pattern) =>\n hostMatches(url.hostname, pattern),\n );\n }\n if (options.blockPrivateNetworks === false) {\n return true;\n }\n return !(await resolvesToPrivateAddress(url.hostname));\n }\n default:\n return false;\n }\n}\n\n/** Logs the origin and path only: query strings may carry secrets. */\nfunction describe(rawUrl: string) {\n try {\n const url = new URL(rawUrl);\n return `${url.origin === 'null' ? `${url.protocol}//` : url.origin}${url.pathname}`;\n } catch {\n return '<invalid url>';\n }\n}\n\n/**\n * Filters every request the page (and its frames) makes, redirects included,\n * and closes the pop-ups a script could open to escape the filter.\n */\nexport async function installRequestGuard(\n context: BrowserContext,\n page: Page,\n options: PdfSecurityOptions,\n) {\n context.on('targetcreated', (target) => {\n if (target.type() === TargetType.PAGE && target.opener()) {\n void target\n .page()\n .then((popup) => popup?.close())\n .catch(() => undefined);\n }\n });\n\n if (options.javascriptEnabled === false) {\n await page.setJavaScriptEnabled(false);\n }\n\n await page.setRequestInterception(true);\n page.on('request', (request: HTTPRequest) => {\n void (async () => {\n if (request.isInterceptResolutionHandled()) return;\n const url = request.url();\n const allowed = await isRequestAllowed(url, options).catch(() => false);\n if (request.isInterceptResolutionHandled()) return;\n if (allowed) {\n await request.continue();\n } else {\n Logger.warn(`Blocked request to ${describe(url)}`, 'NestJsPdf');\n await request.abort('blockedbyclient');\n }\n })().catch(() => undefined);\n });\n}\n","export const PDF_PARAMETERS = 'PDF_PARAMETERS' as const;\n","import { existsSync, promises, readFileSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { Inject, Injectable, Logger, OnModuleDestroy } from '@nestjs/common';\nimport {\n Browser as BrowserType,\n BrowserPlatform,\n canDownload,\n detectBrowserPlatform,\n getInstalledBrowsers,\n install,\n resolveBuildId,\n} from '@puppeteer/browsers';\nimport { Browser, BrowserContext, launch } from 'puppeteer';\n\nimport {\n BrowserInstallationException,\n BrowserUnavailableException,\n NestjsPdfException,\n} from '../../exceptions';\nimport type { PuppeteerParameters } from '../puppeteer-parameters.interface';\n\nexport enum BrowserTag {\n LATEST = 'latest',\n BETA = 'beta',\n DEV = 'dev',\n STABLE = 'stable',\n CANARY = 'canary',\n}\n\nexport type Headless = boolean | 'shell' | undefined;\n\nasync function sleep(ms: number) {\n await new Promise((r) => setTimeout(r, ms));\n}\n\nasync function rmWithRetries(dir: string, retries = 5): Promise<void> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n await promises.rm(dir, { recursive: true, force: true });\n return;\n } catch (err: unknown) {\n const code = (err as NodeJS.ErrnoException)?.code;\n\n const retryable =\n code === 'EPERM' || code === 'EBUSY' || code === 'ENOTEMPTY';\n\n if (!retryable || attempt === retries) {\n throw err;\n }\n\n await sleep(50 * 2 ** (attempt - 1));\n }\n }\n}\n\nfunction isTargetClosedError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n\n return (\n error.name === 'TargetCloseError' ||\n error.message.includes('Target closed') ||\n error.message.includes('Target.createTarget')\n );\n}\n\n@Injectable()\nexport class BrowserService implements OnModuleDestroy {\n readonly #cacheDir: string;\n readonly #options?: PuppeteerParameters;\n\n #browserInstance: Browser | null = null;\n #browser: BrowserType;\n\n public activeJobs = 0;\n public totalJobs = 0;\n\n #recycleRequested = false;\n #recycling = false;\n\n #shuttingDown = false;\n /** Max time to wait for in-flight PDF jobs to finish before closing the browser on shutdown. */\n public shutdownDrainTimeoutMs = 15_000;\n\n #browserTag: BrowserTag;\n #useLockedBrowser: boolean;\n #buildId: string | undefined;\n\n constructor(@Inject('PDF_PARAMETERS') pdfParams: PuppeteerParameters) {\n this.#cacheDir = resolve('.cache/puppeteer-browser');\n this.#options = pdfParams;\n\n this.#loadBuildId();\n this.#loadBrowser();\n this.#loadBrowserTag();\n this.#loadUseLockedBrowser();\n }\n\n async onModuleDestroy() {\n this.#shuttingDown = true;\n await this.#waitForIdle(this.shutdownDrainTimeoutMs);\n\n if (this.#browserInstance?.connected) {\n try {\n await this.#browserInstance.close();\n } catch (error) {\n Logger.warn(\n `Failed to close browser on module destroy: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n }\n\n if (this.#options?.cleanupBrowserCacheOnExit !== false) {\n await this.#cleanupCacheBestEffort();\n }\n }\n\n /** Wait until no PDF job is in flight, or until the timeout elapses. */\n async #waitForIdle(timeoutMs: number): Promise<void> {\n const start = Date.now();\n while (this.activeJobs > 0 && Date.now() - start < timeoutMs) {\n await sleep(50);\n }\n\n if (this.activeJobs > 0) {\n Logger.warn(\n `Shutdown: ${this.activeJobs} PDF job(s) still running after ${timeoutMs}ms, closing the browser anyway`,\n );\n }\n }\n\n async getBrowserInstance(\n args: Array<string>,\n headless: boolean | 'shell' | undefined,\n executablePathBin: string | undefined,\n ) {\n if (!this.#browserInstance?.connected) {\n this.#browserInstance = await this.#launchBrowser(\n args,\n headless,\n executablePathBin,\n );\n }\n\n return this.#browserInstance;\n }\n\n async createContext(\n args: Array<string>,\n headless: Headless,\n executablePath?: string,\n ): Promise<BrowserContext> {\n const browser = await this.getBrowserInstance(\n args,\n headless,\n executablePath,\n );\n try {\n return await browser.createBrowserContext();\n } catch (error) {\n if (!isTargetClosedError(error)) {\n throw error;\n }\n\n Logger.warn(\n 'Puppeteer browser closed while creating a context, retrying once',\n );\n\n this.#browserInstance = null;\n const freshBrowser = await this.getBrowserInstance(\n args,\n headless,\n executablePath,\n );\n return await freshBrowser.createBrowserContext();\n }\n }\n\n markJobStarted() {\n if (this.#shuttingDown) {\n throw new BrowserUnavailableException(\n 'nestjs-pdf is shutting down, refusing new PDF jobs',\n );\n }\n\n this.activeJobs += 1;\n this.totalJobs += 1;\n\n if (this.totalJobs >= 200) {\n this.#recycleRequested = true;\n }\n }\n\n async markJobFinished() {\n this.activeJobs = Math.max(0, this.activeJobs - 1);\n await this.recycleBrowserIfNeeded();\n }\n\n async recycleBrowserIfNeeded() {\n if (!this.#recycleRequested) return;\n if (this.#recycling) return;\n if (this.activeJobs > 0) return;\n if (!this.#browserInstance) return;\n\n this.#recycling = true;\n\n try {\n if (this.#browserInstance.connected) {\n await this.#browserInstance.close();\n }\n\n this.#browserInstance = null;\n this.totalJobs = 0;\n this.#recycleRequested = false;\n\n Logger.log('Puppeteer browser recycled successfully');\n } catch (error) {\n Logger.warn(\n `Failed to recycle browser: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n } finally {\n this.#recycling = false;\n }\n }\n\n async #cleanupCacheBestEffort() {\n const logger = new Logger('NestJsPdf');\n const dir = this.#cacheDir;\n try {\n if (!existsSync(dir)) return;\n\n logger.log(`Cleanup puppeteer cache: ${dir}`);\n\n await rmWithRetries(dir, 6);\n if (existsSync(dir)) {\n await sleep(100);\n await rmWithRetries(dir, 3);\n }\n\n logger.log('Cleanup done');\n } catch (err) {\n logger.error(\n `Cleanup failed for ${dir}`,\n err instanceof Error ? err.stack : String(err),\n );\n }\n try {\n const leftover = await promises.readdir(dir, { recursive: true });\n logger.warn(`Leftover files: ${leftover.slice(0, 20).join(', ')}...`);\n } catch {\n logger.log(`No leftover files in ${dir}`);\n }\n }\n\n async install(lock: boolean = false) {\n try {\n return await this.#doInstall(lock);\n } catch (error) {\n if (error instanceof NestjsPdfException) {\n throw error;\n }\n throw new BrowserInstallationException(\n `Could not install browser: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n async #doInstall(lock: boolean) {\n const browser: BrowserType = this.#browser;\n const versionTag: BrowserTag = this.#browserTag;\n\n const browserPlatform = detectBrowserPlatform() ?? BrowserPlatform.LINUX;\n\n let buildId: string;\n if (this.#buildId === undefined) {\n buildId = await resolveBuildId(browser, browserPlatform, versionTag);\n } else {\n buildId = this.#buildId;\n }\n\n Logger.log(\n `Browser ${browser} ${versionTag} build id: ${buildId}`,\n 'NestJsPdf',\n );\n\n if (await this.hasBrowserInstalled(browser, buildId)) {\n Logger.log('Browser already installed', 'NestJsPdf');\n if (lock) {\n this.#writeLockFile(browser, buildId);\n }\n return;\n } else {\n Logger.log('Starting browser installation', 'NestJsPdf');\n\n const installOption = {\n cacheDir: this.#cacheDir,\n browser: browser,\n buildId: buildId,\n baseUrl: this.#options?.browserInstallBaseUrl ?? undefined,\n };\n\n if (await canDownload(installOption)) {\n Logger.log(\n `Installing ${installOption.browser} ${installOption.buildId}`,\n 'NestJsPdf',\n );\n const installedBrowser = await install(installOption);\n if (await this.hasBrowserInstalled(browser, buildId)) {\n Logger.log('Browser installed successfully', 'NestJsPdf');\n if (lock) {\n this.#writeLockFile(browser, buildId);\n }\n return installedBrowser;\n } else {\n Logger.error('Browser installation failed', 'NestJsPdf');\n }\n } else {\n Logger.error(\n `Error, can't install ${installOption.browser} ${installOption.buildId}`,\n 'NestJsPdf',\n );\n }\n }\n return null;\n }\n\n #loadBrowser(): void {\n let browser: BrowserType;\n if (this.#options?.browser === undefined) {\n browser = BrowserType.CHROMIUM;\n } else {\n browser = this.#options.browser;\n }\n this.#browser = browser;\n }\n\n public getBrowser(): BrowserType {\n return this.#browser;\n }\n\n #loadBrowserTag(): void {\n let versionTag: BrowserTag;\n if (this.#options?.browserTag === undefined) {\n if (this.#browser === BrowserType.CHROMIUM) {\n versionTag = BrowserTag.LATEST;\n } else {\n versionTag = BrowserTag.STABLE;\n }\n } else {\n versionTag = this.#options.browserTag;\n }\n this.#browserTag = versionTag;\n }\n\n #loadBuildId(): void {\n let buildId: string | undefined;\n if (this.#options?.buildId === undefined) {\n buildId = undefined;\n } else {\n buildId = this.#options.buildId;\n }\n this.#buildId = buildId;\n }\n\n public setBrowserTag(browserTag: BrowserTag): void {\n this.#browserTag = browserTag;\n }\n\n public getBrowserTag(): BrowserTag {\n return this.#browserTag;\n }\n\n getBuildId(): string | undefined {\n return this.#buildId;\n }\n\n #loadUseLockedBrowser(): void {\n let useLockedBrowser: boolean;\n if (this.#options?.useLockedBrowser === undefined) {\n useLockedBrowser = false;\n } else {\n useLockedBrowser = this.#options.useLockedBrowser;\n }\n this.#useLockedBrowser = useLockedBrowser;\n }\n\n async hasBrowserInstalled(browser: BrowserType, buildId: string) {\n const installedBrowserlist = await getInstalledBrowsers({\n cacheDir: this.#cacheDir,\n });\n\n const installedBrowser = installedBrowserlist.find((insBrowser) => {\n return insBrowser.browser === browser && insBrowser.buildId === buildId;\n });\n return installedBrowser !== undefined;\n }\n\n async getExecutablePath(): Promise<string> {\n const browser: BrowserType = this.#browser;\n const versionTag: BrowserTag = this.#browserTag;\n const browserPlatform = detectBrowserPlatform() ?? BrowserPlatform.LINUX;\n let buildId: string | null = null;\n if (this.#useLockedBrowser) {\n buildId = this.getLockedBuildId(browser);\n Logger.log(`Using locked browser ${buildId}`, 'NestJsPdf');\n }\n buildId ??= await resolveBuildId(browser, browserPlatform, versionTag);\n const installedBrowserlist = await getInstalledBrowsers({\n cacheDir: this.#cacheDir,\n });\n const installedBrowser = installedBrowserlist.find((insBrowser) => {\n return insBrowser.browser === browser && insBrowser.buildId === buildId;\n });\n if (installedBrowser === undefined) {\n const newinstalledBrowser = await this.install();\n if (newinstalledBrowser === null || newinstalledBrowser === undefined) {\n throw new BrowserInstallationException('Could not install browser');\n } else {\n return newinstalledBrowser.executablePath;\n }\n }\n return installedBrowser.executablePath;\n }\n\n async #launchBrowser(\n args: Array<string>,\n headless: Headless,\n executablePathBin: string | undefined,\n ) {\n const executablePath =\n executablePathBin ?? (await this.getExecutablePath());\n\n const browser = await launch({\n executablePath,\n headless,\n args,\n // Puppeteer disables Chrome's popup blocker by default, which lets a\n // script open a window that escapes the request filter.\n ignoreDefaultArgs: ['--disable-popup-blocking'],\n });\n\n browser.on('disconnected', () => {\n Logger.warn('Puppeteer browser disconnected');\n if (this.#browserInstance === browser) {\n this.#browserInstance = null;\n }\n });\n\n return browser;\n }\n\n #writeLockFile(browser: BrowserType, buildId: string) {\n const lockFile = resolve(this.#cacheDir, `${browser}.lock`);\n const data = JSON.stringify({\n browser: browser,\n buildId: buildId,\n date: new Date().toISOString(),\n });\n writeFileSync(lockFile, data);\n\n Logger.log(`Browser ${browser} locked to build ${buildId}`, 'NestJsPdf');\n }\n\n getLockedBuildId(browser: BrowserType): string | null {\n const lockFile = resolve(this.#cacheDir, `${browser}.lock`);\n if (existsSync(lockFile)) {\n const data = readFileSync(lockFile);\n const lock = JSON.parse(data.toString()) as {\n browser: Browser;\n buildId: string;\n date: string;\n };\n return lock.buildId;\n }\n return null;\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport ejs, { type Data, type Options } from 'ejs';\n\nimport { TemplateRenderException } from '../../../exceptions';\n\nexport interface EjsOptions extends Omit<Options, 'async'> {\n async?: boolean;\n}\n\n@Injectable()\nexport class EjsService {\n async render(template: string, data: Data = {}, options?: EjsOptions) {\n try {\n return await ejs.render(template, data, {\n async: true,\n ...options,\n });\n } catch (error) {\n throw new TemplateRenderException(\n 'EJS',\n `EJS rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n async renderFile(filePath: string, data: Data = {}, options?: EjsOptions) {\n try {\n return await ejs.renderFile(filePath, data, {\n async: true,\n ...options,\n });\n } catch (error) {\n throw new TemplateRenderException(\n 'EJS',\n `EJS file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { Injectable } from '@nestjs/common';\nimport { Eta, EtaConfig } from 'eta';\n\nimport { TemplateRenderException } from '../../../exceptions';\n\nexport interface EtaOptions extends Partial<EtaConfig> {\n cache?: boolean;\n autoEscape?: boolean;\n varName?: string;\n views?: string;\n useWith?: boolean;\n plugins?: Array<any>;\n}\n\n@Injectable()\nexport class EtaService {\n readonly #eta: Eta;\n readonly #templateCache: Map<string, string> = new Map();\n readonly #maxCacheSize = 100;\n\n constructor() {\n this.#eta = new Eta({\n cache: true,\n autoEscape: true,\n useWith: true,\n });\n }\n\n /**\n * Render an Eta template from a string\n * @param template The template string to render\n * @param data The data object to use for rendering\n * @param options Optional Eta rendering options\n * @returns The rendered HTML string\n */\n render(\n template: string,\n data: Record<string, unknown> = {},\n options?: EtaOptions,\n ): string {\n try {\n const eta =\n options && Object.keys(options).length > 0\n ? new Eta({\n cache: true,\n autoEscape: true,\n useWith: true,\n ...options,\n varName: options.varName ?? 'it',\n })\n : this.#eta;\n\n return eta.renderString(template, data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Eta',\n `Eta rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Render an Eta template from a file\n * @param filePath The path to the template file\n * @param data The data object to use for rendering\n * @param options Optional Eta rendering options\n * @returns The rendered HTML string\n */\n renderFile(\n filePath: string,\n data: Record<string, unknown> = {},\n options?: EtaOptions,\n ): string {\n try {\n const resolvedPath = resolve(filePath);\n const useCache = options?.cache ?? true;\n let template = useCache\n ? this.#templateCache.get(resolvedPath)\n : undefined;\n\n if (!template) {\n template = readFileSync(resolvedPath, 'utf-8');\n\n if (useCache && this.#templateCache.size < this.#maxCacheSize) {\n this.#templateCache.set(resolvedPath, template);\n }\n }\n return this.render(template, data, options);\n } catch (error) {\n throw new TemplateRenderException(\n 'Eta',\n `Eta file rendering failed for ${filePath}: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Clear the template cache\n */\n clearCache(): void {\n this.#templateCache.clear();\n }\n\n /**\n * Get the current cache size\n * @returns The number of cached templates\n */\n getCacheSize(): number {\n return this.#templateCache.size;\n }\n}\n","import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';\nimport { basename, extname, join, resolve, sep } from 'node:path';\n\nimport { Injectable } from '@nestjs/common';\nimport Handlebars from 'handlebars';\n\nimport {\n NestjsPdfException,\n TemplateConfigurationException,\n TemplateRenderException,\n} from '../../../exceptions';\n\nexport type HandlebarsHelper = {\n name: string;\n fn: Handlebars.HelperDelegate;\n};\n\nexport interface HandlebarsOptions {\n /** Base directory (relative to `process.cwd()`) used to resolve files passed to `renderFile`. */\n templateDirectory?: string;\n /** Directory (relative to `process.cwd()`) whose files are each registered as a partial. */\n partialDirectory?: string;\n /**\n * Runtime options forwarded to the compiled template function.\n * `helpers` and `partials` are excluded on purpose: register helpers via\n * `helpers` and partials via `partialDirectory`.\n */\n templateOptions?: Omit<Handlebars.RuntimeOptions, 'helpers' | 'partials'>;\n /** Options forwarded to `Handlebars.compile`. */\n compileOptions?: CompileOptions;\n /** Custom helpers registered on the isolated Handlebars environment for this render. */\n helpers?: Array<HandlebarsHelper>;\n}\n\n@Injectable()\nexport class HandlebarsService {\n #cachedOptions?: HandlebarsOptions;\n #cachedEnv?: typeof Handlebars;\n\n render(\n template: string,\n parameters: unknown = {},\n options: HandlebarsOptions = {},\n ): string {\n try {\n const compiled = this.#getEnv(options).compile(\n template,\n options.compileOptions,\n );\n return compiled(parameters, options.templateOptions);\n } catch (error) {\n if (error instanceof NestjsPdfException) {\n throw error;\n }\n throw new TemplateRenderException(\n 'Handlebars',\n `Handlebars rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n renderFile(\n file: string,\n parameters: unknown = {},\n options: HandlebarsOptions = {},\n ): string {\n if (options.templateDirectory === undefined) {\n throw new TemplateConfigurationException(\n 'Handlebars file rendering failed: option `templateDirectory` is not set',\n );\n }\n\n const baseDir = resolve(process.cwd(), options.templateDirectory);\n const templatePath = resolve(baseDir, file);\n if (templatePath !== baseDir && !templatePath.startsWith(baseDir + sep)) {\n throw new TemplateConfigurationException(\n `Handlebars file rendering failed: ’${file}’ resolves outside \\`templateDirectory\\``,\n );\n }\n\n let template: string;\n try {\n template = readFileSync(templatePath, 'utf8');\n } catch (error) {\n throw new TemplateRenderException(\n 'Handlebars',\n `Handlebars file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n\n return this.render(template, parameters, options);\n }\n\n /**\n * Build an isolated Handlebars environment with the given helpers/partials so\n * nothing leaks into the global Handlebars. Memoised for the common case where\n * the same options object is reused across calls (e.g. the module `hbsOptions`).\n */\n #getEnv(options: HandlebarsOptions): typeof Handlebars {\n if (this.#cachedEnv && this.#cachedOptions === options) {\n return this.#cachedEnv;\n }\n\n const env = Handlebars.create();\n\n for (const helper of options.helpers ?? []) {\n env.registerHelper(helper.name, helper.fn);\n }\n this.#registerPartials(env, options.partialDirectory);\n\n this.#cachedOptions = options;\n this.#cachedEnv = env;\n return env;\n }\n\n #registerPartials(\n env: typeof Handlebars,\n partialDirectory: string | undefined,\n ): void {\n if (partialDirectory === undefined) return;\n\n const partialPath = join(process.cwd(), partialDirectory);\n if (!existsSync(partialPath)) {\n throw new TemplateConfigurationException(\n `Handlebars partial directory does not exist: ${partialPath}`,\n );\n }\n\n for (const entry of readdirSync(partialPath)) {\n const filePath = join(partialPath, entry);\n if (!statSync(filePath).isFile()) continue;\n\n env.registerPartial(\n basename(entry, extname(entry)),\n readFileSync(filePath, 'utf8'),\n );\n }\n }\n}\n","import { readFileSync } from 'node:fs';\n\nimport { Injectable } from '@nestjs/common';\nimport mjml from 'mjml';\nimport { type MJMLParsingOptions } from 'mjml-core';\n\nimport { TemplateRenderException } from '../../../exceptions';\n\n@Injectable()\nexport class MjmlService {\n async render(\n template: string,\n options?: MJMLParsingOptions,\n ): Promise<string> {\n try {\n const { html } = await mjml(template, options);\n return html;\n } catch (error) {\n throw new TemplateRenderException(\n 'MJML',\n `MJML rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n async renderFile(\n filePath: string,\n options?: MJMLParsingOptions,\n ): Promise<string> {\n let template: string;\n try {\n template = readFileSync(filePath, 'utf-8');\n } catch (error) {\n throw new TemplateRenderException(\n 'MJML',\n `MJML file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n return await this.render(template, options);\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { Injectable } from '@nestjs/common';\nimport mustache, { EscapeFunction } from 'mustache';\n\nimport { TemplateRenderException } from '../../../exceptions';\n\nexport interface MustacheOptions {\n tags?: [string, string];\n escape?: EscapeFunction;\n}\n\n@Injectable()\nexport class MustacheService {\n readonly #templateCache: Map<string, string> = new Map();\n readonly #maxCacheSize = 100;\n\n /**\n * Render a Mustache template from a string\n * @param template The template string to render\n * @param data The data object to use for rendering\n * @param options Optional Mustache rendering options\n * @returns The rendered HTML string\n */\n render(\n template: string,\n data: Record<string, unknown> = {},\n options?: MustacheOptions,\n ): string {\n try {\n const tags = options?.tags ?? ['{{', '}}'];\n return mustache.render(template, data, undefined, {\n tags: tags,\n escape: options?.escape,\n });\n } catch (error) {\n throw new TemplateRenderException(\n 'Mustache',\n `Mustache rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Render a Mustache template from a file\n * @param filePath The path to the template file\n * @param data The data object to use for rendering\n * @param options Optional Mustache rendering options\n * @returns The rendered HTML string\n */\n renderFile(\n filePath: string,\n data: Record<string, unknown> = {},\n options?: MustacheOptions,\n ): string {\n try {\n const resolvedPath = resolve(filePath);\n let template = this.#templateCache.get(resolvedPath);\n\n if (!template) {\n template = readFileSync(resolvedPath, 'utf-8');\n\n if (this.#templateCache.size < this.#maxCacheSize) {\n this.#templateCache.set(resolvedPath, template);\n }\n }\n\n return this.render(template, data, options);\n } catch (error) {\n throw new TemplateRenderException(\n 'Mustache',\n `Mustache file rendering failed for ${filePath}: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Clear the template cache\n */\n clearCache(): void {\n this.#templateCache.clear();\n }\n\n /**\n * Get the current cache size\n * @returns The number of cached templates\n */\n getCacheSize(): number {\n return this.#templateCache.size;\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport nunjucks, { type ConfigureOptions } from 'nunjucks';\n\nimport { TemplateRenderException } from '../../../exceptions';\n\nexport interface NunjucksOptions extends Partial<ConfigureOptions> {\n noCache?: boolean;\n watch?: boolean;\n throwOnUndefined?: boolean;\n trimBlocks?: boolean;\n lstripBlocks?: boolean;\n}\n\n@Injectable()\nexport class NunjucksService {\n constructor() {\n // Configure default Nunjucks environment\n nunjucks.configure({\n noCache: true,\n trimBlocks: true,\n lstripBlocks: true,\n });\n }\n\n render(\n template: string,\n data: Record<string, unknown> = {},\n options?: NunjucksOptions,\n ) {\n try {\n if (options) {\n const configOptions: Record<string, unknown> = {\n noCache: options.noCache ?? true,\n watch: options.watch ?? false,\n throwOnUndefined: options.throwOnUndefined ?? false,\n trimBlocks: options.trimBlocks ?? true,\n lstripBlocks: options.lstripBlocks ?? true,\n };\n nunjucks.configure(configOptions as ConfigureOptions);\n }\n return nunjucks.renderString(template, data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Nunjucks',\n `Nunjucks rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n renderFile(\n filePath: string,\n data: Record<string, unknown> = {},\n options?: NunjucksOptions,\n ) {\n try {\n if (options) {\n const configOptions: Record<string, unknown> = {\n noCache: options.noCache ?? true,\n watch: options.watch ?? false,\n throwOnUndefined: options.throwOnUndefined ?? false,\n trimBlocks: options.trimBlocks ?? true,\n lstripBlocks: options.lstripBlocks ?? true,\n };\n nunjucks.configure(configOptions as ConfigureOptions);\n }\n return nunjucks.render(filePath, data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Nunjucks',\n `Nunjucks file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n}\n","import { readFileSync } from 'node:fs';\n\nimport { Injectable } from '@nestjs/common';\nimport pug, { type LocalsObject, type Options } from 'pug';\n\nimport { TemplateRenderException } from '../../../exceptions';\n\nexport type PugOptions = Options;\n\n@Injectable()\nexport class PugService {\n render(\n template: string,\n data: LocalsObject = {},\n options?: PugOptions,\n ): string {\n try {\n const compiledFn = pug.compile(template, {\n ...options,\n });\n return compiledFn(data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Pug',\n `Pug rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n renderFile(\n filePath: string,\n data: LocalsObject = {},\n options?: PugOptions,\n ): string {\n try {\n const template = readFileSync(filePath, 'utf-8');\n return this.render(template, data, options);\n } catch (error) {\n throw new TemplateRenderException(\n 'Pug',\n `Pug file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n}\n","import { EngineNotAvailableException } from '../../exceptions';\n\nexport function requireService<T>(service: T | undefined, name: string): T {\n if (!service) {\n throw new EngineNotAvailableException(name);\n }\n\n return service;\n}\n","import { Inject, Injectable, Logger, Optional } from '@nestjs/common';\nimport { Data } from 'ejs';\nimport pLimit from 'p-limit';\nimport { LocalsObject } from 'pug';\nimport { PDFOptions } from 'puppeteer';\n\nimport { NestjsPdfException, PdfGenerationException } from '../exceptions';\nimport { mergePuppeteerParameters } from '../helpers/deepMergePdfparams';\nimport { installRequestGuard } from '../helpers/request-guard.helper';\nimport { PDF_PARAMETERS } from '../helpers/tokens';\nimport { addWatermark } from '../helpers/watermark.helper';\nimport { BrowserService } from './browser/browser.service';\nimport { EjsService } from './engines/ejs/ejs.service';\nimport { EtaService } from './engines/eta/eta.service';\nimport { HandlebarsService } from './engines/handlebars/handlebars.service';\nimport { MjmlService } from './engines/mjml/mjml.service';\nimport { MustacheService } from './engines/mustache/mustache.service';\nimport { NunjucksService } from './engines/nunjucks/nunjucks.service';\nimport { PugService } from './engines/pug/pug.service';\nimport { requireService } from './libs/requireService.utils';\nimport type { PuppeteerParameters } from './puppeteer-parameters.interface';\n\n@Injectable()\nexport class PuppeteerService {\n readonly #browserService: BrowserService;\n readonly #options: PuppeteerParameters;\n readonly #hbsService?: HandlebarsService;\n readonly #mjmlService?: MjmlService;\n readonly #pugService?: PugService;\n readonly #ejsService?: EjsService;\n readonly #nunjucksService?: NunjucksService;\n readonly #etaService?: EtaService;\n readonly #mustacheService?: MustacheService;\n\n constructor(\n browserService: BrowserService,\n @Inject(PDF_PARAMETERS) options: PuppeteerParameters,\n @Optional() hbsService?: HandlebarsService,\n @Optional() mjmlService?: MjmlService,\n @Optional() pugService?: PugService,\n @Optional() ejsService?: EjsService,\n @Optional() nunjucksService?: NunjucksService,\n @Optional() etaService?: EtaService,\n @Optional() mustacheService?: MustacheService,\n ) {\n this.#browserService = browserService;\n this.#options = options;\n this.#hbsService = hbsService;\n this.#mjmlService = mjmlService;\n this.#pugService = pugService;\n this.#ejsService = ejsService;\n this.#nunjucksService = nunjucksService;\n this.#etaService = etaService;\n this.#mustacheService = mustacheService;\n }\n\n readonly #limit = pLimit(3);\n\n async generatePdfFromHtml(\n html: string,\n options?: PuppeteerParameters,\n ): Promise<Uint8Array> {\n const signal = options?.signal ?? this.#options.signal;\n signal?.throwIfAborted();\n\n let started = false;\n const job = this.#limit(async () => {\n signal?.throwIfAborted();\n started = true;\n\n const mergePuppeteerOptions = mergePuppeteerParameters(\n this.#options,\n options,\n );\n if (mergePuppeteerOptions.chromiumRevision !== undefined) {\n Logger.warn(\n 'Using `chromiumRevision` is no longer supported since the puppeteer update.',\n );\n }\n\n const headless: boolean | 'shell' =\n mergePuppeteerOptions.headless ?? true;\n\n const executablePath = mergePuppeteerOptions.executablePath || undefined;\n\n //src: https://www.bannerbear.com/blog/ways-to-speed-up-puppeteer-screenshots/\n const args = mergePuppeteerOptions.extraPuppeteerArgs || [\n '--autoplay-policy=user-gesture-required',\n '--disable-background-networking',\n '--disable-background-timer-throttling',\n '--disable-backgrounding-occluded-windows',\n '--disable-breakpad',\n '--disable-client-side-phishing-detection',\n '--disable-component-update',\n '--disable-default-apps',\n '--disable-dev-shm-usage',\n '--disable-domain-reliability',\n '--disable-extensions',\n '--disable-features=AudioServiceOutOfProcess',\n '--disable-hang-monitor',\n '--disable-ipc-flooding-protection',\n '--disable-notifications',\n '--disable-offer-store-unmasked-wallet-cards',\n '--disable-print-preview',\n '--disable-prompt-on-repost',\n '--disable-renderer-backgrounding',\n '--disable-setuid-sandbox',\n '--disable-speech-api',\n '--disable-sync',\n '--hide-scrollbars',\n '--ignore-gpu-blacklist',\n '--metrics-recording-only',\n '--mute-audio',\n '--no-default-browser-check',\n '--no-first-run',\n '--no-pings',\n '--password-store=basic',\n '--use-gl=swiftshader',\n '--use-mock-keychain',\n '--disable-accelerated-2d-canvas',\n '--no-zygote',\n '--disable-gpu',\n ];\n\n this.#browserService.markJobStarted();\n let context: Awaited<ReturnType<BrowserService['createContext']>> | null =\n null;\n\n let closing: Promise<void> | undefined;\n const onAbort = () => {\n if (!context) return;\n closing = context.close();\n closing.catch(() => undefined);\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n\n try {\n context = await this.#browserService.createContext(\n args,\n headless,\n executablePath,\n );\n signal?.throwIfAborted();\n const page = await context.newPage();\n if (mergePuppeteerOptions.security) {\n await installRequestGuard(\n context,\n page,\n mergePuppeteerOptions.security,\n );\n }\n\n const pdfOptions: PDFOptions = mergePuppeteerOptions.pdfOptions ?? {\n format: 'A4',\n };\n\n await page.setContent(html, { waitUntil: 'domcontentloaded' });\n await page.emulateMediaType('screen');\n await page.waitForNetworkIdle({ idleTime: 500, timeout: 30000 });\n // Executes inside the browser page context via Puppeteer, not in Node — unreachable by unit tests.\n /* v8 ignore next */\n await page.evaluate(() => document.fonts.ready);\n\n const pdf = await page.pdf(pdfOptions);\n signal?.throwIfAborted();\n return mergePuppeteerOptions.watermark\n ? await addWatermark(pdf, mergePuppeteerOptions.watermark)\n : pdf;\n } catch (e) {\n if (signal?.aborted) {\n throw signal.reason;\n }\n Logger.error(e);\n if (e instanceof NestjsPdfException) {\n throw e;\n }\n throw new PdfGenerationException(\n `PDF generation failed: ${String(e)}`,\n { cause: e },\n );\n } finally {\n signal?.removeEventListener('abort', onAbort);\n if (context) {\n try {\n if (closing) await closing;\n else await context.close();\n } catch (error) {\n Logger.error(error);\n }\n }\n await this.#browserService.markJobFinished();\n }\n });\n\n if (!signal) {\n return job;\n }\n\n let onQueuedAbort!: () => void;\n const abortedWhileQueued = new Promise<never>((_, reject) => {\n onQueuedAbort = () => {\n // An abort reason can be any value; callers expect the exact one they passed.\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n if (!started) reject(signal.reason);\n };\n signal.addEventListener('abort', onQueuedAbort, { once: true });\n });\n try {\n return await Promise.race([job, abortedWhileQueued]);\n } finally {\n signal.removeEventListener('abort', onQueuedAbort);\n }\n }\n\n async generatePdfFromTemplateHbsString(\n template: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n const hbsService = requireService(this.#hbsService, 'Handlebars');\n const html = hbsService.render(\n template,\n parameters,\n options?.hbsOptions ?? this.#options.hbsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromTemplateHbsFile(\n file: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n const hbsService = requireService(this.#hbsService, 'Handlebars');\n const html = hbsService.renderFile(\n file,\n parameters,\n options?.hbsOptions ?? this.#options.hbsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMjmlString(\n template: string,\n options?: PuppeteerParameters,\n ) {\n const mjmlService = requireService(this.#mjmlService, 'MJML');\n const html = await mjmlService.render(\n template,\n options?.mjmlOptions ?? this.#options.mjmlOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMjmlFile(file: string, options?: PuppeteerParameters) {\n const mjmlService = requireService(this.#mjmlService, 'MJML');\n const html = await mjmlService.renderFile(\n file,\n options?.mjmlOptions ?? this.#options.mjmlOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromPugString(\n template: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n const pugService = requireService(this.#pugService, 'Pug');\n const html = pugService.render(\n template,\n data,\n options?.pugOptions ?? this.#options.pugOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromPugFile(\n file: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n const pugService = requireService(this.#pugService, 'Pug');\n const html = pugService.renderFile(\n file,\n data,\n options?.pugOptions ?? this.#options.pugOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEjsString(\n template: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n const ejsService = requireService(this.#ejsService, 'EJS');\n const html = await ejsService.render(\n template,\n data,\n options?.ejsOptions ?? this.#options.ejsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEjsFile(\n file: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n const ejsService = requireService(this.#ejsService, 'EJS');\n const html = await ejsService.renderFile(\n file,\n data,\n options?.ejsOptions ?? this.#options.ejsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromNunjucksString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const nunjucksService = requireService(this.#nunjucksService, 'Nunjucks');\n const html = nunjucksService.render(\n template,\n data,\n options?.nunjucksOptions ?? this.#options.nunjucksOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromNunjucksFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const nunjucksService = requireService(this.#nunjucksService, 'Nunjucks');\n const html = nunjucksService.renderFile(\n file,\n data,\n options?.nunjucksOptions ?? this.#options.nunjucksOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEtaString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const etaService = requireService(this.#etaService, 'Eta');\n const html = etaService.render(\n template,\n data,\n options?.etaOptions ?? this.#options.etaOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEtaFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const etaService = requireService(this.#etaService, 'Eta');\n const html = etaService.renderFile(\n file,\n data,\n options?.etaOptions ?? this.#options.etaOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMustacheString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const mustacheService = requireService(this.#mustacheService, 'Mustache');\n const html = mustacheService.render(\n template,\n data,\n options?.mustacheOptions ?? this.#options.mustacheOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMustacheFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const mustacheService = requireService(this.#mustacheService, 'Mustache');\n const html = mustacheService.renderFile(\n file,\n data,\n options?.mustacheOptions ?? this.#options.mustacheOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport { Data } from 'ejs';\nimport { LocalsObject } from 'pug';\n\nimport { addSignatureFieldUsingAnchor } from './helpers/signature.helper';\nimport {\n addWatermark,\n type WatermarkOptions,\n} from './helpers/watermark.helper';\nimport { PuppeteerService } from './puppeteer/puppeteer.service';\nimport { PuppeteerParameters } from './puppeteer/puppeteer-parameters.interface';\n\n@Injectable()\nexport class NestjsPdfService {\n readonly #puppeteerService: PuppeteerService;\n\n constructor(puppeteerService: PuppeteerService) {\n this.#puppeteerService = puppeteerService;\n }\n\n /**\n * @param html HTML string to convert to PDF\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided HTML\n * @description This method uses the Puppeteer service to generate a PDF from an HTML string. Generation options can be customized by passing a `PuppeteerParameters` object as the second argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.\n */\n generatePdfFromHtml(html: string, options?: PuppeteerParameters) {\n return this.#puppeteerService.generatePdfFromHtml(html, options);\n }\n\n /**\n * @param template Handlebars template string\n * @param parameters Data parameters to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Handlebars template with parameters applied\n * @description This method generates a PDF from a Handlebars template provided as a string. The parameters to inject into the template are passed in the `parameters` object, which is used to render the template before converting it to PDF. PDF generation options can also be customized by passing a `PuppeteerParameters` object as the third argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.\n */\n generatePdfFromTemplateHbsString(\n template: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromTemplateHbsString(\n template,\n parameters,\n options,\n );\n }\n\n /**\n * @param file Path to the Handlebars template file\n * @param parameters Data parameters to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Handlebars template at the provided file path with parameters applied\n * @description This method generates a PDF from a Handlebars template located at the specified file path. The file path is passed as a string in the `file` parameter. The parameters to inject into the template are passed in the `parameters` object, which is used to render the template before converting it to PDF. PDF generation options can also be customized by passing a `PuppeteerParameters` object as the third argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.\n */\n generatePdfFromTemplateHbsFile(\n file: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromTemplateHbsFile(\n file,\n parameters,\n options,\n );\n }\n\n /**\n * @param template MJML template string\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided MJML template\n * @description This method generates a PDF from an MJML template provided as a string. MJML (MJML Markup Language) is a markup language designed to reduce the pain of coding a responsive email. The template is first rendered to HTML using the MJML renderer, then converted to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the second argument.\n */\n generatePdfFromMjmlString(template: string, options?: PuppeteerParameters) {\n return this.#puppeteerService.generatePdfFromMjmlString(template, options);\n }\n\n /**\n * @param file Path to the MJML template file\n * @param options PDF generation options (optional)\n * @returns PDF generated from the MJML template at the provided file path\n * @description This method generates a PDF from an MJML template located at the specified file path. The file path is passed as a string in the `file` parameter. The template is first rendered to HTML using the MJML renderer, then converted to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the second argument.\n */\n generatePdfFromMjmlFile(file: string, options?: PuppeteerParameters) {\n return this.#puppeteerService.generatePdfFromMjmlFile(file, options);\n }\n\n /**\n * @param template EJS template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided EJS template with data applied\n * @description This method generates a PDF from an EJS (Embedded JavaScript) template provided as a string. EJS is a templating language with a simple, straightforward syntax. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEjsString(\n template: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEjsString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the EJS template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the EJS template at the provided file path with data applied\n * @description This method generates a PDF from an EJS template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEjsFile(\n file: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEjsFile(file, data, options);\n }\n\n /**\n * @param template Pug template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Pug template with data applied\n * @description This method generates a PDF from a Pug template provided as a string. Pug is a clean, whitespace-sensitive syntax for writing HTML. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromPugString(\n template: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromPugString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Pug template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Pug template at the provided file path with data applied\n * @description This method generates a PDF from a Pug template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromPugFile(\n file: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromPugFile(file, data, options);\n }\n\n /**\n * @param template Nunjucks template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Nunjucks template with data applied\n * @description This method generates a PDF from a Nunjucks template provided as a string. Nunjucks is a powerful templating language with support for inheritance, macros, and filters. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromNunjucksString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromNunjucksString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Nunjucks template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Nunjucks template at the provided file path with data applied\n * @description This method generates a PDF from a Nunjucks template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromNunjucksFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromNunjucksFile(\n file,\n data,\n options,\n );\n }\n\n /**\n * @param template Eta template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Eta template with data applied\n * @description This method generates a PDF from an Eta template provided as a string. Eta is a fast and lightweight embedded templating language with a syntax similar to EJS but with better performance. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEtaString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEtaString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Eta template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Eta template at the provided file path with data applied\n * @description This method generates a PDF from an Eta template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEtaFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEtaFile(file, data, options);\n }\n\n /**\n * @param template Mustache template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Mustache template with data applied\n * @description This method generates a PDF from a Mustache template provided as a string. Mustache is a logic-less template language that emphasizes readable and simple templates. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromMustacheString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromMustacheString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Mustache template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Mustache template at the provided file path with data applied\n * @description This method generates a PDF from a Mustache template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromMustacheFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromMustacheFile(\n file,\n data,\n options,\n );\n }\n\n /**\n * @param pdf The PDF bytes to modify\n * @param fieldName The name of the signature field to add (default: 'SignatureDebtor')\n * @param anchorText The text anchor to locate the signature field position (default: '__SIG_DEBTOR_ANCHOR__')\n * @returns Modified PDF with a signature field added at the anchor position\n * @description This method adds a signature field to a PDF using a text anchor as a reference for the field position. It uses the `addSignatureFieldUsingAnchor` function which finds the anchor in the PDF and inserts a signature field at that location. The signature field is named according to the `fieldName` parameter and the anchor is defined by `anchorText`.\n *\n * Usage example:\n * ```typescript\n * const modifiedPdf = await pdfService.addSignatureFieldSignatureDebtorRaw(\n * originalPdfBytes,\n * 'SignatureDebtor',\n * '__SIG_DEBTOR_ANCHOR__'\n * );\n * ```\n *\n * In this example, `originalPdfBytes` is a byte array representing the original PDF, `SignatureDebtor` is the name of the signature field to add, and `__SIG_DEBTOR_ANCHOR__` is the anchor text used to position the signature field in the PDF.\n *\n * If the anchor is not found, the signature field will be added at a default position (centered at the bottom of the last page).\n *\n * Note: Ensure that the input PDF contains the anchor defined by `anchorText` for the signature field to be positioned correctly. Otherwise, it will be added at a default position.\n */\n async addSignatureFieldSignatureDebtorRaw(\n pdf: Uint8Array | Buffer,\n fieldName: string = 'SignatureDebtor',\n anchorText: string = '__SIG_DEBTOR_ANCHOR__',\n ) {\n return await addSignatureFieldUsingAnchor(pdf, fieldName, anchorText);\n }\n\n /**\n * @param pdf The PDF bytes to modify\n * @param options Watermark options (`text` or `image` is required)\n * @returns Modified PDF with the watermark stamped on the selected pages\n * @description Stamps a text or image watermark on an existing PDF. By default the mark is centered, rotated by 45° at 15% opacity on every page. Use `position: 'tile'` to repeat it across the page and `pages` to target specific pages (1-based). To watermark a PDF while generating it, pass the same options as `watermark` in the `PuppeteerParameters`.\n *\n * ```typescript\n * const watermarked = await pdfService.addWatermark(pdf, {\n * text: 'CONFIDENTIAL',\n * color: '#ff0000',\n * opacity: 0.2,\n * });\n * ```\n *\n * Text uses the PDF standard fonts, which only support WinAnsi characters; use an `image` for anything else.\n * @throws WatermarkException when the options are invalid or the PDF cannot be processed\n */\n async addWatermark(pdf: Uint8Array | Buffer, options: WatermarkOptions) {\n return await addWatermark(pdf, options);\n }\n}\n","import {\n DynamicModule,\n Inject,\n InjectionToken,\n Module,\n ModuleMetadata,\n OnModuleInit,\n OptionalFactoryDependency,\n Provider,\n} from '@nestjs/common';\n\nimport { PDF_PARAMETERS } from '../helpers/tokens';\nimport { BrowserService } from './browser/browser.service';\nimport { EjsService } from './engines/ejs/ejs.service';\nimport { EtaService } from './engines/eta/eta.service';\nimport { HandlebarsService } from './engines/handlebars/handlebars.service';\nimport { MjmlService } from './engines/mjml/mjml.service';\nimport { MustacheService } from './engines/mustache/mustache.service';\nimport { NunjucksService } from './engines/nunjucks/nunjucks.service';\nimport { PugService } from './engines/pug/pug.service';\nimport { PuppeteerService } from './puppeteer.service';\nimport type { PuppeteerParameters } from './puppeteer-parameters.interface';\n\nexport interface PuppeteerModuleAsyncOptions extends Pick<\n ModuleMetadata,\n 'imports'\n> {\n inject?: Array<InjectionToken | OptionalFactoryDependency>;\n useFactory: (\n ...args: Array<any>\n ) => Promise<PuppeteerParameters> | PuppeteerParameters;\n}\n\n@Module({\n providers: [\n PuppeteerService,\n BrowserService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n ],\n exports: [\n PuppeteerService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n ],\n})\nexport class PuppeteerModule implements OnModuleInit {\n readonly #browserService: BrowserService;\n readonly #pdfParams: PuppeteerParameters;\n\n constructor(\n browserService: BrowserService,\n @Inject(PDF_PARAMETERS) pdfParams: PuppeteerParameters,\n ) {\n this.#browserService = browserService;\n this.#pdfParams = pdfParams;\n }\n\n async onModuleInit() {\n if (!this.#pdfParams.executablePath) {\n await this.#browserService.install(\n this.#pdfParams.useLockedBrowser ?? false,\n );\n }\n }\n\n static forRoot(pdfParameters: PuppeteerParameters): DynamicModule {\n const providers: Array<Provider> = [\n {\n provide: PDF_PARAMETERS,\n useValue: pdfParameters,\n },\n HandlebarsService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n ];\n\n return {\n module: PuppeteerModule,\n providers,\n exports: [\n PuppeteerService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n ],\n };\n }\n\n static forRootAsync(options: PuppeteerModuleAsyncOptions): DynamicModule {\n const pdfParamsProvider: Provider = {\n provide: PDF_PARAMETERS,\n inject: options.inject ?? [],\n useFactory: async (...args: Array<unknown>) =>\n options.useFactory(...args),\n };\n\n return {\n module: PuppeteerModule,\n imports: options.imports ?? [],\n providers: [\n pdfParamsProvider,\n PuppeteerService,\n BrowserService,\n HandlebarsService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n ],\n exports: [\n PuppeteerService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n ],\n };\n }\n}\n","import { DynamicModule, Module, ModuleMetadata } from '@nestjs/common';\n\nimport { NestjsPdfService } from './nestjs-pdf.service';\nimport { PuppeteerModule } from './puppeteer/puppeteer.module';\nimport { PuppeteerParameters } from './puppeteer/puppeteer-parameters.interface';\n\nexport interface PdfLibModuleAsyncOptions extends Pick<\n ModuleMetadata,\n 'imports'\n> {\n inject?: Array<any>;\n useFactory: (...args: Array<any>) => any;\n}\n\n@Module({})\nexport class NestjsPdfModule {\n static forRoot(options: PuppeteerParameters): DynamicModule {\n return {\n module: NestjsPdfModule,\n imports: [PuppeteerModule.forRoot(options)],\n providers: [NestjsPdfService],\n exports: [NestjsPdfService],\n };\n }\n\n static forRootAsync(options: PdfLibModuleAsyncOptions): DynamicModule {\n return {\n module: NestjsPdfModule,\n imports: [PuppeteerModule.forRootAsync(options)],\n providers: [NestjsPdfService],\n exports: [NestjsPdfService],\n };\n }\n}\n"],"x_google_ignoreList":[13,14],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["PROVIDER","ROUTE"],"sources":["../src/exceptions/nestjs-pdf.exception.ts","../src/exceptions/browser-installation.exception.ts","../src/exceptions/browser-unavailable.exception.ts","../src/exceptions/engine-not-available.exception.ts","../src/exceptions/pdf-generation.exception.ts","../src/exceptions/renderer-configuration.exception.ts","../src/exceptions/signature-dependency.exception.ts","../src/exceptions/signature-placement.exception.ts","../src/exceptions/template-configuration.exception.ts","../src/exceptions/template-render.exception.ts","../src/exceptions/watermark.exception.ts","../src/helpers/getRelativePath.helper.ts","../src/helpers/signature.helper.ts","../src/helpers/watermark.helper.ts","../node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js","../node_modules/.pnpm/p-limit@7.3.3/node_modules/p-limit/index.js","../src/helpers/deepMergePdfparams.ts","../src/helpers/tokens.ts","../src/renderers/pdf-renderer.interface.ts","../src/renderers/http.utils.ts","../src/renderers/pdf-options.mapper.ts","../src/renderers/api2pdf.renderer.ts","../src/renderers/gotenberg.renderer.ts","../src/puppeteer/libs/loadPuppeteer.utils.ts","../src/helpers/request-guard.helper.ts","../src/renderers/puppeteer.renderer.ts","../src/renderers/create-renderer.ts","../src/puppeteer/libs/enum.utils.ts","../src/puppeteer/browser/browser.service.ts","../src/puppeteer/libs/loadEngine.utils.ts","../src/puppeteer/engines/ejs/ejs.service.ts","../src/puppeteer/engines/eta/eta.service.ts","../src/puppeteer/engines/handlebars/handlebars.service.ts","../src/puppeteer/engines/liquid/liquid.service.ts","../src/puppeteer/engines/mjml/mjml.service.ts","../src/puppeteer/engines/mustache/mustache.service.ts","../src/puppeteer/engines/nunjucks/nunjucks.service.ts","../src/puppeteer/engines/pug/pug.service.ts","../src/puppeteer/libs/requireService.utils.ts","../src/puppeteer/puppeteer.service.ts","../src/nestjs-pdf.service.ts","../src/puppeteer/puppeteer.module.ts","../src/nestjs-pdf.module.ts"],"sourcesContent":["export enum NestjsPdfErrorCode {\n ENGINE_NOT_AVAILABLE = 'ENGINE_NOT_AVAILABLE',\n TEMPLATE_CONFIGURATION_ERROR = 'TEMPLATE_CONFIGURATION_ERROR',\n TEMPLATE_RENDER_ERROR = 'TEMPLATE_RENDER_ERROR',\n BROWSER_INSTALLATION_ERROR = 'BROWSER_INSTALLATION_ERROR',\n BROWSER_UNAVAILABLE = 'BROWSER_UNAVAILABLE',\n PDF_GENERATION_ERROR = 'PDF_GENERATION_ERROR',\n SIGNATURE_DEPENDENCY_ERROR = 'SIGNATURE_DEPENDENCY_ERROR',\n SIGNATURE_PLACEMENT_ERROR = 'SIGNATURE_PLACEMENT_ERROR',\n WATERMARK_ERROR = 'WATERMARK_ERROR',\n RENDERER_CONFIGURATION_ERROR = 'RENDERER_CONFIGURATION_ERROR',\n}\n\nexport abstract class NestjsPdfException extends Error {\n abstract readonly code: NestjsPdfErrorCode;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = this.constructor.name;\n }\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class BrowserInstallationException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.BROWSER_INSTALLATION_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class BrowserUnavailableException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.BROWSER_UNAVAILABLE;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class EngineNotAvailableException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.ENGINE_NOT_AVAILABLE;\n\n constructor(\n engineName: string,\n packageName?: string,\n options?: { cause?: unknown },\n ) {\n super(\n packageName\n ? `${engineName} engine is not available: the '${packageName}' package is not installed. Run \\`npm install ${packageName}\\` to use it.`\n : `${engineName} service is not available. If the problem persists, open an issue in the repo.`,\n options,\n );\n }\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class PdfGenerationException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.PDF_GENERATION_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\n/** The PDF provider is misconfigured, or asked for an option it does not support. */\nexport class RendererConfigurationException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.RENDERER_CONFIGURATION_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class SignatureDependencyException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.SIGNATURE_DEPENDENCY_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class SignaturePlacementException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.SIGNATURE_PLACEMENT_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class TemplateConfigurationException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.TEMPLATE_CONFIGURATION_ERROR;\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class TemplateRenderException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.TEMPLATE_RENDER_ERROR;\n\n constructor(\n public readonly engine: string,\n message: string,\n options?: { cause?: unknown },\n ) {\n super(message, options);\n }\n}\n","import { NestjsPdfErrorCode, NestjsPdfException } from './nestjs-pdf.exception';\n\nexport class WatermarkException extends NestjsPdfException {\n readonly code = NestjsPdfErrorCode.WATERMARK_ERROR;\n}\n","import { relative, resolve } from 'node:path';\n\n/**\n * Get the relative path to a value from the module directory.\n * @param moduleDir the path of the module, typically __dirname\n * @param relativeToModule the path to the value relative to the module directory\n * @returns the relative path from the current working directory to the value\n * @example\n * getRelativePathToValue(__dirname, './templates/my-template.hbs');\n * // returns 'context/pdf/templates/my-template.hbs' if the current working directory is '/\n */\nexport function getRelativePathToValue(\n moduleDir: string,\n relativeToModule: string,\n): string {\n const fullTemplatePath = resolve(moduleDir, relativeToModule);\n return relative(process.cwd(), fullTemplatePath);\n}\n","import {\n PDFArray,\n PDFDict,\n PDFDocument,\n PDFName,\n PDFNumber,\n PDFString,\n} from 'pdf-lib';\nimport type { TextItem } from 'pdfjs-dist/types/src/display/api';\n\nimport {\n SignatureDependencyException,\n SignaturePlacementException,\n} from '../exceptions';\n\n// eslint-disable-next-line @typescript-eslint/consistent-type-imports\nlet pdfjsPromise: typeof import('pdfjs-dist/legacy/build/pdf.mjs') | undefined;\n\nasync function loadPdfjs() {\n if (!pdfjsPromise) {\n try {\n pdfjsPromise = await import('pdfjs-dist/legacy/build/pdf.mjs');\n } catch (error) {\n pdfjsPromise = undefined;\n /* v8 ignore next -- import() rejections are always Error instances in practice */\n const reason = error instanceof Error ? error.message : String(error);\n throw new SignatureDependencyException(\n [\n 'Failed to load pdfjs-dist.',\n 'If you use anchor-based signature placement in Node.js, make sure @napi-rs/canvas is installed.',\n 'Try: npm install @napi-rs/canvas',\n '',\n `Original error: ${reason}`,\n ].join('\\n'),\n { cause: error },\n );\n }\n }\n return pdfjsPromise;\n}\n\nfunction toU8(input: Uint8Array | Buffer): Uint8Array {\n return new Uint8Array(input);\n}\n\nasync function findAnchorPosition(\n pdfBytes: Uint8Array,\n anchorText: string,\n): Promise<null | {\n pageIndex: number;\n x: number;\n y: number;\n pageWidth: number;\n pageHeight: number;\n}> {\n const pdfjsLib = await loadPdfjs();\n const loadingTask = pdfjsLib.getDocument({ data: pdfBytes });\n\n try {\n const pdf = await loadingTask.promise;\n\n for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\n const page = await pdf.getPage(pageNum);\n const viewport = page.getViewport({ scale: 1 });\n const textContent = await page.getTextContent();\n\n for (const itemRaw of textContent.items) {\n const item = itemRaw as TextItem;\n const str = item.str;\n if (!str?.includes(anchorText)) continue;\n\n const t = pdfjsLib.Util.transform(viewport.transform, item.transform);\n const [_a, _b, _c, _d, e, f] = t as Array<number>;\n\n const x = e;\n const y = viewport.height - f;\n\n return {\n pageIndex: pageNum - 1,\n x,\n y,\n pageWidth: viewport.width,\n pageHeight: viewport.height,\n };\n }\n }\n return null;\n } finally {\n await loadingTask.destroy();\n }\n}\n\nfunction addSignatureFieldAt(\n pdfDoc: PDFDocument,\n pageIndex: number,\n opts: {\n fieldName: string;\n x: number;\n y: number;\n width: number;\n height: number;\n },\n) {\n const { fieldName, x, y, width, height } = opts;\n const context = pdfDoc.context;\n\n const page = pdfDoc.getPages()[pageIndex];\n\n const rectArray = context.obj([\n PDFNumber.of(x),\n PDFNumber.of(y),\n PDFNumber.of(x + width),\n PDFNumber.of(y + height),\n ]);\n\n const widgetDict = context.obj({\n Type: PDFName.of('Annot'),\n Subtype: PDFName.of('Widget'),\n Rect: rectArray,\n F: PDFNumber.of(4),\n P: page.ref,\n });\n const widgetRef = context.register(widgetDict);\n\n const fieldDict = context.obj({\n FT: PDFName.of('Sig'),\n T: PDFString.of(fieldName),\n Ff: PDFNumber.of(0),\n Kids: context.obj([widgetRef]),\n });\n const fieldRef = context.register(fieldDict);\n\n widgetDict.set(PDFName.of('Parent'), fieldRef);\n\n let annots = page.node.lookupMaybe(PDFName.of('Annots'), PDFArray);\n if (!annots) {\n annots = context.obj([]);\n page.node.set(PDFName.of('Annots'), annots);\n }\n annots.push(widgetRef);\n\n let acroForm = pdfDoc.catalog.lookupMaybe(PDFName.of('AcroForm'), PDFDict);\n if (!acroForm) {\n acroForm = context.obj({\n Fields: context.obj([]),\n SigFlags: PDFNumber.of(3),\n });\n const acroFormRef = context.register(acroForm);\n pdfDoc.catalog.set(PDFName.of('AcroForm'), acroFormRef);\n }\n\n let fields = acroForm.lookupMaybe(PDFName.of('Fields'), PDFArray);\n if (!fields) {\n fields = context.obj([]);\n acroForm.set(PDFName.of('Fields'), fields);\n }\n fields.push(fieldRef);\n\n return { fieldRef, widgetRef };\n}\n\nexport async function addSignatureFieldUsingAnchor(\n pdf: Uint8Array | Buffer,\n fieldName = 'SignatureDebtor',\n anchorText = '__SIG_DEBTOR_ANCHOR__',\n) {\n const bytes = toU8(pdf);\n\n const anchor = await findAnchorPosition(bytes.slice(), anchorText);\n\n const pdfDoc = await PDFDocument.load(bytes);\n\n const sigWidth = 240;\n const sigHeight = 50;\n\n if (anchor) {\n const pageIndex = anchor.pageIndex;\n const page = pdfDoc.getPages()[pageIndex];\n if (!page) {\n throw new SignaturePlacementException(`Page ${pageIndex} not found`);\n }\n const { width: pw, height: ph } = page.getSize();\n\n const padX = 40;\n const padY = 7;\n let x = anchor.x - sigWidth / 2 + padX;\n\n let y = anchor.y - sigHeight + padY;\n\n const margin = 10;\n\n x = Math.max(margin, Math.min(x, pw - sigWidth - margin));\n y = Math.max(margin, Math.min(y, ph - sigHeight - margin));\n\n addSignatureFieldAt(pdfDoc, anchor.pageIndex, {\n fieldName,\n x,\n y,\n width: sigWidth,\n height: sigHeight,\n });\n } else {\n const pages = pdfDoc.getPages();\n const pageIndex = pages.length - 1;\n const page = pages.at(-1);\n /* v8 ignore next -- pdf-lib always produces at least one page on save/load; only a hand-crafted, malformed PDF could hit this */\n if (!page) {\n throw new SignaturePlacementException(`Page ${pageIndex} not found`);\n }\n const { width: pageWidth } = page.getSize();\n const x = (pageWidth - sigWidth) / 2;\n const y = 90;\n\n addSignatureFieldAt(pdfDoc, pageIndex, {\n fieldName,\n x,\n y,\n width: sigWidth,\n height: sigHeight,\n });\n }\n\n return await pdfDoc.save();\n}\n\n// Test helper to inject a mocked pdfjs implementation and avoid dynamic import in tests\n// This helper throws outside of tests to avoid exposing a test-only API in production.\nexport function __setPdfjsForTests(p: any) {\n if (process.env.NODE_ENV !== 'test') {\n throw new Error('__setPdfjsForTests is only available in test environment');\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n pdfjsPromise = p;\n}\n","import {\n degrees,\n PDFDocument,\n type PDFImage,\n type PDFPage,\n rgb,\n StandardFonts,\n} from 'pdf-lib';\n\nimport { WatermarkException } from '../exceptions';\n\nexport interface WatermarkOptions {\n /** Text to stamp. At least one of `text` or `image` is required. */\n text?: string;\n /** PNG or JPEG bytes to stamp. At least one of `text` or `image` is required. */\n image?: Uint8Array | Buffer;\n /** Opacity between 0 (invisible) and 1 (opaque). Default: 0.15 */\n opacity?: number;\n /** Counter-clockwise rotation in degrees. Default: 45 */\n rotation?: number;\n /** Text font size in points. Default: 60 */\n fontSize?: number;\n /** One of the PDF standard fonts (WinAnsi characters only). Default: 'HelveticaBold' */\n font?: keyof typeof StandardFonts;\n /** Text color as `#rgb` or `#rrggbb`. Default: '#808080' */\n color?: string;\n /** Rendered image width in points (aspect ratio preserved). Default: 50% of the page width */\n imageWidth?: number;\n /** `center` stamps once per page, `tile` repeats the mark across the page. Default: 'center' */\n position?: 'center' | 'tile';\n /** Gap in points between two marks when `position` is `tile`. Default: 100 */\n tileSpacing?: number;\n /** 1-based page numbers to watermark. Default: all pages */\n pages?: Array<number>;\n}\n\nconst DEFAULT_OPACITY = 0.15;\nconst DEFAULT_ROTATION = 45;\nconst DEFAULT_FONT_SIZE = 60;\nconst DEFAULT_FONT: keyof typeof StandardFonts = 'HelveticaBold';\nconst DEFAULT_COLOR = '#808080';\nconst DEFAULT_TILE_SPACING = 100;\n\ninterface Mark {\n width: number;\n height: number;\n draw: (page: PDFPage, x: number, y: number) => void;\n}\n\nfunction parseHexColor(color: string) {\n const match = /^#([\\da-f]{3}|[\\da-f]{6})$/i.exec(color);\n if (!match) {\n throw new WatermarkException(\n `Invalid watermark color \"${color}\", expected #rgb or #rrggbb`,\n );\n }\n const hex =\n match[1].length === 3 ? [...match[1]].map((c) => c + c).join('') : match[1];\n const channel = (i: number) => Number.parseInt(hex.slice(i, i + 2), 16) / 255;\n return rgb(channel(0), channel(2), channel(4));\n}\n\nfunction embedImage(pdfDoc: PDFDocument, bytes: Uint8Array): Promise<PDFImage> {\n const isPng = bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4e;\n const isJpeg = bytes[0] === 0xff && bytes[1] === 0xd8;\n if (isPng) return pdfDoc.embedPng(bytes);\n if (isJpeg) return pdfDoc.embedJpg(bytes);\n throw new WatermarkException('Watermark image must be a PNG or JPEG');\n}\n\nfunction validate(options: WatermarkOptions) {\n const { text, image, opacity, fontSize, imageWidth, tileSpacing } = options;\n if (!text && !image) {\n throw new WatermarkException(\n 'A watermark requires at least a `text` or an `image`',\n );\n }\n if (opacity !== undefined && !(opacity >= 0 && opacity <= 1)) {\n throw new WatermarkException('Watermark `opacity` must be between 0 and 1');\n }\n if (fontSize !== undefined && !(fontSize > 0)) {\n throw new WatermarkException('Watermark `fontSize` must be greater than 0');\n }\n if (imageWidth !== undefined && !(imageWidth > 0)) {\n throw new WatermarkException(\n 'Watermark `imageWidth` must be greater than 0',\n );\n }\n if (tileSpacing !== undefined && !(tileSpacing >= 0)) {\n throw new WatermarkException('Watermark `tileSpacing` must be at least 0');\n }\n}\n\nfunction resolvePageIndexes(pages: Array<number> | undefined, total: number) {\n if (!pages) {\n return Array.from({ length: total }, (_, i) => i);\n }\n for (const page of pages) {\n if (!Number.isInteger(page) || page < 1 || page > total) {\n throw new WatermarkException(\n `Watermark page ${page} is out of range (the PDF has ${total} page(s))`,\n );\n }\n }\n return [...new Set(pages)].map((page) => page - 1);\n}\n\n/**\n * Centers of the marks for one page, in page coordinates. Tiles follow the\n * rotated axes so rotated marks never overlap each other.\n */\nfunction markCenters(\n pageWidth: number,\n pageHeight: number,\n mark: Mark,\n options: { position: 'center' | 'tile'; rotation: number; spacing: number },\n) {\n const cx = pageWidth / 2;\n const cy = pageHeight / 2;\n if (options.position === 'center') {\n return [{ x: cx, y: cy }];\n }\n\n const theta = (options.rotation * Math.PI) / 180;\n const cos = Math.cos(theta);\n const sin = Math.sin(theta);\n const stepX = mark.width + options.spacing;\n const stepY = mark.height + options.spacing;\n const reach = Math.hypot(mark.width, mark.height) / 2;\n const n = Math.ceil(\n (Math.hypot(pageWidth, pageHeight) / 2 + reach) / Math.min(stepX, stepY),\n );\n\n const centers: Array<{ x: number; y: number }> = [];\n for (let i = -n; i <= n; i++) {\n for (let j = -n; j <= n; j++) {\n const x = cx + i * stepX * cos - j * stepY * sin;\n const y = cy + i * stepX * sin + j * stepY * cos;\n if (\n x >= -reach &&\n x <= pageWidth + reach &&\n y >= -reach &&\n y <= pageHeight + reach\n ) {\n centers.push({ x, y });\n }\n }\n }\n return centers;\n}\n\nasync function buildMark(\n pdfDoc: PDFDocument,\n options: WatermarkOptions,\n pageWidth: number,\n): Promise<Mark> {\n const opacity = options.opacity ?? DEFAULT_OPACITY;\n const rotate = degrees(options.rotation ?? DEFAULT_ROTATION);\n\n if (options.image) {\n const image = await embedImage(pdfDoc, new Uint8Array(options.image));\n const width = options.imageWidth ?? pageWidth / 2;\n const height = (image.height / image.width) * width;\n return {\n width,\n height,\n draw: (page, x, y) =>\n page.drawImage(image, { x, y, width, height, opacity, rotate }),\n };\n }\n\n const font = await pdfDoc.embedFont(\n StandardFonts[options.font ?? DEFAULT_FONT],\n );\n const size = options.fontSize ?? DEFAULT_FONT_SIZE;\n const text = options.text!;\n const color = parseHexColor(options.color ?? DEFAULT_COLOR);\n let width: number;\n try {\n width = font.widthOfTextAtSize(text, size);\n } catch (error) {\n throw new WatermarkException(\n `Watermark text cannot be rendered with the ${options.font ?? DEFAULT_FONT} font (only WinAnsi characters are supported)`,\n { cause: error },\n );\n }\n return {\n width,\n height: font.heightAtSize(size, { descender: false }),\n draw: (page, x, y) =>\n page.drawText(text, { x, y, size, font, color, opacity, rotate }),\n };\n}\n\n/**\n * Stamps a text or image watermark on the pages of an existing PDF.\n */\nexport async function addWatermark(\n pdf: Uint8Array | Buffer,\n options: WatermarkOptions,\n): Promise<Uint8Array> {\n validate(options);\n\n try {\n const pdfDoc = await PDFDocument.load(new Uint8Array(pdf));\n const pages = pdfDoc.getPages();\n const indexes = resolvePageIndexes(options.pages, pages.length);\n\n const position = options.position ?? 'center';\n const rotation = options.rotation ?? DEFAULT_ROTATION;\n const spacing = options.tileSpacing ?? DEFAULT_TILE_SPACING;\n const theta = (rotation * Math.PI) / 180;\n const cos = Math.cos(theta);\n const sin = Math.sin(theta);\n\n // The image width depends on the page width, so marks are cached per width.\n const marks = new Map<number, Mark>();\n\n for (const index of indexes) {\n const page = pages[index];\n const { width: pageWidth, height: pageHeight } = page.getSize();\n\n let mark = marks.get(pageWidth);\n if (!mark) {\n mark = await buildMark(pdfDoc, options, pageWidth);\n marks.set(pageWidth, mark);\n }\n\n for (const center of markCenters(pageWidth, pageHeight, mark, {\n position,\n rotation,\n spacing,\n })) {\n // drawText/drawImage rotate around the bottom-left corner, so shift\n // the origin to make the mark's own center land on `center`.\n mark.draw(\n page,\n center.x - ((mark.width / 2) * cos - (mark.height / 2) * sin),\n center.y - ((mark.width / 2) * sin + (mark.height / 2) * cos),\n );\n }\n }\n\n return await pdfDoc.save();\n } catch (error) {\n if (error instanceof WatermarkException) throw error;\n throw new WatermarkException(\n `Failed to add watermark: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error },\n );\n }\n}\n","/*\nHow it works:\n`this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value.\n*/\n\nclass Node {\n\tvalue;\n\tnext;\n\n\tconstructor(value) {\n\t\tthis.value = value;\n\t}\n}\n\nexport default class Queue {\n\t#head;\n\t#tail;\n\t#size;\n\n\tconstructor() {\n\t\tthis.clear();\n\t}\n\n\tenqueue(value) {\n\t\tconst node = new Node(value);\n\n\t\tif (this.#head) {\n\t\t\tthis.#tail.next = node;\n\t\t\tthis.#tail = node;\n\t\t} else {\n\t\t\tthis.#head = node;\n\t\t\tthis.#tail = node;\n\t\t}\n\n\t\tthis.#size++;\n\t}\n\n\tdequeue() {\n\t\tconst current = this.#head;\n\t\tif (!current) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#head = this.#head.next;\n\t\tthis.#size--;\n\n\t\t// Clean up tail reference when queue becomes empty\n\t\tif (!this.#head) {\n\t\t\tthis.#tail = undefined;\n\t\t}\n\n\t\treturn current.value;\n\t}\n\n\tpeek() {\n\t\tif (!this.#head) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this.#head.value;\n\n\t\t// TODO: Node.js 18.\n\t\t// return this.#head?.value;\n\t}\n\n\tclear() {\n\t\tthis.#head = undefined;\n\t\tthis.#tail = undefined;\n\t\tthis.#size = 0;\n\t}\n\n\tget size() {\n\t\treturn this.#size;\n\t}\n\n\t* [Symbol.iterator]() {\n\t\tlet current = this.#head;\n\n\t\twhile (current) {\n\t\t\tyield current.value;\n\t\t\tcurrent = current.next;\n\t\t}\n\t}\n\n\t* drain() {\n\t\twhile (this.#head) {\n\t\t\tyield this.dequeue();\n\t\t}\n\t}\n}\n","import Queue from 'yocto-queue';\n\nexport default function pLimit(concurrency) {\n\tlet rejectOnClear = false;\n\n\tif (typeof concurrency === 'object') {\n\t\t({concurrency, rejectOnClear = false} = concurrency);\n\t}\n\n\tvalidateConcurrency(concurrency);\n\n\tif (typeof rejectOnClear !== 'boolean') {\n\t\tthrow new TypeError('Expected `rejectOnClear` to be a boolean');\n\t}\n\n\tconst queue = new Queue();\n\tlet activeCount = 0;\n\n\tconst resumeNext = () => {\n\t\t// Process the next queued function if we're under the concurrency limit\n\t\tif (activeCount < concurrency && queue.size > 0) {\n\t\t\tactiveCount++;\n\t\t\tqueue.dequeue().run();\n\t\t}\n\t};\n\n\tconst next = () => {\n\t\tactiveCount--;\n\t\tresumeNext();\n\t};\n\n\tconst run = async (function_, resolve, arguments_) => {\n\t\t// Execute the function and capture the result promise\n\t\tconst result = (async () => function_(...arguments_))();\n\n\t\t// Resolve immediately with the promise (don't wait for completion)\n\t\tresolve(result);\n\n\t\t// Wait for the function to complete (success or failure)\n\t\t// We catch errors here to prevent unhandled rejections,\n\t\t// but the original promise rejection is preserved for the caller\n\t\ttry {\n\t\t\tawait result;\n\t\t} catch {}\n\n\t\t// Decrement active count and process next queued function\n\t\tnext();\n\t};\n\n\tconst enqueue = (function_, resolve, reject, arguments_) => {\n\t\tconst queueItem = {reject};\n\n\t\t// Queue the internal resolve function instead of the run function\n\t\t// to preserve the asynchronous execution context.\n\t\tnew Promise(internalResolve => { // eslint-disable-line promise/param-names\n\t\t\tqueueItem.run = internalResolve;\n\t\t\tqueue.enqueue(queueItem);\n\t\t}).then(run.bind(undefined, function_, resolve, arguments_)); // eslint-disable-line promise/prefer-await-to-then\n\n\t\t// Start processing immediately if we haven't reached the concurrency limit\n\t\tif (activeCount < concurrency) {\n\t\t\tresumeNext();\n\t\t}\n\t};\n\n\tconst generator = (function_, ...arguments_) => new Promise((resolve, reject) => {\n\t\tenqueue(function_, resolve, reject, arguments_);\n\t});\n\n\tObject.defineProperties(generator, {\n\t\tactiveCount: {\n\t\t\tget: () => activeCount,\n\t\t},\n\t\tpendingCount: {\n\t\t\tget: () => queue.size,\n\t\t},\n\t\tclearQueue: {\n\t\t\tvalue() {\n\t\t\t\tif (!rejectOnClear) {\n\t\t\t\t\tqueue.clear();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst abortError = AbortSignal.abort().reason;\n\n\t\t\t\twhile (queue.size > 0) {\n\t\t\t\t\tqueue.dequeue().reject(abortError);\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\tconcurrency: {\n\t\t\tget: () => concurrency,\n\n\t\t\tset(newConcurrency) {\n\t\t\t\tvalidateConcurrency(newConcurrency);\n\t\t\t\tconcurrency = newConcurrency;\n\n\t\t\t\tqueueMicrotask(() => {\n\t\t\t\t\t// eslint-disable-next-line no-unmodified-loop-condition\n\t\t\t\t\twhile (activeCount < concurrency && queue.size > 0) {\n\t\t\t\t\t\tresumeNext();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t},\n\t\tmap: {\n\t\t\tasync value(iterable, function_) {\n\t\t\t\tconst promises = [];\n\n\t\t\t\ttry {\n\t\t\t\t\tArray.from(iterable, (value, index) => {\n\t\t\t\t\t\tconst promise = generator(function_, value, index);\n\t\t\t\t\t\tpromises.push(promise);\n\t\t\t\t\t\treturn promise;\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// The iterable threw, so `Promise.all` never observes the already scheduled promises. Observe them here to avoid unhandled rejections.\n\t\t\t\t\tfor (const promise of promises) {\n\t\t\t\t\t\tpromise.catch(() => {}); // eslint-disable-line promise/prefer-await-to-then\n\t\t\t\t\t}\n\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\treturn Promise.all(promises);\n\t\t\t},\n\t\t},\n\t});\n\n\treturn generator;\n}\n\nexport function limitFunction(function_, options) {\n\tconst limit = pLimit(options);\n\n\tconst limitedFunction = (...arguments_) => limit(() => function_(...arguments_));\n\tObject.defineProperty(limitedFunction, 'clearQueue', {\n\t\tvalue: limit.clearQueue,\n\t});\n\n\treturn limitedFunction;\n}\n\nfunction validateConcurrency(concurrency) {\n\tif (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {\n\t\tthrow new TypeError('Expected `concurrency` to be a number from 1 and up');\n\t}\n}\n","import { deepmerge } from 'deepmerge-ts';\n\nimport { type PuppeteerParameters } from '../puppeteer/puppeteer-parameters.interface';\n\nexport function mergePuppeteerParameters(\n defaults: PuppeteerParameters,\n overrides?: PuppeteerParameters,\n): PuppeteerParameters {\n if (!overrides) {\n return { ...defaults };\n }\n\n return deepmerge(defaults, overrides);\n}\n","export const PDF_PARAMETERS = 'PDF_PARAMETERS' as const;\n","import type { PuppeteerParameters } from '../puppeteer/puppeteer-parameters.interface';\n\nexport const PDF_RENDERER = 'PDF_RENDERER' as const;\n\n/** Turns an HTML document into a PDF. One implementation per provider. */\nexport interface PdfRenderer {\n /**\n * @param html the HTML document to print\n * @param options the generation options, already merged with the module defaults\n * @param signal aborts the rendering; the promise then rejects\n */\n render(\n html: string,\n options: PuppeteerParameters,\n signal?: AbortSignal,\n ): Promise<Uint8Array>;\n}\n","import {\n PdfGenerationException,\n RendererConfigurationException,\n} from '../exceptions';\nimport type { PuppeteerParameters } from '../puppeteer/puppeteer-parameters.interface';\n\nconst MAX_ERROR_BODY_LENGTH = 500;\n\n/** Builds a `PdfGenerationException` from a failed HTTP response, body included. */\nexport async function httpError(\n provider: string,\n response: Response,\n): Promise<PdfGenerationException> {\n let body = '';\n try {\n body = (await response.text()).trim().slice(0, MAX_ERROR_BODY_LENGTH);\n } catch {\n // The status is enough when the body cannot be read.\n }\n\n return new PdfGenerationException(\n `${provider} responded with HTTP ${response.status}${body ? `: ${body}` : ''}`,\n );\n}\n\n/** Remote providers render on another machine: the local request guard cannot run there. */\nexport function assertNoRequestGuard(\n provider: string,\n options: PuppeteerParameters,\n hint: string,\n): void {\n if (options.security) {\n throw new RendererConfigurationException(\n `The 'security' option is only supported by the puppeteer provider, not by ${provider}. ${hint}`,\n );\n }\n}\n\nexport function requireNonEmpty(\n value: string | undefined,\n name: string,\n provider: string,\n): string {\n if (!value?.trim()) {\n throw new RendererConfigurationException(\n `The ${provider} provider requires a non-empty '${name}'`,\n );\n }\n return value;\n}\n","import { RendererConfigurationException } from '../exceptions';\nimport type { PdfOptions } from './pdf-options.interface';\n\n/** Paper sizes in inches, as Puppeteer defines them. */\nconst PAPER_FORMATS: Record<string, { width: number; height: number }> = {\n letter: { width: 8.5, height: 11 },\n legal: { width: 8.5, height: 14 },\n tabloid: { width: 11, height: 17 },\n ledger: { width: 17, height: 11 },\n a0: { width: 33.1102, height: 46.811 },\n a1: { width: 23.3858, height: 33.1102 },\n a2: { width: 16.5354, height: 23.3858 },\n a3: { width: 11.6929, height: 16.5354 },\n a4: { width: 8.2677, height: 11.6929 },\n a5: { width: 5.8268, height: 8.2677 },\n a6: { width: 4.1339, height: 5.8268 },\n};\n\nconst INCHES_PER_UNIT: Record<string, number> = {\n px: 1 / 96,\n in: 1,\n cm: 1 / 2.54,\n mm: 1 / 25.4,\n};\n\n/**\n * Converts a Puppeteer length (a number of pixels, or a string with a\n * `px`/`in`/`cm`/`mm` unit) to inches.\n */\nexport function toInches(value: string | number): number {\n if (typeof value === 'number') {\n return value * INCHES_PER_UNIT.px;\n }\n\n const match = /^\\s*(-?\\d*\\.?\\d+)\\s*(px|in|cm|mm)?\\s*$/i.exec(value);\n if (!match) {\n throw new RendererConfigurationException(\n `Invalid length '${value}': expected a number of pixels or a value in px, in, cm or mm`,\n );\n }\n\n const unit = (match[2] ?? 'px').toLowerCase();\n return Number(match[1]) * INCHES_PER_UNIT[unit];\n}\n\nfunction formatInches(inches: number): string {\n return String(Math.round(inches * 10_000) / 10_000);\n}\n\nexport interface PrintLayout {\n /** Paper width, in inches. */\n width: number;\n /** Paper height, in inches. */\n height: number;\n margin: { top?: number; right?: number; bottom?: number; left?: number };\n}\n\nexport function resolvePrintLayout(pdfOptions: PdfOptions): PrintLayout {\n let width: number;\n let height: number;\n\n if (pdfOptions.width !== undefined || pdfOptions.height !== undefined) {\n const fallback = PAPER_FORMATS.letter;\n width =\n pdfOptions.width === undefined\n ? fallback.width\n : toInches(pdfOptions.width);\n height =\n pdfOptions.height === undefined\n ? fallback.height\n : toInches(pdfOptions.height);\n } else {\n const formatName = (pdfOptions.format ?? 'letter').toLowerCase();\n const format = PAPER_FORMATS[formatName];\n if (!format) {\n throw new RendererConfigurationException(\n `Unknown paper format '${pdfOptions.format}'`,\n );\n }\n ({ width, height } = format);\n }\n\n const margin: PrintLayout['margin'] = {};\n for (const side of ['top', 'right', 'bottom', 'left'] as const) {\n const value = pdfOptions.margin?.[side];\n if (value !== undefined) {\n margin[side] = toInches(value);\n }\n }\n\n return { width, height, margin };\n}\n\nfunction toHtmlDocument(template: string): string {\n return /<html[\\s>]/i.test(template)\n ? template\n : `<!DOCTYPE html><html><head></head><body>${template}</body></html>`;\n}\n\nexport interface GotenbergForm {\n fields: Record<string, string>;\n /** Extra files, by form name (`header.html`, `footer.html`). */\n files: Record<string, string>;\n}\n\nexport function toGotenbergForm(pdfOptions: PdfOptions): GotenbergForm {\n const { width, height, margin } = resolvePrintLayout(pdfOptions);\n\n const fields: Record<string, string> = {\n paperWidth: formatInches(width),\n paperHeight: formatInches(height),\n // Puppeteer's default margin is 0, Gotenberg's is 0.39in.\n marginTop: formatInches(margin.top ?? 0),\n marginRight: formatInches(margin.right ?? 0),\n marginBottom: formatInches(margin.bottom ?? 0),\n marginLeft: formatInches(margin.left ?? 0),\n // Same rendering as the Puppeteer provider: screen media, wait for the network.\n emulatedMediaType: 'screen',\n skipNetworkIdleEvent: 'false',\n };\n\n if (pdfOptions.landscape !== undefined) {\n fields.landscape = String(pdfOptions.landscape);\n }\n if (pdfOptions.printBackground !== undefined) {\n fields.printBackground = String(pdfOptions.printBackground);\n }\n if (pdfOptions.omitBackground !== undefined) {\n fields.omitBackground = String(pdfOptions.omitBackground);\n }\n if (pdfOptions.scale !== undefined) fields.scale = String(pdfOptions.scale);\n if (pdfOptions.pageRanges) fields.nativePageRanges = pdfOptions.pageRanges;\n if (pdfOptions.preferCSSPageSize !== undefined) {\n fields.preferCssPageSize = String(pdfOptions.preferCSSPageSize);\n }\n if (pdfOptions.tagged !== undefined) {\n fields.generateTaggedPdf = String(pdfOptions.tagged);\n }\n if (pdfOptions.outline !== undefined) {\n fields.generateDocumentOutline = String(pdfOptions.outline);\n }\n\n const files: Record<string, string> = {};\n if (pdfOptions.displayHeaderFooter) {\n if (pdfOptions.headerTemplate) {\n files['header.html'] = toHtmlDocument(pdfOptions.headerTemplate);\n }\n if (pdfOptions.footerTemplate) {\n files['footer.html'] = toHtmlDocument(pdfOptions.footerTemplate);\n }\n }\n\n return { fields, files };\n}\n\nexport function toApi2PdfOptions(\n pdfOptions: PdfOptions,\n): Record<string, unknown> {\n const { width, height, margin } = resolvePrintLayout(pdfOptions);\n\n const options: Record<string, unknown> = {\n width: `${formatInches(width)}in`,\n height: `${formatInches(height)}in`,\n marginTop: `${formatInches(margin.top ?? 0)}in`,\n marginRight: `${formatInches(margin.right ?? 0)}in`,\n marginBottom: `${formatInches(margin.bottom ?? 0)}in`,\n marginLeft: `${formatInches(margin.left ?? 0)}in`,\n // Same rendering as the Puppeteer provider: screen media.\n usePrintCss: false,\n };\n\n const passthrough = [\n 'landscape',\n 'printBackground',\n 'omitBackground',\n 'scale',\n 'pageRanges',\n 'displayHeaderFooter',\n 'headerTemplate',\n 'footerTemplate',\n ] as const;\n for (const key of passthrough) {\n if (pdfOptions[key] !== undefined) {\n options[key] = pdfOptions[key];\n }\n }\n\n return options;\n}\n","import { PdfGenerationException } from '../exceptions';\nimport type { PuppeteerParameters } from '../puppeteer/puppeteer-parameters.interface';\nimport { assertNoRequestGuard, httpError, requireNonEmpty } from './http.utils';\nimport { toApi2PdfOptions } from './pdf-options.mapper';\nimport type { Api2PdfProviderOptions } from './pdf-provider.interface';\nimport type { PdfRenderer } from './pdf-renderer.interface';\n\nconst PROVIDER = 'Api2Pdf';\nconst DEFAULT_BASE_URL = 'https://v2.api2pdf.com';\nconst ROUTE = '/chrome/pdf/html';\n\ninterface Api2PdfResponse {\n Success?: boolean;\n Error?: string | null;\n FileUrl?: string | null;\n}\n\nfunction isApi2Pdf(data: unknown): data is Api2PdfResponse {\n return (\n typeof data === 'object' &&\n data !== null &&\n ('Success' in data || 'Error' in data || 'FileUrl' in data)\n );\n}\n\nexport class Api2PdfRenderer implements PdfRenderer {\n readonly #endpoint: string;\n readonly #headers: Record<string, string>;\n\n constructor(provider: Api2PdfProviderOptions) {\n const apiKey = requireNonEmpty(provider.apiKey, 'apiKey', PROVIDER);\n const baseUrl = requireNonEmpty(\n provider.baseUrl ?? DEFAULT_BASE_URL,\n 'baseUrl',\n PROVIDER,\n ).replace(/\\/+$/, '');\n this.#endpoint = `${baseUrl}${ROUTE}?outputBinary=true`;\n this.#headers = {\n ...provider.headers,\n Authorization: apiKey,\n 'Content-Type': 'application/json',\n Accept: 'application/pdf, application/json',\n };\n }\n\n async render(\n html: string,\n options: PuppeteerParameters,\n signal?: AbortSignal,\n ): Promise<Uint8Array> {\n assertNoRequestGuard(\n PROVIDER,\n options,\n 'Only render trusted HTML with a remote provider.',\n );\n\n const api2pdfOptions = {\n ...toApi2PdfOptions(options.pdfOptions ?? { format: 'A4' }),\n ...options.api2pdfOptions?.options,\n };\n const body: Record<string, unknown> = {\n html,\n inline: false,\n options: api2pdfOptions,\n };\n if (options.api2pdfOptions?.fileName) {\n body.fileName = options.api2pdfOptions.fileName;\n }\n\n const response = await fetch(this.#endpoint, {\n method: 'POST',\n headers: this.#headers,\n body: JSON.stringify(body),\n signal,\n });\n if (!response.ok) {\n throw await httpError(PROVIDER, response);\n }\n\n if (!response.headers.get('content-type')?.includes('application/json')) {\n return new Uint8Array(await response.arrayBuffer());\n }\n\n const result: unknown = await response.json();\n if (!isApi2Pdf(result)) {\n throw new PdfGenerationException(\n `${PROVIDER} returned an unexpected response: ${JSON.stringify(result)}`,\n );\n }\n if (result.Success === false || !result.FileUrl) {\n throw new PdfGenerationException(\n `${PROVIDER} could not generate the PDF: ${result.Error ?? 'no file returned'}`,\n );\n }\n\n const file = await fetch(result.FileUrl, { signal });\n if (!file.ok) {\n throw await httpError(PROVIDER, file);\n }\n return new Uint8Array(await file.arrayBuffer());\n }\n}\n","import type { PuppeteerParameters } from '../puppeteer/puppeteer-parameters.interface';\nimport { assertNoRequestGuard, httpError, requireNonEmpty } from './http.utils';\nimport { toGotenbergForm } from './pdf-options.mapper';\nimport type { GotenbergProviderOptions } from './pdf-provider.interface';\nimport type { PdfRenderer } from './pdf-renderer.interface';\n\nconst PROVIDER = 'Gotenberg';\nconst ROUTE = '/forms/chromium/convert/html';\n\nexport class GotenbergRenderer implements PdfRenderer {\n readonly #endpoint: string;\n readonly #headers: Record<string, string>;\n\n constructor(provider: GotenbergProviderOptions) {\n const url = requireNonEmpty(provider.url, 'url', PROVIDER);\n this.#endpoint = `${url.replace(/\\/+$/, '')}${ROUTE}`;\n\n this.#headers = { ...provider.headers };\n if (provider.basicAuth) {\n const { username, password } = provider.basicAuth;\n this.#headers.Authorization = `Basic ${Buffer.from(\n `${username}:${password}`,\n ).toString('base64')}`;\n }\n }\n\n async render(\n html: string,\n options: PuppeteerParameters,\n signal?: AbortSignal,\n ): Promise<Uint8Array> {\n assertNoRequestGuard(\n PROVIDER,\n options,\n \"Restrict outbound requests on the Gotenberg server instead, with '--chromium-allow-list' / '--chromium-deny-list'.\",\n );\n\n const { fields, files } = toGotenbergForm(\n options.pdfOptions ?? { format: 'A4' },\n );\n\n const form = new FormData();\n form.append('files', new Blob([html], { type: 'text/html' }), 'index.html');\n for (const [name, content] of Object.entries(files)) {\n form.append('files', new Blob([content], { type: 'text/html' }), name);\n }\n for (const asset of options.gotenbergOptions?.assets ?? []) {\n form.append(\n 'files',\n new Blob([asset.content as BlobPart], {\n type: asset.contentType ?? 'application/octet-stream',\n }),\n asset.filename,\n );\n }\n const allFields = { ...fields, ...options.gotenbergOptions?.formFields };\n for (const [name, value] of Object.entries(allFields)) {\n form.append(name, value);\n }\n\n const response = await fetch(this.#endpoint, {\n method: 'POST',\n headers: this.#headers,\n body: form,\n signal,\n });\n if (!response.ok) {\n throw await httpError(PROVIDER, response);\n }\n\n return new Uint8Array(await response.arrayBuffer());\n }\n}\n","import type * as PuppeteerBrowsers from '@puppeteer/browsers';\nimport type * as Puppeteer from 'puppeteer';\n\nimport { EngineNotAvailableException } from '../../exceptions';\n\nfunction isMissingPackage(error: unknown, packageName: string): boolean {\n const { code, message } = error as NodeJS.ErrnoException;\n return (\n (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND') &&\n typeof message === 'string' &&\n message.includes(`'${packageName}'`)\n );\n}\n\n/** Imports an optional peer dependency, turning \"not installed\" into a clear exception. */\nexport async function loadOptional<T>(\n packageName: string,\n importer: () => Promise<T>,\n): Promise<T> {\n try {\n return await importer();\n } catch (error) {\n if (isMissingPackage(error, packageName)) {\n throw new EngineNotAvailableException('Puppeteer', packageName, {\n cause: error,\n });\n }\n throw error;\n }\n}\n\n/**\n * Puppeteer is an optional peer dependency, only needed by the `puppeteer`\n * provider: it is imported on first use, never when the library loads.\n */\nexport function loadPuppeteer(): Promise<typeof Puppeteer> {\n return loadOptional('puppeteer', () => import('puppeteer'));\n}\n\nexport function loadPuppeteerBrowsers(): Promise<typeof PuppeteerBrowsers> {\n return loadOptional(\n '@puppeteer/browsers',\n () => import('@puppeteer/browsers'),\n );\n}\n","import { lookup } from 'node:dns/promises';\nimport { promises } from 'node:fs';\nimport { BlockList, isIP } from 'node:net';\nimport {\n basename,\n dirname,\n isAbsolute,\n join,\n relative,\n resolve,\n} from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { Logger } from '@nestjs/common';\nimport type { BrowserContext, HTTPRequest, Page } from 'puppeteer';\n\nimport { loadPuppeteer } from '../puppeteer/libs/loadPuppeteer.utils';\n\n/**\n * Filters what the rendered HTML may load (SSRF protection). Disabled unless set:\n * pass `{}` for the defaults (private networks and `file:` blocked).\n */\nexport interface PdfSecurityOptions {\n /**\n * Refuse http(s) requests that resolve to a loopback, private, link-local\n * (cloud metadata included) or otherwise non-public address. Default: true\n */\n blockPrivateNetworks?: boolean;\n /**\n * When set, http(s) requests are only allowed to these hosts (`example.com`\n * or `*.example.com`). Listed hosts are trusted, even on a private address.\n */\n allowedHosts?: Array<string>;\n /**\n * `file:` requests are refused unless the file is inside one of these\n * directories (symbolic links are resolved).\n */\n allowedFileRoots?: Array<string>;\n /** Set to false to disable JavaScript in the rendered page. Default: true */\n javascriptEnabled?: boolean;\n}\n\nconst blockedRanges = new BlockList();\nfor (const [address, prefix] of [\n ['0.0.0.0', 8],\n ['10.0.0.0', 8],\n ['100.64.0.0', 10],\n ['127.0.0.0', 8],\n ['169.254.0.0', 16],\n ['172.16.0.0', 12],\n ['192.0.0.0', 24],\n ['192.168.0.0', 16],\n ['198.18.0.0', 15],\n ['224.0.0.0', 4],\n ['240.0.0.0', 4],\n] as const) {\n blockedRanges.addSubnet(address, prefix, 'ipv4');\n}\nfor (const [address, prefix] of [\n ['::', 128],\n ['::1', 128],\n ['64:ff9b::', 96],\n ['fc00::', 7],\n ['fe80::', 10],\n ['ff00::', 8],\n] as const) {\n blockedRanges.addSubnet(address, prefix, 'ipv6');\n}\n\nconst IPV4_MAPPED_IPV6 = /^::ffff:([\\da-f]{1,4}):([\\da-f]{1,4})$/i;\n\n/** True for addresses that must not be reachable from a rendered document. */\nexport function isPrivateAddress(address: string): boolean {\n const family = isIP(address);\n if (family === 4) {\n return blockedRanges.check(address, 'ipv4');\n }\n if (family === 6) {\n // WHATWG URL serialises ::ffff:127.0.0.1 as ::ffff:7f00:1\n const mapped = IPV4_MAPPED_IPV6.exec(address);\n if (mapped) {\n const high = Number.parseInt(mapped[1], 16);\n const low = Number.parseInt(mapped[2], 16);\n return isPrivateAddress(\n [high >> 8, high & 0xff, low >> 8, low & 0xff].join('.'),\n );\n }\n return blockedRanges.check(address, 'ipv6');\n }\n // Not an IP: unknown format, refuse.\n return true;\n}\n\nfunction hostMatches(hostname: string, pattern: string): boolean {\n const host = hostname.toLowerCase();\n const rule = pattern.toLowerCase();\n if (rule.startsWith('*.')) {\n return host.endsWith(rule.slice(1));\n }\n return host === rule;\n}\n\nfunction isLocalhostName(hostname: string): boolean {\n return hostname === 'localhost' || hostname.endsWith('.localhost');\n}\n\nasync function resolvesToPrivateAddress(hostname: string): Promise<boolean> {\n // IPv6 literals come bracketed from URL.hostname\n const host = hostname.replace(/^\\[|\\]$/g, '');\n if (isIP(host)) {\n return isPrivateAddress(host);\n }\n if (isLocalhostName(host)) {\n return true;\n }\n try {\n const addresses = await lookup(host, { all: true, verbatim: true });\n return addresses.some(({ address }) => isPrivateAddress(address));\n } catch {\n // Unresolvable: the browser would fail too, and we cannot vouch for it.\n return true;\n }\n}\n\nasync function isFileAllowed(url: URL, roots: Array<string>): Promise<boolean> {\n // file://server/share is a network path (SMB), never a local file\n if (\n roots.length === 0 ||\n (url.hostname !== '' && url.hostname !== 'localhost')\n ) {\n return false;\n }\n\n let path: string;\n try {\n path = fileURLToPath(url);\n } catch {\n return false;\n }\n\n // Missing file: nothing to leak, but resolve its closest existing ancestor\n // so symlinks (e.g. macOS /var -> /private/var) match the resolved roots.\n const real = async (candidate: string) => {\n const missing: Array<string> = [];\n let current = resolve(candidate);\n for (;;) {\n try {\n return join(await promises.realpath(current), ...missing);\n } catch {\n const parent = dirname(current);\n if (parent === current) return resolve(candidate);\n missing.unshift(basename(current));\n current = parent;\n }\n }\n };\n\n const target = await real(path);\n for (const root of roots) {\n const rel = relative(await real(root), target);\n if (rel === '' || (!rel.startsWith('..') && !isAbsolute(rel))) {\n return true;\n }\n }\n return false;\n}\n\n/** Decides whether the browser may fetch `rawUrl`. */\nexport async function isRequestAllowed(\n rawUrl: string,\n options: PdfSecurityOptions,\n): Promise<boolean> {\n let url: URL;\n try {\n url = new URL(rawUrl);\n } catch {\n return false;\n }\n\n switch (url.protocol) {\n case 'about:':\n case 'data:':\n case 'blob:':\n return true;\n case 'file:':\n return isFileAllowed(url, options.allowedFileRoots ?? []);\n case 'http:':\n case 'https:': {\n if (options.allowedHosts) {\n return options.allowedHosts.some((pattern) =>\n hostMatches(url.hostname, pattern),\n );\n }\n if (options.blockPrivateNetworks === false) {\n return true;\n }\n return !(await resolvesToPrivateAddress(url.hostname));\n }\n default:\n return false;\n }\n}\n\n/** Logs the origin and path only: query strings may carry secrets. */\nfunction describe(rawUrl: string) {\n try {\n const url = new URL(rawUrl);\n return `${url.origin === 'null' ? `${url.protocol}//` : url.origin}${url.pathname}`;\n } catch {\n return '<invalid url>';\n }\n}\n\n/**\n * Filters every request the page (and its frames) makes, redirects included,\n * and closes the pop-ups a script could open to escape the filter.\n */\nexport async function installRequestGuard(\n context: BrowserContext,\n page: Page,\n options: PdfSecurityOptions,\n) {\n const { TargetType } = await loadPuppeteer();\n context.on('targetcreated', (target) => {\n if (target.type() === TargetType.PAGE && target.opener()) {\n void target\n .page()\n .then((popup) => popup?.close())\n .catch(() => undefined);\n }\n });\n\n if (options.javascriptEnabled === false) {\n await page.setJavaScriptEnabled(false);\n }\n\n await page.setRequestInterception(true);\n page.on('request', (request: HTTPRequest) => {\n void (async () => {\n if (request.isInterceptResolutionHandled()) return;\n const url = request.url();\n const allowed = await isRequestAllowed(url, options).catch(() => false);\n if (request.isInterceptResolutionHandled()) return;\n if (allowed) {\n await request.continue();\n } else {\n Logger.warn(`Blocked request to ${describe(url)}`, 'NestJsPdf');\n await request.abort('blockedbyclient');\n }\n })().catch(() => undefined);\n });\n}\n","import { Logger } from '@nestjs/common';\nimport type { PDFOptions } from 'puppeteer';\n\nimport { RendererConfigurationException } from '../exceptions';\nimport { installRequestGuard } from '../helpers/request-guard.helper';\nimport { type BrowserService } from '../puppeteer/browser/browser.service';\nimport type { PuppeteerParameters } from '../puppeteer/puppeteer-parameters.interface';\nimport { type PdfOptions } from './pdf-options.interface';\nimport type { PdfRenderer } from './pdf-renderer.interface';\n\n//src: https://www.bannerbear.com/blog/ways-to-speed-up-puppeteer-screenshots/\nconst DEFAULT_ARGS = [\n '--autoplay-policy=user-gesture-required',\n '--disable-background-networking',\n '--disable-background-timer-throttling',\n '--disable-backgrounding-occluded-windows',\n '--disable-breakpad',\n '--disable-client-side-phishing-detection',\n '--disable-component-update',\n '--disable-default-apps',\n '--disable-dev-shm-usage',\n '--disable-domain-reliability',\n '--disable-extensions',\n '--disable-features=AudioServiceOutOfProcess',\n '--disable-hang-monitor',\n '--disable-ipc-flooding-protection',\n '--disable-notifications',\n '--disable-offer-store-unmasked-wallet-cards',\n '--disable-print-preview',\n '--disable-prompt-on-repost',\n '--disable-renderer-backgrounding',\n '--disable-setuid-sandbox',\n '--disable-speech-api',\n '--disable-sync',\n '--hide-scrollbars',\n '--ignore-gpu-blacklist',\n '--metrics-recording-only',\n '--mute-audio',\n '--no-default-browser-check',\n '--no-first-run',\n '--no-pings',\n '--password-store=basic',\n '--use-gl=swiftshader',\n '--use-mock-keychain',\n '--disable-accelerated-2d-canvas',\n '--no-zygote',\n '--disable-gpu',\n];\n\nconst PDF_OPTION_KEYS: Record<keyof PDFOptions, true> = {\n scale: true,\n displayHeaderFooter: true,\n headerTemplate: true,\n footerTemplate: true,\n printBackground: true,\n landscape: true,\n pageRanges: true,\n format: true,\n width: true,\n height: true,\n preferCSSPageSize: true,\n margin: true,\n path: true,\n omitBackground: true,\n tagged: true,\n outline: true,\n timeout: true,\n waitForFonts: true,\n};\n\nfunction toPuppeteerPdfOptions(options?: PdfOptions): PDFOptions {\n if (!options) {\n return { format: 'A4' };\n }\n const invalidKeys = Object.keys(options).filter(\n (key) => !Object.hasOwn(PDF_OPTION_KEYS, key),\n );\n if (invalidKeys.length > 0) {\n throw new RendererConfigurationException(\n `Invalid PDF options: ${invalidKeys.join(', ')}. Please check the documentation for valid options.`,\n );\n }\n return options;\n}\n\nexport class PuppeteerRenderer implements PdfRenderer {\n readonly #browserService: BrowserService;\n\n constructor(browserService: BrowserService) {\n this.#browserService = browserService;\n }\n\n async render(\n html: string,\n options: PuppeteerParameters,\n signal?: AbortSignal,\n ): Promise<Uint8Array> {\n if (options.chromiumRevision !== undefined) {\n Logger.warn(\n 'Using `chromiumRevision` is no longer supported since the puppeteer update.',\n );\n }\n\n const pdfOptions = toPuppeteerPdfOptions(options.pdfOptions);\n const headless: boolean | 'shell' = options.headless ?? true;\n const executablePath = options.executablePath || undefined;\n const args = options.extraPuppeteerArgs || DEFAULT_ARGS;\n\n let context: Awaited<ReturnType<BrowserService['createContext']>> | null =\n null;\n\n let closing: Promise<void> | undefined;\n const onAbort = () => {\n if (!context) return;\n closing = context.close();\n closing.catch(() => undefined);\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n\n try {\n context = await this.#browserService.createContext(\n args,\n headless,\n executablePath,\n );\n signal?.throwIfAborted();\n const page = await context.newPage();\n if (options.security) {\n await installRequestGuard(context, page, options.security);\n }\n\n await page.setContent(html, { waitUntil: 'domcontentloaded' });\n await page.emulateMediaType('screen');\n await page.waitForNetworkIdle({ idleTime: 500, timeout: 30000 });\n // Executes inside the browser page context via Puppeteer, not in Node — unreachable by unit tests.\n /* v8 ignore next */\n await page.evaluate(() => document.fonts.ready);\n\n return await page.pdf(pdfOptions);\n } finally {\n signal?.removeEventListener('abort', onAbort);\n if (context) {\n try {\n if (closing) await closing;\n else await context.close();\n } catch (error) {\n Logger.error(error);\n }\n }\n }\n }\n}\n","import { RendererConfigurationException } from '../exceptions';\nimport type { BrowserService } from '../puppeteer/browser/browser.service';\nimport type { PuppeteerParameters } from '../puppeteer/puppeteer-parameters.interface';\nimport { Api2PdfRenderer } from './api2pdf.renderer';\nimport { GotenbergRenderer } from './gotenberg.renderer';\nimport type { PdfRenderer } from './pdf-renderer.interface';\nimport { PuppeteerRenderer } from './puppeteer.renderer';\n\n/** True when the PDFs are printed by the local Chromium (the default). */\nexport function usesPuppeteer(params: PuppeteerParameters): boolean {\n return (params.provider?.type ?? 'puppeteer') === 'puppeteer';\n}\n\nexport function createPdfRenderer(\n params: PuppeteerParameters,\n browserService: BrowserService,\n): PdfRenderer {\n const provider = params.provider ?? { type: 'puppeteer' };\n\n switch (provider.type) {\n case 'puppeteer':\n return new PuppeteerRenderer(browserService);\n case 'gotenberg':\n return new GotenbergRenderer(provider);\n case 'api2pdf':\n return new Api2PdfRenderer(provider);\n default:\n throw new RendererConfigurationException(\n `Unknown PDF provider '${String((provider as { type?: unknown }).type)}': expected 'puppeteer', 'gotenberg' or 'api2pdf'`,\n );\n }\n}\n","import { RendererConfigurationException } from '../../exceptions';\n\n/**\n * Converts a string value to an enum member, throwing a RendererConfigurationException if the value is not a valid member of the enum.\n * @param enumObject\n * @param value\n * @param label\n * @throws RendererConfigurationException\n */\nexport function toEnumMember<E extends Record<string, string>>(\n enumObject: E,\n value: string,\n label: string,\n): E[keyof E] {\n const members = Object.values(enumObject);\n const isMember = (candidate: string): candidate is E[keyof E] =>\n candidate === value;\n\n const member = members.find(isMember);\n if (member === undefined) {\n throw new RendererConfigurationException(\n `Unsupported ${label} '${value}': expected one of ${members\n .map((m) => `'${m}'`)\n .join(', ')}`,\n );\n }\n return member;\n}\n","import { existsSync, promises, readFileSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { Inject, Injectable, Logger, OnModuleDestroy } from '@nestjs/common';\nimport type { Browser, BrowserContext } from 'puppeteer';\n\nimport {\n BrowserInstallationException,\n BrowserUnavailableException,\n NestjsPdfException,\n} from '../../exceptions';\nimport { usesPuppeteer } from '../../renderers/create-renderer';\nimport type { PdfBrowser } from '../../renderers/pdf-options.interface';\nimport { toEnumMember } from '../libs/enum.utils';\nimport {\n loadPuppeteer,\n loadPuppeteerBrowsers,\n} from '../libs/loadPuppeteer.utils';\nimport type { PuppeteerParameters } from '../puppeteer-parameters.interface';\n\nconst DEFAULT_BROWSER: PdfBrowser = 'chromium';\n\nexport enum BrowserTag {\n LATEST = 'latest',\n BETA = 'beta',\n DEV = 'dev',\n STABLE = 'stable',\n CANARY = 'canary',\n}\n\nexport type Headless = boolean | 'shell' | undefined;\n\nasync function sleep(ms: number) {\n await new Promise((r) => setTimeout(r, ms));\n}\n\nasync function rmWithRetries(dir: string, retries = 5): Promise<void> {\n for (let attempt = 1; attempt <= retries; attempt++) {\n try {\n await promises.rm(dir, { recursive: true, force: true });\n return;\n } catch (err: unknown) {\n const code = (err as NodeJS.ErrnoException)?.code;\n\n const retryable =\n code === 'EPERM' || code === 'EBUSY' || code === 'ENOTEMPTY';\n\n if (!retryable || attempt === retries) {\n throw err;\n }\n\n await sleep(50 * 2 ** (attempt - 1));\n }\n }\n}\n\nfunction isTargetClosedError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n\n return (\n error.name === 'TargetCloseError' ||\n error.message.includes('Target closed') ||\n error.message.includes('Target.createTarget')\n );\n}\n\n@Injectable()\nexport class BrowserService implements OnModuleDestroy {\n readonly #cacheDir: string;\n readonly #options?: PuppeteerParameters;\n\n #browserInstance: Browser | null = null;\n #browser: PdfBrowser;\n\n public activeJobs = 0;\n public totalJobs = 0;\n\n #recycleRequested = false;\n #recycling = false;\n\n #shuttingDown = false;\n /** Max time to wait for in-flight PDF jobs to finish before closing the browser on shutdown. */\n public shutdownDrainTimeoutMs = 15_000;\n\n #browserTag: BrowserTag;\n #useLockedBrowser: boolean;\n #buildId: string | undefined;\n\n constructor(@Inject('PDF_PARAMETERS') pdfParams: PuppeteerParameters) {\n this.#cacheDir = resolve('.cache/puppeteer-browser');\n this.#options = pdfParams;\n\n this.#loadBuildId();\n this.#loadBrowser();\n this.#loadBrowserTag();\n this.#loadUseLockedBrowser();\n }\n\n async onModuleDestroy() {\n this.#shuttingDown = true;\n await this.#waitForIdle(this.shutdownDrainTimeoutMs);\n\n if (this.#browserInstance?.connected) {\n try {\n await this.#browserInstance.close();\n } catch (error) {\n Logger.warn(\n `Failed to close browser on module destroy: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n }\n\n if (\n this.#options !== undefined &&\n usesPuppeteer(this.#options) &&\n this.#options.cleanupBrowserCacheOnExit !== false\n ) {\n await this.#cleanupCacheBestEffort();\n }\n }\n\n /** Wait until no PDF job is in flight, or until the timeout elapses. */\n async #waitForIdle(timeoutMs: number): Promise<void> {\n const start = Date.now();\n while (this.activeJobs > 0 && Date.now() - start < timeoutMs) {\n await sleep(50);\n }\n\n if (this.activeJobs > 0) {\n Logger.warn(\n `Shutdown: ${this.activeJobs} PDF job(s) still running after ${timeoutMs}ms, closing the browser anyway`,\n );\n }\n }\n\n async getBrowserInstance(\n args: Array<string>,\n headless: boolean | 'shell' | undefined,\n executablePathBin: string | undefined,\n ) {\n if (!this.#browserInstance?.connected) {\n this.#browserInstance = await this.#launchBrowser(\n args,\n headless,\n executablePathBin,\n );\n }\n\n return this.#browserInstance;\n }\n\n async createContext(\n args: Array<string>,\n headless: Headless,\n executablePath?: string,\n ): Promise<BrowserContext> {\n const browser = await this.getBrowserInstance(\n args,\n headless,\n executablePath,\n );\n try {\n return await browser.createBrowserContext();\n } catch (error) {\n if (!isTargetClosedError(error)) {\n throw error;\n }\n\n Logger.warn(\n 'Puppeteer browser closed while creating a context, retrying once',\n );\n\n this.#browserInstance = null;\n const freshBrowser = await this.getBrowserInstance(\n args,\n headless,\n executablePath,\n );\n return await freshBrowser.createBrowserContext();\n }\n }\n\n markJobStarted() {\n if (this.#shuttingDown) {\n throw new BrowserUnavailableException(\n 'nestjs-pdf is shutting down, refusing new PDF jobs',\n );\n }\n\n this.activeJobs += 1;\n this.totalJobs += 1;\n\n if (this.totalJobs >= 200) {\n this.#recycleRequested = true;\n }\n }\n\n async markJobFinished() {\n this.activeJobs = Math.max(0, this.activeJobs - 1);\n await this.recycleBrowserIfNeeded();\n }\n\n async recycleBrowserIfNeeded() {\n if (!this.#recycleRequested) return;\n if (this.#recycling) return;\n if (this.activeJobs > 0) return;\n if (!this.#browserInstance) return;\n\n this.#recycling = true;\n\n try {\n if (this.#browserInstance.connected) {\n await this.#browserInstance.close();\n }\n\n this.#browserInstance = null;\n this.totalJobs = 0;\n this.#recycleRequested = false;\n\n Logger.log('Puppeteer browser recycled successfully');\n } catch (error) {\n Logger.warn(\n `Failed to recycle browser: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n } finally {\n this.#recycling = false;\n }\n }\n\n async #cleanupCacheBestEffort() {\n const logger = new Logger('NestJsPdf');\n const dir = this.#cacheDir;\n try {\n if (!existsSync(dir)) return;\n\n logger.log(`Cleanup puppeteer cache: ${dir}`);\n\n await rmWithRetries(dir, 6);\n if (existsSync(dir)) {\n await sleep(100);\n await rmWithRetries(dir, 3);\n }\n\n logger.log('Cleanup done');\n } catch (err) {\n logger.error(\n `Cleanup failed for ${dir}`,\n err instanceof Error ? err.stack : String(err),\n );\n }\n try {\n const leftover = await promises.readdir(dir, { recursive: true });\n logger.warn(`Leftover files: ${leftover.slice(0, 20).join(', ')}...`);\n } catch {\n logger.log(`No leftover files in ${dir}`);\n }\n }\n\n async install(lock: boolean = false) {\n try {\n return await this.#doInstall(lock);\n } catch (error) {\n if (error instanceof NestjsPdfException) {\n throw error;\n }\n throw new BrowserInstallationException(\n `Could not install browser: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n async #doInstall(lock: boolean) {\n const {\n Browser: BrowserEnum,\n BrowserPlatform,\n canDownload,\n detectBrowserPlatform,\n install,\n resolveBuildId,\n } = await loadPuppeteerBrowsers();\n const browser = toEnumMember(BrowserEnum, this.#browser, 'browser');\n const versionTag: BrowserTag = this.#browserTag;\n\n const browserPlatform = detectBrowserPlatform() ?? BrowserPlatform.LINUX;\n\n let buildId: string;\n if (this.#buildId === undefined) {\n buildId = await resolveBuildId(browser, browserPlatform, versionTag);\n } else {\n buildId = this.#buildId;\n }\n\n Logger.log(\n `Browser ${browser} ${versionTag} build id: ${buildId}`,\n 'NestJsPdf',\n );\n\n if (await this.hasBrowserInstalled(browser, buildId)) {\n Logger.log('Browser already installed', 'NestJsPdf');\n if (lock) {\n this.#writeLockFile(browser, buildId);\n }\n return;\n } else {\n Logger.log('Starting browser installation', 'NestJsPdf');\n\n const installOption = {\n cacheDir: this.#cacheDir,\n browser: browser,\n buildId: buildId,\n baseUrl: this.#options?.browserInstallBaseUrl ?? undefined,\n };\n\n if (await canDownload(installOption)) {\n Logger.log(\n `Installing ${installOption.browser} ${installOption.buildId}`,\n 'NestJsPdf',\n );\n const installedBrowser = await install(installOption);\n if (await this.hasBrowserInstalled(browser, buildId)) {\n Logger.log('Browser installed successfully', 'NestJsPdf');\n if (lock) {\n this.#writeLockFile(browser, buildId);\n }\n return installedBrowser;\n } else {\n Logger.error('Browser installation failed', 'NestJsPdf');\n }\n } else {\n Logger.error(\n `Error, can't install ${installOption.browser} ${installOption.buildId}`,\n 'NestJsPdf',\n );\n }\n }\n return null;\n }\n\n #loadBrowser(): void {\n this.#browser = this.#options?.browser ?? DEFAULT_BROWSER;\n }\n\n public getBrowser(): PdfBrowser {\n return this.#browser;\n }\n\n #loadBrowserTag(): void {\n let versionTag: BrowserTag;\n if (this.#options?.browserTag === undefined) {\n if (this.#browser === DEFAULT_BROWSER) {\n versionTag = BrowserTag.LATEST;\n } else {\n versionTag = BrowserTag.STABLE;\n }\n } else {\n versionTag = this.#options.browserTag;\n }\n this.#browserTag = versionTag;\n }\n\n #loadBuildId(): void {\n let buildId: string | undefined;\n if (this.#options?.buildId === undefined) {\n buildId = undefined;\n } else {\n buildId = this.#options.buildId;\n }\n this.#buildId = buildId;\n }\n\n public setBrowserTag(browserTag: BrowserTag): void {\n this.#browserTag = browserTag;\n }\n\n public getBrowserTag(): BrowserTag {\n return this.#browserTag;\n }\n\n getBuildId(): string | undefined {\n return this.#buildId;\n }\n\n #loadUseLockedBrowser(): void {\n let useLockedBrowser: boolean;\n if (this.#options?.useLockedBrowser === undefined) {\n useLockedBrowser = false;\n } else {\n useLockedBrowser = this.#options.useLockedBrowser;\n }\n this.#useLockedBrowser = useLockedBrowser;\n }\n\n async hasBrowserInstalled(browser: PdfBrowser, buildId: string) {\n const { Browser: BrowserEnum, getInstalledBrowsers } =\n await loadPuppeteerBrowsers();\n const expected = toEnumMember(BrowserEnum, browser, 'browser');\n const installedBrowserlist = await getInstalledBrowsers({\n cacheDir: this.#cacheDir,\n });\n\n const installedBrowser = installedBrowserlist.find((insBrowser) => {\n return insBrowser.browser === expected && insBrowser.buildId === buildId;\n });\n return installedBrowser !== undefined;\n }\n\n async getExecutablePath(): Promise<string> {\n const {\n Browser: BrowserEnum,\n BrowserPlatform,\n detectBrowserPlatform,\n getInstalledBrowsers,\n resolveBuildId,\n } = await loadPuppeteerBrowsers();\n const browser = toEnumMember(BrowserEnum, this.#browser, 'browser');\n const versionTag: BrowserTag = this.#browserTag;\n const browserPlatform = detectBrowserPlatform() ?? BrowserPlatform.LINUX;\n let buildId: string | null = null;\n if (this.#useLockedBrowser) {\n buildId = this.getLockedBuildId(browser);\n Logger.log(`Using locked browser ${buildId}`, 'NestJsPdf');\n }\n buildId ??= await resolveBuildId(browser, browserPlatform, versionTag);\n const installedBrowserlist = await getInstalledBrowsers({\n cacheDir: this.#cacheDir,\n });\n const installedBrowser = installedBrowserlist.find((insBrowser) => {\n return insBrowser.browser === browser && insBrowser.buildId === buildId;\n });\n if (installedBrowser === undefined) {\n const newinstalledBrowser = await this.install();\n if (newinstalledBrowser === null || newinstalledBrowser === undefined) {\n throw new BrowserInstallationException('Could not install browser');\n } else {\n return newinstalledBrowser.executablePath;\n }\n }\n return installedBrowser.executablePath;\n }\n\n async #launchBrowser(\n args: Array<string>,\n headless: Headless,\n executablePathBin: string | undefined,\n ) {\n const executablePath =\n executablePathBin ?? (await this.getExecutablePath());\n\n const { launch } = await loadPuppeteer();\n const browser = await launch({\n executablePath,\n headless,\n args,\n // Puppeteer disables Chrome's popup blocker by default, which lets a\n // script open a window that escapes the request filter.\n ignoreDefaultArgs: ['--disable-popup-blocking'],\n });\n\n browser.on('disconnected', () => {\n Logger.warn('Puppeteer browser disconnected');\n if (this.#browserInstance === browser) {\n this.#browserInstance = null;\n }\n });\n\n return browser;\n }\n\n #writeLockFile(browser: PdfBrowser, buildId: string) {\n const lockFile = resolve(this.#cacheDir, `${browser}.lock`);\n const data = JSON.stringify({\n browser: browser,\n buildId: buildId,\n date: new Date().toISOString(),\n });\n writeFileSync(lockFile, data);\n\n Logger.log(`Browser ${browser} locked to build ${buildId}`, 'NestJsPdf');\n }\n\n getLockedBuildId(browser: PdfBrowser): string | null {\n const lockFile = resolve(this.#cacheDir, `${browser}.lock`);\n if (existsSync(lockFile)) {\n const data = readFileSync(lockFile);\n const lock = JSON.parse(data.toString()) as {\n browser: PdfBrowser;\n buildId: string;\n date: string;\n };\n return lock.buildId;\n }\n return null;\n }\n}\n","import { createRequire } from 'node:module';\n\nimport { EngineNotAvailableException } from '../../exceptions';\n\nconst requireEngine = createRequire(import.meta.url);\n\n/**\n * Load an optional template engine on first use, so the library can be imported\n * without every engine installed. `require` (not `import()`) is used on purpose:\n * most engines expose a synchronous render API.\n */\nexport function loadEngine<T>(packageName: string, engineName: string): T {\n let mod: { __esModule?: boolean; default?: unknown };\n try {\n mod = requireEngine(packageName) as typeof mod;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'MODULE_NOT_FOUND') {\n throw new EngineNotAvailableException(engineName, packageName, {\n cause: error,\n });\n }\n throw error;\n }\n\n return (mod.__esModule && 'default' in mod ? mod.default : mod) as T;\n}\n","import { Injectable } from '@nestjs/common';\nimport type ejs from 'ejs';\nimport type { Data, Options } from 'ejs';\n\nimport { TemplateRenderException } from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\nexport interface EjsOptions extends Omit<Options, 'async'> {\n async?: boolean;\n}\n\n@Injectable()\nexport class EjsService {\n #ejs?: typeof ejs;\n\n get #engine(): typeof ejs {\n return (this.#ejs ??= loadEngine<typeof ejs>('ejs', 'EJS'));\n }\n\n async render(template: string, data: Data = {}, options?: EjsOptions) {\n const engine = this.#engine;\n try {\n return await engine.render(template, data, {\n async: true,\n ...options,\n });\n } catch (error) {\n throw new TemplateRenderException(\n 'EJS',\n `EJS rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n async renderFile(filePath: string, data: Data = {}, options?: EjsOptions) {\n const engine = this.#engine;\n try {\n return await engine.renderFile(filePath, data, {\n async: true,\n ...options,\n });\n } catch (error) {\n throw new TemplateRenderException(\n 'EJS',\n `EJS file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { Injectable } from '@nestjs/common';\nimport type * as EtaModule from 'eta';\nimport type { Eta, EtaConfig } from 'eta';\n\nimport {\n EngineNotAvailableException,\n TemplateRenderException,\n} from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\nexport interface EtaOptions extends Partial<EtaConfig> {\n cache?: boolean;\n autoEscape?: boolean;\n varName?: string;\n views?: string;\n useWith?: boolean;\n plugins?: Array<any>;\n}\n\n@Injectable()\nexport class EtaService {\n #etaModule?: typeof EtaModule;\n #eta?: Eta;\n readonly #templateCache: Map<string, string> = new Map();\n readonly #maxCacheSize = 100;\n\n get #engine(): typeof EtaModule {\n return (this.#etaModule ??= loadEngine<typeof EtaModule>('eta', 'Eta'));\n }\n\n /**\n * Render an Eta template from a string\n * @param template The template string to render\n * @param data The data object to use for rendering\n * @param options Optional Eta rendering options\n * @returns The rendered HTML string\n */\n render(\n template: string,\n data: Record<string, unknown> = {},\n options?: EtaOptions,\n ): string {\n const { Eta } = this.#engine;\n try {\n const eta =\n options && Object.keys(options).length > 0\n ? new Eta({\n cache: true,\n autoEscape: true,\n useWith: true,\n ...options,\n varName: options.varName ?? 'it',\n })\n : (this.#eta ??= new Eta({\n cache: true,\n autoEscape: true,\n useWith: true,\n }));\n\n return eta.renderString(template, data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Eta',\n `Eta rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Render an Eta template from a file\n * @param filePath The path to the template file\n * @param data The data object to use for rendering\n * @param options Optional Eta rendering options\n * @returns The rendered HTML string\n */\n renderFile(\n filePath: string,\n data: Record<string, unknown> = {},\n options?: EtaOptions,\n ): string {\n try {\n const resolvedPath = resolve(filePath);\n const useCache = options?.cache ?? true;\n let template = useCache\n ? this.#templateCache.get(resolvedPath)\n : undefined;\n\n if (!template) {\n template = readFileSync(resolvedPath, 'utf-8');\n\n if (useCache && this.#templateCache.size < this.#maxCacheSize) {\n this.#templateCache.set(resolvedPath, template);\n }\n }\n return this.render(template, data, options);\n } catch (error) {\n if (error instanceof EngineNotAvailableException) {\n throw error;\n }\n throw new TemplateRenderException(\n 'Eta',\n `Eta file rendering failed for ${filePath}: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Clear the template cache\n */\n clearCache(): void {\n this.#templateCache.clear();\n }\n\n /**\n * Get the current cache size\n * @returns The number of cached templates\n */\n getCacheSize(): number {\n return this.#templateCache.size;\n }\n}\n","import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';\nimport { basename, extname, join, resolve, sep } from 'node:path';\n\nimport { Injectable } from '@nestjs/common';\nimport type Handlebars from 'handlebars';\n\nimport {\n NestjsPdfException,\n TemplateConfigurationException,\n TemplateRenderException,\n} from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\nexport type HandlebarsHelper = {\n name: string;\n fn: Handlebars.HelperDelegate;\n};\n\nexport interface HandlebarsOptions {\n /** Base directory (relative to `process.cwd()`) used to resolve files passed to `renderFile`. */\n templateDirectory?: string;\n /** Directory (relative to `process.cwd()`) whose files are each registered as a partial. */\n partialDirectory?: string;\n /**\n * Runtime options forwarded to the compiled template function.\n * `helpers` and `partials` are excluded on purpose: register helpers via\n * `helpers` and partials via `partialDirectory`.\n */\n templateOptions?: Omit<Handlebars.RuntimeOptions, 'helpers' | 'partials'>;\n /** Options forwarded to `Handlebars.compile`. */\n compileOptions?: CompileOptions;\n /** Custom helpers registered on the isolated Handlebars environment for this render. */\n helpers?: Array<HandlebarsHelper>;\n}\n\n@Injectable()\nexport class HandlebarsService {\n #handlebars?: typeof Handlebars;\n #cachedOptions?: HandlebarsOptions;\n #cachedEnv?: typeof Handlebars;\n\n get #engine(): typeof Handlebars {\n return (this.#handlebars ??= loadEngine<typeof Handlebars>(\n 'handlebars',\n 'Handlebars',\n ));\n }\n\n render(\n template: string,\n parameters: unknown = {},\n options: HandlebarsOptions = {},\n ): string {\n try {\n const compiled = this.#getEnv(options).compile(\n template,\n options.compileOptions,\n );\n return compiled(parameters, options.templateOptions);\n } catch (error) {\n if (error instanceof NestjsPdfException) {\n throw error;\n }\n throw new TemplateRenderException(\n 'Handlebars',\n `Handlebars rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n renderFile(\n file: string,\n parameters: unknown = {},\n options: HandlebarsOptions = {},\n ): string {\n if (options.templateDirectory === undefined) {\n throw new TemplateConfigurationException(\n 'Handlebars file rendering failed: option `templateDirectory` is not set',\n );\n }\n\n const baseDir = resolve(process.cwd(), options.templateDirectory);\n const templatePath = resolve(baseDir, file);\n if (templatePath !== baseDir && !templatePath.startsWith(baseDir + sep)) {\n throw new TemplateConfigurationException(\n `Handlebars file rendering failed: ’${file}’ resolves outside \\`templateDirectory\\``,\n );\n }\n\n let template: string;\n try {\n template = readFileSync(templatePath, 'utf8');\n } catch (error) {\n throw new TemplateRenderException(\n 'Handlebars',\n `Handlebars file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n\n return this.render(template, parameters, options);\n }\n\n /**\n * Build an isolated Handlebars environment with the given helpers/partials so\n * nothing leaks into the global Handlebars. Memoised for the common case where\n * the same options object is reused across calls (e.g. the module `hbsOptions`).\n */\n #getEnv(options: HandlebarsOptions): typeof Handlebars {\n if (this.#cachedEnv && this.#cachedOptions === options) {\n return this.#cachedEnv;\n }\n\n const env = this.#engine.create();\n\n for (const helper of options.helpers ?? []) {\n env.registerHelper(helper.name, helper.fn);\n }\n this.#registerPartials(env, options.partialDirectory);\n\n this.#cachedOptions = options;\n this.#cachedEnv = env;\n return env;\n }\n\n #registerPartials(\n env: typeof Handlebars,\n partialDirectory: string | undefined,\n ): void {\n if (partialDirectory === undefined) return;\n\n const partialPath = join(process.cwd(), partialDirectory);\n if (!existsSync(partialPath)) {\n throw new TemplateConfigurationException(\n `Handlebars partial directory does not exist: ${partialPath}`,\n );\n }\n\n for (const entry of readdirSync(partialPath)) {\n const filePath = join(partialPath, entry);\n if (!statSync(filePath).isFile()) continue;\n\n env.registerPartial(\n basename(entry, extname(entry)),\n readFileSync(filePath, 'utf8'),\n );\n }\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { Injectable } from '@nestjs/common';\nimport type * as LiquidModule from 'liquidjs';\nimport type { Liquid, LiquidOptions as LiquidJsOptions } from 'liquidjs';\n\nimport {\n EngineNotAvailableException,\n TemplateRenderException,\n} from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\nexport type LiquidOptions = LiquidJsOptions;\n\n@Injectable()\nexport class LiquidService {\n #liquidModule?: typeof LiquidModule;\n #liquid?: Liquid;\n readonly #templateCache: Map<string, string> = new Map();\n readonly #maxCacheSize = 100;\n\n get #engine(): typeof LiquidModule {\n return (this.#liquidModule ??= loadEngine<typeof LiquidModule>(\n 'liquidjs',\n 'Liquid',\n ));\n }\n\n /**\n * Render a Liquid template from a string\n * @param template The template string to render\n * @param data The data object to use for rendering\n * @param options Optional Liquid engine options\n * @returns The rendered HTML string\n */\n render(\n template: string,\n data: Record<string, unknown> = {},\n options?: LiquidOptions,\n ): string {\n const { Liquid } = this.#engine;\n try {\n const liquid =\n options && Object.keys(options).length > 0\n ? new Liquid(options)\n : (this.#liquid ??= new Liquid());\n\n return liquid.parseAndRenderSync(template, data) as string;\n } catch (error) {\n throw new TemplateRenderException(\n 'Liquid',\n `Liquid rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Render a Liquid template from a file\n * @param filePath The path to the template file\n * @param data The data object to use for rendering\n * @param options Optional Liquid engine options\n * @returns The rendered HTML string\n */\n renderFile(\n filePath: string,\n data: Record<string, unknown> = {},\n options?: LiquidOptions,\n ): string {\n try {\n const resolvedPath = resolve(filePath);\n const useCache = options?.cache !== false;\n let template = useCache\n ? this.#templateCache.get(resolvedPath)\n : undefined;\n\n if (!template) {\n template = readFileSync(resolvedPath, 'utf-8');\n\n if (useCache && this.#templateCache.size < this.#maxCacheSize) {\n this.#templateCache.set(resolvedPath, template);\n }\n }\n return this.render(template, data, options);\n } catch (error) {\n if (error instanceof EngineNotAvailableException) {\n throw error;\n }\n throw new TemplateRenderException(\n 'Liquid',\n `Liquid file rendering failed for ${filePath}: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Clear the template cache\n */\n clearCache(): void {\n this.#templateCache.clear();\n }\n\n /**\n * Get the current cache size\n * @returns The number of cached templates\n */\n getCacheSize(): number {\n return this.#templateCache.size;\n }\n}\n","import { readFileSync } from 'node:fs';\n\nimport { Injectable } from '@nestjs/common';\nimport type mjml from 'mjml';\nimport type { MJMLParsingOptions } from 'mjml-core';\n\nimport { TemplateRenderException } from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\n@Injectable()\nexport class MjmlService {\n #mjml?: typeof mjml;\n\n get #engine(): typeof mjml {\n return (this.#mjml ??= loadEngine<typeof mjml>('mjml', 'MJML'));\n }\n\n async render(\n template: string,\n options?: MJMLParsingOptions,\n ): Promise<string> {\n const engine = this.#engine;\n try {\n const { html } = await engine(template, options);\n return html;\n } catch (error) {\n throw new TemplateRenderException(\n 'MJML',\n `MJML rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n async renderFile(\n filePath: string,\n options?: MJMLParsingOptions,\n ): Promise<string> {\n let template: string;\n try {\n template = readFileSync(filePath, 'utf-8');\n } catch (error) {\n throw new TemplateRenderException(\n 'MJML',\n `MJML file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n return await this.render(template, options);\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { Injectable } from '@nestjs/common';\nimport type mustache from 'mustache';\nimport type { EscapeFunction } from 'mustache';\n\nimport {\n EngineNotAvailableException,\n TemplateRenderException,\n} from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\nexport interface MustacheOptions {\n tags?: [string, string];\n escape?: EscapeFunction;\n}\n\n@Injectable()\nexport class MustacheService {\n #mustache?: typeof mustache;\n readonly #templateCache: Map<string, string> = new Map();\n readonly #maxCacheSize = 100;\n\n get #engine(): typeof mustache {\n return (this.#mustache ??= loadEngine<typeof mustache>(\n 'mustache',\n 'Mustache',\n ));\n }\n\n /**\n * Render a Mustache template from a string\n * @param template The template string to render\n * @param data The data object to use for rendering\n * @param options Optional Mustache rendering options\n * @returns The rendered HTML string\n */\n render(\n template: string,\n data: Record<string, unknown> = {},\n options?: MustacheOptions,\n ): string {\n const engine = this.#engine;\n try {\n const tags = options?.tags ?? ['{{', '}}'];\n return engine.render(template, data, undefined, {\n tags: tags,\n escape: options?.escape,\n });\n } catch (error) {\n throw new TemplateRenderException(\n 'Mustache',\n `Mustache rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Render a Mustache template from a file\n * @param filePath The path to the template file\n * @param data The data object to use for rendering\n * @param options Optional Mustache rendering options\n * @returns The rendered HTML string\n */\n renderFile(\n filePath: string,\n data: Record<string, unknown> = {},\n options?: MustacheOptions,\n ): string {\n try {\n const resolvedPath = resolve(filePath);\n let template = this.#templateCache.get(resolvedPath);\n\n if (!template) {\n template = readFileSync(resolvedPath, 'utf-8');\n\n if (this.#templateCache.size < this.#maxCacheSize) {\n this.#templateCache.set(resolvedPath, template);\n }\n }\n\n return this.render(template, data, options);\n } catch (error) {\n if (error instanceof EngineNotAvailableException) {\n throw error;\n }\n throw new TemplateRenderException(\n 'Mustache',\n `Mustache file rendering failed for ${filePath}: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n /**\n * Clear the template cache\n */\n clearCache(): void {\n this.#templateCache.clear();\n }\n\n /**\n * Get the current cache size\n * @returns The number of cached templates\n */\n getCacheSize(): number {\n return this.#templateCache.size;\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport type nunjucks from 'nunjucks';\nimport type { ConfigureOptions } from 'nunjucks';\n\nimport { TemplateRenderException } from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\nexport interface NunjucksOptions extends Partial<ConfigureOptions> {\n noCache?: boolean;\n watch?: boolean;\n throwOnUndefined?: boolean;\n trimBlocks?: boolean;\n lstripBlocks?: boolean;\n}\n\n@Injectable()\nexport class NunjucksService {\n #nunjucks?: typeof nunjucks;\n\n get #engine(): typeof nunjucks {\n if (!this.#nunjucks) {\n this.#nunjucks = loadEngine<typeof nunjucks>('nunjucks', 'Nunjucks');\n // Configure default Nunjucks environment\n this.#nunjucks.configure({\n noCache: true,\n trimBlocks: true,\n lstripBlocks: true,\n });\n }\n return this.#nunjucks;\n }\n\n render(\n template: string,\n data: Record<string, unknown> = {},\n options?: NunjucksOptions,\n ) {\n const nunjucks = this.#engine;\n try {\n if (options) {\n const configOptions: Record<string, unknown> = {\n noCache: options.noCache ?? true,\n watch: options.watch ?? false,\n throwOnUndefined: options.throwOnUndefined ?? false,\n trimBlocks: options.trimBlocks ?? true,\n lstripBlocks: options.lstripBlocks ?? true,\n };\n nunjucks.configure(configOptions as ConfigureOptions);\n }\n return nunjucks.renderString(template, data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Nunjucks',\n `Nunjucks rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n renderFile(\n filePath: string,\n data: Record<string, unknown> = {},\n options?: NunjucksOptions,\n ) {\n const nunjucks = this.#engine;\n try {\n if (options) {\n const configOptions: Record<string, unknown> = {\n noCache: options.noCache ?? true,\n watch: options.watch ?? false,\n throwOnUndefined: options.throwOnUndefined ?? false,\n trimBlocks: options.trimBlocks ?? true,\n lstripBlocks: options.lstripBlocks ?? true,\n };\n nunjucks.configure(configOptions as ConfigureOptions);\n }\n return nunjucks.render(filePath, data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Nunjucks',\n `Nunjucks file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n}\n","import { readFileSync } from 'node:fs';\n\nimport { Injectable } from '@nestjs/common';\nimport type pug from 'pug';\nimport type { LocalsObject, Options } from 'pug';\n\nimport {\n EngineNotAvailableException,\n TemplateRenderException,\n} from '../../../exceptions';\nimport { loadEngine } from '../../libs/loadEngine.utils';\n\nexport type PugOptions = Options;\n\n@Injectable()\nexport class PugService {\n #pug?: typeof pug;\n\n get #engine(): typeof pug {\n return (this.#pug ??= loadEngine<typeof pug>('pug', 'Pug'));\n }\n\n render(\n template: string,\n data: LocalsObject = {},\n options?: PugOptions,\n ): string {\n const engine = this.#engine;\n try {\n const compiledFn = engine.compile(template, {\n ...options,\n });\n return compiledFn(data);\n } catch (error) {\n throw new TemplateRenderException(\n 'Pug',\n `Pug rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n\n renderFile(\n filePath: string,\n data: LocalsObject = {},\n options?: PugOptions,\n ): string {\n try {\n const template = readFileSync(filePath, 'utf-8');\n return this.render(template, data, options);\n } catch (error) {\n if (error instanceof EngineNotAvailableException) {\n throw error;\n }\n throw new TemplateRenderException(\n 'Pug',\n `Pug file rendering failed: ${String(error)}`,\n { cause: error },\n );\n }\n }\n}\n","import { EngineNotAvailableException } from '../../exceptions';\n\nexport function requireService<T>(service: T | undefined, name: string): T {\n if (!service) {\n throw new EngineNotAvailableException(name);\n }\n\n return service;\n}\n","import { Inject, Injectable, Logger, Optional } from '@nestjs/common';\nimport type { Data } from 'ejs';\nimport pLimit from 'p-limit';\nimport type { LocalsObject } from 'pug';\n\nimport { NestjsPdfException, PdfGenerationException } from '../exceptions';\nimport { mergePuppeteerParameters } from '../helpers/deepMergePdfparams';\nimport { PDF_PARAMETERS } from '../helpers/tokens';\nimport { addWatermark } from '../helpers/watermark.helper';\nimport {\n PDF_RENDERER,\n type PdfRenderer,\n} from '../renderers/pdf-renderer.interface';\nimport { BrowserService } from './browser/browser.service';\n\n/**\n * The part of BrowserService used here. Typed as an interface so the public\n * declarations of PuppeteerService do not pull Puppeteer's types in.\n */\ninterface PdfJobTracker {\n markJobStarted(): void;\n markJobFinished(): Promise<void>;\n}\nimport { EjsService } from './engines/ejs/ejs.service';\nimport { EtaService } from './engines/eta/eta.service';\nimport { HandlebarsService } from './engines/handlebars/handlebars.service';\nimport { LiquidService } from './engines/liquid/liquid.service';\nimport { MjmlService } from './engines/mjml/mjml.service';\nimport { MustacheService } from './engines/mustache/mustache.service';\nimport { NunjucksService } from './engines/nunjucks/nunjucks.service';\nimport { PugService } from './engines/pug/pug.service';\nimport { requireService } from './libs/requireService.utils';\nimport type { PuppeteerParameters } from './puppeteer-parameters.interface';\n\n@Injectable()\nexport class PuppeteerService {\n readonly #renderer: PdfRenderer;\n readonly #jobs: PdfJobTracker;\n readonly #options: PuppeteerParameters;\n readonly #hbsService?: HandlebarsService;\n readonly #mjmlService?: MjmlService;\n readonly #pugService?: PugService;\n readonly #ejsService?: EjsService;\n readonly #nunjucksService?: NunjucksService;\n readonly #etaService?: EtaService;\n readonly #mustacheService?: MustacheService;\n readonly #liquidService?: LiquidService;\n\n constructor(\n @Inject(PDF_RENDERER) renderer: PdfRenderer,\n @Inject(BrowserService) jobs: PdfJobTracker,\n @Inject(PDF_PARAMETERS) options: PuppeteerParameters,\n @Optional() hbsService?: HandlebarsService,\n @Optional() mjmlService?: MjmlService,\n @Optional() pugService?: PugService,\n @Optional() ejsService?: EjsService,\n @Optional() nunjucksService?: NunjucksService,\n @Optional() etaService?: EtaService,\n @Optional() mustacheService?: MustacheService,\n @Optional() liquidService?: LiquidService,\n ) {\n this.#renderer = renderer;\n this.#jobs = jobs;\n this.#options = options;\n this.#hbsService = hbsService;\n this.#mjmlService = mjmlService;\n this.#pugService = pugService;\n this.#ejsService = ejsService;\n this.#nunjucksService = nunjucksService;\n this.#etaService = etaService;\n this.#mustacheService = mustacheService;\n this.#liquidService = liquidService;\n }\n\n readonly #limit = pLimit(3);\n\n async generatePdfFromHtml(\n html: string,\n options?: PuppeteerParameters,\n ): Promise<Uint8Array> {\n const signal = options?.signal ?? this.#options.signal;\n signal?.throwIfAborted();\n\n let started = false;\n const job = this.#limit(async () => {\n signal?.throwIfAborted();\n started = true;\n\n const mergedOptions = mergePuppeteerParameters(this.#options, options);\n\n this.#jobs.markJobStarted();\n try {\n const pdf = await this.#renderer.render(html, mergedOptions, signal);\n signal?.throwIfAborted();\n return mergedOptions.watermark\n ? await addWatermark(pdf, mergedOptions.watermark)\n : pdf;\n } catch (e) {\n if (signal?.aborted) {\n throw signal.reason;\n }\n Logger.error(e);\n if (e instanceof NestjsPdfException) {\n throw e;\n }\n throw new PdfGenerationException(\n `PDF generation failed: ${String(e)}`,\n { cause: e },\n );\n } finally {\n await this.#jobs.markJobFinished();\n }\n });\n\n if (!signal) {\n return job;\n }\n\n let onQueuedAbort!: () => void;\n const abortedWhileQueued = new Promise<never>((_, reject) => {\n onQueuedAbort = () => {\n // An abort reason can be any value; callers expect the exact one they passed.\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n if (!started) reject(signal.reason);\n };\n signal.addEventListener('abort', onQueuedAbort, { once: true });\n });\n try {\n return await Promise.race([job, abortedWhileQueued]);\n } finally {\n signal.removeEventListener('abort', onQueuedAbort);\n }\n }\n\n async generatePdfFromTemplateHbsString(\n template: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n const hbsService = requireService(this.#hbsService, 'Handlebars');\n const html = hbsService.render(\n template,\n parameters,\n options?.hbsOptions ?? this.#options.hbsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromTemplateHbsFile(\n file: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n const hbsService = requireService(this.#hbsService, 'Handlebars');\n const html = hbsService.renderFile(\n file,\n parameters,\n options?.hbsOptions ?? this.#options.hbsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMjmlString(\n template: string,\n options?: PuppeteerParameters,\n ) {\n const mjmlService = requireService(this.#mjmlService, 'MJML');\n const html = await mjmlService.render(\n template,\n options?.mjmlOptions ?? this.#options.mjmlOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMjmlFile(file: string, options?: PuppeteerParameters) {\n const mjmlService = requireService(this.#mjmlService, 'MJML');\n const html = await mjmlService.renderFile(\n file,\n options?.mjmlOptions ?? this.#options.mjmlOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromPugString(\n template: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n const pugService = requireService(this.#pugService, 'Pug');\n const html = pugService.render(\n template,\n data,\n options?.pugOptions ?? this.#options.pugOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromPugFile(\n file: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n const pugService = requireService(this.#pugService, 'Pug');\n const html = pugService.renderFile(\n file,\n data,\n options?.pugOptions ?? this.#options.pugOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEjsString(\n template: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n const ejsService = requireService(this.#ejsService, 'EJS');\n const html = await ejsService.render(\n template,\n data,\n options?.ejsOptions ?? this.#options.ejsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEjsFile(\n file: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n const ejsService = requireService(this.#ejsService, 'EJS');\n const html = await ejsService.renderFile(\n file,\n data,\n options?.ejsOptions ?? this.#options.ejsOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromNunjucksString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const nunjucksService = requireService(this.#nunjucksService, 'Nunjucks');\n const html = nunjucksService.render(\n template,\n data,\n options?.nunjucksOptions ?? this.#options.nunjucksOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromNunjucksFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const nunjucksService = requireService(this.#nunjucksService, 'Nunjucks');\n const html = nunjucksService.renderFile(\n file,\n data,\n options?.nunjucksOptions ?? this.#options.nunjucksOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEtaString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const etaService = requireService(this.#etaService, 'Eta');\n const html = etaService.render(\n template,\n data,\n options?.etaOptions ?? this.#options.etaOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromEtaFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const etaService = requireService(this.#etaService, 'Eta');\n const html = etaService.renderFile(\n file,\n data,\n options?.etaOptions ?? this.#options.etaOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMustacheString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const mustacheService = requireService(this.#mustacheService, 'Mustache');\n const html = mustacheService.render(\n template,\n data,\n options?.mustacheOptions ?? this.#options.mustacheOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromMustacheFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const mustacheService = requireService(this.#mustacheService, 'Mustache');\n const html = mustacheService.renderFile(\n file,\n data,\n options?.mustacheOptions ?? this.#options.mustacheOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromLiquidString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const liquidService = requireService(this.#liquidService, 'Liquid');\n const html = liquidService.render(\n template,\n data,\n options?.liquidOptions ?? this.#options.liquidOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n\n async generatePdfFromLiquidFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n const liquidService = requireService(this.#liquidService, 'Liquid');\n const html = liquidService.renderFile(\n file,\n data,\n options?.liquidOptions ?? this.#options.liquidOptions,\n );\n return this.generatePdfFromHtml(html, options);\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport type { Data } from 'ejs';\nimport type { LocalsObject } from 'pug';\n\nimport { addSignatureFieldUsingAnchor } from './helpers/signature.helper';\nimport {\n addWatermark,\n type WatermarkOptions,\n} from './helpers/watermark.helper';\nimport { PuppeteerService } from './puppeteer/puppeteer.service';\nimport { PuppeteerParameters } from './puppeteer/puppeteer-parameters.interface';\n\n@Injectable()\nexport class NestjsPdfService {\n readonly #puppeteerService: PuppeteerService;\n\n constructor(puppeteerService: PuppeteerService) {\n this.#puppeteerService = puppeteerService;\n }\n\n /**\n * @param html HTML string to convert to PDF\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided HTML\n * @description This method uses the Puppeteer service to generate a PDF from an HTML string. Generation options can be customized by passing a `PuppeteerParameters` object as the second argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.\n */\n generatePdfFromHtml(html: string, options?: PuppeteerParameters) {\n return this.#puppeteerService.generatePdfFromHtml(html, options);\n }\n\n /**\n * @param template Handlebars template string\n * @param parameters Data parameters to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Handlebars template with parameters applied\n * @description This method generates a PDF from a Handlebars template provided as a string. The parameters to inject into the template are passed in the `parameters` object, which is used to render the template before converting it to PDF. PDF generation options can also be customized by passing a `PuppeteerParameters` object as the third argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.\n */\n generatePdfFromTemplateHbsString(\n template: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromTemplateHbsString(\n template,\n parameters,\n options,\n );\n }\n\n /**\n * @param file Path to the Handlebars template file\n * @param parameters Data parameters to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Handlebars template at the provided file path with parameters applied\n * @description This method generates a PDF from a Handlebars template located at the specified file path. The file path is passed as a string in the `file` parameter. The parameters to inject into the template are passed in the `parameters` object, which is used to render the template before converting it to PDF. PDF generation options can also be customized by passing a `PuppeteerParameters` object as the third argument. This allows you to control various aspects of PDF rendering, such as page size, margins, background display, etc. If no options are provided, the default parameters defined in the Puppeteer service will be used.\n */\n generatePdfFromTemplateHbsFile(\n file: string,\n parameters: any = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromTemplateHbsFile(\n file,\n parameters,\n options,\n );\n }\n\n /**\n * @param template MJML template string\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided MJML template\n * @description This method generates a PDF from an MJML template provided as a string. MJML (MJML Markup Language) is a markup language designed to reduce the pain of coding a responsive email. The template is first rendered to HTML using the MJML renderer, then converted to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the second argument.\n */\n generatePdfFromMjmlString(template: string, options?: PuppeteerParameters) {\n return this.#puppeteerService.generatePdfFromMjmlString(template, options);\n }\n\n /**\n * @param file Path to the MJML template file\n * @param options PDF generation options (optional)\n * @returns PDF generated from the MJML template at the provided file path\n * @description This method generates a PDF from an MJML template located at the specified file path. The file path is passed as a string in the `file` parameter. The template is first rendered to HTML using the MJML renderer, then converted to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the second argument.\n */\n generatePdfFromMjmlFile(file: string, options?: PuppeteerParameters) {\n return this.#puppeteerService.generatePdfFromMjmlFile(file, options);\n }\n\n /**\n * @param template EJS template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided EJS template with data applied\n * @description This method generates a PDF from an EJS (Embedded JavaScript) template provided as a string. EJS is a templating language with a simple, straightforward syntax. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEjsString(\n template: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEjsString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the EJS template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the EJS template at the provided file path with data applied\n * @description This method generates a PDF from an EJS template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEjsFile(\n file: string,\n data: Data = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEjsFile(file, data, options);\n }\n\n /**\n * @param template Pug template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Pug template with data applied\n * @description This method generates a PDF from a Pug template provided as a string. Pug is a clean, whitespace-sensitive syntax for writing HTML. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromPugString(\n template: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromPugString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Pug template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Pug template at the provided file path with data applied\n * @description This method generates a PDF from a Pug template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromPugFile(\n file: string,\n data: LocalsObject = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromPugFile(file, data, options);\n }\n\n /**\n * @param template Nunjucks template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Nunjucks template with data applied\n * @description This method generates a PDF from a Nunjucks template provided as a string. Nunjucks is a powerful templating language with support for inheritance, macros, and filters. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromNunjucksString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromNunjucksString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Nunjucks template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Nunjucks template at the provided file path with data applied\n * @description This method generates a PDF from a Nunjucks template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromNunjucksFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromNunjucksFile(\n file,\n data,\n options,\n );\n }\n\n /**\n * @param template Eta template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Eta template with data applied\n * @description This method generates a PDF from an Eta template provided as a string. Eta is a fast and lightweight embedded templating language with a syntax similar to EJS but with better performance. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEtaString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEtaString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Eta template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Eta template at the provided file path with data applied\n * @description This method generates a PDF from an Eta template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromEtaFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromEtaFile(file, data, options);\n }\n\n /**\n * @param template Mustache template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Mustache template with data applied\n * @description This method generates a PDF from a Mustache template provided as a string. Mustache is a logic-less template language that emphasizes readable and simple templates. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromMustacheString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromMustacheString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Mustache template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Mustache template at the provided file path with data applied\n * @description This method generates a PDF from a Mustache template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromMustacheFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromMustacheFile(\n file,\n data,\n options,\n );\n }\n\n /**\n * @param template Liquid template string\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the provided Liquid template with data applied\n * @description This method generates a PDF from a Liquid template provided as a string. Liquid is a safe, Shopify-compatible template language with filters, tags, partials and layouts. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromLiquidString(\n template: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromLiquidString(\n template,\n data,\n options,\n );\n }\n\n /**\n * @param file Path to the Liquid template file\n * @param data Data to inject into the template\n * @param options PDF generation options (optional)\n * @returns PDF generated from the Liquid template at the provided file path with data applied\n * @description This method generates a PDF from a Liquid template located at the specified file path. The file path is passed as a string in the `file` parameter. The data to inject into the template is passed in the `data` object, which is used to render the template before converting it to PDF. PDF generation options can be customized by passing a `PuppeteerParameters` object as the third argument.\n */\n generatePdfFromLiquidFile(\n file: string,\n data: Record<string, unknown> = {},\n options?: PuppeteerParameters,\n ) {\n return this.#puppeteerService.generatePdfFromLiquidFile(\n file,\n data,\n options,\n );\n }\n\n /**\n * @param pdf The PDF bytes to modify\n * @param fieldName The name of the signature field to add (default: 'SignatureDebtor')\n * @param anchorText The text anchor to locate the signature field position (default: '__SIG_DEBTOR_ANCHOR__')\n * @returns Modified PDF with a signature field added at the anchor position\n * @description This method adds a signature field to a PDF using a text anchor as a reference for the field position. It uses the `addSignatureFieldUsingAnchor` function which finds the anchor in the PDF and inserts a signature field at that location. The signature field is named according to the `fieldName` parameter and the anchor is defined by `anchorText`.\n *\n * Usage example:\n * ```typescript\n * const modifiedPdf = await pdfService.addSignatureFieldSignatureDebtorRaw(\n * originalPdfBytes,\n * 'SignatureDebtor',\n * '__SIG_DEBTOR_ANCHOR__'\n * );\n * ```\n *\n * In this example, `originalPdfBytes` is a byte array representing the original PDF, `SignatureDebtor` is the name of the signature field to add, and `__SIG_DEBTOR_ANCHOR__` is the anchor text used to position the signature field in the PDF.\n *\n * If the anchor is not found, the signature field will be added at a default position (centered at the bottom of the last page).\n *\n * Note: Ensure that the input PDF contains the anchor defined by `anchorText` for the signature field to be positioned correctly. Otherwise, it will be added at a default position.\n */\n async addSignatureFieldSignatureDebtorRaw(\n pdf: Uint8Array | Buffer,\n fieldName: string = 'SignatureDebtor',\n anchorText: string = '__SIG_DEBTOR_ANCHOR__',\n ) {\n return await addSignatureFieldUsingAnchor(pdf, fieldName, anchorText);\n }\n\n /**\n * @param pdf The PDF bytes to modify\n * @param options Watermark options (`text` or `image` is required)\n * @returns Modified PDF with the watermark stamped on the selected pages\n * @description Stamps a text or image watermark on an existing PDF. By default the mark is centered, rotated by 45° at 15% opacity on every page. Use `position: 'tile'` to repeat it across the page and `pages` to target specific pages (1-based). To watermark a PDF while generating it, pass the same options as `watermark` in the `PuppeteerParameters`.\n *\n * ```typescript\n * const watermarked = await pdfService.addWatermark(pdf, {\n * text: 'CONFIDENTIAL',\n * color: '#ff0000',\n * opacity: 0.2,\n * });\n * ```\n *\n * Text uses the PDF standard fonts, which only support WinAnsi characters; use an `image` for anything else.\n * @throws WatermarkException when the options are invalid or the PDF cannot be processed\n */\n async addWatermark(pdf: Uint8Array | Buffer, options: WatermarkOptions) {\n return await addWatermark(pdf, options);\n }\n}\n","import {\n DynamicModule,\n Inject,\n InjectionToken,\n Module,\n ModuleMetadata,\n OnModuleInit,\n OptionalFactoryDependency,\n Provider,\n} from '@nestjs/common';\n\nimport { PDF_PARAMETERS } from '../helpers/tokens';\nimport { createPdfRenderer, usesPuppeteer } from '../renderers/create-renderer';\nimport { PDF_RENDERER } from '../renderers/pdf-renderer.interface';\nimport { BrowserService } from './browser/browser.service';\nimport { EjsService } from './engines/ejs/ejs.service';\nimport { EtaService } from './engines/eta/eta.service';\nimport { HandlebarsService } from './engines/handlebars/handlebars.service';\nimport { LiquidService } from './engines/liquid/liquid.service';\nimport { MjmlService } from './engines/mjml/mjml.service';\nimport { MustacheService } from './engines/mustache/mustache.service';\nimport { NunjucksService } from './engines/nunjucks/nunjucks.service';\nimport { PugService } from './engines/pug/pug.service';\nimport {\n loadPuppeteer,\n loadPuppeteerBrowsers,\n} from './libs/loadPuppeteer.utils';\nimport { PuppeteerService } from './puppeteer.service';\nimport type { PuppeteerParameters } from './puppeteer-parameters.interface';\n\nexport interface PuppeteerModuleAsyncOptions extends Pick<\n ModuleMetadata,\n 'imports'\n> {\n inject?: Array<InjectionToken | OptionalFactoryDependency>;\n useFactory: (\n ...args: Array<any>\n ) => Promise<PuppeteerParameters> | PuppeteerParameters;\n}\n\n/** Builds the renderer of the configured provider, once the parameters are known. */\nconst pdfRendererProvider: Provider = {\n provide: PDF_RENDERER,\n inject: [PDF_PARAMETERS, BrowserService],\n useFactory: createPdfRenderer,\n};\n\n/** The part of BrowserService used here: keeps Puppeteer's types out of the public declarations. */\ninterface BrowserInstaller {\n install(useLockedBrowser: boolean): Promise<void>;\n}\n\n@Module({\n providers: [\n PuppeteerService,\n BrowserService,\n pdfRendererProvider,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n LiquidService,\n ],\n exports: [\n PuppeteerService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n LiquidService,\n ],\n})\nexport class PuppeteerModule implements OnModuleInit {\n readonly #browserService: BrowserInstaller;\n readonly #pdfParams: PuppeteerParameters;\n\n constructor(\n @Inject(BrowserService) browserService: BrowserInstaller,\n @Inject(PDF_PARAMETERS) pdfParams: PuppeteerParameters,\n ) {\n this.#browserService = browserService;\n this.#pdfParams = pdfParams;\n }\n\n async onModuleInit() {\n if (!usesPuppeteer(this.#pdfParams)) {\n return;\n }\n await loadPuppeteer();\n if (!this.#pdfParams.executablePath) {\n await loadPuppeteerBrowsers();\n await this.#browserService.install(\n this.#pdfParams.useLockedBrowser ?? false,\n );\n }\n }\n\n static forRoot(pdfParameters: PuppeteerParameters): DynamicModule {\n const providers: Array<Provider> = [\n {\n provide: PDF_PARAMETERS,\n useValue: pdfParameters,\n },\n HandlebarsService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n LiquidService,\n ];\n\n return {\n module: PuppeteerModule,\n providers,\n exports: [\n PuppeteerService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n LiquidService,\n ],\n };\n }\n\n static forRootAsync(options: PuppeteerModuleAsyncOptions): DynamicModule {\n const pdfParamsProvider: Provider = {\n provide: PDF_PARAMETERS,\n inject: options.inject ?? [],\n useFactory: async (...args: Array<unknown>) =>\n options.useFactory(...args),\n };\n\n return {\n module: PuppeteerModule,\n imports: options.imports ?? [],\n providers: [\n pdfParamsProvider,\n PuppeteerService,\n BrowserService,\n pdfRendererProvider,\n HandlebarsService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n LiquidService,\n ],\n exports: [\n PuppeteerService,\n MjmlService,\n PugService,\n EjsService,\n NunjucksService,\n EtaService,\n MustacheService,\n LiquidService,\n ],\n };\n }\n}\n","import { DynamicModule, Module, ModuleMetadata } from '@nestjs/common';\n\nimport { NestjsPdfService } from './nestjs-pdf.service';\nimport { PuppeteerModule } from './puppeteer/puppeteer.module';\nimport { PuppeteerParameters } from './puppeteer/puppeteer-parameters.interface';\n\nexport interface PdfLibModuleAsyncOptions extends Pick<\n ModuleMetadata,\n 'imports'\n> {\n inject?: Array<any>;\n useFactory: (...args: Array<any>) => any;\n}\n\n@Module({})\nexport class NestjsPdfModule {\n static forRoot(options: PuppeteerParameters): DynamicModule {\n return {\n module: NestjsPdfModule,\n imports: [PuppeteerModule.forRoot(options)],\n providers: [NestjsPdfService],\n exports: [NestjsPdfService],\n };\n }\n\n static forRootAsync(options: PdfLibModuleAsyncOptions): DynamicModule {\n return {\n module: NestjsPdfModule,\n imports: [PuppeteerModule.forRootAsync(options)],\n providers: [NestjsPdfService],\n exports: [NestjsPdfService],\n };\n }\n}\n"],"ignoreList":[14,15],"mappings":";;;;;;;;;;AAAA,IAAY,qBAAL,yBAAA,oBAAA;CACL,mBAAA,0BAAA;CACA,mBAAA,kCAAA;CACA,mBAAA,2BAAA;CACA,mBAAA,gCAAA;CACA,mBAAA,yBAAA;CACA,mBAAA,0BAAA;CACA,mBAAA,gCAAA;CACA,mBAAA,+BAAA;CACA,mBAAA,qBAAA;CACA,mBAAA,kCAAA;;AACF,EAAA,CAAA,CAAA;AAEA,IAAsB,qBAAtB,cAAiD,MAAM;CAGrD,YAAY,SAAiB,SAA+B;EAC1D,MAAM,SAAS,OAAO;EACtB,KAAK,OAAO,KAAK,YAAY;CAC/B;AACF;;AClBA,IAAa,+BAAb,cAAkD,mBAAmB;CACnE,OAAS;AACX;;ACFA,IAAa,8BAAb,cAAiD,mBAAmB;CAClE,OAAS;AACX;;ACFA,IAAa,8BAAb,cAAiD,mBAAmB;CAClE,OAAS;CAET,YACE,YACA,aACA,SACA;EACA,MACE,cACI,GAAG,WAAW,iCAAiC,YAAY,gDAAgD,YAAY,iBACvH,GAAG,WAAW,iFAClB,OACF;CACF;AACF;;ACfA,IAAa,yBAAb,cAA4C,mBAAmB;CAC7D,OAAS;AACX;;;ACDA,IAAa,iCAAb,cAAoD,mBAAmB;CACrE,OAAS;AACX;;ACHA,IAAa,+BAAb,cAAkD,mBAAmB;CACnE,OAAS;AACX;;ACFA,IAAa,8BAAb,cAAiD,mBAAmB;CAClE,OAAS;AACX;;ACFA,IAAa,iCAAb,cAAoD,mBAAmB;CACrE,OAAS;AACX;;ACFA,IAAa,0BAAb,cAA6C,mBAAmB;CAI5C;CAHlB,OAAS;CAET,YACE,QACA,SACA,SACA;EACA,MAAM,SAAS,OAAO;EAJN,KAAA,SAAA;CAKlB;AACF;;ACVA,IAAa,qBAAb,cAAwC,mBAAmB;CACzD,OAAS;AACX;;;;;;;;;;;ACOA,SAAgB,uBACd,WACA,kBACQ;CACR,MAAM,mBAAmB,QAAQ,WAAW,gBAAgB;CAC5D,OAAO,SAAS,QAAQ,IAAI,GAAG,gBAAgB;AACjD;;ACDA,IAAI;AAEJ,eAAe,YAAY;CACzB,IAAI,CAAC,cACH,IAAI;EACF,eAAe,MAAM,OAAO;CAC9B,SAAS,OAAO;EACd,eAAe,KAAA;EAGf,MAAM,IAAI,6BACR;GACE;GACA;GACA;GACA;GACA,mBAPW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EAQlE,CAAC,CAAC,KAAK,IAAI,GACX,EAAE,OAAO,MAAM,CACjB;CACF;CAEF,OAAO;AACT;AAEA,SAAS,KAAK,OAAwC;CACpD,OAAO,IAAI,WAAW,KAAK;AAC7B;AAEA,eAAe,mBACb,UACA,YAOC;CACD,MAAM,WAAW,MAAM,UAAU;CACjC,MAAM,cAAc,SAAS,YAAY,EAAE,MAAM,SAAS,CAAC;CAE3D,IAAI;EACF,MAAM,MAAM,MAAM,YAAY;EAE9B,KAAK,IAAI,UAAU,GAAG,WAAW,IAAI,UAAU,WAAW;GACxD,MAAM,OAAO,MAAM,IAAI,QAAQ,OAAO;GACtC,MAAM,WAAW,KAAK,YAAY,EAAE,OAAO,EAAE,CAAC;GAC9C,MAAM,cAAc,MAAM,KAAK,eAAe;GAE9C,KAAK,MAAM,WAAW,YAAY,OAAO;IACvC,MAAM,OAAO;IAEb,IAAI,CADQ,KAAK,KACP,SAAS,UAAU,GAAG;IAGhC,MAAM,CAAC,IAAI,IAAI,IAAI,IAAI,GAAG,KADhB,SAAS,KAAK,UAAU,SAAS,WAAW,KAAK,SAC5B;IAE/B,MAAM,IAAI;IACV,MAAM,IAAI,SAAS,SAAS;IAE5B,OAAO;KACL,WAAW,UAAU;KACrB;KACA;KACA,WAAW,SAAS;KACpB,YAAY,SAAS;IACvB;GACF;EACF;EACA,OAAO;CACT,UAAU;EACR,MAAM,YAAY,QAAQ;CAC5B;AACF;AAEA,SAAS,oBACP,QACA,WACA,MAOA;CACA,MAAM,EAAE,WAAW,GAAG,GAAG,OAAO,WAAW;CAC3C,MAAM,UAAU,OAAO;CAEvB,MAAM,OAAO,OAAO,SAAS,CAAC,CAAC;CAE/B,MAAM,YAAY,QAAQ,IAAI;EAC5B,UAAU,GAAG,CAAC;EACd,UAAU,GAAG,CAAC;EACd,UAAU,GAAG,IAAI,KAAK;EACtB,UAAU,GAAG,IAAI,MAAM;CACzB,CAAC;CAED,MAAM,aAAa,QAAQ,IAAI;EAC7B,MAAM,QAAQ,GAAG,OAAO;EACxB,SAAS,QAAQ,GAAG,QAAQ;EAC5B,MAAM;EACN,GAAG,UAAU,GAAG,CAAC;EACjB,GAAG,KAAK;CACV,CAAC;CACD,MAAM,YAAY,QAAQ,SAAS,UAAU;CAE7C,MAAM,YAAY,QAAQ,IAAI;EAC5B,IAAI,QAAQ,GAAG,KAAK;EACpB,GAAG,UAAU,GAAG,SAAS;EACzB,IAAI,UAAU,GAAG,CAAC;EAClB,MAAM,QAAQ,IAAI,CAAC,SAAS,CAAC;CAC/B,CAAC;CACD,MAAM,WAAW,QAAQ,SAAS,SAAS;CAE3C,WAAW,IAAI,QAAQ,GAAG,QAAQ,GAAG,QAAQ;CAE7C,IAAI,SAAS,KAAK,KAAK,YAAY,QAAQ,GAAG,QAAQ,GAAG,QAAQ;CACjE,IAAI,CAAC,QAAQ;EACX,SAAS,QAAQ,IAAI,CAAC,CAAC;EACvB,KAAK,KAAK,IAAI,QAAQ,GAAG,QAAQ,GAAG,MAAM;CAC5C;CACA,OAAO,KAAK,SAAS;CAErB,IAAI,WAAW,OAAO,QAAQ,YAAY,QAAQ,GAAG,UAAU,GAAG,OAAO;CACzE,IAAI,CAAC,UAAU;EACb,WAAW,QAAQ,IAAI;GACrB,QAAQ,QAAQ,IAAI,CAAC,CAAC;GACtB,UAAU,UAAU,GAAG,CAAC;EAC1B,CAAC;EACD,MAAM,cAAc,QAAQ,SAAS,QAAQ;EAC7C,OAAO,QAAQ,IAAI,QAAQ,GAAG,UAAU,GAAG,WAAW;CACxD;CAEA,IAAI,SAAS,SAAS,YAAY,QAAQ,GAAG,QAAQ,GAAG,QAAQ;CAChE,IAAI,CAAC,QAAQ;EACX,SAAS,QAAQ,IAAI,CAAC,CAAC;EACvB,SAAS,IAAI,QAAQ,GAAG,QAAQ,GAAG,MAAM;CAC3C;CACA,OAAO,KAAK,QAAQ;CAEpB,OAAO;EAAE;EAAU;CAAU;AAC/B;AAEA,eAAsB,6BACpB,KACA,YAAY,mBACZ,aAAa,yBACb;CACA,MAAM,QAAQ,KAAK,GAAG;CAEtB,MAAM,SAAS,MAAM,mBAAmB,MAAM,MAAM,GAAG,UAAU;CAEjE,MAAM,SAAS,MAAM,YAAY,KAAK,KAAK;CAE3C,MAAM,WAAW;CACjB,MAAM,YAAY;CAElB,IAAI,QAAQ;EACV,MAAM,YAAY,OAAO;EACzB,MAAM,OAAO,OAAO,SAAS,CAAC,CAAC;EAC/B,IAAI,CAAC,MACH,MAAM,IAAI,4BAA4B,QAAQ,UAAU,WAAW;EAErE,MAAM,EAAE,OAAO,IAAI,QAAQ,OAAO,KAAK,QAAQ;EAE/C,MAAM,OAAO;EACb,MAAM,OAAO;EACb,IAAI,IAAI,OAAO,IAAI,WAAW,IAAI;EAElC,IAAI,IAAI,OAAO,IAAI,YAAY;EAE/B,MAAM,SAAS;EAEf,IAAI,KAAK,IAAI,QAAQ,KAAK,IAAI,GAAG,KAAK,WAAW,MAAM,CAAC;EACxD,IAAI,KAAK,IAAI,QAAQ,KAAK,IAAI,GAAG,KAAK,YAAY,MAAM,CAAC;EAEzD,oBAAoB,QAAQ,OAAO,WAAW;GAC5C;GACA;GACA;GACA,OAAO;GACP,QAAQ;EACV,CAAC;CACH,OAAO;EACL,MAAM,QAAQ,OAAO,SAAS;EAC9B,MAAM,YAAY,MAAM,SAAS;EACjC,MAAM,OAAO,MAAM,GAAG,EAAE;;EAExB,IAAI,CAAC,MACH,MAAM,IAAI,4BAA4B,QAAQ,UAAU,WAAW;EAErE,MAAM,EAAE,OAAO,cAAc,KAAK,QAAQ;EAI1C,oBAAoB,QAAQ,WAAW;GACrC;GACA,IALS,YAAY,YAAY;GAMjC,GAAA;GACA,OAAO;GACP,QAAQ;EACV,CAAC;CACH;CAEA,OAAO,MAAM,OAAO,KAAK;AAC3B;;AC3LA,MAAM,kBAAkB;AACxB,MAAM,mBAAmB;AACzB,MAAM,oBAAoB;AAC1B,MAAM,eAA2C;AACjD,MAAM,gBAAgB;AACtB,MAAM,uBAAuB;AAQ7B,SAAS,cAAc,OAAe;CACpC,MAAM,QAAQ,8BAA8B,KAAK,KAAK;CACtD,IAAI,CAAC,OACH,MAAM,IAAI,mBACR,4BAA4B,MAAM,4BACpC;CAEF,MAAM,MACJ,MAAM,EAAE,CAAC,WAAW,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,MAAM;CAC3E,MAAM,WAAW,MAAc,OAAO,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI;CAC1E,OAAO,IAAI,QAAQ,CAAC,GAAG,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC;AAC/C;AAEA,SAAS,WAAW,QAAqB,OAAsC;CAC7E,MAAM,QAAQ,MAAM,OAAO,OAAQ,MAAM,OAAO,MAAQ,MAAM,OAAO;CACrE,MAAM,SAAS,MAAM,OAAO,OAAQ,MAAM,OAAO;CACjD,IAAI,OAAO,OAAO,OAAO,SAAS,KAAK;CACvC,IAAI,QAAQ,OAAO,OAAO,SAAS,KAAK;CACxC,MAAM,IAAI,mBAAmB,uCAAuC;AACtE;AAEA,SAAS,SAAS,SAA2B;CAC3C,MAAM,EAAE,MAAM,OAAO,SAAS,UAAU,YAAY,gBAAgB;CACpE,IAAI,CAAC,QAAQ,CAAC,OACZ,MAAM,IAAI,mBACR,sDACF;CAEF,IAAI,YAAY,KAAA,KAAa,EAAE,WAAW,KAAK,WAAW,IACxD,MAAM,IAAI,mBAAmB,6CAA6C;CAE5E,IAAI,aAAa,KAAA,KAAa,EAAE,WAAW,IACzC,MAAM,IAAI,mBAAmB,6CAA6C;CAE5E,IAAI,eAAe,KAAA,KAAa,EAAE,aAAa,IAC7C,MAAM,IAAI,mBACR,+CACF;CAEF,IAAI,gBAAgB,KAAA,KAAa,EAAE,eAAe,IAChD,MAAM,IAAI,mBAAmB,4CAA4C;AAE7E;AAEA,SAAS,mBAAmB,OAAkC,OAAe;CAC3E,IAAI,CAAC,OACH,OAAO,MAAM,KAAK,EAAE,QAAQ,MAAM,IAAI,GAAG,MAAM,CAAC;CAElD,KAAK,MAAM,QAAQ,OACjB,IAAI,CAAC,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,OAAO,OAChD,MAAM,IAAI,mBACR,kBAAkB,KAAK,gCAAgC,MAAM,UAC/D;CAGJ,OAAO,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,OAAO,CAAC;AACnD;;;;;AAMA,SAAS,YACP,WACA,YACA,MACA,SACA;CACA,MAAM,KAAK,YAAY;CACvB,MAAM,KAAK,aAAa;CACxB,IAAI,QAAQ,aAAa,UACvB,OAAO,CAAC;EAAE,GAAG;EAAI,GAAG;CAAG,CAAC;CAG1B,MAAM,QAAS,QAAQ,WAAW,KAAK,KAAM;CAC7C,MAAM,MAAM,KAAK,IAAI,KAAK;CAC1B,MAAM,MAAM,KAAK,IAAI,KAAK;CAC1B,MAAM,QAAQ,KAAK,QAAQ,QAAQ;CACnC,MAAM,QAAQ,KAAK,SAAS,QAAQ;CACpC,MAAM,QAAQ,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,IAAI;CACpD,MAAM,IAAI,KAAK,MACZ,KAAK,MAAM,WAAW,UAAU,IAAI,IAAI,SAAS,KAAK,IAAI,OAAO,KAAK,CACzE;CAEA,MAAM,UAA2C,CAAC;CAClD,KAAK,IAAI,IAAI,CAAC,GAAG,KAAK,GAAG,KACvB,KAAK,IAAI,IAAI,CAAC,GAAG,KAAK,GAAG,KAAK;EAC5B,MAAM,IAAI,KAAK,IAAI,QAAQ,MAAM,IAAI,QAAQ;EAC7C,MAAM,IAAI,KAAK,IAAI,QAAQ,MAAM,IAAI,QAAQ;EAC7C,IACE,KAAK,CAAC,SACN,KAAK,YAAY,SACjB,KAAK,CAAC,SACN,KAAK,aAAa,OAElB,QAAQ,KAAK;GAAE;GAAG;EAAE,CAAC;CAEzB;CAEF,OAAO;AACT;AAEA,eAAe,UACb,QACA,SACA,WACe;CACf,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,SAAS,QAAQ,QAAQ,YAAY,gBAAgB;CAE3D,IAAI,QAAQ,OAAO;EACjB,MAAM,QAAQ,MAAM,WAAW,QAAQ,IAAI,WAAW,QAAQ,KAAK,CAAC;EACpE,MAAM,QAAQ,QAAQ,cAAc,YAAY;EAChD,MAAM,SAAU,MAAM,SAAS,MAAM,QAAS;EAC9C,OAAO;GACL;GACA;GACA,OAAO,MAAM,GAAG,MACd,KAAK,UAAU,OAAO;IAAE;IAAG;IAAG;IAAO;IAAQ;IAAS;GAAO,CAAC;EAClE;CACF;CAEA,MAAM,OAAO,MAAM,OAAO,UACxB,cAAc,QAAQ,QAAQ,aAChC;CACA,MAAM,OAAO,QAAQ,YAAY;CACjC,MAAM,OAAO,QAAQ;CACrB,MAAM,QAAQ,cAAc,QAAQ,SAAS,aAAa;CAC1D,IAAI;CACJ,IAAI;EACF,QAAQ,KAAK,kBAAkB,MAAM,IAAI;CAC3C,SAAS,OAAO;EACd,MAAM,IAAI,mBACR,8CAA8C,QAAQ,QAAQ,aAAa,gDAC3E,EAAE,OAAO,MAAM,CACjB;CACF;CACA,OAAO;EACL;EACA,QAAQ,KAAK,aAAa,MAAM,EAAE,WAAW,MAAM,CAAC;EACpD,OAAO,MAAM,GAAG,MACd,KAAK,SAAS,MAAM;GAAE;GAAG;GAAG;GAAM;GAAM;GAAO;GAAS;EAAO,CAAC;CACpE;AACF;;;;AAKA,eAAsB,aACpB,KACA,SACqB;CACrB,SAAS,OAAO;CAEhB,IAAI;EACF,MAAM,SAAS,MAAM,YAAY,KAAK,IAAI,WAAW,GAAG,CAAC;EACzD,MAAM,QAAQ,OAAO,SAAS;EAC9B,MAAM,UAAU,mBAAmB,QAAQ,OAAO,MAAM,MAAM;EAE9D,MAAM,WAAW,QAAQ,YAAY;EACrC,MAAM,WAAW,QAAQ,YAAY;EACrC,MAAM,UAAU,QAAQ,eAAe;EACvC,MAAM,QAAS,WAAW,KAAK,KAAM;EACrC,MAAM,MAAM,KAAK,IAAI,KAAK;EAC1B,MAAM,MAAM,KAAK,IAAI,KAAK;EAG1B,MAAM,wBAAQ,IAAI,IAAkB;EAEpC,KAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,OAAO,MAAM;GACnB,MAAM,EAAE,OAAO,WAAW,QAAQ,eAAe,KAAK,QAAQ;GAE9D,IAAI,OAAO,MAAM,IAAI,SAAS;GAC9B,IAAI,CAAC,MAAM;IACT,OAAO,MAAM,UAAU,QAAQ,SAAS,SAAS;IACjD,MAAM,IAAI,WAAW,IAAI;GAC3B;GAEA,KAAK,MAAM,UAAU,YAAY,WAAW,YAAY,MAAM;IAC5D;IACA;IACA;GACF,CAAC,GAGC,KAAK,KACH,MACA,OAAO,KAAM,KAAK,QAAQ,IAAK,MAAO,KAAK,SAAS,IAAK,MACzD,OAAO,KAAM,KAAK,QAAQ,IAAK,MAAO,KAAK,SAAS,IAAK,IAC3D;EAEJ;EAEA,OAAO,MAAM,OAAO,KAAK;CAC3B,SAAS,OAAO;EACd,IAAI,iBAAiB,oBAAoB,MAAM;EAC/C,MAAM,IAAI,mBACR,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KACjF,EAAE,OAAO,MAAM,CACjB;CACF;AACF;;ACtPA,IAAM,OAAN,MAAW;CACV;CACA;CAEA,YAAY,OAAO;EAClB,KAAK,QAAQ;CACd;AACD;AAEA,IAAqB,QAArB,MAA2B;CAC1B;CACA;CACA;CAEA,cAAc;EACb,KAAK,MAAM;CACZ;CAEA,QAAQ,OAAO;EACd,MAAM,OAAO,IAAI,KAAK,KAAK;EAE3B,IAAI,KAAK,OAAO;GACf,KAAK,MAAM,OAAO;GAClB,KAAK,QAAQ;EACd,OAAO;GACN,KAAK,QAAQ;GACb,KAAK,QAAQ;EACd;EAEA,KAAK;CACN;CAEA,UAAU;EACT,MAAM,UAAU,KAAK;EACrB,IAAI,CAAC,SACJ;EAGD,KAAK,QAAQ,KAAK,MAAM;EACxB,KAAK;EAGL,IAAI,CAAC,KAAK,OACT,KAAK,QAAQ,KAAA;EAGd,OAAO,QAAQ;CAChB;CAEA,OAAO;EACN,IAAI,CAAC,KAAK,OACT;EAGD,OAAO,KAAK,MAAM;CAInB;CAEA,QAAQ;EACP,KAAK,QAAQ,KAAA;EACb,KAAK,QAAQ,KAAA;EACb,KAAK,QAAQ;CACd;CAEA,IAAI,OAAO;EACV,OAAO,KAAK;CACb;CAEA,EAAG,OAAO,YAAY;EACrB,IAAI,UAAU,KAAK;EAEnB,OAAO,SAAS;GACf,MAAM,QAAQ;GACd,UAAU,QAAQ;EACnB;CACD;CAEA,CAAE,QAAQ;EACT,OAAO,KAAK,OACX,MAAM,KAAK,QAAQ;CAErB;AACD;;ACvFA,SAAwB,OAAO,aAAa;CAC3C,IAAI,gBAAgB;CAEpB,IAAI,OAAO,gBAAgB,UAC1B,CAAC,CAAC,aAAa,gBAAgB,SAAS;CAGzC,oBAAoB,WAAW;CAE/B,IAAI,OAAO,kBAAkB,WAC5B,MAAM,IAAI,UAAU,0CAA0C;CAG/D,MAAM,QAAQ,IAAI,MAAM;CACxB,IAAI,cAAc;CAElB,MAAM,mBAAmB;EAExB,IAAI,cAAc,eAAe,MAAM,OAAO,GAAG;GAChD;GACA,MAAM,QAAQ,CAAC,CAAC,IAAI;EACrB;CACD;CAEA,MAAM,aAAa;EAClB;EACA,WAAW;CACZ;CAEA,MAAM,MAAM,OAAO,WAAW,SAAS,eAAe;EAErD,MAAM,UAAU,YAAY,UAAU,GAAG,UAAU,EAAA,CAAG;EAGtD,QAAQ,MAAM;EAKd,IAAI;GACH,MAAM;EACP,QAAQ,CAAC;EAGT,KAAK;CACN;CAEA,MAAM,WAAW,WAAW,SAAS,QAAQ,eAAe;EAC3D,MAAM,YAAY,EAAC,OAAM;EAIzB,IAAI,SAAQ,oBAAmB;GAC9B,UAAU,MAAM;GAChB,MAAM,QAAQ,SAAS;EACxB,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,KAAA,GAAW,WAAW,SAAS,UAAU,CAAC;EAG3D,IAAI,cAAc,aACjB,WAAW;CAEb;CAEA,MAAM,aAAa,WAAW,GAAG,eAAe,IAAI,SAAS,SAAS,WAAW;EAChF,QAAQ,WAAW,SAAS,QAAQ,UAAU;CAC/C,CAAC;CAED,OAAO,iBAAiB,WAAW;EAClC,aAAa,EACZ,WAAW,YACZ;EACA,cAAc,EACb,WAAW,MAAM,KAClB;EACA,YAAY,EACX,QAAQ;GACP,IAAI,CAAC,eAAe;IACnB,MAAM,MAAM;IACZ;GACD;GAEA,MAAM,aAAa,YAAY,MAAM,CAAC,CAAC;GAEvC,OAAO,MAAM,OAAO,GACnB,MAAM,QAAQ,CAAC,CAAC,OAAO,UAAU;EAEnC,EACD;EACA,aAAa;GACZ,WAAW;GAEX,IAAI,gBAAgB;IACnB,oBAAoB,cAAc;IAClC,cAAc;IAEd,qBAAqB;KAEpB,OAAO,cAAc,eAAe,MAAM,OAAO,GAChD,WAAW;IAEb,CAAC;GACF;EACD;EACA,KAAK,EACJ,MAAM,MAAM,UAAU,WAAW;GAChC,MAAM,WAAW,CAAC;GAElB,IAAI;IACH,MAAM,KAAK,WAAW,OAAO,UAAU;KACtC,MAAM,UAAU,UAAU,WAAW,OAAO,KAAK;KACjD,SAAS,KAAK,OAAO;KACrB,OAAO;IACR,CAAC;GACF,SAAS,OAAO;IAEf,KAAK,MAAM,WAAW,UACrB,QAAQ,YAAY,CAAC,CAAC;IAGvB,MAAM;GACP;GAEA,OAAO,QAAQ,IAAI,QAAQ;EAC5B,EACD;CACD,CAAC;CAED,OAAO;AACR;AAaA,SAAS,oBAAoB,aAAa;CACzC,IAAI,GAAG,OAAO,UAAU,WAAW,KAAK,gBAAgB,OAAO,sBAAsB,cAAc,IAClG,MAAM,IAAI,UAAU,qDAAqD;AAE3E;;AC/IA,SAAgB,yBACd,UACA,WACqB;CACrB,IAAI,CAAC,WACH,OAAO,EAAE,GAAG,SAAS;CAGvB,OAAO,UAAU,UAAU,SAAS;AACtC;;ACbA,MAAa,iBAAiB;;ACE9B,MAAa,eAAe;;ACI5B,MAAM,wBAAwB;;AAG9B,eAAsB,UACpB,UACA,UACiC;CACjC,IAAI,OAAO;CACX,IAAI;EACF,QAAQ,MAAM,SAAS,KAAK,EAAA,CAAG,KAAK,CAAC,CAAC,MAAM,GAAG,qBAAqB;CACtE,QAAQ,CAER;CAEA,OAAO,IAAI,uBACT,GAAG,SAAS,uBAAuB,SAAS,SAAS,OAAO,KAAK,SAAS,IAC5E;AACF;;AAGA,SAAgB,qBACd,UACA,SACA,MACM;CACN,IAAI,QAAQ,UACV,MAAM,IAAI,+BACR,6EAA6E,SAAS,IAAI,MAC5F;AAEJ;AAEA,SAAgB,gBACd,OACA,MACA,UACQ;CACR,IAAI,CAAC,OAAO,KAAK,GACf,MAAM,IAAI,+BACR,OAAO,SAAS,kCAAkC,KAAK,EACzD;CAEF,OAAO;AACT;;;AC7CA,MAAM,gBAAmE;CACvE,QAAQ;EAAE,OAAO;EAAK,QAAQ;CAAG;CACjC,OAAO;EAAE,OAAO;EAAK,QAAQ;CAAG;CAChC,SAAS;EAAE,OAAO;EAAI,QAAQ;CAAG;CACjC,QAAQ;EAAE,OAAO;EAAI,QAAQ;CAAG;CAChC,IAAI;EAAE,OAAO;EAAS,QAAQ;CAAO;CACrC,IAAI;EAAE,OAAO;EAAS,QAAQ;CAAQ;CACtC,IAAI;EAAE,OAAO;EAAS,QAAQ;CAAQ;CACtC,IAAI;EAAE,OAAO;EAAS,QAAQ;CAAQ;CACtC,IAAI;EAAE,OAAO;EAAQ,QAAQ;CAAQ;CACrC,IAAI;EAAE,OAAO;EAAQ,QAAQ;CAAO;CACpC,IAAI;EAAE,OAAO;EAAQ,QAAQ;CAAO;AACtC;AAEA,MAAM,kBAA0C;CAC9C,IAAI,IAAI;CACR,IAAI;CACJ,IAAI,IAAI;CACR,IAAI,IAAI;AACV;;;;;AAMA,SAAgB,SAAS,OAAgC;CACvD,IAAI,OAAO,UAAU,UACnB,OAAO,QAAQ,gBAAgB;CAGjC,MAAM,QAAQ,0CAA0C,KAAK,KAAK;CAClE,IAAI,CAAC,OACH,MAAM,IAAI,+BACR,mBAAmB,MAAM,8DAC3B;CAGF,MAAM,QAAQ,MAAM,MAAM,KAAA,CAAM,YAAY;CAC5C,OAAO,OAAO,MAAM,EAAE,IAAI,gBAAgB;AAC5C;AAEA,SAAS,aAAa,QAAwB;CAC5C,OAAO,OAAO,KAAK,MAAM,SAAS,GAAM,IAAI,GAAM;AACpD;AAUA,SAAgB,mBAAmB,YAAqC;CACtE,IAAI;CACJ,IAAI;CAEJ,IAAI,WAAW,UAAU,KAAA,KAAa,WAAW,WAAW,KAAA,GAAW;EACrE,MAAM,WAAW,cAAc;EAC/B,QACE,WAAW,UAAU,KAAA,IACjB,SAAS,QACT,SAAS,WAAW,KAAK;EAC/B,SACE,WAAW,WAAW,KAAA,IAClB,SAAS,SACT,SAAS,WAAW,MAAM;CAClC,OAAO;EACL,MAAM,cAAc,WAAW,UAAU,SAAA,CAAU,YAAY;EAC/D,MAAM,SAAS,cAAc;EAC7B,IAAI,CAAC,QACH,MAAM,IAAI,+BACR,yBAAyB,WAAW,OAAO,EAC7C;EAEF,CAAC,CAAE,OAAO,UAAW;CACvB;CAEA,MAAM,SAAgC,CAAC;CACvC,KAAK,MAAM,QAAQ;EAAC;EAAO;EAAS;EAAU;CAAM,GAAY;EAC9D,MAAM,QAAQ,WAAW,SAAS;EAClC,IAAI,UAAU,KAAA,GACZ,OAAO,QAAQ,SAAS,KAAK;CAEjC;CAEA,OAAO;EAAE;EAAO;EAAQ;CAAO;AACjC;AAEA,SAAS,eAAe,UAA0B;CAChD,OAAO,cAAc,KAAK,QAAQ,IAC9B,WACA,2CAA2C,SAAS;AAC1D;AAQA,SAAgB,gBAAgB,YAAuC;CACrE,MAAM,EAAE,OAAO,QAAQ,WAAW,mBAAmB,UAAU;CAE/D,MAAM,SAAiC;EACrC,YAAY,aAAa,KAAK;EAC9B,aAAa,aAAa,MAAM;EAEhC,WAAW,aAAa,OAAO,OAAO,CAAC;EACvC,aAAa,aAAa,OAAO,SAAS,CAAC;EAC3C,cAAc,aAAa,OAAO,UAAU,CAAC;EAC7C,YAAY,aAAa,OAAO,QAAQ,CAAC;EAEzC,mBAAmB;EACnB,sBAAsB;CACxB;CAEA,IAAI,WAAW,cAAc,KAAA,GAC3B,OAAO,YAAY,OAAO,WAAW,SAAS;CAEhD,IAAI,WAAW,oBAAoB,KAAA,GACjC,OAAO,kBAAkB,OAAO,WAAW,eAAe;CAE5D,IAAI,WAAW,mBAAmB,KAAA,GAChC,OAAO,iBAAiB,OAAO,WAAW,cAAc;CAE1D,IAAI,WAAW,UAAU,KAAA,GAAW,OAAO,QAAQ,OAAO,WAAW,KAAK;CAC1E,IAAI,WAAW,YAAY,OAAO,mBAAmB,WAAW;CAChE,IAAI,WAAW,sBAAsB,KAAA,GACnC,OAAO,oBAAoB,OAAO,WAAW,iBAAiB;CAEhE,IAAI,WAAW,WAAW,KAAA,GACxB,OAAO,oBAAoB,OAAO,WAAW,MAAM;CAErD,IAAI,WAAW,YAAY,KAAA,GACzB,OAAO,0BAA0B,OAAO,WAAW,OAAO;CAG5D,MAAM,QAAgC,CAAC;CACvC,IAAI,WAAW,qBAAqB;EAClC,IAAI,WAAW,gBACb,MAAM,iBAAiB,eAAe,WAAW,cAAc;EAEjE,IAAI,WAAW,gBACb,MAAM,iBAAiB,eAAe,WAAW,cAAc;CAEnE;CAEA,OAAO;EAAE;EAAQ;CAAM;AACzB;AAEA,SAAgB,iBACd,YACyB;CACzB,MAAM,EAAE,OAAO,QAAQ,WAAW,mBAAmB,UAAU;CAE/D,MAAM,UAAmC;EACvC,OAAO,GAAG,aAAa,KAAK,EAAE;EAC9B,QAAQ,GAAG,aAAa,MAAM,EAAE;EAChC,WAAW,GAAG,aAAa,OAAO,OAAO,CAAC,EAAE;EAC5C,aAAa,GAAG,aAAa,OAAO,SAAS,CAAC,EAAE;EAChD,cAAc,GAAG,aAAa,OAAO,UAAU,CAAC,EAAE;EAClD,YAAY,GAAG,aAAa,OAAO,QAAQ,CAAC,EAAE;EAE9C,aAAa;CACf;CAYA,KAAK,MAAM,OAAO;EAThB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CAE0B,GAC1B,IAAI,WAAW,SAAS,KAAA,GACtB,QAAQ,OAAO,WAAW;CAI9B,OAAO;AACT;;ACrLA,MAAMA,aAAW;AACjB,MAAM,mBAAmB;AACzB,MAAMC,UAAQ;AAQd,SAAS,UAAU,MAAwC;CACzD,OACE,OAAO,SAAS,YAChB,SAAS,SACR,aAAa,QAAQ,WAAW,QAAQ,aAAa;AAE1D;AAEA,IAAa,kBAAb,MAAoD;CAClD;CACA;CAEA,YAAY,UAAkC;EAC5C,MAAM,SAAS,gBAAgB,SAAS,QAAQ,UAAUD,UAAQ;EAClE,MAAM,UAAU,gBACd,SAAS,WAAW,kBACpB,WACAA,UACF,CAAC,CAAC,QAAQ,QAAQ,EAAE;EACpB,KAAK,YAAY,GAAG,UAAUC,QAAM;EACpC,KAAK,WAAW;GACd,GAAG,SAAS;GACZ,eAAe;GACf,gBAAgB;GAChB,QAAQ;EACV;CACF;CAEA,MAAM,OACJ,MACA,SACA,QACqB;EACrB,qBACED,YACA,SACA,kDACF;EAMA,MAAM,OAAgC;GACpC;GACA,QAAQ;GACR,SAAS;IANT,GAAG,iBAAiB,QAAQ,cAAc,EAAE,QAAQ,KAAK,CAAC;IAC1D,GAAG,QAAQ,gBAAgB;GAKL;EACxB;EACA,IAAI,QAAQ,gBAAgB,UAC1B,KAAK,WAAW,QAAQ,eAAe;EAGzC,MAAM,WAAW,MAAM,MAAM,KAAK,WAAW;GAC3C,QAAQ;GACR,SAAS,KAAK;GACd,MAAM,KAAK,UAAU,IAAI;GACzB;EACF,CAAC;EACD,IAAI,CAAC,SAAS,IACZ,MAAM,MAAM,UAAUA,YAAU,QAAQ;EAG1C,IAAI,CAAC,SAAS,QAAQ,IAAI,cAAc,CAAC,EAAE,SAAS,kBAAkB,GACpE,OAAO,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;EAGpD,MAAM,SAAkB,MAAM,SAAS,KAAK;EAC5C,IAAI,CAAC,UAAU,MAAM,GACnB,MAAM,IAAI,uBACR,GAAGA,WAAS,oCAAoC,KAAK,UAAU,MAAM,GACvE;EAEF,IAAI,OAAO,YAAY,SAAS,CAAC,OAAO,SACtC,MAAM,IAAI,uBACR,GAAGA,WAAS,+BAA+B,OAAO,SAAS,oBAC7D;EAGF,MAAM,OAAO,MAAM,MAAM,OAAO,SAAS,EAAE,OAAO,CAAC;EACnD,IAAI,CAAC,KAAK,IACR,MAAM,MAAM,UAAUA,YAAU,IAAI;EAEtC,OAAO,IAAI,WAAW,MAAM,KAAK,YAAY,CAAC;CAChD;AACF;;AC/FA,MAAM,WAAW;AACjB,MAAM,QAAQ;AAEd,IAAa,oBAAb,MAAsD;CACpD;CACA;CAEA,YAAY,UAAoC;EAC9C,MAAM,MAAM,gBAAgB,SAAS,KAAK,OAAO,QAAQ;EACzD,KAAK,YAAY,GAAG,IAAI,QAAQ,QAAQ,EAAE,IAAI;EAE9C,KAAK,WAAW,EAAE,GAAG,SAAS,QAAQ;EACtC,IAAI,SAAS,WAAW;GACtB,MAAM,EAAE,UAAU,aAAa,SAAS;GACxC,KAAK,SAAS,gBAAgB,SAAS,OAAO,KAC5C,GAAG,SAAS,GAAG,UACjB,CAAC,CAAC,SAAS,QAAQ;EACrB;CACF;CAEA,MAAM,OACJ,MACA,SACA,QACqB;EACrB,qBACE,UACA,SACA,oHACF;EAEA,MAAM,EAAE,QAAQ,UAAU,gBACxB,QAAQ,cAAc,EAAE,QAAQ,KAAK,CACvC;EAEA,MAAM,OAAO,IAAI,SAAS;EAC1B,KAAK,OAAO,SAAS,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,YAAY,CAAC,GAAG,YAAY;EAC1E,KAAK,MAAM,CAAC,MAAM,YAAY,OAAO,QAAQ,KAAK,GAChD,KAAK,OAAO,SAAS,IAAI,KAAK,CAAC,OAAO,GAAG,EAAE,MAAM,YAAY,CAAC,GAAG,IAAI;EAEvE,KAAK,MAAM,SAAS,QAAQ,kBAAkB,UAAU,CAAC,GACvD,KAAK,OACH,SACA,IAAI,KAAK,CAAC,MAAM,OAAmB,GAAG,EACpC,MAAM,MAAM,eAAe,2BAC7B,CAAC,GACD,MAAM,QACR;EAEF,MAAM,YAAY;GAAE,GAAG;GAAQ,GAAG,QAAQ,kBAAkB;EAAW;EACvE,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,SAAS,GAClD,KAAK,OAAO,MAAM,KAAK;EAGzB,MAAM,WAAW,MAAM,MAAM,KAAK,WAAW;GAC3C,QAAQ;GACR,SAAS,KAAK;GACd,MAAM;GACN;EACF,CAAC;EACD,IAAI,CAAC,SAAS,IACZ,MAAM,MAAM,UAAU,UAAU,QAAQ;EAG1C,OAAO,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;CACpD;AACF;;ACnEA,SAAS,iBAAiB,OAAgB,aAA8B;CACtE,MAAM,EAAE,MAAM,YAAY;CAC1B,QACG,SAAS,0BAA0B,SAAS,uBAC7C,OAAO,YAAY,YACnB,QAAQ,SAAS,IAAI,YAAY,EAAE;AAEvC;;AAGA,eAAsB,aACpB,aACA,UACY;CACZ,IAAI;EACF,OAAO,MAAM,SAAS;CACxB,SAAS,OAAO;EACd,IAAI,iBAAiB,OAAO,WAAW,GACrC,MAAM,IAAI,4BAA4B,aAAa,aAAa,EAC9D,OAAO,MACT,CAAC;EAEH,MAAM;CACR;AACF;;;;;AAMA,SAAgB,gBAA2C;CACzD,OAAO,aAAa,mBAAmB,OAAO,YAAY;AAC5D;AAEA,SAAgB,wBAA2D;CACzE,OAAO,aACL,6BACM,OAAO,sBACf;AACF;;ACFA,MAAM,gBAAgB,IAAI,UAAU;AACpC,KAAK,MAAM,CAAC,SAAS,WAAW;CAC9B,CAAC,WAAW,CAAC;CACb,CAAC,YAAY,CAAC;CACd,CAAC,cAAc,EAAE;CACjB,CAAC,aAAa,CAAC;CACf,CAAC,eAAe,EAAE;CAClB,CAAC,cAAc,EAAE;CACjB,CAAC,aAAa,EAAE;CAChB,CAAC,eAAe,EAAE;CAClB,CAAC,cAAc,EAAE;CACjB,CAAC,aAAa,CAAC;CACf,CAAC,aAAa,CAAC;AACjB,GACE,cAAc,UAAU,SAAS,QAAQ,MAAM;AAEjD,KAAK,MAAM,CAAC,SAAS,WAAW;CAC9B,CAAC,MAAM,GAAG;CACV,CAAC,OAAO,GAAG;CACX,CAAC,aAAa,EAAE;CAChB,CAAC,UAAU,CAAC;CACZ,CAAC,UAAU,EAAE;CACb,CAAC,UAAU,CAAC;AACd,GACE,cAAc,UAAU,SAAS,QAAQ,MAAM;AAGjD,MAAM,mBAAmB;;AAGzB,SAAgB,iBAAiB,SAA0B;CACzD,MAAM,SAAS,KAAK,OAAO;CAC3B,IAAI,WAAW,GACb,OAAO,cAAc,MAAM,SAAS,MAAM;CAE5C,IAAI,WAAW,GAAG;EAEhB,MAAM,SAAS,iBAAiB,KAAK,OAAO;EAC5C,IAAI,QAAQ;GACV,MAAM,OAAO,OAAO,SAAS,OAAO,IAAI,EAAE;GAC1C,MAAM,MAAM,OAAO,SAAS,OAAO,IAAI,EAAE;GACzC,OAAO,iBACL;IAAC,QAAQ;IAAG,OAAO;IAAM,OAAO;IAAG,MAAM;GAAI,CAAC,CAAC,KAAK,GAAG,CACzD;EACF;EACA,OAAO,cAAc,MAAM,SAAS,MAAM;CAC5C;CAEA,OAAO;AACT;AAEA,SAAS,YAAY,UAAkB,SAA0B;CAC/D,MAAM,OAAO,SAAS,YAAY;CAClC,MAAM,OAAO,QAAQ,YAAY;CACjC,IAAI,KAAK,WAAW,IAAI,GACtB,OAAO,KAAK,SAAS,KAAK,MAAM,CAAC,CAAC;CAEpC,OAAO,SAAS;AAClB;AAEA,SAAS,gBAAgB,UAA2B;CAClD,OAAO,aAAa,eAAe,SAAS,SAAS,YAAY;AACnE;AAEA,eAAe,yBAAyB,UAAoC;CAE1E,MAAM,OAAO,SAAS,QAAQ,YAAY,EAAE;CAC5C,IAAI,KAAK,IAAI,GACX,OAAO,iBAAiB,IAAI;CAE9B,IAAI,gBAAgB,IAAI,GACtB,OAAO;CAET,IAAI;EAEF,QAAO,MADiB,OAAO,MAAM;GAAE,KAAK;GAAM,UAAU;EAAK,CAAC,EAAA,CACjD,MAAM,EAAE,cAAc,iBAAiB,OAAO,CAAC;CAClE,QAAQ;EAEN,OAAO;CACT;AACF;AAEA,eAAe,cAAc,KAAU,OAAwC;CAE7E,IACE,MAAM,WAAW,KAChB,IAAI,aAAa,MAAM,IAAI,aAAa,aAEzC,OAAO;CAGT,IAAI;CACJ,IAAI;EACF,OAAO,cAAc,GAAG;CAC1B,QAAQ;EACN,OAAO;CACT;CAIA,MAAM,OAAO,OAAO,cAAsB;EACxC,MAAM,UAAyB,CAAC;EAChC,IAAI,UAAU,QAAQ,SAAS;EAC/B,SACE,IAAI;GACF,OAAO,KAAK,MAAM,SAAS,SAAS,OAAO,GAAG,GAAG,OAAO;EAC1D,QAAQ;GACN,MAAM,SAAS,QAAQ,OAAO;GAC9B,IAAI,WAAW,SAAS,OAAO,QAAQ,SAAS;GAChD,QAAQ,QAAQ,SAAS,OAAO,CAAC;GACjC,UAAU;EACZ;CAEJ;CAEA,MAAM,SAAS,MAAM,KAAK,IAAI;CAC9B,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,MAAM,SAAS,MAAM,KAAK,IAAI,GAAG,MAAM;EAC7C,IAAI,QAAQ,MAAO,CAAC,IAAI,WAAW,IAAI,KAAK,CAAC,WAAW,GAAG,GACzD,OAAO;CAEX;CACA,OAAO;AACT;;AAGA,eAAsB,iBACpB,QACA,SACkB;CAClB,IAAI;CACJ,IAAI;EACF,MAAM,IAAI,IAAI,MAAM;CACtB,QAAQ;EACN,OAAO;CACT;CAEA,QAAQ,IAAI,UAAZ;EACE,KAAK;EACL,KAAK;EACL,KAAK,SACH,OAAO;EACT,KAAK,SACH,OAAO,cAAc,KAAK,QAAQ,oBAAoB,CAAC,CAAC;EAC1D,KAAK;EACL,KAAK;GACH,IAAI,QAAQ,cACV,OAAO,QAAQ,aAAa,MAAM,YAChC,YAAY,IAAI,UAAU,OAAO,CACnC;GAEF,IAAI,QAAQ,yBAAyB,OACnC,OAAO;GAET,OAAO,CAAE,MAAM,yBAAyB,IAAI,QAAQ;EAEtD,SACE,OAAO;CACX;AACF;;AAGA,SAAS,SAAS,QAAgB;CAChC,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,MAAM;EAC1B,OAAO,GAAG,IAAI,WAAW,SAAS,GAAG,IAAI,SAAS,MAAM,IAAI,SAAS,IAAI;CAC3E,QAAQ;EACN,OAAO;CACT;AACF;;;;;AAMA,eAAsB,oBACpB,SACA,MACA,SACA;CACA,MAAM,EAAE,eAAe,MAAM,cAAc;CAC3C,QAAQ,GAAG,kBAAkB,WAAW;EACtC,IAAI,OAAO,KAAK,MAAM,WAAW,QAAQ,OAAO,OAAO,GACrD,OACG,KAAK,CAAC,CACN,MAAM,UAAU,OAAO,MAAM,CAAC,CAAC,CAC/B,YAAY,KAAA,CAAS;CAE5B,CAAC;CAED,IAAI,QAAQ,sBAAsB,OAChC,MAAM,KAAK,qBAAqB,KAAK;CAGvC,MAAM,KAAK,uBAAuB,IAAI;CACtC,KAAK,GAAG,YAAY,YAAyB;EAC3C,CAAM,YAAY;GAChB,IAAI,QAAQ,6BAA6B,GAAG;GAC5C,MAAM,MAAM,QAAQ,IAAI;GACxB,MAAM,UAAU,MAAM,iBAAiB,KAAK,OAAO,CAAC,CAAC,YAAY,KAAK;GACtE,IAAI,QAAQ,6BAA6B,GAAG;GAC5C,IAAI,SACF,MAAM,QAAQ,SAAS;QAClB;IACL,OAAO,KAAK,sBAAsB,SAAS,GAAG,KAAK,WAAW;IAC9D,MAAM,QAAQ,MAAM,iBAAiB;GACvC;EACF,EAAA,CAAG,CAAC,CAAC,YAAY,KAAA,CAAS;CAC5B,CAAC;AACH;;AChPA,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,kBAAkD;CACtD,OAAO;CACP,qBAAqB;CACrB,gBAAgB;CAChB,gBAAgB;CAChB,iBAAiB;CACjB,WAAW;CACX,YAAY;CACZ,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,mBAAmB;CACnB,QAAQ;CACR,MAAM;CACN,gBAAgB;CAChB,QAAQ;CACR,SAAS;CACT,SAAS;CACT,cAAc;AAChB;AAEA,SAAS,sBAAsB,SAAkC;CAC/D,IAAI,CAAC,SACH,OAAO,EAAE,QAAQ,KAAK;CAExB,MAAM,cAAc,OAAO,KAAK,OAAO,CAAC,CAAC,QACtC,QAAQ,CAAC,OAAO,OAAO,iBAAiB,GAAG,CAC9C;CACA,IAAI,YAAY,SAAS,GACvB,MAAM,IAAI,+BACR,wBAAwB,YAAY,KAAK,IAAI,EAAE,oDACjD;CAEF,OAAO;AACT;AAEA,IAAa,oBAAb,MAAsD;CACpD;CAEA,YAAY,gBAAgC;EAC1C,KAAK,kBAAkB;CACzB;CAEA,MAAM,OACJ,MACA,SACA,QACqB;EACrB,IAAI,QAAQ,qBAAqB,KAAA,GAC/B,OAAO,KACL,6EACF;EAGF,MAAM,aAAa,sBAAsB,QAAQ,UAAU;EAC3D,MAAM,WAA8B,QAAQ,YAAY;EACxD,MAAM,iBAAiB,QAAQ,kBAAkB,KAAA;EACjD,MAAM,OAAO,QAAQ,sBAAsB;EAE3C,IAAI,UACF;EAEF,IAAI;EACJ,MAAM,gBAAgB;GACpB,IAAI,CAAC,SAAS;GACd,UAAU,QAAQ,MAAM;GACxB,QAAQ,YAAY,KAAA,CAAS;EAC/B;EACA,QAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;EAEzD,IAAI;GACF,UAAU,MAAM,KAAK,gBAAgB,cACnC,MACA,UACA,cACF;GACA,QAAQ,eAAe;GACvB,MAAM,OAAO,MAAM,QAAQ,QAAQ;GACnC,IAAI,QAAQ,UACV,MAAM,oBAAoB,SAAS,MAAM,QAAQ,QAAQ;GAG3D,MAAM,KAAK,WAAW,MAAM,EAAE,WAAW,mBAAmB,CAAC;GAC7D,MAAM,KAAK,iBAAiB,QAAQ;GACpC,MAAM,KAAK,mBAAmB;IAAE,UAAU;IAAK,SAAS;GAAM,CAAC;;GAG/D,MAAM,KAAK,eAAe,SAAS,MAAM,KAAK;GAE9C,OAAO,MAAM,KAAK,IAAI,UAAU;EAClC,UAAU;GACR,QAAQ,oBAAoB,SAAS,OAAO;GAC5C,IAAI,SACF,IAAI;IACF,IAAI,SAAS,MAAM;SACd,MAAM,QAAQ,MAAM;GAC3B,SAAS,OAAO;IACd,OAAO,MAAM,KAAK;GACpB;EAEJ;CACF;AACF;;;AC9IA,SAAgB,cAAc,QAAsC;CAClE,QAAQ,OAAO,UAAU,QAAQ,iBAAiB;AACpD;AAEA,SAAgB,kBACd,QACA,gBACa;CACb,MAAM,WAAW,OAAO,YAAY,EAAE,MAAM,YAAY;CAExD,QAAQ,SAAS,MAAjB;EACE,KAAK,aACH,OAAO,IAAI,kBAAkB,cAAc;EAC7C,KAAK,aACH,OAAO,IAAI,kBAAkB,QAAQ;EACvC,KAAK,WACH,OAAO,IAAI,gBAAgB,QAAQ;EACrC,SACE,MAAM,IAAI,+BACR,yBAAyB,OAAQ,SAAgC,IAAI,EAAE,kDACzE;CACJ;AACF;;;;;;;;;ACtBA,SAAgB,aACd,YACA,OACA,OACY;CACZ,MAAM,UAAU,OAAO,OAAO,UAAU;CACxC,MAAM,YAAY,cAChB,cAAc;CAEhB,MAAM,SAAS,QAAQ,KAAK,QAAQ;CACpC,IAAI,WAAW,KAAA,GACb,MAAM,IAAI,+BACR,eAAe,MAAM,IAAI,MAAM,qBAAqB,QACjD,KAAK,MAAM,IAAI,EAAE,EAAE,CAAC,CACpB,KAAK,IAAI,GACd;CAEF,OAAO;AACT;;;;;;;;;;;;;;;;;;;ACPA,MAAM,kBAA8B;AAYpC,eAAe,MAAM,IAAY;CAC/B,MAAM,IAAI,SAAS,MAAM,WAAW,GAAG,EAAE,CAAC;AAC5C;AAEA,eAAe,cAAc,KAAa,UAAU,GAAkB;CACpE,KAAK,IAAI,UAAU,GAAG,WAAW,SAAS,WACxC,IAAI;EACF,MAAM,SAAS,GAAG,KAAK;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;EACvD;CACF,SAAS,KAAc;EACrB,MAAM,OAAQ,KAA+B;EAK7C,IAAI,EAFF,SAAS,WAAW,SAAS,WAAW,SAAS,gBAEjC,YAAY,SAC5B,MAAM;EAGR,MAAM,MAAM,KAAK,MAAM,UAAU,EAAE;CACrC;AAEJ;AAEA,SAAS,oBAAoB,OAAyB;CACpD,IAAI,EAAE,iBAAiB,QAAQ,OAAO;CAEtC,OACE,MAAM,SAAS,sBACf,MAAM,QAAQ,SAAS,eAAe,KACtC,MAAM,QAAQ,SAAS,qBAAqB;AAEhD;AAGO,IAAM,iBAAN,MAAM,eAA0C;CACrD;CACA;CAEA,mBAAmC;CACnC;CAEA,aAAoB;CACpB,YAAmB;CAEnB,oBAAoB;CACpB,aAAa;CAEb,gBAAgB;;CAEhB,yBAAgC;CAEhC;CACA;CACA;CAEA,YAAY,WAA0D;EACpE,KAAK,YAAY,QAAQ,0BAA0B;EACnD,KAAK,WAAW;EAEhB,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,gBAAgB;EACrB,KAAK,sBAAsB;CAC7B;CAEA,MAAM,kBAAkB;EACtB,KAAK,gBAAgB;EACrB,MAAM,KAAK,aAAa,KAAK,sBAAsB;EAEnD,IAAI,KAAK,kBAAkB,WACzB,IAAI;GACF,MAAM,KAAK,iBAAiB,MAAM;EACpC,SAAS,OAAO;GACd,OAAO,KACL,8CACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAEzD;EACF;EAGF,IACE,KAAK,aAAa,KAAA,KAClB,cAAc,KAAK,QAAQ,KAC3B,KAAK,SAAS,8BAA8B,OAE5C,MAAM,KAAK,wBAAwB;CAEvC;;CAGA,MAAM,aAAa,WAAkC;EACnD,MAAM,QAAQ,KAAK,IAAI;EACvB,OAAO,KAAK,aAAa,KAAK,KAAK,IAAI,IAAI,QAAQ,WACjD,MAAM,MAAM,EAAE;EAGhB,IAAI,KAAK,aAAa,GACpB,OAAO,KACL,aAAa,KAAK,WAAW,kCAAkC,UAAU,+BAC3E;CAEJ;CAEA,MAAM,mBACJ,MACA,UACA,mBACA;EACA,IAAI,CAAC,KAAK,kBAAkB,WAC1B,KAAK,mBAAmB,MAAM,KAAK,eACjC,MACA,UACA,iBACF;EAGF,OAAO,KAAK;CACd;CAEA,MAAM,cACJ,MACA,UACA,gBACyB;EACzB,MAAM,UAAU,MAAM,KAAK,mBACzB,MACA,UACA,cACF;EACA,IAAI;GACF,OAAO,MAAM,QAAQ,qBAAqB;EAC5C,SAAS,OAAO;GACd,IAAI,CAAC,oBAAoB,KAAK,GAC5B,MAAM;GAGR,OAAO,KACL,kEACF;GAEA,KAAK,mBAAmB;GAMxB,OAAO,OAAM,MALc,KAAK,mBAC9B,MACA,UACA,cACF,EAAA,CAC0B,qBAAqB;EACjD;CACF;CAEA,iBAAiB;EACf,IAAI,KAAK,eACP,MAAM,IAAI,4BACR,oDACF;EAGF,KAAK,cAAc;EACnB,KAAK,aAAa;EAElB,IAAI,KAAK,aAAa,KACpB,KAAK,oBAAoB;CAE7B;CAEA,MAAM,kBAAkB;EACtB,KAAK,aAAa,KAAK,IAAI,GAAG,KAAK,aAAa,CAAC;EACjD,MAAM,KAAK,uBAAuB;CACpC;CAEA,MAAM,yBAAyB;EAC7B,IAAI,CAAC,KAAK,mBAAmB;EAC7B,IAAI,KAAK,YAAY;EACrB,IAAI,KAAK,aAAa,GAAG;EACzB,IAAI,CAAC,KAAK,kBAAkB;EAE5B,KAAK,aAAa;EAElB,IAAI;GACF,IAAI,KAAK,iBAAiB,WACxB,MAAM,KAAK,iBAAiB,MAAM;GAGpC,KAAK,mBAAmB;GACxB,KAAK,YAAY;GACjB,KAAK,oBAAoB;GAEzB,OAAO,IAAI,yCAAyC;EACtD,SAAS,OAAO;GACd,OAAO,KACL,8BACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAEzD;EACF,UAAU;GACR,KAAK,aAAa;EACpB;CACF;CAEA,MAAM,0BAA0B;EAC9B,MAAM,SAAS,IAAI,OAAO,WAAW;EACrC,MAAM,MAAM,KAAK;EACjB,IAAI;GACF,IAAI,CAAC,WAAW,GAAG,GAAG;GAEtB,OAAO,IAAI,4BAA4B,KAAK;GAE5C,MAAM,cAAc,KAAK,CAAC;GAC1B,IAAI,WAAW,GAAG,GAAG;IACnB,MAAM,MAAM,GAAG;IACf,MAAM,cAAc,KAAK,CAAC;GAC5B;GAEA,OAAO,IAAI,cAAc;EAC3B,SAAS,KAAK;GACZ,OAAO,MACL,sBAAsB,OACtB,eAAe,QAAQ,IAAI,QAAQ,OAAO,GAAG,CAC/C;EACF;EACA,IAAI;GACF,MAAM,WAAW,MAAM,SAAS,QAAQ,KAAK,EAAE,WAAW,KAAK,CAAC;GAChE,OAAO,KAAK,mBAAmB,SAAS,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,IAAI;EACtE,QAAQ;GACN,OAAO,IAAI,wBAAwB,KAAK;EAC1C;CACF;CAEA,MAAM,QAAQ,OAAgB,OAAO;EACnC,IAAI;GACF,OAAO,MAAM,KAAK,WAAW,IAAI;EACnC,SAAS,OAAO;GACd,IAAI,iBAAiB,oBACnB,MAAM;GAER,MAAM,IAAI,6BACR,8BAA8B,OAAO,KAAK,KAC1C,EAAE,OAAO,MAAM,CACjB;EACF;CACF;CAEA,MAAM,WAAW,MAAe;EAC9B,MAAM,EACJ,SAAS,aACT,iBACA,aACA,uBACA,SACA,mBACE,MAAM,sBAAsB;EAChC,MAAM,UAAU,aAAa,aAAa,KAAK,UAAU,SAAS;EAClE,MAAM,aAAyB,KAAK;EAEpC,MAAM,kBAAkB,sBAAsB,KAAK,gBAAgB;EAEnE,IAAI;EACJ,IAAI,KAAK,aAAa,KAAA,GACpB,UAAU,MAAM,eAAe,SAAS,iBAAiB,UAAU;OAEnE,UAAU,KAAK;EAGjB,OAAO,IACL,WAAW,QAAQ,GAAG,WAAW,aAAa,WAC9C,WACF;EAEA,IAAI,MAAM,KAAK,oBAAoB,SAAS,OAAO,GAAG;GACpD,OAAO,IAAI,6BAA6B,WAAW;GACnD,IAAI,MACF,KAAK,eAAe,SAAS,OAAO;GAEtC;EACF,OAAO;GACL,OAAO,IAAI,iCAAiC,WAAW;GAEvD,MAAM,gBAAgB;IACpB,UAAU,KAAK;IACN;IACA;IACT,SAAS,KAAK,UAAU,yBAAyB,KAAA;GACnD;GAEA,IAAI,MAAM,YAAY,aAAa,GAAG;IACpC,OAAO,IACL,cAAc,cAAc,QAAQ,GAAG,cAAc,WACrD,WACF;IACA,MAAM,mBAAmB,MAAM,QAAQ,aAAa;IACpD,IAAI,MAAM,KAAK,oBAAoB,SAAS,OAAO,GAAG;KACpD,OAAO,IAAI,kCAAkC,WAAW;KACxD,IAAI,MACF,KAAK,eAAe,SAAS,OAAO;KAEtC,OAAO;IACT,OACE,OAAO,MAAM,+BAA+B,WAAW;GAE3D,OACE,OAAO,MACL,wBAAwB,cAAc,QAAQ,GAAG,cAAc,WAC/D,WACF;EAEJ;EACA,OAAO;CACT;CAEA,eAAqB;EACnB,KAAK,WAAW,KAAK,UAAU,WAAW;CAC5C;CAEA,aAAgC;EAC9B,OAAO,KAAK;CACd;CAEA,kBAAwB;EACtB,IAAI;EACJ,IAAI,KAAK,UAAU,eAAe,KAAA,GAAW;GAC3C,IAAI,KAAK,aAAa,iBACpB,aAAA;QAEA,aAAA;EAEJ,OACE,aAAa,KAAK,SAAS;EAE7B,KAAK,cAAc;CACrB;CAEA,eAAqB;EACnB,IAAI;EACJ,IAAI,KAAK,UAAU,YAAY,KAAA,GAC7B,UAAU,KAAA;OAEV,UAAU,KAAK,SAAS;EAE1B,KAAK,WAAW;CAClB;CAEA,cAAqB,YAA8B;EACjD,KAAK,cAAc;CACrB;CAEA,gBAAmC;EACjC,OAAO,KAAK;CACd;CAEA,aAAiC;EAC/B,OAAO,KAAK;CACd;CAEA,wBAA8B;EAC5B,IAAI;EACJ,IAAI,KAAK,UAAU,qBAAqB,KAAA,GACtC,mBAAmB;OAEnB,mBAAmB,KAAK,SAAS;EAEnC,KAAK,oBAAoB;CAC3B;CAEA,MAAM,oBAAoB,SAAqB,SAAiB;EAC9D,MAAM,EAAE,SAAS,aAAa,yBAC5B,MAAM,sBAAsB;EAC9B,MAAM,WAAW,aAAa,aAAa,SAAS,SAAS;EAQ7D,QAHyB,MAJU,qBAAqB,EACtD,UAAU,KAAK,UACjB,CAAC,EAAA,CAE6C,MAAM,eAAe;GACjE,OAAO,WAAW,YAAY,YAAY,WAAW,YAAY;EACnE,CACsB,MAAM,KAAA;CAC9B;CAEA,MAAM,oBAAqC;EACzC,MAAM,EACJ,SAAS,aACT,iBACA,uBACA,sBACA,mBACE,MAAM,sBAAsB;EAChC,MAAM,UAAU,aAAa,aAAa,KAAK,UAAU,SAAS;EAClE,MAAM,aAAyB,KAAK;EACpC,MAAM,kBAAkB,sBAAsB,KAAK,gBAAgB;EACnE,IAAI,UAAyB;EAC7B,IAAI,KAAK,mBAAmB;GAC1B,UAAU,KAAK,iBAAiB,OAAO;GACvC,OAAO,IAAI,wBAAwB,WAAW,WAAW;EAC3D;EACA,YAAY,MAAM,eAAe,SAAS,iBAAiB,UAAU;EAIrE,MAAM,oBAAmB,MAHU,qBAAqB,EACtD,UAAU,KAAK,UACjB,CAAC,EAAA,CAC6C,MAAM,eAAe;GACjE,OAAO,WAAW,YAAY,WAAW,WAAW,YAAY;EAClE,CAAC;EACD,IAAI,qBAAqB,KAAA,GAAW;GAClC,MAAM,sBAAsB,MAAM,KAAK,QAAQ;GAC/C,IAAI,wBAAwB,QAAQ,wBAAwB,KAAA,GAC1D,MAAM,IAAI,6BAA6B,2BAA2B;QAElE,OAAO,oBAAoB;EAE/B;EACA,OAAO,iBAAiB;CAC1B;CAEA,MAAM,eACJ,MACA,UACA,mBACA;EACA,MAAM,iBACJ,qBAAsB,MAAM,KAAK,kBAAkB;EAErD,MAAM,EAAE,WAAW,MAAM,cAAc;EACvC,MAAM,UAAU,MAAM,OAAO;GAC3B;GACA;GACA;GAGA,mBAAmB,CAAC,0BAA0B;EAChD,CAAC;EAED,QAAQ,GAAG,sBAAsB;GAC/B,OAAO,KAAK,gCAAgC;GAC5C,IAAI,KAAK,qBAAqB,SAC5B,KAAK,mBAAmB;EAE5B,CAAC;EAED,OAAO;CACT;CAEA,eAAe,SAAqB,SAAiB;EACnD,MAAM,WAAW,QAAQ,KAAK,WAAW,GAAG,QAAQ,MAAM;EAC1D,MAAM,OAAO,KAAK,UAAU;GACjB;GACA;GACT,uBAAM,IAAI,KAAK,EAAA,CAAE,YAAY;EAC/B,CAAC;EACD,cAAc,UAAU,IAAI;EAE5B,OAAO,IAAI,WAAW,QAAQ,mBAAmB,WAAW,WAAW;CACzE;CAEA,iBAAiB,SAAoC;EACnD,MAAM,WAAW,QAAQ,KAAK,WAAW,GAAG,QAAQ,MAAM;EAC1D,IAAI,WAAW,QAAQ,GAAG;GACxB,MAAM,OAAO,aAAa,QAAQ;GAMlC,OALa,KAAK,MAAM,KAAK,SAAS,CAK5B,CAAC,CAAC;EACd;EACA,OAAO;CACT;AACF;;CAhbC,WAAW;CAsBG,gBAAA,GAAA,OAAO,gBAAgB,CAAA;;;;ACpFtC,MAAM,gBAAgB,cAAc,YAAY,GAAG;;;;;;AAOnD,SAAgB,WAAc,aAAqB,YAAuB;CACxE,IAAI;CACJ,IAAI;EACF,MAAM,cAAc,WAAW;CACjC,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,oBAC5C,MAAM,IAAI,4BAA4B,YAAY,aAAa,EAC7D,OAAO,MACT,CAAC;EAEH,MAAM;CACR;CAEA,OAAQ,IAAI,cAAc,aAAa,MAAM,IAAI,UAAU;AAC7D;;ACbO,IAAM,aAAN,MAAM,WAAW;CACtB;CAEA,IAAI,UAAsB;EACxB,OAAQ,KAAK,SAAS,WAAuB,OAAO,KAAK;CAC3D;CAEA,MAAM,OAAO,UAAkB,OAAa,CAAC,GAAG,SAAsB;EACpE,MAAM,SAAS,KAAK;EACpB,IAAI;GACF,OAAO,MAAM,OAAO,OAAO,UAAU,MAAM;IACzC,OAAO;IACP,GAAG;GACL,CAAC;EACH,SAAS,OAAO;GACd,MAAM,IAAI,wBACR,OACA,yBAAyB,OAAO,KAAK,KACrC,EAAE,OAAO,MAAM,CACjB;EACF;CACF;CAEA,MAAM,WAAW,UAAkB,OAAa,CAAC,GAAG,SAAsB;EACxE,MAAM,SAAS,KAAK;EACpB,IAAI;GACF,OAAO,MAAM,OAAO,WAAW,UAAU,MAAM;IAC7C,OAAO;IACP,GAAG;GACL,CAAC;EACH,SAAS,OAAO;GACd,MAAM,IAAI,wBACR,OACA,8BAA8B,OAAO,KAAK,KAC1C,EAAE,OAAO,MAAM,CACjB;EACF;CACF;AACF;AAvCC,aAAA,WAAA,CAAA,WAAW,CAAA,GAAA,UAAA;;ACYL,IAAM,aAAN,MAAM,WAAW;CACtB;CACA;CACA,iCAA+C,IAAI,IAAI;CACvD,gBAAyB;CAEzB,IAAI,UAA4B;EAC9B,OAAQ,KAAK,eAAe,WAA6B,OAAO,KAAK;CACvE;;;;;;;;CASA,OACE,UACA,OAAgC,CAAC,GACjC,SACQ;EACR,MAAM,EAAE,QAAQ,KAAK;EACrB,IAAI;GAgBF,QAdE,WAAW,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,IACrC,IAAI,IAAI;IACN,OAAO;IACP,YAAY;IACZ,SAAS;IACT,GAAG;IACH,SAAS,QAAQ,WAAW;GAC9B,CAAC,IACA,KAAK,SAAS,IAAI,IAAI;IACrB,OAAO;IACP,YAAY;IACZ,SAAS;GACX,CAAC,EAAA,CAEI,aAAa,UAAU,IAAI;EACxC,SAAS,OAAO;GACd,MAAM,IAAI,wBACR,OACA,yBAAyB,OAAO,KAAK,KACrC,EAAE,OAAO,MAAM,CACjB;EACF;CACF;;;;;;;;CASA,WACE,UACA,OAAgC,CAAC,GACjC,SACQ;EACR,IAAI;GACF,MAAM,eAAe,QAAQ,QAAQ;GACrC,MAAM,WAAW,SAAS,SAAS;GACnC,IAAI,WAAW,WACX,KAAK,eAAe,IAAI,YAAY,IACpC,KAAA;GAEJ,IAAI,CAAC,UAAU;IACb,WAAW,aAAa,cAAc,OAAO;IAE7C,IAAI,YAAY,KAAK,eAAe,OAAO,KAAK,eAC9C,KAAK,eAAe,IAAI,cAAc,QAAQ;GAElD;GACA,OAAO,KAAK,OAAO,UAAU,MAAM,OAAO;EAC5C,SAAS,OAAO;GACd,IAAI,iBAAiB,6BACnB,MAAM;GAER,MAAM,IAAI,wBACR,OACA,iCAAiC,SAAS,IAAI,OAAO,KAAK,KAC1D,EAAE,OAAO,MAAM,CACjB;EACF;CACF;;;;CAKA,aAAmB;EACjB,KAAK,eAAe,MAAM;CAC5B;;;;;CAMA,eAAuB;EACrB,OAAO,KAAK,eAAe;CAC7B;AACF;AAvGC,aAAA,WAAA,CAAA,WAAW,CAAA,GAAA,UAAA;;ACcL,IAAM,oBAAN,MAAM,kBAAkB;CAC7B;CACA;CACA;CAEA,IAAI,UAA6B;EAC/B,OAAQ,KAAK,gBAAgB,WAC3B,cACA,YACF;CACF;CAEA,OACE,UACA,aAAsB,CAAC,GACvB,UAA6B,CAAC,GACtB;EACR,IAAI;GAKF,OAJiB,KAAK,QAAQ,OAAO,CAAC,CAAC,QACrC,UACA,QAAQ,cAEI,CAAC,CAAC,YAAY,QAAQ,eAAe;EACrD,SAAS,OAAO;GACd,IAAI,iBAAiB,oBACnB,MAAM;GAER,MAAM,IAAI,wBACR,cACA,gCAAgC,OAAO,KAAK,KAC5C,EAAE,OAAO,MAAM,CACjB;EACF;CACF;CAEA,WACE,MACA,aAAsB,CAAC,GACvB,UAA6B,CAAC,GACtB;EACR,IAAI,QAAQ,sBAAsB,KAAA,GAChC,MAAM,IAAI,+BACR,yEACF;EAGF,MAAM,UAAU,QAAQ,QAAQ,IAAI,GAAG,QAAQ,iBAAiB;EAChE,MAAM,eAAe,QAAQ,SAAS,IAAI;EAC1C,IAAI,iBAAiB,WAAW,CAAC,aAAa,WAAW,UAAU,GAAG,GACpE,MAAM,IAAI,+BACR,sCAAsC,KAAK,yCAC7C;EAGF,IAAI;EACJ,IAAI;GACF,WAAW,aAAa,cAAc,MAAM;EAC9C,SAAS,OAAO;GACd,MAAM,IAAI,wBACR,cACA,qCAAqC,OAAO,KAAK,KACjD,EAAE,OAAO,MAAM,CACjB;EACF;EAEA,OAAO,KAAK,OAAO,UAAU,YAAY,OAAO;CAClD;;;;;;CAOA,QAAQ,SAA+C;EACrD,IAAI,KAAK,cAAc,KAAK,mBAAmB,SAC7C,OAAO,KAAK;EAGd,MAAM,MAAM,KAAK,QAAQ,OAAO;EAEhC,KAAK,MAAM,UAAU,QAAQ,WAAW,CAAC,GACvC,IAAI,eAAe,OAAO,MAAM,OAAO,EAAE;EAE3C,KAAK,kBAAkB,KAAK,QAAQ,gBAAgB;EAEpD,KAAK,iBAAiB;EACtB,KAAK,aAAa;EAClB,OAAO;CACT;CAEA,kBACE,KACA,kBACM;EACN,IAAI,qBAAqB,KAAA,GAAW;EAEpC,MAAM,cAAc,KAAK,QAAQ,IAAI,GAAG,gBAAgB;EACxD,IAAI,CAAC,WAAW,WAAW,GACzB,MAAM,IAAI,+BACR,gDAAgD,aAClD;EAGF,KAAK,MAAM,SAAS,YAAY,WAAW,GAAG;GAC5C,MAAM,WAAW,KAAK,aAAa,KAAK;GACxC,IAAI,CAAC,SAAS,QAAQ,CAAC,CAAC,OAAO,GAAG;GAElC,IAAI,gBACF,SAAS,OAAO,QAAQ,KAAK,CAAC,GAC9B,aAAa,UAAU,MAAM,CAC/B;EACF;CACF;AACF;AAlHC,oBAAA,WAAA,CAAA,WAAW,CAAA,GAAA,iBAAA;;ACnBL,IAAM,gBAAN,MAAM,cAAc;CACzB;CACA;CACA,iCAA+C,IAAI,IAAI;CACvD,gBAAyB;CAEzB,IAAI,UAA+B;EACjC,OAAQ,KAAK,kBAAkB,WAC7B,YACA,QACF;CACF;;;;;;;;CASA,OACE,UACA,OAAgC,CAAC,GACjC,SACQ;EACR,MAAM,EAAE,WAAW,KAAK;EACxB,IAAI;GAMF,QAJE,WAAW,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,IACrC,IAAI,OAAO,OAAO,IACjB,KAAK,YAAY,IAAI,OAAO,EAAA,CAErB,mBAAmB,UAAU,IAAI;EACjD,SAAS,OAAO;GACd,MAAM,IAAI,wBACR,UACA,4BAA4B,OAAO,KAAK,KACxC,EAAE,OAAO,MAAM,CACjB;EACF;CACF;;;;;;;;CASA,WACE,UACA,OAAgC,CAAC,GACjC,SACQ;EACR,IAAI;GACF,MAAM,eAAe,QAAQ,QAAQ;GACrC,MAAM,WAAW,SAAS,UAAU;GACpC,IAAI,WAAW,WACX,KAAK,eAAe,IAAI,YAAY,IACpC,KAAA;GAEJ,IAAI,CAAC,UAAU;IACb,WAAW,aAAa,cAAc,OAAO;IAE7C,IAAI,YAAY,KAAK,eAAe,OAAO,KAAK,eAC9C,KAAK,eAAe,IAAI,cAAc,QAAQ;GAElD;GACA,OAAO,KAAK,OAAO,UAAU,MAAM,OAAO;EAC5C,SAAS,OAAO;GACd,IAAI,iBAAiB,6BACnB,MAAM;GAER,MAAM,IAAI,wBACR,UACA,oCAAoC,SAAS,IAAI,OAAO,KAAK,KAC7D,EAAE,OAAO,MAAM,CACjB;EACF;CACF;;;;CAKA,aAAmB;EACjB,KAAK,eAAe,MAAM;CAC5B;;;;;CAMA,eAAuB;EACrB,OAAO,KAAK,eAAe;CAC7B;AACF;AAhGC,gBAAA,WAAA,CAAA,WAAW,CAAA,GAAA,aAAA;;ACLL,IAAM,cAAN,MAAM,YAAY;CACvB;CAEA,IAAI,UAAuB;EACzB,OAAQ,KAAK,UAAU,WAAwB,QAAQ,MAAM;CAC/D;CAEA,MAAM,OACJ,UACA,SACiB;EACjB,MAAM,SAAS,KAAK;EACpB,IAAI;GACF,MAAM,EAAE,SAAS,MAAM,OAAO,UAAU,OAAO;GAC/C,OAAO;EACT,SAAS,OAAO;GACd,MAAM,IAAI,wBACR,QACA,0BAA0B,OAAO,KAAK,KACtC,EAAE,OAAO,MAAM,CACjB;EACF;CACF;CAEA,MAAM,WACJ,UACA,SACiB;EACjB,IAAI;EACJ,IAAI;GACF,WAAW,aAAa,UAAU,OAAO;EAC3C,SAAS,OAAO;GACd,MAAM,IAAI,wBACR,QACA,+BAA+B,OAAO,KAAK,KAC3C,EAAE,OAAO,MAAM,CACjB;EACF;EACA,OAAO,MAAM,KAAK,OAAO,UAAU,OAAO;CAC5C;AACF;AAzCC,cAAA,WAAA,CAAA,WAAW,CAAA,GAAA,WAAA;;ACUL,IAAM,kBAAN,MAAM,gBAAgB;CAC3B;CACA,iCAA+C,IAAI,IAAI;CACvD,gBAAyB;CAEzB,IAAI,UAA2B;EAC7B,OAAQ,KAAK,cAAc,WACzB,YACA,UACF;CACF;;;;;;;;CASA,OACE,UACA,OAAgC,CAAC,GACjC,SACQ;EACR,MAAM,SAAS,KAAK;EACpB,IAAI;GACF,MAAM,OAAO,SAAS,QAAQ,CAAC,MAAM,IAAI;GACzC,OAAO,OAAO,OAAO,UAAU,MAAM,KAAA,GAAW;IACxC;IACN,QAAQ,SAAS;GACnB,CAAC;EACH,SAAS,OAAO;GACd,MAAM,IAAI,wBACR,YACA,8BAA8B,OAAO,KAAK,KAC1C,EAAE,OAAO,MAAM,CACjB;EACF;CACF;;;;;;;;CASA,WACE,UACA,OAAgC,CAAC,GACjC,SACQ;EACR,IAAI;GACF,MAAM,eAAe,QAAQ,QAAQ;GACrC,IAAI,WAAW,KAAK,eAAe,IAAI,YAAY;GAEnD,IAAI,CAAC,UAAU;IACb,WAAW,aAAa,cAAc,OAAO;IAE7C,IAAI,KAAK,eAAe,OAAO,KAAK,eAClC,KAAK,eAAe,IAAI,cAAc,QAAQ;GAElD;GAEA,OAAO,KAAK,OAAO,UAAU,MAAM,OAAO;EAC5C,SAAS,OAAO;GACd,IAAI,iBAAiB,6BACnB,MAAM;GAER,MAAM,IAAI,wBACR,YACA,sCAAsC,SAAS,IAAI,OAAO,KAAK,KAC/D,EAAE,OAAO,MAAM,CACjB;EACF;CACF;;;;CAKA,aAAmB;EACjB,KAAK,eAAe,MAAM;CAC5B;;;;;CAMA,eAAuB;EACrB,OAAO,KAAK,eAAe;CAC7B;AACF;AA5FC,kBAAA,WAAA,CAAA,WAAW,CAAA,GAAA,eAAA;;ACFL,IAAM,kBAAN,MAAM,gBAAgB;CAC3B;CAEA,IAAI,UAA2B;EAC7B,IAAI,CAAC,KAAK,WAAW;GACnB,KAAK,YAAY,WAA4B,YAAY,UAAU;GAEnE,KAAK,UAAU,UAAU;IACvB,SAAS;IACT,YAAY;IACZ,cAAc;GAChB,CAAC;EACH;EACA,OAAO,KAAK;CACd;CAEA,OACE,UACA,OAAgC,CAAC,GACjC,SACA;EACA,MAAM,WAAW,KAAK;EACtB,IAAI;GACF,IAAI,SAAS;IACX,MAAM,gBAAyC;KAC7C,SAAS,QAAQ,WAAW;KAC5B,OAAO,QAAQ,SAAS;KACxB,kBAAkB,QAAQ,oBAAoB;KAC9C,YAAY,QAAQ,cAAc;KAClC,cAAc,QAAQ,gBAAgB;IACxC;IACA,SAAS,UAAU,aAAiC;GACtD;GACA,OAAO,SAAS,aAAa,UAAU,IAAI;EAC7C,SAAS,OAAO;GACd,MAAM,IAAI,wBACR,YACA,8BAA8B,OAAO,KAAK,KAC1C,EAAE,OAAO,MAAM,CACjB;EACF;CACF;CAEA,WACE,UACA,OAAgC,CAAC,GACjC,SACA;EACA,MAAM,WAAW,KAAK;EACtB,IAAI;GACF,IAAI,SAAS;IACX,MAAM,gBAAyC;KAC7C,SAAS,QAAQ,WAAW;KAC5B,OAAO,QAAQ,SAAS;KACxB,kBAAkB,QAAQ,oBAAoB;KAC9C,YAAY,QAAQ,cAAc;KAClC,cAAc,QAAQ,gBAAgB;IACxC;IACA,SAAS,UAAU,aAAiC;GACtD;GACA,OAAO,SAAS,OAAO,UAAU,IAAI;EACvC,SAAS,OAAO;GACd,MAAM,IAAI,wBACR,YACA,mCAAmC,OAAO,KAAK,KAC/C,EAAE,OAAO,MAAM,CACjB;EACF;CACF;AACF;AAtEC,kBAAA,WAAA,CAAA,WAAW,CAAA,GAAA,eAAA;;ACAL,IAAM,aAAN,MAAM,WAAW;CACtB;CAEA,IAAI,UAAsB;EACxB,OAAQ,KAAK,SAAS,WAAuB,OAAO,KAAK;CAC3D;CAEA,OACE,UACA,OAAqB,CAAC,GACtB,SACQ;EACR,MAAM,SAAS,KAAK;EACpB,IAAI;GAIF,OAHmB,OAAO,QAAQ,UAAU,EAC1C,GAAG,QACL,CACgB,CAAC,CAAC,IAAI;EACxB,SAAS,OAAO;GACd,MAAM,IAAI,wBACR,OACA,yBAAyB,OAAO,KAAK,KACrC,EAAE,OAAO,MAAM,CACjB;EACF;CACF;CAEA,WACE,UACA,OAAqB,CAAC,GACtB,SACQ;EACR,IAAI;GACF,MAAM,WAAW,aAAa,UAAU,OAAO;GAC/C,OAAO,KAAK,OAAO,UAAU,MAAM,OAAO;EAC5C,SAAS,OAAO;GACd,IAAI,iBAAiB,6BACnB,MAAM;GAER,MAAM,IAAI,wBACR,OACA,8BAA8B,OAAO,KAAK,KAC1C,EAAE,OAAO,MAAM,CACjB;EACF;CACF;AACF;AA/CC,aAAA,WAAA,CAAA,WAAW,CAAA,GAAA,UAAA;;ACZZ,SAAgB,eAAkB,SAAwB,MAAiB;CACzE,IAAI,CAAC,SACH,MAAM,IAAI,4BAA4B,IAAI;CAG5C,OAAO;AACT;;AC2BO,IAAM,mBAAN,MAAM,iBAAiB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YACE,UACA,MACA,SACA,YACA,aACA,YACA,YACA,iBACA,YACA,iBACA,eACA;EACA,KAAK,YAAY;EACjB,KAAK,QAAQ;EACb,KAAK,WAAW;EAChB,KAAK,cAAc;EACnB,KAAK,eAAe;EACpB,KAAK,cAAc;EACnB,KAAK,cAAc;EACnB,KAAK,mBAAmB;EACxB,KAAK,cAAc;EACnB,KAAK,mBAAmB;EACxB,KAAK,iBAAiB;CACxB;CAEA,SAAkB,OAAO,CAAC;CAE1B,MAAM,oBACJ,MACA,SACqB;EACrB,MAAM,SAAS,SAAS,UAAU,KAAK,SAAS;EAChD,QAAQ,eAAe;EAEvB,IAAI,UAAU;EACd,MAAM,MAAM,KAAK,OAAO,YAAY;GAClC,QAAQ,eAAe;GACvB,UAAU;GAEV,MAAM,gBAAgB,yBAAyB,KAAK,UAAU,OAAO;GAErE,KAAK,MAAM,eAAe;GAC1B,IAAI;IACF,MAAM,MAAM,MAAM,KAAK,UAAU,OAAO,MAAM,eAAe,MAAM;IACnE,QAAQ,eAAe;IACvB,OAAO,cAAc,YACjB,MAAM,aAAa,KAAK,cAAc,SAAS,IAC/C;GACN,SAAS,GAAG;IACV,IAAI,QAAQ,SACV,MAAM,OAAO;IAEf,OAAO,MAAM,CAAC;IACd,IAAI,aAAa,oBACf,MAAM;IAER,MAAM,IAAI,uBACR,0BAA0B,OAAO,CAAC,KAClC,EAAE,OAAO,EAAE,CACb;GACF,UAAU;IACR,MAAM,KAAK,MAAM,gBAAgB;GACnC;EACF,CAAC;EAED,IAAI,CAAC,QACH,OAAO;EAGT,IAAI;EACJ,MAAM,qBAAqB,IAAI,SAAgB,GAAG,WAAW;GAC3D,sBAAsB;IAGpB,IAAI,CAAC,SAAS,OAAO,OAAO,MAAM;GACpC;GACA,OAAO,iBAAiB,SAAS,eAAe,EAAE,MAAM,KAAK,CAAC;EAChE,CAAC;EACD,IAAI;GACF,OAAO,MAAM,QAAQ,KAAK,CAAC,KAAK,kBAAkB,CAAC;EACrD,UAAU;GACR,OAAO,oBAAoB,SAAS,aAAa;EACnD;CACF;CAEA,MAAM,iCACJ,UACA,aAAkB,CAAC,GACnB,SACA;EAEA,MAAM,OADa,eAAe,KAAK,aAAa,YAC9B,CAAC,CAAC,OACtB,UACA,YACA,SAAS,cAAc,KAAK,SAAS,UACvC;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,+BACJ,MACA,aAAkB,CAAC,GACnB,SACA;EAEA,MAAM,OADa,eAAe,KAAK,aAAa,YAC9B,CAAC,CAAC,WACtB,MACA,YACA,SAAS,cAAc,KAAK,SAAS,UACvC;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,0BACJ,UACA,SACA;EAEA,MAAM,OAAO,MADO,eAAe,KAAK,cAAc,MACzB,CAAC,CAAC,OAC7B,UACA,SAAS,eAAe,KAAK,SAAS,WACxC;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,wBAAwB,MAAc,SAA+B;EAEzE,MAAM,OAAO,MADO,eAAe,KAAK,cAAc,MACzB,CAAC,CAAC,WAC7B,MACA,SAAS,eAAe,KAAK,SAAS,WACxC;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,yBACJ,UACA,OAAqB,CAAC,GACtB,SACA;EAEA,MAAM,OADa,eAAe,KAAK,aAAa,KAC9B,CAAC,CAAC,OACtB,UACA,MACA,SAAS,cAAc,KAAK,SAAS,UACvC;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,uBACJ,MACA,OAAqB,CAAC,GACtB,SACA;EAEA,MAAM,OADa,eAAe,KAAK,aAAa,KAC9B,CAAC,CAAC,WACtB,MACA,MACA,SAAS,cAAc,KAAK,SAAS,UACvC;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,yBACJ,UACA,OAAa,CAAC,GACd,SACA;EAEA,MAAM,OAAO,MADM,eAAe,KAAK,aAAa,KACxB,CAAC,CAAC,OAC5B,UACA,MACA,SAAS,cAAc,KAAK,SAAS,UACvC;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,uBACJ,MACA,OAAa,CAAC,GACd,SACA;EAEA,MAAM,OAAO,MADM,eAAe,KAAK,aAAa,KACxB,CAAC,CAAC,WAC5B,MACA,MACA,SAAS,cAAc,KAAK,SAAS,UACvC;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,8BACJ,UACA,OAAgC,CAAC,GACjC,SACA;EAEA,MAAM,OADkB,eAAe,KAAK,kBAAkB,UACnC,CAAC,CAAC,OAC3B,UACA,MACA,SAAS,mBAAmB,KAAK,SAAS,eAC5C;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,4BACJ,MACA,OAAgC,CAAC,GACjC,SACA;EAEA,MAAM,OADkB,eAAe,KAAK,kBAAkB,UACnC,CAAC,CAAC,WAC3B,MACA,MACA,SAAS,mBAAmB,KAAK,SAAS,eAC5C;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,yBACJ,UACA,OAAgC,CAAC,GACjC,SACA;EAEA,MAAM,OADa,eAAe,KAAK,aAAa,KAC9B,CAAC,CAAC,OACtB,UACA,MACA,SAAS,cAAc,KAAK,SAAS,UACvC;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,uBACJ,MACA,OAAgC,CAAC,GACjC,SACA;EAEA,MAAM,OADa,eAAe,KAAK,aAAa,KAC9B,CAAC,CAAC,WACtB,MACA,MACA,SAAS,cAAc,KAAK,SAAS,UACvC;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,8BACJ,UACA,OAAgC,CAAC,GACjC,SACA;EAEA,MAAM,OADkB,eAAe,KAAK,kBAAkB,UACnC,CAAC,CAAC,OAC3B,UACA,MACA,SAAS,mBAAmB,KAAK,SAAS,eAC5C;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,4BACJ,MACA,OAAgC,CAAC,GACjC,SACA;EAEA,MAAM,OADkB,eAAe,KAAK,kBAAkB,UACnC,CAAC,CAAC,WAC3B,MACA,MACA,SAAS,mBAAmB,KAAK,SAAS,eAC5C;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,4BACJ,UACA,OAAgC,CAAC,GACjC,SACA;EAEA,MAAM,OADgB,eAAe,KAAK,gBAAgB,QACjC,CAAC,CAAC,OACzB,UACA,MACA,SAAS,iBAAiB,KAAK,SAAS,aAC1C;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;CAEA,MAAM,0BACJ,MACA,OAAgC,CAAC,GACjC,SACA;EAEA,MAAM,OADgB,eAAe,KAAK,gBAAgB,QACjC,CAAC,CAAC,WACzB,MACA,MACA,SAAS,iBAAiB,KAAK,SAAS,aAC1C;EACA,OAAO,KAAK,oBAAoB,MAAM,OAAO;CAC/C;AACF;;CA5TC,WAAW;CAeP,gBAAA,GAAA,OAAO,YAAY,CAAA;CACnB,gBAAA,GAAA,OAAO,cAAc,CAAA;CACrB,gBAAA,GAAA,OAAO,cAAc,CAAA;CACrB,gBAAA,GAAA,SAAS,CAAA;CACT,gBAAA,GAAA,SAAS,CAAA;CACT,gBAAA,GAAA,SAAS,CAAA;CACT,gBAAA,GAAA,SAAS,CAAA;CACT,gBAAA,GAAA,SAAS,CAAA;CACT,gBAAA,GAAA,SAAS,CAAA;CACT,gBAAA,GAAA,SAAS,CAAA;CACT,gBAAA,IAAA,SAAS,CAAA;;;;;;;;;;;;;;;;AC9CP,IAAM,mBAAN,MAAM,iBAAiB;CAC5B;CAEA,YAAY,kBAAoC;EAC9C,KAAK,oBAAoB;CAC3B;;;;;;;CAQA,oBAAoB,MAAc,SAA+B;EAC/D,OAAO,KAAK,kBAAkB,oBAAoB,MAAM,OAAO;CACjE;;;;;;;;CASA,iCACE,UACA,aAAkB,CAAC,GACnB,SACA;EACA,OAAO,KAAK,kBAAkB,iCAC5B,UACA,YACA,OACF;CACF;;;;;;;;CASA,+BACE,MACA,aAAkB,CAAC,GACnB,SACA;EACA,OAAO,KAAK,kBAAkB,+BAC5B,MACA,YACA,OACF;CACF;;;;;;;CAQA,0BAA0B,UAAkB,SAA+B;EACzE,OAAO,KAAK,kBAAkB,0BAA0B,UAAU,OAAO;CAC3E;;;;;;;CAQA,wBAAwB,MAAc,SAA+B;EACnE,OAAO,KAAK,kBAAkB,wBAAwB,MAAM,OAAO;CACrE;;;;;;;;CASA,yBACE,UACA,OAAa,CAAC,GACd,SACA;EACA,OAAO,KAAK,kBAAkB,yBAC5B,UACA,MACA,OACF;CACF;;;;;;;;CASA,uBACE,MACA,OAAa,CAAC,GACd,SACA;EACA,OAAO,KAAK,kBAAkB,uBAAuB,MAAM,MAAM,OAAO;CAC1E;;;;;;;;CASA,yBACE,UACA,OAAqB,CAAC,GACtB,SACA;EACA,OAAO,KAAK,kBAAkB,yBAC5B,UACA,MACA,OACF;CACF;;;;;;;;CASA,uBACE,MACA,OAAqB,CAAC,GACtB,SACA;EACA,OAAO,KAAK,kBAAkB,uBAAuB,MAAM,MAAM,OAAO;CAC1E;;;;;;;;CASA,8BACE,UACA,OAAgC,CAAC,GACjC,SACA;EACA,OAAO,KAAK,kBAAkB,8BAC5B,UACA,MACA,OACF;CACF;;;;;;;;CASA,4BACE,MACA,OAAgC,CAAC,GACjC,SACA;EACA,OAAO,KAAK,kBAAkB,4BAC5B,MACA,MACA,OACF;CACF;;;;;;;;CASA,yBACE,UACA,OAAgC,CAAC,GACjC,SACA;EACA,OAAO,KAAK,kBAAkB,yBAC5B,UACA,MACA,OACF;CACF;;;;;;;;CASA,uBACE,MACA,OAAgC,CAAC,GACjC,SACA;EACA,OAAO,KAAK,kBAAkB,uBAAuB,MAAM,MAAM,OAAO;CAC1E;;;;;;;;CASA,8BACE,UACA,OAAgC,CAAC,GACjC,SACA;EACA,OAAO,KAAK,kBAAkB,8BAC5B,UACA,MACA,OACF;CACF;;;;;;;;CASA,4BACE,MACA,OAAgC,CAAC,GACjC,SACA;EACA,OAAO,KAAK,kBAAkB,4BAC5B,MACA,MACA,OACF;CACF;;;;;;;;CASA,4BACE,UACA,OAAgC,CAAC,GACjC,SACA;EACA,OAAO,KAAK,kBAAkB,4BAC5B,UACA,MACA,OACF;CACF;;;;;;;;CASA,0BACE,MACA,OAAgC,CAAC,GACjC,SACA;EACA,OAAO,KAAK,kBAAkB,0BAC5B,MACA,MACA,OACF;CACF;;;;;;;;;;;;;;;;;;;;;;;CAwBA,MAAM,oCACJ,KACA,YAAoB,mBACpB,aAAqB,yBACrB;EACA,OAAO,MAAM,6BAA6B,KAAK,WAAW,UAAU;CACtE;;;;;;;;;;;;;;;;;;CAmBA,MAAM,aAAa,KAA0B,SAA2B;EACtE,OAAO,MAAM,aAAa,KAAK,OAAO;CACxC;AACF;AAtVC,mBAAA,WAAA,CAAA,WAAW,GAAA,mBAAA,qBAAA,CAAA,OAAA,qBAAA,cAAA,SAAA,gBAAA,CAAA,CAAA,GAAA,gBAAA;;;;AC6BZ,MAAM,sBAAgC;CACpC,SAAS;CACT,QAAQ,CAAC,gBAAgB,cAAc;CACvC,YAAY;AACd;AA+BO,IAAM,kBAAA,mBAAN,MAAM,gBAAwC;CACnD;CACA;CAEA,YACE,gBACA,WACA;EACA,KAAK,kBAAkB;EACvB,KAAK,aAAa;CACpB;CAEA,MAAM,eAAe;EACnB,IAAI,CAAC,cAAc,KAAK,UAAU,GAChC;EAEF,MAAM,cAAc;EACpB,IAAI,CAAC,KAAK,WAAW,gBAAgB;GACnC,MAAM,sBAAsB;GAC5B,MAAM,KAAK,gBAAgB,QACzB,KAAK,WAAW,oBAAoB,KACtC;EACF;CACF;CAEA,OAAO,QAAQ,eAAmD;EAgBhE,OAAO;GACL,QAAA;GACA,WAAA;IAhBA;KACE,SAAS;KACT,UAAU;IACZ;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GAKQ;GACR,SAAS;IACP;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF;EACF;CACF;CAEA,OAAO,aAAa,SAAqD;EACvE,MAAM,oBAA8B;GAClC,SAAS;GACT,QAAQ,QAAQ,UAAU,CAAC;GAC3B,YAAY,OAAO,GAAG,SACpB,QAAQ,WAAW,GAAG,IAAI;EAC9B;EAEA,OAAO;GACL,QAAA;GACA,SAAS,QAAQ,WAAW,CAAC;GAC7B,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF;GACA,SAAS;IACP;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF;EACF;CACF;AACF;;CAtHC,OAAO;EACN,WAAW;GACT;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;CACF,CAAC;CAMI,gBAAA,GAAA,OAAO,cAAc,CAAA;CACrB,gBAAA,GAAA,OAAO,cAAc,CAAA;;;;;ACnEnB,IAAM,kBAAA,mBAAN,MAAM,gBAAgB;CAC3B,OAAO,QAAQ,SAA6C;EAC1D,OAAO;GACL,QAAA;GACA,SAAS,CAAC,gBAAgB,QAAQ,OAAO,CAAC;GAC1C,WAAW,CAAC,gBAAgB;GAC5B,SAAS,CAAC,gBAAgB;EAC5B;CACF;CAEA,OAAO,aAAa,SAAkD;EACpE,OAAO;GACL,QAAA;GACA,SAAS,CAAC,gBAAgB,aAAa,OAAO,CAAC;GAC/C,WAAW,CAAC,gBAAgB;GAC5B,SAAS,CAAC,gBAAgB;EAC5B;CACF;AACF;AAnBC,kBAAA,mBAAA,WAAA,CAAA,OAAO,CAAC,CAAC,CAAA,GAAA,eAAA"}