export declare const postHogProviderLazyTemplate = "\"use client\";\n\nimport posthog from \"posthog-js\";\nimport { Suspense, useEffect, useRef, useState } from \"react\";\nimport { usePathname, useSearchParams } from \"next/navigation\";\nimport rawAnalyticsConfig from \"@/analytics.json\";\n\ninterface AnalyticsConfig {\n provider?: string;\n posthog?: {\n key?: string;\n host?: string;\n };\n}\n\nconst analyticsConfig = rawAnalyticsConfig as AnalyticsConfig;\n\nconst posthogKey =\n analyticsConfig?.provider === \"posthog\" ? analyticsConfig.posthog?.key : null;\n\n// `host` is the *ingestion* endpoint (us.i.posthog.com); `ui_host` wants the\n// dashboard it belongs to (us.posthog.com), which is what \"view in PostHog\"\n// links and the toolbar point at. Self-hosted instances serve both from one\n// origin, so leaving those untouched is correct.\nconst uiHost = (\n analyticsConfig.posthog?.host || \"https://us.i.posthog.com\"\n).replace(\".i.posthog.com\", \".posthog.com\");\n\n/**\n * Adopt the session id the middleware already decided on (see proxy.ts), so the\n * server's document-load `$pageview` and every client event after it land in\n * the same session.\n *\n * Without this the two disagree: the middleware used to forward posthog-js's\n * own session id without checking whether it had expired, so a returning\n * reader's pageview was filed under a dead session and the real new session\n * began with no pageview in it \u2014 wrong landing page, wrong bounce rate.\n *\n * Reading document.cookie works on the first request because the middleware\n * sets the cookie on the same response that carries this HTML. Returns\n * undefined if absent or malformed, in which case posthog-js mints its own id\n * as before: degraded, never broken.\n */\n// Both the middleware and this file WRITE the session cookie, so these three\n// must stay identical to their counterparts in proxy.ts. They are duplicated\n// rather than shared because a client component cannot import from the\n// middleware. A drifted max-age here would silently expire live sessions.\nconst SESSION_COOKIE = \"dcp_sid\";\nconst SESSION_MAX_MS = 24 * 60 * 60 * 1000;\n\nfunction isValidSessionId(id: string): boolean {\n return /^[0-9a-f]{32}$/i.test(id.replace(/-/g, \"\"));\n}\n\nfunction readSessionCookie(): { id: string; startTs: number } | undefined {\n if (typeof document === \"undefined\") return undefined;\n\n const match = document.cookie.match(/(?:^|;\\s*)dcp_sid=([^;]*)/);\n if (!match) return undefined;\n\n // Cookie is `id.startTs.lastTs`; posthog-js requires the id be a UUID and\n // logs an error if not, so check before handing it over.\n const [id, startRaw] = decodeURIComponent(match[1]).split(\".\");\n const startTs = Number(startRaw);\n if (!isValidSessionId(id) || !Number.isFinite(startTs)) return undefined;\n\n return { id, startTs };\n}\n\nfunction readEdgeSessionId(): string | undefined {\n return readSessionCookie()?.id;\n}\n\n/**\n * Keep the session cookie's last-activity fresh, from the browser.\n *\n * This is the half of session upkeep the middleware deliberately does NOT do.\n * A response carrying `Set-Cookie` is not cacheable by Vercel's CDN, so\n * refreshing last-activity server-side would have put one on roughly every doc\n * page an engaged reader loads. A `document.cookie` write sets no response\n * header at all, so your doc pages stay cacheable \u2014 and the browser is the side\n * that actually sees soft navigations and in-page activity.\n *\n * `startTs` is carried forward while the id is unchanged, so the 24h hard cap\n * still measures from when the session really began; a rotation restarts it.\n */\nfunction syncSessionCookie(sessionId: string | undefined) {\n if (typeof document === \"undefined\" || !sessionId) return;\n if (!isValidSessionId(sessionId)) return;\n\n const now = Date.now();\n const existing = readSessionCookie();\n const startTs = existing?.id === sessionId ? existing.startTs : now;\n const secure = location.protocol === \"https:\" ? \"; secure\" : \"\";\n\n document.cookie =\n SESSION_COOKIE +\n \"=\" +\n sessionId +\n \".\" +\n startTs +\n \".\" +\n now +\n \"; path=/; max-age=\" +\n SESSION_MAX_MS / 1000 +\n \"; samesite=lax\" +\n secure;\n}\n\nfunction PostHogInit({ onReady }: { onReady: () => void }) {\n const initRef = useRef(false);\n\n useEffect(() => {\n if (!posthogKey) return;\n\n // The init guard deliberately does NOT wrap the subscription below.\n //\n // Under React StrictMode's dev double-invoke the effect runs, is cleaned\n // up, then runs again. With an early `return` here, that second run would\n // skip past the subscription and leave `onSessionId` permanently\n // unsubscribed \u2014 in dev only, which is precisely where you would go to\n // check that any of this works. Initialising once while re-subscribing on\n // every run is correct in both modes.\n if (!initRef.current) {\n initRef.current = true;\n\n const sessionID = readEdgeSessionId();\n\n posthog.init(posthogKey, {\n api_host: \"/ingest\",\n ui_host: uiHost,\n capture_pageview: false,\n capture_pageleave: true,\n // The middleware owns session identity; this makes the SDK agree.\n ...(sessionID ? { bootstrap: { sessionID } } : {}),\n loaded: (ph) => {\n // Write once at startup so a session the middleware adopted (and\n // therefore did not rewrite) still gets its last-activity advanced.\n syncSessionCookie(ph.get_session_id());\n onReady();\n },\n });\n }\n\n // Fires when the session id first appears and on every rotation, so the\n // cookie follows posthog-js rather than drifting from it. posthog-js is the\n // better judge of idleness \u2014 it sees every captured event, not just\n // navigations. Returning its unsubscribe doubles as the effect cleanup.\n return posthog.onSessionId((id: string) => syncSessionCookie(id));\n }, [onReady]);\n\n return null;\n}\n\n/**\n * Captures soft navigations only.\n *\n * The document load that got the reader here was already captured in the\n * middleware (see proxy.ts), so counting it again here is what produced two\n * `$pageview` events per page load. Server owns document loads, client owns\n * soft navigations: disjoint, so neither double-counts nor leaves a gap.\n */\nfunction PostHogPageviewTracker() {\n const pathname = usePathname();\n const searchParams = useSearchParams();\n const isFirstRun = useRef(true);\n\n useEffect(() => {\n if (isFirstRun.current) {\n isFirstRun.current = false;\n return;\n }\n if (pathname) {\n const url = searchParams?.size\n ? `${pathname}?${searchParams.toString()}`\n : pathname;\n posthog.capture(\"$pageview\", { $current_url: url });\n\n // A soft navigation is activity the middleware never sees, and\n // `onSessionId` won't fire because the id hasn't changed. Without this, a\n // reader who browses only via client-side links would look idle to the\n // next document load and have their session rotated out from under them.\n syncSessionCookie(posthog.get_session_id());\n }\n }, [pathname, searchParams]);\n\n return null;\n}\n\nexport function PostHogSetup() {\n const [ready, setReady] = useState(false);\n\n if (!posthogKey) {\n return null;\n }\n\n return (\n <>\n setReady(true)} />\n {ready && }\n \n );\n}\n";