@xenia-martech/sdk-js 1.2.0-dev.6 → 1.2.0-dev.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +2 -2
  2. package/dist/{actions-C18Kv-4w.d.cts → actions-35V37IT0.d.cts} +2 -1
  3. package/dist/{actions-C18Kv-4w.d.ts → actions-35V37IT0.d.ts} +2 -1
  4. package/dist/{chunk-OMMIRSPK.js → chunk-F3WZFXYK.js} +5 -3
  5. package/dist/chunk-F3WZFXYK.js.map +1 -0
  6. package/dist/{chunk-YLMMTKQL.cjs → chunk-IOY6IPUW.cjs} +5 -3
  7. package/dist/chunk-IOY6IPUW.cjs.map +1 -0
  8. package/dist/client/index.d.cts +4 -3
  9. package/dist/client/index.d.ts +4 -3
  10. package/dist/client/react/index.cjs +14 -7
  11. package/dist/client/react/index.cjs.map +1 -1
  12. package/dist/client/react/index.d.cts +10 -4
  13. package/dist/client/react/index.d.ts +10 -4
  14. package/dist/client/react/index.js +14 -7
  15. package/dist/client/react/index.js.map +1 -1
  16. package/dist/cms/contentful.d.cts +3 -2
  17. package/dist/cms/contentful.d.ts +3 -2
  18. package/dist/{consent-DgWdjsSy.d.cts → consent-BgAETCkL.d.cts} +2 -1
  19. package/dist/{consent-Cemn91j3.d.ts → consent-DRCV0N0d.d.ts} +2 -1
  20. package/dist/{cookie-names-CnL65Oly.d.cts → cookie-names-DFItnSLK.d.cts} +2 -1
  21. package/dist/{cookie-names-BvUaW3uo.d.ts → cookie-names-DU3MtcNG.d.ts} +2 -1
  22. package/dist/edge/index.cjs +22 -22
  23. package/dist/edge/index.d.cts +5 -4
  24. package/dist/edge/index.d.ts +5 -4
  25. package/dist/edge/index.js +1 -1
  26. package/dist/index.d.cts +4 -3
  27. package/dist/index.d.ts +4 -3
  28. package/dist/next/index.cjs +23 -19
  29. package/dist/next/index.cjs.map +1 -1
  30. package/dist/next/index.d.cts +7 -5
  31. package/dist/next/index.d.ts +7 -5
  32. package/dist/next/index.js +6 -2
  33. package/dist/next/index.js.map +1 -1
  34. package/dist/{personalize-content-c2DDAV6g.d.ts → personalize-content-Cwc2AomC.d.ts} +2 -1
  35. package/dist/{personalize-content-ghZPKlf1.d.cts → personalize-content-CxSdplMV.d.cts} +2 -1
  36. package/dist/server/index.d.cts +5 -4
  37. package/dist/server/index.d.ts +5 -4
  38. package/dist/{xenia-server-DV8Sjmoo.d.ts → xenia-server-Cf24mL0c.d.ts} +3 -2
  39. package/dist/{xenia-server-C3O-cWQT.d.cts → xenia-server-D-bx14lw.d.cts} +3 -2
  40. package/package.json +10 -10
  41. package/dist/chunk-OMMIRSPK.js.map +0 -1
  42. package/dist/chunk-YLMMTKQL.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/next/shared.ts","../../src/edge/debug-entries.ts","../../src/next/edge-debug.ts","../../src/next/edge-proxy.ts","../../src/next/edge-routes.ts","../../src/next/index.ts"],"names":["headers","NextResponse"],"mappings":"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","file":"index.js","sourcesContent":["import type { VisitorCookieOptions } from \"../core/types\";\n\n/** Request header the proxy stamps with the URL being served (a Server Component can't see its own). */\nexport const URL_HEADER = \"x-xenia-url\";\n\n/** `NextResponse.cookies.set` attributes for the visitor cookie. Default: `path=/`, `SameSite=Lax`, one year. */\nexport function cookieAttributes(c: VisitorCookieOptions = {}) {\n const sameSite = c.sameSite ?? \"Lax\";\n return {\n path: \"/\",\n maxAge: Math.floor((c.maxAgeDays ?? 365) * 86400),\n sameSite: sameSite.toLowerCase() as \"lax\" | \"strict\" | \"none\",\n secure: c.secure || sameSite === \"None\",\n ...(c.domain && { domain: c.domain }),\n };\n}\n\n/**\n * The request headers to hand the render: the URL on {@link URL_HEADER}, and a cookie just minted\n * (`name=value`) added to the forwarded `Cookie` header — `NextRequest.cookies.set` doesn't rewrite\n * it, and `cookies()` reads that — so this very request's render already sees it.\n */\nexport function forwardedHeaders(headers: Headers, url: string, newCookie?: string): Headers {\n const forwarded = new Headers(headers);\n forwarded.set(URL_HEADER, url);\n if (newCookie) {\n const header = forwarded.get(\"cookie\");\n forwarded.set(\"cookie\", header ? `${header}; ${newCookie}` : newCookie);\n }\n return forwarded;\n}\n","/** One page's entry in the edge debug cookie (written by `xeniaEdgeProxy({ debug })`, read by `<XeniaDebugPanel>`). */\nexport type DebugEntry = Record<string, unknown> & { page: string };\n\n/** The debug cookie's pages (it may arrive encoded once or twice); anything unreadable is none. */\nexport function readDebugEntries(raw: string | undefined | null): Record<string, DebugEntry> {\n if (!raw) return {};\n try {\n let text = decodeURIComponent(raw);\n if (text.startsWith(\"%\")) text = decodeURIComponent(text);\n const parsed: unknown = JSON.parse(text);\n return parsed && typeof parsed === \"object\" && !Array.isArray(parsed) ? (parsed as Record<string, DebugEntry>) : {};\n } catch {\n return {};\n }\n}\n","/**\n * QA and debugging for the edge flow (`xeniaEdgeProxy`'s `qa` and `debug` options):\n * - QA overrides: `?xn_geo=<city>` places the visitor in a QA city, `?xn_date=YYYY-MM-DD` decides\n * as of that day (midday in the US), `?xn_geo=off` forgets them; kept for the visit in a cookie;\n * - the debug cookie: what was decided for each of the last few pages, read by `<XeniaDebugPanel>`.\n * A cookie rather than the HTML, because variant pages are cached and shared.\n */\nimport type { NextRequest, NextResponse } from \"next/server\";\nimport { isPrefetch } from \"../edge/request-facts\";\nimport { readDebugEntries, type DebugEntry } from \"../edge/debug-entries\";\nimport type { ViewerGeo } from \"../edge/types\";\nimport type { EdgeDecisionInfo } from \"./edge-proxy\";\n\nexport { readDebugEntries, type DebugEntry };\n\n/** Cities a QA visitor can be placed in, with what an edge would report for them. */\nexport const QA_CITIES: Record<string, ViewerGeo> = {\n minneapolis: { country: \"US\", region: \"MN\", regionName: \"Minnesota\", city: \"Minneapolis\", timeZone: \"America/Chicago\", latitude: \"44.98\", longitude: \"-93.27\" },\n chicago: { country: \"US\", region: \"IL\", regionName: \"Illinois\", city: \"Chicago\", timeZone: \"America/Chicago\", latitude: \"41.88\", longitude: \"-87.63\" },\n miami: { country: \"US\", region: \"FL\", regionName: \"Florida\", city: \"Miami\", timeZone: \"America/New_York\", latitude: \"25.76\", longitude: \"-80.19\" },\n new_york: { country: \"US\", region: \"NY\", regionName: \"New York\", city: \"New York\", timeZone: \"America/New_York\", latitude: \"40.71\", longitude: \"-74.01\" },\n los_angeles: { country: \"US\", region: \"CA\", regionName: \"California\", city: \"Los Angeles\", timeZone: \"America/Los_Angeles\", latitude: \"34.05\", longitude: \"-118.24\" },\n seattle: { country: \"US\", region: \"WA\", regionName: \"Washington\", city: \"Seattle\", timeZone: \"America/Los_Angeles\", latitude: \"47.61\", longitude: \"-122.33\" },\n london: { country: \"GB\", region: \"ENG\", regionName: \"England\", city: \"London\", timeZone: \"Europe/London\", latitude: \"51.51\", longitude: \"-0.13\" },\n sydney: { country: \"AU\", region: \"NSW\", regionName: \"New South Wales\", city: \"Sydney\", timeZone: \"Australia/Sydney\", latitude: \"-33.87\", longitude: \"151.21\" },\n};\n\nexport interface QaState {\n geo?: string;\n date?: string;\n}\n\nconst QA_MAX_AGE_S = 60 * 60;\n\nconst validDate = (d: unknown): d is string =>\n typeof d === \"string\" && /^\\d{4}-\\d{2}-\\d{2}$/.test(d) && !Number.isNaN(Date.parse(d));\n\n/** The QA overrides for this request: from the URL (then remembered) or the cookie, each checked alike. */\nexport function readQa(request: NextRequest, cities: Record<string, ViewerGeo>, cookie: string): { qa: QaState; changed: boolean } {\n const isCity = (c: unknown): c is string => typeof c === \"string\" && Object.hasOwn(cities, c);\n let qa: QaState;\n try {\n const saved = JSON.parse(request.cookies.get(cookie)?.value ?? \"{}\") as Record<string, unknown> | null;\n qa = {\n ...(isCity(saved?.geo) ? { geo: saved.geo } : {}),\n ...(validDate(saved?.date) ? { date: saved.date } : {}),\n };\n } catch {\n qa = {};\n }\n const p = request.nextUrl.searchParams;\n let changed = false;\n // `off` forgets what was remembered; values on the same URL then apply on a clean slate.\n if (p.get(\"xn_geo\") === \"off\") {\n changed = Object.keys(qa).length > 0;\n qa = {};\n }\n const city = p.get(\"xn_geo\")?.toLowerCase();\n if (isCity(city)) {\n qa = { ...qa, geo: city };\n changed = true;\n }\n const date = p.get(\"xn_date\");\n if (validDate(date)) {\n qa = { ...qa, date };\n changed = true;\n }\n return { qa, changed };\n}\n\nexport function rememberQa(response: NextResponse, qa: QaState, cookie: string) {\n if (Object.keys(qa).length) response.cookies.set(cookie, JSON.stringify(qa), { path: \"/\", maxAge: QA_MAX_AGE_S, sameSite: \"lax\" });\n else response.cookies.delete(cookie);\n}\n\n/** \"Now\" for a QA date: midday in the US (17:00 UTC) that day. */\nexport const qaNow = (qa: QaState): Date | undefined => (qa.date ? new Date(`${qa.date}T17:00:00Z`) : undefined);\n\n// ── debug cookie ─────────────────────────────────────────────────────────────\n\n/** Longest page path kept in an entry (a longer one would make the header itself too large). */\nconst MAX_PAGE = 200;\n/** Room for the cookie's value, under the browser's 4096 bytes for name, value and attributes. */\nconst DEBUG_COOKIE_MAX = 3900;\nconst DEBUG_PAGES = 4;\nconst DEBUG_MAX_AGE_S = 300;\n/** Location headers named on the panel, to show whether the host's geo reached the proxy. */\nconst GEO_HEADERS = [\"x-xn-geo\", \"x-nf-geo\", \"x-country\", \"x-vercel-ip-country\", \"cloudfront-viewer-country\", \"cf-ipcountry\"];\n\nconst geoLabel = (g: ViewerGeo | undefined) =>\n g ? `${g.city ? `${g.city}, ` : \"\"}${g.country ?? \"-\"}${g.region ? `/${g.region}` : \"\"} (${g.source ?? \"?\"})` : \"none\";\n\n/** The location sources that reached the proxy: geo headers, and Netlify's runtime context. */\nfunction sourcesSeen(request: Request): string[] {\n const seen = GEO_HEADERS.filter((n) => request.headers.get(n));\n const g = globalThis as unknown as { Netlify?: { context?: unknown } };\n if (g.Netlify) seen.push(g.Netlify.context ? \"Netlify.context\" : \"Netlify (no context)\");\n return seen;\n}\n\n/**\n * The visitor's local time to the minute (\"Thursday 21:58\") — what the `local_*` facts were made\n * from: the request's time (or a QA date) in the visitor's time zone, UTC (said so) when unknown.\n */\nfunction localTimeLabel(timeZone: string | undefined, now: Date): string {\n const format = (tz: string) =>\n new Intl.DateTimeFormat(\"en-GB\", { timeZone: tz, weekday: \"long\", hour: \"2-digit\", minute: \"2-digit\", hourCycle: \"h23\" }).format(now).replace(\",\", \"\");\n if (timeZone) {\n try {\n return format(timeZone);\n } catch {\n /* not a time zone this runtime knows */\n }\n }\n return `${format(\"UTC\")} (UTC)`;\n}\n\n/** Each Visitor Intent answer with its strongest scores (a step with many options would overflow the cookie). */\nfunction profileSummary(profile: Record<string, unknown> | null | undefined) {\n if (!profile) return undefined;\n const answers = Object.fromEntries(\n Object.entries((profile.answers ?? {}) as Record<string, Record<string, unknown> & { scores?: Record<string, number> }>).map(([name, a]) => [\n name,\n { ...a, scores: Object.fromEntries(Object.entries(a?.scores ?? {}).filter(([, v]) => v > 0).sort((x, y) => y[1] - x[1]).slice(0, 5)) },\n ]),\n );\n return { answers, pageViews: profile.page_views, lastSection: profile.last_section, campaign: profile.last_utm_campaign };\n}\n\nconst SOURCES: Record<string, string> = { skipped: \"site page\", \"not-targeted\": \"not targeted\", \"no-consent\": \"no consent\", error: \"error\" };\n\n/** What the panel shows for one page view. */\nexport function debugEntry(info: EdgeDecisionInfo): DebugEntry {\n const { outcome } = info;\n return {\n page: info.ctx.path,\n geo: geoLabel(info.ctx.geo),\n // Structured, for the panel's Request tab.\n request: {\n location: info.ctx.geo,\n via: info.ctx.geoVia,\n seen: sourcesSeen(info.ctx.request),\n ...(info.ctx.detectedGeo ? { detected: info.ctx.detectedGeo } : {}),\n device: info.ctx.device,\n consent: info.ctx.consent,\n localTime: localTimeLabel(info.ctx.geo?.timeZone, info.ctx.now),\n },\n source: outcome?.source ?? SOURCES[info.exit] ?? info.exit,\n ...(outcome ? { ms: outcome.ms, profile: profileSummary(outcome.profile) } : {}),\n decisions: (outcome?.decisions ?? []).map((d) => ({\n key: d.contentKey,\n result: d.personalized ? d.variant || \"personalized\" : d.reason?.startsWith(\"suppressed\") ? \"suppressed\" : (d.bucket ?? \"base\"),\n reason: d.reason,\n trace: d.trace,\n })),\n };\n}\n\n/**\n * Add this page's entry, keyed by page — a link prefetch passes through the proxy too, and must not\n * replace the page's own entry. Keeps the last few pages; drops the oldest until it fits, then this\n * page's profile.\n */\nexport function writeDebug(request: NextRequest, response: NextResponse, entry: DebugEntry, cookie: string) {\n if (isPrefetch(request.headers)) return;\n entry = { ...entry, page: entry.page.slice(0, MAX_PAGE) };\n const pages = readDebugEntries(request.cookies.get(cookie)?.value);\n delete pages[entry.page];\n pages[entry.page] = { ...entry, at: Date.now() };\n // Browsers drop a cookie over 4 KB whole, and the value is encoded twice (here and by `cookies.set`).\n let entries = Object.entries(pages).slice(-DEBUG_PAGES);\n const encoded = () => encodeURIComponent(JSON.stringify(Object.fromEntries(entries)));\n while (entries.length > 1 && encodeURIComponent(encoded()).length > DEBUG_COOKIE_MAX) entries = entries.slice(1);\n if (encodeURIComponent(encoded()).length > DEBUG_COOKIE_MAX) {\n const { profile: _drop, ...rest } = pages[entry.page];\n void _drop;\n entries = [[entry.page, rest as DebugEntry]];\n }\n if (encodeURIComponent(encoded()).length > DEBUG_COOKIE_MAX) {\n entries = [[entry.page, { page: entry.page, source: entry.source, note: \"entry too large for the debug cookie\" } as DebugEntry]];\n }\n response.cookies.set(cookie, encoded(), { path: \"/\", maxAge: DEBUG_MAX_AGE_S, sameSite: \"lax\" });\n}\n","/**\n * The edge decide flow in one proxy call: which page views need Xenia, the facts Xenia decides on,\n * and the rewrite to the variant page. Every failure ends in base content.\n *\n * Cost per request:\n * - page no journey targets → an in-memory manifest lookup, no Xenia call\n * - targeted page, returning visitor → an in-memory decision-cache hit\n * - targeted page, first view this session → one `/decide` call, capped at the budget\n */\nimport { NextResponse, type NextRequest } from \"next/server\";\nimport { DEFAULT_PREFIX, visitorCookieName } from \"../core/cookie-names\";\nimport { generateUlid } from \"../core/id\";\nimport type { VisitorCookieOptions } from \"../core/types\";\nimport type { DecideOutcome, XeniaEdge } from \"../edge/client\";\nimport { edgeConsent, type EdgeConsent } from \"../edge/consent\";\nimport { deviceOf, isBot, isPageLoad, landingContext, localTime, viewerGeo, type GeoHeader } from \"../edge/request-facts\";\nimport { TRAIL_MAX_AGE_S, readTrail, trailCookieName, trailCookieValue, withView } from \"../edge/trail\";\nimport type { EdgeDecision, EdgeFacts, ManifestKey, TrailView, ViewerGeo } from \"../edge/types\";\nimport { encodeVariant, swapGroups, type SwapGroup } from \"../edge/variant\";\nimport { QA_CITIES, debugEntry, qaNow, readQa, rememberQa, writeDebug, type DebugEntry } from \"./edge-debug\";\nimport { cookieAttributes, forwardedHeaders } from \"./shared\";\n\n/** What the proxy knows about this page view. `prepare` may change the fields marked so. */\nexport interface EdgeRequestContext {\n request: NextRequest;\n host: string | null;\n path: string;\n /** The visitor this view is decided for (changeable in `prepare`, e.g. a profile's own visitor). */\n visitorId: string;\n /** The visitor cookie the browser sent, if any. */\n existingVisitorId?: string;\n /** Where the visitor is (changeable in `prepare`, e.g. a QA city). */\n geo?: ViewerGeo;\n /** Which source supplied `geo` (see `viewerGeo`). */\n geoVia: string;\n /** While a QA city stands in for `geo`: what the edge really detected (for the debug panel). */\n detectedGeo?: ViewerGeo;\n device: \"mobile\" | \"tablet\" | \"desktop\";\n /** First-touch campaign and referrer (changeable in `prepare`). */\n landing: Record<string, string>;\n /** Recent views before this one (changeable in `prepare`). */\n previousTrail: TrailView[];\n /** The trail with this view first — set after `prepare`. */\n trail: TrailView[];\n consent: EdgeConsent;\n /** \"Now\" for local-time facts: the real time, or a QA date (changeable in `prepare`). */\n now: Date;\n}\n\n/** `error`: something threw (a hook, the edge client) — base content was served. */\nexport type EdgeExit = \"skipped\" | \"not-targeted\" | \"no-consent\" | \"decided\" | \"error\";\n\nexport interface EdgeDecisionInfo<S = unknown> {\n ctx: EdgeRequestContext;\n exit: EdgeExit;\n /** The facts sent to `/decide` (standard ones with the site's on top); absent when skipped. */\n facts?: EdgeFacts;\n outcome?: DecideOutcome;\n side?: S;\n /** The response about to be returned — set cookies on it here. */\n response: NextResponse;\n}\n\nexport interface XeniaEdgeProxyOptions<S = unknown> {\n /** One client per instance: `createXeniaEdge(…)` from `/edge`. */\n edge: XeniaEdge;\n /** Server-only secret the variant token is signed with. */\n variantSecret: string;\n /** Where variant pages live. Default `/xv` (`/xv/<token>/women`). */\n variantPrefix?: string;\n /** Must match the browser client's `config.prefix`, if you set one. */\n prefix?: string;\n cookie?: VisitorCookieOptions;\n /**\n * The location headers your host (or edge function) sets and overwrites, e.g.\n * `[\"x-vercel-ip-country\"]` — see `viewerGeo`. Default none: a visitor can send any header.\n */\n geoHeaders?: readonly GeoHeader[];\n /** Treat `Sec-GPC` / `DNT` as analytics off. Default true. */\n respectDnt?: boolean;\n /** Paths with no variant page (app routes): their views join the trail, but they're never decided. */\n skip?: (path: string) => boolean;\n /** Adjust the context before facts are built: the visitor, geo, landing or earlier trail. */\n prepare?: (ctx: EdgeRequestContext) => void | Promise<void>;\n /** The site's own facts, on top of the standard ones. */\n facts?: (ctx: EdgeRequestContext) => EdgeFacts | Promise<EdgeFacts>;\n /** What else makes this visitor's decision different (a new value → a fresh decision). */\n cacheFacts?: (ctx: EdgeRequestContext) => EdgeFacts | Promise<EdgeFacts>;\n /** This view's `/decide` budget, instead of the client's (e.g. a journey that calls a back office). */\n budgetMs?: (ctx: EdgeRequestContext) => number | undefined;\n /** Work started before `/decide` and awaited after it; its result reaches the hooks below as `side`. */\n alongside?: (ctx: EdgeRequestContext, keys: ManifestKey[]) => Promise<S>;\n filterDecisions?: (decisions: EdgeDecision[], ctx: EdgeRequestContext, side: S | undefined, outcome: DecideOutcome) => EdgeDecision[];\n /**\n * Where to render this view: a URL to rewrite to, `null` for the page itself, `undefined` for the\n * default (the signed variant page when anything was swapped). Called on every exit but `skipped`;\n * `outcome` is absent when Xenia wasn't asked.\n */\n rewrite?: (\n ctx: EdgeRequestContext,\n groups: SwapGroup[],\n side: S | undefined,\n outcome: DecideOutcome | undefined,\n ) => URL | null | undefined | Promise<URL | null | undefined>;\n /** Carried in the variant token beside the swaps (left out if it would make the token too long). */\n extra?: (ctx: EdgeRequestContext, side: S | undefined, outcome: DecideOutcome) => unknown;\n /** Called on every exit, with the response about to be returned. */\n onDecision?: (info: EdgeDecisionInfo<S>) => void | Promise<void>;\n /** Anything that threw on the way (base content was served instead). Default: nothing. */\n onError?: (error: unknown) => void;\n /**\n * Write what was decided for each page to the `<prefix>_debug` cookie `<XeniaDebugPanel>` reads.\n * For development and QA only — turn it on with `process.env.NODE_ENV === \"development\"` or a flag.\n */\n debug?: boolean;\n /** Fields of your own for the panel (or replacements for the SDK's), per page view. */\n debugInfo?: (info: EdgeDecisionInfo<S>) => Record<string, unknown>;\n /**\n * QA overrides for development and QA only: `?xn_geo=<city>` (`QA_CITIES`, or your own `cities`),\n * `?xn_date=YYYY-MM-DD`, `?xn_geo=off` to forget them, and `?xn_country=GB` under `next dev`.\n */\n qa?: boolean | { cities?: Record<string, ViewerGeo> };\n}\n\nconst MAX_QUERY = 20;\nconst MAX_QUERY_VALUE = 500;\n\n/**\n * Next.js `proxy.ts`/`middleware.ts` step for edge personalization: ensures the visitor cookie\n * (like `xeniaProxy()`), keeps the landing campaign and page trail, decides targeted pages with\n * Xenia within the budget and rewrites a personalized view to its signed variant page\n * (`decodeVariant` there). Respects consent (see `edgeConsent`).\n *\n * ```ts\n * const edge = createXeniaEdge({ baseUrl, token: process.env.XENIA_SDK_TOKEN! });\n * export const proxy = (request: NextRequest) =>\n * xeniaEdgeProxy(request, { edge, variantSecret: process.env.XENIA_VARIANT_SECRET! });\n * ```\n */\nexport async function xeniaEdgeProxy<S = unknown>(request: NextRequest, opts: XeniaEdgeProxyOptions<S>): Promise<NextResponse> {\n if (request.method !== \"GET\" && request.method !== \"HEAD\") return NextResponse.next();\n if (isBot(request.headers.get(\"user-agent\"))) return NextResponse.next();\n\n const started = Date.now();\n const prefix = opts.prefix ?? DEFAULT_PREFIX;\n const vidCookie = visitorCookieName(prefix);\n const ctxCookie = `${prefix}_ctx`;\n const trailCookie = trailCookieName(prefix);\n const { pathname: path } = request.nextUrl;\n const existingVisitorId = request.cookies.get(vidCookie)?.value;\n const landing = landingContext(request.nextUrl, request.headers.get(\"referer\"), request.cookies.get(ctxCookie)?.value);\n const qaOn = Boolean(opts.qa);\n const cities = (typeof opts.qa === \"object\" && opts.qa.cities) || QA_CITIES;\n const qaCookie = `${prefix}_qa_ctx`;\n const { qa, changed: qaChanged } = qaOn ? readQa(request, cities, qaCookie) : { qa: {}, changed: false };\n const detected = viewerGeo(request, { trust: opts.geoHeaders, devOverride: qaOn && process.env.NODE_ENV === \"development\" });\n const qaCity = qa.geo && Object.hasOwn(cities, qa.geo) ? cities[qa.geo] : undefined;\n const { geo, via } = qaCity ? { geo: { ...qaCity, source: \"qa\" }, via: \"qa\" } : detected;\n\n const ctx: EdgeRequestContext = {\n request,\n host: request.headers.get(\"host\"),\n path,\n visitorId: existingVisitorId ?? generateUlid(),\n existingVisitorId,\n geo,\n geoVia: via,\n ...(qaCity && detected.geo ? { detectedGeo: detected.geo } : {}),\n device: deviceOf(request.headers),\n landing: landing.ctx,\n previousTrail: readTrail(request.cookies.get(trailCookie)?.value),\n trail: [],\n consent: edgeConsent(request.headers, { prefix, respectDnt: opts.respectDnt }),\n now: qaNow(qa) ?? new Date(),\n };\n // Read when the response is built, so a visitor `prepare` switched to is the one forwarded.\n const newVisitor = () => ctx.visitorId !== existingVisitorId;\n const forwarded = () =>\n forwardedHeaders(request.headers, request.url, newVisitor() ? `${vidCookie}=${ctx.visitorId}` : undefined);\n const base = () => NextResponse.next({ request: { headers: forwarded() } });\n const respond = (url: URL | null | undefined) =>\n url ? NextResponse.rewrite(url, { request: { headers: forwarded() } }) : base();\n\n const finish = async (\n response: NextResponse,\n exit: EdgeExit,\n desc: string,\n rest: Omit<EdgeDecisionInfo<S>, \"ctx\" | \"exit\" | \"response\"> = {},\n ) => {\n if (newVisitor()) response.cookies.set(vidCookie, ctx.visitorId, cookieAttributes(opts.cookie));\n if (landing.changed || ctx.landing !== landing.ctx) {\n response.cookies.set(ctxCookie, JSON.stringify(ctx.landing), { path: \"/\", sameSite: \"lax\", httpOnly: true });\n }\n if (ctx.consent.analytics && isPageLoad(request.headers) && ctx.trail.length && ctx.trail !== ctx.previousTrail) {\n response.cookies.set(trailCookie, trailCookieValue(ctx.trail), { path: \"/\", maxAge: TRAIL_MAX_AGE_S, sameSite: \"lax\" });\n }\n response.headers.set(\"Server-Timing\", `xenia;dur=${Date.now() - started};desc=\"${desc}\"`);\n if (qaChanged) rememberQa(response, qa, qaCookie);\n try {\n const info: EdgeDecisionInfo<S> = { ctx, exit, response, ...rest };\n await opts.onDecision?.(info);\n if (opts.debug) writeDebug(request, response, { ...debugEntry(info), ...opts.debugInfo?.(info) } as DebugEntry, `${prefix}_debug`);\n } catch (error) {\n opts.onError?.(error);\n }\n return response;\n };\n\n // Every failure — a throwing hook, a bad manifest entry — ends in base content, never an error page.\n try {\n return await decideAndRespond();\n } catch (error) {\n opts.onError?.(error);\n return finish(base(), \"error\", \"error\");\n }\n\n async function decideAndRespond(): Promise<NextResponse> {\n await opts.prepare?.(ctx);\n ctx.trail = withView(ctx.previousTrail, path);\n\n if (opts.skip?.(path)) return finish(base(), \"skipped\", \"site page\");\n\n const query: Record<string, string> = {};\n for (const [k, v] of request.nextUrl.searchParams) {\n if (Object.keys(query).length >= MAX_QUERY) break;\n if (v.length <= MAX_QUERY_VALUE) query[k] = v;\n }\n const facts: EdgeFacts = {\n ...ctx.landing,\n ...localTime(ctx.geo, ctx.now),\n device: ctx.device,\n path,\n url: request.nextUrl.href,\n query,\n ...(ctx.geo ? { geo: ctx.geo as Record<string, string> } : {}),\n ...(ctx.trail[1] ? { previousPath: ctx.trail[1].path } : {}),\n ...(await opts.facts?.(ctx)),\n };\n\n if (!ctx.consent.personalization) {\n return finish(respond(await opts.rewrite?.(ctx, [], undefined, undefined)), \"no-consent\", \"no consent\", { facts });\n }\n\n // No manifest yet (a cold start whose first fetch hasn't come back): decide by path, and Xenia\n // answers \"none\" for pages no journey targets — rather than serving base content to every visitor.\n const keys = (await opts.edge.match(ctx.host, path)) ?? [{ contentKey: \"\", mode: \"server\" as const, pages: [path] }];\n if (!keys.length) {\n return finish(respond(await opts.rewrite?.(ctx, [], undefined, undefined)), \"not-targeted\", \"not targeted\", { facts });\n }\n\n const pending = opts.alongside?.(ctx, keys);\n const cacheFacts: EdgeFacts = {\n ...ctx.landing,\n device: ctx.device,\n country: ctx.geo?.country ?? \"\",\n city: ctx.geo?.city ?? \"\",\n // A page the visitor hadn't viewed, a time on page, or a click can change their profile.\n pages: ctx.trail.map((t) => t.path).sort().join(\" \"),\n timed: ctx.trail.filter((t) => t.seconds !== undefined).map((t) => `${t.path}:${Math.round(t.seconds!)}`).sort().join(\" \"),\n clicks: request.cookies.get(`${prefix}_clicks`)?.value ?? \"0\",\n // A QA date is another moment: never answer it from today's cached decision.\n ...(qa.date ? { qaDate: qa.date } : {}),\n ...(await opts.cacheFacts?.(ctx)),\n };\n const outcome = await opts.edge.decide(keys, {\n host: ctx.host,\n path,\n visitorId: ctx.visitorId,\n facts,\n cacheFacts,\n ...(ctx.consent.analytics ? { trail: ctx.trail } : {}),\n budgetMs: opts.budgetMs?.(ctx),\n });\n const side = await pending;\n const decisions = opts.filterDecisions ? opts.filterDecisions(outcome.decisions, ctx, side, outcome) : outcome.decisions;\n const groups = swapGroups(decisions);\n\n let url = await opts.rewrite?.(ctx, groups, side, outcome);\n if (url === undefined && groups.length) {\n const token = await encodeVariant(groups, opts.variantSecret, await opts.extra?.(ctx, side, outcome));\n url = request.nextUrl.clone();\n url.pathname = `${opts.variantPrefix ?? \"/xv\"}/${token}${path === \"/\" ? \"\" : path}`;\n }\n return finish(respond(url), \"decided\", outcome.source, { facts, outcome, side });\n }\n}\n","/** Route Handlers a Next.js storefront serves for edge personalization. */\nimport { revalidatePath } from \"next/cache\";\nimport { fetchManifest, trimManifest } from \"../edge/manifest\";\nimport type { PublicManifest } from \"../edge/types\";\nimport { verifyWebhook } from \"../edge/webhook\";\n\nconst EMPTY: PublicManifest = { version: \"\", pages: [] };\nconst MAX_WEBHOOK_BODY = 64 * 1024;\n\n/**\n * `GET` for a public, CDN-cached copy of the manifest (version + targeted page patterns only — no\n * content keys or rules), so a cold proxy instance reads it from the nearby CDN instead of waiting on\n * Xenia, and the server token never leaves the server. Point the edge client's `manifestUrl` at it.\n * At build time an unreachable Xenia serves an empty manifest instead of failing the deploy; at\n * runtime it throws, so the cache keeps the last good copy.\n *\n * ```ts\n * // app/api/xenia/manifest/route.ts\n * export const revalidate = 36000; // a safety net — the storefront webhook regenerates it at once\n * export const GET = createManifestRoute({ token: process.env.XENIA_SDK_TOKEN, revalidate });\n * ```\n */\nexport function createManifestRoute(opts: { token?: string; baseUrl?: string; revalidate?: number }): () => Promise<Response> {\n return async () => {\n if (!opts.token) return Response.json(EMPTY);\n try {\n const manifest = await fetchManifest({\n baseUrl: opts.baseUrl,\n token: opts.token,\n ...(opts.revalidate !== undefined ? { init: { next: { revalidate: opts.revalidate } } as RequestInit } : {}),\n });\n return Response.json(trimManifest(manifest));\n } catch (error) {\n if (process.env.NEXT_PHASE === \"phase-production-build\") {\n console.warn(\"[xenia] manifest unavailable at build:\", error instanceof Error ? error.message : error);\n return Response.json(EMPTY);\n }\n throw error;\n }\n };\n}\n\n/**\n * `POST` for Xenia's storefront webhook (Journey Orchestrator → Storefront webhook): verifies the\n * signature (`verifyWebhook`), answers `ping`, and on `manifest.changed` regenerates `paths` (the\n * manifest route) at once, then runs `onManifestChanged` (e.g. a rebuild hook) and merges what it\n * returns into the response.\n */\nexport function createRevalidateRoute(opts: {\n secret?: string;\n paths: string[];\n onManifestChanged?: () => Promise<Record<string, unknown>> | Record<string, unknown>;\n}): (request: Request) => Promise<Response> {\n return async (request) => {\n const body = await request.text();\n if (body.length > MAX_WEBHOOK_BODY || !(await verifyWebhook({ headers: request.headers, body }, opts.secret ?? \"\"))) {\n return Response.json({ error: \"invalid signature\" }, { status: 401 });\n }\n const event = request.headers.get(\"x-xenia-event\") ?? \"\";\n if (event === \"ping\") return Response.json({ ok: true, event });\n if (event !== \"manifest.changed\") return Response.json({ ok: true, ignored: event });\n for (const path of opts.paths) revalidatePath(path);\n return Response.json({ ok: true, event, revalidated: opts.paths, ...(await opts.onManifestChanged?.()) });\n };\n}\n","/**\n * `@xenia-martech/sdk-js/next` — Next.js (App Router, 15+) glue for the server SDK.\n *\n * A Server Component can't see its own URL or set cookies during render, so the two halves split\n * the work: `xeniaProxy()` runs in `proxy.ts`/`middleware.ts` (mints the visitor cookie, stamps the\n * URL onto a request header), and `xeniaServerFromNext()` reads both back to bind a per-request\n * `XeniaServer`. Use them together; each alone degrades gracefully (no URL context / a throwaway\n * visitor id).\n */\n\nimport * as React from \"react\";\nimport { cookies, headers } from \"next/headers\";\nimport { NextResponse, type NextRequest } from \"next/server\";\nimport { visitorCookieName } from \"../core/cookie-names\";\nimport { generateUlid } from \"../core/id\";\nimport { contextFromUrl } from \"../core/request-context\";\nimport type { ConsentState, VisitorCookieOptions, XeniaConfig } from \"../core/types\";\nimport { getConsent } from \"../server/cookies\";\nimport { createXeniaServer, type XeniaServer } from \"../server/xenia-server\";\nimport { URL_HEADER, cookieAttributes, forwardedHeaders } from \"./shared\";\n\nexport { URL_HEADER };\nexport { xeniaEdgeProxy } from \"./edge-proxy\";\nexport type { EdgeDecisionInfo, EdgeExit, EdgeRequestContext, XeniaEdgeProxyOptions } from \"./edge-proxy\";\nexport { createManifestRoute, createRevalidateRoute } from \"./edge-routes\";\nexport { QA_CITIES, readDebugEntries } from \"./edge-debug\";\nexport type { DebugEntry, QaState } from \"./edge-debug\";\n\n\nexport interface XeniaProxyOptions {\n /** Request headers to forward (e.g. your own additions); defaults to the incoming ones. */\n headers?: Headers;\n /** Must match the browser client's `config.prefix`, if you set one. */\n prefix?: string;\n /** Visitor cookie attributes. Default: `path=/`, `SameSite=Lax`, one year. */\n cookie?: VisitorCookieOptions;\n}\n\n/**\n * Next.js proxy/middleware step: ensure the visitor cookie exists and stamp the URL onto\n * {@link URL_HEADER}, then continue. A new visitor id is also put on the forwarded `Cookie` header,\n * so this very request's render already sees it.\n *\n * ```ts\n * // proxy.ts\n * export const proxy = (request: NextRequest) => xeniaProxy(request);\n * ```\n */\nexport function xeniaProxy(request: NextRequest, opts: XeniaProxyOptions = {}): NextResponse {\n const name = visitorCookieName(opts.prefix);\n const existing = request.cookies.get(name)?.value;\n const visitorId = existing ?? generateUlid();\n\n const forwarded = forwardedHeaders(opts.headers ?? request.headers, request.url, existing ? undefined : `${name}=${visitorId}`);\n\n const response = NextResponse.next({ request: { headers: forwarded } });\n if (!existing) response.cookies.set(name, visitorId, cookieAttributes(opts.cookie));\n return response;\n}\n\n/**\n * A `XeniaServer` bound to this request's visitor (the cookie `xeniaProxy()` set) and URL context\n * (path, query, UTMs, referrer). For Server Components, Server Actions and Route Handlers.\n * `config.visitorId`/`config.context` still win when passed.\n */\nexport async function xeniaServerFromNext(config: XeniaConfig): Promise<XeniaServer> {\n const [jar, h] = await Promise.all([cookies(), headers()]);\n const name = visitorCookieName(config.prefix);\n let visitorId = config.visitorId ?? jar.get(name)?.value;\n if (!visitorId) {\n visitorId = generateUlid();\n try {\n jar.set(name, visitorId, cookieAttributes());\n } catch {\n // Expected during a Server Component render; xeniaProxy() is the place that persists it.\n }\n }\n return createXeniaServer({\n ...config,\n visitorId,\n context: { ...contextFromUrl(h.get(URL_HEADER), h.get(\"referer\")), ...config.context },\n });\n}\n\n/** This request's consent, from the cookie the browser client's `consent()` (or `consentCookie()`) wrote. */\nexport async function consentFromNext(prefix?: string): Promise<ConsentState> {\n return getConsent((await headers()).get(\"cookie\"), prefix);\n}\n\n// ── CMS page personalization ──────────────────────────────────────────────────\n\n// One store per server request (React.cache scopes it to the render), so every section that asks\n// for the same page shares ONE personalization run. Falls back to \"no sharing\" outside React\n// Server Components, where `cache` is unavailable.\nconst requestStore: () => Map<string, Promise<unknown>> =\n typeof (React as { cache?: unknown }).cache === \"function\"\n ? (React as unknown as { cache: <F extends () => unknown>(fn: F) => F }).cache(() => new Map())\n : () => new Map();\n\n/**\n * Run `personalize` at most once per request for `key`, and share the promise. Lets a page shell\n * render immediately while each personalized section awaits the same run inside its own\n * `<Suspense>`, streaming in as soon as it's ready:\n *\n * ```tsx\n * const run = (ref) => personalizeOnce(`page:${ref}`, async () =>\n * (await xeniaServerFromNext(config)).personalizePage(ref, { cms, timeoutMs: 800 }));\n *\n * export default async function Page({ params }) {\n * const xenia = await xeniaServerFromNext(config);\n * const base = await xenia.personalizePage(ref, { cms, maxRounds: 0 }); // CMS only, no Xenia call\n * const pending = new Set(pendingTargets(base.content, cms)); // from the markers\n * return base.content.fields.sections.map((s) =>\n * pending.has(s.sys.id) ? (\n * <Suspense key={s.sys.id} fallback={<SectionSkeleton />}> // never base content that will change\n * <PersonalizedSection id={s.sys.id} run={() => run(ref)} />\n * </Suspense>\n * ) : (\n * <Section key={s.sys.id} entry={s} />\n * ));\n * }\n * ```\n *\n * To finish deeper levels in the browser instead, pass `maxRounds: 1` here and hand the result's\n * `content` to `usePersonalizedContent` — already-decided entries are not asked about again.\n */\nexport function personalizeOnce<T>(key: string, personalize: () => Promise<T>): Promise<T> {\n const store = requestStore();\n let run = store.get(key) as Promise<T> | undefined;\n if (!run) {\n run = personalize();\n store.set(key, run);\n }\n return run;\n}\n"]}
1
+ {"version":3,"sources":["../../src/next/shared.ts","../../src/edge/debug-entries.ts","../../src/next/edge-debug.ts","../../src/next/edge-proxy.ts","../../src/next/edge-routes.ts","../../src/next/index.ts"],"names":["headers","NextResponse"],"mappings":"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","file":"index.js","sourcesContent":["import type { VisitorCookieOptions } from \"../core/types\";\n\n/** Request header the proxy stamps with the URL being served (a Server Component can't see its own). */\nexport const URL_HEADER = \"x-xenia-url\";\n\n/** `NextResponse.cookies.set` attributes for the visitor cookie. Default: `path=/`, `SameSite=Lax`, one year. */\nexport function cookieAttributes(c: VisitorCookieOptions = {}) {\n const sameSite = c.sameSite ?? \"Lax\";\n return {\n path: \"/\",\n maxAge: Math.floor((c.maxAgeDays ?? 365) * 86400),\n sameSite: sameSite.toLowerCase() as \"lax\" | \"strict\" | \"none\",\n secure: c.secure || sameSite === \"None\",\n ...(c.domain && { domain: c.domain }),\n };\n}\n\n/**\n * The request headers to hand the render: the URL on {@link URL_HEADER}, and a cookie just minted\n * (`name=value`) added to the forwarded `Cookie` header — `NextRequest.cookies.set` doesn't rewrite\n * it, and `cookies()` reads that — so this very request's render already sees it.\n */\nexport function forwardedHeaders(headers: Headers, url: string, newCookie?: string): Headers {\n const forwarded = new Headers(headers);\n forwarded.set(URL_HEADER, url);\n if (newCookie) {\n const header = forwarded.get(\"cookie\");\n forwarded.set(\"cookie\", header ? `${header}; ${newCookie}` : newCookie);\n }\n return forwarded;\n}\n","/** One page's entry in the edge debug cookie (written by `xeniaEdgeProxy({ debug })`, read by `<XeniaDebugPanel>`). */\nexport type DebugEntry = Record<string, unknown> & { page: string };\n\n/** The debug cookie's pages (it may arrive encoded once or twice); anything unreadable is none. */\nexport function readDebugEntries(raw: string | undefined | null): Record<string, DebugEntry> {\n if (!raw) return {};\n try {\n let text = decodeURIComponent(raw);\n if (text.startsWith(\"%\")) text = decodeURIComponent(text);\n const parsed: unknown = JSON.parse(text);\n return parsed && typeof parsed === \"object\" && !Array.isArray(parsed) ? (parsed as Record<string, DebugEntry>) : {};\n } catch {\n return {};\n }\n}\n","/**\n * QA and debugging for the edge flow (`xeniaEdgeProxy`'s `qa` and `debug` options):\n * - QA overrides: `?xn_geo=<city>` places the visitor in a QA city, `?xn_date=YYYY-MM-DD` decides\n * as of that day (midday in the US), `?xn_geo=off` forgets them; kept for the visit in a cookie;\n * - the debug cookie: what was decided for each of the last few pages, read by `<XeniaDebugPanel>`.\n * A cookie rather than the HTML, because variant pages are cached and shared.\n */\nimport type { NextRequest, NextResponse } from \"next/server\";\nimport { isPrefetch } from \"../edge/request-facts\";\nimport { readDebugEntries, type DebugEntry } from \"../edge/debug-entries\";\nimport type { ViewerGeo } from \"../edge/types\";\nimport type { EdgeDecisionInfo } from \"./edge-proxy\";\n\nexport { readDebugEntries, type DebugEntry };\n\n/** Cities a QA visitor can be placed in, with what an edge would report for them. */\nexport const QA_CITIES: Record<string, ViewerGeo> = {\n minneapolis: { country: \"US\", region: \"MN\", regionName: \"Minnesota\", city: \"Minneapolis\", timeZone: \"America/Chicago\", latitude: \"44.98\", longitude: \"-93.27\" },\n chicago: { country: \"US\", region: \"IL\", regionName: \"Illinois\", city: \"Chicago\", timeZone: \"America/Chicago\", latitude: \"41.88\", longitude: \"-87.63\" },\n miami: { country: \"US\", region: \"FL\", regionName: \"Florida\", city: \"Miami\", timeZone: \"America/New_York\", latitude: \"25.76\", longitude: \"-80.19\" },\n new_york: { country: \"US\", region: \"NY\", regionName: \"New York\", city: \"New York\", timeZone: \"America/New_York\", latitude: \"40.71\", longitude: \"-74.01\" },\n los_angeles: { country: \"US\", region: \"CA\", regionName: \"California\", city: \"Los Angeles\", timeZone: \"America/Los_Angeles\", latitude: \"34.05\", longitude: \"-118.24\" },\n seattle: { country: \"US\", region: \"WA\", regionName: \"Washington\", city: \"Seattle\", timeZone: \"America/Los_Angeles\", latitude: \"47.61\", longitude: \"-122.33\" },\n london: { country: \"GB\", region: \"ENG\", regionName: \"England\", city: \"London\", timeZone: \"Europe/London\", latitude: \"51.51\", longitude: \"-0.13\" },\n sydney: { country: \"AU\", region: \"NSW\", regionName: \"New South Wales\", city: \"Sydney\", timeZone: \"Australia/Sydney\", latitude: \"-33.87\", longitude: \"151.21\" },\n};\n\nexport interface QaState {\n geo?: string;\n date?: string;\n}\n\nconst QA_MAX_AGE_S = 60 * 60;\n\nconst validDate = (d: unknown): d is string =>\n typeof d === \"string\" && /^\\d{4}-\\d{2}-\\d{2}$/.test(d) && !Number.isNaN(Date.parse(d));\n\n/** The QA overrides for this request: from the URL (then remembered) or the cookie, each checked alike. */\nexport function readQa(request: NextRequest, cities: Record<string, ViewerGeo>, cookie: string): { qa: QaState; changed: boolean } {\n const isCity = (c: unknown): c is string => typeof c === \"string\" && Object.hasOwn(cities, c);\n let qa: QaState;\n try {\n const saved = JSON.parse(request.cookies.get(cookie)?.value ?? \"{}\") as Record<string, unknown> | null;\n qa = {\n ...(isCity(saved?.geo) ? { geo: saved.geo } : {}),\n ...(validDate(saved?.date) ? { date: saved.date } : {}),\n };\n } catch {\n qa = {};\n }\n const p = request.nextUrl.searchParams;\n let changed = false;\n // `off` forgets what was remembered; values on the same URL then apply on a clean slate.\n if (p.get(\"xn_geo\") === \"off\") {\n changed = Object.keys(qa).length > 0;\n qa = {};\n }\n const city = p.get(\"xn_geo\")?.toLowerCase();\n if (isCity(city)) {\n qa = { ...qa, geo: city };\n changed = true;\n }\n const date = p.get(\"xn_date\");\n if (validDate(date)) {\n qa = { ...qa, date };\n changed = true;\n }\n return { qa, changed };\n}\n\nexport function rememberQa(response: NextResponse, qa: QaState, cookie: string) {\n if (Object.keys(qa).length) response.cookies.set(cookie, JSON.stringify(qa), { path: \"/\", maxAge: QA_MAX_AGE_S, sameSite: \"lax\" });\n else response.cookies.delete(cookie);\n}\n\n/** \"Now\" for a QA date: midday in the US (17:00 UTC) that day. */\nexport const qaNow = (qa: QaState): Date | undefined => (qa.date ? new Date(`${qa.date}T17:00:00Z`) : undefined);\n\n// ── debug cookie ─────────────────────────────────────────────────────────────\n\n/** Longest page path kept in an entry (a longer one would make the header itself too large). */\nconst MAX_PAGE = 200;\n/** Room for the cookie's value, under the browser's 4096 bytes for name, value and attributes. */\nconst DEBUG_COOKIE_MAX = 3900;\nconst DEBUG_PAGES = 4;\nconst DEBUG_MAX_AGE_S = 300;\n/** Location headers named on the panel, to show whether the host's geo reached the proxy. */\nconst GEO_HEADERS = [\"x-xn-geo\", \"x-nf-geo\", \"x-country\", \"x-vercel-ip-country\", \"cloudfront-viewer-country\", \"cf-ipcountry\"];\n\nconst geoLabel = (g: ViewerGeo | undefined) =>\n g ? `${g.city ? `${g.city}, ` : \"\"}${g.country ?? \"-\"}${g.region ? `/${g.region}` : \"\"} (${g.source ?? \"?\"})` : \"none\";\n\n/** The location sources that reached the proxy: geo headers, and Netlify's runtime context. */\nfunction sourcesSeen(request: Request): string[] {\n const seen = GEO_HEADERS.filter((n) => request.headers.get(n));\n const g = globalThis as unknown as { Netlify?: { context?: unknown } };\n if (g.Netlify) seen.push(g.Netlify.context ? \"Netlify.context\" : \"Netlify (no context)\");\n return seen;\n}\n\n/**\n * The visitor's local time to the minute (\"Thursday 21:58\") — what the `local_*` facts were made\n * from: the request's time (or a QA date) in the visitor's time zone, UTC (said so) when unknown.\n */\nfunction localTimeLabel(timeZone: string | undefined, now: Date): string {\n const format = (tz: string) =>\n new Intl.DateTimeFormat(\"en-GB\", { timeZone: tz, weekday: \"long\", hour: \"2-digit\", minute: \"2-digit\", hourCycle: \"h23\" }).format(now).replace(\",\", \"\");\n if (timeZone) {\n try {\n return format(timeZone);\n } catch {\n /* not a time zone this runtime knows */\n }\n }\n return `${format(\"UTC\")} (UTC)`;\n}\n\n/** Each Visitor Intent answer with its strongest scores (a step with many options would overflow the cookie). */\nfunction profileSummary(profile: Record<string, unknown> | null | undefined) {\n if (!profile) return undefined;\n const answers = Object.fromEntries(\n Object.entries((profile.answers ?? {}) as Record<string, Record<string, unknown> & { scores?: Record<string, number> }>).map(([name, a]) => [\n name,\n { ...a, scores: Object.fromEntries(Object.entries(a?.scores ?? {}).filter(([, v]) => v > 0).sort((x, y) => y[1] - x[1]).slice(0, 5)) },\n ]),\n );\n return { answers, pageViews: profile.page_views, lastSection: profile.last_section, campaign: profile.last_utm_campaign };\n}\n\nconst SOURCES: Record<string, string> = { skipped: \"site page\", \"not-targeted\": \"not targeted\", \"no-consent\": \"no consent\", error: \"error\" };\n\n/** What the panel shows for one page view. */\nexport function debugEntry(info: EdgeDecisionInfo): DebugEntry {\n const { outcome } = info;\n return {\n page: info.ctx.path,\n geo: geoLabel(info.ctx.geo),\n // Structured, for the panel's Request tab.\n request: {\n location: info.ctx.geo,\n via: info.ctx.geoVia,\n seen: sourcesSeen(info.ctx.request),\n ...(info.ctx.detectedGeo ? { detected: info.ctx.detectedGeo } : {}),\n device: info.ctx.device,\n consent: info.ctx.consent,\n localTime: localTimeLabel(info.ctx.geo?.timeZone, info.ctx.now),\n },\n source: outcome?.source ?? SOURCES[info.exit] ?? info.exit,\n ...(outcome ? { ms: outcome.ms, profile: profileSummary(outcome.profile) } : {}),\n decisions: (outcome?.decisions ?? []).map((d) => ({\n key: d.contentKey,\n result: d.personalized ? d.variant || \"personalized\" : d.reason?.startsWith(\"suppressed\") ? \"suppressed\" : (d.bucket ?? \"base\"),\n reason: d.reason,\n trace: d.trace,\n })),\n };\n}\n\n/**\n * Add this page's entry, keyed by page — a link prefetch passes through the proxy too, and must not\n * replace the page's own entry. Keeps the last few pages; drops the oldest until it fits, then this\n * page's profile.\n */\nexport function writeDebug(request: NextRequest, response: NextResponse, entry: DebugEntry, cookie: string) {\n if (isPrefetch(request.headers)) return;\n entry = { ...entry, page: entry.page.slice(0, MAX_PAGE) };\n const pages = readDebugEntries(request.cookies.get(cookie)?.value);\n delete pages[entry.page];\n pages[entry.page] = { ...entry, at: Date.now() };\n // Browsers drop a cookie over 4 KB whole, and the value is encoded twice (here and by `cookies.set`).\n let entries = Object.entries(pages).slice(-DEBUG_PAGES);\n const encoded = () => encodeURIComponent(JSON.stringify(Object.fromEntries(entries)));\n while (entries.length > 1 && encodeURIComponent(encoded()).length > DEBUG_COOKIE_MAX) entries = entries.slice(1);\n if (encodeURIComponent(encoded()).length > DEBUG_COOKIE_MAX) {\n const { profile: _drop, ...rest } = pages[entry.page];\n void _drop;\n entries = [[entry.page, rest as DebugEntry]];\n }\n if (encodeURIComponent(encoded()).length > DEBUG_COOKIE_MAX) {\n entries = [[entry.page, { page: entry.page, source: entry.source, note: \"entry too large for the debug cookie\" } as DebugEntry]];\n }\n response.cookies.set(cookie, encoded(), { path: \"/\", maxAge: DEBUG_MAX_AGE_S, sameSite: \"lax\" });\n}\n","/**\n * The edge decide flow in one proxy call: which page views need Xenia, the facts Xenia decides on,\n * and the rewrite to the variant page. Every failure ends in base content.\n *\n * Cost per request:\n * - page no journey targets → an in-memory manifest lookup, no Xenia call\n * - targeted page, returning visitor → an in-memory decision-cache hit\n * - targeted page, first view this session → one `/decide` call, capped at the budget\n */\nimport { NextResponse, type NextRequest } from \"next/server\";\nimport { DEFAULT_PREFIX, visitorCookieName } from \"../core/cookie-names\";\nimport { generateUlid } from \"../core/id\";\nimport type { VisitorCookieOptions } from \"../core/types\";\nimport type { DecideOutcome, XeniaEdge } from \"../edge/client\";\nimport { edgeConsent, type EdgeConsent } from \"../edge/consent\";\nimport { deviceOf, isBot, isPageLoad, landingContext, localTime, viewerGeo, type GeoHeader } from \"../edge/request-facts\";\nimport { TRAIL_MAX_AGE_S, readTrail, trailCookieName, trailCookieValue, withView } from \"../edge/trail\";\nimport type { EdgeDecision, EdgeFacts, ManifestKey, TrailView, ViewerGeo } from \"../edge/types\";\nimport { encodeVariant, swapGroups, type SwapGroup } from \"../edge/variant\";\nimport { QA_CITIES, debugEntry, qaNow, readQa, rememberQa, writeDebug, type DebugEntry } from \"./edge-debug\";\nimport { cookieAttributes, forwardedHeaders } from \"./shared\";\n\n/** What the proxy knows about this page view. `prepare` may change the fields marked so. */\nexport interface EdgeRequestContext {\n request: NextRequest;\n host: string | null;\n path: string;\n /** The visitor this view is decided for (changeable in `prepare`, e.g. a profile's own visitor). */\n visitorId: string;\n /** The visitor cookie the browser sent, if any. */\n existingVisitorId?: string;\n /** Where the visitor is (changeable in `prepare`, e.g. a QA city). */\n geo?: ViewerGeo;\n /** Which source supplied `geo` (see `viewerGeo`). */\n geoVia: string;\n /** While a QA city stands in for `geo`: what the edge really detected (for the debug panel). */\n detectedGeo?: ViewerGeo;\n device: \"mobile\" | \"tablet\" | \"desktop\";\n /** First-touch campaign and referrer (changeable in `prepare`). */\n landing: Record<string, string>;\n /** Recent views before this one (changeable in `prepare`). */\n previousTrail: TrailView[];\n /** The trail with this view first — set after `prepare`. */\n trail: TrailView[];\n consent: EdgeConsent;\n /** \"Now\" for local-time facts: the real time, or a QA date (changeable in `prepare`). */\n now: Date;\n}\n\n/** `error`: something threw (a hook, the edge client) — base content was served. */\nexport type EdgeExit = \"skipped\" | \"not-targeted\" | \"no-consent\" | \"decided\" | \"error\";\n\nexport interface EdgeDecisionInfo<S = unknown> {\n ctx: EdgeRequestContext;\n exit: EdgeExit;\n /** The facts sent to `/decide` (standard ones with the site's on top); absent when skipped. */\n facts?: EdgeFacts;\n outcome?: DecideOutcome;\n side?: S;\n /** The response about to be returned — set cookies on it here. */\n response: NextResponse;\n}\n\nexport interface XeniaEdgeProxyOptions<S = unknown> {\n /** One client per instance: `createXeniaEdge(…)` from `/edge`. */\n edge: XeniaEdge;\n /** Server-only secret the variant token is signed with. */\n variantSecret: string;\n /** Where variant pages live. Default `/xv` (`/xv/<token>/women`). */\n variantPrefix?: string;\n /** Must match the browser client's `config.prefix`, if you set one. */\n prefix?: string;\n cookie?: VisitorCookieOptions;\n /**\n * The location headers your host (or edge function) sets and overwrites, e.g.\n * `[\"x-vercel-ip-country\"]` — see `viewerGeo`. Default none: a visitor can send any header.\n */\n geoHeaders?: readonly GeoHeader[];\n /** Treat `Sec-GPC` / `DNT` as analytics off. Default true. */\n respectDnt?: boolean;\n /** Paths with no variant page (app routes): their views join the trail, but they're never decided. */\n skip?: (path: string) => boolean;\n /** Adjust the context before facts are built: the visitor, geo, landing or earlier trail. */\n prepare?: (ctx: EdgeRequestContext) => void | Promise<void>;\n /** The site's own facts, on top of the standard ones. */\n facts?: (ctx: EdgeRequestContext) => EdgeFacts | Promise<EdgeFacts>;\n /** What else makes this visitor's decision different (a new value → a fresh decision). */\n cacheFacts?: (ctx: EdgeRequestContext) => EdgeFacts | Promise<EdgeFacts>;\n /** This view's `/decide` budget, instead of the client's (e.g. a journey that calls a back office). */\n budgetMs?: (ctx: EdgeRequestContext) => number | undefined;\n /** Work started before `/decide` and awaited after it; its result reaches the hooks below as `side`. */\n alongside?: (ctx: EdgeRequestContext, keys: ManifestKey[]) => Promise<S>;\n filterDecisions?: (decisions: EdgeDecision[], ctx: EdgeRequestContext, side: S | undefined, outcome: DecideOutcome) => EdgeDecision[];\n /**\n * Where to render this view: a URL to rewrite to, `null` for the page itself, `undefined` for the\n * default (the signed variant page when anything was swapped). Called on every exit but `skipped`;\n * `outcome` is absent when Xenia wasn't asked.\n */\n rewrite?: (\n ctx: EdgeRequestContext,\n groups: SwapGroup[],\n side: S | undefined,\n outcome: DecideOutcome | undefined,\n ) => URL | null | undefined | Promise<URL | null | undefined>;\n /** Carried in the variant token beside the swaps (left out if it would make the token too long). */\n extra?: (ctx: EdgeRequestContext, side: S | undefined, outcome: DecideOutcome) => unknown;\n /** Called on every exit, with the response about to be returned. */\n onDecision?: (info: EdgeDecisionInfo<S>) => void | Promise<void>;\n /** Anything that threw on the way (base content was served instead). Default: nothing. */\n onError?: (error: unknown) => void;\n /**\n * Write what was decided for each page to the `<prefix>_debug` cookie `<XeniaDebugPanel>` reads.\n * For development and QA only — turn it on with `process.env.NODE_ENV === \"development\"` or a flag.\n */\n debug?: boolean;\n /** Fields of your own for the panel (or replacements for the SDK's), per page view. */\n debugInfo?: (info: EdgeDecisionInfo<S>) => Record<string, unknown>;\n /**\n * QA overrides for development and QA only: `?xn_geo=<city>` (`QA_CITIES`, or your own `cities`),\n * `?xn_date=YYYY-MM-DD`, `?xn_geo=off` to forget them, and `?xn_country=GB` under `next dev`.\n */\n qa?: boolean | { cities?: Record<string, ViewerGeo> };\n}\n\nconst MAX_QUERY = 20;\nconst MAX_QUERY_VALUE = 500;\n\n/**\n * Next.js `proxy.ts`/`middleware.ts` step for edge personalization: ensures the visitor cookie\n * (like `xeniaProxy()`), keeps the landing campaign and page trail, decides targeted pages with\n * Xenia within the budget and rewrites a personalized view to its signed variant page\n * (`decodeVariant` there). Respects consent (see `edgeConsent`).\n *\n * ```ts\n * const edge = createXeniaEdge({ baseUrl, token: process.env.XENIA_SDK_TOKEN! });\n * export const proxy = (request: NextRequest) =>\n * xeniaEdgeProxy(request, { edge, variantSecret: process.env.XENIA_VARIANT_SECRET! });\n * ```\n */\nexport async function xeniaEdgeProxy<S = unknown>(request: NextRequest, opts: XeniaEdgeProxyOptions<S>): Promise<NextResponse> {\n if (request.method !== \"GET\" && request.method !== \"HEAD\") return NextResponse.next();\n if (isBot(request.headers.get(\"user-agent\"))) return NextResponse.next();\n\n const started = Date.now();\n const prefix = opts.prefix ?? DEFAULT_PREFIX;\n const vidCookie = visitorCookieName(prefix);\n const ctxCookie = `${prefix}_ctx`;\n const trailCookie = trailCookieName(prefix);\n const { pathname: path } = request.nextUrl;\n const existingVisitorId = request.cookies.get(vidCookie)?.value;\n const landing = landingContext(request.nextUrl, request.headers.get(\"referer\"), request.cookies.get(ctxCookie)?.value);\n const qaOn = Boolean(opts.qa);\n const cities = (typeof opts.qa === \"object\" && opts.qa.cities) || QA_CITIES;\n const qaCookie = `${prefix}_qa_ctx`;\n const { qa, changed: qaChanged } = qaOn ? readQa(request, cities, qaCookie) : { qa: {}, changed: false };\n const detected = viewerGeo(request, { trust: opts.geoHeaders, devOverride: qaOn && process.env.NODE_ENV === \"development\" });\n const qaCity = qa.geo && Object.hasOwn(cities, qa.geo) ? cities[qa.geo] : undefined;\n const { geo, via } = qaCity ? { geo: { ...qaCity, source: \"qa\" }, via: \"qa\" } : detected;\n\n const ctx: EdgeRequestContext = {\n request,\n host: request.headers.get(\"host\"),\n path,\n visitorId: existingVisitorId ?? generateUlid(),\n existingVisitorId,\n geo,\n geoVia: via,\n ...(qaCity && detected.geo ? { detectedGeo: detected.geo } : {}),\n device: deviceOf(request.headers),\n landing: landing.ctx,\n previousTrail: readTrail(request.cookies.get(trailCookie)?.value),\n trail: [],\n consent: edgeConsent(request.headers, { prefix, respectDnt: opts.respectDnt }),\n now: qaNow(qa) ?? new Date(),\n };\n // Read when the response is built, so a visitor `prepare` switched to is the one forwarded.\n const newVisitor = () => ctx.visitorId !== existingVisitorId;\n const forwarded = () =>\n forwardedHeaders(request.headers, request.url, newVisitor() ? `${vidCookie}=${ctx.visitorId}` : undefined);\n const base = () => NextResponse.next({ request: { headers: forwarded() } });\n const respond = (url: URL | null | undefined) =>\n url ? NextResponse.rewrite(url, { request: { headers: forwarded() } }) : base();\n\n const finish = async (\n response: NextResponse,\n exit: EdgeExit,\n desc: string,\n rest: Omit<EdgeDecisionInfo<S>, \"ctx\" | \"exit\" | \"response\"> = {},\n ) => {\n if (newVisitor()) response.cookies.set(vidCookie, ctx.visitorId, cookieAttributes(opts.cookie));\n if (landing.changed || ctx.landing !== landing.ctx) {\n response.cookies.set(ctxCookie, JSON.stringify(ctx.landing), { path: \"/\", sameSite: \"lax\", httpOnly: true });\n }\n if (ctx.consent.analytics && isPageLoad(request.headers) && ctx.trail.length && ctx.trail !== ctx.previousTrail) {\n response.cookies.set(trailCookie, trailCookieValue(ctx.trail), { path: \"/\", maxAge: TRAIL_MAX_AGE_S, sameSite: \"lax\" });\n }\n response.headers.set(\"Server-Timing\", `xenia;dur=${Date.now() - started};desc=\"${desc}\"`);\n if (qaChanged) rememberQa(response, qa, qaCookie);\n try {\n const info: EdgeDecisionInfo<S> = { ctx, exit, response, ...rest };\n await opts.onDecision?.(info);\n if (opts.debug) writeDebug(request, response, { ...debugEntry(info), ...opts.debugInfo?.(info) } as DebugEntry, `${prefix}_debug`);\n } catch (error) {\n opts.onError?.(error);\n }\n return response;\n };\n\n // Every failure — a throwing hook, a bad manifest entry — ends in base content, never an error page.\n try {\n return await decideAndRespond();\n } catch (error) {\n opts.onError?.(error);\n return finish(base(), \"error\", \"error\");\n }\n\n async function decideAndRespond(): Promise<NextResponse> {\n await opts.prepare?.(ctx);\n ctx.trail = withView(ctx.previousTrail, path);\n\n if (opts.skip?.(path)) return finish(base(), \"skipped\", \"site page\");\n\n const query: Record<string, string> = {};\n for (const [k, v] of request.nextUrl.searchParams) {\n if (Object.keys(query).length >= MAX_QUERY) break;\n if (v.length <= MAX_QUERY_VALUE) query[k] = v;\n }\n const facts: EdgeFacts = {\n ...ctx.landing,\n ...localTime(ctx.geo, ctx.now),\n device: ctx.device,\n path,\n url: request.nextUrl.href,\n query,\n ...(ctx.geo ? { geo: ctx.geo as Record<string, string> } : {}),\n ...(ctx.trail[1] ? { previousPath: ctx.trail[1].path } : {}),\n ...(await opts.facts?.(ctx)),\n };\n\n if (!ctx.consent.personalization) {\n return finish(respond(await opts.rewrite?.(ctx, [], undefined, undefined)), \"no-consent\", \"no consent\", { facts });\n }\n\n // No manifest yet (a cold start whose first fetch hasn't come back): decide by path, and Xenia\n // answers \"none\" for pages no journey targets — rather than serving base content to every visitor.\n const keys = (await opts.edge.match(ctx.host, path)) ?? [{ contentKey: \"\", mode: \"server\" as const, pages: [path] }];\n if (!keys.length) {\n return finish(respond(await opts.rewrite?.(ctx, [], undefined, undefined)), \"not-targeted\", \"not targeted\", { facts });\n }\n\n const pending = opts.alongside?.(ctx, keys);\n const cacheFacts: EdgeFacts = {\n ...ctx.landing,\n device: ctx.device,\n country: ctx.geo?.country ?? \"\",\n city: ctx.geo?.city ?? \"\",\n // A page the visitor hadn't viewed, a time on page, or a click can change their profile.\n pages: ctx.trail.map((t) => t.path).sort().join(\" \"),\n timed: ctx.trail.filter((t) => t.seconds !== undefined).map((t) => `${t.path}:${Math.round(t.seconds!)}`).sort().join(\" \"),\n clicks: request.cookies.get(`${prefix}_clicks`)?.value ?? \"0\",\n // A QA date is another moment: never answer it from today's cached decision.\n ...(qa.date ? { qaDate: qa.date } : {}),\n ...(await opts.cacheFacts?.(ctx)),\n };\n const outcome = await opts.edge.decide(keys, {\n host: ctx.host,\n path,\n visitorId: ctx.visitorId,\n facts,\n cacheFacts,\n ...(ctx.consent.analytics ? { trail: ctx.trail } : {}),\n budgetMs: opts.budgetMs?.(ctx),\n });\n const side = await pending;\n const decisions = opts.filterDecisions ? opts.filterDecisions(outcome.decisions, ctx, side, outcome) : outcome.decisions;\n const groups = swapGroups(decisions);\n\n let url = await opts.rewrite?.(ctx, groups, side, outcome);\n if (url === undefined && groups.length) {\n const token = await encodeVariant(groups, opts.variantSecret, await opts.extra?.(ctx, side, outcome));\n url = request.nextUrl.clone();\n url.pathname = `${opts.variantPrefix ?? \"/xv\"}/${token}${path === \"/\" ? \"\" : path}`;\n }\n return finish(respond(url), \"decided\", outcome.source, { facts, outcome, side });\n }\n}\n","/** Route Handlers a Next.js storefront serves for edge personalization. */\nimport { revalidatePath } from \"next/cache\";\nimport { fetchManifest, trimManifest } from \"../edge/manifest\";\nimport type { PublicManifest } from \"../edge/types\";\nimport { verifyWebhook } from \"../edge/webhook\";\n\nconst EMPTY: PublicManifest = { version: \"\", pages: [] };\n\n/**\n * Part of the manifest fetch's cache key. Next's fetch cache outlives builds (`.next/cache`, which\n * hosts like Netlify keep between builds), and the route's `revalidate` makes the fetch use it even\n * without its own option, so a new build would bake in a manifest up to `revalidate` old. One key per\n * process gives every build a fresh copy; `cache: \"no-store\"` would instead make the route dynamic\n * and lose the CDN copy. `revalidatePath` (the storefront webhook) still clears it.\n */\nconst PROCESS_KEY = `${Date.now()}-${Math.random().toString(36).slice(2)}`;\nconst MAX_WEBHOOK_BODY = 64 * 1024;\n\n/**\n * `GET` for a public, CDN-cached copy of the manifest (version + targeted page patterns only — no\n * content keys or rules), so a cold proxy instance reads it from the nearby CDN instead of waiting on\n * Xenia, and the server token never leaves the server. Point the edge client's `manifestUrl` at it.\n * At build time an unreachable Xenia serves an empty manifest instead of failing the deploy; at\n * runtime it throws, so the cache keeps the last good copy.\n *\n * ```ts\n * // app/api/xenia/manifest/route.ts\n * export const revalidate = 36000; // a safety net — the storefront webhook regenerates it at once\n * export const GET = createManifestRoute({ token: process.env.XENIA_SDK_TOKEN, revalidate });\n * ```\n */\nexport function createManifestRoute(opts: { token?: string; baseUrl?: string; revalidate?: number }): () => Promise<Response> {\n return async () => {\n if (!opts.token) return Response.json(EMPTY);\n try {\n const manifest = await fetchManifest({\n baseUrl: opts.baseUrl,\n token: opts.token,\n init: {\n headers: { \"X-Xenia-Cache-Key\": PROCESS_KEY },\n ...(opts.revalidate !== undefined && { next: { revalidate: opts.revalidate } }),\n } as RequestInit,\n });\n return Response.json(trimManifest(manifest));\n } catch (error) {\n if (process.env.NEXT_PHASE === \"phase-production-build\") {\n console.warn(\"[xenia] manifest unavailable at build:\", error instanceof Error ? error.message : error);\n return Response.json(EMPTY);\n }\n throw error;\n }\n };\n}\n\n/**\n * `POST` for Xenia's storefront webhook (Journey Orchestrator → Storefront webhook): verifies the\n * signature (`verifyWebhook`), answers `ping`, and on `manifest.changed` regenerates `paths` (the\n * manifest route) at once, then runs `onManifestChanged` (e.g. a rebuild hook) and merges what it\n * returns into the response.\n */\nexport function createRevalidateRoute(opts: {\n secret?: string;\n paths: string[];\n onManifestChanged?: () => Promise<Record<string, unknown>> | Record<string, unknown>;\n}): (request: Request) => Promise<Response> {\n return async (request) => {\n const body = await request.text();\n if (body.length > MAX_WEBHOOK_BODY || !(await verifyWebhook({ headers: request.headers, body }, opts.secret ?? \"\"))) {\n return Response.json({ error: \"invalid signature\" }, { status: 401 });\n }\n const event = request.headers.get(\"x-xenia-event\") ?? \"\";\n if (event === \"ping\") return Response.json({ ok: true, event });\n if (event !== \"manifest.changed\") return Response.json({ ok: true, ignored: event });\n for (const path of opts.paths) revalidatePath(path);\n return Response.json({ ok: true, event, revalidated: opts.paths, ...(await opts.onManifestChanged?.()) });\n };\n}\n","/**\n * `@xenia-martech/sdk-js/next` — Next.js (App Router, 15+) glue for the server SDK.\n *\n * A Server Component can't see its own URL or set cookies during render, so the two halves split\n * the work: `xeniaProxy()` runs in `proxy.ts`/`middleware.ts` (mints the visitor cookie, stamps the\n * URL onto a request header), and `xeniaServerFromNext()` reads both back to bind a per-request\n * `XeniaServer`. Use them together; each alone degrades gracefully (no URL context / a throwaway\n * visitor id).\n */\n\nimport * as React from \"react\";\nimport { cookies, headers } from \"next/headers\";\nimport { NextResponse, type NextRequest } from \"next/server\";\nimport { visitorCookieName } from \"../core/cookie-names\";\nimport { generateUlid } from \"../core/id\";\nimport { contextFromUrl } from \"../core/request-context\";\nimport type { ConsentState, VisitorCookieOptions, XeniaConfig } from \"../core/types\";\nimport { getConsent } from \"../server/cookies\";\nimport { createXeniaServer, type XeniaServer } from \"../server/xenia-server\";\nimport { URL_HEADER, cookieAttributes, forwardedHeaders } from \"./shared\";\n\nexport { URL_HEADER };\nexport { xeniaEdgeProxy } from \"./edge-proxy\";\nexport type { EdgeDecisionInfo, EdgeExit, EdgeRequestContext, XeniaEdgeProxyOptions } from \"./edge-proxy\";\nexport { createManifestRoute, createRevalidateRoute } from \"./edge-routes\";\nexport { QA_CITIES, readDebugEntries } from \"./edge-debug\";\nexport type { DebugEntry, QaState } from \"./edge-debug\";\n\n\nexport interface XeniaProxyOptions {\n /** Request headers to forward (e.g. your own additions); defaults to the incoming ones. */\n headers?: Headers;\n /** Must match the browser client's `config.prefix`, if you set one. */\n prefix?: string;\n /** Visitor cookie attributes. Default: `path=/`, `SameSite=Lax`, one year. */\n cookie?: VisitorCookieOptions;\n}\n\n/**\n * Next.js proxy/middleware step: ensure the visitor cookie exists and stamp the URL onto\n * {@link URL_HEADER}, then continue. A new visitor id is also put on the forwarded `Cookie` header,\n * so this very request's render already sees it.\n *\n * ```ts\n * // proxy.ts\n * export const proxy = (request: NextRequest) => xeniaProxy(request);\n * ```\n */\nexport function xeniaProxy(request: NextRequest, opts: XeniaProxyOptions = {}): NextResponse {\n const name = visitorCookieName(opts.prefix);\n const existing = request.cookies.get(name)?.value;\n const visitorId = existing ?? generateUlid();\n\n const forwarded = forwardedHeaders(opts.headers ?? request.headers, request.url, existing ? undefined : `${name}=${visitorId}`);\n\n const response = NextResponse.next({ request: { headers: forwarded } });\n if (!existing) response.cookies.set(name, visitorId, cookieAttributes(opts.cookie));\n return response;\n}\n\n/**\n * A `XeniaServer` bound to this request's visitor (the cookie `xeniaProxy()` set) and URL context\n * (path, query, UTMs, referrer). For Server Components, Server Actions and Route Handlers.\n * `config.visitorId`/`config.context` still win when passed.\n */\nexport async function xeniaServerFromNext(config: XeniaConfig): Promise<XeniaServer> {\n const [jar, h] = await Promise.all([cookies(), headers()]);\n const name = visitorCookieName(config.prefix);\n let visitorId = config.visitorId ?? jar.get(name)?.value;\n if (!visitorId) {\n visitorId = generateUlid();\n try {\n jar.set(name, visitorId, cookieAttributes());\n } catch {\n // Expected during a Server Component render; xeniaProxy() is the place that persists it.\n }\n }\n return createXeniaServer({\n ...config,\n visitorId,\n context: { ...contextFromUrl(h.get(URL_HEADER), h.get(\"referer\")), ...config.context },\n });\n}\n\n/** This request's consent, from the cookie the browser client's `consent()` (or `consentCookie()`) wrote. */\nexport async function consentFromNext(prefix?: string): Promise<ConsentState> {\n return getConsent((await headers()).get(\"cookie\"), prefix);\n}\n\n// ── CMS page personalization ──────────────────────────────────────────────────\n\n// One store per server request (React.cache scopes it to the render), so every section that asks\n// for the same page shares ONE personalization run. Falls back to \"no sharing\" outside React\n// Server Components, where `cache` is unavailable.\nconst requestStore: () => Map<string, Promise<unknown>> =\n typeof (React as { cache?: unknown }).cache === \"function\"\n ? (React as unknown as { cache: <F extends () => unknown>(fn: F) => F }).cache(() => new Map())\n : () => new Map();\n\n/**\n * Run `personalize` at most once per request for `key`, and share the promise. Lets a page shell\n * render immediately while each personalized section awaits the same run inside its own\n * `<Suspense>`, streaming in as soon as it's ready:\n *\n * ```tsx\n * const run = (ref) => personalizeOnce(`page:${ref}`, async () =>\n * (await xeniaServerFromNext(config)).personalizePage(ref, { cms, timeoutMs: 800 }));\n *\n * export default async function Page({ params }) {\n * const xenia = await xeniaServerFromNext(config);\n * const base = await xenia.personalizePage(ref, { cms, maxRounds: 0 }); // CMS only, no Xenia call\n * const pending = new Set(pendingTargets(base.content, cms)); // from the markers\n * return base.content.fields.sections.map((s) =>\n * pending.has(s.sys.id) ? (\n * <Suspense key={s.sys.id} fallback={<SectionSkeleton />}> // never base content that will change\n * <PersonalizedSection id={s.sys.id} run={() => run(ref)} />\n * </Suspense>\n * ) : (\n * <Section key={s.sys.id} entry={s} />\n * ));\n * }\n * ```\n *\n * To finish deeper levels in the browser instead, pass `maxRounds: 1` here and hand the result's\n * `content` to `usePersonalizedContent` — already-decided entries are not asked about again.\n */\nexport function personalizeOnce<T>(key: string, personalize: () => Promise<T>): Promise<T> {\n const store = requestStore();\n let run = store.get(key) as Promise<T> | undefined;\n if (!run) {\n run = personalize();\n store.set(key, run);\n }\n return run;\n}\n"]}
@@ -137,4 +137,5 @@ declare function pendingTargets(payload: unknown, adapter: CmsAdapter, contentKe
137
137
  */
138
138
  declare function personalizePage<T>(ref: PageRef, options: PersonalizeContentOptions): Promise<PersonalizeContentResult<T | null>>;
139
139
 
140
- export { type AppliedSwap as A, type CmsAdapter as C, type EntryResolver as E, type PagePersonalizeOptions as P, type XeniaMarker as X, type PageRef as a, type PersonalizeContentOptions as b, type PersonalizeContentResult as c, personalizeContent as d, personalizePage as e, pendingTargets as p };
140
+ export { personalizeContent as d, personalizePage as e, pendingTargets as p };
141
+ export type { AppliedSwap as A, CmsAdapter as C, EntryResolver as E, PagePersonalizeOptions as P, XeniaMarker as X, PageRef as a, PersonalizeContentOptions as b, PersonalizeContentResult as c };
@@ -137,4 +137,5 @@ declare function pendingTargets(payload: unknown, adapter: CmsAdapter, contentKe
137
137
  */
138
138
  declare function personalizePage<T>(ref: PageRef, options: PersonalizeContentOptions): Promise<PersonalizeContentResult<T | null>>;
139
139
 
140
- export { type AppliedSwap as A, type CmsAdapter as C, type EntryResolver as E, type PagePersonalizeOptions as P, type XeniaMarker as X, type PageRef as a, type PersonalizeContentOptions as b, type PersonalizeContentResult as c, personalizeContent as d, personalizePage as e, pendingTargets as p };
140
+ export { personalizeContent as d, personalizePage as e, pendingTargets as p };
141
+ export type { AppliedSwap as A, CmsAdapter as C, EntryResolver as E, PagePersonalizeOptions as P, XeniaMarker as X, PageRef as a, PersonalizeContentOptions as b, PersonalizeContentResult as c };
@@ -1,9 +1,9 @@
1
- export { S as ServerResolveOptions, a as ServerTrackOptions, b as ServerWebhookOptions, W as WithFallback, X as XeniaServer, c as createXeniaServer } from '../xenia-server-C3O-cWQT.cjs';
1
+ export { S as ServerResolveOptions, a as ServerTrackOptions, b as ServerWebhookOptions, W as WithFallback, X as XeniaServer, c as createXeniaServer } from '../xenia-server-D-bx14lw.cjs';
2
2
  import { d as ConsentState } from '../types-DgVHS4Qw.cjs';
3
3
  export { A as AnalyticsContext, a as AnalyticsEventName, b as AnalyticsIdentity, c as AnalyticsIngestResponse, C as CircuitBreakerConfig, E as EventContext, i as EventIdentity, I as IdentifyRequest, j as IdentifyResponse, J as JsonValue, P as PersonalizationSwap, R as ResolveBatchItem, n as ResolveBatchResult, p as ResolveOptions, q as ResolveResult, W as WebhookResponse, x as XeniaConfig, y as XeniaEvent } from '../types-DgVHS4Qw.cjs';
4
4
  export { X as XeniaApi } from '../api-0IycTYJR.cjs';
5
- export { C as CONSENT_COOKIE, a as CircuitOpenError, V as VISITOR_COOKIE, f as consentCookie, g as consentCookieName, p as parseActions, v as visitorCookieName } from '../cookie-names-CnL65Oly.cjs';
6
- export { A as AppliedSwap, C as CmsAdapter, P as PagePersonalizeOptions, a as PageRef, c as PersonalizeContentResult, X as XeniaMarker, p as pendingTargets, d as personalizeContent, e as personalizePage } from '../personalize-content-ghZPKlf1.cjs';
5
+ export { C as CONSENT_COOKIE, a as CircuitOpenError, V as VISITOR_COOKIE, f as consentCookie, g as consentCookieName, p as parseActions, v as visitorCookieName } from '../cookie-names-DFItnSLK.cjs';
6
+ export { A as AppliedSwap, C as CmsAdapter, P as PagePersonalizeOptions, a as PageRef, c as PersonalizeContentResult, X as XeniaMarker, p as pendingTargets, d as personalizeContent, e as personalizePage } from '../personalize-content-CxSdplMV.cjs';
7
7
 
8
8
  interface RefreshTokenOptions {
9
9
  /**
@@ -71,4 +71,5 @@ declare function getVisitorId(cookieHeader: string | null | undefined, prefix?:
71
71
  */
72
72
  declare function getConsent(cookieHeader: string | null | undefined, prefix?: string): ConsentState;
73
73
 
74
- export { ConsentState, type RefreshTokenOptions, type RefreshedToken, createTokenRoute, getConsent, getVisitorId, parseCookies, refreshSdkToken };
74
+ export { ConsentState, createTokenRoute, getConsent, getVisitorId, parseCookies, refreshSdkToken };
75
+ export type { RefreshTokenOptions, RefreshedToken };
@@ -1,9 +1,9 @@
1
- export { S as ServerResolveOptions, a as ServerTrackOptions, b as ServerWebhookOptions, W as WithFallback, X as XeniaServer, c as createXeniaServer } from '../xenia-server-DV8Sjmoo.js';
1
+ export { S as ServerResolveOptions, a as ServerTrackOptions, b as ServerWebhookOptions, W as WithFallback, X as XeniaServer, c as createXeniaServer } from '../xenia-server-Cf24mL0c.js';
2
2
  import { d as ConsentState } from '../types-DgVHS4Qw.js';
3
3
  export { A as AnalyticsContext, a as AnalyticsEventName, b as AnalyticsIdentity, c as AnalyticsIngestResponse, C as CircuitBreakerConfig, E as EventContext, i as EventIdentity, I as IdentifyRequest, j as IdentifyResponse, J as JsonValue, P as PersonalizationSwap, R as ResolveBatchItem, n as ResolveBatchResult, p as ResolveOptions, q as ResolveResult, W as WebhookResponse, x as XeniaConfig, y as XeniaEvent } from '../types-DgVHS4Qw.js';
4
4
  export { X as XeniaApi } from '../api-COXWLL5L.js';
5
- export { C as CONSENT_COOKIE, a as CircuitOpenError, V as VISITOR_COOKIE, f as consentCookie, g as consentCookieName, p as parseActions, v as visitorCookieName } from '../cookie-names-BvUaW3uo.js';
6
- export { A as AppliedSwap, C as CmsAdapter, P as PagePersonalizeOptions, a as PageRef, c as PersonalizeContentResult, X as XeniaMarker, p as pendingTargets, d as personalizeContent, e as personalizePage } from '../personalize-content-c2DDAV6g.js';
5
+ export { C as CONSENT_COOKIE, a as CircuitOpenError, V as VISITOR_COOKIE, f as consentCookie, g as consentCookieName, p as parseActions, v as visitorCookieName } from '../cookie-names-DU3MtcNG.js';
6
+ export { A as AppliedSwap, C as CmsAdapter, P as PagePersonalizeOptions, a as PageRef, c as PersonalizeContentResult, X as XeniaMarker, p as pendingTargets, d as personalizeContent, e as personalizePage } from '../personalize-content-Cwc2AomC.js';
7
7
 
8
8
  interface RefreshTokenOptions {
9
9
  /**
@@ -71,4 +71,5 @@ declare function getVisitorId(cookieHeader: string | null | undefined, prefix?:
71
71
  */
72
72
  declare function getConsent(cookieHeader: string | null | undefined, prefix?: string): ConsentState;
73
73
 
74
- export { ConsentState, type RefreshTokenOptions, type RefreshedToken, createTokenRoute, getConsent, getVisitorId, parseCookies, refreshSdkToken };
74
+ export { ConsentState, createTokenRoute, getConsent, getVisitorId, parseCookies, refreshSdkToken };
75
+ export type { RefreshTokenOptions, RefreshedToken };
@@ -1,5 +1,5 @@
1
1
  import { X as XeniaApi } from './api-COXWLL5L.js';
2
- import { P as PagePersonalizeOptions, c as PersonalizeContentResult, a as PageRef } from './personalize-content-c2DDAV6g.js';
2
+ import { P as PagePersonalizeOptions, c as PersonalizeContentResult, a as PageRef } from './personalize-content-Cwc2AomC.js';
3
3
  import { x as XeniaConfig, a as AnalyticsEventName, z as CallerIdentity, A as AnalyticsContext, J as JsonValue, d as ConsentState, c as AnalyticsIngestResponse, i as EventIdentity, E as EventContext, W as WebhookResponse, I as IdentifyRequest, j as IdentifyResponse, p as ResolveOptions, q as ResolveResult, R as ResolveBatchItem, n as ResolveBatchResult } from './types-DgVHS4Qw.js';
4
4
 
5
5
  /**
@@ -138,4 +138,5 @@ declare class XeniaServer {
138
138
  /** Create a server-native client. */
139
139
  declare function createXeniaServer(config: XeniaConfig): XeniaServer;
140
140
 
141
- export { type ServerResolveOptions as S, type WithFallback as W, XeniaServer as X, type ServerTrackOptions as a, type ServerWebhookOptions as b, createXeniaServer as c };
141
+ export { XeniaServer as X, createXeniaServer as c };
142
+ export type { ServerResolveOptions as S, WithFallback as W, ServerTrackOptions as a, ServerWebhookOptions as b };
@@ -1,5 +1,5 @@
1
1
  import { X as XeniaApi } from './api-0IycTYJR.cjs';
2
- import { P as PagePersonalizeOptions, c as PersonalizeContentResult, a as PageRef } from './personalize-content-ghZPKlf1.cjs';
2
+ import { P as PagePersonalizeOptions, c as PersonalizeContentResult, a as PageRef } from './personalize-content-CxSdplMV.cjs';
3
3
  import { x as XeniaConfig, a as AnalyticsEventName, z as CallerIdentity, A as AnalyticsContext, J as JsonValue, d as ConsentState, c as AnalyticsIngestResponse, i as EventIdentity, E as EventContext, W as WebhookResponse, I as IdentifyRequest, j as IdentifyResponse, p as ResolveOptions, q as ResolveResult, R as ResolveBatchItem, n as ResolveBatchResult } from './types-DgVHS4Qw.cjs';
4
4
 
5
5
  /**
@@ -138,4 +138,5 @@ declare class XeniaServer {
138
138
  /** Create a server-native client. */
139
139
  declare function createXeniaServer(config: XeniaConfig): XeniaServer;
140
140
 
141
- export { type ServerResolveOptions as S, type WithFallback as W, XeniaServer as X, type ServerTrackOptions as a, type ServerWebhookOptions as b, createXeniaServer as c };
141
+ export { XeniaServer as X, createXeniaServer as c };
142
+ export type { ServerResolveOptions as S, WithFallback as W, ServerTrackOptions as a, ServerWebhookOptions as b };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenia-martech/sdk-js",
3
- "version": "1.2.0-dev.6",
3
+ "version": "1.2.0-dev.8",
4
4
  "description": "Xenia Marketer SDK for web (pull) channels — declarative event tracking, webhook request/response with in-page actions (swap/hide/banner/popup/modal), and content personalization. Client and server builds.",
5
5
  "author": "Xenia Martech",
6
6
  "license": "MIT",
@@ -166,20 +166,20 @@
166
166
  "@semantic-release/npm": "^13.1.5",
167
167
  "@semantic-release/release-notes-generator": "^14.1.0",
168
168
  "@testing-library/react": "^16.3.3",
169
- "@types/node": "^26.1.1",
169
+ "@types/node": "^26.6.5",
170
170
  "@types/react": "^19.3.0",
171
171
  "@types/react-dom": "^19.3.0",
172
- "@vitest/coverage-v8": "^5.0.3",
173
- "eslint": "^10.7.0",
174
- "jsdom": "^30.1.1",
172
+ "@vitest/coverage-v8": "^5.0.5",
173
+ "eslint": "^10.13.0",
174
+ "jsdom": "^30.1.3",
175
175
  "next": "^16.3.8",
176
- "react": "^19.3.0",
177
- "react-dom": "^19.3.0",
176
+ "react": "^19.3.1",
177
+ "react-dom": "^19.3.1",
178
178
  "semantic-release": "^25.0.7",
179
- "tsup": "^8.5.1",
179
+ "tsup": "^9.0.0",
180
180
  "typescript": "^6.0.2",
181
- "typescript-eslint": "^8.63.0",
182
- "vitest": "^5.0.3"
181
+ "typescript-eslint": "^8.72.0",
182
+ "vitest": "^5.0.5"
183
183
  },
184
184
  "engines": {
185
185
  "node": ">=18.0.0"
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/edge/consent.ts","../src/edge/request-facts.ts","../src/edge/trail.ts","../src/edge/webhook.ts","../src/edge/variant.ts","../src/edge/manifest.ts"],"names":["enc"],"mappings":";;;;AAqBO,SAAS,WAAA,CAAY,OAAA,EAAkB,IAAA,GAAkD,EAAC,EAAgB;AAC/G,EAAA,MAAM,GAAA,GAAM,YAAA,CAAa,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAC,CAAA,CAAE,iBAAA,CAAkB,IAAA,CAAK,MAAM,CAAC,CAAA;AAC9E,EAAA,IAAI,OAAA,GAAuB,EAAE,eAAA,EAAiB,IAAA,EAAM,WAAW,IAAA,EAAK;AACpE,EAAA,IAAI,GAAA,EAAK;AACP,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAkB,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AACtC,MAAA,IAAI,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,EAAU;AACxC,QAAA,MAAM,CAAA,GAAI,MAAA;AACV,QAAA,OAAA,GAAU,EAAE,iBAAiB,CAAA,CAAE,eAAA,KAAoB,OAAO,SAAA,EAAW,CAAA,CAAE,cAAc,KAAA,EAAM;AAAA,MAC7F;AAAA,IACF,CAAA,CAAA,MAAQ;AACN,MAAA,IAAI,2BAAA,CAA4B,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,CAAA,EAAG;AAChD,QAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAC,CAAA;AAC1D,QAAA,OAAA,GAAU,EAAE,eAAA,EAAiB,MAAA,CAAO,GAAA,CAAI,iBAAiB,GAAG,SAAA,EAAW,MAAA,CAAO,GAAA,CAAI,WAAW,CAAA,EAAE;AAAA,MACjG;AAAA,IACF;AAAA,EACF;AACA,EAAA,MAAM,aAAA,GAAgB,QAAQ,GAAA,CAAI,SAAS,MAAM,GAAA,IAAO,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,KAAM,GAAA;AAC/E,EAAA,IAAI,IAAA,CAAK,eAAe,KAAA,IAAS,aAAA,YAAyB,EAAE,GAAG,OAAA,EAAS,SAAA,EAAW,KAAA,EAAM;AACzF,EAAA,OAAO,OAAA;AACT;;;ACnCA,IAAM,QAAA,GAAW;AAAA,EACf,SAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAA;AAkBA,SAAS,WAAA,CAAY,GAAwB,MAAA,EAAuC;AAClF,EAAA,IAAI,CAAC,GAAG,OAAO,MAAA;AACf,EAAA,MAAM,OAAA,GAAU,OAAO,CAAA,CAAE,OAAA,KAAY,WAAW,CAAA,CAAE,OAAA,GAAU,EAAE,OAAA,EAAS,IAAA;AACvE,EAAA,IAAI,CAAC,SAAS,OAAO,MAAA;AACrB,EAAA,MAAM,GAAA,GAA+B;AAAA,IACnC,OAAA,EAAS,QAAQ,WAAA,EAAY;AAAA,IAC7B,WAAA,EAAa,EAAE,WAAA,KAAgB,OAAO,EAAE,OAAA,KAAY,QAAA,GAAW,CAAA,CAAE,OAAA,EAAS,IAAA,GAAO,MAAA,CAAA;AAAA,IACjF,MAAA,EAAQ,CAAA,CAAE,MAAA,IAAU,CAAA,CAAE,WAAA,EAAa,IAAA;AAAA,IACnC,UAAA,EAAY,CAAA,CAAE,UAAA,IAAc,CAAA,CAAE,WAAA,EAAa,IAAA;AAAA,IAC3C,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,YAAY,CAAA,CAAE,UAAA;AAAA,IACd,QAAA,EAAU,CAAA,CAAE,QAAA,IAAY,CAAA,CAAE,QAAA;AAAA,IAC1B,QAAA,EAAU,CAAA,CAAE,QAAA,EAAU,QAAA,EAAS;AAAA,IAC/B,SAAA,EAAW,CAAA,CAAE,SAAA,EAAW,QAAA,EAAS;AAAA,IACjC;AAAA,GACF;AACA,EAAA,MAAM,MAAiB,EAAC;AACxB,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,MAAM,CAAA,GAAI,IAAI,CAAC,CAAA;AACf,IAAA,IAAI,OAAO,MAAM,QAAA,IAAY,CAAA,IAAK,EAAE,MAAA,IAAU,GAAA,EAAK,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,EAC9D;AACA,EAAA,OAAO,GAAA;AACT;AAEA,IAAM,SAAA,GAAY,CAAC,IAAA,KAAsC;AACvD,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EACxB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF,CAAA;AAEA,SAAS,WAAW,CAAA,EAAmB;AACrC,EAAA,IAAI;AACF,IAAA,OAAO,mBAAmB,CAAC,CAAA;AAAA,EAC7B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,CAAA;AAAA,EACT;AACF;AAEA,SAAS,WAAW,CAAA,EAAmB;AACrC,EAAA,IAAI;AACF,IAAA,OAAO,KAAK,CAAC,CAAA;AAAA,EACf,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAA;AAAA,EACT;AACF;AAGA,SAAS,cAAA,GAAgD;AACvD,EAAA,IAAI;AACF,IAAA,OAAQ,UAAA,CAA+E,SAAS,OAAA,IAAW,KAAA,CAAA;AAAA,EAC7G,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAEA,IAAM,eAAA,GAAkB,CAAC,WAAA,EAAa,qBAAA,EAAuB,6BAA6B,cAAc,CAAA;AAKxG,SAAS,UAAA,CAAW,GAAY,OAAA,EAA0B;AACxD,EAAA,MAAM,KAAK,CAAC,IAAA,KAAiB,CAAA,CAAE,GAAA,CAAI,IAAI,CAAA,IAAK,MAAA;AAC5C,EAAA,IAAI,YAAY,qBAAA,EAAuB;AACrC,IAAA,OAAO,EAAE,MAAA,EAAQ,EAAA,CAAG,4BAA4B,CAAA,EAAG,MAAM,UAAA,CAAW,EAAA,CAAG,kBAAkB,CAAA,IAAK,EAAE,CAAA,IAAK,MAAA,EAAW,QAAA,EAAU,EAAA,CAAG,sBAAsB,CAAA,EAAE;AAAA,EACvJ;AACA,EAAA,IAAI,YAAY,2BAAA,EAA6B;AAC3C,IAAA,OAAO,EAAE,MAAA,EAAQ,EAAA,CAAG,kCAAkC,CAAA,EAAG,MAAM,UAAA,CAAW,EAAA,CAAG,wBAAwB,CAAA,IAAK,EAAE,CAAA,IAAK,MAAA,EAAW,QAAA,EAAU,EAAA,CAAG,6BAA6B,CAAA,EAAE;AAAA,EAC1K;AACA,EAAA,OAAO,EAAC;AACV;AAkBO,SAAS,SAAA,CACd,OAAA,EACA,IAAA,GAAgE,EAAC,EAC/B;AAClC,EAAA,MAAM,UAAU,IAAI,GAAA,CAAY,IAAA,CAAK,KAAA,IAAS,EAAE,CAAA;AAChD,EAAA,MAAM,WAAA,GAAc,WAAA,CAAY,cAAA,EAAe,EAAG,KAAK,MAAM,CAAA;AAC7D,EAAA,IAAI,aAAa,OAAO,EAAE,GAAA,EAAK,WAAA,EAAa,KAAK,iBAAA,EAAkB;AAEnE,EAAA,MAAM,CAAA,GAAI,EAAE,GAAA,EAAK,CAAC,SAAkB,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,GAAI,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,IAAI,IAAI,IAAA,EAAM;AAC1F,EAAA,MAAM,EAAA,GAAK,CAAA,CAAE,GAAA,CAAI,UAAU,CAAA;AAC3B,EAAA,MAAM,MAAA,GAAS,KAAK,WAAA,CAAY,SAAA,CAAU,WAAW,EAAE,CAAC,CAAA,EAAG,MAAM,CAAA,GAAI,MAAA;AACrE,EAAA,IAAI,QAAQ,OAAO,EAAE,GAAA,EAAK,MAAA,EAAQ,KAAK,0BAAA,EAA2B;AAElE,EAAA,MAAM,WAAA,GAAc,WAAA,CAAa,OAAA,CAAyC,GAAA,EAAK,MAAM,CAAA;AACrF,EAAA,IAAI,aAAa,OAAO,EAAE,GAAA,EAAK,WAAA,EAAa,KAAK,aAAA,EAAc;AAE/D,EAAA,MAAM,EAAA,GAAK,CAAA,CAAE,GAAA,CAAI,UAAU,CAAA;AAC3B,EAAA,IAAI,EAAA,EAAI;AACN,IAAA,MAAM,MAAA,GAAS,WAAA,CAAY,SAAA,CAAU,UAAA,CAAW,EAAE,CAAC,CAAA,IAAK,SAAA,CAAU,UAAA,CAAW,EAAE,CAAC,CAAA,EAAG,MAAM,CAAA;AACzF,IAAA,IAAI,QAAQ,OAAO,EAAE,GAAA,EAAK,MAAA,EAAQ,KAAK,UAAA,EAAW;AAAA,EACpD;AAEA,EAAA,MAAM,GAAA,GAAM,gBAAgB,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,CAAA;AAChD,EAAA,MAAM,aAAA,GAAgB,GAAA,GAAM,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA,GAAI,IAAA;AACzC,EAAA,IAAI,GAAA,IAAO,aAAA,IAAiB,aAAA,CAAc,IAAA,CAAK,aAAa,CAAA,EAAG;AAC7D,IAAA,MAAM,GAAA,GAAM,WAAA;AAAA,MACV;AAAA,QACE,OAAA,EAAS,aAAA;AAAA;AAAA,QAET,GAAG,UAAA,CAAW,OAAA,CAAQ,OAAA,EAAS,GAAG;AAAA,OACpC;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,EAAE,KAAK,GAAA,EAAI;AAAA,EACpB;AAEA,EAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA,CAAE,YAAA,CAAa,IAAI,YAAY,CAAA;AACnE,EAAA,IAAI,KAAK,WAAA,IAAe,QAAA,IAAY,aAAA,CAAc,IAAA,CAAK,QAAQ,CAAA,EAAG;AAChE,IAAA,OAAO,EAAE,GAAA,EAAK,EAAE,OAAA,EAAS,QAAA,CAAS,WAAA,EAAY,EAAG,MAAA,EAAQ,KAAA,EAAM,EAAG,GAAA,EAAK,mBAAA,EAAoB;AAAA,EAC7F;AACA,EAAA,OAAO,EAAE,KAAK,MAAA,EAAO;AACvB;AAEO,SAAS,SAAS,OAAA,EAAmD;AAC1E,EAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,GAAA,CAAI,YAAY,CAAA,IAAK,EAAA;AACxC,EAAA,IAAI,cAAA,CAAe,IAAA,CAAK,EAAE,CAAA,EAAG,OAAO,QAAA;AACpC,EAAA,IAAI,OAAA,CAAQ,IAAI,kBAAkB,CAAA,KAAM,QAAQ,sBAAA,CAAuB,IAAA,CAAK,EAAE,CAAA,EAAG,OAAO,QAAA;AACxF,EAAA,OAAO,SAAA;AACT;AAEA,IAAM,GAAA,GAAM,kFAAA;AAGL,SAAS,MAAM,SAAA,EAA+C;AACnE,EAAA,OAAO,GAAA,CAAI,IAAA,CAAK,SAAA,IAAa,EAAE,CAAA;AACjC;AAGO,SAAS,WAAW,OAAA,EAA2B;AACpD,EAAA,OACE,QAAQ,GAAA,CAAI,sBAAsB,KAClC,WAAA,CAAY,IAAA,CAAK,QAAQ,GAAA,CAAI,SAAS,CAAA,IAAK,EAAE,KAC7C,WAAA,CAAY,IAAA,CAAK,QAAQ,GAAA,CAAI,aAAa,KAAK,EAAE,CAAA;AAErD;AAMO,SAAS,WAAW,OAAA,EAA2B;AACpD,EAAA,OAAA,CAAQ,OAAA,CAAQ,IAAI,gBAAgB,CAAA,IAAK,gBAAgB,UAAA,IAAc,CAAC,WAAW,OAAO,CAAA;AAC5F;AAEA,IAAM,GAAA,GAA8B;AAAA,EAClC,UAAA,EAAY,WAAA;AAAA,EACZ,UAAA,EAAY,WAAA;AAAA,EACZ,YAAA,EAAc,aAAA;AAAA,EACd,WAAA,EAAa,YAAA;AAAA,EACb,QAAA,EAAU,SAAA;AAAA,EACV,MAAA,EAAQ;AACV,CAAA;AAOO,SAAS,cAAA,CACd,GAAA,EACA,QAAA,EACA,KAAA,EACmD;AACnD,EAAA,MAAM,YAAoC,EAAC;AAC3C,EAAA,KAAA,MAAW,CAAC,KAAA,EAAO,IAAI,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC/C,IAAA,MAAM,CAAA,GAAI,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,KAAK,CAAA;AACpC,IAAA,IAAI,GAAG,SAAA,CAAU,IAAI,IAAI,CAAA,CAAE,KAAA,CAAM,GAAG,GAAG,CAAA;AAAA,EACzC;AACA,EAAA,MAAM,QAAA,GAAW,QAAA,IAAY,CAAC,QAAA,CAAS,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA,GAAI,QAAA,CAAS,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,GAAI,IAAA;AAEzF,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAkB,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA,GAAI,IAAA;AACpD,IAAA,IAAA,GAAO,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,GAAK,MAAA,GAAoC,IAAA;AAAA,EAC/G,CAAA,CAAA,MAAQ;AACN,IAAA,IAAA,GAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,IAAA,IAAQ,CAAC,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA,EAAQ,OAAO,EAAE,GAAA,EAAK,IAAA,EAAM,OAAA,EAAS,KAAA,EAAM;AAC/E,EAAA,OAAO,EAAE,GAAA,EAAK,EAAE,GAAG,WAAW,GAAI,QAAA,GAAW,EAAE,QAAA,EAAU,UAAS,GAAI,EAAC,EAAG,EAAG,SAAS,IAAA,EAAK;AAC7F;AAEA,IAAM,QAAA,GAAW,CAAC,QAAA,EAAU,QAAA,EAAU,WAAW,WAAA,EAAa,UAAA,EAAY,UAAU,UAAU,CAAA;AAGvF,SAAS,QAAA,CAAS,KAAA,EAAe,kBAAA,GAAqB,KAAA,EAAe;AAC1E,EAAA,MAAM,KAAA,GAAQ,CAAC,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU,MAAA,EAAQ,MAAA,EAAQ,QAAQ,QAAQ,CAAA;AAC/H,EAAA,MAAM,MAAA,GAAS,KAAA,CAAA,CAAO,KAAA,GAAQ,CAAA,GAAI,MAAM,EAAE,CAAA;AAC1C,EAAA,IAAI,CAAC,oBAAoB,OAAO,MAAA;AAChC,EAAA,OAAQ,EAAE,MAAA,EAAQ,QAAA,EAAU,MAAA,EAAQ,QAAA,EAAU,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,QAAA,EAAS,CAA6B,MAAM,CAAA,IAAK,MAAA;AACvH;AAEA,SAAS,cAAc,EAAA,EAA4C;AACjE,EAAA,IAAI,CAAC,IAAI,OAAO,MAAA;AAChB,EAAA,IAAI;AACF,IAAA,IAAI,KAAK,cAAA,CAAe,OAAA,EAAS,EAAE,QAAA,EAAU,IAAI,CAAA;AACjD,IAAA,OAAO,EAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAWO,SAAS,SAAA,CAAU,KAA4B,GAAA,EAAsB;AAC1E,EAAA,MAAM,QAAA,GAAW,aAAA,CAAc,GAAA,EAAK,QAAQ,CAAA,IAAK,KAAA;AACjD,EAAA,MAAM,QAAQ,MAAA,CAAO,WAAA;AAAA,IACnB,IAAI,IAAA,CAAK,cAAA,CAAe,OAAA,EAAS,EAAE,QAAA,EAAU,OAAA,EAAS,MAAA,EAAQ,KAAA,EAAO,SAAA,EAAW,IAAA,EAAM,SAAA,EAAW,SAAA,EAAW,KAAA,EAAO,CAAA,CAChH,aAAA,CAAc,GAAG,CAAA,CACjB,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,KAAK,CAAC;AAAA,GACjC;AACA,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,KAAA,CAAM,OAAA,IAAW,QAAA,CAAS,IAAI,SAAA,EAAW,CAAC,CAAA,CAAE,WAAA,EAAY;AAC/E,EAAA,MAAM,QAAQ,MAAA,CAAO,KAAA,CAAM,KAAK,CAAA,IAAK,GAAA,CAAI,aAAY,GAAI,CAAA;AACzD,EAAA,OAAO;AAAA,IACL,aAAA,EAAe,OAAA;AAAA,IACf,WAAA,EAAa,KAAA;AAAA,IACb,UAAA,EAAY,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA,GAAI,EAAA;AAAA,IACjC,UAAA,EAAY,OAAA,KAAY,UAAA,IAAc,OAAA,KAAY,QAAA;AAAA,IAClD,QAAQ,QAAA,CAAS,KAAA,EAAO,OAAO,GAAA,EAAK,QAAQ,IAAI,CAAC;AAAA,GACnD;AACF;;;AC/QO,IAAM,SAAA,GAAY;AAElB,IAAM,kBAAkB,EAAA,GAAK;AAE7B,SAAS,eAAA,CAAgB,SAAiB,cAAA,EAAwB;AACvE,EAAA,OAAO,GAAG,MAAM,CAAA,MAAA,CAAA;AAClB;AAEA,IAAM,MAAA,GAAS,CAAC,CAAA,KAAc;AAC5B,EAAA,IAAI;AACF,IAAA,OAAO,mBAAmB,CAAC,CAAA;AAAA,EAC7B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,CAAA;AAAA,EACT;AACF,CAAA;AAGO,SAAS,UAAU,KAAA,EAA+C;AACvE,EAAA,IAAI,CAAC,KAAA,EAAO,OAAO,EAAC;AACpB,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAkB,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAChD,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,SAAU,EAAC;AACpC,IAAA,OAAO,MAAA,CACJ,OAAO,CAAC,CAAA,KAAsC,MAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,OAAO,CAAA,CAAE,CAAC,MAAM,QAAA,IAAY,OAAO,EAAE,CAAC,CAAA,KAAM,QAAQ,CAAA,CACtH,KAAA,CAAM,CAAA,EAAG,SAAS,CAAA,CAClB,GAAA;AAAA,MAAI,CAAC,CAAC,IAAA,EAAM,EAAA,EAAI,OAAO,CAAA,KACtB,OAAO,YAAY,QAAA,IAAY,OAAA,IAAW,KAAK,OAAA,IAAW,KAAA,GAAS,EAAE,IAAA,EAAM,EAAA,EAAI,SAAQ,GAAI,EAAE,MAAM,EAAA;AAAG,KACxG;AAAA,EACJ,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAC;AAAA,EACV;AACF;AAMO,SAAS,SAAS,KAAA,EAAoB,IAAA,EAAc,GAAA,GAAc,IAAA,CAAK,KAAI,EAAgB;AAChG,EAAA,IAAI,KAAA,CAAM,CAAC,CAAA,EAAG,IAAA,KAAS,MAAM,OAAO,KAAA;AACpC,EAAA,MAAM,UAAU,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,IAAI,CAAA;AACjD,EAAA,OAAO,CAAC,EAAE,IAAA,EAAM,EAAA,EAAI,SAAS,EAAA,IAAM,GAAA,IAAO,GAAG,KAAA,CAAM,OAAO,CAAC,CAAA,KAAM,EAAE,IAAA,KAAS,IAAI,CAAC,CAAA,CAAE,KAAA,CAAM,GAAG,SAAS,CAAA;AACvG;AAGO,SAAS,iBAAiB,KAAA,EAA4B;AAC3D,EAAA,OAAO,IAAA,CAAK,SAAA;AAAA,IACV,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,SAAS,CAAA,CAAE,IAAI,CAAC,CAAA,KAAO,CAAA,CAAE,OAAA,KAAY,MAAA,GAAY,CAAC,EAAE,IAAA,EAAM,CAAA,CAAE,EAAE,CAAA,GAAI,CAAC,CAAA,CAAE,MAAM,CAAA,CAAE,EAAA,EAAI,CAAA,CAAE,OAAO,CAAE;AAAA,GAC7G;AACF;;;ACzDA,IAAM,GAAA,GAAM,IAAI,WAAA,EAAY;AAE5B,eAAe,OAAA,CAAQ,QAAgB,OAAA,EAAkC;AACvE,EAAA,MAAM,MAAM,MAAM,MAAA,CAAO,OAAO,SAAA,CAAU,KAAA,EAAO,IAAI,MAAA,CAAO,MAAM,GAAG,EAAE,IAAA,EAAM,QAAQ,IAAA,EAAM,SAAA,IAAa,KAAA,EAAO,CAAC,MAAM,CAAC,CAAA;AACvH,EAAA,MAAM,GAAA,GAAM,IAAI,UAAA,CAAW,MAAM,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,MAAA,EAAQ,GAAA,EAAK,GAAA,CAAI,MAAA,CAAO,OAAO,CAAC,CAAC,CAAA;AACrF,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,GAAA,EAAK,CAAC,MAAM,CAAA,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,SAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAE,KAAK,EAAE,CAAA;AACxE;AAGO,SAAS,UAAA,CAAW,GAAW,CAAA,EAAoB;AACxD,EAAA,IAAI,CAAA,CAAE,MAAA,KAAW,CAAA,CAAE,MAAA,EAAQ,OAAO,KAAA;AAClC,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,MAAA,EAAQ,CAAA,EAAA,EAAK,IAAA,IAAQ,CAAA,CAAE,UAAA,CAAW,CAAC,CAAA,GAAI,CAAA,CAAE,WAAW,CAAC,CAAA;AAC3E,EAAA,OAAO,IAAA,KAAS,CAAA;AAClB;AAOA,eAAsB,aAAA,CACpB,KAAA,EACA,MAAA,EACA,UAAA,GAAa,GAAA,EACK;AAClB,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,mBAAmB,CAAA,IAAK,EAAA;AACzD,EAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ,OAAO,KAAA;AAC/B,EAAA,MAAM,QAAQ,MAAA,CAAO,WAAA,CAAY,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,IAAA,EAAK,CAAE,MAAM,GAAA,EAAK,CAAC,CAAC,CAAC,CAAA;AACrF,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA;AACxB,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,IAAK,KAAK,GAAA,CAAI,IAAA,CAAK,GAAA,EAAI,GAAI,MAAO,CAAC,CAAA,GAAI,cAAc,CAAC,KAAA,CAAM,IAAI,OAAO,KAAA;AAC7F,EAAA,OAAO,WAAW,MAAM,OAAA,CAAQ,MAAA,EAAQ,CAAA,EAAG,MAAM,CAAC,CAAA,CAAA,EAAI,KAAA,CAAM,IAAI,EAAE,CAAA,EAAG,MAAA,CAAO,MAAM,EAAE,CAAA,CAAE,aAAa,CAAA;AACrG;;;ACPA,IAAM,WAAA,GAAc,IAAA;AAEpB,IAAMA,IAAAA,GAAM,IAAI,WAAA,EAAY;AAE5B,IAAM,MAAA,GAAS,CAAC,KAAA,KACd,IAAA,CAAK,OAAO,YAAA,CAAa,GAAG,KAAK,CAAC,CAAA,CAC/B,QAAQ,KAAA,EAAO,GAAG,EAClB,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAClB,OAAA,CAAQ,OAAO,EAAE,CAAA;AAEtB,IAAM,UAAA,GAAa,CAAC,CAAA,KAClB,UAAA,CAAW,KAAK,IAAA,CAAK,CAAA,CAAE,QAAQ,IAAA,EAAM,GAAG,EAAE,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,CAAA,CAAE,UAAA,CAAW,CAAC,CAAC,CAAA;AAEvF,IAAM,IAAA,uBAAW,GAAA,EAAgC;AACjD,IAAM,MAAA,GAAS,CAAC,MAAA,KAAmB;AACjC,EAAA,IAAI,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;AACzB,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,GAAA,GAAM,OAAO,MAAA,CAAO,SAAA,CAAU,KAAA,EAAOA,IAAAA,CAAI,OAAO,MAAM,CAAA,EAAG,EAAE,IAAA,EAAM,QAAQ,IAAA,EAAM,SAAA,IAAa,KAAA,EAAO,CAAC,MAAM,CAAC,CAAA;AAC3G,IAAA,IAAA,CAAK,GAAA,CAAI,QAAQ,GAAG,CAAA;AAAA,EACtB;AACA,EAAA,OAAO,GAAA;AACT,CAAA;AAEA,eAAe,IAAA,CAAK,QAAgB,OAAA,EAAkC;AACpE,EAAA,MAAM,GAAA,GAAM,MAAM,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,MAAA,EAAQ,MAAM,MAAA,CAAO,MAAM,CAAA,EAAGA,IAAAA,CAAI,MAAA,CAAO,OAAO,CAAC,CAAA;AACtF,EAAA,OAAO,MAAA,CAAO,IAAI,UAAA,CAAW,GAAG,EAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA;AAChD;AAGO,SAAS,WAAW,SAAA,EAAwC;AACjE,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAsC;AACzD,EAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,IAAA,IAAI,CAAC,CAAA,CAAE,YAAA,IAAgB,CAAC,EAAE,WAAA,EAAa;AACvC,IAAA,KAAA,MAAW,CAAA,IAAK,EAAE,KAAA,EAAO;AACvB,MAAA,IAAI,CAAC,CAAA,CAAE,UAAA,IAAc,CAAC,EAAE,kBAAA,EAAoB;AAC5C,MAAA,IAAI,CAAC,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,WAAW,CAAA,EAAG,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,WAAA,kBAAa,IAAI,GAAA,EAAK,CAAA;AACnE,MAAA,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,WAAW,CAAA,CAAG,IAAI,CAAA,CAAE,UAAA,EAAY,CAAC,CAAA,CAAE,UAAA,EAAY,CAAA,CAAE,kBAAA,EAAoB,CAAA,CAAE,UAAU,CAAC,CAAA;AAAA,IACjG;AAAA,EACF;AACA,EAAA,OAAO,CAAC,GAAG,MAAA,CAAO,OAAA,EAAS,CAAA,CACxB,IAAA,CAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAA,CAAE,aAAA,CAAc,CAAC,CAAC,CAAA,CACrC,GAAA,CAAI,CAAC,CAAC,IAAA,EAAM,KAAK,CAAA,MAAO,EAAE,MAAM,KAAA,EAAO,CAAC,GAAG,KAAA,CAAM,MAAA,EAAQ,CAAA,CAAE,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA,KAAM,EAAE,aAAA,CAAc,CAAC,CAAC,CAAA,EAAE,CAAE,CAAA;AACzG;AAMA,eAAsB,aAAA,CAAc,MAAA,EAAqB,MAAA,EAAgB,KAAA,EAAkC;AACzG,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,KAAK,CAAC,CAAA;AAC7C,EAAA,MAAM,YAAY,CAAC,CAAA,KAAe,OAAOA,IAAAA,CAAI,MAAA,CAAO,KAAK,SAAA,CAAU,CAAA,KAAM,MAAA,GAAY,EAAE,GAAE,GAAI,EAAE,GAAG,CAAA,EAAG,CAAC,CAAC,CAAA;AACvG,EAAA,IAAI,OAAA,GAAU,UAAU,KAAK,CAAA;AAC7B,EAAA,IAAI,QAAQ,MAAA,GAAS,WAAA,IAAe,UAAU,MAAA,EAAW,OAAA,GAAU,UAAU,MAAS,CAAA;AACtF,EAAA,OAAO,GAAG,OAAO,CAAA,CAAA,EAAI,MAAM,IAAA,CAAK,MAAA,EAAQ,OAAO,CAAC,CAAA,CAAA;AAClD;AAGA,eAAsB,aAAA,CACpB,OACA,MAAA,EACoD;AACpD,EAAA,MAAM,CAAC,OAAA,EAAS,GAAA,EAAK,IAAI,CAAA,GAAI,KAAA,CAAM,MAAM,GAAG,CAAA;AAC5C,EAAA,IAAI,CAAC,WAAW,CAAC,GAAA,IAAO,SAAS,MAAA,IAAa,OAAA,CAAQ,MAAA,GAAS,WAAA,EAAa,OAAO,IAAA;AACnF,EAAA,IAAI,CAAC,WAAW,MAAM,IAAA,CAAK,QAAQ,OAAO,CAAA,EAAG,GAAG,CAAA,EAAG,OAAO,IAAA;AAC1D,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,IAAI,WAAA,GAAc,MAAA,CAAO,UAAA,CAAW,OAAO,CAAC,CAAC,CAAA;AACpE,IAAA,MAAM,MAAA,GAAS,GAAA,CAAI,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,IAAA,EAAM,KAAK,CAAA,MAAO,EAAE,IAAA,EAAM,KAAA,EAAM,CAAE,CAAA;AAC7D,IAAA,OAAO,GAAA,CAAI,CAAA,KAAM,KAAA,CAAA,GAAY,EAAE,MAAA,KAAW,EAAE,MAAA,EAAQ,KAAA,EAAO,GAAA,CAAI,CAAA,EAAE;AAAA,EACnE,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;;;AChFA,eAAsB,cAAc,IAAA,EAA+C;AACjF,EAAA,MAAM,QAAQ,IAAA,CAAK,OAAA,IAAW,gBAAA,EAAkB,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAClE,EAAA,MAAM,MAAM,MAAA,CAAO,IAAA,CAAK,SAAS,KAAA,EAAO,CAAA,EAAG,IAAI,CAAA,kCAAA,CAAA,EAAsC;AAAA,IACnF,GAAG,IAAA,CAAK,IAAA;AAAA,IACR,SAAS,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,KAAK,CAAA,CAAA,EAAG;AAAA,IACjD,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,IAAA,CAAK,aAAa,GAAK;AAAA,GACpD,CAAA;AACD,EAAA,IAAI,CAAC,IAAI,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAC7D,EAAA,OAAQ,MAAM,IAAI,IAAA,EAAK;AACzB;AAOO,SAAS,aAAa,CAAA,EAA6B;AACxD,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAC9B,EAAA,KAAA,MAAW,KAAK,CAAA,CAAE,IAAA,IAAQ,EAAC,MAAO,CAAA,CAAE,IAAA,KAAS,KAAA,EAAO,KAAA,MAAW,KAAK,CAAA,CAAE,KAAA,IAAS,EAAC,EAAG,KAAA,CAAM,IAAI,CAAC,CAAA;AAC9F,EAAA,OAAO,EAAE,OAAA,EAAS,CAAA,CAAE,OAAA,EAAS,KAAA,EAAO,CAAC,GAAG,KAAK,CAAA,CAAE,IAAA,EAAK,EAAE;AACxD","file":"chunk-OMMIRSPK.js","sourcesContent":["import { consentCookieName } from \"../core/cookie-names\";\nimport { parseCookies } from \"../server/cookies\";\n\nexport interface EdgeConsent {\n /** Off: don't ask Xenia, serve base content. */\n personalization: boolean;\n /** Off: decide, but keep no trail or click cookies and send no trail. */\n analytics: boolean;\n}\n\n/**\n * What the edge flow may do for this request, from the consent cookie the browser client's\n * `consent()` writes and the visitor's privacy signals:\n * - no consent cookie (or an unreadable one) → no choice made: everything on, as before;\n * - an explicit choice → followed (JSON `{analytics, personalization}`, or the scopes form\n * `analytics,personalization` where an unlisted scope is refused);\n * - `Sec-GPC: 1` / `DNT: 1` → analytics off, like the browser client's `respectDnt` (default on).\n *\n * Unlike `getConsent()`, an absent cookie isn't \"all denied\": the edge can't tell a visitor who\n * refused from one who was never asked, and refusing both would change every first page view.\n */\nexport function edgeConsent(headers: Headers, opts: { prefix?: string; respectDnt?: boolean } = {}): EdgeConsent {\n const raw = parseCookies(headers.get(\"cookie\"))[consentCookieName(opts.prefix)];\n let consent: EdgeConsent = { personalization: true, analytics: true };\n if (raw) {\n try {\n const parsed: unknown = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\") {\n const p = parsed as Record<string, unknown>;\n consent = { personalization: p.personalization !== false, analytics: p.analytics !== false };\n }\n } catch {\n if (/^[a-z]+(\\s*,\\s*[a-z]+)*$/i.test(raw.trim())) {\n const scopes = new Set(raw.split(\",\").map((s) => s.trim()));\n consent = { personalization: scopes.has(\"personalization\"), analytics: scopes.has(\"analytics\") };\n }\n }\n }\n const privacySignal = headers.get(\"sec-gpc\") === \"1\" || headers.get(\"dnt\") === \"1\";\n if (opts.respectDnt !== false && privacySignal) consent = { ...consent, analytics: false };\n return consent;\n}\n","/**\n * Facts about a request that journey rules read — where the visitor is, on what device, where they\n * came from, their local time — derived from a standard `Request` in any runtime.\n */\nimport type { ViewerGeo } from \"./types\";\n\nconst GEO_KEYS = [\n \"country\",\n \"countryName\",\n \"region\",\n \"regionName\",\n \"city\",\n \"postalCode\",\n \"timeZone\",\n \"latitude\",\n \"longitude\",\n \"source\",\n] as const;\n\n/** Any host's geo object (Netlify, Next.js runtimes, our own edge function). */\ntype GeoLike = {\n country?: string | { code?: string; name?: string };\n countryName?: string;\n region?: string;\n subdivision?: { code?: string; name?: string };\n regionName?: string;\n city?: string;\n postalCode?: string;\n timeZone?: string;\n timezone?: string;\n latitude?: string | number;\n longitude?: string | number;\n};\n\n/** Normalizes any host's geo object into Xenia's `ViewerGeo` keys (values over 100 chars dropped). */\nfunction toViewerGeo(g: GeoLike | undefined, source: string): ViewerGeo | undefined {\n if (!g) return undefined;\n const country = typeof g.country === \"string\" ? g.country : g.country?.code;\n if (!country) return undefined;\n const raw: Record<string, unknown> = {\n country: country.toUpperCase(),\n countryName: g.countryName ?? (typeof g.country === \"object\" ? g.country?.name : undefined),\n region: g.region ?? g.subdivision?.code,\n regionName: g.regionName ?? g.subdivision?.name,\n city: g.city,\n postalCode: g.postalCode,\n timeZone: g.timeZone ?? g.timezone,\n latitude: g.latitude?.toString(),\n longitude: g.longitude?.toString(),\n source,\n };\n const geo: ViewerGeo = {};\n for (const k of GEO_KEYS) {\n const v = raw[k];\n if (typeof v === \"string\" && v && v.length <= 100) geo[k] = v;\n }\n return geo;\n}\n\nconst parseJson = (text: string): GeoLike | undefined => {\n try {\n return JSON.parse(text) as GeoLike;\n } catch {\n return undefined;\n }\n};\n\nfunction safeDecode(v: string): string {\n try {\n return decodeURIComponent(v);\n } catch {\n return v;\n }\n}\n\nfunction safeBase64(v: string): string {\n try {\n return atob(v);\n } catch {\n return \"\";\n }\n}\n\n/** Netlify's per-request context, when running in Netlify's runtime. */\nfunction netlifyContext(): { geo?: GeoLike } | undefined {\n try {\n return (globalThis as unknown as { Netlify?: { context?: { geo?: GeoLike } | null } }).Netlify?.context ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nconst COUNTRY_HEADERS = [\"x-country\", \"x-vercel-ip-country\", \"cloudfront-viewer-country\", \"cf-ipcountry\"];\n\n/** The location headers `viewerGeo` can read, when trusted. */\nexport type GeoHeader = \"x-xn-geo\" | \"x-nf-geo\" | \"x-country\" | \"x-vercel-ip-country\" | \"cloudfront-viewer-country\" | \"cf-ipcountry\";\n\nfunction companions(h: Headers, country: string): GeoLike {\n const of = (name: string) => h.get(name) ?? undefined;\n if (country === \"x-vercel-ip-country\") {\n return { region: of(\"x-vercel-ip-country-region\"), city: safeDecode(of(\"x-vercel-ip-city\") ?? \"\") || undefined, timeZone: of(\"x-vercel-ip-timezone\") };\n }\n if (country === \"cloudfront-viewer-country\") {\n return { region: of(\"cloudfront-viewer-country-region\"), city: safeDecode(of(\"cloudfront-viewer-city\") ?? \"\") || undefined, timeZone: of(\"cloudfront-viewer-time-zone\") };\n }\n return {};\n}\n\n/**\n * The visitor's location as the hosting edge resolved it, and which source supplied it (`via`).\n * Geo must come from the storefront's edge, never Xenia's: `/decide` is server to server. Tried in\n * order — whichever the host provides:\n * 1. Netlify's per-request `Netlify.context.geo` (can't be spoofed by the client, unlike a header)\n * 2. `x-xn-geo` (URI-encoded JSON) from the site's own edge function\n * 3. a `request.geo` some runtimes attach\n * 4. Netlify's `x-nf-geo` header (base64 or URI-encoded JSON)\n * 5. `x-country` (Netlify), `x-vercel-ip-*`, `cloudfront-viewer-*`, `cf-ipcountry`\n * 6. `?xn_country=GB` — only with `devOverride`, for testing geo rules without an edge\n *\n * Headers (2, 4 and 5) are read only when named in `trust`: a visitor can send any header, and only\n * the site knows which ones its own host or edge function sets (and overwrites). Name exactly those,\n * e.g. `[\"x-vercel-ip-country\"]` on Vercel, `[\"cf-ipcountry\"]` behind Cloudflare,\n * `[\"x-nf-geo\", \"x-country\"]` on Netlify. 1 and 3 come from the runtime and are always used.\n */\nexport function viewerGeo(\n request: Request,\n opts: { devOverride?: boolean; trust?: readonly GeoHeader[] } = {},\n): { geo?: ViewerGeo; via: string } {\n const trusted = new Set<string>(opts.trust ?? []);\n const fromNetlify = toViewerGeo(netlifyContext()?.geo, \"edge\");\n if (fromNetlify) return { geo: fromNetlify, via: \"Netlify.context\" };\n\n const h = { get: (name: string) => (trusted.has(name) ? request.headers.get(name) : null) };\n const xn = h.get(\"x-xn-geo\");\n const fromXn = xn ? toViewerGeo(parseJson(safeDecode(xn)), \"edge\") : undefined;\n if (fromXn) return { geo: fromXn, via: \"x-xn-geo (edge function)\" };\n\n const fromRuntime = toViewerGeo((request as unknown as { geo?: GeoLike }).geo, \"edge\");\n if (fromRuntime) return { geo: fromRuntime, via: \"request.geo\" };\n\n const nf = h.get(\"x-nf-geo\");\n if (nf) {\n const fromNf = toViewerGeo(parseJson(safeBase64(nf)) ?? parseJson(safeDecode(nf)), \"edge\");\n if (fromNf) return { geo: fromNf, via: \"x-nf-geo\" };\n }\n\n const via = COUNTRY_HEADERS.find((n) => h.get(n));\n const headerCountry = via ? h.get(via) : null;\n if (via && headerCountry && /^[a-z]{2}$/i.test(headerCountry)) {\n const geo = toViewerGeo(\n {\n country: headerCountry,\n // The region, city and time zone of the same provider as the country header.\n ...companions(request.headers, via),\n },\n \"edge\",\n );\n return { geo, via };\n }\n\n const override = new URL(request.url).searchParams.get(\"xn_country\");\n if (opts.devOverride && override && /^[a-z]{2}$/i.test(override)) {\n return { geo: { country: override.toUpperCase(), source: \"dev\" }, via: \"?xn_country (dev)\" };\n }\n return { via: \"none\" };\n}\n\nexport function deviceOf(headers: Headers): \"mobile\" | \"tablet\" | \"desktop\" {\n const ua = headers.get(\"user-agent\") ?? \"\";\n if (/iPad|Tablet/i.test(ua)) return \"tablet\";\n if (headers.get(\"sec-ch-ua-mobile\") === \"?1\" || /Mobi|Android|iPhone/i.test(ua)) return \"mobile\";\n return \"desktop\";\n}\n\nconst BOT = /bot|crawl|spider|slurp|facebookexternalhit|embedly|preview|whatsapp|bingpreview/i;\n\n/** Crawlers and link-preview fetchers: never decided, never recorded. */\nexport function isBot(userAgent: string | null | undefined): boolean {\n return BOT.test(userAgent ?? \"\");\n}\n\n/** Link prefetches pass through a proxy too; they aren't page views. */\nexport function isPrefetch(headers: Headers): boolean {\n return (\n headers.has(\"next-router-prefetch\") ||\n /prefetch/i.test(headers.get(\"purpose\") ?? \"\") ||\n /prefetch/i.test(headers.get(\"sec-purpose\") ?? \"\")\n );\n}\n\n/**\n * Whether this is the browser loading a page (a full page load), by `Sec-Fetch-Dest`. Requests\n * without it (old browsers, curl) count as page loads.\n */\nexport function isPageLoad(headers: Headers): boolean {\n return (headers.get(\"sec-fetch-dest\") ?? \"document\") === \"document\" && !isPrefetch(headers);\n}\n\nconst UTM: Record<string, string> = {\n utm_source: \"utmSource\",\n utm_medium: \"utmMedium\",\n utm_campaign: \"utmCampaign\",\n utm_content: \"utmContent\",\n utm_term: \"utmTerm\",\n utm_id: \"utmId\",\n};\n\n/**\n * This session's landing context — first-touch attribution, so a campaign carries across pages:\n * the UTMs (≤200 chars each) and an external referrer (≤500), refreshed when the visitor arrives\n * from a new campaign. `saved` is the value kept from earlier (a cookie); `changed` says to save it.\n */\nexport function landingContext(\n url: URL,\n referrer: string | null | undefined,\n saved: string | undefined,\n): { ctx: Record<string, string>; changed: boolean } {\n const fromQuery: Record<string, string> = {};\n for (const [param, fact] of Object.entries(UTM)) {\n const v = url.searchParams.get(param);\n if (v) fromQuery[fact] = v.slice(0, 200);\n }\n const external = referrer && !referrer.startsWith(url.origin) ? referrer.slice(0, 500) : null;\n\n let kept: Record<string, string> | null;\n try {\n const parsed: unknown = saved ? JSON.parse(saved) : null;\n kept = parsed && typeof parsed === \"object\" && !Array.isArray(parsed) ? (parsed as Record<string, string>) : null;\n } catch {\n kept = null;\n }\n if (kept && !Object.keys(fromQuery).length) return { ctx: kept, changed: false };\n return { ctx: { ...fromQuery, ...(external ? { referrer: external } : {}) }, changed: true };\n}\n\nconst WEEKDAYS = [\"sunday\", \"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\", \"saturday\"];\n\n/** Meteorological seasons: Dec–Feb winter, Mar–May spring, Jun–Aug summer, Sep–Nov fall. */\nexport function seasonOf(month: number, southernHemisphere = false): string {\n const north = [\"winter\", \"winter\", \"spring\", \"spring\", \"spring\", \"summer\", \"summer\", \"summer\", \"fall\", \"fall\", \"fall\", \"winter\"];\n const season = north[(month - 1 + 12) % 12];\n if (!southernHemisphere) return season;\n return ({ winter: \"summer\", summer: \"winter\", spring: \"fall\", fall: \"spring\" } as Record<string, string>)[season] ?? season;\n}\n\nfunction validTimeZone(tz: string | undefined): string | undefined {\n if (!tz) return undefined;\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: tz });\n return tz;\n } catch {\n return undefined;\n }\n}\n\nexport interface LocalTime {\n local_weekday: string;\n local_month: number;\n local_hour: number;\n is_weekend: boolean;\n season: string;\n}\n\n/** Weekday, month, hour and season where the visitor is (their time zone; UTC when unknown). */\nexport function localTime(geo: ViewerGeo | undefined, now: Date): LocalTime {\n const timeZone = validTimeZone(geo?.timeZone) ?? \"UTC\";\n const parts = Object.fromEntries(\n new Intl.DateTimeFormat(\"en-US\", { timeZone, weekday: \"long\", month: \"numeric\", hour: \"numeric\", hourCycle: \"h23\" })\n .formatToParts(now)\n .map((p) => [p.type, p.value]),\n );\n const weekday = String(parts.weekday ?? WEEKDAYS[now.getUTCDay()]).toLowerCase();\n const month = Number(parts.month) || now.getUTCMonth() + 1;\n return {\n local_weekday: weekday,\n local_month: month,\n local_hour: Number(parts.hour) % 24,\n is_weekend: weekday === \"saturday\" || weekday === \"sunday\",\n season: seasonOf(month, Number(geo?.latitude) < 0),\n };\n}\n","/**\n * The visitor's recent page views, most recent first, kept in a short-lived first-party cookie\n * (`[[path, at], [path, at, seconds], …]`). The proxy sends it with `/decide`, so profile rules see\n * pages whose analytics events haven't been processed yet; the browser adds client-side navigations\n * and the time spent on a page as the visitor leaves it. Shared by both sides.\n */\nimport { DEFAULT_PREFIX } from \"../core/cookie-names\";\nimport type { TrailView } from \"./types\";\n\nexport const MAX_TRAIL = 8;\n/** Cookie lifetime: a visit ends after 30 idle minutes, like the SDK's session. */\nexport const TRAIL_MAX_AGE_S = 30 * 60;\n\nexport function trailCookieName(prefix: string = DEFAULT_PREFIX): string {\n return `${prefix}_trail`;\n}\n\nconst decode = (v: string) => {\n try {\n return decodeURIComponent(v);\n } catch {\n return v;\n }\n};\n\n/** The trail in a cookie value (raw or URI-encoded); anything malformed reads as no trail. */\nexport function readTrail(value: string | undefined | null): TrailView[] {\n if (!value) return [];\n try {\n const parsed: unknown = JSON.parse(decode(value));\n if (!Array.isArray(parsed)) return [];\n return parsed\n .filter((t): t is [string, number, number?] => Array.isArray(t) && typeof t[0] === \"string\" && typeof t[1] === \"number\")\n .slice(0, MAX_TRAIL)\n .map(([path, at, seconds]) =>\n typeof seconds === \"number\" && seconds >= 0 && seconds <= 86_400 ? { path, at, seconds } : { path, at },\n );\n } catch {\n return [];\n }\n}\n\n/**\n * The trail with this view first: a revisit moves to the front and keeps its first time (its old\n * time on page is dropped — this view's isn't known yet). The same array when `path` is already first.\n */\nexport function withView(trail: TrailView[], path: string, now: number = Date.now()): TrailView[] {\n if (trail[0]?.path === path) return trail;\n const earlier = trail.find((t) => t.path === path);\n return [{ path, at: earlier?.at ?? now }, ...trail.filter((t) => t.path !== path)].slice(0, MAX_TRAIL);\n}\n\n/** The cookie value for a trail (not URI-encoded; cookie setters encode it). */\nexport function trailCookieValue(trail: TrailView[]): string {\n return JSON.stringify(\n trail.slice(0, MAX_TRAIL).map((t) => (t.seconds === undefined ? [t.path, t.at] : [t.path, t.at, t.seconds])),\n );\n}\n","const enc = new TextEncoder();\n\nasync function hmacHex(secret: string, payload: string): Promise<string> {\n const key = await crypto.subtle.importKey(\"raw\", enc.encode(secret), { name: \"HMAC\", hash: \"SHA-256\" }, false, [\"sign\"]);\n const mac = new Uint8Array(await crypto.subtle.sign(\"HMAC\", key, enc.encode(payload)));\n return Array.from(mac, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n/** Constant-time comparison, so a signature can't be guessed byte by byte. */\nexport function sameString(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i);\n return diff === 0;\n}\n\n/**\n * Whether a storefront webhook from Xenia is genuine and fresh:\n * `X-Xenia-Signature: t=<unix s>,v1=<hex HMAC-SHA256(secret, \"<t>.<body>\")>`. Requests older than\n * `toleranceS` are refused, so a captured request can't be replayed. Pass the raw body text.\n */\nexport async function verifyWebhook(\n input: { headers: Headers; body: string },\n secret: string,\n toleranceS = 300,\n): Promise<boolean> {\n const header = input.headers.get(\"x-xenia-signature\") ?? \"\";\n if (!secret || !header) return false;\n const parts = Object.fromEntries(header.split(\",\").map((p) => p.trim().split(\"=\", 2)));\n const t = Number(parts.t);\n if (!Number.isFinite(t) || Math.abs(Date.now() / 1000 - t) > toleranceS || !parts.v1) return false;\n return sameString(await hmacHex(secret, `${parts.t}.${input.body}`), String(parts.v1).toLowerCase());\n}\n","/**\n * The proxy hands a decision to the page as a signed token in the rewritten URL\n * (`/xv/<token>/women`). The token is just the swaps — identical for every visitor in the same\n * variant — so each variant renders once and is then served from the ISR/CDN cache like any static\n * page. A site may carry its own data along (`extra`), e.g. what the page fills itself from.\n *\n * Signed (HMAC-SHA256) so nobody can craft a URL that renders arbitrary entries. Web Crypto only, so\n * it runs in any runtime.\n */\nimport type { EdgeDecision } from \"./types\";\nimport { sameString } from \"./webhook\";\n\n/**\n * One swap: the base entry's field, the entry shown in its place, and the content key whose\n * decision it is — so the page can report impressions and clicks per journey and entry.\n */\nexport type VariantSwap = [identifier: string, replacementEntryId: string, contentKey?: string];\n\n/** Swaps for one base entry. */\nexport interface SwapGroup {\n base: string;\n swaps: VariantSwap[];\n}\n\n/** The longest payload `decodeVariant` accepts. */\nconst MAX_PAYLOAD = 4096;\n\nconst enc = new TextEncoder();\n\nconst b64url = (bytes: Uint8Array) =>\n btoa(String.fromCharCode(...bytes))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n\nconst fromB64url = (s: string) =>\n Uint8Array.from(atob(s.replace(/-/g, \"+\").replace(/_/g, \"/\")), (c) => c.charCodeAt(0));\n\nconst keys = new Map<string, Promise<CryptoKey>>();\nconst keyFor = (secret: string) => {\n let key = keys.get(secret);\n if (!key) {\n key = crypto.subtle.importKey(\"raw\", enc.encode(secret), { name: \"HMAC\", hash: \"SHA-256\" }, false, [\"sign\"]);\n keys.set(secret, key);\n }\n return key;\n};\n\nasync function sign(secret: string, payload: string): Promise<string> {\n const mac = await crypto.subtle.sign(\"HMAC\", await keyFor(secret), enc.encode(payload));\n return b64url(new Uint8Array(mac).slice(0, 16));\n}\n\n/** The swap groups of the personalized decisions, in a stable order (stable cache keys). */\nexport function swapGroups(decisions: EdgeDecision[]): SwapGroup[] {\n const byBase = new Map<string, Map<string, VariantSwap>>();\n for (const d of decisions) {\n if (!d.personalized || !d.baseEntryId) continue;\n for (const s of d.swaps) {\n if (!s.identifier || !s.replacementEntryId) continue;\n if (!byBase.has(d.baseEntryId)) byBase.set(d.baseEntryId, new Map());\n byBase.get(d.baseEntryId)!.set(s.identifier, [s.identifier, s.replacementEntryId, d.contentKey]);\n }\n }\n return [...byBase.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([base, swaps]) => ({ base, swaps: [...swaps.values()].sort(([a], [b]) => a.localeCompare(b)) }));\n}\n\n/**\n * The token for a variant. An `extra` that would push it past the payload limit is left out — the\n * page still renders its swaps — rather than making a token no page accepts.\n */\nexport async function encodeVariant(groups: SwapGroup[], secret: string, extra?: unknown): Promise<string> {\n const g = groups.map((x) => [x.base, x.swaps]);\n const payloadOf = (x: unknown) => b64url(enc.encode(JSON.stringify(x === undefined ? { g } : { g, x })));\n let payload = payloadOf(extra);\n if (payload.length > MAX_PAYLOAD && extra !== undefined) payload = payloadOf(undefined);\n return `${payload}.${await sign(secret, payload)}`;\n}\n\n/** The variant in a token, or `null` if it is malformed or not signed with `secret`. */\nexport async function decodeVariant<E = unknown>(\n token: string,\n secret: string,\n): Promise<{ groups: SwapGroup[]; extra?: E } | null> {\n const [payload, mac, rest] = token.split(\".\");\n if (!payload || !mac || rest !== undefined || payload.length > MAX_PAYLOAD) return null;\n if (!sameString(await sign(secret, payload), mac)) return null;\n try {\n const raw = JSON.parse(new TextDecoder().decode(fromB64url(payload))) as { g: [string, VariantSwap[]][]; x?: E };\n const groups = raw.g.map(([base, swaps]) => ({ base, swaps }));\n return raw.x === undefined ? { groups } : { groups, extra: raw.x };\n } catch {\n return null;\n }\n}\n","import { DEFAULT_BASE_URL } from \"../core/http-client\";\nimport type { Manifest, PublicManifest } from \"./types\";\n\nexport interface FetchManifestOptions {\n /** Xenia engine base URL. Default the hosted engine. */\n baseUrl?: string;\n /** A server-type SDK token. */\n token: string;\n /** Default 5000 ms. */\n timeoutMs?: number;\n fetch?: typeof fetch;\n /** Extra fetch options, e.g. Next.js `{ next: { revalidate } }`. */\n init?: RequestInit;\n}\n\n/** Xenia's manifest (`GET /api/personalization/edge/manifest`). Throws on a non-2xx answer. */\nexport async function fetchManifest(opts: FetchManifestOptions): Promise<Manifest> {\n const base = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n const res = await (opts.fetch ?? fetch)(`${base}/api/personalization/edge/manifest`, {\n ...opts.init,\n headers: { Authorization: `Bearer ${opts.token}` },\n signal: AbortSignal.timeout(opts.timeoutMs ?? 5_000),\n });\n if (!res.ok) throw new Error(`[xenia] manifest ${res.status}`);\n return (await res.json()) as Manifest;\n}\n\n/**\n * The manifest as a storefront may serve it publicly (e.g. from a CDN): the version and the page\n * patterns any live journey targets — no content keys, modes or rules. A proxy reading it decides by\n * path, and Xenia picks the content keys itself.\n */\nexport function trimManifest(m: Manifest): PublicManifest {\n const pages = new Set<string>();\n for (const k of m.keys ?? []) if (k.mode !== \"off\") for (const p of k.pages ?? []) pages.add(p);\n return { version: m.version, pages: [...pages].sort() };\n}\n"]}