feat: add client-side PostHog analytics and refactor /api/events to use posthog-node

- Add `src/components/posthog-provider.tsx` — initializes the `posthog-js` browser SDK once (guarded by `VITE_PUBLIC_POSTHOG_KEY` and `posthog.__loaded`) with history-based pageview capture, pageleave tracking, and session replay + autocapture disabled; wraps the app shell in `__root.tsx` via `<PostHogProvider>`
- Add `src/lib/analytics.ts` with a `useAnalytics` hook that returns a stable `capture` callback bound to the PostHog singleton (no-ops when the key is absent or the SDK is uninitialized) and a `selectionProperties` helper that flattens slot/addon selections into a consistent event property shape across events
- Wire `capture` into `Builder` (`builder_module_selected`, `builder_module_deselected`, `builder_addon_toggled`) and `CommandPreview` (`builder_command_copied` with `package_manager`, `command`, `name_customized`, `module_count`, and per-slot properties); add an `onCopied` callback prop to `CopyButton` to fire the capture after a successful clipboard write
- Add `src/server/posthog.server.ts` — a lazy singleton that constructs a `posthog-node` `PostHog` client from `VITE_PUBLIC_POSTHOG_KEY`/`VITE_PUBLIC_POSTHOG_HOST` and returns `null` when unconfigured; refactor `/api/events` to use this client instead of a raw `fetch` to PostHog's `/batch/` endpoint, and flush via `waitUntil` from `@vercel/functions` so the serverless function stays alive past the response without blocking it
This commit is contained in:
jake committed 2026-05-21 21:32:20 -04:00
1 parent 69e02522be
commit ab5ef7ec4a
10 files changed
+511 -50

No files matched your search

+3
View File
@@ -29,6 +29,7 @@
"@tanstack/react-start": "^1.168.10", "@tanstack/react-start": "^1.168.10",
"@tanstack/router-plugin": "^1.168.10", "@tanstack/router-plugin": "^1.168.10",
"@vercel/analytics": "^2.0.1", "@vercel/analytics": "^2.0.1",
"@vercel/functions": "^3.6.0",
"@vercel/og": "^0.11.1", "@vercel/og": "^0.11.1",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
@@ -36,6 +37,8 @@
"fumadocs-mdx": "^15.0.7", "fumadocs-mdx": "^15.0.7",
"fumadocs-ui": "npm:@fumadocs/base-ui@^16.9.0", "fumadocs-ui": "npm:@fumadocs/base-ui@^16.9.0",
"nitro": "^3.0.260429-beta", "nitro": "^3.0.260429-beta",
"posthog-js": "^1.375.0",
"posthog-node": "^5.35.0",
"react": "^19.2.6", "react": "^19.2.6",
"react-dom": "^19.2.6", "react-dom": "^19.2.6",
"react-resizable-panels": "^4.11.1", "react-resizable-panels": "^4.11.1",
+9 -3
View File
@@ -5,6 +5,7 @@ import { useCallback } from "react";
import { FilePreview } from "@/components/builder/file-preview"; import { FilePreview } from "@/components/builder/file-preview";
import { ProjectSetup } from "@/components/builder/project-setup"; import { ProjectSetup } from "@/components/builder/project-setup";
import { SlotCards } from "@/components/builder/slot-cards"; import { SlotCards } from "@/components/builder/slot-cards";
import { useAnalytics } from "@/lib/analytics";
import { import {
type AddonSelections, type AddonSelections,
type BuilderSearch, type BuilderSearch,
@@ -19,6 +20,7 @@ import type { BuilderState } from "@/server/builder-state.functions";
export function Builder({ state, search }: { state: BuilderState; search: BuilderSearch }) { export function Builder({ state, search }: { state: BuilderState; search: BuilderSearch }) {
const navigate = useNavigate({ from: "/" }); const navigate = useNavigate({ from: "/" });
const capture = useAnalytics();
const { name, selections, addons } = parseSelections(search); const { name, selections, addons } = parseSelections(search);
const resolved = resolveSelectedAdapters(state.modules, selections); const resolved = resolveSelectedAdapters(state.modules, selections);
const resolvedAddons = resolveSelectedAddons(state.modules, selections, addons); const resolvedAddons = resolveSelectedAddons(state.modules, selections, addons);
@@ -42,29 +44,33 @@ export function Builder({ state, search }: { state: BuilderState; search: Builde
const next: Selections = { ...selections }; const next: Selections = { ...selections };
if (id) next[slot] = id; if (id) next[slot] = id;
else delete next[slot]; else delete next[slot];
if (id) capture("builder_module_selected", { slot, module: id });
else capture("builder_module_deselected", { slot });
void navigate({ void navigate({
search: toSearchParams({ name, selections: next, addons }), search: toSearchParams({ name, selections: next, addons }),
replace: true, replace: true,
resetScroll: false, resetScroll: false,
}); });
}, },
[navigate, name, selections, addons], [capture, navigate, name, selections, addons],
); );
const toggleAddon = useCallback( const toggleAddon = useCallback(
(category: AddonCategoryId, id: string) => { (category: AddonCategoryId, id: string) => {
const current = addons[category] ?? []; const current = addons[category] ?? [];
const nextIds = current.includes(id) ? current.filter((x) => x !== id) : [...current, id]; const enabled = !current.includes(id);
const nextIds = enabled ? [...current, id] : current.filter((x) => x !== id);
const next: AddonSelections = { ...addons }; const next: AddonSelections = { ...addons };
if (nextIds.length > 0) next[category] = nextIds; if (nextIds.length > 0) next[category] = nextIds;
else delete next[category]; else delete next[category];
capture("builder_addon_toggled", { category, addon: id, enabled });
void navigate({ void navigate({
search: toSearchParams({ name, selections, addons: next }), search: toSearchParams({ name, selections, addons: next }),
replace: true, replace: true,
resetScroll: false, resetScroll: false,
}); });
}, },
[navigate, name, selections, addons], [capture, navigate, name, selections, addons],
); );
const commandBar = ( const commandBar = (
+19 -2
View File
@@ -1,7 +1,10 @@
import { useCallback } from "react";
import { CopyButton } from "@/components/copy-button"; import { CopyButton } from "@/components/copy-button";
import { PackageManagerSelect } from "@/components/package-manager-select"; import { PackageManagerSelect } from "@/components/package-manager-select";
import { selectionProperties, useAnalytics } from "@/lib/analytics";
import { usePackageManager } from "@/lib/package-manager"; import { usePackageManager } from "@/lib/package-manager";
import { type AddonSelections, buildCommand, type Selections } from "@/lib/selection"; import { type AddonSelections, buildCommand, DEFAULT_NAME, type Selections } from "@/lib/selection";
/** /**
* The `<pm> create stanza …` command box: a package-manager picker, the command * The `<pm> create stanza …` command box: a package-manager picker, the command
@@ -19,6 +22,20 @@ export function CommandPreview({
}) { }) {
const { pm, setPm } = usePackageManager(); const { pm, setPm } = usePackageManager();
const command = buildCommand({ name, selections, addons, pm }); const command = buildCommand({ name, selections, addons, pm });
const capture = useAnalytics();
const onCopied = useCallback(() => {
const addonSelections = addons ?? {};
capture("builder_command_copied", {
package_manager: pm,
command,
name_customized: name !== DEFAULT_NAME,
module_count:
Object.keys(selections).length +
Object.values(addonSelections).reduce((n, ids) => n + (ids?.length ?? 0), 0),
...selectionProperties(selections, addonSelections),
});
}, [capture, pm, command, name, selections, addons]);
return ( return (
<div className="flex items-stretch gap-2"> <div className="flex items-stretch gap-2">
@@ -26,7 +43,7 @@ export function CommandPreview({
<pre className="no-scrollbar flex h-8 min-w-0 flex-1 items-center overflow-x-auto rounded-none border border-border bg-muted/50 px-3 font-mono text-[11px] whitespace-pre [font-variant-ligatures:none] sm:text-xs"> <pre className="no-scrollbar flex h-8 min-w-0 flex-1 items-center overflow-x-auto rounded-none border border-border bg-muted/50 px-3 font-mono text-[11px] whitespace-pre [font-variant-ligatures:none] sm:text-xs">
<code>{command}</code> <code>{command}</code>
</pre> </pre>
<CopyButton value={command} /> <CopyButton value={command} onCopied={onCopied} />
</div> </div>
); );
} }
+4 -1
View File
@@ -10,19 +10,22 @@ export function CopyButton({
value, value,
label = "Copy command", label = "Copy command",
className, className,
onCopied,
}: { }: {
value: string; value: string;
label?: string; label?: string;
className?: string; className?: string;
onCopied?: () => void;
}) { }) {
const onCopy = useCallback(async () => { const onCopy = useCallback(async () => {
try { try {
await navigator.clipboard.writeText(value); await navigator.clipboard.writeText(value);
toast.success("Copied to clipboard"); toast.success("Copied to clipboard");
onCopied?.();
} catch { } catch {
toast.error("Couldn't access the clipboard"); toast.error("Couldn't access the clipboard");
} }
}, [value]); }, [value, onCopied]);
const trigger = useMemo( const trigger = useMemo(
() => ( () => (
@@ -0,0 +1,30 @@
import posthog from "posthog-js";
import { PostHogProvider as PostHogReactProvider } from "posthog-js/react";
/**
* Client-side PostHog. Initializes the browser SDK once, but only when a key is
* configured (`VITE_PUBLIC_POSTHOG_KEY`) — local dev and self-hosters without
* analytics get an uninitialized singleton that no-ops on capture, mirroring the
* `/api/events` proxy's "no key → do nothing" behavior.
*
* Auto-captures pageviews + pageleaves (history-based, for the SPA router) and
* web vitals; DOM click autocapture and session replay are off.
*/
const key = import.meta.env.VITE_PUBLIC_POSTHOG_KEY;
// oxlint-disable-next-line no-underscore-dangle
if (typeof window !== "undefined" && key && !posthog.__loaded) {
posthog.init(key, {
api_host: import.meta.env.VITE_PUBLIC_POSTHOG_HOST ?? "https://us.i.posthog.com",
defaults: "2026-01-30",
autocapture: false,
capture_pageview: "history_change",
capture_pageleave: true,
disable_session_recording: true,
});
}
export function PostHogProvider({ children }: { children: React.ReactNode }) {
return <PostHogReactProvider client={posthog}>{children}</PostHogReactProvider>;
}
+39
View File
@@ -0,0 +1,39 @@
import { KNOWN_SLOTS } from "@stanza/registry";
import { usePostHog } from "posthog-js/react";
import { useCallback } from "react";
import type { AddonSelections, Selections } from "@/lib/selection";
/**
* Stable `capture(event, properties)` bound to the client-side PostHog instance.
* Safe to call unconditionally: when no key is configured the singleton is
* uninitialized and `capture` is a no-op.
*/
export function useAnalytics(): (event: string, properties?: Record<string, unknown>) => void {
const posthog = usePostHog();
return useCallback(
(event, properties) => {
// oxlint-disable-next-line no-underscore-dangle
if (!posthog.__loaded) return;
posthog.capture(event, properties);
},
[posthog],
);
}
/**
* Flatten the current builder selection into event properties: one key per slot
* (`framework`, `db`, …) plus an `addons` array. Shared across the builder
* events so they all carry the same selection shape.
*/
export function selectionProperties(
selections: Selections,
addons: AddonSelections,
): Record<string, unknown> {
const props: Record<string, unknown> = {};
for (const slot of KNOWN_SLOTS) props[slot] = selections[slot] ?? null;
props.addons = Object.entries(addons).flatMap(([category, ids]) =>
(ids ?? []).map((id) => `${category}:${id}`),
);
return props;
}
+15 -12
View File
@@ -5,6 +5,7 @@ import { Analytics } from "@vercel/analytics/react";
import { Footer } from "@/components/footer"; import { Footer } from "@/components/footer";
import { Header } from "@/components/header"; import { Header } from "@/components/header";
import { PostHogProvider } from "@/components/posthog-provider";
import { ThemeProvider } from "@/components/theme-provider"; import { ThemeProvider } from "@/components/theme-provider";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Toaster } from "@/components/ui/sonner"; import { Toaster } from "@/components/ui/sonner";
@@ -84,18 +85,20 @@ function RootComponent() {
<HeadContent /> <HeadContent />
</head> </head>
<body className="min-h-svh bg-background font-sans text-foreground antialiased"> <body className="min-h-svh bg-background font-sans text-foreground antialiased">
<ThemeProvider defaultTheme="system" storageKey="stanza-theme"> <PostHogProvider>
<TooltipProvider> <ThemeProvider defaultTheme="system" storageKey="stanza-theme">
<div className="flex min-h-svh flex-col"> <TooltipProvider>
<Header /> <div className="flex min-h-svh flex-col">
<main className="flex-1"> <Header />
<Outlet /> <main className="flex-1">
</main> <Outlet />
<Footer /> </main>
</div> <Footer />
<Toaster /> </div>
</TooltipProvider> <Toaster />
</ThemeProvider> </TooltipProvider>
</ThemeProvider>
</PostHogProvider>
<TanStackDevtools config={DEVTOOLS_CONFIG} plugins={DEVTOOLS_PLUGINS} /> <TanStackDevtools config={DEVTOOLS_CONFIG} plugins={DEVTOOLS_PLUGINS} />
<Analytics /> <Analytics />
<Scripts /> <Scripts />
+24 -23
View File
@@ -1,15 +1,20 @@
import { createFileRoute } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router";
import { waitUntil } from "@vercel/functions";
import { getPostHogServerClient } from "@/server/posthog.server";
/** /**
* `POST /api/events` — analytics ingest for the `@stanza/cli`. The CLI sends * `POST /api/events` — analytics ingest for the `@stanza/cli`. The CLI sends
* plain `fetch` batches here so it never has to bundle `posthog-node`; this * plain `fetch` batches here so it never has to bundle `posthog-node`; this
* route holds the PostHog project key server-side and forwards to PostHog's * route holds the PostHog project key server-side and forwards each event via
* HTTP capture API. * the `posthog-node` client.
* *
* Configure via env (set these in the Vercel project for prod): * Configure via env (set these in the Vercel project for prod):
* POSTHOG_API_KEY — the PostHog project key. When unset the route no-ops * VITE_PUBLIC_POSTHOG_KEY — the PostHog project key. When unset the route
* (returns 204) so local dev / self-hosters never error. * no-ops (returns 204) so local dev / self-hosters
* POSTHOG_HOST — PostHog ingest host. Defaults to https://us.i.posthog.com. * never error.
* VITE_PUBLIC_POSTHOG_HOST — PostHog ingest host. Defaults to
* https://us.i.posthog.com.
*/ */
const MAX_EVENTS = 20; const MAX_EVENTS = 20;
@@ -51,30 +56,26 @@ export const Route = createFileRoute("/api/events")({
const payload = parsePayload(body); const payload = parsePayload(body);
if (!payload) return new Response("Invalid payload", { status: 400 }); if (!payload) return new Response("Invalid payload", { status: 400 });
const apiKey = process.env.VITE_PUBLIC_POSTHOG_KEY; const posthog = getPostHogServerClient();
// No key configured (local dev / self-host without analytics): accept // No key configured (local dev / self-host without analytics): accept
// and discard so the CLI never sees an error. // and discard so the CLI never sees an error.
if (!apiKey) return new Response(null, { status: 204 }); if (!posthog) return new Response(null, { status: 204 });
const host = process.env.VITE_PUBLIC_POSTHOG_HOST ?? "https://us.i.posthog.com"; for (const e of payload.events) {
const batch = payload.events.map((e) => ({ posthog.capture({
event: e.event, distinctId: payload.distinctId,
distinct_id: payload.distinctId, event: e.event,
properties: e.properties ?? {}, properties: e.properties ?? {},
timestamp: e.timestamp, timestamp: e.timestamp ? new Date(e.timestamp) : undefined,
}));
try {
await fetch(`${host.replace(/\/$/, "")}/batch/`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ api_key: apiKey, batch }),
signal: AbortSignal.timeout(5000),
}); });
} catch {
// Telemetry must never surface as a user-facing error — swallow.
} }
// Serverless functions can freeze before in-flight requests settle, so
// hand the flush to `waitUntil` to keep it alive past the response
// without blocking it. Telemetry must never surface as a user-facing
// error, so swallow failures.
waitUntil(posthog.flush().catch(() => {}));
return new Response(null, { status: 202 }); return new Response(null, { status: 202 });
}, },
}, },
+28
View File
@@ -0,0 +1,28 @@
import { PostHog } from "posthog-node";
/**
* Server-only PostHog client. Holds the project key (read from env) and talks
* to PostHog's HTTP API so the `/api/events` proxy never has to hand-roll the
* capture protocol. Returns `null` when no key is configured (local dev /
* self-host without analytics) so callers can no-op.
*
* `flushAt: 1` + `flushInterval: 0` make capture send eagerly; serverless
* handlers should still `await client.flush()` before returning since the
* function may freeze before an in-flight request settles.
*/
let client: PostHog | null = null;
export function getPostHogServerClient(): PostHog | null {
const apiKey = process.env.VITE_PUBLIC_POSTHOG_KEY;
if (!apiKey) return null;
if (!client) {
client = new PostHog(apiKey, {
host: process.env.VITE_PUBLIC_POSTHOG_HOST ?? "https://us.i.posthog.com",
flushAt: 1,
flushInterval: 0,
});
}
return client;
}
+340 -9
View File
@@ -74,7 +74,7 @@ importers:
version: 6.0.3 version: 6.0.3
vitest: vitest:
specifier: ^4.1.7 specifier: ^4.1.7
version: 4.1.7(@types/node@25.9.1)(jsdom@29.1.1(@noble/hashes@1.8.0))(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)) version: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(jsdom@29.1.1(@noble/hashes@1.8.0))(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3))
apps/web: apps/web:
dependencies: dependencies:
@@ -123,6 +123,9 @@ importers:
'@vercel/analytics': '@vercel/analytics':
specifier: ^2.0.1 specifier: ^2.0.1
version: 2.0.1(react@19.2.6) version: 2.0.1(react@19.2.6)
'@vercel/functions':
specifier: ^3.6.0
version: 3.6.0
'@vercel/og': '@vercel/og':
specifier: ^0.11.1 specifier: ^0.11.1
version: 0.11.1 version: 0.11.1
@@ -143,7 +146,13 @@ importers:
version: '@fumadocs/base-ui@16.9.0(@tailwindcss/oxide@4.3.0)(@types/mdx@2.0.13)(@types/react@19.2.15)(fumadocs-core@16.9.0(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(tailwindcss@4.3.0)' version: '@fumadocs/base-ui@16.9.0(@tailwindcss/oxide@4.3.0)(@types/mdx@2.0.13)(@types/react@19.2.15)(fumadocs-core@16.9.0(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(tailwindcss@4.3.0)'
nitro: nitro:
specifier: ^3.0.260429-beta specifier: ^3.0.260429-beta
version: 3.0.260429-beta(chokidar@5.0.0)(dotenv@17.4.2)(jiti@2.7.0)(lru-cache@11.5.0)(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)) version: 3.0.260429-beta(@vercel/functions@3.6.0)(chokidar@5.0.0)(dotenv@17.4.2)(jiti@2.7.0)(lru-cache@11.5.0)(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3))
posthog-js:
specifier: ^1.375.0
version: 1.375.0
posthog-node:
specifier: ^5.35.0
version: 5.35.0
react: react:
specifier: ^19.2.6 specifier: ^19.2.6
version: 19.2.6 version: 19.2.6
@@ -210,7 +219,7 @@ importers:
version: 8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3) version: 8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)
vitest: vitest:
specifier: ^4.1.7 specifier: ^4.1.7
version: 4.1.7(@types/node@25.9.1)(jsdom@29.1.1(@noble/hashes@1.8.0))(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)) version: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(jsdom@29.1.1(@noble/hashes@1.8.0))(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3))
web-vitals: web-vitals:
specifier: ^5.2.0 specifier: ^5.2.0
version: 5.2.0 version: 5.2.0
@@ -232,7 +241,7 @@ importers:
version: 6.0.3 version: 6.0.3
vitest: vitest:
specifier: ^4.1.7 specifier: ^4.1.7
version: 4.1.7(@types/node@25.9.1)(jsdom@29.1.1(@noble/hashes@1.8.0))(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)) version: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(jsdom@29.1.1(@noble/hashes@1.8.0))(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3))
packages/create-stanza: packages/create-stanza:
dependencies: dependencies:
@@ -261,7 +270,7 @@ importers:
version: 6.0.3 version: 6.0.3
vitest: vitest:
specifier: ^4.1.7 specifier: ^4.1.7
version: 4.1.7(@types/node@25.9.1)(jsdom@29.1.1(@noble/hashes@1.8.0))(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)) version: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(jsdom@29.1.1(@noble/hashes@1.8.0))(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3))
registry/modules/auth-better-auth: registry/modules/auth-better-auth:
dependencies: dependencies:
@@ -1200,6 +1209,78 @@ packages:
'@open-draft/until@2.1.0': '@open-draft/until@2.1.0':
resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==}
'@opentelemetry/api-logs@0.208.0':
resolution: {integrity: sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg==}
engines: {node: '>=8.0.0'}
'@opentelemetry/api@1.9.1':
resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==}
engines: {node: '>=8.0.0'}
'@opentelemetry/core@2.2.0':
resolution: {integrity: sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
'@opentelemetry/core@2.7.1':
resolution: {integrity: sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
'@opentelemetry/exporter-logs-otlp-http@0.208.0':
resolution: {integrity: sha512-jOv40Bs9jy9bZVLo/i8FwUiuCvbjWDI+ZW13wimJm4LjnlwJxGgB+N/VWOZUTpM+ah/awXeQqKdNlpLf2EjvYg==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/otlp-exporter-base@0.208.0':
resolution: {integrity: sha512-gMd39gIfVb2OgxldxUtOwGJYSH8P1kVFFlJLuut32L6KgUC4gl1dMhn+YC2mGn0bDOiQYSk/uHOdSjuKp58vvA==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/otlp-transformer@0.208.0':
resolution: {integrity: sha512-DCFPY8C6lAQHUNkzcNT9R+qYExvsk6C5Bto2pbNxgicpcSWbe2WHShLxkOxIdNcBiYPdVHv/e7vH7K6TI+C+fQ==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/resources@2.2.0':
resolution: {integrity: sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.3.0 <1.10.0'
'@opentelemetry/resources@2.7.1':
resolution: {integrity: sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.3.0 <1.10.0'
'@opentelemetry/sdk-logs@0.208.0':
resolution: {integrity: sha512-QlAyL1jRpOeaqx7/leG1vJMp84g0xKP6gJmfELBpnI4O/9xPX+Hu5m1POk9Kl+veNkyth5t19hRlN6tNY1sjbA==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.4.0 <1.10.0'
'@opentelemetry/sdk-metrics@2.2.0':
resolution: {integrity: sha512-G5KYP6+VJMZzpGipQw7Giif48h6SGQ2PFKEYCybeXJsOCB4fp8azqMAAzE5lnnHK3ZVwYQrgmFbsUJO/zOnwGw==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.9.0 <1.10.0'
'@opentelemetry/sdk-trace-base@2.2.0':
resolution: {integrity: sha512-xWQgL0Bmctsalg6PaXExmzdedSp3gyKV8mQBwK/j9VGdCDu2fmXIb2gAehBKbkXCpJ4HPkgv3QfoJWRT4dHWbw==}
engines: {node: ^18.19.0 || >=20.6.0}
peerDependencies:
'@opentelemetry/api': '>=1.3.0 <1.10.0'
'@opentelemetry/semantic-conventions@1.41.1':
resolution: {integrity: sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==}
engines: {node: '>=14'}
'@orama/orama@3.1.18': '@orama/orama@3.1.18':
resolution: {integrity: sha512-a61ljmRVVyG5MC/698C8/FfFDw5a8LOIvyOLW5fztgUXqUpc1jOfQzOitSCbge657OgXXThmY3Tk8fpiDb4UcA==} resolution: {integrity: sha512-a61ljmRVVyG5MC/698C8/FfFDw5a8LOIvyOLW5fztgUXqUpc1jOfQzOitSCbge657OgXXThmY3Tk8fpiDb4UcA==}
engines: {node: '>= 20.0.0'} engines: {node: '>= 20.0.0'}
@@ -1587,6 +1668,42 @@ packages:
react: ^18.3.1 || ^19.0.0 react: ^18.3.1 || ^19.0.0
react-dom: ^18.3.1 || ^19.0.0 react-dom: ^18.3.1 || ^19.0.0
'@posthog/core@1.29.8':
resolution: {integrity: sha512-wdX4/WzZ+sV92z4ppC9SjOWdztY/0bN74SbJFy1X8/1N8+aNTSHsGEKHtbHitkIkJc861oYWr4ZzOoV0iVDP4w==}
'@posthog/types@1.375.0':
resolution: {integrity: sha512-ykjHtJv1eUnEUQIuCavMi/+lnBhZPRVnFDrbG6m4fS+vZ3ajn8dGooPpbWjF33Uo4g7W4ew51dBtJGf2evvurA==}
'@protobufjs/aspromise@1.1.2':
resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
'@protobufjs/base64@1.1.2':
resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
'@protobufjs/codegen@2.0.5':
resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==}
'@protobufjs/eventemitter@1.1.0':
resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==}
'@protobufjs/fetch@1.1.1':
resolution: {integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==}
'@protobufjs/float@1.0.2':
resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
'@protobufjs/inquire@1.1.2':
resolution: {integrity: sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==}
'@protobufjs/path@1.1.2':
resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
'@protobufjs/pool@1.1.0':
resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
'@protobufjs/utf8@1.1.1':
resolution: {integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==}
'@quansync/fs@1.0.0': '@quansync/fs@1.0.0':
resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==}
@@ -2226,6 +2343,9 @@ packages:
'@types/statuses@2.0.6': '@types/statuses@2.0.6':
resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==}
'@types/trusted-types@2.0.7':
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
'@types/unist@2.0.11': '@types/unist@2.0.11':
resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
@@ -2267,10 +2387,23 @@ packages:
vue-router: vue-router:
optional: true optional: true
'@vercel/functions@3.6.0':
resolution: {integrity: sha512-Xj68JYqqJwtqFWJN7EWmFN7MOiUjv5whjw48UEKqQbg8r7hRkhuJhncTU0ba3jJCh/wxEuLWckrtsKcrHQraxw==}
engines: {node: '>= 20'}
peerDependencies:
'@aws-sdk/credential-provider-web-identity': '*'
peerDependenciesMeta:
'@aws-sdk/credential-provider-web-identity':
optional: true
'@vercel/og@0.11.1': '@vercel/og@0.11.1':
resolution: {integrity: sha512-02rXXRABFq1B03w3aNhcVfxkY+8Ba5QFi4ax0zS0oOiD/LL9WUd/LA7BjVPakrQmVhIBjuo2oBM5U25R9IuXMg==} resolution: {integrity: sha512-02rXXRABFq1B03w3aNhcVfxkY+8Ba5QFi4ax0zS0oOiD/LL9WUd/LA7BjVPakrQmVhIBjuo2oBM5U25R9IuXMg==}
engines: {node: '>=16'} engines: {node: '>=16'}
'@vercel/oidc@3.4.1':
resolution: {integrity: sha512-H6B+/ig/GoahccL3WZjiHayHw1H5KhvTJNceqYulwfK9kkz5iul2hTmYzcJ7tTCQzyd0dutuL9xYFZCyLUqsog==}
engines: {node: '>= 20'}
'@vitejs/plugin-react@6.0.2': '@vitejs/plugin-react@6.0.2':
resolution: {integrity: sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==} resolution: {integrity: sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
@@ -2598,6 +2731,9 @@ packages:
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
core-js@3.49.0:
resolution: {integrity: sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==}
cors@2.8.6: cors@2.8.6:
resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==}
engines: {node: '>= 0.10'} engines: {node: '>= 0.10'}
@@ -2781,6 +2917,9 @@ packages:
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
engines: {node: '>= 4'} engines: {node: '>= 4'}
dompurify@3.4.5:
resolution: {integrity: sha512-OrwIBKsdNSVEeubdJ1HBv/wNENRM9ytAVCv7YXt//A3vPdVMNuACRqK9mXCGCBW2ln7BT/A4X0jXHo2Gu89miA==}
domutils@3.2.2: domutils@3.2.2:
resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
@@ -3026,6 +3165,9 @@ packages:
fetchdts@0.1.7: fetchdts@0.1.7:
resolution: {integrity: sha512-YoZjBdafyLIop9lSxXVI33oLD5kN31q4Td+CasofLLYeLXRFeOsuOw0Uo+XNRi9PZlbfdlN2GmRtm4tCEQ9/KA==} resolution: {integrity: sha512-YoZjBdafyLIop9lSxXVI33oLD5kN31q4Td+CasofLLYeLXRFeOsuOw0Uo+XNRi9PZlbfdlN2GmRtm4tCEQ9/KA==}
fflate@0.4.8:
resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==}
fflate@0.7.4: fflate@0.7.4:
resolution: {integrity: sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==} resolution: {integrity: sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==}
@@ -3650,6 +3792,9 @@ packages:
resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==}
engines: {node: '>=18'} engines: {node: '>=18'}
long@5.3.2:
resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
longest-streak@3.1.0: longest-streak@3.1.0:
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
@@ -4205,6 +4350,18 @@ packages:
resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==}
engines: {node: ^10 || ^12 || >=14} engines: {node: ^10 || ^12 || >=14}
posthog-js@1.375.0:
resolution: {integrity: sha512-aHr9LPwEmL1/QDv+HpXBXuCtAdFaamDBqUqzTTVEIoHrN+ZZUQVr0kfv3v5w79TvUS7QezvHyUeigDQdCZRbSQ==}
posthog-node@5.35.0:
resolution: {integrity: sha512-5Hos1mlwrZtzZbh1Pij1FyU9p4R3bajVtAKjPZ3vxhAScsGeyLsF5KqMaEAw3EYWmsX9SQ5CbYZtSlHf+nkw6g==}
engines: {node: ^20.20.0 || >=22.22.0}
peerDependencies:
rxjs: ^7.0.0
peerDependenciesMeta:
rxjs:
optional: true
powershell-utils@0.1.0: powershell-utils@0.1.0:
resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==}
engines: {node: '>=20'} engines: {node: '>=20'}
@@ -4214,6 +4371,9 @@ packages:
peerDependencies: peerDependencies:
preact: '>=10 || >= 11.0.0-0' preact: '>=10 || >= 11.0.0-0'
preact@10.29.2:
resolution: {integrity: sha512-7tNmwg/7mzzAoB/8kSg6Hl37JraAZw3Z3A0JSY7VXlZwo82Xn0G7wKbNNs2qoF4ZEEsQGTwDAroNdqKs1ofJxQ==}
preact@11.0.0-beta.0: preact@11.0.0-beta.0:
resolution: {integrity: sha512-IcODoASASYwJ9kxz7+MJeiJhvLriwSb4y4mHIyxdgaRZp6kPUud7xytrk/6GZw8U3y6EFJaRb5wi9SrEK+8+lg==} resolution: {integrity: sha512-IcODoASASYwJ9kxz7+MJeiJhvLriwSb4y4mHIyxdgaRZp6kPUud7xytrk/6GZw8U3y6EFJaRb5wi9SrEK+8+lg==}
@@ -4242,6 +4402,10 @@ packages:
property-information@7.1.0: property-information@7.1.0:
resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
protobufjs@7.6.0:
resolution: {integrity: sha512-LtESOsMPTZgyYtwxhvdgdjGL0HmXEaRA/hVD6sol4zA60hVXXXP/SGmxnqDbgGE8gy7pYex7cym+5vYPcmaXBQ==}
engines: {node: '>=12.0.0'}
proxy-addr@2.0.7: proxy-addr@2.0.7:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'} engines: {node: '>= 0.10'}
@@ -4260,6 +4424,9 @@ packages:
quansync@1.0.0: quansync@1.0.0:
resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==}
query-selector-shadow-dom@1.0.1:
resolution: {integrity: sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==}
queue-microtask@1.2.3: queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
@@ -6140,6 +6307,82 @@ snapshots:
'@open-draft/until@2.1.0': {} '@open-draft/until@2.1.0': {}
'@opentelemetry/api-logs@0.208.0':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/api@1.9.1': {}
'@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/semantic-conventions': 1.41.1
'@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/semantic-conventions': 1.41.1
'@opentelemetry/exporter-logs-otlp-http@0.208.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/api-logs': 0.208.0
'@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.1)
'@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.1)
'@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.1)
'@opentelemetry/otlp-exporter-base@0.208.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.1)
'@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.1)
'@opentelemetry/otlp-transformer@0.208.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/api-logs': 0.208.0
'@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.1)
'@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.1)
protobufjs: 7.6.0
'@opentelemetry/resources@2.2.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.1)
'@opentelemetry/semantic-conventions': 1.41.1
'@opentelemetry/resources@2.7.1(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1)
'@opentelemetry/semantic-conventions': 1.41.1
'@opentelemetry/sdk-logs@0.208.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/api-logs': 0.208.0
'@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.1)
'@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-metrics@2.2.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.1)
'@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.1)':
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.1)
'@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.1)
'@opentelemetry/semantic-conventions': 1.41.1
'@opentelemetry/semantic-conventions@1.41.1': {}
'@orama/orama@3.1.18': {} '@orama/orama@3.1.18': {}
'@oxc-parser/binding-android-arm-eabi@0.120.0': '@oxc-parser/binding-android-arm-eabi@0.120.0':
@@ -6332,6 +6575,34 @@ snapshots:
react: 19.2.6 react: 19.2.6
react-dom: 19.2.6(react@19.2.6) react-dom: 19.2.6(react@19.2.6)
'@posthog/core@1.29.8':
dependencies:
'@posthog/types': 1.375.0
'@posthog/types@1.375.0': {}
'@protobufjs/aspromise@1.1.2': {}
'@protobufjs/base64@1.1.2': {}
'@protobufjs/codegen@2.0.5': {}
'@protobufjs/eventemitter@1.1.0': {}
'@protobufjs/fetch@1.1.1':
dependencies:
'@protobufjs/aspromise': 1.1.2
'@protobufjs/float@1.0.2': {}
'@protobufjs/inquire@1.1.2': {}
'@protobufjs/path@1.1.2': {}
'@protobufjs/pool@1.1.0': {}
'@protobufjs/utf8@1.1.1': {}
'@quansync/fs@1.0.0': '@quansync/fs@1.0.0':
dependencies: dependencies:
quansync: 1.0.0 quansync: 1.0.0
@@ -6990,6 +7261,9 @@ snapshots:
'@types/statuses@2.0.6': {} '@types/statuses@2.0.6': {}
'@types/trusted-types@2.0.7':
optional: true
'@types/unist@2.0.11': {} '@types/unist@2.0.11': {}
'@types/unist@3.0.3': {} '@types/unist@3.0.3': {}
@@ -7002,6 +7276,10 @@ snapshots:
optionalDependencies: optionalDependencies:
react: 19.2.6 react: 19.2.6
'@vercel/functions@3.6.0':
dependencies:
'@vercel/oidc': 3.4.1
'@vercel/og@0.11.1': '@vercel/og@0.11.1':
dependencies: dependencies:
'@resvg/resvg-wasm': 2.4.0 '@resvg/resvg-wasm': 2.4.0
@@ -7009,6 +7287,8 @@ snapshots:
optionalDependencies: optionalDependencies:
sharp: 0.34.5 sharp: 0.34.5
'@vercel/oidc@3.4.1': {}
'@vitejs/plugin-react@6.0.2(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3))': '@vitejs/plugin-react@6.0.2(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3))':
dependencies: dependencies:
'@rolldown/pluginutils': 1.0.1 '@rolldown/pluginutils': 1.0.1
@@ -7304,6 +7584,8 @@ snapshots:
cookie@1.1.1: {} cookie@1.1.1: {}
core-js@3.49.0: {}
cors@2.8.6: cors@2.8.6:
dependencies: dependencies:
object-assign: 4.1.1 object-assign: 4.1.1
@@ -7435,6 +7717,10 @@ snapshots:
dependencies: dependencies:
domelementtype: 2.3.0 domelementtype: 2.3.0
dompurify@3.4.5:
optionalDependencies:
'@types/trusted-types': 2.0.7
domutils@3.2.2: domutils@3.2.2:
dependencies: dependencies:
dom-serializer: 2.0.0 dom-serializer: 2.0.0
@@ -7726,6 +8012,8 @@ snapshots:
fetchdts@0.1.7: {} fetchdts@0.1.7: {}
fflate@0.4.8: {}
fflate@0.7.4: {} fflate@0.7.4: {}
figures@6.1.0: figures@6.1.0:
@@ -8328,6 +8616,8 @@ snapshots:
chalk: 5.6.2 chalk: 5.6.2
is-unicode-supported: 1.3.0 is-unicode-supported: 1.3.0
long@5.3.2: {}
longest-streak@3.1.0: {} longest-streak@3.1.0: {}
lru-cache@11.5.0: {} lru-cache@11.5.0: {}
@@ -8866,7 +9156,7 @@ snapshots:
nf3@0.3.17: {} nf3@0.3.17: {}
nitro@3.0.260429-beta(chokidar@5.0.0)(dotenv@17.4.2)(jiti@2.7.0)(lru-cache@11.5.0)(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)): nitro@3.0.260429-beta(@vercel/functions@3.6.0)(chokidar@5.0.0)(dotenv@17.4.2)(jiti@2.7.0)(lru-cache@11.5.0)(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)):
dependencies: dependencies:
consola: 3.4.2 consola: 3.4.2
crossws: 0.4.5(srvx@0.11.15) crossws: 0.4.5(srvx@0.11.15)
@@ -8881,7 +9171,7 @@ snapshots:
rolldown: 1.0.2 rolldown: 1.0.2
srvx: 0.11.15 srvx: 0.11.15
unenv: 2.0.0-rc.24 unenv: 2.0.0-rc.24
unstorage: 2.0.0-alpha.7(chokidar@5.0.0)(db0@0.3.4)(lru-cache@11.5.0)(ofetch@2.0.0-alpha.3) unstorage: 2.0.0-alpha.7(@vercel/functions@3.6.0)(chokidar@5.0.0)(db0@0.3.4)(lru-cache@11.5.0)(ofetch@2.0.0-alpha.3)
optionalDependencies: optionalDependencies:
dotenv: 17.4.2 dotenv: 17.4.2
jiti: 2.7.0 jiti: 2.7.0
@@ -9191,12 +9481,34 @@ snapshots:
picocolors: 1.1.1 picocolors: 1.1.1
source-map-js: 1.2.1 source-map-js: 1.2.1
posthog-js@1.375.0:
dependencies:
'@opentelemetry/api': 1.9.1
'@opentelemetry/api-logs': 0.208.0
'@opentelemetry/exporter-logs-otlp-http': 0.208.0(@opentelemetry/api@1.9.1)
'@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1)
'@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.1)
'@posthog/core': 1.29.8
'@posthog/types': 1.375.0
core-js: 3.49.0
dompurify: 3.4.5
fflate: 0.4.8
preact: 10.29.2
query-selector-shadow-dom: 1.0.1
web-vitals: 5.2.0
posthog-node@5.35.0:
dependencies:
'@posthog/core': 1.29.8
powershell-utils@0.1.0: {} powershell-utils@0.1.0: {}
preact-render-to-string@6.6.5(preact@11.0.0-beta.0): preact-render-to-string@6.6.5(preact@11.0.0-beta.0):
dependencies: dependencies:
preact: 11.0.0-beta.0 preact: 11.0.0-beta.0
preact@10.29.2: {}
preact@11.0.0-beta.0: {} preact@11.0.0-beta.0: {}
prettier@2.8.8: {} prettier@2.8.8: {}
@@ -9220,6 +9532,21 @@ snapshots:
property-information@7.1.0: {} property-information@7.1.0: {}
protobufjs@7.6.0:
dependencies:
'@protobufjs/aspromise': 1.1.2
'@protobufjs/base64': 1.1.2
'@protobufjs/codegen': 2.0.5
'@protobufjs/eventemitter': 1.1.0
'@protobufjs/fetch': 1.1.1
'@protobufjs/float': 1.0.2
'@protobufjs/inquire': 1.1.2
'@protobufjs/path': 1.1.2
'@protobufjs/pool': 1.1.0
'@protobufjs/utf8': 1.1.1
'@types/node': 25.9.1
long: 5.3.2
proxy-addr@2.0.7: proxy-addr@2.0.7:
dependencies: dependencies:
forwarded: 0.2.0 forwarded: 0.2.0
@@ -9235,6 +9562,8 @@ snapshots:
quansync@1.0.0: {} quansync@1.0.0: {}
query-selector-shadow-dom@1.0.1: {}
queue-microtask@1.2.3: {} queue-microtask@1.2.3: {}
range-parser@1.2.1: {} range-parser@1.2.1: {}
@@ -9971,8 +10300,9 @@ snapshots:
picomatch: 4.0.4 picomatch: 4.0.4
webpack-virtual-modules: 0.6.2 webpack-virtual-modules: 0.6.2
unstorage@2.0.0-alpha.7(chokidar@5.0.0)(db0@0.3.4)(lru-cache@11.5.0)(ofetch@2.0.0-alpha.3): unstorage@2.0.0-alpha.7(@vercel/functions@3.6.0)(chokidar@5.0.0)(db0@0.3.4)(lru-cache@11.5.0)(ofetch@2.0.0-alpha.3):
optionalDependencies: optionalDependencies:
'@vercel/functions': 3.6.0
chokidar: 5.0.0 chokidar: 5.0.0
db0: 0.3.4 db0: 0.3.4
lru-cache: 11.5.0 lru-cache: 11.5.0
@@ -10044,7 +10374,7 @@ snapshots:
optionalDependencies: optionalDependencies:
vite: 8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3) vite: 8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)
vitest@4.1.7(@types/node@25.9.1)(jsdom@29.1.1(@noble/hashes@1.8.0))(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)): vitest@4.1.7(@opentelemetry/api@1.9.1)(@types/node@25.9.1)(jsdom@29.1.1(@noble/hashes@1.8.0))(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)):
dependencies: dependencies:
'@vitest/expect': 4.1.7 '@vitest/expect': 4.1.7
'@vitest/mocker': 4.1.7(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)) '@vitest/mocker': 4.1.7(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3))
@@ -10067,6 +10397,7 @@ snapshots:
vite: 8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3) vite: 8.0.14(@types/node@25.9.1)(esbuild@0.28.0)(jiti@2.7.0)(tsx@4.22.3)
why-is-node-running: 2.3.0 why-is-node-running: 2.3.0
optionalDependencies: optionalDependencies:
'@opentelemetry/api': 1.9.1
'@types/node': 25.9.1 '@types/node': 25.9.1
jsdom: 29.1.1(@noble/hashes@1.8.0) jsdom: 29.1.1(@noble/hashes@1.8.0)
transitivePeerDependencies: transitivePeerDependencies: