{"version":3,"file":"index.cjs","names":["z","z","suggestionHint","z"],"sources":["../src/doclet-schema.ts","../src/site/manifest.ts","../src/site/render.ts","../src/site/site-name.ts","../src/site/slug-rules.ts","../src/site/base-path.ts","../src/site/collapsible.ts","../src/site/llms.ts","../src/config/format.ts","../src/config/diagnostics.ts","../src/config/opts-schema.ts","../src/config/suggest.ts","../src/config/site-name.ts","../src/config/fonts.ts","../src/config/locales.ts","../src/config/google-fonts.ts","../src/config/llms-txt.ts","../src/config/site-url.ts","../src/config/validate-opts.ts","../src/config/report.ts","../src/config/scrollbar.ts"],"sourcesContent":["/**\n * Derived from the JSDoc doclet JSON schema.\n * @see {@link https://github.com/jsdoc/jsdoc/blob/813e0afe83ba147eadfb780facfc3f46f2a2aca5/packages/jsdoc-doclet/lib/schema.js}\n **/\n\nimport { z } from 'zod';\n\n// ── Primitive aliases ────────────────────────────────────────────────────────\n\nexport const EventRefSchema = z.string().regex(/event:.+/);\nexport type TEventRef = z.infer<typeof EventRefSchema>;\n\nexport const PackageRefSchema = z.string().regex(/^package:.+/);\nexport type TPackageRef = z.infer<typeof PackageRefSchema>;\n\n// ── META_SCHEMA ──────────────────────────────────────────────────────────────\n\nexport const DocletMetaCodeSchema = z.object({\n  funcscope: z.string().optional(),\n  id: z.string().optional(),\n  name: z.unknown().optional(),\n  node: z.object().optional(),\n  paramnames: z.array(z.string()).optional(),\n  type: z.string().optional(),\n  value: z.unknown().optional(),\n});\nexport type TDocletMetaCode = z.infer<typeof DocletMetaCodeSchema>;\n\nexport const DocletMetaSchema = z.object({\n  code: DocletMetaCodeSchema.optional(),\n  columnno: z.number().optional(),\n  filename: z.string().optional(),\n  lineno: z.number().optional(),\n  path: z.string().optional(),\n  range: z.tuple([z.number(), z.number()]).optional(),\n  vars: z.object().optional(),\n});\nexport type TDocletMeta = z.infer<typeof DocletMetaSchema>;\n\n// ── TYPE_PROPERTY_SCHEMA ─────────────────────────────────────────────────────\n\nexport const DocletTypePropertySchema = z.object({\n  expression: z.string().optional(),\n  names: z.array(z.string()).min(1),\n});\nexport type TDocletTypeProperty = z.infer<typeof DocletTypePropertySchema>;\n\n// ── PARAM_SCHEMA ─────────────────────────────────────────────────────────────\n\nexport const DocletParamSchema = z.object({\n  defaultvalue: z.unknown().optional(),\n  description: z.string().nullable().optional(),\n  name: z.string().optional(),\n  nullable: z.boolean().nullable().optional(),\n  optional: z.boolean().nullable().optional(),\n  type: DocletTypePropertySchema.optional(),\n  variable: z.boolean().nullable().optional(),\n});\nexport type TDocletParam = z.infer<typeof DocletParamSchema>;\n\n// ── TYPE_PARAM_SCHEMA ────────────────────────────────────────────────────────\n\n/**\n * A generic type parameter (`<T extends Base = Default>`). JSDoc has no native\n * concept of these, so the JSDoc bridge never populates `typeParams`; the\n * TypeDoc bridge fills it from each reflection's `typeParameters` so generics\n * render as a structured \"Type Parameters\" section instead of only living in the\n * signature string. `constraint` (the `extends` bound) and `default` are type\n * expressions kept as plain strings.\n */\nexport const DocletTypeParamSchema = z.object({\n  name: z.string(),\n  constraint: z.string().optional(),\n  default: z.string().optional(),\n  description: z.string().nullable().optional(),\n});\nexport type TDocletTypeParam = z.infer<typeof DocletTypeParamSchema>;\n\n// ── OVERLOAD_SCHEMA ──────────────────────────────────────────────────────────\n\n/**\n * One *additional* call signature of an overloaded function/method, beyond the\n * first. JSDoc has no overloads, so only the TypeDoc bridge populates\n * `overloads` (from `reflection.signatures[1..]`); the first signature stays on\n * the doclet's own `typeParams`/`params`/`returns`, so non-overloaded output is\n * unchanged. Each carries just the per-signature data that differs — generics,\n * parameters, return type, and an optional signature-specific description.\n */\nexport const DocletOverloadSchema = z.object({\n  typeParams: z.array(DocletTypeParamSchema).optional(),\n  params: z.array(DocletParamSchema).optional(),\n  returns: z.array(DocletParamSchema).optional(),\n  description: z.string().nullable().optional(),\n});\nexport type TDocletOverload = z.infer<typeof DocletOverloadSchema>;\n\n// ── ENUM_PROPERTY_SCHEMA ─────────────────────────────────────────────────────\n\nexport const DocletEnumPropertySchema = z.object({\n  comment: z.string().optional(),\n  defaultvalue: z.unknown().optional(),\n  description: z.string().nullable().optional(),\n  kind: z.literal('member'),\n  longname: z.string().optional(),\n  memberof: z.string().optional(),\n  meta: DocletMetaSchema.optional(),\n  name: z.string().optional(),\n  nullable: z.boolean().nullable().optional(),\n  optional: z.boolean().nullable().optional(),\n  scope: z.literal('static'),\n  type: DocletTypePropertySchema.optional(),\n  variable: z.boolean().nullable().optional(),\n});\n\nexport type TDocletEnumProperty = z.infer<typeof DocletEnumPropertySchema>;\n\n// ── DOCLET ENUMS ─────────────────────────────────────────────────────────────\n\nexport const DocletKindSchema = z.enum([\n  'class',\n  'constant',\n  'enum',\n  'event',\n  'external',\n  'file',\n  'function',\n  'interface',\n  'member',\n  'mixin',\n  'module',\n  'namespace',\n  'package',\n  'param',\n  'typedef',\n  // A top-level value with its own page under the TypeDoc bridge's typedoc\n  // flavor. JSDoc never emits this kind (it uses `member`/`constant`).\n  'variable',\n]);\n\nexport type TDocletKind = z.infer<typeof DocletKindSchema>;\n\nexport const DocletScopeSchema = z.enum(['global', 'inner', 'instance', 'static']);\nexport type TDocletScope = z.infer<typeof DocletScopeSchema>;\n\nexport const DocletAccessSchema = z.enum(['package', 'private', 'protected', 'public']);\nexport type TDocletAccess = z.infer<typeof DocletAccessSchema>;\n\n// ── TAG ─────────────────────────────────────────────────────────────────────\n\nexport const DocletTagSchema = z.object({\n  originalTitle: z.string().optional(),\n  text: z.string().optional(),\n  title: z.string().optional(),\n  value: z.union([z.string(), z.lazy(() => DocletParamSchema)]).optional(),\n});\n\nexport type TDocletTag = z.infer<typeof DocletTagSchema>;\n\n// ── DOCLET ──────────────────────────────────────────────────────────────────\n\nexport const DocletSchema = z.object({\n  access: DocletAccessSchema.optional(),\n  alias: z.string().optional(),\n  async: z.boolean().optional(),\n  augments: z.array(z.string()).optional(),\n  author: z.array(z.string()).optional(),\n  borrowed: z\n    .array(\n      z.object({\n        as: z.string().optional(),\n        from: z.string().optional(),\n      })\n    )\n    .optional(),\n  classdesc: z.string().optional(),\n  comment: z.string().optional(),\n  copyright: z.string().optional(),\n  defaultvalue: z.unknown().optional(),\n  defaultvaluetype: z.enum(['object', 'array']).optional(),\n  deprecated: z.union([z.string(), z.boolean()]).optional(),\n  description: z.string().nullable().optional(),\n  examples: z.array(z.string()).optional(),\n  exceptions: z.array(DocletParamSchema).optional(),\n  extends: z.array(z.string()).optional(),\n  fires: z.array(EventRefSchema).optional(),\n  forceMemberof: z.boolean().nullable().optional(),\n  generator: z.boolean().optional(),\n  hideconstructor: z.boolean().optional(),\n  ignore: z.boolean().optional(),\n  implementations: z.array(z.string()).optional(),\n  implements: z.array(z.string()).optional(),\n  // TypeDoc-only: longname of the interface member this implements (\"Implementation of\").\n  implementationOf: z.string().optional(),\n  inheritdoc: z.string().optional(),\n  inherited: z.boolean().optional(),\n  inherits: z.string().optional(),\n  isEnum: z.boolean().optional(),\n  /**\n   * Set by the TypeDoc bridge on a getter/setter member so setu can route it to\n   * an \"Accessors\" section instead of folding it into Fields. JSDoc never sets\n   * it (accessors aren't a distinct JSDoc concept), so JSDoc bucketing is\n   * unchanged.\n   */\n  isAccessor: z.boolean().optional(),\n  kind: DocletKindSchema.optional(),\n  license: z.string().optional(),\n  listens: z.array(EventRefSchema).optional(),\n  longname: z.string().optional(),\n  memberof: z.string().optional(),\n  meta: DocletMetaSchema.optional(),\n  mixed: z.boolean().optional(),\n  mixes: z.array(z.string()).optional(),\n  modifies: z.array(DocletParamSchema).optional(),\n  name: z.string().optional(),\n  nullable: z.boolean().nullable().optional(),\n  optional: z.boolean().nullable().optional(),\n  override: z.boolean().optional(),\n  overrides: z.string().optional(),\n  /**\n   * Additional call signatures of an overloaded function/method (the first lives\n   * on `params`/`returns`/`typeParams`). TypeDoc-bridge-only — JSDoc never sets\n   * it, so non-overloaded output is unchanged. See {@link DocletOverloadSchema}.\n   */\n  overloads: z.array(DocletOverloadSchema).optional(),\n  params: z.array(DocletParamSchema).optional(),\n  preserveName: z.boolean().optional(),\n  properties: z.array(z.union([DocletEnumPropertySchema, DocletParamSchema])).optional(),\n  readonly: z.boolean().optional(),\n  /**\n   * `@remarks` — detailed prose (HTML) shown as its own section after the\n   * summary/description, matching TypeDoc. Set by the TypeDoc bridge only; JSDoc\n   * has no `@remarks` field, so JSDoc output is unaffected.\n   */\n  remarks: z.string().optional(),\n  requires: z.array(z.string()).optional(),\n  returns: z.array(DocletParamSchema).optional(),\n  scope: DocletScopeSchema.optional(),\n  see: z.array(z.string()).optional(),\n  since: z.string().optional(),\n  summary: z.string().optional(),\n  tags: z.array(DocletTagSchema).optional(),\n  this: z.string().optional(),\n  todo: z.array(z.string()).optional(),\n  tutorials: z.array(z.string()).optional(),\n  type: DocletTypePropertySchema.optional(),\n  /** Structured generics (`<T extends … = …>`); TypeDoc-bridge-only. */\n  typeParams: z.array(DocletTypeParamSchema).optional(),\n  undocumented: z.boolean().optional(),\n  variable: z.boolean().nullable().optional(),\n  variation: z.string().optional(),\n  version: z.string().optional(),\n  virtual: z.boolean().optional(),\n  yields: z.array(DocletParamSchema).optional(),\n});\n\nexport type TDoclet = z.infer<typeof DocletSchema>;\n\n// ── PACKAGE_SCHEMA ───────────────────────────────────────────────────────────\n\nexport const TContactInfoSchema = z.object({\n  email: z.string().optional(),\n  name: z.string().optional(),\n  url: z.string().optional(),\n});\n\nexport type TContactInfo = z.infer<typeof TContactInfoSchema>;\n\nexport const TBugsInfoSchema = z.object({\n  email: z.string().optional(),\n  url: z.string().optional(),\n});\n\nexport type TBugsInfo = z.infer<typeof TBugsInfoSchema>;\n\nexport const PackageDocletSchema = z.object({\n  author: z.union([z.string(), TContactInfoSchema]).optional(),\n  bugs: z.union([z.string(), TBugsInfoSchema]).optional(),\n  contributors: z.array(z.union([z.string(), TContactInfoSchema])).optional(),\n  dependencies: z.object().optional(),\n  description: z.string().optional(),\n  devDependencies: z.object().optional(),\n  engines: z.object().optional(),\n  files: z.array(z.string()).optional(),\n  homepage: z.string().optional(),\n  keywords: z.array(z.string()).optional(),\n  kind: z.literal('package'),\n  licenses: z\n    .array(\n      z.object({\n        type: z.string().optional(),\n        url: z.string().optional(),\n      })\n    )\n    .optional(),\n  longname: PackageRefSchema.optional(),\n  main: z.string().optional(),\n  name: z.string().optional(),\n  repository: z\n    .object({\n      type: z.string().optional(),\n      url: z.string().optional(),\n    })\n    .optional(),\n  version: z.string().optional(),\n});\n\nexport type TPackageDoclet = z.infer<typeof PackageDocletSchema>;\n\n// ── DOCLETS LIST ─────────────────────────────────────────────────────────────\n\nexport const DocletListSchema = z.array(z.union([DocletSchema, PackageDocletSchema]));\n\nexport type TDocletList = z.infer<typeof DocletListSchema>;\n\nexport function isPackageDoclet(doclet: unknown): doclet is TPackageDoclet {\n  if (!PackageDocletSchema.safeParse(doclet).success) return true;\n  return (doclet as TPackageDoclet).kind === 'package';\n}\n\nexport function isDoclet(doclet: unknown): doclet is TDoclet {\n  if (!DocletSchema.safeParse(doclet).success) return false;\n  return (doclet as TDoclet).kind !== 'package';\n}\n","/**\n * SiteManifest — the boundary object setu emits and dwar consumes.\n */\n\nimport type { Page } from './page';\n\n/** Recursive nav tree node. Leaves have `slug`; branches have `children`. */\nexport interface NavNode {\n  label: string;\n  slug?: string;\n  children?: NavNode[];\n  /** Optional grouping label; sibling nodes sharing a group render together. */\n  group?: string;\n  /** Sort order within siblings. */\n  order?: number;\n  /**\n   * TypeDoc-only: when set on a branch node, the sidebar auto-opens it if ANY\n   * descendant (not just a direct child) is the current page. JSDoc never sets\n   * this — its branches keep the legacy direct-children-only auto-open check, so\n   * JSDoc SSR output stays byte-identical. See rang's `NavEntry`.\n   */\n  deepExpand?: boolean;\n  /**\n   * Absolute URL for an external menu link (e.g. a GitHub/npm link). Mutually\n   * exclusive with `slug`; when set, the entry opens in a new tab.\n   */\n  href?: string;\n  /** True for an external link entry (`href` set) — render with `target=\"_blank\"`. */\n  external?: boolean;\n  /**\n   * Link `target` attribute for a menu entry (e.g. `_blank`, `_self`). When\n   * omitted, an external entry still defaults to `_blank`; an internal one omits\n   * the attribute.\n   */\n  target?: string;\n  /** Extra CSS class(es) merged onto a menu entry's rendered link. */\n  class?: string;\n  /**\n   * Icon for the entry (menu items only), as a prefixed `source:code` string:\n   * `simpleicons:<slug>` renders the `cdn.simpleicons.org` glyph painted with\n   * the `fg` theme token (CSS-masked, so it swaps light/dark on its own), and\n   * `lucide:<name>` renders from the bundled lucide set (`home`,\n   * `code-xml`, `globe`, `mail`, `external-link`; an unknown name →\n   * `external-link`).\n   */\n  icon?: string;\n  /**\n   * True for a top-region menu entry. The sidebar renders all menu entries above\n   * the API sections, with a divider between.\n   */\n  menu?: boolean;\n}\n\n/**\n * A single entry in the fuzzy search index the `cmdk` palette fetches.\n *\n * A page entry has `slug` = the page slug and `title` = the page title; a\n * **member entry** has `slug` = `page#heading-anchor` (a deep link to a member /\n * field / method heading), `title` = the member name, and `context` = the parent\n * page title. `description` + `content` are matched (so README prose, member\n * descriptions, and identifiers are all findable), not just the title; `excerpt`\n * is shown under page hits.\n */\nexport interface SearchEntry {\n  slug: string;\n  title: string;\n  /** Short plain-text snippet shown under a page hit. */\n  excerpt?: string;\n  /** Page/member description — matched, and used as a member hit's subtitle. */\n  description?: string;\n  /** Full plain-text body (identifiers preserved) — matched, never displayed. */\n  content?: string;\n  /** For a member entry, the parent page title (shown as the hit's context). */\n  context?: string;\n}\n\n/**\n * One translatable API string in the locale-independent template setu emits.\n *\n * Every translatable doclet prose field (a description, a `@summary`, an\n * `@example` caption) becomes a slot keyed by the symbol's longname + field path\n * (bhasha's `apiSlotKey`). The slot carries the default-locale `sourceText` and a\n * content `hash` (bhasha's `sourceHash`) so aadesh can extract a catalog skeleton\n * and detect when a source string drifts (stale translation). Locale-invariant:\n * the same slot key appears on every build of the same symbol+field, so a\n * translation tracks its source across rebuilds. Names, type strings, enum\n * values, and `@example` code are NOT slots — they stay locale-invariant.\n */\nexport interface SlotEntry {\n  /** Stable catalog key — `api.<longname>#<field>` (bhasha `apiSlotKey`). */\n  key: string;\n  /** The default-locale source string this slot renders (HTML or Markdown). */\n  sourceText: string;\n  /** Content hash of `sourceText` (bhasha `sourceHash`) for staleness detection. */\n  hash: string;\n}\n\n/** What setu hands to dwar. Self-contained: dwar should not re-read the doclet DB. */\nexport interface SiteManifest {\n  pages: Page[];\n  nav: NavNode[];\n  /** Package.json fields exposed for rendering (header, footer, OG tags, ...). */\n  pkg?: {\n    name?: string;\n    version?: string;\n    description?: string;\n    repository?: string;\n    homepage?: string;\n  };\n  /** Stable per-build identifier (e.g. timestamp + content hash) for cache busting. */\n  buildId: string;\n  /**\n   * The translatable API slots collected during this build — the\n   * locale-independent template aadesh extracts catalogs from. setu always\n   * populates it (possibly empty); dwar ignores it. A build *stamped* for a\n   * locale carries the same slot set (keys/sources are locale-invariant); only\n   * the page bodies differ. See {@link SlotEntry}.\n   */\n  slots?: SlotEntry[];\n  /**\n   * Top-level sidebar section labels that render as collapse toggles (the\n   * resolved `collapsibleSidebarSections` opt). Populated by setu (default: all\n   * present sections). dwar threads it into the sidebar/mobile-nav island props;\n   * rang renders a header as a toggle when its label is in this list. An empty\n   * list means every header is static (today's behavior).\n   */\n  collapsibleGroups?: string[];\n}\n\n/** Current schema version of the {@link ExtractManifest}. */\nexport const EXTRACT_MANIFEST_VERSION = 1;\n\n/**\n * The minimal artifact the theme's localization **extract mode** writes to disk\n * for aadesh: just the translatable API slot template (chrome strings come from\n * bhasha's catalog, so they aren't duplicated here). aadesh spawns the jsdoc/\n * typedoc pipeline with the theme signaled to emit this — instead of rendering —\n * then builds the per-locale catalogs from it. Regenerate-on-build, never\n * committed. See the localization plan, §4.\n */\nexport interface ExtractManifest {\n  /** Schema version ({@link EXTRACT_MANIFEST_VERSION}). */\n  version: number;\n  /** The translatable API slots (longname+field keyed, with source + hash). */\n  slots: SlotEntry[];\n}\n\n/** Project a built {@link SiteManifest} down to the {@link ExtractManifest} aadesh reads. */\nexport function toExtractManifest(manifest: SiteManifest): ExtractManifest {\n  return { version: EXTRACT_MANIFEST_VERSION, slots: manifest.slots ?? [] };\n}\n\n/** Current schema version of the {@link BuildSpec}. */\nexport const BUILD_SPEC_VERSION = 1;\n\n/**\n * The per-locale render instruction aadesh writes for the theme's **build mode**\n * (the localization plan §4: \"template + filled catalogs → setu stamp → dwar\n * render → per-locale sites\"). aadesh spawns the pipeline once per locale with\n * the theme pointed at this spec; the theme stamps the API translations\n * (`setu.stampSite`) and renders to `destination` with `basePath`. The default\n * locale renders unprefixed (`basePath: '/'`); others under `/<locale>`.\n */\nexport interface BuildSpec {\n  /** Schema version ({@link BUILD_SPEC_VERSION}). */\n  version: number;\n  /** Locale code being rendered. */\n  locale: string;\n  /** Default locale code — the fallback for untranslated chrome/API. */\n  defaultLocale: string;\n  /**\n   * `api.*` key → translated string, fed to `setu.stampSite`. Empty/omitted\n   * entries fall back to the source text. The default locale typically passes\n   * `{}` (identity → live source).\n   */\n  apiMessages: Record<string, string>;\n  /**\n   * `chrome.*` key → translated UI string, fed to dwar's `RenderOptions.locale`\n   * so chrome renders in the locale (SSR + island seeding). The default locale\n   * typically passes `{}` (identity → English fallback).\n   */\n  chromeMessages: Record<string, string>;\n  /** Output directory for this locale's site. */\n  destination: string;\n  /** Base-path prefix for this locale's links — `/<locale>`, or `/` for the default. */\n  basePath: string;\n  /**\n   * The UN-prefixed site base path (the default locale's base), for the language\n   * switcher's cross-locale URLs. Same across every locale in the build.\n   */\n  siteBasePath: string;\n  /** All configured locales (code + optional display name) — feeds the switcher. */\n  locales: Array<{ code: string; name?: string }>;\n  /**\n   * Absolute path of this locale's docs-overlay directory (a sibling\n   * `docs.<locale>/` of the configured `opts.docs`), when one exists. The bridge\n   * overlays its files over the default docs by path — a translated doc wins, a\n   * missing one falls back to the default. Omitted when the locale has no overlay\n   * (the default-locale + untranslated locales render the default docs).\n   */\n  docsDir?: string;\n}\n","/**\n * dwar.render result + options. Note: no `embedSearchIndex` — Pagefind runs in\n * a separate post-write step (`runPagefindAgainstDir`). See Q5.\n */\n\nimport type { LlmsTxtConfig } from './llms';\nimport type { SearchEntry } from './manifest';\nimport type { ThemeConfig } from './theme';\n\n/** A single emitted file. `path` is forward-slash, relative to destination root. */\nexport interface OutputFile {\n  path: string;\n  contents: string | Uint8Array;\n}\n\n/** A page that failed to render and was skipped, with the reason. */\nexport interface RenderError {\n  /** Slug of the page that failed. */\n  slug: string;\n  /** The error message (e.g. an MDX compile failure). */\n  message: string;\n  /** 1-based source line of the failure, when the error carries a position. */\n  line?: number;\n  /** 1-based source column of the failure (best-effort — see issue #333 spec). */\n  column?: number;\n  /** A few numbered lines of `page.body` around the failure, with a caret. */\n  snippet?: string;\n}\n\n/**\n * A non-fatal authoring issue found while rendering a page — e.g. an unbalanced\n * inline-code backtick. Unlike a {@link RenderError} the page still renders; the\n * bridge surfaces these so the author can fix the source. Same positional shape\n * as `RenderError`, so {@link formatRenderError} prints both identically.\n */\nexport interface RenderWarning {\n  /** Slug of the page the issue was found on. */\n  slug: string;\n  /** Human-readable description of the issue. */\n  message: string;\n  /** 1-based source line in `page.body`, when known. */\n  line?: number;\n  /** 1-based source column in `page.body`, when known (best-effort). */\n  column?: number;\n  /** A few numbered lines of `page.body` around the issue, with a caret. */\n  snippet?: string;\n}\n\n/**\n * Format one skipped-page {@link RenderError} (or a {@link RenderWarning}, which\n * has the same shape) for a build log, so both bridges (JSDoc + TypeDoc) print\n * them identically. A positioned entry shows `slug (line L:C): message` followed\n * by its indented code-frame snippet; an unpositioned one falls back to the\n * legacy `slug: message` single line.\n */\nexport function formatRenderError(error: RenderError | RenderWarning, indent = '  '): string {\n  const hasLine = typeof error.line === 'number';\n  const loc = hasLine\n    ? ` (line ${error.line}${typeof error.column === 'number' ? `:${error.column}` : ''})`\n    : '';\n  const header = `${indent}- ${error.slug}${loc}: ${error.message}`;\n  if (!error.snippet) return header;\n  const snippet = error.snippet\n    .split('\\n')\n    .map((l) => `${indent}    ${l}`)\n    .join('\\n');\n  return `${header}\\n${snippet}`;\n}\n\n/** Aggregated result returned by `dwar.render`. Pure — no I/O is performed here. */\nexport interface RenderResult {\n  files: OutputFile[];\n  /** Entries that callers should hand to Pagefind after writing files. */\n  search?: SearchEntry[];\n  /**\n   * Pages that failed to render and were skipped. A single bad page (e.g. MDX\n   * that won't compile) must not abort the whole build — render() collects the\n   * failures here so the caller can surface them. Empty when all pages render.\n   */\n  errors?: RenderError[];\n  /**\n   * Non-fatal authoring issues found while rendering (e.g. unbalanced inline-code\n   * backticks). The pages still rendered — these are surfaced so the author can\n   * clean up the source. Empty/absent when nothing was flagged.\n   */\n  warnings?: RenderWarning[];\n  stats: {\n    /** Pages successfully rendered (excludes any in `errors`). */\n    pageCount: number;\n    assetCount: number;\n    cssBytes: number;\n    jsBytes: number;\n    durationMs: number;\n  };\n}\n\n/**\n * Options to `dwar.render`. There is intentionally no `embedSearchIndex` flag:\n * search index generation is a separate step (`runPagefindAgainstDir`) that\n * runs against the already-written output directory. See Q5.\n */\nexport interface RenderOptions {\n  theme: ThemeConfig;\n  /**\n   * Destination directory. Used only for resolving paths inside output `OutputFile.path`\n   * entries — dwar never writes files itself.\n   */\n  destination?: string;\n  /**\n   * Optional directory for an on-disk cache of the bundled island chunks. When\n   * set, dwar caches the esbuild island bundle keyed on a content hash of its\n   * inputs (rang's compiled output + the island entry sources + the preact\n   * version), so a warm rebuild whose inputs are unchanged skips the ~0.4s\n   * esbuild step — the big win for the `jsdoc --watch`/dev loop. This is the\n   * one place render() touches disk and is opt-in: omit it (the default) and\n   * render() stays pure. The bridge (the I/O layer) supplies it, typically\n   * `<project>/node_modules/.cache/clean-jsdoc-theme`.\n   */\n  islandCacheDir?: string;\n  /**\n   * Map from a doc image `src` (the root-relative `/_assets/<name>.<hash>.svg`\n   * the bridge rewrote it to) to that SVG's raw markup. When an `<img>`'s `src`\n   * is in this map, rang inlines the SVG into the page instead of `<img>`-ing it\n   * — so its `[data-theme=\"dark\"]` styles follow the theme toggle (an\n   * `<img>`-loaded SVG only sees the OS `prefers-color-scheme`). The bridge reads\n   * the SVGs (the I/O layer); render() just looks them up, staying pure.\n   */\n  inlineSvgs?: Record<string, string>;\n  /**\n   * Active-locale info for a localized build (aadesh `build`). When present, dwar\n   * renders chrome in this locale — it wraps the SSR page tree in bhasha's\n   * `LanguageProvider` and seeds each island root from the per-page payload, and\n   * sets `<html lang>`. Absent for a normal single-locale build, so that path's\n   * output stays byte-identical.\n   */\n  locale?: RenderLocale;\n  /**\n   * The site's public base URL (e.g. `https://example.com` or\n   * `https://example.com/docs`). When set, dwar emits a `sitemap.xml` at the\n   * output root listing every non-hidden page's canonical URL. Only the URL's\n   * **origin** is used — the deploy sub-path comes from `theme.basePath`, so the\n   * two never double-count (a bare origin works, and so does a full URL whose\n   * path equals basePath). Omit it and no sitemap is emitted (today's behavior).\n   */\n  siteUrl?: string;\n  /**\n   * Resolved `llmsTxt` config. When set AND {@link RenderOptions.siteUrl} is\n   * usable, dwar emits `llms.txt` (+ `llms-full.txt` unless `full: false`) at the\n   * output root — an llmstxt.org index linking each page's companion `.md`.\n   * The bridge validates this and owns the \"enabled but no siteUrl\" warning, so\n   * `render()` stays pure: a missing `siteUrl` here simply emits nothing.\n   */\n  llmsTxt?: LlmsTxtConfig;\n}\n\n/** Active-locale chrome translations for a localized render. See {@link RenderOptions.locale}. */\nexport interface RenderLocale {\n  /** Active locale code (also the `<html lang>`). */\n  code: string;\n  /** Default locale code — the fallback for any untranslated chrome key. */\n  defaultLocale: string;\n  /** Chrome translations: full `chrome.*` key → translated string (non-empty only). */\n  messages: Record<string, string>;\n  /**\n   * The UN-prefixed site base path (the default locale's base), used to build the\n   * language switcher's cross-locale URLs — `<siteBasePath>/<locale>/<slug>` for a\n   * non-default locale, `<siteBasePath>/<slug>` for the default. Distinct from\n   * `theme.basePath`, which is already prefixed with the active locale.\n   */\n  siteBasePath?: string;\n  /**\n   * All configured locales (code + display label) for the switcher. When two or\n   * more are present, dwar mounts a `language-switcher` island in the header.\n   */\n  locales?: Array<{ code: string; label: string }>;\n}\n","/**\n * Site name / logo contract. `siteName` is either plain text (shown in the\n * header, footer, and `<title>` suffix) or a logo image set with per-theme\n * sources.\n */\n\n/**\n * A logo image set. Values are image sources — a URL, a `data:` URI, or (when\n * processed by the bridge) a path it copies into the output. At least one key\n * must be set for a logo to render.\n */\nexport interface SiteLogo {\n  /** Used when the active theme has no dedicated image. */\n  default?: string;\n  /** Used under the dark theme (falls back to `default`). */\n  dark?: string;\n  /** Used under the light theme (falls back to `default`). */\n  light?: string;\n  /**\n   * Text label for the logo — used as the image `alt` and the `<title>` (browser\n   * tab) suffix. Falls back to `pkg.name` when omitted.\n   */\n  alt?: string;\n}\n\n/** Either plain text or a per-theme logo image set. */\nexport type SiteName = string | SiteLogo;\n\n/**\n * Text label for the site — used for the `<title>` suffix, image `alt`, and the\n * footer when no logo applies. Returns the string form directly; for a logo set\n * its `alt`, then the supplied fallback (typically `pkg.name`).\n */\nexport function siteNameText(\n  siteName: SiteName | undefined,\n  fallback?: string\n): string | undefined {\n  if (typeof siteName === 'string') return siteName;\n  return siteName?.alt ?? fallback;\n}\n\n/**\n * Resolve the per-theme logo sources, or `null` when `siteName` carries no\n * image (plain text or an empty set). Each theme falls back to `default`, then\n * to the other theme's image, so a single supplied image is reused everywhere\n * rather than leaving a theme with no logo.\n */\nexport function resolveSiteLogo(\n  siteName: SiteName | undefined\n): { light: string; dark: string } | null {\n  if (!siteName || typeof siteName === 'string') return null;\n  const { default: def, dark, light } = siteName;\n  const lightSrc = light ?? def ?? dark;\n  const darkSrc = dark ?? def ?? light;\n  if (!lightSrc || !darkSrc) return null;\n  return { light: lightSrc, dark: darkSrc };\n}\n","/**\n * Slugification rules shared between setu (sidebar / TOC generation) and dwar\n * (rendered heading anchors). Both sides MUST import from here so that anchor\n * IDs and sidebar links match. This addresses Risk R4.\n */\n\n// Latin combining diacritical marks block (U+0300..U+036F): the accents NFKD\n// peels off Latin letters (é → e + U+0301). Scoped to this block on purpose —\n// matching every `\\p{M}` would also strip Devanagari vowel signs (matras) and\n// the Japanese voiced-sound mark, mangling non-Latin headings into degenerate\n// slugs. Those marks are kept by the character classes below and recomposed by\n// the final NFC pass. The `\\u` escapes keep the regex source pure ASCII.\nconst DIACRITICS = /[\\u0300-\\u036f]+/g;\n\n// Anything that is not a letter, number, combining mark, whitespace, or hyphen\n// is punctuation to drop. The `u` flag makes `\\p{L}`/`\\p{N}` cover every script\n// (Devanagari, Kana, CJK, …), not just ASCII; `\\p{M}` keeps the marks the NFC\n// pass needs to recompose. Latin diacritics are already gone via DIACRITICS.\nconst NON_SLUG_HEADING = /[^\\p{L}\\p{N}\\p{M}\\s-]+/gu;\nconst NON_SLUG_PATH = /[^\\p{L}\\p{N}\\p{M}]+/gu;\n\n/**\n * GitHub-style heading slugifier:\n *   - lowercase\n *   - strip combining diacritics (after NFKD normalization)\n *   - drop any character that isn't a letter, number, mark, space, or hyphen\n *   - collapse runs of whitespace/hyphens into a single hyphen\n *   - trim leading/trailing hyphens\n *   - recompose to NFC so non-Latin slugs match what authors type in\n *     `#fragment` links\n *\n * Letters/numbers/marks are matched per-script (Unicode-aware), so Devanagari\n * and Japanese headings produce meaningful, non-empty slugs — not the empty or\n * Latin-only degenerate slugs an ASCII-only class would yield.\n *\n * When `registry` is provided, repeated slugs are deduped by appending `-1`,\n * `-2`, ... — the registry tracks how many times each base slug has been seen\n * so callers can reuse it across all headings on a page.\n *\n * @example\n *   const reg = new Map<string, number>();\n *   slugifyHeading('Hello World', reg); // 'hello-world'\n *   slugifyHeading('Hello World', reg); // 'hello-world-1'\n */\nexport function slugifyHeading(text: string, registry?: Map<string, number>): string {\n  const base = String(text ?? '')\n    .normalize('NFKD')\n    .replace(DIACRITICS, '')\n    .toLowerCase()\n    .replace(NON_SLUG_HEADING, '') // drop punctuation\n    .trim()\n    .replace(/[\\s-]+/g, '-') // collapse whitespace/hyphens\n    .replace(/^-+|-+$/g, '') // trim hyphens\n    .normalize('NFC'); // recompose marks split apart by NFKD\n\n  if (!registry) return base;\n\n  const seen = registry.get(base) ?? 0;\n  registry.set(base, seen + 1);\n  return seen === 0 ? base : `${base}-${seen}`;\n}\n\n/**\n * Path slug for URLs: lowercases each part, replaces any run of\n * non-alphanumeric characters with `-`, trims hyphens, drops empty parts, and\n * joins with `/`. Slashes between parts are preserved; slashes inside a part\n * are not — split before calling if you want sub-paths. Unicode-aware, so\n * non-Latin path parts survive instead of collapsing to empty.\n *\n * @example\n *   slugifyPath(['Foo Bar', 'Baz!']); // 'foo-bar/baz'\n */\nexport function slugifyPath(parts: string[]): string {\n  return parts\n    .map((part) =>\n      String(part ?? '')\n        .normalize('NFKD')\n        .replace(DIACRITICS, '')\n        .toLowerCase()\n        .replace(NON_SLUG_PATH, '-')\n        .replace(/^-+|-+$/g, '')\n        .normalize('NFC')\n    )\n    .filter((part) => part.length > 0)\n    .join('/');\n}\n\n/**\n * Slug for a project-relative source file path. Used BOTH for the source\n * viewer page slug and the in-doc \"Source: file:line\" link target so the two\n * always agree. Normalizes backslashes to `/`, then per segment lowercases and\n * replaces any run of non-alphanumeric characters (including dots) with `-`,\n * trimming hyphens; empty segments are dropped. The extension is folded into\n * the segment (not stripped) so `foo.js` and `foo.ts` stay distinct.\n *\n * @example\n *   slugifySourcePath('src/Foo.js');        // 'src/foo-js'\n *   slugifySourcePath('lib\\\\util\\\\index.ts'); // 'lib/util/index-ts'\n */\nexport function slugifySourcePath(relPath: string): string {\n  return String(relPath ?? '')\n    .replace(/\\\\/g, '/')\n    .split('/')\n    .map((segment) =>\n      segment\n        .toLowerCase()\n        .replace(NON_SLUG_PATH, '-')\n        .replace(/^-+|-+$/g, '')\n    )\n    .filter((segment) => segment.length > 0)\n    .join('/');\n}\n","/**\n * Base-path helpers — let the site be served from a sub-directory\n * (e.g. `https://example.com/doc/api`) by prefixing every emitted URL.\n *\n * Both functions are pure and browser-safe: utils is imported by rang in the\n * browser, so these use only the global `URL` (no node builtins) and never\n * throw — bad input fails safe to the root prefix `'/'`.\n */\n\n/**\n * Normalize a developer-supplied base path into a canonical prefix:\n *  - `'/'` for the site root, or\n *  - `'/sub/dir'` — a leading slash, NO trailing slash — for a sub-directory.\n *\n * Accepts either a bare path (`'/doc/api/'`) or a full / protocol-relative URL\n * (`'https://example.com/doc/api'`, `'//host/doc/api'`); for a URL the pathname\n * is extracted. Empty / `undefined` / `'/'` → `'/'`. Fail-safe: anything that\n * can't be parsed sensibly returns `'/'` (never throws).\n *\n * @example\n * normalizeBasePath('/doc/api/');                  // '/doc/api'\n * normalizeBasePath('https://example.com/doc/api'); // '/doc/api'\n * normalizeBasePath('https://example.com');         // '/'\n * normalizeBasePath('');                            // '/'\n * normalizeBasePath(undefined);                     // '/'\n */\nexport function normalizeBasePath(input: unknown): string {\n  if (typeof input !== 'string') return '/';\n  const trimmed = input.trim();\n  if (trimmed.length === 0) return '/';\n\n  let path = trimmed;\n  // Full (`http(s)://host/path`) or protocol-relative (`//host/path`) URL:\n  // pull out just the pathname. A bare path is left as-is.\n  if (/^(https?:)?\\/\\//i.test(trimmed)) {\n    try {\n      // `//host/path` has no protocol; give `new URL` one so it parses.\n      const withProtocol = trimmed.startsWith('//') ? `https:${trimmed}` : trimmed;\n      path = new URL(withProtocol).pathname;\n    } catch {\n      return '/';\n    }\n  }\n\n  // Collapse to a clean prefix: ensure a single leading slash, strip any\n  // trailing slash(es). An empty / root pathname → '/'.\n  const cleaned = '/' + path.replace(/^\\/+/, '').replace(/\\/+$/, '');\n  return cleaned === '/' ? '/' : cleaned;\n}\n\n/**\n * Join a base-path prefix with a root-relative path, with no double slashes,\n * for any `basePath` value (`'/'`, `''`, or `'/doc/api'`).\n *\n * Backward compatible: `withBase('/', '/x')` returns `'/x'` unchanged, so with\n * the default root base every emitted URL is byte-identical to before.\n *\n * @example\n * withBase('/', '/x');         // '/x'\n * withBase('/doc/api', '/x');  // '/doc/api/x'\n * withBase('/doc/api', 'x');   // '/doc/api/x'\n */\nexport function withBase(basePath: string | undefined, path: string): string {\n  const b = (basePath ?? '/').replace(/\\/+$/, '');\n  const p = path.startsWith('/') ? path : '/' + path;\n  return b + p;\n}\n","/**\n * Collapsible top-level sidebar sections — the build-time resolver for the\n * `collapsibleSidebarSections` opt. A function form is deliberately NOT\n * supported: the decision is static per build, and neither the pure\n * `SiteManifest` boundary nor the JSON island-props payload can carry a\n * function. All input forms resolve here to a concrete `string[]` of section\n * labels that rang renders as collapse toggles.\n */\n\nimport type { NavNode } from './manifest';\n\n/** `boolean` (all / none) or an explicit allowlist of section labels. */\nexport type CollapsibleSidebarSections = boolean | string[];\n\n/**\n * The distinct top-level section labels present in a nav tree, in first-seen\n * order. Mirrors rang's `groupNav` bucketing: a \"section\" is a run of non-menu\n * nodes sharing a truthy `group`. Menu entries and ungrouped nodes are ignored.\n */\nexport function topLevelSectionLabels(nav: readonly NavNode[]): string[] {\n  const seen = new Set<string>();\n  const out: string[] = [];\n  for (const node of nav) {\n    if (node.menu) continue;\n    const g = node.group;\n    if (!g || seen.has(g)) continue;\n    seen.add(g);\n    out.push(g);\n  }\n  return out;\n}\n\n/**\n * Resolve the config against the sections actually present:\n *  - `undefined` (default) or `true` → every present section is collapsible.\n *  - `false` → none.\n *  - `string[]` → only present sections whose label EXACTLY matches an entry\n *    (case-sensitive), keeping present order. Non-matching entries are dropped\n *    here and surfaced as a warning by the bridge (see\n *    {@link unmatchedCollapsibleSections}).\n * The result is always a subset of `present`, so rang can trust it.\n */\nexport function resolveCollapsibleSections(\n  config: CollapsibleSidebarSections | undefined,\n  present: readonly string[]\n): string[] {\n  if (config === false) return [];\n  if (config === undefined || config === true) return [...present];\n  const wanted = new Set(config);\n  return present.filter((label) => wanted.has(label));\n}\n\n/** Array entries that matched no present section — for the bridge's warning. */\nexport function unmatchedCollapsibleSections(\n  config: CollapsibleSidebarSections | undefined,\n  present: readonly string[]\n): string[] {\n  if (!Array.isArray(config)) return [];\n  const have = new Set(present);\n  return config.filter((label) => !have.has(label));\n}\n\n/**\n * Normalize a raw opt value into the accepted shape, collecting human-readable\n * warnings (each bridge routes them to its own logger). Only `boolean` and\n * `string[]` are accepted; anything else falls back to `undefined` (default:\n * all sections collapsible) with a warning.\n */\nexport function normalizeCollapsibleSidebarSections(raw: unknown): {\n  value: CollapsibleSidebarSections | undefined;\n  warnings: string[];\n} {\n  if (raw === undefined) return { value: undefined, warnings: [] };\n  if (typeof raw === 'boolean') return { value: raw, warnings: [] };\n  if (Array.isArray(raw)) {\n    const labels = raw.filter((x): x is string => typeof x === 'string');\n    const warnings =\n      labels.length !== raw.length\n        ? ['collapsibleSidebarSections — ignoring non-string entries in the array.']\n        : [];\n    return { value: labels, warnings };\n  }\n  return {\n    value: undefined,\n    warnings: [\n      `collapsibleSidebarSections must be a boolean or an array of section labels; got ${typeof raw}. Ignoring it (all sections collapsible).`,\n    ],\n  };\n}\n","/**\n * `llms.txt` contract — the resolved config the bridges hand dwar.\n *\n * Lives here (the setu→dwar boundary) rather than in `config/` so\n * `RenderOptions` can reference it without `site/` importing from `config/` —\n * `config/` already imports `site/`, and the reverse would close a module cycle.\n */\nimport type { PageKind } from './page';\n\n/** Resolved `llmsTxt` options — every field defaulted by `validateLlmsTxt`. */\nexport interface LlmsTxtConfig {\n  /** Also emit `llms-full.txt` (every page's Markdown concatenated). */\n  full: boolean;\n  /**\n   * How API-reference pages are treated. `true` lists them with descriptions and\n   * includes their bodies in `llms-full.txt`; `'index'` lists them as a bare\n   * index (no descriptions) and omits their bodies from `llms-full.txt`; `false`\n   * omits them from both files.\n   */\n  api: boolean | 'index';\n}\n\n/**\n * Page kinds that count as API reference — everything setu derives from doclets.\n * `index`/`guide` (home, README, docs, tutorials) and `source` are NOT API.\n */\nexport const API_PAGE_KINDS: readonly PageKind[] = [\n  'class',\n  'module',\n  'namespace',\n  'mixin',\n  'interface',\n  'typedef',\n  'enum',\n  'function',\n  'variable',\n  'global',\n];\n","/**\n * Small formatting helpers shared by the diagnostics output and the build\n * report — human-readable byte sizes, fixed-width column padding, and a tiny\n * ANSI color helper gated on a `color` boolean.\n *\n * Strictly node-free (rang imports utils in the browser): byte sizes use\n * `TextEncoder`, never `Buffer`; there is no `chalk` dependency and no TTY\n * autodetection — the caller decides whether color is on.\n */\n\n/** Shared encoder for measuring UTF-8 byte lengths of strings. */\nconst ENCODER = new TextEncoder();\n\n/**\n * Byte length of a string or `Uint8Array`. Strings are measured as UTF-8 via\n * `TextEncoder` (not `Buffer.byteLength`) so this stays browser-safe.\n */\nexport function byteLength(contents: string | Uint8Array): number {\n  return typeof contents === 'string' ? ENCODER.encode(contents).length : contents.byteLength;\n}\n\n/**\n * Format a raw byte count as a human-readable size — `B` under 1 kB, then `kB`\n * / `MB` / `GB` with one decimal place (decimal/SI units, 1 kB = 1000 B, to\n * match the build-report convention). Negative inputs are clamped to `0`.\n */\nexport function humanFileSize(bytes: number): string {\n  if (!Number.isFinite(bytes) || bytes <= 0) return '0 B';\n\n  const units = ['kB', 'MB', 'GB', 'TB'] as const;\n  if (bytes < 1000) return `${bytes} B`;\n\n  let value = bytes / 1000;\n  let unit = 0;\n  while (value >= 1000 && unit < units.length - 1) {\n    value /= 1000;\n    unit++;\n  }\n  return `${value.toFixed(1)} ${units[unit]}`;\n}\n\n/**\n * Pad `text` to `width` columns (measured in visible characters — assumes the\n * input carries no ANSI escapes, so apply color *after* padding). `align`\n * controls the side: `'left'` (default) right-pads, `'right'` left-pads.\n * Strings already at/over `width` are returned unchanged.\n */\nexport function padColumn(text: string, width: number, align: 'left' | 'right' = 'left'): string {\n  const gap = width - text.length;\n  if (gap <= 0) return text;\n  const pad = ' '.repeat(gap);\n  return align === 'right' ? pad + text : text + pad;\n}\n\n/** SGR codes for the colors the diagnostics + report output use. */\nconst SGR = {\n  red: 31,\n  yellow: 33,\n  green: 32,\n  cyan: 36,\n  gray: 90,\n} as const;\n\n/** Wrap `text` in an SGR pair when `enabled`, else return it untouched. */\nfunction wrap(code: number, text: string, enabled: boolean): string {\n  return enabled ? `\u001b[${code}m${text}\u001b[0m` : text;\n}\n\n/**\n * Tiny ANSI color helper — each method colors `text` only when `enabled` is\n * `true`, so callers thread a single `color` boolean through. No `chalk`\n * dependency; the second arg keeps it a no-op for non-TTY / tests.\n */\nexport const ansi = {\n  red: (text: string, enabled: boolean): string => wrap(SGR.red, text, enabled),\n  yellow: (text: string, enabled: boolean): string => wrap(SGR.yellow, text, enabled),\n  green: (text: string, enabled: boolean): string => wrap(SGR.green, text, enabled),\n  cyan: (text: string, enabled: boolean): string => wrap(SGR.cyan, text, enabled),\n  /** Dimmed/gray — used for codes, paths, and separators. */\n  dim: (text: string, enabled: boolean): string => wrap(SGR.gray, text, enabled),\n};\n","/**\n * Diagnostics model — the shared reporting spine for opts validation. Every\n * field validator collects {@link Diagnostic}s into a {@link DiagnosticBag};\n * the caller decides the policy (log + continue vs. fail on errors), and\n * {@link formatDiagnostics} renders the bag for the console.\n *\n * Pure + node-free (rang imports utils in the browser) — no I/O, no `process`,\n * no color autodetection here. Color is an explicit opt passed by the caller.\n */\n\nimport { ansi } from './format';\n\n/** Severity of a diagnostic. Drives the caller's strict-mode policy. */\nexport type DiagnosticLevel = 'error' | 'warning' | 'info';\n\n/** A single, structured validation finding. */\nexport interface Diagnostic {\n  /** Severity — `error` is the only level a strict build fails on. */\n  level: DiagnosticLevel;\n  /** Stable identifier, e.g. `'opts/unknown-key'` or `'fonts/not-google'`. */\n  code: string;\n  /** What's wrong, in plain language. */\n  message: string;\n  /** What to use instead — the actionable \"reason\" (e.g. \"did you mean X?\"). */\n  hint?: string;\n  /** Opt path the finding applies to, e.g. `'siteName.alt'` or `'fonts.heading'`. */\n  path?: string;\n}\n\n/** Convenience extras for the {@link DiagnosticBag} level helpers. */\ntype DiagnosticExtras = Pick<Diagnostic, 'hint' | 'path'>;\n\n/**\n * An append-only collector of {@link Diagnostic}s. Validators share one bag so\n * the caller gets a single ordered list to format and to gate strict mode on.\n */\nexport class DiagnosticBag {\n  private readonly items: Diagnostic[] = [];\n\n  /** Append a fully-formed diagnostic. */\n  add(d: Diagnostic): void {\n    this.items.push(d);\n  }\n\n  /** Add an `error` — the level a strict build fails on. */\n  error(code: string, message: string, extras?: DiagnosticExtras): void {\n    this.add({ level: 'error', code, message, ...extras });\n  }\n\n  /** Add a `warning` — reported but never fatal (unless strict escalates it). */\n  warning(code: string, message: string, extras?: DiagnosticExtras): void {\n    this.add({ level: 'warning', code, message, ...extras });\n  }\n\n  /** Add an `info` — purely advisory (e.g. \"couldn't verify offline\"). */\n  info(code: string, message: string, extras?: DiagnosticExtras): void {\n    this.add({ level: 'info', code, message, ...extras });\n  }\n\n  /** The diagnostics collected so far, in insertion order. */\n  get list(): readonly Diagnostic[] {\n    return this.items;\n  }\n\n  /** `true` when at least one `error`-level diagnostic was collected. */\n  hasErrors(): boolean {\n    return this.items.some((d) => d.level === 'error');\n  }\n}\n\n/** Console label + color for each level. */\nconst LEVEL_META: Record<DiagnosticLevel, { label: string; color: keyof typeof ansi }> = {\n  error: { label: 'error', color: 'red' },\n  warning: { label: 'warning', color: 'yellow' },\n  info: { label: 'info', color: 'cyan' },\n};\n\n/** Order levels are grouped in the formatted output (most severe first). */\nconst LEVEL_ORDER: readonly DiagnosticLevel[] = ['error', 'warning', 'info'];\n\n/**\n * Format a bag for the console — grouped by level (errors first), each line\n * carrying the code, message, optional path, and a `→` hint. `color` gates the\n * ANSI escapes (default off, so the output is plain/testable); the caller\n * passes `true` only for a real TTY.\n */\nexport function formatDiagnostics(bag: DiagnosticBag, opts?: { color?: boolean }): string {\n  const color = opts?.color ?? false;\n  const lines: string[] = [];\n\n  for (const level of LEVEL_ORDER) {\n    const group = bag.list.filter((d) => d.level === level);\n    if (group.length === 0) continue;\n\n    const meta = LEVEL_META[level];\n    for (const d of group) {\n      const tag = ansi[meta.color](`${meta.label}`, color);\n      const where = d.path ? ` ${ansi.dim(`(${d.path})`, color)}` : '';\n      lines.push(`${tag} ${d.message}${where} ${ansi.dim(`[${d.code}]`, color)}`);\n      if (d.hint) {\n        lines.push(`  ${ansi.dim('→', color)} ${d.hint}`);\n      }\n    }\n  }\n\n  return lines.join('\\n');\n}\n\n/**\n * A new bag holding only the `warning`-level diagnostics of `bag`, in the same\n * order. Lets a bridge re-print just the warnings at the END of a build, where\n * they are actually visible — validation runs before any render work, so its\n * output otherwise scrolls away behind the build log.\n */\nexport function warningsOnly(bag: DiagnosticBag): DiagnosticBag {\n  const out = new DiagnosticBag();\n  for (const d of bag.list) {\n    if (d.level === 'warning') out.add(d);\n  }\n  return out;\n}\n","/**\n * zod schemas for the theme option surface — the recognized `siteName`,\n * `fonts`, `menu`, `copyPage`, `pageNav`, `playground`, `sectionOrder`,\n * `docs`, `docGroups`, `defaultDocGroup`, `clubSidebarItems`, `aiPrompt`, and\n * `basePath` opts the JSDoc bridge accepts.\n *\n * These mirror the theme-relevant subset of `clean-jsdoc-theme`'s `JSDocOpts`\n * and the lenient `normalize*` / `prepareSiteName` helpers in `publish.ts`, but\n * expressed as zod so failures carry a structured `path` + `message`. Object\n * schemas are `.strip()`-style (extra keys are dropped, not rejected) — the\n * unknown-key policy is handled explicitly elsewhere so we control the\n * messaging. Pure + node-free.\n */\n\nimport { z } from 'zod';\n\n// ── siteName ─────────────────────────────────────────────────────────────────\n\n/**\n * A logo image set — mirrors `SiteLogo`. Only `default`/`dark`/`light`/`alt`\n * are recognized; extras are stripped. Each value is a string (URL, `data:`\n * URI, or a local path the bridge copies).\n */\nexport const SiteLogoSchema = z\n  .object({\n    default: z.string().optional(),\n    dark: z.string().optional(),\n    light: z.string().optional(),\n    alt: z.string().optional(),\n  })\n  .strip();\nexport type TSiteLogoOpt = z.infer<typeof SiteLogoSchema>;\n\n/** Recognized sub-keys of a `siteName` logo set, for typo suggestions. */\nexport const SITE_LOGO_KEYS = ['default', 'dark', 'light', 'alt'] as const;\n\n/** `siteName` is plain text OR a logo set (mirrors `SiteName`). */\nexport const SiteNameSchema = z.union([z.string(), SiteLogoSchema]);\nexport type TSiteNameOpt = z.infer<typeof SiteNameSchema>;\n\n// ── fonts ────────────────────────────────────────────────────────────────────\n\n/**\n * Font overrides — `heading`/`body`/`mono`, each optionally prefixed with a\n * locale code (`ja:heading`) to override that locale only. `heading`/`body` are\n * Google Fonts family names (existence-checked later); `mono` is a CSS stack.\n * The `catchall` admits the `<locale>:slot` keys; `validateFonts` does the real\n * shape/slot validation (this schema is declarative — the runtime path uses it\n * for documentation/typing, not parsing).\n */\nexport const FontsSchema = z\n  .object({\n    heading: z.string().optional(),\n    body: z.string().optional(),\n    mono: z.string().optional(),\n  })\n  .catchall(z.string());\nexport type TFontsOpt = z.infer<typeof FontsSchema>;\n\n/** Recognized `fonts` sub-keys, for typo suggestions. */\nexport const FONT_KEYS = ['heading', 'body', 'mono'] as const;\n\n// ── menu ─────────────────────────────────────────────────────────────────────\n\n/**\n * A sidebar menu entry — mirrors setu's `MenuItem` plus the `href` alias the\n * bridge accepts. All fields optional; the bridge keeps only entries with an\n * `id` (built-in) or a link.\n */\nexport const MenuItemSchema = z\n  .object({\n    id: z.string().optional(),\n    title: z.string().optional(),\n    link: z.string().optional(),\n    href: z.string().optional(),\n    icon: z.string().optional(),\n    /** Link `target` attribute (e.g. `_blank`, `_self`). */\n    target: z.string().optional(),\n    /** Extra CSS class(es) merged onto the rendered menu link. */\n    class: z.string().optional(),\n  })\n  .strip();\nexport type TMenuItemOpt = z.infer<typeof MenuItemSchema>;\n\n/** `menu` is an ordered list of {@link MenuItemSchema} entries. */\nexport const MenuSchema = z.array(MenuItemSchema);\n\n// ── copyPage ───────────────────────────────────────────────────────────────\n\n/** Valid copy-page dropdown actions (mirrors `CopyPageAction`). */\nexport const COPY_PAGE_ACTIONS = ['copy', 'view', 'claude', 'chatgpt', 'perplexity'] as const;\n\n/** Copy-page config object — mirrors `CopyPageConfig`. */\nexport const CopyPageConfigSchema = z\n  .object({\n    enabled: z.boolean().optional(),\n    actions: z.array(z.enum(COPY_PAGE_ACTIONS)).optional(),\n  })\n  .strip();\nexport type TCopyPageConfigOpt = z.infer<typeof CopyPageConfigSchema>;\n\n/** `copyPage` is a boolean shorthand OR a config object. */\nexport const CopyPageSchema = z.union([z.boolean(), CopyPageConfigSchema]);\n\n// ── pageNav ──────────────────────────────────────────────────────────────────\n\n/** Prev/next pager config object — mirrors `PageNavConfig`. */\nexport const PageNavConfigSchema = z\n  .object({\n    enabled: z.boolean().optional(),\n  })\n  .strip();\nexport type TPageNavConfigOpt = z.infer<typeof PageNavConfigSchema>;\n\n/** `pageNav` is a boolean shorthand OR a config object. */\nexport const PageNavSchema = z.union([z.boolean(), PageNavConfigSchema]);\n\n// ── playground ───────────────────────────────────────────────────────────────\n\n/** Valid code-playground providers (mirrors `PlaygroundProvider`). */\nexport const PLAYGROUND_PROVIDERS = ['codepen', 'jsfiddle', 'codesandbox'] as const;\n\n/**\n * `playground` config — mirrors `PlaygroundConfig`. `enableForAllExamples` opts\n * every `@example` in; `providers` is the default provider set + order; the\n * per-provider records hold site-wide runtime options. The records are lenient\n * (`z.unknown()` values) so each provider's API can grow without schema churn.\n */\nexport const PlaygroundSchema = z\n  .object({\n    enableForAllExamples: z.boolean().optional(),\n    providers: z.array(z.enum(PLAYGROUND_PROVIDERS)).optional(),\n    codepen: z.record(z.string(), z.unknown()).optional(),\n    jsfiddle: z.record(z.string(), z.unknown()).optional(),\n    codesandbox: z.record(z.string(), z.unknown()).optional(),\n  })\n  .strip();\nexport type TPlaygroundOpt = z.infer<typeof PlaygroundSchema>;\n\n// ── footer ───────────────────────────────────────────────────────────────────\n\n/**\n * Footer file form — `{ file: \"./footer.html\" }`. Modeled as its own object so\n * a later reusable-partial shape (`{ file, css, js }`) is a non-breaking\n * extension; only `file` is recognized today (extras stripped).\n */\nexport const FooterFileSchema = z.object({ file: z.string() }).strip();\nexport type TFooterFileOpt = z.infer<typeof FooterFileSchema>;\n\n/**\n * `footer` is a discriminated union: an inline HTML string (the common case,\n * v4 parity) OR a `{ file }` object the bridge reads from disk. The boundary\n * (`ThemeConfig.footer`) is always the resolved string — the union lives only\n * at the opts/bridge layer.\n */\nexport const FooterSchema = z.union([z.string(), FooterFileSchema]);\nexport type TFooterOpt = z.infer<typeof FooterSchema>;\n\n// ── meta ─────────────────────────────────────────────────────────────────────\n\n/**\n * `meta` is an array of attribute maps — each object's key/value pairs become\n * the attributes of one `<meta>` tag (`{ name, content }`, `{ property, content }`,\n * `{ \"http-equiv\", content }`, `{ charset }`, …). Maximally flexible (v4 parity);\n * dwar escapes the values, validates attribute names, and de-dupes against its\n * own head defaults.\n */\nexport const MetaSchema = z.array(z.record(z.string(), z.string()));\nexport type TMetaOpt = z.infer<typeof MetaSchema>;\n\n// ── simple list / scalar opts ────────────────────────────────────────────────\n\n/** `sectionOrder` / `docGroups` — an ordered list of label strings. */\nexport const StringListSchema = z.array(z.string());\n\n/** `defaultDocGroup` — a single group label. */\nexport const DefaultDocGroupSchema = z.string();\n\n/** `clubSidebarItems` — toggles prefix-grouped sidebar subtrees. */\nexport const ClubSidebarItemsSchema = z.boolean();\n\n/** `collapsibleSidebarSections` — which top-level sidebar sections collapse. */\nexport const CollapsibleSidebarSectionsSchema = z.union([z.boolean(), z.array(z.string())]);\n\n/** `scrollbar` — scrollbar presentation mode. */\nexport const ScrollbarSchema = z.enum(['styled', 'visible', 'native']);\n\n/** `aiPrompt` — a custom copy-page LLM prompt. */\nexport const AiPromptSchema = z.string();\n\n/** `basePath` — site root path the renderer prefixes onto links. */\nexport const BasePathSchema = z.string();\n\n// ── the recognized theme-option surface ──────────────────────────────────────\n\n/**\n * The set of recognized top-level theme option names. The unknown-key policy\n * compares each incoming opt against this set (via Levenshtein) for typo\n * suggestions — keys NOT here and NOT a JSDoc-own opt may earn a \"did you mean\"\n * hint. Mirrors the theme-relevant `JSDocOpts` subset.\n */\nexport const THEME_OPT_KEYS = [\n  'siteName',\n  'fonts',\n  'menu',\n  'copyPage',\n  'pageNav',\n  'playground',\n  'sectionOrder',\n  'docs',\n  'docGroups',\n  'defaultDocGroup',\n  'clubSidebarItems',\n  'collapsibleSidebarSections',\n  'scrollbar',\n  'aiPrompt',\n  'basePath',\n  'siteUrl',\n  'llmsTxt',\n  'favicon',\n  'footer',\n  'meta',\n  'locales',\n  'defaultLocale',\n  'customCss',\n  'customCssFile',\n  'customJs',\n  'customJsFile',\n  'hashCustomAssets',\n  'progress',\n] as const;\n\n/** Union of the recognized theme option key names. */\nexport type ThemeOptKey = (typeof THEME_OPT_KEYS)[number];\n","/**\n * Near-miss key suggestions — a small Levenshtein distance used to turn an\n * unknown opt key into a \"did you mean X?\" hint. Pure + node-free.\n *\n * Used by the unknown-key policy: for a key not in the recognized set, pick the\n * closest known key and, when it's close enough, surface it as a typo hint.\n */\n\n/**\n * Levenshtein edit distance between two strings (insert/delete/substitute, each\n * cost 1). Iterative two-row DP — O(a·b) time, O(min) space. Comparison is\n * case-sensitive; lowercase both sides first if you want it case-insensitive.\n */\nexport function levenshtein(a: string, b: string): number {\n  if (a === b) return 0;\n  if (a.length === 0) return b.length;\n  if (b.length === 0) return a.length;\n\n  // Keep the shorter string as the column axis to bound the row width.\n  if (a.length > b.length) [a, b] = [b, a];\n\n  let prev = Array.from({ length: a.length + 1 }, (_, i) => i);\n  let curr = new Array<number>(a.length + 1);\n\n  for (let j = 1; j <= b.length; j++) {\n    curr[0] = j;\n    for (let i = 1; i <= a.length; i++) {\n      const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n      curr[i] = Math.min(\n        prev[i] + 1, // deletion\n        curr[i - 1] + 1, // insertion\n        prev[i - 1] + cost // substitution\n      );\n    }\n    [prev, curr] = [curr, prev];\n  }\n\n  return prev[a.length];\n}\n\n/**\n * Suggest the closest entry in `candidates` to `input`, or `undefined` when\n * nothing is close enough. Matching is case-insensitive; `maxDistance` (default\n * `2`) is the inclusive edit-distance threshold — a far-off key (no candidate\n * within the threshold) returns `undefined` so we never invent a bad \"did you\n * mean\". Ties resolve to the first candidate at the best distance.\n */\nexport function suggestKey(\n  input: string,\n  candidates: Iterable<string>,\n  maxDistance = 2\n): string | undefined {\n  const needle = input.toLowerCase();\n  let best: string | undefined;\n  let bestDistance = Infinity;\n\n  for (const candidate of candidates) {\n    const distance = levenshtein(needle, candidate.toLowerCase());\n    if (distance < bestDistance) {\n      best = candidate;\n      bestDistance = distance;\n      if (bestDistance === 0) break;\n    }\n  }\n\n  return bestDistance <= maxDistance ? best : undefined;\n}\n","/**\n * `siteName` validation — strict shape checking + diagnostics on top of the\n * lenient resolution `prepareSiteName` does in the bridge. Validation only\n * checks the *shape*; the bridge still does the file-copy I/O for local logo\n * paths. Pure + node-free.\n */\n\nimport type { SiteLogo, SiteName } from '../site/site-name';\nimport type { DiagnosticBag } from './diagnostics';\nimport { SITE_LOGO_KEYS } from './opts-schema';\nimport { suggestKey } from './suggest';\n\n/** Logo sub-keys that carry an image source (vs. the `alt` text label). */\nconst IMAGE_KEYS = ['default', 'dark', 'light'] as const;\n\n/** Build the \"did you mean X?\" tail for an unknown sub-key, when one is close. */\nfunction suggestionHint(key: string): string {\n  const guess = suggestKey(key, SITE_LOGO_KEYS);\n  return guess ? `did you mean \\`${guess}\\`?` : `expected one of: ${SITE_LOGO_KEYS.join(', ')}.`;\n}\n\n/**\n * Validate `raw` (the user's `siteName` opt) into a clean {@link SiteName}, or\n * `undefined` when it carries nothing usable. Collects diagnostics into `bag`:\n *\n * - `string` → trimmed; empty → `undefined` (no diagnostic — an omitted name).\n * - object → only `{ default?, dark?, light?, alt? }` are recognized:\n *   - unknown sub-keys → `warning` + a typo suggestion, then ignored.\n *   - non-string values → `error` + hint, then dropped.\n *   - a set with no image source AND no `alt` → `warning` (nothing to render).\n * - any other type (number/boolean/array/…) → `error`, returns `undefined`.\n */\nexport function validateSiteName(raw: unknown, bag: DiagnosticBag): SiteName | undefined {\n  if (raw == null) return undefined;\n\n  if (typeof raw === 'string') {\n    const trimmed = raw.trim();\n    return trimmed.length > 0 ? trimmed : undefined;\n  }\n\n  if (typeof raw !== 'object' || Array.isArray(raw)) {\n    bag.error('siteName/invalid-type', 'siteName must be a string or a logo set.', {\n      hint: 'use a string (header text) or an object `{ default, dark, light, alt }`.',\n      path: 'siteName',\n    });\n    return undefined;\n  }\n\n  const obj = raw as Record<string, unknown>;\n  const out: SiteLogo = {};\n\n  for (const [key, value] of Object.entries(obj)) {\n    if (!(SITE_LOGO_KEYS as readonly string[]).includes(key)) {\n      bag.warning('siteName/unknown-key', `unknown siteName key \"${key}\"; ignoring.`, {\n        hint: suggestionHint(key),\n        path: `siteName.${key}`,\n      });\n      continue;\n    }\n    if (value == null) continue;\n    if (typeof value !== 'string') {\n      bag.error('siteName/invalid-value', `siteName.${key} must be a string.`, {\n        hint:\n          key === 'alt'\n            ? 'expected a text label.'\n            : 'expected a string path/URL (a local path, `http(s)://`, or `data:` URI).',\n        path: `siteName.${key}`,\n      });\n      continue;\n    }\n    const trimmed = value.trim();\n    if (trimmed.length > 0) out[key as keyof SiteLogo] = trimmed;\n  }\n\n  const hasImage = IMAGE_KEYS.some((k) => out[k]);\n  const hasAlt = typeof out.alt === 'string' && out.alt.length > 0;\n\n  if (!hasImage && !hasAlt) {\n    bag.warning('siteName/empty', 'siteName has no usable image or text; ignoring.', {\n      hint: 'set at least one of `default`/`dark`/`light` (an image) or `alt` (text).',\n      path: 'siteName',\n    });\n    return undefined;\n  }\n\n  return out;\n}\n","/**\n * `fonts` validation — keys must be a subset of `{ heading, body, mono }`,\n * optionally prefixed with a locale code (`ja:heading`, `hi:body`) to override\n * the font for that locale only. `heading`/`body` families (base AND per-locale)\n * are existence-checked against Google Fonts via an injected resolver (`mono` is\n * a local CSS stack, never checked). Pure + node-free: the one networked\n * dependency arrives as the `fontResolver` argument.\n */\n\nimport type { DiagnosticBag } from './diagnostics';\nimport type { FontExistence } from './google-fonts';\nimport { FONT_KEYS } from './opts-schema';\nimport { suggestKey } from './suggest';\n\n/** One font triple — any subset of `{ heading, body, mono }`. */\nexport interface FontSet {\n  heading?: string;\n  body?: string;\n  mono?: string;\n}\n\n/**\n * The validated font overrides. The top-level `heading`/`body`/`mono` are the\n * default (and default-locale) fonts; `locales` carries per-locale overrides\n * (from `<code>:heading`-style keys). A locale that omits a slot falls back to\n * the top-level font, then to the theme default — resolved by the bridge per\n * build (each locale is its own static render).\n */\nexport interface ValidatedFonts extends FontSet {\n  /** Per-locale font overrides, keyed by locale code (e.g. `{ ja: { heading } }`). */\n  locales?: Record<string, FontSet>;\n}\n\n/**\n * Split a fonts key into its optional locale prefix + slot. `heading` →\n * `{ slot: 'heading' }`; `ja:heading` → `{ locale: 'ja', slot: 'heading' }`. A\n * leading `:` (empty locale) is treated as no locale, so the slot check rejects it.\n */\nfunction parseFontKey(key: string): { locale?: string; slot: string } {\n  const colon = key.indexOf(':');\n  if (colon > 0) return { locale: key.slice(0, colon), slot: key.slice(colon + 1) };\n  return { slot: key };\n}\n\n/** Resolver signature — supplied by the bridge (defaults to fail-open offline). */\nexport type FontResolver = (family: string) => Promise<FontExistence>;\n\n/** Keys that name a Google Fonts family (existence-checked); `mono` is excluded. */\nconst GOOGLE_FONT_KEYS = ['heading', 'body'] as const;\n\n/** Build the \"did you mean X?\" tail for an unknown fonts key, when one is close. */\nfunction suggestionHint(key: string): string {\n  const guess = suggestKey(key, FONT_KEYS);\n  return guess ? `did you mean \\`${guess}\\`?` : `expected one of: ${FONT_KEYS.join(', ')}.`;\n}\n\n/**\n * Validate `raw` (the user's `fonts` opt) into a clean {@link ValidatedFonts}.\n * Collects diagnostics into `bag`:\n *\n * - non-object (or array) → `error`, returns `{}`.\n * - keys whose slot is outside `{ heading, body, mono }` → `warning` +\n *   suggestion, ignored. Keys may carry a `<locale>:` prefix (`ja:heading`) to\n *   target one locale; the slot after the prefix is what's checked.\n * - non-string values → `error` + hint, dropped.\n * - for `heading`/`body` slots only (not `mono`), base AND per-locale, `await\n *   fontResolver(name)`:\n *   - `'missing'` → `error` (not a Google Font); the value is still returned so\n *     the bridge can decide to fall back to its default.\n *   - `'unknown'` → `info` (couldn't verify — offline?); used as-is.\n *   - `'exists'` → ok.\n *\n * When no `fontResolver` is supplied the existence check is skipped silently\n * (shape validation still runs).\n */\nexport async function validateFonts(\n  raw: unknown,\n  bag: DiagnosticBag,\n  fontResolver?: FontResolver\n): Promise<ValidatedFonts> {\n  if (raw == null) return {};\n\n  if (typeof raw !== 'object' || Array.isArray(raw)) {\n    bag.error('fonts/invalid-type', 'fonts must be an object.', {\n      hint: 'use `{ heading, body, mono }` (optionally `<locale>:heading`), any subset.',\n      path: 'fonts',\n    });\n    return {};\n  }\n\n  const obj = raw as Record<string, unknown>;\n  const out: ValidatedFonts = {};\n\n  for (const [key, value] of Object.entries(obj)) {\n    const { locale, slot } = parseFontKey(key);\n    if (!(FONT_KEYS as readonly string[]).includes(slot)) {\n      bag.warning('fonts/unknown-key', `unknown fonts key \"${key}\"; ignoring.`, {\n        hint: suggestionHint(slot),\n        path: `fonts.${key}`,\n      });\n      continue;\n    }\n    if (value == null) continue;\n    if (typeof value !== 'string') {\n      bag.error('fonts/invalid-value', `fonts.${key} must be a string.`, {\n        hint:\n          slot === 'mono'\n            ? 'expected a CSS font-family stack.'\n            : 'expected a Google Fonts family name (e.g. \"Roboto\").',\n        path: `fonts.${key}`,\n      });\n      continue;\n    }\n    const trimmed = value.trim();\n    if (trimmed.length === 0) continue;\n    if (locale) {\n      out.locales ??= {};\n      (out.locales[locale] ??= {})[slot as keyof FontSet] = trimmed;\n    } else {\n      out[slot as keyof FontSet] = trimmed;\n    }\n  }\n\n  // Existence-check the Google-Fonts-backed slots (heading/body), base AND\n  // per-locale, when a resolver is available. Done after shape validation so\n  // only clean string values flow in; checks run concurrently (each is\n  // independent) and report against the originating key path (`fonts.ja:heading`).\n  if (fontResolver) {\n    const checks: Array<{ path: string; family: string }> = [];\n    for (const slot of GOOGLE_FONT_KEYS) {\n      if (out[slot]) checks.push({ path: `fonts.${slot}`, family: out[slot] as string });\n    }\n    for (const [locale, set] of Object.entries(out.locales ?? {})) {\n      for (const slot of GOOGLE_FONT_KEYS) {\n        if (set[slot]) checks.push({ path: `fonts.${locale}:${slot}`, family: set[slot] as string });\n      }\n    }\n    await Promise.all(\n      checks.map(async ({ path, family }) => {\n        const verdict = await fontResolver(family);\n        if (verdict === 'missing') {\n          bag.error(\n            'fonts/not-google',\n            `Font \"${family}\" is not a Google Font; falling back to the default.`,\n            {\n              hint: 'pick a family from https://fonts.google.com.',\n              path,\n            }\n          );\n        } else if (verdict === 'unknown') {\n          bag.info('fonts/unverified', `couldn't verify \"${family}\" (offline?); using it as-is.`, {\n            path,\n          });\n        }\n      })\n    );\n  }\n\n  return out;\n}\n","/**\n * Locale-config validation (`opts.locales` + `opts.defaultLocale`) — the single\n * config source for localization (the plan's decision 7: \"Locales are declared\n * in jsdoc opts … validated through utils like every other opt\").\n *\n * Posture mirrors the rest of opts validation (§5): a malformation is an error,\n * a soft issue is a warning. Pure + node-free.\n */\n\nimport type { DiagnosticBag } from './diagnostics';\n\n/** One configured locale: its code and an optional display name for the switcher. */\nexport interface LocaleConfig {\n  /** Locale code, e.g. `'en'`, `'fr'`, `'pt-BR'`. */\n  code: string;\n  /** Display label for the language switcher (defaults to the code if unset). */\n  name?: string;\n}\n\n/** Normalized locale configuration — the default is always present in `locales`. */\nexport interface ValidatedLocales {\n  /** All configured locales, in declaration order (includes the default). */\n  locales: LocaleConfig[];\n  /** The default locale's code — rendered unprefixed; every page must exist in it. */\n  defaultLocale: string;\n}\n\n/** A locale code is non-empty and BCP-47-ish: letters/digits + `-` separators. */\nconst LOCALE_CODE_RE = /^[A-Za-z0-9]+(-[A-Za-z0-9]+)*$/;\n\n/**\n * Validate `opts.locales` + `opts.defaultLocale` into a {@link ValidatedLocales},\n * or `undefined` when localization is off (no `locales`). Collects diagnostics:\n *\n * - `locales` absent/empty → `undefined` (localization disabled; no diagnostic).\n * - a non-array `locales`, or an entry that is neither a non-empty string nor a\n *   `{ code }` object, or a malformed/duplicate code → `error` (dropped).\n * - `defaultLocale` set but not among `locales` → `error` (falls back to the\n *   first locale). `defaultLocale` unset → defaults to the first locale (`info`).\n */\nexport function validateLocales(\n  localesRaw: unknown,\n  defaultLocaleRaw: unknown,\n  bag: DiagnosticBag\n): ValidatedLocales | undefined {\n  if (localesRaw == null) return undefined;\n\n  if (!Array.isArray(localesRaw)) {\n    bag.error('locales/invalid-type', 'locales must be an array of locale codes or objects.', {\n      hint: \"e.g. `['en', 'fr']` or `[{ code: 'en', name: 'English' }]`.\",\n      path: 'locales',\n    });\n    return undefined;\n  }\n\n  const locales: LocaleConfig[] = [];\n  const seen = new Set<string>();\n\n  localesRaw.forEach((entry, i) => {\n    let code: string | undefined;\n    let name: string | undefined;\n\n    if (typeof entry === 'string') {\n      code = entry.trim();\n    } else if (entry && typeof entry === 'object' && !Array.isArray(entry)) {\n      const obj = entry as Record<string, unknown>;\n      if (typeof obj.code === 'string') code = obj.code.trim();\n      if (typeof obj.name === 'string' && obj.name.trim()) name = obj.name.trim();\n    } else {\n      bag.error('locales/invalid-entry', `locales[${i}] must be a string or a { code } object.`, {\n        path: `locales.${i}`,\n      });\n      return;\n    }\n\n    if (!code) {\n      bag.error('locales/empty-code', `locales[${i}] has no locale code.`, {\n        hint: \"e.g. 'fr' or { code: 'fr' }.\",\n        path: `locales.${i}`,\n      });\n      return;\n    }\n    if (!LOCALE_CODE_RE.test(code)) {\n      bag.error('locales/invalid-code', `invalid locale code \"${code}\".`, {\n        hint: 'use a BCP-47-style code: letters/digits, hyphen-separated (e.g. `pt-BR`).',\n        path: `locales.${i}`,\n      });\n      return;\n    }\n    if (seen.has(code)) {\n      bag.error('locales/duplicate', `duplicate locale \"${code}\".`, { path: `locales.${i}` });\n      return;\n    }\n\n    seen.add(code);\n    locales.push(name ? { code, name } : { code });\n  });\n\n  if (locales.length === 0) return undefined;\n\n  // Resolve the default locale. Must be one of the configured locales.\n  let defaultLocale = typeof defaultLocaleRaw === 'string' ? defaultLocaleRaw.trim() : '';\n  if (defaultLocale && !seen.has(defaultLocale)) {\n    bag.error('locales/default-not-listed', `defaultLocale \"${defaultLocale}\" is not in locales.`, {\n      hint: `add it to locales, or pick one of: ${locales.map((l) => l.code).join(', ')}.`,\n      path: 'defaultLocale',\n    });\n    defaultLocale = '';\n  }\n  if (!defaultLocale) {\n    defaultLocale = locales[0].code;\n    if (defaultLocaleRaw == null) {\n      // Unset → implied default (advisory).\n      bag.info('locales/default-implied', `defaultLocale defaults to \"${defaultLocale}\".`, {\n        hint: 'set `defaultLocale` to choose the unprefixed locale explicitly.',\n        path: 'defaultLocale',\n      });\n    } else if (typeof defaultLocaleRaw !== 'string' || defaultLocaleRaw.trim() === '') {\n      // Set but unusable (non-string or blank) — distinct from a listed-but-unknown\n      // code, which already errored above. Warn so the silent fallback is visible.\n      bag.warning(\n        'locales/default-ignored',\n        `defaultLocale is not a usable code; using \"${defaultLocale}\".`,\n        {\n          hint: 'set `defaultLocale` to one of the configured locale codes.',\n          path: 'defaultLocale',\n        }\n      );\n    }\n  }\n\n  return { locales, defaultLocale };\n}\n","/**\n * Google Fonts existence resolver — the ONLY networked piece of the config\n * surface, kept behind an injectable so `@clean-jsdoc-theme/utils` stays pure\n * and browser-safe. Nothing here imports `node:*` / `fs` / `Buffer`; it relies\n * only on the globals `fetch` and `AbortController` (present in Node 18+ and\n * every browser).\n *\n * The check is **fail-open**: a real `'missing'` answer needs a definitive\n * `400` from the CSS endpoint; anything ambiguous (network error, timeout, an\n * unexpected status) resolves to `'unknown'` so an offline build never breaks.\n */\n\n/** The verdict for a single font family. */\nexport type FontExistence = 'exists' | 'missing' | 'unknown';\n\n/** Minimal slice of the `fetch` contract the resolver depends on. */\nexport type FetchLike = (\n  url: string,\n  init?: { signal?: AbortSignal; headers?: Record<string, string> }\n) => Promise<{ status: number }>;\n\n/** Options for {@link createGoogleFontResolver}. All are injectable for tests. */\nexport interface GoogleFontResolverOptions {\n  /** `fetch` implementation. Defaults to the global `fetch`. */\n  fetch?: FetchLike;\n  /** Per-request timeout in milliseconds (via `AbortController`). Default `3000`. */\n  timeoutMs?: number;\n  /**\n   * In-memory cache keyed by family name, so heading/body dedupe and repeat\n   * builds within a process never refetch. Defaults to a fresh `Map`; inject\n   * one to share or inspect it.\n   */\n  cache?: Map<string, FontExistence>;\n}\n\n/**\n * The Google Fonts CSS endpoint. A `GET` for an existing family returns `200`;\n * a non-existent family returns `400` (verified: `Roboto`/`Spline Sans` → 200,\n * `NotARealFontXyz123` → 400). Spaces are encoded as `+` per the endpoint's\n * query convention.\n */\nconst CSS_ENDPOINT = 'https://fonts.googleapis.com/css?family=';\n\n/** Desktop UA — the endpoint is UA-tolerant, but be safe. */\nconst USER_AGENT =\n  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' +\n  '(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';\n\n/** Build the CSS-endpoint URL for a family (`%20` → `+`). */\nfunction fontUrl(family: string): string {\n  return CSS_ENDPOINT + encodeURIComponent(family).replace(/%20/g, '+');\n}\n\n/**\n * Create a resolver `(family) => Promise<'exists'|'missing'|'unknown'>` backed\n * by the Google Fonts CSS endpoint. Results are cached per family for the life\n * of the resolver (one network round-trip per distinct family).\n *\n * Mapping: `200` → `'exists'`, `400` → `'missing'`, everything else (other\n * status, thrown error, abort/timeout) → `'unknown'` (**fail-open**).\n */\nexport function createGoogleFontResolver(\n  options: GoogleFontResolverOptions = {}\n): (family: string) => Promise<FontExistence> {\n  const doFetch = options.fetch ?? (globalThis.fetch as unknown as FetchLike | undefined);\n  const timeoutMs = options.timeoutMs ?? 3000;\n  const cache = options.cache ?? new Map<string, FontExistence>();\n\n  return async function resolve(family: string): Promise<FontExistence> {\n    const name = family.trim();\n    if (name.length === 0) return 'unknown';\n\n    const cached = cache.get(name);\n    if (cached !== undefined) return cached;\n\n    // No fetch available (e.g. an old runtime) — fail open, but don't cache the\n    // non-answer so a later environment with `fetch` can still try.\n    if (typeof doFetch !== 'function') return 'unknown';\n\n    const controller = new AbortController();\n    const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n    let verdict: FontExistence;\n    try {\n      const res = await doFetch(fontUrl(name), {\n        signal: controller.signal,\n        headers: { 'User-Agent': USER_AGENT },\n      });\n      if (res.status === 200) verdict = 'exists';\n      else if (res.status === 400) verdict = 'missing';\n      else verdict = 'unknown';\n    } catch {\n      // Network error, abort, or timeout — fail open.\n      verdict = 'unknown';\n    } finally {\n      clearTimeout(timer);\n    }\n\n    cache.set(name, verdict);\n    return verdict;\n  };\n}\n","/**\n * `llmsTxt` option validation — the union parse, the defaults, and the one\n * warning that matters: enabled but no usable site URL, so the file can't be\n * generated. Resilient by design (a `warning`, never a throw); `strict`\n * escalates it like every other diagnostic.\n *\n * Pure + node-free.\n */\nimport { z } from 'zod';\nimport type { LlmsTxtConfig } from '../site/llms';\nimport type { DiagnosticBag } from './diagnostics';\n\n/** `llmsTxt` object form — both fields optional, defaulted by the validator. */\nexport const LlmsTxtConfigSchema = z.object({\n  full: z.boolean().optional(),\n  api: z.union([z.boolean(), z.literal('index')]).optional(),\n});\n\n/** `llmsTxt` is a boolean shorthand OR a config object. */\nexport const LlmsTxtSchema = z.union([z.boolean(), LlmsTxtConfigSchema]);\n\n/**\n * Resolve the `llmsTxt` opt. Returns `undefined` (feature off) when unset,\n * `false`, or malformed — and when `siteUrl` isn't usable, which warns, because\n * the author asked for a file they would otherwise never receive.\n */\nexport function validateLlmsTxt(\n  raw: unknown,\n  siteUrl: string | undefined,\n  bag: DiagnosticBag\n): LlmsTxtConfig | undefined {\n  if (raw === undefined || raw === null) return undefined;\n\n  const parsed = LlmsTxtSchema.safeParse(raw);\n  if (!parsed.success) {\n    bag.warning('llms-txt/invalid', 'llmsTxt must be `true`/`false` or `{ full?, api? }`.', {\n      hint: \"`full` is a boolean; `api` accepts `true`, `false`, or `'index'`.\",\n      path: 'llmsTxt',\n    });\n    return undefined;\n  }\n\n  if (parsed.data === false) return undefined;\n  const cfg = parsed.data === true ? {} : parsed.data;\n\n  if (!siteUrl) {\n    bag.warning(\n      'llms-txt/no-site-url',\n      'llmsTxt is enabled but no usable site URL is configured — llms.txt will NOT be generated.',\n      {\n        hint: 'set `siteUrl` to the published docs URL (e.g. `https://example.com/docs`); llms.txt needs absolute links.',\n        path: 'llmsTxt',\n      }\n    );\n    return undefined;\n  }\n\n  return { full: cfg.full ?? true, api: cfg.api ?? true };\n}\n","/**\n * Site-URL validation — the single place that decides whether a configured\n * public URL is usable for absolute-link output (`sitemap.xml`, `llms.txt`).\n *\n * Contract (unchanged from dwar's sitemap): only the URL's **origin** is used;\n * the deploy sub-path comes from `basePath`. A URL that carries a path while\n * `basePath` is unset is therefore silently losing that path — we warn, because\n * it produces wrong-but-plausible links.\n *\n * Pure + node-free.\n */\nimport type { DiagnosticBag } from './diagnostics';\n\n/**\n * The absolute `http(s)` origin of `value`, or `null` when `value` isn't an\n * absolute http(s) URL. (`new URL('mailto:x').origin` yields the *string*\n * `'null'`, hence the explicit guard.)\n */\nexport function httpOrigin(value: string): string | null {\n  let origin: string;\n  try {\n    origin = new URL(value).origin;\n  } catch {\n    return null;\n  }\n  if (!origin || origin === 'null' || !/^https?:\\/\\//i.test(origin)) return null;\n  return origin;\n}\n\n/** `true` when `raw` is a meaningful (non-root) base path. */\nfunction basePathIsSet(raw: unknown): boolean {\n  if (typeof raw !== 'string') return false;\n  const trimmed = raw.trim();\n  return trimmed !== '' && trimmed !== '/';\n}\n\n/**\n * Validate the `siteUrl` opt. Returns the trimmed URL when it's usable, else\n * `undefined` (with a `warning` — never fatal; `strict` escalates). `rawBasePath`\n * is the un-normalized `basePath` opt, used only to decide whether a dropped URL\n * path is worth warning about.\n */\nexport function validateSiteUrl(\n  raw: unknown,\n  rawBasePath: unknown,\n  bag: DiagnosticBag\n): string | undefined {\n  if (raw === undefined || raw === null) return undefined;\n\n  if (typeof raw !== 'string' || raw.trim() === '') {\n    bag.warning('site-url/invalid', 'siteUrl must be a non-empty string.', {\n      hint: 'use an absolute URL, e.g. `https://example.com`.',\n      path: 'siteUrl',\n    });\n    return undefined;\n  }\n\n  const trimmed = raw.trim();\n  if (!httpOrigin(trimmed)) {\n    bag.warning('site-url/invalid', `siteUrl \"${trimmed}\" is not an absolute http(s) URL.`, {\n      hint: 'use an absolute URL, e.g. `https://example.com`.',\n      path: 'siteUrl',\n    });\n    return undefined;\n  }\n\n  const { pathname } = new URL(trimmed);\n  if (pathname !== '' && pathname !== '/' && !basePathIsSet(rawBasePath)) {\n    const suggestion = pathname.replace(/\\/+$/, '');\n    bag.warning(\n      'site-url/path-ignored',\n      `siteUrl path \"${pathname}\" is ignored — the deploy sub-path comes from \\`basePath\\`.`,\n      {\n        hint: `set \\`basePath: \"${suggestion}\"\\` so emitted URLs include it.`,\n        path: 'siteUrl',\n      }\n    );\n  }\n\n  return trimmed;\n}\n","/**\n * Orchestrator — runs every field validator into a single {@link DiagnosticBag}\n * and returns clean, normalized option values for the bridge. This replaces the\n * scattered `normalize*` / `prepareSiteName` shape-checks: the bridge makes one\n * `validateThemeOpts` call, logs the bag, then (in strict mode) fails on errors.\n *\n * Pure + node-free. The only networked dependency — Google Fonts existence —\n * arrives as the optional `fontResolver`; without it, font checks are skipped\n * gracefully and the build proceeds.\n */\n\nimport type { LlmsTxtConfig } from '../site/llms';\nimport type { SiteName } from '../site/site-name';\nimport { DiagnosticBag } from './diagnostics';\nimport { validateFonts, type FontResolver, type ValidatedFonts } from './fonts';\nimport { validateLocales, type ValidatedLocales } from './locales';\nimport { THEME_OPT_KEYS } from './opts-schema';\nimport { validateLlmsTxt } from './llms-txt';\nimport { validateSiteName } from './site-name';\nimport { validateSiteUrl } from './site-url';\nimport { suggestKey } from './suggest';\n\n/** How `validateThemeOpts` treats keys not in {@link THEME_OPT_KEYS}. */\nexport type UnknownKeyPolicy = 'suggest-typos' | 'warn-all' | 'ignore';\n\n/** Input to {@link validateThemeOpts}. */\nexport interface ValidateThemeOptsInput {\n  /** Raw opts (JSDoc's flat `env.opts`, or a namespaced typedoc block). */\n  opts: Record<string, unknown>;\n  /**\n   * Google Fonts existence resolver (see `createGoogleFontResolver`). Omit to\n   * skip the live `heading`/`body` check (shape validation still runs).\n   */\n  fontResolver?: FontResolver;\n  /**\n   * Unknown-key handling. `'suggest-typos'` (default) only flags keys within an\n   * edit-distance of a known theme key — safe for JSDoc's shared flat namespace.\n   * `'warn-all'` flags every unrecognized key — for a dedicated namespaced block.\n   * `'ignore'` flags nothing.\n   */\n  unknownKeyPolicy?: UnknownKeyPolicy;\n  /**\n   * Keys that are valid in this namespace but aren't theme opts (e.g. JSDoc's\n   * own `destination`/`template`/…). Never flagged, regardless of policy.\n   */\n  knownNonThemeKeys?: ReadonlySet<string>;\n}\n\n/**\n * Clean, defaulted values for the bridge to consume directly. Only the keys\n * Phase 2 validates richly (`siteName`, `fonts`) are reshaped; the rest pass\n * through after the bridge's own `normalize*` step (Phase 4 folds those in).\n * `undefined` means \"fall back to the theme default for this key\".\n */\nexport interface NormalizedThemeOpts {\n  /** Validated site identity (text or logo set), or `undefined` if unusable/omitted. */\n  siteName: SiteName | undefined;\n  /** Validated font overrides — a subset of `{ heading, body, mono }`. */\n  fonts: ValidatedFonts;\n  /** Validated locale config, or `undefined` when localization is off. */\n  locales: ValidatedLocales | undefined;\n  /** Validated public site URL, or `undefined` when unset/unusable. */\n  siteUrl: string | undefined;\n  /** Resolved `llmsTxt` config, or `undefined` when the feature is off. */\n  llmsTxt: LlmsTxtConfig | undefined;\n}\n\n/** Result of {@link validateThemeOpts}. */\nexport interface ValidateThemeOptsResult {\n  /** Normalized, defaulted values for the bridge. */\n  value: NormalizedThemeOpts;\n  /** Every finding from every validator, in one ordered bag. */\n  diagnostics: DiagnosticBag;\n}\n\n/**\n * Apply the unknown-key policy: for each opt key that is neither a recognized\n * theme key nor a declared non-theme key, emit a `warning`. `'suggest-typos'`\n * only warns when the key is a near-miss of a known theme key (and attaches the\n * \"did you mean\" hint); `'warn-all'` warns on every leftover; `'ignore'` skips.\n */\nfunction checkUnknownKeys(\n  opts: Record<string, unknown>,\n  bag: DiagnosticBag,\n  policy: UnknownKeyPolicy,\n  knownNonThemeKeys: ReadonlySet<string>\n): void {\n  if (policy === 'ignore') return;\n\n  const themeKeys = new Set<string>(THEME_OPT_KEYS);\n  for (const key of Object.keys(opts)) {\n    if (themeKeys.has(key) || knownNonThemeKeys.has(key)) continue;\n\n    if (policy === 'warn-all') {\n      const guess = suggestKey(key, THEME_OPT_KEYS);\n      bag.warning('opts/unknown-key', `unknown option \"${key}\".`, {\n        ...(guess ? { hint: `did you mean \\`${guess}\\`?` } : {}),\n        path: key,\n      });\n      continue;\n    }\n\n    // 'suggest-typos': only flag keys close enough to a known theme key.\n    const guess = suggestKey(key, THEME_OPT_KEYS);\n    if (guess) {\n      bag.warning('opts/unknown-key', `unknown option \"${key}\".`, {\n        hint: `did you mean \\`${guess}\\`?`,\n        path: key,\n      });\n    }\n  }\n}\n\n/**\n * Validate a raw opts object. Runs `siteName` + `fonts` validators (the latter\n * does the async Google Fonts check when a resolver is supplied) and the\n * unknown-key policy, all into one bag, then returns normalized values. Never\n * throws — strict-mode enforcement is the caller's job via\n * `result.diagnostics.hasErrors()`.\n */\nexport async function validateThemeOpts(\n  input: ValidateThemeOptsInput\n): Promise<ValidateThemeOptsResult> {\n  const { opts, fontResolver } = input;\n  const policy = input.unknownKeyPolicy ?? 'suggest-typos';\n  const knownNonThemeKeys = input.knownNonThemeKeys ?? new Set<string>();\n\n  const diagnostics = new DiagnosticBag();\n\n  const siteName = validateSiteName(opts.siteName, diagnostics);\n  const fonts = await validateFonts(opts.fonts, diagnostics, fontResolver);\n  const locales = validateLocales(opts.locales, opts.defaultLocale, diagnostics);\n  // siteUrl feeds both sitemap.xml and llms.txt; llmsTxt needs it to be usable.\n  const siteUrl = validateSiteUrl(opts.siteUrl, opts.basePath, diagnostics);\n  const llmsTxt = validateLlmsTxt(opts.llmsTxt, siteUrl, diagnostics);\n\n  checkUnknownKeys(opts, diagnostics, policy, knownNonThemeKeys);\n\n  return { value: { siteName, fonts, locales, siteUrl, llmsTxt }, diagnostics };\n}\n","/**\n * Next.js-style build report — given the emitted {@link OutputFile}s plus the\n * render {@link RenderResult.stats}, render a console summary: a header (where\n * + page/asset counts + optional duration), a per-route table sorted by route\n * (size + optional gzip), an assets section, and a totals footer.\n *\n * Pure + synchronous + node-free (rang imports utils in the browser): byte\n * sizes come from {@link byteLength} (`TextEncoder`, never `Buffer`); gzip is\n * never imported, only the optional `gzipSizer` injected by the caller. Output\n * is deterministic for a given input.\n */\n\nimport type { OutputFile, RenderResult } from '../site/render';\nimport { ansi, byteLength, humanFileSize, padColumn } from './format';\n\n/** Input to {@link formatBuildReport}. */\nexport interface BuildReportInput {\n  /** Files emitted by the render (plus any extra written files, e.g. logos). */\n  files: OutputFile[];\n  /** Render stats — supplies the `built in …` duration when present. */\n  stats?: RenderResult['stats'];\n  /** Absolute or display path the files were written to — the \"where\". */\n  destination: string;\n  /**\n   * Optional gzip sizer (e.g. `(b) => zlib.gzipSync(b).length`). Injected by\n   * the caller so utils stays node-free; the gzip column appears only when set.\n   */\n  gzipSizer?: (bytes: Uint8Array | string) => number;\n  /** Whether to emit ANSI color. Default `false` (plain/testable). */\n  color?: boolean;\n  /**\n   * Cap the per-route table at the N largest routes, adding a `+N more pages`\n   * line for the remainder (never silently truncated). Omit to list every\n   * route (the recommended default).\n   */\n  maxRoutes?: number;\n}\n\n/** A classified HTML page row. */\ninterface PageRow {\n  /** Route the page serves, e.g. `/` or `/module/userservice`. */\n  route: string;\n  /** UTF-8 byte length of the page contents. */\n  size: number;\n  /** Gzipped byte length, when a `gzipSizer` was provided. */\n  gzip?: number;\n}\n\n/** A classified asset row. */\ninterface AssetRow {\n  /** Output path of the asset, e.g. `_assets/styles.<id>.css`. */\n  path: string;\n  size: number;\n  gzip?: number;\n}\n\n/** Files split into the three reported buckets, with running byte totals. */\ninterface Classified {\n  pages: PageRow[];\n  /** Companion Markdown files (`*.md`). */\n  markdownBytes: number;\n  assets: AssetRow[];\n  htmlBytes: number;\n  assetBytes: number;\n}\n\n/**\n * Turn an HTML page path into its route: strip a trailing `index.html`, drop\n * the leading/trailing slashes, then re-add a single leading slash. The root\n * `index.html` (or empty) becomes `/`.\n */\nfunction routeFor(path: string): string {\n  const trimmed = path.replace(/\\/?index\\.html$/i, '').replace(/^\\/+|\\/+$/g, '');\n  return trimmed === '' ? '/' : `/${trimmed}`;\n}\n\n/** `true` for files under `_assets`/`_islands` or with an image extension. */\nfunction isAsset(path: string): boolean {\n  return (\n    /(^|\\/)_(assets|islands)\\//.test(path) ||\n    /\\.(png|jpe?g|gif|svg|webp|avif|ico|woff2?|ttf|otf|eot)$/i.test(path)\n  );\n}\n\n/**\n * Split the files into pages / markdown / assets, summing bytes per bucket.\n * Order: assets first (covers `_assets/*.html` etc.), then `*.html` pages,\n * then `*.md` companions; anything else falls through to assets so its bytes\n * are still accounted for in the total.\n */\nfunction classify(input: BuildReportInput): Classified {\n  const { files, gzipSizer } = input;\n  const sizeGzip = (contents: string | Uint8Array): number | undefined =>\n    gzipSizer ? gzipSizer(contents) : undefined;\n\n  const pages: PageRow[] = [];\n  const assets: AssetRow[] = [];\n  let markdownBytes = 0;\n  let htmlBytes = 0;\n  let assetBytes = 0;\n\n  for (const file of files) {\n    const size = byteLength(file.contents);\n\n    if (isAsset(file.path)) {\n      assets.push({ path: file.path, size, gzip: sizeGzip(file.contents) });\n      assetBytes += size;\n    } else if (/\\.html$/i.test(file.path)) {\n      pages.push({ route: routeFor(file.path), size, gzip: sizeGzip(file.contents) });\n      htmlBytes += size;\n    } else if (/\\.md$/i.test(file.path)) {\n      markdownBytes += size;\n    } else {\n      assets.push({ path: file.path, size, gzip: sizeGzip(file.contents) });\n      assetBytes += size;\n    }\n  }\n\n  return { pages, markdownBytes, assets, htmlBytes, assetBytes };\n}\n\n/** Render one `label  size  (gzip)` row, padded to the shared column widths. */\nfunction renderRow(\n  label: string,\n  size: number,\n  gzip: number | undefined,\n  widths: { label: number; size: number; gzip: number },\n  color: boolean\n): string {\n  const sizeCell = padColumn(humanFileSize(size), widths.size, 'right');\n  const cells = `${padColumn(label, widths.label)}  ${ansi.cyan(sizeCell, color)}`;\n  if (gzip === undefined) return `  ${cells}`;\n  const gzipCell = padColumn(humanFileSize(gzip), widths.gzip, 'right');\n  return `  ${cells}  ${ansi.dim(gzipCell, color)}`;\n}\n\n/**\n * Render the Next.js-style build report as a single string. Routes are sorted\n * alphabetically by default; when `maxRoutes` is set, the N largest routes are\n * shown (sorted by route) followed by a `+N more pages` line.\n */\nexport function formatBuildReport(input: BuildReportInput): string {\n  const { stats, destination, gzipSizer, maxRoutes } = input;\n  const color = input.color ?? false;\n  const withGzip = gzipSizer !== undefined;\n\n  const { pages, markdownBytes, assets, htmlBytes, assetBytes } = classify(input);\n\n  // Pick the rows shown: optionally the N largest, otherwise every page.\n  let shownPages = [...pages];\n  let hiddenCount = 0;\n  if (maxRoutes !== undefined && pages.length > maxRoutes) {\n    shownPages = [...pages].sort((a, b) => b.size - a.size).slice(0, maxRoutes);\n    hiddenCount = pages.length - maxRoutes;\n  }\n  shownPages.sort((a, b) => a.route.localeCompare(b.route));\n\n  // Column widths span both the route table and the assets section so the\n  // size/gzip columns line up across the whole report.\n  const labels = ['Route', ...shownPages.map((p) => p.route), ...assets.map((a) => a.path)];\n  const sizeStrings = [\n    ...shownPages.map((p) => humanFileSize(p.size)),\n    ...assets.map((a) => humanFileSize(a.size)),\n  ];\n  const gzipStrings = withGzip\n    ? [\n        ...shownPages.map((p) => humanFileSize(p.gzip ?? 0)),\n        ...assets.map((a) => humanFileSize(a.gzip ?? 0)),\n      ]\n    : [];\n  const widths = {\n    label: Math.max(...labels.map((l) => l.length)),\n    size: Math.max('Size'.length, ...sizeStrings.map((s) => s.length)),\n    gzip: Math.max('(gzip)'.length, ...gzipStrings.map((s) => s.length), 0),\n  };\n\n  const ruleWidth = 2 + widths.label + 2 + widths.size + (withGzip ? 2 + widths.gzip : 0);\n  const rule = ansi.dim('─'.repeat(ruleWidth), color);\n\n  const lines: string[] = [];\n\n  // Header: title (+ duration), then the destination + counts.\n  const pageCount = stats?.pageCount ?? pages.length;\n  const assetCount = stats?.assetCount ?? assets.length;\n  const duration =\n    stats && Number.isFinite(stats.durationMs)\n      ? ` in ${(stats.durationMs / 1000).toFixed(2)}s`\n      : '';\n  lines.push(ansi.green(`clean-jsdoc-theme — build complete${duration}`, color));\n  lines.push(\n    `Output: ${ansi.cyan(destination, color)}  (${pageCount} pages, ${assetCount} assets)`\n  );\n  lines.push('');\n\n  // Per-route table header.\n  const headerLabel = padColumn('Route', widths.label);\n  const headerSize = padColumn('Size', widths.size, 'right');\n  const header = withGzip\n    ? `  ${headerLabel}  ${headerSize}  ${padColumn('(gzip)', widths.gzip, 'right')}`\n    : `  ${headerLabel}  ${headerSize}`;\n  lines.push(ansi.dim(header, color));\n  lines.push(rule);\n\n  for (const page of shownPages) {\n    lines.push(renderRow(page.route, page.size, page.gzip, widths, color));\n  }\n  if (hiddenCount > 0) {\n    lines.push(`  ${ansi.dim(`+${hiddenCount} more pages`, color)}`);\n  }\n\n  // Assets section.\n  lines.push(rule);\n  lines.push(`  ${ansi.dim('Assets', color)}`);\n  for (const asset of assets) {\n    lines.push(renderRow(asset.path, asset.size, asset.gzip, widths, color));\n  }\n\n  // Totals footer.\n  const total = htmlBytes + markdownBytes + assetBytes;\n  lines.push(rule);\n  lines.push(\n    `  HTML ${humanFileSize(htmlBytes)} · Markdown ${humanFileSize(\n      markdownBytes\n    )} · Assets ${humanFileSize(assetBytes)} · Total ${humanFileSize(total)}`\n  );\n\n  return lines.join('\\n');\n}\n","/**\n * Normalize the `scrollbar` opt into a {@link ScrollbarMode}. Pure and\n * dependency-free — both bridges call it and route the warnings to their own\n * logger. An unrecognized value falls back to `undefined` (dwar then defaults\n * to `styled`) with a warning.\n */\n\nimport type { ScrollbarMode } from '../site/theme';\n\nconst SCROLLBAR_MODES: readonly ScrollbarMode[] = ['styled', 'visible', 'native'];\n\nexport function normalizeScrollbar(raw: unknown): {\n  value: ScrollbarMode | undefined;\n  warnings: string[];\n} {\n  if (raw === undefined) return { value: undefined, warnings: [] };\n  if (typeof raw === 'string' && (SCROLLBAR_MODES as readonly string[]).includes(raw)) {\n    return { value: raw as ScrollbarMode, warnings: [] };\n  }\n  return {\n    value: undefined,\n    warnings: [\n      `scrollbar must be one of ${SCROLLBAR_MODES.map((m) => `\"${m}\"`).join(', ')}; ` +\n        `got ${JSON.stringify(raw)}. Ignoring it (using \"styled\").`,\n    ],\n  };\n}\n"],"mappings":"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"}