{"version":3,"sources":["../src/renderPdf.ts","../src/browser/launchBrowser.ts","../src/browser/detectBrowser.ts","../src/constants/browserPaths.ts","../src/types/types.ts","../src/browser/browserManager.ts","../src/styles/printStyles.ts","../src/utils/cleanup.ts","../src/utils/validateOptions.ts"],"sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { PDFOptions, Page } from \"puppeteer-core\";\n\nimport { browserManager } from \"./browser/browserManager\";\nimport { injectPrintStyles } from \"./styles/printStyles\";\nimport {\n  PdfEngineError,\n  type AssetLoadFailure,\n  type NormalizedRenderPdfOptions,\n  type RenderPdfFileResult,\n  type RenderPdfOptions,\n  type RenderPdfResult\n} from \"./types/types\";\nimport { closePage } from \"./utils/cleanup\";\nimport { validateOptions } from \"./utils/validateOptions\";\n\ntype RenderPdfFileOptions = RenderPdfOptions & {\n  output: \"file\";\n  outputPath: string;\n};\n\ntype RenderPdfBufferOptions = RenderPdfOptions & {\n  output?: \"buffer\";\n};\n\nfunction cssLengthToPixels(length: string, fallback: number): number {\n  const trimmed = length.trim().toLowerCase();\n  const match = /^(-?\\d+(?:\\.\\d+)?)(px|in|cm|mm|pt)?$/.exec(trimmed);\n\n  if (!match) {\n    return fallback;\n  }\n\n  const value = Number(match[1]);\n  const unit = match[2] ?? \"px\";\n\n  if (!Number.isFinite(value) || value <= 0) {\n    return fallback;\n  }\n\n  switch (unit) {\n    case \"px\":\n      return Math.round(value);\n    case \"in\":\n      return Math.round(value * 96);\n    case \"cm\":\n      return Math.round((value * 96) / 2.54);\n    case \"mm\":\n      return Math.round((value * 96) / 25.4);\n    case \"pt\":\n      return Math.round((value * 96) / 72);\n    default:\n      return fallback;\n  }\n}\n\nfunction isTimeoutError(error: unknown): boolean {\n  if (!(error instanceof Error)) {\n    return false;\n  }\n\n  return error.name === \"TimeoutError\" || /timeout|timed out/i.test(error.message);\n}\n\nfunction toErrorMessage(error: unknown): string {\n  return error instanceof Error ? error.message : String(error);\n}\n\nfunction withTimeout<T>(\n  promise: Promise<T>,\n  timeout: number,\n  timeoutMessage: string\n): Promise<T> {\n  let timeoutId: NodeJS.Timeout | undefined;\n\n  const timeoutPromise = new Promise<never>((_, reject) => {\n    timeoutId = setTimeout(() => {\n      reject(new PdfEngineError(\"TIMEOUT\", timeoutMessage));\n    }, timeout);\n  });\n\n  return Promise.race([promise, timeoutPromise]).finally(() => {\n    if (timeoutId) {\n      clearTimeout(timeoutId);\n    }\n  });\n}\n\nasync function ensureOutputPathWritable(outputPath: string): Promise<void> {\n  const parent = path.dirname(outputPath);\n\n  try {\n    const parentStat = await fs.stat(parent);\n    if (!parentStat.isDirectory()) {\n      throw new PdfEngineError(\n        \"FILE_OUTPUT_FAILED\",\n        \"The outputPath parent exists but is not a directory.\",\n        {\n          details: {\n            outputPath,\n            parent\n          }\n        }\n      );\n    }\n  } catch (error) {\n    if (error instanceof PdfEngineError) {\n      throw error;\n    }\n\n    throw new PdfEngineError(\n      \"FILE_OUTPUT_FAILED\",\n      \"The outputPath parent directory does not exist or is not accessible.\",\n      {\n        cause: error,\n        details: {\n          outputPath,\n          parent\n        }\n      }\n    );\n  }\n\n  try {\n    const outputStat = await fs.stat(outputPath);\n    if (outputStat.isDirectory()) {\n      throw new PdfEngineError(\n        \"FILE_OUTPUT_FAILED\",\n        \"outputPath points to a directory, not a PDF file path.\",\n        {\n          details: {\n            outputPath\n          }\n        }\n      );\n    }\n  } catch (error) {\n    const nodeError = error as NodeJS.ErrnoException;\n    if (nodeError.code !== \"ENOENT\") {\n      if (error instanceof PdfEngineError) {\n        throw error;\n      }\n\n      throw new PdfEngineError(\n        \"FILE_OUTPUT_FAILED\",\n        \"Unable to validate outputPath.\",\n        {\n          cause: error,\n          details: {\n            outputPath\n          }\n        }\n      );\n    }\n  }\n}\n\nfunction createPdfOptions(options: NormalizedRenderPdfOptions): PDFOptions {\n  const pdfOptions: PDFOptions = {\n    printBackground: true,\n    preferCSSPageSize: true,\n    width: options.size.width,\n    height: options.size.height,\n    scale: options.scale\n  };\n\n  if (options.landscape !== undefined) {\n    pdfOptions.landscape = options.landscape;\n  }\n\n  if (options.margins) {\n    pdfOptions.margin = {\n      top: options.margins.top,\n      right: options.margins.right,\n      bottom: options.margins.bottom,\n      left: options.margins.left\n    };\n  }\n\n  if (options.output === \"file\" && options.outputPath) {\n    pdfOptions.path = options.outputPath;\n  }\n\n  return pdfOptions;\n}\n\nasync function waitForAssets(page: Page, timeout: number): Promise<AssetLoadFailure[]> {\n  return withTimeout(\n    page.evaluate(async () => {\n      const failures: AssetLoadFailure[] = [];\n\n      if (\"fonts\" in document) {\n        await document.fonts.ready;\n      }\n\n      const images = Array.from(document.images);\n      await Promise.all(\n        images.map(\n          (image) =>\n            new Promise<void>((resolve) => {\n              const src = image.currentSrc || image.src || \"inline image\";\n\n              if (image.complete && image.naturalWidth > 0) {\n                resolve();\n                return;\n              }\n\n              const finish = () => {\n                if (!image.complete || image.naturalWidth === 0) {\n                  failures.push({\n                    url: src,\n                    errorText: \"Image failed to load.\"\n                  });\n                }\n\n                resolve();\n              };\n\n              image.addEventListener(\"load\", finish, { once: true });\n              image.addEventListener(\"error\", finish, { once: true });\n\n              if (\"decode\" in image) {\n                image.decode().then(finish).catch(finish);\n              }\n            })\n        )\n      );\n\n      return failures;\n    }),\n    timeout,\n    \"Timed out while waiting for images and fonts to finish loading.\"\n  );\n}\n\nfunction trackAssetFailures(page: Page, failures: AssetLoadFailure[]): void {\n  page.on(\"requestfailed\", (request) => {\n    const url = request.url();\n\n    if (url === \"about:blank\" || url.startsWith(\"data:\") || url.startsWith(\"blob:\")) {\n      return;\n    }\n\n    failures.push({\n      url,\n      errorText: request.failure()?.errorText ?? \"Request failed.\"\n    });\n  });\n\n  page.on(\"response\", (response) => {\n    const status = response.status();\n    const url = response.url();\n\n    if (\n      status < 400 ||\n      url === \"about:blank\" ||\n      url.startsWith(\"data:\") ||\n      url.startsWith(\"blob:\")\n    ) {\n      return;\n    }\n\n    failures.push({\n      url,\n      errorText: `HTTP ${status}`\n    });\n  });\n}\n\nasync function renderWithBrowser(options: NormalizedRenderPdfOptions): Promise<RenderPdfResult> {\n  const browser = await browserManager.getBrowser(\n    options.executablePath ? { executablePath: options.executablePath } : {}\n  );\n  let page: Page | undefined;\n  const requestFailures: AssetLoadFailure[] = [];\n\n  try {\n    page = await browser.newPage();\n    page.setDefaultTimeout(options.timeout);\n    page.setDefaultNavigationTimeout(options.timeout);\n    trackAssetFailures(page, requestFailures);\n\n    await page.setViewport({\n      width: cssLengthToPixels(options.size.width, 794),\n      height: cssLengthToPixels(options.size.height, 1123),\n      deviceScaleFactor: 2\n    });\n\n    await page.setContent(injectPrintStyles(options.html), {\n      waitUntil: \"networkidle0\",\n      timeout: options.timeout\n    });\n\n    const imageFailures = await waitForAssets(page, options.timeout);\n    const assetFailures = [...requestFailures, ...imageFailures];\n\n    if (assetFailures.length > 0) {\n      throw new PdfEngineError(\n        \"ASSET_LOAD_FAILED\",\n        \"One or more PDF assets failed to load.\",\n        {\n          details: {\n            assetFailures\n          }\n        }\n      );\n    }\n\n    if (options.output === \"file\" && options.outputPath) {\n      await ensureOutputPathWritable(options.outputPath);\n    }\n\n    const pdf = await page.pdf(createPdfOptions(options));\n\n    if (options.output === \"file\" && options.outputPath) {\n      return {\n        path: options.outputPath\n      };\n    }\n\n    return Buffer.from(pdf);\n  } finally {\n    await closePage(page).catch(() => undefined);\n  }\n}\n\nexport function renderPdf(options: RenderPdfFileOptions): Promise<RenderPdfFileResult>;\nexport function renderPdf(options: RenderPdfBufferOptions): Promise<Buffer>;\nexport function renderPdf(options: RenderPdfOptions): Promise<RenderPdfResult>;\nexport async function renderPdf(options: RenderPdfOptions): Promise<RenderPdfResult> {\n  const normalizedOptions = validateOptions(options);\n\n  try {\n    return await renderWithBrowser(normalizedOptions);\n  } catch (error) {\n    if (error instanceof PdfEngineError) {\n      throw error;\n    }\n\n    if (isTimeoutError(error)) {\n      throw new PdfEngineError(\"TIMEOUT\", \"PDF rendering timed out.\", {\n        cause: error\n      });\n    }\n\n    throw new PdfEngineError(\n      \"RENDER_FAILED\",\n      `Failed to render PDF: ${toErrorMessage(error)}`,\n      {\n        cause: error\n      }\n    );\n  }\n}\n","import puppeteer, { type Browser } from \"puppeteer-core\";\n\nimport { detectBrowser } from \"./detectBrowser\";\nimport { PdfEngineError, type DetectedBrowser } from \"../types/types\";\n\nexport type LaunchBrowserOptions = {\n  executablePath?: string;\n};\n\nexport type LaunchedBrowser = {\n  browser: Browser;\n  detectedBrowser: DetectedBrowser;\n};\n\nexport async function launchBrowser(\n  options: LaunchBrowserOptions = {}\n): Promise<LaunchedBrowser> {\n  const detectedBrowser = detectBrowser(\n    options.executablePath ? { executablePath: options.executablePath } : {}\n  );\n\n  try {\n    const browser = await puppeteer.launch({\n      executablePath: detectedBrowser.executablePath,\n      headless: true,\n      args: [\n        \"--disable-dev-shm-usage\",\n        \"--disable-background-networking\",\n        \"--disable-default-apps\",\n        \"--disable-extensions\"\n      ]\n    });\n\n    return {\n      browser,\n      detectedBrowser\n    };\n  } catch (error) {\n    throw new PdfEngineError(\n      \"BROWSER_LAUNCH_FAILED\",\n      `Failed to launch ${detectedBrowser.name} for PDF rendering.`,\n      {\n        cause: error,\n        details: detectedBrowser\n      }\n    );\n  }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport {\n  getBundledChromiumCandidates,\n  getWindowsBrowserCandidates,\n  type BrowserPathCandidate\n} from \"../constants/browserPaths\";\nimport { PdfEngineError, type DetectedBrowser } from \"../types/types\";\n\nexport type BrowserDetectionOptions = {\n  executablePath?: string;\n  cwd?: string;\n  env?: NodeJS.ProcessEnv;\n  platform?: NodeJS.Platform;\n  processExecPath?: string;\n  fileExists?: (filePath: string) => boolean;\n};\n\nfunction defaultFileExists(filePath: string): boolean {\n  try {\n    return fs.statSync(filePath).isFile();\n  } catch {\n    return false;\n  }\n}\n\nfunction assertSafeExecutablePath(executablePath: string, source: string): void {\n  if (executablePath.includes(\"\\0\")) {\n    throw new PdfEngineError(\n      \"VALIDATION_ERROR\",\n      `${source} browser executable path contains an invalid null byte.`\n    );\n  }\n}\n\nfunction toDetectedBrowser(candidate: BrowserPathCandidate): DetectedBrowser {\n  return {\n    name: candidate.name,\n    source: candidate.source,\n    executablePath: path.resolve(candidate.executablePath)\n  };\n}\n\nexport function detectBrowser(options: BrowserDetectionOptions = {}): DetectedBrowser {\n  const env = options.env ?? process.env;\n  const cwd = options.cwd ?? process.cwd();\n  const platform = options.platform ?? process.platform;\n  const processExecPath = options.processExecPath ?? process.execPath;\n  const fileExists = options.fileExists ?? defaultFileExists;\n  const triedPaths: string[] = [];\n\n  if (options.executablePath) {\n    assertSafeExecutablePath(options.executablePath, \"Configured\");\n\n    if (!fileExists(options.executablePath)) {\n      throw new PdfEngineError(\n        \"VALIDATION_ERROR\",\n        \"Configured browser executablePath does not exist or is not a file.\",\n        {\n          details: {\n            executablePath: options.executablePath\n          }\n        }\n      );\n    }\n\n    return {\n      name: \"Configured Chromium\",\n      source: \"override\",\n      executablePath: path.resolve(options.executablePath)\n    };\n  }\n\n  const installedCandidates =\n    platform === \"win32\" ? getWindowsBrowserCandidates(env) : [];\n  const bundledCandidates = getBundledChromiumCandidates(env, cwd, processExecPath);\n  const candidates = [...installedCandidates, ...bundledCandidates];\n\n  for (const candidate of candidates) {\n    assertSafeExecutablePath(candidate.executablePath, candidate.name);\n    triedPaths.push(candidate.executablePath);\n\n    if (fileExists(candidate.executablePath)) {\n      return toDetectedBrowser(candidate);\n    }\n  }\n\n  throw new PdfEngineError(\n    \"BROWSER_NOT_FOUND\",\n    \"No local Chrome, Edge, or bundled Chromium executable was found.\",\n    {\n      details: {\n        triedPaths\n      }\n    }\n  );\n}\n","import path from \"node:path\";\n\nimport type { BrowserSource } from \"../types/types\";\n\nexport const CHROMIUM_PATH_ENV = \"REACT_PDF_ENGINE_CHROMIUM_PATH\";\n\nexport type BrowserPathCandidate = {\n  name: string;\n  source: BrowserSource;\n  executablePath: string;\n};\n\nconst windowsPath = path.win32;\n\nfunction compact(values: Array<string | undefined>): string[] {\n  return values.filter((value): value is string => Boolean(value));\n}\n\nfunction uniqueCandidates(candidates: BrowserPathCandidate[]): BrowserPathCandidate[] {\n  const seen = new Set<string>();\n  const unique: BrowserPathCandidate[] = [];\n\n  for (const candidate of candidates) {\n    const key = windowsPath.normalize(candidate.executablePath).toLowerCase();\n    if (seen.has(key)) {\n      continue;\n    }\n\n    seen.add(key);\n    unique.push(candidate);\n  }\n\n  return unique;\n}\n\nexport function getWindowsBrowserCandidates(\n  env: NodeJS.ProcessEnv = process.env\n): BrowserPathCandidate[] {\n  const programFiles = compact([env.ProgramFiles, env[\"ProgramFiles(x86)\"]]);\n  const localAppData = env.LOCALAPPDATA;\n\n  const chromePaths = [\n    ...programFiles.map((root) =>\n      windowsPath.join(root, \"Google\", \"Chrome\", \"Application\", \"chrome.exe\")\n    ),\n    localAppData\n      ? windowsPath.join(localAppData, \"Google\", \"Chrome\", \"Application\", \"chrome.exe\")\n      : undefined\n  ];\n\n  const edgePaths = [\n    ...programFiles.map((root) =>\n      windowsPath.join(root, \"Microsoft\", \"Edge\", \"Application\", \"msedge.exe\")\n    ),\n    localAppData\n      ? windowsPath.join(localAppData, \"Microsoft\", \"Edge\", \"Application\", \"msedge.exe\")\n      : undefined\n  ];\n\n  return uniqueCandidates([\n    ...compact(chromePaths).map((executablePath) => ({\n      name: \"Google Chrome\",\n      source: \"chrome\" as const,\n      executablePath\n    })),\n    ...compact(edgePaths).map((executablePath) => ({\n      name: \"Microsoft Edge\",\n      source: \"edge\" as const,\n      executablePath\n    }))\n  ]);\n}\n\nexport function getBundledChromiumCandidates(\n  env: NodeJS.ProcessEnv = process.env,\n  cwd = process.cwd(),\n  processExecPath = process.execPath\n): BrowserPathCandidate[] {\n  const executableName = process.platform === \"win32\" ? \"chrome.exe\" : \"chrome\";\n  const roots = compact([\n    cwd,\n    path.dirname(processExecPath),\n    process.env.APPDIR,\n    process.env.PORTABLE_EXECUTABLE_DIR\n  ]);\n\n  const relativePaths = [\n    [\"chromium\", executableName],\n    [\"chromium\", \"chrome-win\", executableName],\n    [\"chrome-win\", executableName],\n    [\"bin\", \"chromium\", executableName],\n    [\"resources\", \"chromium\", executableName],\n    [\"resources\", \"chrome-win\", executableName]\n  ];\n\n  const envCandidate = env[CHROMIUM_PATH_ENV]\n    ? [\n        {\n          name: \"Bundled Chromium\",\n          source: \"bundled\" as const,\n          executablePath: env[CHROMIUM_PATH_ENV]\n        }\n      ]\n    : [];\n\n  const conventionCandidates = roots.flatMap((root) =>\n    relativePaths.map((segments) => ({\n      name: \"Bundled Chromium\",\n      source: \"bundled\" as const,\n      executablePath: path.join(root, ...segments)\n    }))\n  );\n\n  return uniqueCandidates([...envCandidate, ...conventionCandidates]);\n}\n","export type PdfOutputMode = \"buffer\" | \"file\";\n\nexport type PdfEngineErrorCode =\n  | \"VALIDATION_ERROR\"\n  | \"BROWSER_NOT_FOUND\"\n  | \"BROWSER_LAUNCH_FAILED\"\n  | \"ASSET_LOAD_FAILED\"\n  | \"RENDER_FAILED\"\n  | \"TIMEOUT\"\n  | \"FILE_OUTPUT_FAILED\";\n\nexport type BrowserSource = \"override\" | \"chrome\" | \"edge\" | \"bundled\";\n\nexport type CssLength = string;\n\nexport type PdfPageSize = {\n  width: CssLength;\n  height: CssLength;\n};\n\nexport type PdfMargins = {\n  top?: CssLength;\n  right?: CssLength;\n  bottom?: CssLength;\n  left?: CssLength;\n};\n\nexport type RenderPdfOptions = {\n  html: string;\n  size: PdfPageSize;\n  margins?: PdfMargins;\n  landscape?: boolean;\n  output?: PdfOutputMode;\n  outputPath?: string;\n  scale?: number;\n  timeout?: number;\n  executablePath?: string;\n};\n\nexport type NormalizedRenderPdfOptions = {\n  html: string;\n  size: PdfPageSize;\n  margins?: Required<PdfMargins>;\n  landscape?: boolean;\n  output: PdfOutputMode;\n  outputPath?: string;\n  scale: number;\n  timeout: number;\n  executablePath?: string;\n};\n\nexport type RenderPdfFileResult = {\n  path: string;\n};\n\nexport type RenderPdfResult = Buffer | RenderPdfFileResult;\n\nexport type DetectedBrowser = {\n  name: string;\n  source: BrowserSource;\n  executablePath: string;\n};\n\nexport type AssetLoadFailure = {\n  url: string;\n  errorText: string;\n};\n\nexport type PdfEngineErrorOptions = {\n  cause?: unknown;\n  details?: unknown;\n};\n\nexport class PdfEngineError extends Error {\n  readonly code: PdfEngineErrorCode;\n  readonly details?: unknown;\n\n  constructor(\n    code: PdfEngineErrorCode,\n    message: string,\n    options: PdfEngineErrorOptions = {}\n  ) {\n    super(message);\n    this.name = \"PdfEngineError\";\n    this.code = code;\n\n    if (\"cause\" in options) {\n      this.cause = options.cause;\n    }\n\n    if (\"details\" in options) {\n      this.details = options.details;\n    }\n  }\n}\n","import type { Browser } from \"puppeteer-core\";\n\nimport { launchBrowser, type LaunchedBrowser } from \"./launchBrowser\";\n\ntype BrowserRequest = {\n  executablePath?: string;\n};\n\nclass BrowserManager {\n  private browser: Browser | undefined;\n  private requestKey: string | undefined;\n  private launchPromise: Promise<LaunchedBrowser> | undefined;\n  private launchRequestKey: string | undefined;\n\n  async getBrowser(request: BrowserRequest = {}): Promise<Browser> {\n    const nextRequestKey = request.executablePath ?? \"auto\";\n\n    if (this.browser?.isConnected() && this.requestKey === nextRequestKey) {\n      return this.browser;\n    }\n\n    if (this.launchPromise && this.launchRequestKey === nextRequestKey) {\n      const launched = await this.launchPromise;\n      return launched.browser;\n    }\n\n    if (this.browser?.isConnected() && this.requestKey !== nextRequestKey) {\n      await this.close();\n    }\n\n    this.launchRequestKey = nextRequestKey;\n    this.launchPromise = launchBrowser(request)\n      .then((launched) => {\n        this.browser = launched.browser;\n        this.requestKey = nextRequestKey;\n\n        this.browser.once(\"disconnected\", () => {\n          if (this.browser === launched.browser) {\n            this.browser = undefined;\n            this.requestKey = undefined;\n          }\n        });\n\n        return launched;\n      })\n      .finally(() => {\n        this.launchPromise = undefined;\n        this.launchRequestKey = undefined;\n      });\n\n    const launched = await this.launchPromise;\n    return launched.browser;\n  }\n\n  async close(): Promise<void> {\n    const browser = this.browser;\n    this.browser = undefined;\n    this.requestKey = undefined;\n\n    if (browser?.isConnected()) {\n      await browser.close();\n    }\n  }\n}\n\nexport const browserManager = new BrowserManager();\n\nexport async function closePdfEngine(): Promise<void> {\n  await browserManager.close();\n}\n","export const PRINT_SAFE_CSS = `@page {\n  margin: 0;\n}\n\nbody {\n  margin: 0;\n}\n\n* {\n  -webkit-print-color-adjust: exact;\n  print-color-adjust: exact;\n}`;\n\nexport function injectPrintStyles(html: string): string {\n  const styleTag = `<style data-react-pdf-engine-print>${PRINT_SAFE_CSS}</style>`;\n\n  if (/<\\/head>/i.test(html)) {\n    return html.replace(/<\\/head>/i, `${styleTag}\\n</head>`);\n  }\n\n  if (/<head\\b[^>]*>/i.test(html)) {\n    return html.replace(/<head\\b[^>]*>/i, (match) => `${match}\\n${styleTag}`);\n  }\n\n  if (/<html\\b[^>]*>/i.test(html)) {\n    return html.replace(\n      /<html\\b[^>]*>/i,\n      (match) => `${match}\\n<head>${styleTag}</head>`\n    );\n  }\n\n  return `${styleTag}\\n${html}`;\n}\n","import type { Page } from \"puppeteer-core\";\n\nexport async function closePage(page: Page | undefined): Promise<void> {\n  if (!page || page.isClosed()) {\n    return;\n  }\n\n  await page.close();\n}\n","import path from \"node:path\";\n\nimport {\n  PdfEngineError,\n  type NormalizedRenderPdfOptions,\n  type PdfMargins,\n  type RenderPdfOptions\n} from \"../types/types\";\n\nconst DEFAULT_TIMEOUT = 30_000;\nconst DEFAULT_SCALE = 1;\n\nfunction isNonEmptyString(value: unknown): value is string {\n  return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction assertCssLength(value: unknown, fieldName: string): asserts value is string {\n  if (!isNonEmptyString(value)) {\n    throw new PdfEngineError(\n      \"VALIDATION_ERROR\",\n      `${fieldName} must be a non-empty CSS length string.`\n    );\n  }\n}\n\nfunction assertSafePath(filePath: string, fieldName: string): void {\n  if (filePath.includes(\"\\0\")) {\n    throw new PdfEngineError(\n      \"VALIDATION_ERROR\",\n      `${fieldName} contains an invalid null byte.`\n    );\n  }\n}\n\nfunction normalizeMargins(margins: PdfMargins | undefined): Required<PdfMargins> | undefined {\n  if (!margins) {\n    return undefined;\n  }\n\n  if (margins.top !== undefined) {\n    assertCssLength(margins.top, \"margins.top\");\n  }\n\n  if (margins.right !== undefined) {\n    assertCssLength(margins.right, \"margins.right\");\n  }\n\n  if (margins.bottom !== undefined) {\n    assertCssLength(margins.bottom, \"margins.bottom\");\n  }\n\n  if (margins.left !== undefined) {\n    assertCssLength(margins.left, \"margins.left\");\n  }\n\n  return {\n    top: margins.top ?? \"0\",\n    right: margins.right ?? \"0\",\n    bottom: margins.bottom ?? \"0\",\n    left: margins.left ?? \"0\"\n  };\n}\n\nexport function validateOptions(options: RenderPdfOptions): NormalizedRenderPdfOptions {\n  if (!options || typeof options !== \"object\") {\n    throw new PdfEngineError(\"VALIDATION_ERROR\", \"renderPdf options are required.\");\n  }\n\n  if (!isNonEmptyString(options.html)) {\n    throw new PdfEngineError(\n      \"VALIDATION_ERROR\",\n      \"html must be a non-empty string.\"\n    );\n  }\n\n  if (!options.size || typeof options.size !== \"object\") {\n    throw new PdfEngineError(\"VALIDATION_ERROR\", \"size is required.\");\n  }\n\n  assertCssLength(options.size.width, \"size.width\");\n  assertCssLength(options.size.height, \"size.height\");\n\n  const output = options.output ?? \"buffer\";\n  if (output !== \"buffer\" && output !== \"file\") {\n    throw new PdfEngineError(\n      \"VALIDATION_ERROR\",\n      'output must be either \"buffer\" or \"file\".'\n    );\n  }\n\n  const normalized: NormalizedRenderPdfOptions = {\n    html: options.html,\n    size: {\n      width: options.size.width,\n      height: options.size.height\n    },\n    output,\n    scale: options.scale ?? DEFAULT_SCALE,\n    timeout: options.timeout ?? DEFAULT_TIMEOUT\n  };\n\n  const margins = normalizeMargins(options.margins);\n  if (margins) {\n    normalized.margins = margins;\n  }\n\n  if (options.landscape !== undefined) {\n    if (typeof options.landscape !== \"boolean\") {\n      throw new PdfEngineError(\n        \"VALIDATION_ERROR\",\n        \"landscape must be a boolean when provided.\"\n      );\n    }\n\n    normalized.landscape = options.landscape;\n  }\n\n  if (!Number.isFinite(normalized.scale) || normalized.scale < 0.1 || normalized.scale > 2) {\n    throw new PdfEngineError(\n      \"VALIDATION_ERROR\",\n      \"scale must be a number between 0.1 and 2.\"\n    );\n  }\n\n  if (\n    !Number.isFinite(normalized.timeout) ||\n    normalized.timeout <= 0 ||\n    !Number.isInteger(normalized.timeout)\n  ) {\n    throw new PdfEngineError(\n      \"VALIDATION_ERROR\",\n      \"timeout must be a positive integer in milliseconds.\"\n    );\n  }\n\n  if (options.executablePath !== undefined) {\n    assertCssLength(options.executablePath, \"executablePath\");\n    assertSafePath(options.executablePath, \"executablePath\");\n    normalized.executablePath = options.executablePath;\n  }\n\n  if (output === \"file\") {\n    if (!isNonEmptyString(options.outputPath)) {\n      throw new PdfEngineError(\n        \"VALIDATION_ERROR\",\n        'outputPath is required when output is \"file\".'\n      );\n    }\n\n    assertSafePath(options.outputPath, \"outputPath\");\n    normalized.outputPath = path.resolve(options.outputPath);\n  }\n\n  return normalized;\n}\n"],"mappings":";AAAA,OAAOA,SAAQ;AACf,OAAOC,WAAU;;;ACDjB,OAAO,eAAiC;;;ACAxC,OAAO,QAAQ;AACf,OAAOC,WAAU;;;ACDjB,OAAO,UAAU;AAIV,IAAM,oBAAoB;AAQjC,IAAM,cAAc,KAAK;AAEzB,SAAS,QAAQ,QAA6C;AAC5D,SAAO,OAAO,OAAO,CAAC,UAA2B,QAAQ,KAAK,CAAC;AACjE;AAEA,SAAS,iBAAiB,YAA4D;AACpF,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAAiC,CAAC;AAExC,aAAW,aAAa,YAAY;AAClC,UAAM,MAAM,YAAY,UAAU,UAAU,cAAc,EAAE,YAAY;AACxE,QAAI,KAAK,IAAI,GAAG,GAAG;AACjB;AAAA,IACF;AAEA,SAAK,IAAI,GAAG;AACZ,WAAO,KAAK,SAAS;AAAA,EACvB;AAEA,SAAO;AACT;AAEO,SAAS,4BACd,MAAyB,QAAQ,KACT;AACxB,QAAM,eAAe,QAAQ,CAAC,IAAI,cAAc,IAAI,mBAAmB,CAAC,CAAC;AACzE,QAAM,eAAe,IAAI;AAEzB,QAAM,cAAc;AAAA,IAClB,GAAG,aAAa;AAAA,MAAI,CAAC,SACnB,YAAY,KAAK,MAAM,UAAU,UAAU,eAAe,YAAY;AAAA,IACxE;AAAA,IACA,eACI,YAAY,KAAK,cAAc,UAAU,UAAU,eAAe,YAAY,IAC9E;AAAA,EACN;AAEA,QAAM,YAAY;AAAA,IAChB,GAAG,aAAa;AAAA,MAAI,CAAC,SACnB,YAAY,KAAK,MAAM,aAAa,QAAQ,eAAe,YAAY;AAAA,IACzE;AAAA,IACA,eACI,YAAY,KAAK,cAAc,aAAa,QAAQ,eAAe,YAAY,IAC/E;AAAA,EACN;AAEA,SAAO,iBAAiB;AAAA,IACtB,GAAG,QAAQ,WAAW,EAAE,IAAI,CAAC,oBAAoB;AAAA,MAC/C,MAAM;AAAA,MACN,QAAQ;AAAA,MACR;AAAA,IACF,EAAE;AAAA,IACF,GAAG,QAAQ,SAAS,EAAE,IAAI,CAAC,oBAAoB;AAAA,MAC7C,MAAM;AAAA,MACN,QAAQ;AAAA,MACR;AAAA,IACF,EAAE;AAAA,EACJ,CAAC;AACH;AAEO,SAAS,6BACd,MAAyB,QAAQ,KACjC,MAAM,QAAQ,IAAI,GAClB,kBAAkB,QAAQ,UACF;AACxB,QAAM,iBAAiB,QAAQ,aAAa,UAAU,eAAe;AACrE,QAAM,QAAQ,QAAQ;AAAA,IACpB;AAAA,IACA,KAAK,QAAQ,eAAe;AAAA,IAC5B,QAAQ,IAAI;AAAA,IACZ,QAAQ,IAAI;AAAA,EACd,CAAC;AAED,QAAM,gBAAgB;AAAA,IACpB,CAAC,YAAY,cAAc;AAAA,IAC3B,CAAC,YAAY,cAAc,cAAc;AAAA,IACzC,CAAC,cAAc,cAAc;AAAA,IAC7B,CAAC,OAAO,YAAY,cAAc;AAAA,IAClC,CAAC,aAAa,YAAY,cAAc;AAAA,IACxC,CAAC,aAAa,cAAc,cAAc;AAAA,EAC5C;AAEA,QAAM,eAAe,IAAI,iBAAiB,IACtC;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,gBAAgB,IAAI,iBAAiB;AAAA,IACvC;AAAA,EACF,IACA,CAAC;AAEL,QAAM,uBAAuB,MAAM;AAAA,IAAQ,CAAC,SAC1C,cAAc,IAAI,CAAC,cAAc;AAAA,MAC/B,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,gBAAgB,KAAK,KAAK,MAAM,GAAG,QAAQ;AAAA,IAC7C,EAAE;AAAA,EACJ;AAEA,SAAO,iBAAiB,CAAC,GAAG,cAAc,GAAG,oBAAoB,CAAC;AACpE;;;ACzCO,IAAM,iBAAN,cAA6B,MAAM;AAAA,EAC/B;AAAA,EACA;AAAA,EAET,YACE,MACA,SACA,UAAiC,CAAC,GAClC;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AAEZ,QAAI,WAAW,SAAS;AACtB,WAAK,QAAQ,QAAQ;AAAA,IACvB;AAEA,QAAI,aAAa,SAAS;AACxB,WAAK,UAAU,QAAQ;AAAA,IACzB;AAAA,EACF;AACF;;;AF3EA,SAAS,kBAAkB,UAA2B;AACpD,MAAI;AACF,WAAO,GAAG,SAAS,QAAQ,EAAE,OAAO;AAAA,EACtC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,yBAAyB,gBAAwB,QAAsB;AAC9E,MAAI,eAAe,SAAS,IAAI,GAAG;AACjC,UAAM,IAAI;AAAA,MACR;AAAA,MACA,GAAG,MAAM;AAAA,IACX;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,WAAkD;AAC3E,SAAO;AAAA,IACL,MAAM,UAAU;AAAA,IAChB,QAAQ,UAAU;AAAA,IAClB,gBAAgBC,MAAK,QAAQ,UAAU,cAAc;AAAA,EACvD;AACF;AAEO,SAAS,cAAc,UAAmC,CAAC,GAAoB;AACpF,QAAM,MAAM,QAAQ,OAAO,QAAQ;AACnC,QAAM,MAAM,QAAQ,OAAO,QAAQ,IAAI;AACvC,QAAM,WAAW,QAAQ,YAAY,QAAQ;AAC7C,QAAM,kBAAkB,QAAQ,mBAAmB,QAAQ;AAC3D,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,aAAuB,CAAC;AAE9B,MAAI,QAAQ,gBAAgB;AAC1B,6BAAyB,QAAQ,gBAAgB,YAAY;AAE7D,QAAI,CAAC,WAAW,QAAQ,cAAc,GAAG;AACvC,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,UACE,SAAS;AAAA,YACP,gBAAgB,QAAQ;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,gBAAgBA,MAAK,QAAQ,QAAQ,cAAc;AAAA,IACrD;AAAA,EACF;AAEA,QAAM,sBACJ,aAAa,UAAU,4BAA4B,GAAG,IAAI,CAAC;AAC7D,QAAM,oBAAoB,6BAA6B,KAAK,KAAK,eAAe;AAChF,QAAM,aAAa,CAAC,GAAG,qBAAqB,GAAG,iBAAiB;AAEhE,aAAW,aAAa,YAAY;AAClC,6BAAyB,UAAU,gBAAgB,UAAU,IAAI;AACjE,eAAW,KAAK,UAAU,cAAc;AAExC,QAAI,WAAW,UAAU,cAAc,GAAG;AACxC,aAAO,kBAAkB,SAAS;AAAA,IACpC;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ADnFA,eAAsB,cACpB,UAAgC,CAAC,GACP;AAC1B,QAAM,kBAAkB;AAAA,IACtB,QAAQ,iBAAiB,EAAE,gBAAgB,QAAQ,eAAe,IAAI,CAAC;AAAA,EACzE;AAEA,MAAI;AACF,UAAM,UAAU,MAAM,UAAU,OAAO;AAAA,MACrC,gBAAgB,gBAAgB;AAAA,MAChC,UAAU;AAAA,MACV,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,MACA,oBAAoB,gBAAgB,IAAI;AAAA,MACxC;AAAA,QACE,OAAO;AAAA,QACP,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;;;AIvCA,IAAM,iBAAN,MAAqB;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,MAAM,WAAW,UAA0B,CAAC,GAAqB;AAC/D,UAAM,iBAAiB,QAAQ,kBAAkB;AAEjD,QAAI,KAAK,SAAS,YAAY,KAAK,KAAK,eAAe,gBAAgB;AACrE,aAAO,KAAK;AAAA,IACd;AAEA,QAAI,KAAK,iBAAiB,KAAK,qBAAqB,gBAAgB;AAClE,YAAMC,YAAW,MAAM,KAAK;AAC5B,aAAOA,UAAS;AAAA,IAClB;AAEA,QAAI,KAAK,SAAS,YAAY,KAAK,KAAK,eAAe,gBAAgB;AACrE,YAAM,KAAK,MAAM;AAAA,IACnB;AAEA,SAAK,mBAAmB;AACxB,SAAK,gBAAgB,cAAc,OAAO,EACvC,KAAK,CAACA,cAAa;AAClB,WAAK,UAAUA,UAAS;AACxB,WAAK,aAAa;AAElB,WAAK,QAAQ,KAAK,gBAAgB,MAAM;AACtC,YAAI,KAAK,YAAYA,UAAS,SAAS;AACrC,eAAK,UAAU;AACf,eAAK,aAAa;AAAA,QACpB;AAAA,MACF,CAAC;AAED,aAAOA;AAAA,IACT,CAAC,EACA,QAAQ,MAAM;AACb,WAAK,gBAAgB;AACrB,WAAK,mBAAmB;AAAA,IAC1B,CAAC;AAEH,UAAM,WAAW,MAAM,KAAK;AAC5B,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,QAAuB;AAC3B,UAAM,UAAU,KAAK;AACrB,SAAK,UAAU;AACf,SAAK,aAAa;AAElB,QAAI,SAAS,YAAY,GAAG;AAC1B,YAAM,QAAQ,MAAM;AAAA,IACtB;AAAA,EACF;AACF;AAEO,IAAM,iBAAiB,IAAI,eAAe;AAEjD,eAAsB,iBAAgC;AACpD,QAAM,eAAe,MAAM;AAC7B;;;ACrEO,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAavB,SAAS,kBAAkB,MAAsB;AACtD,QAAM,WAAW,sCAAsC,cAAc;AAErE,MAAI,YAAY,KAAK,IAAI,GAAG;AAC1B,WAAO,KAAK,QAAQ,aAAa,GAAG,QAAQ;AAAA,QAAW;AAAA,EACzD;AAEA,MAAI,iBAAiB,KAAK,IAAI,GAAG;AAC/B,WAAO,KAAK,QAAQ,kBAAkB,CAAC,UAAU,GAAG,KAAK;AAAA,EAAK,QAAQ,EAAE;AAAA,EAC1E;AAEA,MAAI,iBAAiB,KAAK,IAAI,GAAG;AAC/B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,CAAC,UAAU,GAAG,KAAK;AAAA,QAAW,QAAQ;AAAA,IACxC;AAAA,EACF;AAEA,SAAO,GAAG,QAAQ;AAAA,EAAK,IAAI;AAC7B;;;AC9BA,eAAsB,UAAU,MAAuC;AACrE,MAAI,CAAC,QAAQ,KAAK,SAAS,GAAG;AAC5B;AAAA,EACF;AAEA,QAAM,KAAK,MAAM;AACnB;;;ACRA,OAAOC,WAAU;AASjB,IAAM,kBAAkB;AACxB,IAAM,gBAAgB;AAEtB,SAAS,iBAAiB,OAAiC;AACzD,SAAO,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS;AAC5D;AAEA,SAAS,gBAAgB,OAAgB,WAA4C;AACnF,MAAI,CAAC,iBAAiB,KAAK,GAAG;AAC5B,UAAM,IAAI;AAAA,MACR;AAAA,MACA,GAAG,SAAS;AAAA,IACd;AAAA,EACF;AACF;AAEA,SAAS,eAAe,UAAkB,WAAyB;AACjE,MAAI,SAAS,SAAS,IAAI,GAAG;AAC3B,UAAM,IAAI;AAAA,MACR;AAAA,MACA,GAAG,SAAS;AAAA,IACd;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,SAAmE;AAC3F,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,QAAQ,QAAW;AAC7B,oBAAgB,QAAQ,KAAK,aAAa;AAAA,EAC5C;AAEA,MAAI,QAAQ,UAAU,QAAW;AAC/B,oBAAgB,QAAQ,OAAO,eAAe;AAAA,EAChD;AAEA,MAAI,QAAQ,WAAW,QAAW;AAChC,oBAAgB,QAAQ,QAAQ,gBAAgB;AAAA,EAClD;AAEA,MAAI,QAAQ,SAAS,QAAW;AAC9B,oBAAgB,QAAQ,MAAM,cAAc;AAAA,EAC9C;AAEA,SAAO;AAAA,IACL,KAAK,QAAQ,OAAO;AAAA,IACpB,OAAO,QAAQ,SAAS;AAAA,IACxB,QAAQ,QAAQ,UAAU;AAAA,IAC1B,MAAM,QAAQ,QAAQ;AAAA,EACxB;AACF;AAEO,SAAS,gBAAgB,SAAuD;AACrF,MAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C,UAAM,IAAI,eAAe,oBAAoB,iCAAiC;AAAA,EAChF;AAEA,MAAI,CAAC,iBAAiB,QAAQ,IAAI,GAAG;AACnC,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,QAAQ,QAAQ,OAAO,QAAQ,SAAS,UAAU;AACrD,UAAM,IAAI,eAAe,oBAAoB,mBAAmB;AAAA,EAClE;AAEA,kBAAgB,QAAQ,KAAK,OAAO,YAAY;AAChD,kBAAgB,QAAQ,KAAK,QAAQ,aAAa;AAElD,QAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,WAAW,YAAY,WAAW,QAAQ;AAC5C,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAyC;AAAA,IAC7C,MAAM,QAAQ;AAAA,IACd,MAAM;AAAA,MACJ,OAAO,QAAQ,KAAK;AAAA,MACpB,QAAQ,QAAQ,KAAK;AAAA,IACvB;AAAA,IACA;AAAA,IACA,OAAO,QAAQ,SAAS;AAAA,IACxB,SAAS,QAAQ,WAAW;AAAA,EAC9B;AAEA,QAAM,UAAU,iBAAiB,QAAQ,OAAO;AAChD,MAAI,SAAS;AACX,eAAW,UAAU;AAAA,EACvB;AAEA,MAAI,QAAQ,cAAc,QAAW;AACnC,QAAI,OAAO,QAAQ,cAAc,WAAW;AAC1C,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,eAAW,YAAY,QAAQ;AAAA,EACjC;AAEA,MAAI,CAAC,OAAO,SAAS,WAAW,KAAK,KAAK,WAAW,QAAQ,OAAO,WAAW,QAAQ,GAAG;AACxF,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MACE,CAAC,OAAO,SAAS,WAAW,OAAO,KACnC,WAAW,WAAW,KACtB,CAAC,OAAO,UAAU,WAAW,OAAO,GACpC;AACA,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,mBAAmB,QAAW;AACxC,oBAAgB,QAAQ,gBAAgB,gBAAgB;AACxD,mBAAe,QAAQ,gBAAgB,gBAAgB;AACvD,eAAW,iBAAiB,QAAQ;AAAA,EACtC;AAEA,MAAI,WAAW,QAAQ;AACrB,QAAI,CAAC,iBAAiB,QAAQ,UAAU,GAAG;AACzC,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,mBAAe,QAAQ,YAAY,YAAY;AAC/C,eAAW,aAAaC,MAAK,QAAQ,QAAQ,UAAU;AAAA,EACzD;AAEA,SAAO;AACT;;;AR/HA,SAAS,kBAAkB,QAAgB,UAA0B;AACnE,QAAM,UAAU,OAAO,KAAK,EAAE,YAAY;AAC1C,QAAM,QAAQ,uCAAuC,KAAK,OAAO;AAEjE,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,OAAO,MAAM,CAAC,CAAC;AAC7B,QAAM,OAAO,MAAM,CAAC,KAAK;AAEzB,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS,GAAG;AACzC,WAAO;AAAA,EACT;AAEA,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,KAAK,MAAM,KAAK;AAAA,IACzB,KAAK;AACH,aAAO,KAAK,MAAM,QAAQ,EAAE;AAAA,IAC9B,KAAK;AACH,aAAO,KAAK,MAAO,QAAQ,KAAM,IAAI;AAAA,IACvC,KAAK;AACH,aAAO,KAAK,MAAO,QAAQ,KAAM,IAAI;AAAA,IACvC,KAAK;AACH,aAAO,KAAK,MAAO,QAAQ,KAAM,EAAE;AAAA,IACrC;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,eAAe,OAAyB;AAC/C,MAAI,EAAE,iBAAiB,QAAQ;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,SAAS,kBAAkB,qBAAqB,KAAK,MAAM,OAAO;AACjF;AAEA,SAAS,eAAe,OAAwB;AAC9C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAEA,SAAS,YACP,SACA,SACA,gBACY;AACZ,MAAI;AAEJ,QAAM,iBAAiB,IAAI,QAAe,CAAC,GAAG,WAAW;AACvD,gBAAY,WAAW,MAAM;AAC3B,aAAO,IAAI,eAAe,WAAW,cAAc,CAAC;AAAA,IACtD,GAAG,OAAO;AAAA,EACZ,CAAC;AAED,SAAO,QAAQ,KAAK,CAAC,SAAS,cAAc,CAAC,EAAE,QAAQ,MAAM;AAC3D,QAAI,WAAW;AACb,mBAAa,SAAS;AAAA,IACxB;AAAA,EACF,CAAC;AACH;AAEA,eAAe,yBAAyB,YAAmC;AACzE,QAAM,SAASC,MAAK,QAAQ,UAAU;AAEtC,MAAI;AACF,UAAM,aAAa,MAAMC,IAAG,KAAK,MAAM;AACvC,QAAI,CAAC,WAAW,YAAY,GAAG;AAC7B,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,UACE,SAAS;AAAA,YACP;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,QAAI,iBAAiB,gBAAgB;AACnC,YAAM;AAAA,IACR;AAEA,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,SAAS;AAAA,UACP;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACF,UAAM,aAAa,MAAMA,IAAG,KAAK,UAAU;AAC3C,QAAI,WAAW,YAAY,GAAG;AAC5B,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,UACE,SAAS;AAAA,YACP;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,YAAY;AAClB,QAAI,UAAU,SAAS,UAAU;AAC/B,UAAI,iBAAiB,gBAAgB;AACnC,cAAM;AAAA,MACR;AAEA,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,SAAS;AAAA,YACP;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,SAAiD;AACzE,QAAM,aAAyB;AAAA,IAC7B,iBAAiB;AAAA,IACjB,mBAAmB;AAAA,IACnB,OAAO,QAAQ,KAAK;AAAA,IACpB,QAAQ,QAAQ,KAAK;AAAA,IACrB,OAAO,QAAQ;AAAA,EACjB;AAEA,MAAI,QAAQ,cAAc,QAAW;AACnC,eAAW,YAAY,QAAQ;AAAA,EACjC;AAEA,MAAI,QAAQ,SAAS;AACnB,eAAW,SAAS;AAAA,MAClB,KAAK,QAAQ,QAAQ;AAAA,MACrB,OAAO,QAAQ,QAAQ;AAAA,MACvB,QAAQ,QAAQ,QAAQ;AAAA,MACxB,MAAM,QAAQ,QAAQ;AAAA,IACxB;AAAA,EACF;AAEA,MAAI,QAAQ,WAAW,UAAU,QAAQ,YAAY;AACnD,eAAW,OAAO,QAAQ;AAAA,EAC5B;AAEA,SAAO;AACT;AAEA,eAAe,cAAc,MAAY,SAA8C;AACrF,SAAO;AAAA,IACL,KAAK,SAAS,YAAY;AACxB,YAAM,WAA+B,CAAC;AAEtC,UAAI,WAAW,UAAU;AACvB,cAAM,SAAS,MAAM;AAAA,MACvB;AAEA,YAAM,SAAS,MAAM,KAAK,SAAS,MAAM;AACzC,YAAM,QAAQ;AAAA,QACZ,OAAO;AAAA,UACL,CAAC,UACC,IAAI,QAAc,CAAC,YAAY;AAC7B,kBAAM,MAAM,MAAM,cAAc,MAAM,OAAO;AAE7C,gBAAI,MAAM,YAAY,MAAM,eAAe,GAAG;AAC5C,sBAAQ;AACR;AAAA,YACF;AAEA,kBAAM,SAAS,MAAM;AACnB,kBAAI,CAAC,MAAM,YAAY,MAAM,iBAAiB,GAAG;AAC/C,yBAAS,KAAK;AAAA,kBACZ,KAAK;AAAA,kBACL,WAAW;AAAA,gBACb,CAAC;AAAA,cACH;AAEA,sBAAQ;AAAA,YACV;AAEA,kBAAM,iBAAiB,QAAQ,QAAQ,EAAE,MAAM,KAAK,CAAC;AACrD,kBAAM,iBAAiB,SAAS,QAAQ,EAAE,MAAM,KAAK,CAAC;AAEtD,gBAAI,YAAY,OAAO;AACrB,oBAAM,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,MAAM;AAAA,YAC1C;AAAA,UACF,CAAC;AAAA,QACL;AAAA,MACF;AAEA,aAAO;AAAA,IACT,CAAC;AAAA,IACD;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,mBAAmB,MAAY,UAAoC;AAC1E,OAAK,GAAG,iBAAiB,CAAC,YAAY;AACpC,UAAM,MAAM,QAAQ,IAAI;AAExB,QAAI,QAAQ,iBAAiB,IAAI,WAAW,OAAO,KAAK,IAAI,WAAW,OAAO,GAAG;AAC/E;AAAA,IACF;AAEA,aAAS,KAAK;AAAA,MACZ;AAAA,MACA,WAAW,QAAQ,QAAQ,GAAG,aAAa;AAAA,IAC7C,CAAC;AAAA,EACH,CAAC;AAED,OAAK,GAAG,YAAY,CAAC,aAAa;AAChC,UAAM,SAAS,SAAS,OAAO;AAC/B,UAAM,MAAM,SAAS,IAAI;AAEzB,QACE,SAAS,OACT,QAAQ,iBACR,IAAI,WAAW,OAAO,KACtB,IAAI,WAAW,OAAO,GACtB;AACA;AAAA,IACF;AAEA,aAAS,KAAK;AAAA,MACZ;AAAA,MACA,WAAW,QAAQ,MAAM;AAAA,IAC3B,CAAC;AAAA,EACH,CAAC;AACH;AAEA,eAAe,kBAAkB,SAA+D;AAC9F,QAAM,UAAU,MAAM,eAAe;AAAA,IACnC,QAAQ,iBAAiB,EAAE,gBAAgB,QAAQ,eAAe,IAAI,CAAC;AAAA,EACzE;AACA,MAAI;AACJ,QAAM,kBAAsC,CAAC;AAE7C,MAAI;AACF,WAAO,MAAM,QAAQ,QAAQ;AAC7B,SAAK,kBAAkB,QAAQ,OAAO;AACtC,SAAK,4BAA4B,QAAQ,OAAO;AAChD,uBAAmB,MAAM,eAAe;AAExC,UAAM,KAAK,YAAY;AAAA,MACrB,OAAO,kBAAkB,QAAQ,KAAK,OAAO,GAAG;AAAA,MAChD,QAAQ,kBAAkB,QAAQ,KAAK,QAAQ,IAAI;AAAA,MACnD,mBAAmB;AAAA,IACrB,CAAC;AAED,UAAM,KAAK,WAAW,kBAAkB,QAAQ,IAAI,GAAG;AAAA,MACrD,WAAW;AAAA,MACX,SAAS,QAAQ;AAAA,IACnB,CAAC;AAED,UAAM,gBAAgB,MAAM,cAAc,MAAM,QAAQ,OAAO;AAC/D,UAAM,gBAAgB,CAAC,GAAG,iBAAiB,GAAG,aAAa;AAE3D,QAAI,cAAc,SAAS,GAAG;AAC5B,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,UACE,SAAS;AAAA,YACP;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ,WAAW,UAAU,QAAQ,YAAY;AACnD,YAAM,yBAAyB,QAAQ,UAAU;AAAA,IACnD;AAEA,UAAM,MAAM,MAAM,KAAK,IAAI,iBAAiB,OAAO,CAAC;AAEpD,QAAI,QAAQ,WAAW,UAAU,QAAQ,YAAY;AACnD,aAAO;AAAA,QACL,MAAM,QAAQ;AAAA,MAChB;AAAA,IACF;AAEA,WAAO,OAAO,KAAK,GAAG;AAAA,EACxB,UAAE;AACA,UAAM,UAAU,IAAI,EAAE,MAAM,MAAM,MAAS;AAAA,EAC7C;AACF;AAKA,eAAsB,UAAU,SAAqD;AACnF,QAAM,oBAAoB,gBAAgB,OAAO;AAEjD,MAAI;AACF,WAAO,MAAM,kBAAkB,iBAAiB;AAAA,EAClD,SAAS,OAAO;AACd,QAAI,iBAAiB,gBAAgB;AACnC,YAAM;AAAA,IACR;AAEA,QAAI,eAAe,KAAK,GAAG;AACzB,YAAM,IAAI,eAAe,WAAW,4BAA4B;AAAA,QAC9D,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,UAAM,IAAI;AAAA,MACR;AAAA,MACA,yBAAyB,eAAe,KAAK,CAAC;AAAA,MAC9C;AAAA,QACE,OAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACF;","names":["fs","path","path","path","launched","path","path","path","fs"]}