import { H as SeoConfiguration, x as BreadcrumbCrumb, z as ReviewSource, F as FaqSource, y as BlogMeta, T as ResolvedPageSeo, N as SeoSchemaConfig, G as GlobalSeoConfig, L as SeoOpenGraphConfig, M as SeoTwitterConfig } from './vitepressTransform-CZ_IB3dq.js'; /** * Framework-agnostic SEO head-tag resolution. * * This module is the single source of truth for turning a * (`pageSlug`, `pagePath`, `SeoConfiguration`) triple into a plain, * serialisable description of the `` tags a page should carry: * resolved title, meta[], link[], and JSON-LD script[]. * * It is consumed by: * - `useSEO` (runtime, via `@unhead/vue`) — see `../composables/useSEO.ts` * - `dcsSeoPlugin`'s build-time static-HTML emitter — see * `../plugins/dcsSeoPlugin.ts` * * Keeping the resolution here (rather than inside the Vue composable) means * the runtime and the build-time emitter produce byte-identical tags from the * same `seo.yaml`, with no Vue/unhead dependency required at build time. * * Runtime behaviour is intentionally identical to the previous in-composable * logic **except** for one corrected bug: `og:title` now falls back to the * fully-resolved (template-applied) page title instead of the raw, untemplated * `page.title`. Previously `og:title` could diverge from the `` element * (e.g. `<title>Iron Oak Contractors | Our Services` but * `og:title = "Our Services"`). */ /** A `` tag — either a `name=`/`content=` or `property=`/`content=` pair. */ interface HeadMetaTag { name?: string; property?: string; content: string; } /** A `` tag (canonical, alternate, etc.). */ interface HeadLinkTag { rel: string; href: string; hreflang?: string; } /** A `` could * break out of the script and inject markup (stored XSS). * * Per OWASP "JSON in an HTML context", we escape the three HTML-significant * characters as their `\uXXXX` JSON escapes. Because these characters only ever * appear INSIDE JSON string literals (never as JSON structure), the result is * still byte-for-byte valid JSON that `JSON.parse` round-trips: * `<` → `<` (defeats `` and `