@hanzo/event 0.3.49 → 0.3.50

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/attribution.ts","../src/org.ts","../src/scrub.ts","../src/throwable.ts","../src/anon.js","../src/uid.ts","../src/storage.ts","../src/link.ts","../package.json","../src/version.ts","../src/core.ts","../src/exception.ts","../src/cookie.ts","../src/consent.ts","../src/touch.ts","../src/tags.ts","../src/items.ts","../src/goals.ts"],"names":["get","now","set","normalizeError","g","truncate","read","namesOn"],"mappings":"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","file":"index.mjs","sourcesContent":["// Pure attribution helpers: parse first-touch UTM/referrer/refCode from a URL,\n// derive the acquisition channel, and compute the ISO week for the signup cohort.\n// No I/O, no globals — trivially testable.\n\nimport type { Attribution } from './types'\n\nconst SOCIAL_HOSTS = [\n 'facebook.', 'instagram.', 'twitter.', 'x.com', 't.co', 'linkedin.',\n 'reddit.', 'youtube.', 'tiktok.', 'pinterest.', 'news.ycombinator.com',\n]\nconst SEARCH_HOSTS = ['google.', 'bing.', 'duckduckgo.', 'yahoo.', 'baidu.', 'ecosia.']\n\n/** parseAttribution reads UTM params + ref/refCode from a query string and pairs\n * them with the referrer. `search` is a location.search value (\"?utm_source=…\"). */\nexport function parseAttribution(search: string, referrer: string): Attribution {\n const q = new URLSearchParams(search || '')\n const get = (k: string) => {\n const v = q.get(k)\n return v ? v.trim() : undefined\n }\n const a: Attribution = {\n utm: {\n source: get('utm_source'),\n medium: get('utm_medium'),\n campaign: get('utm_campaign'),\n term: get('utm_term'),\n content: get('utm_content'),\n },\n referrer: referrer ? referrer.trim() : undefined,\n refCode: get('ref') || get('refCode') || get('ref_code') || undefined,\n }\n a.channel = deriveChannel(a)\n return a\n}\n\n/** deriveChannel classifies the visit: paid | referral | social | organic | direct. */\nexport function deriveChannel(a: Attribution): string {\n const medium = (a.utm.medium || '').toLowerCase()\n if (/(cpc|ppc|paid|paidsearch|display|cpm)/.test(medium)) return 'paid'\n if (a.utm.source || a.utm.campaign) return 'campaign'\n if (a.refCode) return 'referral'\n const host = hostOf(a.referrer)\n if (!host) return 'direct'\n if (SOCIAL_HOSTS.some((h) => host.includes(h))) return 'social'\n if (SEARCH_HOSTS.some((h) => host.includes(h))) return 'organic'\n return 'referral'\n}\n\n/** hostOf extracts a bare lowercase host from a URL; \"\" when unparseable. */\nexport function hostOf(raw?: string): string {\n if (!raw) return ''\n let s = raw.trim()\n const scheme = s.indexOf('://')\n if (scheme >= 0) s = s.slice(scheme + 3)\n const cut = s.search(/[/?#]/)\n if (cut >= 0) s = s.slice(0, cut)\n const at = s.indexOf('@')\n if (at >= 0) s = s.slice(at + 1)\n const colon = s.indexOf(':')\n if (colon >= 0) s = s.slice(0, colon)\n return s.toLowerCase().trim()\n}\n\n/** hasAttribution reports whether anything was captured (so we don't persist an\n * empty first-touch that would shadow a later real one). */\nexport function hasAttribution(a: Attribution): boolean {\n return Boolean(\n a.utm.source || a.utm.medium || a.utm.campaign || a.utm.term ||\n a.utm.content || a.refCode || (a.referrer && hostOf(a.referrer)),\n )\n}\n\n/** isoWeek returns the ISO-8601 week label, e.g. \"2026-W28\". */\nexport function isoWeek(d: Date): string {\n // Copy to UTC midnight; ISO week: Thursday-anchored.\n const date = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()))\n const day = date.getUTCDay() || 7\n date.setUTCDate(date.getUTCDate() + 4 - day)\n const yearStart = new Date(Date.UTC(date.getUTCFullYear(), 0, 1))\n const week = Math.ceil(((date.getTime() - yearStart.getTime()) / 86400000 + 1) / 7)\n return `${date.getUTCFullYear()}-W${String(week).padStart(2, '0')}`\n}\n","/**\n * Which org owns a host's telemetry.\n *\n * A surface should not have to LEARN its key. It already knows the domain it is\n * served from, and a domain belongs to exactly one brand, so the key is derivable\n * and asking a surface to carry one is asking it to restate something already\n * true. This module answers `orgOf(location.hostname)` and hands back that org's\n * publishable key, which is what lets a static export report correctly while\n * configuring nothing.\n *\n * This is the SAME question `hanzo.id` answers at runtime for the identity hosts\n * (`pkgs/shared/src/ingest.ts`): one image serves every brand, so the key cannot\n * be a property of the build. It was, and the bill is on record — Lux's, Zoo's,\n * Osage's and Pars' visitors were all filed in HANZO's project, because one\n * build-time key was inlined for every brand. That is the white-label boundary\n * crossed in the direction that shows up latest. The marketing sites carry the\n * identical defect in its other form: each commits its OWN key literal, so the\n * fleet holds N copies of a value with one source, and a site added tomorrow\n * reports nothing until somebody remembers to paste one in.\n *\n * A `pk-` is PUBLISHABLE: it authorizes a write into one org and mints no reading\n * principal. It is readable in devtools on every deployed page that sends an\n * event, so stating it here exposes nothing that serving the page did not. What\n * it does buy is that correct attribution becomes the DEFAULT rather than\n * something each surface opts into.\n *\n * Keyed by ORG, never by host: a brand's facts repeat on every alias it owns\n * (`lux.id`, `id.lux.network`), and a key stated per host would have to be\n * repeated too — so the day someone adds an alias and forgets the key, that host\n * silently stops reporting. Stated once per org, a new alias inherits its brand's\n * key by naming its brand's domain, which is all an alias ever says.\n */\n\n/** One publishable key per org. */\nexport type Keyring = Readonly<Record<string, string>>\n\n/**\n * Each org's registrable domains. A host matches a domain when it IS that domain\n * or a subdomain of it, so `explore.lux.network` needs no entry of its own.\n *\n * An org absent from this table resolves to undefined, and that is deliberate:\n * `osage`, `pars` and `bootnode` have no project of their own yet, and reporting\n * NOTHING is the honest answer. Filing them under a brand that is not theirs is\n * the defect this module exists to prevent — it is silent, it reads as working,\n * and it is only visible later in someone else's warehouse.\n */\nexport const ORG_DOMAIN: Readonly<Record<string, readonly string[]>> = Object.freeze({\n // A brand's domains are not a pattern — `hanzoskills.com` is Hanzo's and does\n // not end in `hanzo.ai`, while `hanzo.works` is a registrable domain of its own\n // rather than a subdomain of anything here. Each is stated because each is a\n // separate fact, which is the whole reason this is a table.\n hanzo: Object.freeze([\n 'hanzo.ai',\n 'hanzo.agency',\n 'hanzo.app',\n 'hanzo.bot',\n 'hanzo.chat',\n 'hanzo.codes',\n 'hanzo.id',\n 'hanzo.industries',\n 'hanzo.market',\n 'hanzo.network',\n 'hanzo.sh',\n 'hanzo.team',\n 'hanzo.ventures',\n 'hanzo.works',\n 'hanzoskills.com',\n ]),\n lux: Object.freeze([\n 'lux.network',\n 'lux.exchange',\n 'lux.market',\n 'lux.finance',\n 'lux.financial',\n 'lux.credit',\n 'lux.fund',\n 'lux.id',\n ]),\n zoo: Object.freeze(['zoo.ngo', 'zoo.network', 'zoolabs.id', 'zoolabs.io']),\n})\n\n/**\n * Each org's publishable key, and a copy: the values live in universe at\n * infra/k8s/id/configmap.yaml as SPA_INGEST_KEYRING, which serves them to the\n * identity hosts, and this table is what a statically exported page carries when\n * it cannot ask. The two must say the same thing. Add an org the day its project\n * exists, never before.\n *\n * A key is only as real as the project it names, and these had stopped naming\n * one: all three answered `403 ingest_key_unknown` against /v1/event, so every\n * page that fell back to this table reported nowhere while looking fine. The\n * copy drifted silently because nothing compares it to the keyring. If you\n * recreate a project, move BOTH.\n */\nexport const ORG_KEY: Keyring = Object.freeze({\n hanzo: 'pk-rM_CdaF2MQckGCrla113SrR1oH4zvqN8xh2I95Z9tY8',\n lux: 'pk-gUZp6ZVfhJzSwK-rb4oLbVkpCnMBx5uSCpxf_5yEhQk',\n zoo: 'pk-3TKpKnERV9AQSsBUERWkZejC1O1mUxc1jRzsP3MPbs4',\n})\n\n/** `pk-` is publishable; `sk-` is not, and there is no third thing. Checked at the\n * one point a key becomes something a page will send, so a mistyped entry fails\n * closed rather than putting a secret in every visitor's tab. */\nconst PUBLISHABLE = 'pk-'\n\n/** Strip the port and case a hostname the way a domain compares. */\nconst normalize = (host: string): string =>\n host.trim().toLowerCase().replace(/\\.$/, '').split(':')[0] ?? ''\n\n/**\n * The org that owns a host, or undefined when no brand claims it.\n *\n * Longest match wins, so a brand owning both a domain and a subdomain of another\n * brand's cannot be decided by table order. Pure and total.\n */\nexport function orgOf(host: string): string | undefined {\n const h = normalize(host)\n if (!h) return undefined\n let best: string | undefined\n let bestLen = 0\n for (const [org, domains] of Object.entries(ORG_DOMAIN)) {\n for (const d of domains) {\n if ((h === d || h.endsWith(`.${d}`)) && d.length > bestLen) {\n best = org\n bestLen = d.length\n }\n }\n }\n return best\n}\n\n/**\n * The publishable key for a host, or undefined when there is not exactly one to\n * give.\n *\n * Deliberately WITHOUT a fallback: returning Hanzo's key for an unrecognised host\n * is precisely the defect described above. Undefined is the honest answer and the\n * caller reports nothing.\n *\n * `keyring` is a parameter so the identity runtime — which receives its keyring\n * from `/config.json` because one image serves every brand — resolves through\n * this SAME function rather than a second copy of it.\n */\nexport function keyFor(host: string, keyring: Keyring = ORG_KEY): string | undefined {\n const org = orgOf(host)\n if (!org) return undefined\n const key = keyring[org]\n if (typeof key !== 'string') return undefined\n const trimmed = key.trim()\n return trimmed.startsWith(PUBLISHABLE) ? trimmed : undefined\n}\n\n/** The key for the page this code is running on; undefined off a browser. */\nexport function keyForPage(keyring: Keyring = ORG_KEY): string | undefined {\n if (typeof location === 'undefined') return undefined\n return keyFor(location.hostname, keyring)\n}\n","// Client-side redaction for error text — a faithful port of the server's\n// errortracking scrub (o11y pkg/modules/errortracking/implerrortracking/scrub.go),\n// applied BEFORE anything leaves the browser. Two layers, default-secure:\n//\n// - Secret shapes are ALWAYS redacted (sk-… keys, bearer/JWT tokens, DB DSNs,\n// PANs, cloud keys). There is no mode that ships a secret off-device.\n// - PII (email/IP) is scrubbed UNLESS capturePII is explicitly enabled.\n//\n// The server scrubs again — this is defense in depth, not a substitute — but the\n// point is that a Hanzo browser never emits a raw secret/email/IP in the first\n// place. Pure, no I/O.\n\nconst REDACTED = '[redacted]'\nconst EMAIL_MARK = '[email]'\nconst IP_MARK = '[ip]'\n\n// Secret patterns mirror scrub.go's secretPatterns. Order matters (broad DSN/PAN\n// rules run last). All are applied unconditionally.\nconst SECRET_PATTERNS: RegExp[] = [\n /-----BEGIN[ A-Z]*PRIVATE KEY-----[\\s\\S]*?-----END[ A-Z]*PRIVATE KEY-----/g,\n /eyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{6,}\\.[A-Za-z0-9_-]{6,}/g, // JWT\n /\\bbearer\\s+[A-Za-z0-9._~+/-]{12,}=*/gi, // bearer token\n /\\b(?:sk|pk|rk)-[A-Za-z0-9]{2,}-?[A-Za-z0-9]{12,}/g, // openai-style\n /\\b(?:sk|pk)_(?:live|test)_[A-Za-z0-9]{16,}/g, // stripe\n /\\bhk-[A-Za-z0-9]{16,}/g, // hanzo key\n /\\bAKIA[0-9A-Z]{16}\\b/g, // aws access key id\n /\\bASIA[0-9A-Z]{16}\\b/g, // aws sts key id\n /\\bAIza[0-9A-Za-z_-]{20,}/g, // google api key\n /\\bgh[posru]_[A-Za-z0-9]{20,}/g, // github token\n /\\bxox[baprs]-[A-Za-z0-9-]{10,}/g, // slack token\n // Creds in a URL/DSN. The repetition is BOUNDED on purpose: the unbounded form\n // ([^\\s:@/]+:[^\\s@/]+@) backtracks quadratically on colon-rich text with no\n // terminating '@' — an HTML error page pasted into an error message took 4.9s\n // at 32KB and >60s at 128KB, freezing the main thread from inside captureError.\n // Real userinfo is far below these caps, so bounding costs nothing.\n /[a-zA-Z][a-zA-Z0-9+.-]{0,32}:\\/\\/[^\\s:@/]{1,256}:[^\\s@/]{1,256}@/g,\n]\n\n/** Candidate card numbers. Gated by Luhn below — the bare digit-run pattern is a\n * false-positive cannon that redacts every millisecond epoch, order id and\n * phone number it sees (\"request 1753468800000 timed out\" became\n * \"request [redacted]timed out\"), which destroys the readability of the very\n * error messages this client exists to deliver. */\nconst RE_PAN = /\\b(?:\\d[ -]?){13,19}\\b/g\n\n/** luhn reports whether a digit string satisfies the Luhn checksum. Every real\n * card number does, so gating redaction on it removes the false positives\n * WITHOUT introducing a false negative — the safe direction for a redactor. */\nfunction luhn(digits: string): boolean {\n let sum = 0\n let alt = false\n for (let i = digits.length - 1; i >= 0; i--) {\n let d = digits.charCodeAt(i) - 48\n if (alt) {\n d *= 2\n if (d > 9) d -= 9\n }\n sum += d\n alt = !alt\n }\n return sum % 10 === 0\n}\n\n/** redactPAN removes digit runs that actually check out as card numbers. */\nfunction redactPAN(s: string): string {\n return s.replace(RE_PAN, (m) => {\n const digits = m.replace(/[ -]/g, '')\n if (digits.length < 13 || digits.length > 19) return m\n return luhn(digits) ? REDACTED : m\n })\n}\n\n// Bounded to the RFC 5321 maxima (local-part 64, domain 255) for the same reason\n// as the creds-in-URL rule: the unbounded form backtracks quadratically across a\n// long run of local-part-legal characters that never reaches an '@' — measured at\n// 20ms on an 8KB worst case, on the main thread, per captured error. No real\n// address is excluded by these caps.\nconst RE_EMAIL = /[A-Za-z0-9._%+-]{1,64}@[A-Za-z0-9.-]{1,255}\\.[A-Za-z]{2,24}/g\nconst RE_IPV4 = /\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b/g\nconst RE_IPV6 = /\\b(?:[0-9A-Fa-f]{1,4}:){2,7}[0-9A-Fa-f]{1,4}\\b/g\n\n// A CREDENTIAL IN A QUERY PARAM HAS NO SHAPE TO MATCH.\n//\n// Every pattern above recognises a secret by what it LOOKS like — a JWT's three\n// dots, `sk-`, `AKIA`, `ghp_`. An OAuth `code`, a `state`, a password-reset\n// nonce and an invite token are opaque random strings, indistinguishable from a\n// page id, so none of them match and all of them survive.\n//\n// That matters because the client stamps `url: window.location.href` on EVERY\n// event, not just pageviews. So one visit to `/callback?code=…&state=…` puts a\n// live authorization code on the wire, once per event, in cleartext — and the\n// code is exchangeable until it is redeemed.\n//\n// The fix is to redact by the NAME the value is filed under rather than by the\n// value's shape, which is the only signal available for an opaque token. The\n// name half is bounded (`{1,32}`) and the value half stops at the first\n// separator, so neither half can backtrack across a long string — the same\n// discipline the creds-in-URL pattern above documents.\nconst CREDENTIAL_PARAMS = [\n 'code', 'state', 'token', 'access_token', 'id_token', 'refresh_token',\n 'auth', 'authorization', 'secret', 'client_secret', 'password', 'passwd', 'pwd',\n 'api_key', 'apikey', 'key', 'session', 'session_id', 'sid',\n 'sig', 'signature', 'nonce', 'otp', 'invite', 'invitation',\n 'reset_token', 'confirmation_token', 'magic', 'ticket', 'assertion',\n]\nconst RE_CREDENTIAL_PARAM = new RegExp(\n '([?&#;](?:' + CREDENTIAL_PARAMS.join('|') + ')=)[^&#;\\\\s]{1,4096}',\n 'gi',\n)\n\n/** redactCredentialParams removes the VALUE of any query parameter whose NAME\n * says it carries a credential, leaving the name so the URL still reads. */\nexport function redactCredentialParams(s: string): string {\n return s.replace(RE_CREDENTIAL_PARAM, (_m, prefix: string) => prefix + REDACTED)\n}\n\n// A 256-bit secret written as unpadded base64url is exactly 43 characters of\n// [A-Za-z0-9_-] — the shape of a share-link secret, and of any other opaque key\n// minted the same way. The run must stand alone — nothing of the same alphabet\n// on either side, a percent-escape such as the `%23` of an encoded `#` counting\n// as a boundary — so it never fires inside a longer token, and it must mix upper\n// and lower case, which a random 32 bytes does with near certainty and an\n// ordinary word or slug does not. No lookbehind, so it runs on every engine the\n// client ships to.\nconst RE_SECRET43 = /(^|[^A-Za-z0-9_-]|%[0-9A-Fa-f]{2})((?=[A-Za-z0-9_-]{0,42}[a-z])(?=[A-Za-z0-9_-]{0,42}[A-Z])[A-Za-z0-9_-]{43})(?![A-Za-z0-9_-])/g\n\n/** redactSecrets removes known secret shapes. Always applied. */\nexport function redactSecrets(s: string): string {\n s = redactCredentialParams(s)\n for (const re of SECRET_PATTERNS) s = s.replace(re, REDACTED)\n s = s.replace(RE_SECRET43, (_m, lead: string) => lead + REDACTED)\n return redactPAN(s)\n}\n\n/** withoutFragment returns a URL with its fragment removed. A browser never\n * sends the fragment to any server — it is where an app keeps what must stay\n * on the device, a share link's secret among them — so the client does not\n * send it either. */\nexport function withoutFragment(url: string): string {\n const at = url.indexOf('#')\n return at < 0 ? url : url.slice(0, at)\n}\n\n/** scrubPII masks emails and IPs. Applied unless PII capture is enabled. */\nexport function scrubPII(s: string): string {\n s = s.replace(RE_EMAIL, EMAIL_MARK)\n s = s.replace(RE_IPV6, IP_MARK)\n s = s.replace(RE_IPV4, IP_MARK)\n return s\n}\n\n/** Longest free-text field this module will scrub. Every pattern here is a regex\n * run synchronously on the main thread, and the input is attacker-influenced —\n * `throw new Error(await res.text())` against an HTML error page is a one-line\n * way to hand us 128KB. Bounding the INPUT bounds the work regardless of which\n * pattern is pathological. 8KB is far beyond any real error message. */\nexport const MAX_SCRUB_LEN = 8192\n\n/** truncate caps a string at MAX_SCRUB_LEN, marking that it was cut so a reader\n * never mistakes a truncated message for the whole one. */\nexport function truncate(s: string, max = MAX_SCRUB_LEN): string {\n return s.length > max ? s.slice(0, max) + '… [truncated]' : s\n}\n\n/** scrubText applies the redaction policy to a free-text field. Input is capped\n * first: unbounded text is a denial-of-service surface, not just a size problem. */\nexport function scrubText(s: string | undefined, capturePII = false): string {\n if (!s) return s ?? ''\n s = truncate(s)\n s = redactSecrets(s)\n if (!capturePII) s = scrubPII(s)\n return s\n}\n","// Pure throwable parsing: coerce anything thrown into {name, message, stack} and\n// parse a browser stack into frames. No I/O, no globals.\n\nimport type { SentryFrame } from './types'\n\nconst MAX_FRAMES = 50\n/** Max stack lines examined, and max length of a line worth examining. Guards the\n * frame regexes against a hostile `stack` string (see framesFromStack). */\nconst MAX_LINES = 500\nconst MAX_LINE_LEN = 2048\n\nconst V8_FRAME = /^\\s*at\\s+(?:(.+?)\\s+\\()?(?:(.+?):(\\d+):(\\d+)|([^)]+))\\)?\\s*$/\nconst MOZ_FRAME = /^\\s*(?:(.*?)@)?(.+?):(\\d+):(\\d+)\\s*$/\n\n/** inApp marks a frame as the app's own code (vs vendor/runtime) for grouping. */\nfunction inApp(file: string): boolean {\n if (!file) return false\n return !(\n file.includes('node_modules') ||\n file.startsWith('webpack-internal') ||\n file.startsWith('webpack://') ||\n file.startsWith('chrome-extension://') ||\n file.startsWith('moz-extension://')\n )\n}\n\n/**\n * framesFromStack parses a browser Error.stack into Sentry frames, OLDEST-FIRST\n * (Sentry orders caller->callee; the crash site is last — matching the server's\n * pickCrashFrame). Handles both V8 (\"at fn (file:li:co)\") and\n * Firefox/Safari (\"fn@file:li:co\"). Unparseable lines are skipped.\n */\nexport function framesFromStack(stack: string | undefined): SentryFrame[] {\n if (!stack) return []\n // Both frame regexes use lazy nested quantifiers, which backtrack badly on a\n // long line that never matches. A stack is attacker-influenced (a thrown value\n // can carry any `stack` string), so bound the work: skip absurd lines and stop\n // after MAX_LINES. Only the innermost MAX_FRAMES are kept anyway.\n const lines = stack.split('\\n', MAX_LINES)\n const frames: SentryFrame[] = []\n for (const raw of lines) {\n if (raw.length > MAX_LINE_LEN) continue\n const line = raw.trimEnd()\n if (!line) continue\n // Header lines like \"TypeError: x is not a function\" match neither frame\n // regex (no \"at \" prefix, no trailing :line:col) and are skipped naturally.\n let fn: string | undefined\n let file = ''\n let lineno = 0\n let colno = 0\n const v = V8_FRAME.exec(line)\n if (v) {\n fn = v[1]\n if (v[2]) {\n file = v[2]\n lineno = Number(v[3]) || 0\n colno = Number(v[4]) || 0\n } else {\n file = (v[5] || '').trim()\n }\n } else {\n const f = MOZ_FRAME.exec(line)\n if (!f) continue\n fn = f[1]\n file = f[2]\n lineno = Number(f[3]) || 0\n colno = Number(f[4]) || 0\n }\n if (!file && !fn) continue\n frames.push({\n function: fn || '<anonymous>',\n filename: file,\n abs_path: file,\n lineno,\n colno,\n in_app: inApp(file),\n })\n }\n // Reverse to oldest-first and cap to the innermost MAX_FRAMES.\n frames.reverse()\n if (frames.length > MAX_FRAMES) return frames.slice(frames.length - MAX_FRAMES)\n return frames\n}\n\n/** normalizeError coerces an unknown throwable into {name, message, stack}. */\nexport function normalizeError(err: unknown): { name: string; message: string; stack?: string } {\n if (err instanceof Error) {\n // `name`, `message` and `stack` are ordinary getters, and the thrown object is\n // the least trustworthy input this library handles — any of them may throw.\n // Losing the whole report to a hostile getter is not acceptable.\n const name = read(err, 'name')\n const message = read(err, 'message')\n const stack = read(err, 'stack')\n return {\n name: typeof name === 'string' && name ? name : 'Error',\n message: typeof message === 'string' && message ? message : str(err),\n stack: typeof stack === 'string' ? stack : undefined,\n }\n }\n if (typeof err === 'string') return { name: 'Error', message: err }\n try {\n return { name: 'Error', message: JSON.stringify(err) ?? str(err) }\n } catch {\n return { name: 'Error', message: str(err) }\n }\n}\n\n/** read pulls a property off a possibly-hostile value without letting a throwing\n * getter escape. */\nfunction read(o: unknown, k: string): unknown {\n try {\n return (o as Record<string, unknown>)[k]\n } catch {\n return undefined\n }\n}\n\n/** str coerces to a string without letting a throwing toString/Symbol.toPrimitive\n * escape. */\nfunction str(v: unknown): string {\n try {\n return String(v)\n } catch {\n return '[unstringifiable]'\n }\n}\n","/*! anon.js — THE anonymous-identity chain. ONE implementation, two distributions.\n *\n * One browser is ONE person on every Hanzo surface, whichever client a page\n * happens to have loaded. There were once three implementations writing TWO keys —\n * `hz_anon_id` and `hz_id` — so the same visitor was several people depending on\n * which snippet the surface shipped.\n *\n * The two call sites:\n * 1. src/storage.ts — the bundled npm client; IMPORTS this file.\n * 2. hanzoai/cloud apps/analytics/tag.js — the tag served at\n * /v1/event.js; vendors this file and its tag.go serves the marked region\n * with the tag as one asset, so cloud holds no second copy either.\n *\n * (2) has no bundler and cannot import anything, which is why the chain lives in a\n * file that is plain ES5 rather than in a .ts: the region between the BEGIN and END\n * markers is COPIED VERBATIM. Keep it ES5, dependency-free, `hz`-prefixed (it is\n * spliced into other people's scopes) and unformatted — a reformat here is a diff\n * against the vendored copy. After editing, resync that copy:\n *\n * curl -fsSL https://unpkg.com/@hanzo/event/src/anon.js -o apps/analytics/anon.js\n */\n\n/* ── BEGIN hz anon chain — copied VERBATIM into hanzoai/cloud ──────────────── */\n\n/** The ONE anonymous-id key, on every surface and in every distribution.\n *\n * It names what it is, not who ships it: this value is visible to anyone who opens\n * their own cookie jar, and a vendor's name has no business there. Identity is IAM's\n * concern whether or not the visitor has said who they are. */\nvar HZ_ANON_KEY = 'iam-anon-id'\n\n/** Keys an id may already be living under. READ, never written.\n *\n * Each was canonical once — `hz_anon_id` most recently, and `hz_id` before it, when a\n * no-build tag wrote a second identity space and one page could hold two people.\n * Adopting an id already in the wild is what makes this a rename rather than an\n * erasure: minting over one detaches a returning visitor from their own history.\n * They are never written, so they leave with the cookies that hold them. */\nvar HZ_ANON_ADOPT = ['hz_anon_id', 'hz_id']\n\n/** The registrable domain the cookie is scoped to, so docs, cloud, console,\n * studio, pay, id and www all read the ONE id. localStorage cannot do this: it is\n * ORIGIN-scoped, which is what made one journey arrive as several strangers. */\nvar HZ_ANON_DOMAIN = 'hanzo.ai'\n\n/** Two years, rewritten on every read, so the cookie rolls forward with the\n * visitor instead of expiring two years after first touch. Safari caps a\n * SCRIPT-written cookie at 7 days no matter what this says, so the rewrite is\n * what keeps a returning Safari visitor: each read re-arms the 7-day window. */\nvar HZ_ANON_MAX_AGE = 2 * 365 * 24 * 60 * 60\n\n/** Last resort for a browser that refuses cookies AND localStorage: without it\n * every event in a page load would mint an id of its own. */\nvar hzAnonMemo\n\n/**\n * hzUuidv7 mints a time-ordered UUIDv7 (RFC 9562 §5.7) for `now` in epoch ms.\n *\n * It has to be v7, and this is the only minter any distribution may use. The\n * session rollups on the event plane derive a session's start instant FROM THE ID\n * and admit only ids whose version nibble is 7, so a crypto.randomUUID() (v4) id\n * is not merely unordered there — it is DISCARDED, silently, and the rollup stays\n * empty. Without crypto only the ENTROPY degrades; the shape is always a valid v7.\n */\nfunction hzUuidv7(now) {\n var b = new Uint8Array(16)\n var i\n var c = typeof crypto !== 'undefined' ? crypto : undefined\n if (c && typeof c.getRandomValues === 'function') c.getRandomValues(b)\n else for (i = 0; i < 16; i++) b[i] = (Math.random() * 256) | 0\n var t = Math.floor(now === undefined ? Date.now() : now)\n for (i = 5; i >= 0; i--) {\n b[i] = t % 256\n t = Math.floor(t / 256)\n }\n b[6] = 0x70 | (b[6] & 0x0f) // version 7\n b[8] = 0x80 | (b[8] & 0x3f) // variant 0b10\n var h = ''\n for (i = 0; i < 16; i++) {\n h += (b[i] + 0x100).toString(16).slice(1)\n if (i === 3 || i === 5 || i === 7 || i === 9) h += '-'\n }\n return h\n}\n\n/** The cookie jar, or null wherever there is no document to read one from. */\nfunction hzAnonJar() {\n try {\n if (typeof document === 'undefined' || typeof document.cookie !== 'string') return null\n return document\n } catch (e) {\n return null // sandboxed frame with an opaque origin\n }\n}\n\n/** localStorage, or null when the browser refuses it (Safari private mode). */\nfunction hzAnonStore() {\n try {\n if (typeof window === 'undefined' || !window.localStorage) return null\n return window.localStorage\n } catch (e) {\n return null\n }\n}\n\n/** One stored value, or '' — a jar can read as well as refuse to. */\nfunction hzAnonItem(store, name) {\n try {\n return (store && store.getItem(name)) || ''\n } catch (e) {\n return ''\n }\n}\n\n/** The value of cookie `name`, or ''. */\nfunction hzAnonCookie(name) {\n var d = hzAnonJar()\n if (!d) return ''\n var parts = d.cookie.split(';')\n for (var i = 0; i < parts.length; i++) {\n var eq = parts[i].indexOf('=')\n if (eq < 0 || parts[i].slice(0, eq).trim() !== name) continue\n var v = parts[i].slice(eq + 1).trim()\n if (!v) continue\n try {\n return decodeURIComponent(v)\n } catch (e) {\n return v // not percent-encoded — take it as written\n }\n }\n return ''\n}\n\n/** Writes `name` on the registrable domain, for as long as the browser allows. */\nfunction hzAnonWrite(name, value) {\n var d = hzAnonJar()\n if (!d) return\n var host = ''\n var secure = false\n try {\n if (typeof window !== 'undefined' && window.location) {\n host = window.location.hostname || ''\n // A Secure cookie is refused outright by a non-secure origin, which would\n // strand http://localhost dev on the localStorage path.\n secure = window.location.protocol === 'https:'\n }\n } catch (e) {\n /* location unreachable — write a host-only, non-secure cookie */\n }\n // encodeURIComponent leaves a UUID byte-identical while making any value that is\n // not one unable to forge a `;` and inject an attribute.\n var c = name + '=' + encodeURIComponent(value)\n c += '; Path=/; Max-Age=' + HZ_ANON_MAX_AGE + '; SameSite=Lax'\n // Off hanzo.ai (localhost, previews, other registrable domains) the attribute\n // would be rejected and the whole cookie dropped, so it stays host-only there.\n // Prefixing both sides with '.' matches the domain itself and its subdomains\n // while refusing a suffix that merely ends in the same letters (evilhanzo.ai).\n if (('.' + host).slice(-(HZ_ANON_DOMAIN.length + 1)) === '.' + HZ_ANON_DOMAIN) {\n c += '; Domain=' + HZ_ANON_DOMAIN\n }\n if (secure) c += '; Secure'\n try {\n d.cookie = c\n } catch (e) {\n /* cookies refused — localStorage still carries the id */\n }\n}\n\n/**\n * hzAnonId returns the stable anonymous id for this browser, '' during SSR.\n *\n * Resolution is strictly ADDITIVE — every id that already exists is ADOPTED, and\n * only a browser holding none of them is given a new one:\n *\n * cookie · localStorage iam-anon-id · adopted keys · in-memory · mint\n *\n * Minting over an id resets a returning visitor and detaches them from their own\n * history, so the order is the migration: the cookie is the shared home, the two\n * localStorage keys are what the three implementations wrote before it existed,\n * and each is read until nothing is left to adopt.\n *\n * localStorage keeps being written, so a rollback finds everyone where it left\n * them, and a browser that refuses cookies still holds one id per origin.\n */\n/**\n * hzAnonAdopted returns an id already living under a key that used to be canonical,\n * from the cookie jar first — that is the copy shared across subdomains, so a visitor\n * who arrived on one host is the same person on the next.\n */\nfunction hzAnonAdopted(s) {\n for (var i = 0; i < HZ_ANON_ADOPT.length; i++) {\n var id = hzAnonCookie(HZ_ANON_ADOPT[i]) || hzAnonItem(s, HZ_ANON_ADOPT[i])\n if (id) return id\n }\n return ''\n}\n\nfunction hzAnonId() {\n if (typeof window === 'undefined') return '' // SSR / prerender: no browser to identify\n var s = hzAnonStore()\n var id =\n hzAnonCookie(HZ_ANON_KEY) ||\n hzAnonItem(s, HZ_ANON_KEY) ||\n hzAnonAdopted(s) ||\n hzAnonMemo ||\n hzUuidv7()\n hzAnonMemo = id\n hzAnonWrite(HZ_ANON_KEY, id)\n try {\n if (s && s.getItem(HZ_ANON_KEY) !== id) s.setItem(HZ_ANON_KEY, id)\n } catch (e) {\n /* quota exhausted, or a private-mode jar that reads but refuses writes */\n }\n return id\n}\n\n/**\n * hzAnonAdopt makes `id` this browser's anonymous id, replacing whatever it held.\n *\n * A visitor who followed a link from another Hanzo host arrives carrying the id that\n * host minted; keeping the local one splits one journey into two strangers. The\n * caller has already checked the shape.\n */\nfunction hzAnonAdopt(id) {\n hzAnonMemo = id\n hzAnonWrite(HZ_ANON_KEY, id)\n try {\n var s = hzAnonStore()\n if (s) s.setItem(HZ_ANON_KEY, id)\n } catch (e) {\n /* quota exhausted or a read-only jar — the cookie and memo still carry it */\n }\n}\n\n/* ── END hz anon chain ─────────────────────────────────────────────────────── */\n\nexport { hzAnonId, hzAnonAdopt, hzUuidv7 }\n","// The ONE id minter for this client — UUIDv7 (RFC 9562 §5.7).\n//\n// The implementation is `hzUuidv7` in ./anon.js and this file only re-exports it.\n// It lives there because the anonymous-id chain has to mint too, and that chain is\n// inlined verbatim by the distribution that has no bundler (the tag\n// served at /v1/event.js) — a minter here as well would be a second implementation, and\n// the version nibble it produces is exactly the thing that must never diverge.\n//\n// WHY NOT crypto.randomUUID(): it mints v4, whose 122 bits are pure entropy and\n// carry no time. The session rollups on the event plane derive a session's start\n// instant FROM THE ID — their PARTITION BY and ORDER BY are\n// `fromUnixTimestamp(intDiv(toUInt64(bitShiftRight(session_id_v7, 80)), 1000))` —\n// so they admit only ids whose version nibble is 7\n// (`bitAnd(bitShiftRight(toUInt128(session_id), 76), 15) = 7`). A v4 session id is\n// not merely unordered there: it is DISCARDED by that predicate, silently, and the\n// rollup stays empty forever. Minting v7 is the whole reason those rollups can\n// exist; it also clusters index writes by time instead of scattering them across\n// the keyspace.\n//\n// Layout, 16 bytes big-endian:\n// 0..5 unix_ts_ms — 48-bit millisecond timestamp\n// 6 0111 (version 7) in the high nibble | rand_a\n// 7 rand_a\n// 8 10 (variant) in the high 2 bits | rand_b\n// 9..15 rand_b\n//\n// Never returns a non-UUID shape. The old minters fell back to `'a-' + base36`\n// when crypto was absent, and the plane casts a session id with\n// accurateCastOrNull(…, 'UUID') — a shape that does not parse becomes NULL and is\n// dropped by the same gate, so the fallback failed exactly like v4 did. Only the\n// ENTROPY degrades without crypto; the shape is always a valid v7 UUID.\n\n/**\n * uuidv7 mints a time-ordered UUIDv7 for `now` (epoch milliseconds).\n *\n * Two ids minted in the same millisecond sort arbitrarily between themselves; ids\n * from different milliseconds sort by time, lexically and numerically alike.\n */\nexport { hzUuidv7 as uuidv7 } from './anon.js'\n\n/** The millisecond timestamp a v7 id was minted at — the inverse of uuidv7. */\nexport function uuidv7Time(id: string): number {\n return parseInt(id.slice(0, 8) + id.slice(9, 13), 16)\n}\n","// SSR-safe browser storage for stable identifiers and first-touch state. Every\n// accessor no-ops (returns undefined) when there is no window/localStorage, so the\n// client imports cleanly in a Next.js server component.\n//\n// The anonymous id is the one value that must outlive an ORIGIN, and it is also\n// the one value the OTHER two distributions must agree with, so its chain lives in\n// ./anon.js and this file only calls it. Everything else here stays origin-local.\n\nimport { hzAnonAdopt, hzAnonId } from './anon.js'\nimport type { Attribution, Cohort } from './types'\nimport { uuidv7 } from './uid'\n\nconst KEY = {\n session: 'hz_session',\n firstTouch: 'hz_first_touch',\n cohort: 'hz_cohort',\n} as const\n\n/** 30-minute inactivity window defines a session (PostHog/GA convention). */\nconst SESSION_TTL_MS = 30 * 60 * 1000\n\nfunction ls(): Storage | undefined {\n try {\n if (typeof window === 'undefined' || !window.localStorage) return undefined\n return window.localStorage\n } catch {\n return undefined // Safari private mode / blocked storage\n }\n}\n\n/**\n * Stable anonymous id, shared by every *.hanzo.ai surface AND by every Hanzo\n * client on the page — the npm client and the hosted tag both run the one\n * chain in ./anon.js, so which snippet a surface loaded no longer decides who the\n * visitor is.\n *\n * It lives in a first-party cookie on the registrable domain because localStorage\n * is ORIGIN-scoped: docs, cloud and console each minted their own id for the same\n * person, so one marketing → docs → signup → checkout journey arrived as several\n * strangers — 463 anonymous identities carried 545 events in a week, about 1.2\n * events each.\n */\nexport function anonId(): string | undefined {\n return hzAnonId() || undefined // '' during SSR / prerender\n}\n\ninterface SessionState {\n id: string\n last: number\n}\n\n/**\n * Current session id, rotated after SESSION_TTL_MS of inactivity.\n *\n * Minted at `now`, so the v7 timestamp the id carries IS the session's start\n * instant — which is what the session rollups partition and order on. Passing the\n * caller's clock rather than reading Date.now() again keeps the id's embedded time\n * and the recorded `last` from disagreeing.\n */\nexport function sessionId(now = Date.now()): string | undefined {\n const s = ls()\n if (!s) return undefined\n let state: SessionState | null = null\n try {\n state = JSON.parse(s.getItem(KEY.session) || 'null')\n } catch {\n state = null\n }\n if (!state || now - state.last > SESSION_TTL_MS) {\n state = { id: uuidv7(now), last: now }\n } else {\n state.last = now\n }\n s.setItem(KEY.session, JSON.stringify(state))\n return state.id\n}\n\n/** Make `id` the current session, as if it had begun now. The session a link\n * carries is the one the visitor is already in, so the journey stays one session\n * across the hop instead of splitting at the host boundary. */\nexport function adoptSession(id: string, now = Date.now()): void {\n const s = ls()\n if (s) s.setItem(KEY.session, JSON.stringify({ id, last: now }))\n}\n\n/** Make `id` the browser's anonymous id, replacing the one it held. */\nexport function adoptAnonId(id: string): void {\n hzAnonAdopt(id)\n}\n\n/** Read the persisted first-touch attribution. */\nexport function getFirstTouch(): Attribution | undefined {\n const s = ls()\n if (!s) return undefined\n try {\n const v = s.getItem(KEY.firstTouch)\n return v ? (JSON.parse(v) as Attribution) : undefined\n } catch {\n return undefined\n }\n}\n\n/** Persist first-touch attribution ONCE — never overwrite an existing record. */\nexport function setFirstTouchOnce(a: Attribution): Attribution {\n const s = ls()\n const existing = getFirstTouch()\n if (existing) return existing\n if (s) s.setItem(KEY.firstTouch, JSON.stringify(a))\n return a\n}\n\n/** Read persisted cohort dimensions. */\nexport function getCohort(): Cohort | undefined {\n const s = ls()\n if (!s) return undefined\n try {\n const v = s.getItem(KEY.cohort)\n return v ? (JSON.parse(v) as Cohort) : undefined\n } catch {\n return undefined\n }\n}\n\n/** Merge + persist cohort dimensions (signupWeek set once). */\nexport function mergeCohort(patch: Cohort): Cohort {\n const s = ls()\n const cur = getCohort() || {}\n const next: Cohort = {\n signupWeek: cur.signupWeek || patch.signupWeek,\n channel: patch.channel || cur.channel,\n refCode: cur.refCode || patch.refCode,\n }\n if (s) s.setItem(KEY.cohort, JSON.stringify(next))\n return next\n}\n","// Cross-domain visitor continuity.\n//\n// Cookies and localStorage stop at the registrable domain, so a visitor who goes\n// hanzo.ai -> hanzo.id (sign-in) -> back arrived as separate people on each host, and\n// the journey across the sign-in redirect could not be read. A link between two\n// Hanzo hosts therefore carries the visitor's identity in three short query\n// parameters, and the destination adopts them before its first pageview and\n// removes them from the address bar.\n//\n// hz_aid anonymous id hz_sid session id hz_ft first-touch attribution\n//\n// They are appended ONLY when the destination host belongs to a brand in ORG_DOMAIN:\n// an id handed to a host outside the table would be handed to a stranger.\n\nimport { orgOf } from './org'\nimport type { Attribution } from './types'\n\nexport const LINK_PARAMS = { anon: 'hz_aid', session: 'hz_sid', firstTouch: 'hz_ft' } as const\n\n/** Ids are v7 UUIDs; anything else in a URL is someone else's input and is refused. */\nconst UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\nexport const isId = (v: string | null | undefined): v is string => !!v && UUID.test(v)\n\n/** What a link carries. Any field may be absent. */\nexport interface LinkState {\n anonId?: string\n sessionId?: string\n firstTouch?: Attribution\n}\n\n/** First touch as a compact tuple: utm source, medium, campaign, term, content, refCode,\n * referrer, channel. Short because it rides a URL; a tuple because keys cost bytes. */\nexport function encodeFirstTouch(a: Attribution): string {\n return JSON.stringify([\n a.utm.source, a.utm.medium, a.utm.campaign, a.utm.term, a.utm.content,\n a.refCode, a.referrer, a.channel,\n ].map((v) => v ?? ''))\n}\n\nexport function decodeFirstTouch(raw: string | null | undefined): Attribution | undefined {\n if (!raw || raw.length > 1024) return undefined\n try {\n const t: unknown = JSON.parse(raw)\n if (!Array.isArray(t) || t.length !== 8 || t.some((v) => typeof v !== 'string')) return undefined\n const [source, medium, campaign, term, content, refCode, referrer, channel] = t as string[]\n const u = (v: string) => v || undefined\n return {\n utm: { source: u(source), medium: u(medium), campaign: u(campaign), term: u(term), content: u(content) },\n refCode: u(refCode),\n referrer: u(referrer),\n channel: u(channel),\n }\n } catch {\n return undefined\n }\n}\n\n/** linkUrl returns `url` with the visitor's identity appended when its host is\n * Hanzo-owned and is not `fromHost`; otherwise `url` unchanged. Relative URLs\n * resolve against `base`. Never throws. */\nexport function linkUrl(url: string, state: LinkState, fromHost: string, base?: string): string {\n let u: URL\n try {\n u = new URL(url, base)\n } catch {\n return url\n }\n if (u.protocol !== 'https:' && u.protocol !== 'http:') return url\n if (!orgOf(u.hostname) || u.hostname === fromHost) return url\n const set = (k: string, v: string | undefined) => v && u.searchParams.set(k, v)\n if (isId(state.anonId)) set(LINK_PARAMS.anon, state.anonId)\n if (isId(state.sessionId)) set(LINK_PARAMS.session, state.sessionId)\n if (state.firstTouch) set(LINK_PARAMS.firstTouch, encodeFirstTouch(state.firstTouch))\n return u.toString()\n}\n\n/** readLink parses what a link carried out of a location.search value. Invalid\n * values are dropped, not repaired. */\nexport function readLink(search: string): LinkState {\n const q = new URLSearchParams(search || '')\n const a = q.get(LINK_PARAMS.anon)\n const s = q.get(LINK_PARAMS.session)\n return {\n anonId: isId(a) ? a : undefined,\n sessionId: isId(s) ? s : undefined,\n firstTouch: decodeFirstTouch(q.get(LINK_PARAMS.firstTouch)),\n }\n}\n\n/** stripLink returns the path, query and hash of `href` without the link parameters, or\n * undefined when there were none. */\nexport function stripLink(href: string): string | undefined {\n const u = new URL(href)\n let hit = false\n for (const k of Object.values(LINK_PARAMS)) {\n if (u.searchParams.has(k)) {\n u.searchParams.delete(k)\n hit = true\n }\n }\n return hit ? u.pathname + u.search + u.hash : undefined\n}\n","{\n \"name\": \"@hanzo/event\",\n \"version\": \"0.3.49\",\n \"description\": \"Hanzo Event \\u2014 the ONE telemetry client. Emits pageview/event/identify/group to the Hanzo Cloud event stream (POST /v1/event), AND reports errors to Sentry as real Sentry envelopes \\u2014 the error plane needs a DSN, without one nothing reaches Sentry. First-touch attribution, beacon-on-unload, auto error capture, client-side secret/PII scrubbing, a shared event + goal vocabulary. Subsumes @sentry.\",\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org/\",\n \"access\": \"public\",\n \"scope\": \"@hanzo\"\n },\n \"author\": \"Hanzo AI <dev@hanzo.ai>\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"sideEffects\": false,\n \"files\": [\n \"dist\",\n \"src\",\n \"README.md\",\n \"TAXONOMY.md\"\n ],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/hanzoai/ui.git\",\n \"directory\": \"pkg/event\"\n },\n \"keywords\": [\n \"analytics\",\n \"product-analytics\",\n \"telemetry\",\n \"events\",\n \"error-tracking\",\n \"sentry\",\n \"attribution\",\n \"funnel\",\n \"hanzo\"\n ],\n \"scripts\": {\n \"prepublishOnly\": \"node ../../scripts/guard-publish.mjs\",\n \"build\": \"tsup && tsc --emitDeclarationOnly --declaration --outDir dist && node ../../scripts/dts.mjs\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"typecheck\": \"tsc --noEmit -p tsconfig.json\",\n \"clean\": \"rm -rf dist\"\n },\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.mjs\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n },\n \"./react\": {\n \"import\": {\n \"types\": \"./dist/react.d.ts\",\n \"default\": \"./dist/react.mjs\"\n },\n \"require\": {\n \"types\": \"./dist/react.d.cts\",\n \"default\": \"./dist/react.cjs\"\n }\n }\n },\n \"peerDependencies\": {\n \"react\": \">=19.2.8\"\n },\n \"peerDependenciesMeta\": {\n \"react\": {\n \"optional\": true\n }\n },\n \"devDependencies\": {\n \"@types/node\": \"catalog:\",\n \"@types/react\": \"catalog:\",\n \"react\": \"catalog:\",\n \"tsup\": \"catalog:\",\n \"typescript\": \"catalog:\",\n \"vitest\": \"catalog:\"\n },\n \"dependencies\": {\n \"@hanzo/events\": \"catalog:\"\n }\n}\n","// The library version, stamped on every event (`libraryVersion`) and on the\n// Sentry `sdk` block. It lives alone so `sentry.ts` can read it without importing\n// `core.ts` — core imports sentry, so the reverse would be an import cycle.\n//\n// Read from package.json rather than restated, because a version restated is a\n// version that drifts: 0.3.38 and 0.3.39 both shipped while this file still said\n// 0.3.37, so every event those builds sent named a library that was two releases\n// behind. `resolveJsonModule` inlines the literal at build time, and tsup shakes\n// the rest of the manifest out.\nimport { version } from '../package.json'\n\nexport const VERSION: string = version\n","// The framework-agnostic event client. ONE API surface over TWO orthogonal\n// planes, sharing one session and one identity:\n//\n// 1. EVENT STREAM — buffered pageview/event/identify/group, flushed as ONE\n// batch to the Hanzo Cloud entry point:\n// POST {host}/v1/event body: { batch: [Event, …] } -> { accepted, dropped }\n// Cloud resolves the tenant server-side (validated session, or the signed\n// publishable key) and stamps it; the client NEVER sends the org.\n//\n// Errors ride the same pipe: a captured exception is ONE event of type 'error'\n// carrying {type, message, frames|stack, handled} plus release, environment,\n// site, product and level. The server files it on the error plane and groups it\n// into an issue. There is no second endpoint, DSN or envelope.\n//\n// Auth is orthogonal — the SAME body to the SAME endpoint, differing only in how the\n// caller proves its tenant:\n//\n// • cookie/session app (host:'') — same-origin credentials ride the request.\n// • bearer app (getToken) — Authorization: Bearer <jwt>.\n// • publishable-key app (ingestKey: 'pk-…') — ?ingest_key=pk-… on the query, on\n// the fetch and the beacon alike, with a text/plain body. Write-only and safe\n// to ship in a bundle; the endpoint resolves it to an org server-side. The query\n// is the carrier neither send needs a header for, which is what keeps both\n// CORS-simple and therefore sendable from a customer's own origin.\n//\n// The wire is the canonical `Event` (== the cloud CaptureEvent).\n\nimport {\n parseAttribution,\n hasAttribution,\n deriveChannel,\n} from './attribution'\nimport { keyForPage } from './org'\nimport { PAGEVIEW } from './events'\nimport { scrubText, withoutFragment } from './scrub'\nimport { framesFromStack, normalizeError as normalizeThrowable } from './throwable'\nimport {\n adoptAnonId,\n adoptSession,\n anonId,\n sessionId,\n getFirstTouch,\n setFirstTouchOnce,\n getCohort,\n mergeCohort,\n} from './storage'\nimport { uuidv7 } from './uid'\nimport { linkUrl, readLink, stripLink } from './link'\nimport type {\n AnalyticsConfig,\n Attribution,\n CaptureErrorOptions,\n Cohort,\n EventKind,\n Exception,\n Transport,\n WireEvent,\n} from './types'\nimport { VERSION } from './version'\n\nexport { VERSION }\n\nconst EVENT_PATH = '/v1/event' // the ONE canonical ingestion entry point\nconst DEFAULT_HOST = 'https://api.hanzo.ai' // the one edge; cookie apps pass host:''\n// The beacon body's type. text/plain is CORS-SAFELISTED, which is the whole\n// property: a safelisted type makes the POST a SIMPLE request, and a simple\n// request needs no preflight. An unloading document does not get a second round\n// trip, so cross-origin a preflighted beacon is never sent at all. The endpoint reads\n// the raw body and dispatches on its first non-space byte, so the type names the\n// CORS class and nothing else.\nconst BEACON_CONTENT_TYPE = 'text/plain'\n\n/** readEnv reads an inlined build-time variable, guarded for SSR. */\nfunction readEnv(name: string): string | undefined {\n try {\n if (typeof process !== 'undefined' && process.env) return process.env[name] || undefined\n } catch {\n /* no process */\n }\n return undefined\n}\n\n/** appendQuery adds a single query param to a URL string — used to carry a\n * publishable key on either send (?ingest_key=…). */\nfunction appendQuery(url: string, key: string, value: string): string {\n return url + (url.includes('?') ? '&' : '?') + key + '=' + encodeURIComponent(value)\n}\n\n/** Normalize anything thrown (Error | string | unknown) into an Exception. */\n/** normalizeError adapts the hostile-input-safe normalizer (sentry.ts) to the\n * stream's Exception shape: a thrown object may define `name`/`message`/`stack`\n * as throwing getters. */\nfunction normalizeError(err: unknown): Exception {\n const n = normalizeThrowable(err)\n const frames = framesFromStack(n.stack)\n .slice(-50)\n .map((f) => ({ function: f.function, file: f.filename, line: f.lineno, column: f.colno }))\n return { type: n.name, message: n.message, stack: n.stack, frames }\n}\n\n// React Native defines a `window` but no `document` (and no `window.location`),\n// so `typeof window !== 'undefined'` alone took the browser path there and\n// `init()` threw on `window.location.search`. Requiring `document` makes RN read\n// as non-browser: `init()` returns early (skips attribution + the visibility/\n// unload listeners RN doesn't have), while `capture()`/`flush()` — which are NOT\n// gated on this and post through plain `fetch` — still emit. So the client is\n// inert-safe under SSR/Node and live on RN, without a second transport.\nconst isBrowser = () => typeof window !== 'undefined' && typeof document !== 'undefined'\n\n/** serializeBatch stringifies a batch, salvaging what it can. `properties` is\n * arbitrary caller data — a DOM node, a React synthetic event, an axios error are\n * all circular, and a getter on one can throw — so a whole batch must never be\n * lost to a single poisoned event. Falls back to per-event serialization, then to\n * keeping the event and dropping its properties. Returns null only when nothing\n * at all survives. */\nfunction serializeBatch(batch: WireEvent[]): string | null {\n try {\n return JSON.stringify({ batch })\n } catch {\n /* one bad event — salvage the rest below */\n }\n const parts: string[] = []\n for (const e of batch) {\n try {\n parts.push(JSON.stringify(e))\n } catch {\n try {\n // Keep the event (identity, session, type all matter); drop the payload\n // that could not be serialized, and say so rather than lying by omission.\n parts.push(JSON.stringify({ ...e, properties: { $unserializable: true } }))\n } catch {\n /* unsalvageable — drop this ONE event, never the batch */\n }\n }\n }\n return parts.length > 0 ? '{\"batch\":[' + parts.join(',') + ']}' : null\n}\n\n/** DefaultTransport: fetch(keepalive) for authenticated/normal sends;\n * navigator.sendBeacon for page-unload beacons.\n *\n * A publishable key rides the ?ingest_key query on BOTH, which is what keeps\n * both CORS-simple: the query is the one carrier neither send needs a header\n * for, and a simple request leaves the browser from any origin — permission is\n * asked to READ a cross-origin response, never to send one. That is what lets a\n * bundled client run on a customer's own page. A JWT is first-party by\n * construction, so it keeps Authorization and the session it travels with.\n *\n * `contentType` names the FETCH request's Content-Type (the error plane sets the\n * envelope type there, and keeps the header carrier with it). The beacon body is\n * always BEACON_CONTENT_TYPE: its type is a CORS class, not a payload\n * description, and a beacon that is not a simple request is never sent. */\nclass DefaultTransport implements Transport {\n send(\n url: string,\n body: string,\n opts: {\n beacon: boolean\n token?: string\n ingestKey?: string\n contentType?: string\n debug?: boolean\n },\n ): void {\n if (opts.beacon && isBrowser() && typeof navigator.sendBeacon === 'function') {\n const beaconUrl = opts.ingestKey ? appendQuery(url, 'ingest_key', opts.ingestKey) : url\n try {\n // The answer is whether the agent QUEUED the batch — false for a body past\n // the beacon size limit, or a full queue. Only a queued batch ends the\n // send; a refused one falls through to the keepalive fetch below.\n const queued = navigator.sendBeacon(\n beaconUrl,\n new Blob([body], { type: BEACON_CONTENT_TYPE }),\n )\n if (queued) return\n if (opts.debug) console.warn('[event] beacon refused, falling back to fetch')\n } catch {\n /* fall through to fetch */\n }\n }\n if (typeof fetch !== 'function') return\n // A publishable key makes the send a CORS SIMPLE request: the key rides the\n // query, the body is text/plain, and nothing asks for credentials. That is what\n // lets a bundled client run on a customer's own page — every send from there is\n // cross-origin, and an Authorization header or a JSON type preflights the POST\n // for an origin that cannot pass one. A JWT is first-party by construction, so\n // it keeps the header and the session it travels with, and so does the error\n // plane, which names its own envelope type.\n const simple = opts.ingestKey !== undefined && opts.contentType === undefined\n const headers: Record<string, string> = {\n 'Content-Type': simple ? BEACON_CONTENT_TYPE : (opts.contentType ?? 'application/json'),\n }\n const bearer = simple ? undefined : (opts.ingestKey ?? opts.token)\n if (bearer) headers.Authorization = `Bearer ${bearer}`\n void fetch(simple ? appendQuery(url, 'ingest_key', opts.ingestKey!) : url, {\n method: 'POST',\n headers,\n body,\n keepalive: true,\n credentials: simple ? 'omit' : 'include',\n })\n .then((res) => {\n // Telemetry loss never throws into the app — but silence is how this\n // client lost the fleet's errors in the first place. Under `debug`, say\n // so. A rejected ingest (the CORS allowlist 403s non-production origins,\n // so local dev NEVER reports) is otherwise indistinguishable from success.\n if (!res.ok && opts.debug) {\n console.warn('[event] ingest rejected', res.status, url.split('?')[0])\n }\n })\n .catch((e: unknown) => {\n if (opts.debug) console.warn('[event] ingest failed', url.split('?')[0], e)\n })\n }\n}\n\nexport class Analytics {\n private cfg: Required<\n Pick<AnalyticsConfig, 'product' | 'batchSize' | 'flushIntervalMs' | 'enabled' | 'captureErrors'>\n > &\n AnalyticsConfig\n private transport: Transport\n private queue: WireEvent[] = []\n private timer: ReturnType<typeof setTimeout> | null = null\n private personId?: string\n private attribution: Attribution = { utm: {} }\n private cohort: Cohort = {}\n private started = false\n /** The view pageview() last counted — path + location. */\n private counted?: string\n /** Guards against an error thrown *inside* the error path re-entering it. */\n private reentrant = false\n\n constructor(config: AnalyticsConfig) {\n this.cfg = {\n host: DEFAULT_HOST,\n batchSize: 20,\n flushIntervalMs: 5000,\n enabled: true,\n captureErrors: true,\n ...config,\n // The publishable key resolves from ONE live source, never a literal baked\n // beside the code. Most specific first:\n // 1. an explicit `ingestKey` in config;\n // 2. NEXT_PUBLIC_PUBLISHABLE_KEY, the inlined build-time env the fleet\n // carries end to end — KMS `deploy/PUBLISHABLE_KEY` -> the PUBLISHABLE_KEY\n // build-arg -> the NEXT_PUBLIC_ prefix Next inlines.\n //\n // 3. the org that owns the HOST this page is served from (`org.ts`).\n //\n // Step 3 fires only when a surface configured NOTHING, so it never overrides\n // the KMS chain above — it replaces going dark with reporting to the right\n // brand. That is what a static export needs: `output: export` inlines no env,\n // so before this the only way to report was to commit a key literal, and the\n // fleet grew one copy per site of a value with a single source.\n //\n // A surface no brand claims still has no key, and the edge REFUSES an\n // unattributed event (401 `ingest_key_required`) — the reserved `$public`\n // tenant that once caught keyless beacons is retired, and anonymous ingest is\n // refused at every edge on every brand host. So there is no quiet fallback to\n // rely on: an event lands in the org a credential names, or it does not land.\n ingestKey:\n config.ingestKey ?? readEnv('NEXT_PUBLIC_PUBLISHABLE_KEY') ?? keyForPage(),\n }\n this.transport = config.transport ?? new DefaultTransport()\n }\n\n /** adopt gives this client a credential it does not have. The key belongs to\n * the stream, not to whichever caller happened to ask for the handle first,\n * so a later caller carrying one hands it over. Present fields are never overwritten: the first caller's key stays. */\n adopt(config: AnalyticsConfig): void {\n if (config.ingestKey && !this.cfg.ingestKey) this.cfg.ingestKey = config.ingestKey\n if (config.getToken && !this.cfg.getToken) this.cfg.getToken = config.getToken\n }\n\n /** init is idempotent and browser-only for its side effects: capture first-touch\n * attribution, hydrate cohort, register the unload flush, and (unless opted out)\n * auto-capture unhandled errors. Safe to call from a React effect on every\n * render. */\n init(): void {\n if (this.started || !this.cfg.enabled) return\n this.started = true\n if (!isBrowser()) return\n\n // A link from another Hanzo host carries the visitor with it. Adopt it FIRST, so\n // the first pageview is already the same person, session and first touch.\n const linked = readLink(window.location.search)\n if (linked.anonId) adoptAnonId(linked.anonId)\n if (linked.sessionId) adoptSession(linked.sessionId)\n const clean = stripLink(window.location.href)\n if (clean !== undefined) {\n try {\n window.history.replaceState(window.history.state, '', clean)\n } catch {\n /* a sandboxed frame may refuse; the params are then simply visible */\n }\n }\n\n const parsed = parseAttribution(window.location.search, document.referrer)\n // The first touch the link carries is the visit's real origin. Without it this\n // host's own \"first touch\" would be the referring Hanzo page, which says nothing.\n const first = linked.firstTouch && !getFirstTouch() ? setFirstTouchOnce(linked.firstTouch) : undefined\n this.attribution =\n first ?? (hasAttribution(parsed) ? setFirstTouchOnce(parsed) : getFirstTouch() ?? parsed)\n this.cohort = mergeCohort({\n channel: this.attribution.channel ?? deriveChannel(this.attribution),\n refCode: this.attribution.refCode,\n })\n\n const flushHidden = () => {\n if (document.visibilityState === 'hidden') this.flush(true)\n }\n window.addEventListener('visibilitychange', flushHidden)\n window.addEventListener('pagehide', () => this.flush(true))\n\n // Unhandled errors and rejected promises are reported as type:'error' events.\n if (this.cfg.captureErrors) {\n window.addEventListener('error', (e: ErrorEvent) => {\n this.captureError(e.error ?? e.message, { handled: false })\n })\n window.addEventListener('unhandledrejection', (e: PromiseRejectionEvent) => {\n this.captureError(e.reason, { handled: false })\n })\n }\n }\n\n /** link returns `url` carrying this visitor's anonymous id, session and first\n * touch when the destination is a Hanzo-owned host, so the journey continues\n * across the hop. Any other URL comes back unchanged. */\n link(url: string): string {\n if (!isBrowser()) return url\n if (!this.started) this.init()\n return linkUrl(\n url,\n { anonId: anonId(), sessionId: sessionId(), firstTouch: this.attribution },\n window.location.hostname,\n window.location.href,\n )\n }\n\n /** authorize decorates an OAuth authorize URL for the redirect to IAM and flushes\n * what is queued, because the page is about to unload. Assign the result to\n * `location`. */\n authorize(url: string): string {\n const out = this.link(url)\n this.flush(true)\n return out\n }\n\n /** identify binds the current visitor to a stable person id (post-login). */\n identify(personId: string, traits?: Record<string, unknown>): void {\n this.personId = personId\n this.enqueue('identify', undefined, { properties: traits })\n }\n\n /** group associates the visitor with an org/team (analytics grouping, not the\n * server tenant — the server still derives tenant from the session). */\n group(groupId: string, traits?: Record<string, unknown>): void {\n this.enqueue('group', undefined, { groupId, properties: traits })\n }\n\n /** pageview records a $pageview for the current (or given) location, once per\n * view. A view is the path plus the full location, so a query or hash change\n * is a new one and a repeat call for the same place is not. */\n pageview(path?: string, properties?: Record<string, unknown>): void {\n // No `url` here: build() reads window.location.href for every event, in the\n // same tick, so this recomputed it to the identical value. Only `path` is\n // passed, because a route change fires before window.location has caught up\n // and the caller's value has to win.\n const p = path ?? (isBrowser() ? window.location.pathname : undefined)\n // Counting a page once is the client's rule, not each caller's. A page holds\n // several emitters that each correctly believe they count the first view —\n // the provider's autoPageview, a router hook, a nav autocapture — and per\n // emitter state cannot see the others. On the stream they are one page.\n const view = (p ?? '') + '\\0' + (isBrowser() ? window.location.href : '')\n if (view === this.counted) return\n this.counted = view\n this.enqueue('pageview', PAGEVIEW, { path: p, properties })\n }\n\n /** capture records a named product event with optional properties. Commerce\n * fields (productId/quantity/revenue/currency) may be passed for order events. */\n capture(\n event: string,\n properties?: Record<string, unknown>,\n commerce?: Pick<WireEvent, 'productId' | 'quantity' | 'revenue' | 'currency'>,\n ): void {\n this.enqueue('event', event, { properties, ...commerce })\n }\n\n /** captureError reports a caught error, an unhandled rejection, a React render\n * error, or a manual report as ONE event of type 'error' on the one stream.\n * It carries the exception (type, message, frames, stack, handled) and the\n * release, environment, site, product and level that group and scope it, and\n * flushes promptly (a crash may unload the page moments later). Never throws\n * back into the app. */\n captureError(err: unknown, context?: CaptureErrorOptions): void {\n // A failure inside the error path must not recurse through the global handlers.\n if (this.reentrant) return\n this.reentrant = true\n try {\n const handled = context?.handled ?? true\n const ex = normalizeError(err)\n ex.handled = handled\n this.enqueue('error', undefined, {\n error: ex,\n level: context?.level ?? (handled ? 'error' : 'fatal'),\n release: this.cfg.release ?? readEnv('NEXT_PUBLIC_HANZO_RELEASE'),\n environment: this.cfg.environment ?? readEnv('NODE_ENV'),\n site: isBrowser() ? window.location.hostname : undefined,\n properties: context?.properties,\n })\n this.flush()\n } catch {\n /* the error path never takes the app down */\n } finally {\n this.reentrant = false\n }\n }\n\n /** setCohort persists cohort dimensions (e.g. signupWeek at signup) so they ride\n * every subsequent event. */\n setCohort(patch: Cohort): void {\n this.cohort = mergeCohort(patch)\n }\n\n /** flush drains the buffer to the server as ONE batch through the ONE ingest\n * endpoint POST /v1/event, body { batch: [Event…] }. beacon=true selects the\n * unload-safe transport. Auth is orthogonal to the wire:\n *\n * • publishable key set → rides ?ingest_key=pk-… on both sends, keeping each\n * a CORS-simple request that any origin may send.\n * • else a bearer JWT rides Authorization (fetch only — sendBeacon cannot\n * carry a header, so token apps fall back to keepalive fetch on unload).\n * • else a cookie app rides same-origin credentials (beacon carries the\n * cookie fine).\n */\n flush(beacon = false): void {\n if (!this.cfg.enabled || this.queue.length === 0) return\n const batch = this.queue\n this.queue = []\n this.clearTimer()\n\n // A publishable key and a bearer JWT are mutually exclusive credentials, and the\n // BEARER WINS. It names a real principal and resolves to THAT person's org;\n // a pk- names one org for everybody holding it. So the key is what attributes\n // a visitor nobody has vouched for, and it must never displace someone who\n // has been.\n //\n // The precedence used to run the other way, which was survivable only while\n // the key had to be passed in code. Once it also resolves from the build env,\n // key-wins means setting one variable silently blanks every signed-in user's\n // token and re-files their events under whichever org minted the key — on a\n // console served to several brands from one bundle, that is a cross-tenant\n // leak introduced by an env var.\n const token = this.cfg.getToken?.() ?? undefined\n const key = token ? undefined : this.cfg.ingestKey?.trim() || undefined\n // Only a bearer JWT blocks the beacon: sendBeacon cannot set an Authorization\n // header. A pk- rides ?ingest_key; a cookie rides credentials.\n const useBeacon = beacon && !token\n const body = serializeBatch(batch)\n if (body === null) {\n if (this.cfg.debug) console.debug('[event] flush → dropped, batch unserializable')\n return\n }\n if (this.cfg.debug) console.debug('[event] flush →', EVENT_PATH, batch.length)\n this.transport.send(this.cfg.host + EVENT_PATH, body, {\n beacon: useBeacon,\n token,\n ingestKey: key,\n debug: this.cfg.debug,\n })\n }\n\n // ── internals ────────────────────────────────────────────────────────────\n\n private enqueue(kind: EventKind, event: string | undefined, extra: Partial<WireEvent>): void {\n if (!this.cfg.enabled) return\n if (!this.started) this.init()\n this.queue.push(this.build(kind, event, extra))\n if (this.queue.length >= this.cfg.batchSize) this.flush()\n else this.schedule()\n }\n\n private build(kind: EventKind, event: string | undefined, extra: Partial<WireEvent>): WireEvent {\n const anon = anonId()\n const wire: WireEvent = {\n messageId: uuidv7(),\n type: kind,\n event,\n timestamp: new Date().toISOString(),\n distinctId: this.personId ?? anon,\n anonymousId: anon,\n personId: this.personId,\n sessionId: sessionId(),\n product: this.cfg.product,\n referrer: this.attribution.referrer,\n utm: this.attribution.utm,\n refCode: this.cohort.refCode ?? this.attribution.refCode,\n channel: this.cohort.channel ?? this.attribution.channel,\n signupWeek: this.cohort.signupWeek,\n // Where the event happened, stamped for every kind rather than only for\n // pageviews. An interaction is reported against the page it happened on,\n // and autocapture ($click/$input/$change) reaches the wire through\n // capture(), which supplies no location — so every click arrived with an\n // empty url and path, and `host`, derived from url, was empty with them.\n // That is unattributable to a page, which is the one thing a heatmap\n // needs. Read here, at the single point every event is built, so it\n // cannot go missing from a call site again.\n //\n // Before `...extra`: pageview() passes an explicit path for route\n // changes that fire before window.location has caught up, and that value\n // has to win over the one read here.\n url: isBrowser() ? window.location.href : undefined,\n path: isBrowser() ? window.location.pathname : undefined,\n library: '@hanzo/event',\n libraryVersion: VERSION,\n ...extra,\n }\n\n // A location is free text an attacker (or an ordinary product flow) controls,\n // and it is now stamped on EVERY event rather than only pageviews — so the\n // one field that is always a URL gets the same policy the error plane has\n // always applied to error text. A password-reset, invite or magic link puts\n // a JWT in the query and an address in `?email=`; without this, one click on\n // that page ships both to the warehouse in cleartext, and every later click\n // repeats it.\n //\n // AFTER `...extra`, deliberately. A call site can pass its own location —\n // pageview() passes `path`, and until this commit it passed `url` too — and\n // `extra` merges over the fields read above, so scrubbing at the read would\n // have left the highest-volume event emitting a raw location while looking\n // scrubbed. Applied to the ASSEMBLED record, the guarantee holds for every\n // call site, including ones not written yet.\n //\n // `scrubText` is the SAME policy as the error plane (secrets always,\n // PII unless capturePII) rather than a second URL-specific redactor: one\n // definition of \"must not leave the browser\", already tested, mirroring the\n // server's. Guarded on presence so an absent field stays absent instead of\n // becoming the empty string that `host` derivation reads as a page.\n //\n // The fragment goes first and whole: nothing after `#` is ever the server's\n // (see withoutFragment), so it is dropped rather than scrubbed.\n const capturePII = this.cfg.capturePII ?? false\n if (wire.url) wire.url = scrubText(withoutFragment(wire.url), capturePII)\n if (wire.path) wire.path = scrubText(withoutFragment(wire.path), capturePII)\n if (wire.referrer) wire.referrer = scrubText(withoutFragment(wire.referrer), capturePII)\n return wire\n }\n\n private schedule(): void {\n if (this.timer || !this.cfg.enabled) return\n this.timer = setTimeout(() => {\n this.timer = null\n this.flush()\n }, this.cfg.flushIntervalMs)\n }\n\n private clearTimer(): void {\n if (this.timer) {\n clearTimeout(this.timer)\n this.timer = null\n }\n }\n}\n\n// ── one stream, one client ──────────────────────────────────────────────────\n//\n// A page has ONE event stream per (host, product): one queue, one anon id, one\n// credential. Two clients on it split the batch and double the pageview, and\n// the half built by the caller that had no key is refused at the edge — so the\n// same page is both over- and under-counted, and neither number says so.\n//\n// Two callers ask for that stream on any real page and both are right to: the\n// app mounts a provider, and the component library mounts its own telemetry.\n// Neither can see the other, so the fix cannot live in either. It lives here,\n// where the stream is: asking twice returns the same client.\n//\n// The registry is on the PAGE, under a `Symbol.for` slot, not in module scope.\n// `@hanzo/event` and `@hanzo/event/react` are separate bundles that each carry\n// a copy of this module, so a module-scope map is per-copy and the two copies\n// never see each other's — which is exactly how the duplicate arises. A\n// well-known symbol is the one slot every copy resolves to the same value.\n//\n// Browser only. A server process serves many visitors, and one client shared\n// across requests would carry one visitor's personId into the next.\nconst CLIENTS = Symbol.for('hanzo.event.clients')\n\nfunction registry(): Map<string, Analytics> {\n const g = globalThis as unknown as Record<symbol, Map<string, Analytics> | undefined>\n const existing = g[CLIENTS]\n if (existing) return existing\n const fresh = new Map<string, Analytics>()\n g[CLIENTS] = fresh\n return fresh\n}\n\n/** resetClients drops the page's clients, so the next `createAnalytics` for a\n * stream builds a fresh one.\n *\n * A real page loads once and never needs this. A TEST RUNNER is what it exists\n * for: one document, many mounts, each meant to be its own page. The second one\n * gets a client that already counted this location, so its pageview is\n * correctly suppressed and the suite reads it as \"nothing was emitted\".\n *\n * It is exported so a suite calls this instead of reaching for the slot itself.\n * A consumer that deletes the registry from its own code path takes the\n * guarantee with it: `<Provider/>` unmount/remount is not a new page, and the\n * fresh client it would get counts the same view again. */\nexport function resetClients(): void {\n const g = globalThis as unknown as Record<symbol, Map<string, Analytics> | undefined>\n delete g[CLIENTS]\n}\n\n/** createAnalytics returns the client for a stream, building it on first ask.\n * This is the ONE way to get a client: `new Analytics` bypasses the registry\n * and is for tests and for a deliberately separate instance. */\nexport function createAnalytics(config: AnalyticsConfig): Analytics {\n // A disabled client emits nothing, so it can double nothing and does not take\n // the stream. Callers reach their answer at different moments — a provider\n // whose ownership resolves in an effect renders once saying `false` before it\n // has decided anything — and the client built in that moment must not become\n // the one the page keeps. Registering it would silence the page, and adopting\n // `enabled` from a later caller would let one surface overrule another's\n // reading of consent. Neither: it is simply not the stream's client.\n if (!isBrowser() || config.enabled === false) return new Analytics(config)\n const key = (config.host ?? DEFAULT_HOST) + '\\0' + config.product\n const clients = registry()\n const existing = clients.get(key)\n if (existing) {\n existing.adopt(config)\n return existing\n }\n const fresh = new Analytics(config)\n clients.set(key, fresh)\n return fresh\n}\n\n// Re-export the hydrate helpers so consumers can read persisted cohort/attribution\n// (e.g. to send refCode to the referrals API) without reaching into storage.\nexport { getCohort, getFirstTouch }\n","// The `$exception` product-event shape — pure builders, no I/O.\n//\n// An exception reaches TWO destinations, and they read different shapes:\n//\n// 1. The ERROR PLANE — a Sentry envelope to the DSN host (sentry.ts). Untouched\n// by this module.\n// 2. ERROR TRACKING in Hanzo Insights — reads the PRODUCT-EVENT plane\n// (`insights.events WHERE event = '$exception'`) and expects the PostHog\n// exception vocabulary: `$exception_list` plus the denormalized `$exception_*`\n// properties. This module builds that.\n//\n// WHY THE FULLY-DERIVED SHAPE. Upstream, a server stage (Cymbal) symbolicates\n// frames and computes `$exception_fingerprint`, `$exception_types`, `_values`,\n// `_sources`, `_functions`, then REPLACES the property bag. That stage is not in\n// Hanzo's path: the ingest endpoint writes `event.fact` and a materialized view projects it\n// into `insights.events`, so nothing between the client and the warehouse derives\n// anything. Whatever the product reads, the client has to have sent. Two\n// consequences are load-bearing rather than cosmetic:\n//\n// • The issue query drops any event whose `$exception_fingerprint` is null, so an\n// event without one is invisible no matter how well-formed the rest is.\n// • `stacktrace.type` must be the literal 'resolved'; on any other value the\n// renderer falls through both match arms and draws nothing under the header.\n//\n// If that server stage is ever put in front of this plane it replaces these\n// properties wholesale, so sending them stays correct either way.\n//\n// FRAME ORDER is bottom-up: frames[0] is the entry point and the LAST frame is the\n// throw site. framesFromStack (sentry.ts) already returns that order, which is why\n// this module reuses it rather than re-parsing.\n\nimport { framesFromStack, normalizeError } from './throwable'\nimport type {\n ExceptionEntry,\n ExceptionFrame,\n ExceptionProperties,\n SentryFrame,\n SentryLevel,\n} from './types'\n\n/** Cap on the frames carried per exception, matching the Sentry path's budget. */\nconst MAX_FRAMES = 50\n/** Cap on `value`, so one enormous message cannot dominate a batch. The product\n * truncates for display anyway; this bounds the wire. */\nconst MAX_VALUE = 4096\n\n/**\n * digest is a stable 32-hex-char (128-bit) content hash, computed synchronously.\n *\n * Grouping keys are needed on the capture path, which is synchronous and may be\n * running inside an unload handler — SubtleCrypto is async and unavailable on\n * insecure origins, so it cannot be used here. This is FNV-1a run over four seeds\n * and concatenated. It is a GROUPING key, never a security boundary: it is not\n * collision-resistant against a chosen-input adversary, and nothing authorizes or\n * authenticates on it. The product treats the value as opaque.\n */\nexport function digest(s: string): string {\n let out = ''\n for (const seed of [0x811c9dc5, 0x01000193, 0x9e3779b9, 0x85ebca6b]) {\n let h = seed >>> 0\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i)\n // FNV prime 16777619, via shifts to stay in 32-bit integer math.\n h = (h + (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24)) >>> 0\n }\n out += h.toString(16).padStart(8, '0')\n }\n return out\n}\n\n/**\n * frameOf converts one parsed stack frame into the shape the product renders.\n *\n * The product's frame vocabulary is the POST-symbolication one (`mangled_name`,\n * `source`, `line`, `column`), so that is what is emitted. `resolved` is false and\n * honest: a browser bundle is minified and no symbol set has been uploaded, so the\n * original name and line are genuinely unknown. Claiming `resolved: true` would\n * trade an accurate \"upload your symbol sets\" hint for a misleading \"source code is\n * not available\" error.\n */\nfunction frameOf(f: SentryFrame): ExceptionFrame {\n const source = f.filename ?? ''\n const name = f.function ?? '<anonymous>'\n const line = f.lineno ?? 0\n const column = f.colno ?? 0\n return {\n // Stable per code location, so the same frame groups and re-renders under one\n // key. The '/part' suffix is the product's format for one raw frame expanding\n // into several resolved ones; a browser frame is always part 0.\n raw_id: `${digest(`${source}|${name}|${line}|${column}`)}/0`,\n mangled_name: name,\n source,\n line,\n column,\n in_app: f.in_app ?? false,\n lang: 'javascript',\n resolved: false,\n resolve_failure: 'no symbol set uploaded for this release',\n resolved_name: null,\n module: null,\n }\n}\n\n/** truncate bounds a free-text field without splitting a surrogate pair. */\nfunction truncate(s: string, max: number): string {\n if (s.length <= max) return s\n let end = max\n const c = s.charCodeAt(end - 1)\n // A high surrogate at the cut point would leave a lone half.\n if (c >= 0xd800 && c <= 0xdbff) end--\n return s.slice(0, end)\n}\n\n/**\n * exceptionEntry builds the single `$exception_list` entry for a throwable.\n *\n * One entry, not a chain: `Error.cause` chaining is a distinct fact with its own\n * ordering rules, and emitting it wrongly is worse than not emitting it.\n */\nexport function exceptionEntry(\n err: unknown,\n opts: { handled: boolean; id: string },\n): ExceptionEntry {\n const n = normalizeError(err)\n const frames = framesFromStack(n.stack).slice(-MAX_FRAMES)\n const entry: ExceptionEntry = {\n id: opts.id,\n type: n.name,\n value: truncate(n.message, MAX_VALUE),\n mechanism: {\n type: 'generic',\n handled: opts.handled,\n // An exception the app reported by hand was constructed, not thrown by the\n // runtime at a real call site.\n synthetic: !(err instanceof Error),\n },\n }\n if (frames.length > 0) {\n // 'resolved' names the SHAPE of the frame list, not the symbolication state of\n // any frame — the renderer only walks frames on this exact value.\n entry.stacktrace = { type: 'resolved', frames: frames.map(frameOf) }\n }\n return entry\n}\n\n/**\n * fingerprint is the issue grouping key.\n *\n * Keyed on exception type plus each in-app frame's function and source — the same\n * pieces the server-side grouper records (\"Exception Type\", \"Resolved function\n * name\", \"Source file name\"). Deliberately NOT the message: `Loading chunk 3324\n * failed` and `Loading chunk 998 failed` are one bug, and grouping on message is\n * precisely the mistake that made every distinct error string its own event name.\n *\n * Falls back to the type alone when no in-app frame survived, which keeps\n * stackless errors (`Script error.`, cross-origin) in one issue instead of\n * scattering them.\n */\nexport function fingerprint(entry: ExceptionEntry): string {\n const frames = entry.stacktrace?.frames ?? []\n const pieces = frames\n .filter((f) => f.in_app)\n .map((f) => `${f.mangled_name}@${f.source}`)\n return digest([entry.type, ...pieces].join('\\n'))\n}\n\n/**\n * exceptionProperties builds the full `$exception_*` property bag for one captured\n * throwable — everything Error Tracking reads off the event.\n *\n * The denormalized arrays are ordered like `frames`: last element is the throw\n * site, which is the element the issue list indexes at -1 for its source/function\n * columns.\n */\nexport function exceptionProperties(\n err: unknown,\n opts: { handled: boolean; id: string; level?: SentryLevel },\n): ExceptionProperties {\n const entry = exceptionEntry(err, opts)\n const frames = entry.stacktrace?.frames ?? []\n const fp = fingerprint(entry)\n return {\n $exception_list: [entry],\n $exception_fingerprint: fp,\n // Records WHY this fingerprint holds. 'manual' is the honest value: the client\n // supplied the key rather than a server grouper deriving one.\n $exception_fingerprint_record: [{ type: 'manual' }],\n $exception_type: entry.type,\n $exception_message: entry.value,\n $exception_level: opts.level ?? 'error',\n $exception_handled: opts.handled,\n $exception_synthetic: entry.mechanism?.synthetic ?? false,\n $exception_types: [entry.type],\n $exception_values: [entry.value],\n $exception_sources: frames.map((f) => f.source).filter((s): s is string => !!s),\n $exception_functions: frames\n .map((f) => f.resolved_name ?? f.mangled_name)\n .filter((s): s is string => !!s),\n }\n}\n","// First-party cookies for consent, the ad click and the browser ids the ad\n// platforms match on. Set on the registrable domain so every subdomain of a site\n// reads the same choice and the same click; on localhost or an address it stays\n// on the host.\n\nconst DAY = 86_400\n\n/** The domain attribute for this host, or '' to keep the cookie on the host. */\nfunction domain(): string {\n const h = window.location.hostname\n if (h === 'localhost' || /^[\\d.]+$/.test(h) || h.includes(':')) return ''\n const parts = h.split('.')\n return parts.length > 2 ? `; Domain=.${parts.slice(-2).join('.')}` : `; Domain=.${h}`\n}\n\n/** Reads one cookie, or undefined. */\nexport function get(name: string): string | undefined {\n if (typeof document === 'undefined') return undefined\n const hit = document.cookie.split('; ').find((c) => c.startsWith(`${name}=`))\n return hit ? decodeURIComponent(hit.slice(name.length + 1)) : undefined\n}\n\n/** Writes one cookie for `days`. */\nexport function set(name: string, value: string, days: number): void {\n if (typeof document === 'undefined') return\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${name}=${encodeURIComponent(value)}; Max-Age=${days * DAY}; Path=/; SameSite=Lax${domain()}${secure}`\n}\n","// Cookie consent: what a visitor lets a site measure and share, and the rule for\n// what a visitor who has not chosen is presumed to allow.\n//\n// Three categories. Analytics is our own stream and GA4. Marketing is the ad\n// platforms measuring the conversions they bought (Google Ads, Meta, LinkedIn,\n// X, TikTok) and every server-side send. Ads is those platforms using the visit\n// for audiences; off, Google's ad_personalization is denied and Meta runs under\n// Limited Data Use.\n//\n// THE DEFAULT depends on where the visitor is. In the EU, UK and Switzerland,\n// and anywhere else that is not a US state, nothing is allowed until they say\n// so: a visitor with no stored choice has allowed nothing. In the US the default\n// is on and the choice is an opt-out (\"Do not sell or share my personal\n// information\"). Global Privacy Control, and Do Not Track, turn marketing and\n// ads off in every region whatever is stored: California reads GPC as the opt-out\n// of sale and sharing.\n//\n// There is no geo lookup. The page cannot ask a server where the visitor is, so\n// the zone is the browser's own time zone, and a zone that is not a US zone is\n// treated as opt-in. Wrong in the safe direction: a US visitor on a foreign\n// clock is asked, and a European is never presumed to have agreed.\n//\n// The choice is a first-party cookie, `hz_consent`, on the registrable domain\n// for 13 months: the granted categories, comma separated. cloud reads the same\n// string off each event's `consent` property.\n\nimport { get, set } from './cookie'\n\nexport const CONSENT_COOKIE = 'hz_consent'\n\n/** Fired on `window` whenever a choice is stored. */\nexport const CONSENT_EVENT = 'hzconsent'\n\nexport interface Choice {\n analytics: boolean\n marketing: boolean\n ads: boolean\n}\n\nexport type Region = 'opt-in' | 'opt-out'\n\ntype Nav = { doNotTrack?: string; msDoNotTrack?: string; globalPrivacyControl?: boolean }\n\nconst US =\n /^(America\\/(New_York|Chicago|Denver|Los_Angeles|Phoenix|Anchorage|Adak|Boise|Detroit|Juneau|Sitka|Nome|Yakutat|Menominee|Metlakatla|Indiana\\/.*|Kentucky\\/.*|North_Dakota\\/.*)|Pacific\\/Honolulu|US\\/.*)$/\n\n/** Whether the browser sends Global Privacy Control. */\nexport function gpc(): boolean {\n if (typeof navigator === 'undefined') return false\n return (navigator as unknown as Nav).globalPrivacyControl === true\n}\n\n/** Whether the browser sends Global Privacy Control or Do Not Track. */\nexport function refused(): boolean {\n if (typeof window === 'undefined') return false\n const n = navigator as unknown as Nav\n const dnt = n.doNotTrack ?? (window as unknown as Nav).doNotTrack ?? n.msDoNotTrack\n return gpc() || dnt === '1' || dnt === 'yes'\n}\n\n/** Which rule applies to this visitor. */\nexport function region(): Region {\n try {\n const zone = Intl.DateTimeFormat().resolvedOptions().timeZone ?? ''\n return US.test(zone) ? 'opt-out' : 'opt-in'\n } catch {\n return 'opt-in'\n }\n}\n\n/** Whether the visitor has stored a choice. */\nexport function stored(): boolean {\n return get(CONSENT_COOKIE) !== undefined\n}\n\n/** The visitor's choice: the stored one, else the regional default, with GPC applied. */\nexport function read(): Choice {\n const kept = get(CONSENT_COOKIE)\n const on =\n kept !== undefined\n ? kept.split(',')\n : region() === 'opt-in' || refused()\n ? []\n : ['analytics', 'marketing', 'ads']\n const has = (k: string) => on.includes(k)\n return { analytics: has('analytics'), marketing: has('marketing') && !gpc(), ads: has('ads') && !gpc() }\n}\n\n/** Whether the consent banner must be shown: an opt-in visitor who has not chosen. */\nexport function asks(): boolean {\n return typeof document !== 'undefined' && region() === 'opt-in' && !stored()\n}\n\n/** The choice as the `consent` property and the cookie spell it. */\nexport function render(c: Choice): string {\n return (['analytics', 'marketing', 'ads'] as const).filter((k) => c[k]).join(',')\n}\n\n/**\n * Stores a choice and tells the page. The tags react without a reload: a\n * category just allowed loads its libraries, and Google's consent state is\n * updated. An ad library already running cannot be unloaded, so a choice that\n * withdraws marketing takes effect for what has not loaded yet and for every\n * later page.\n */\nexport function save(c: Choice): void {\n const out: Choice = { analytics: c.analytics, marketing: c.marketing && !gpc(), ads: c.ads && !gpc() }\n set(CONSENT_COOKIE, render(out), 395)\n if (typeof window !== 'undefined') window.dispatchEvent(new Event(CONSENT_EVENT))\n}\n\n/** Accept every category. */\nexport const acceptAll = (): void => save({ analytics: true, marketing: true, ads: true })\n\n/** Refuse every optional category. */\nexport const rejectAll = (): void => save({ analytics: false, marketing: false, ads: false })\n","// The ad click a visitor arrived on, kept first-party so a conversion days later\n// is credited to it even when the ad tags never loaded.\n//\n// On every page load the click ids in the address are read: gclid, gbraid and\n// wbraid (Google), fbclid (Meta), li_fat_id (LinkedIn), twclid (X), ttclid\n// (TikTok). When any is there the whole set replaces the last one in `hz_touch`\n// with the time it was captured: the last click is the one credited. It is kept\n// 90 days, the lookback cloud applies before it offers a click to a platform\n// (apps/destination/touch.go).\n//\n// Beside it are the browser ids the platforms match on. `_fbc` is Meta's click\n// cookie, built from fbclid in the shape the Pixel would write it; `_fbp` is its\n// browser id. `cid` is GA4's client id: the last two fields of `_ga`, or a\n// first-party `hz_cid` of the same shape when gtag.js never ran.\n//\n// Nothing here runs without consent: the click and the Meta ids need Marketing,\n// the client id needs Analytics.\n\nimport type { Choice } from './consent'\nimport { get, set } from './cookie'\n\nexport const CLICK_IDS = ['gclid', 'gbraid', 'wbraid', 'fbclid', 'li_fat_id', 'twclid', 'ttclid'] as const\n\nconst DAYS = 90\nconst now = () => Math.floor(Date.now() / 1000)\nconst rand = () => Math.floor(Math.random() * 2 ** 31)\n\n/** Records this page's click and the browser ids. Call once per page load. */\nexport function capture(c: Choice): void {\n if (typeof window === 'undefined') return\n if (c.marketing) {\n const q = new URLSearchParams(window.location.search)\n const click: Record<string, string | number> = {}\n for (const k of CLICK_IDS) {\n const v = q.get(k)?.trim()\n if (v) click[k] = v\n }\n if (Object.keys(click).length) {\n click.clicked = now()\n set('hz_touch', JSON.stringify(click), DAYS)\n if (click.fbclid) set('_fbc', `fb.1.${Date.now()}.${click.fbclid}`, DAYS)\n }\n if (!get('_fbp')) set('_fbp', `fb.1.${Date.now()}.${rand()}`, DAYS)\n }\n if (c.analytics && !get('_ga') && !get('hz_cid')) set('hz_cid', `${rand()}.${now()}`, 730)\n}\n\n/** The properties an event carries for cloud to match it on. */\nexport function touch(c: Choice): Record<string, string | number> {\n const out: Record<string, string | number> = {}\n if (c.marketing) {\n try {\n Object.assign(out, JSON.parse(get('hz_touch') ?? '{}'))\n } catch {\n /* a cookie that does not parse names no click */\n }\n const fbc = get('_fbc')\n const fbp = get('_fbp')\n if (fbc) out.fbc = fbc\n if (fbp) out.fbp = fbp\n }\n if (c.analytics) {\n const ga = get('_ga')?.split('.')\n const cid = ga && ga.length >= 4 ? ga.slice(-2).join('.') : get('hz_cid')\n if (cid) out.cid = cid\n }\n return out\n}\n","// The tag manager: loads each ad and analytics platform's browser pixel, after\n// consent, from the site's tag configuration, and fires every event to each one\n// under one event_id.\n//\n// WHERE THE IDS COME FROM. Never from a site's code. The site's tag set is\n// cloud's `GET /v1/project/tags` (non-secret ids only), so connecting a\n// platform to a site is a configuration change and every surface gets it:\n//\n// { tags: [{ platform: 'ga4', type: 'ga', id: 'G-…' },\n// { platform: 'linkedin', type: 'linkedin', id: '1234',\n// events: { order_completed: '9876' } }, …] }\n//\n// `events` maps one of OUR event names to the platform's own conversion id for\n// it: a Google Ads `AW-…/label`, a LinkedIn conversion rule, an X event id.\n// Google Ads, LinkedIn and X name conversions by rule, not by event, and an\n// event with no rule there is not sent to that platform.\n//\n// WHAT LOADS WHEN. Nothing loads before consent. Analytics allows GA4;\n// Marketing allows Google Ads, Meta, LinkedIn, X and TikTok. A visitor who has\n// not chosen has allowed what their region presumes (consent.ts), so an EU\n// visitor's page makes no request to any platform until they accept. Google's\n// Consent Mode v2 is set denied before gtag.js is fetched and updated on every\n// choice. A choice that allows more loads the rest with no reload.\n//\n// ONE EVENT ID. `track` mints it, fires the browser pixels with it, and records\n// it on our stream with the list of pixels that fired (`tags`). Cloud forwards\n// the same moment server-side under the same id, and each platform keeps one\n// (Meta and TikTok by event_id, GA4 by transaction_id on a purchase); it sends\n// GA4 only what the page's own gtag did not, which is what `tags` says.\n//\n// WHAT EACH PLATFORM CALLS AN EVENT is the one table in @hanzo/events; cloud\n// reads the same table.\n\nimport { namesOn } from '@hanzo/events'\nimport { CONSENT_EVENT, read, render, type Choice } from './consent'\nimport { capture, touch } from './touch'\nimport type { Analytics } from './core'\n\nexport interface BrowserTag {\n platform: string\n type: string\n id: string\n events?: Record<string, string>\n}\n\nexport interface TagOptions {\n /** The site's publishable key; resolves its tag set. */\n key?: string\n /** The site's host, for a site whose key is the org's. */\n host?: string\n /** cloud's origin; defaults to https://api.hanzo.ai. */\n base?: string\n /** Domains one visit crosses, so GA4 keeps it one session. */\n domains?: string[]\n}\n\n/**\n * The publishable key of each site's project, which is how cloud finds the site's\n * tag set. A `pk-` is public by design (it ships in every page); it names a site,\n * never a platform id. A host absent here has no tag config unless `start` is\n * given a key.\n */\nexport const SITE_KEY: Readonly<Record<string, string>> = Object.freeze({\n 'hanzo.ai': 'pk-CmfLA2K6kvsPflrS9DSkt06H_kSoQB_21sjedt6VJdc',\n 'www.hanzo.ai': 'pk-CmfLA2K6kvsPflrS9DSkt06H_kSoQB_21sjedt6VJdc',\n 'hanzo.app': 'pk-wlnXN2a9_vmCm60yTFtQ629Q8TyuaxBNZbY1RWT72gQ',\n 'hanzo.team': 'pk-NCzD2FiHpZv8KUpkCX4olT1LJOJsMxBC_Z8NkiQsOFQ',\n 'pay.hanzo.ai': 'pk-eX6kv7JZNoiYn1WkeJH3tT_8OvkVYScmCXnLMwxTKf8',\n 'platform.hanzo.ai': 'pk-My1RpZLEUnTj8vAdPbWKYdDUuhxZJ4dVjHcwjZN4rZ8',\n 'docs.hanzo.ai': 'pk-jukhtjMT2ymoeBDAeFjINQWlBv-v9sNn1TPztiCrrwk',\n 'hanzo.bot': 'pk-W5d7Mn7ZukT7igyscIy6Pqe8JpA0Ge604Yn4xNR4JCU',\n 'cloud.hanzo.ai': 'pk-RAfEGHPoNdCEU9fnA_cPd_Xo9Tci44rlYQV9xuJ1Ob0',\n})\n\ntype Call = (...args: unknown[]) => void\ntype Page = {\n dataLayer?: unknown[]\n gtag?: Call\n fbq?: Call & { queue?: unknown[]; callMethod?: Call; push?: unknown; loaded?: boolean; version?: string }\n _fbq?: unknown\n lintrk?: Call & { q?: unknown[] }\n _linkedin_data_partner_ids?: string[]\n twq?: Call & { queue?: unknown[]; exe?: Call; version?: string }\n ttq?: Record<string, Call> & { _i?: Record<string, unknown>; _t?: Record<string, number>; _o?: Record<string, unknown>; methods?: string[]; load?: Call; page?: Call; track?: Call }\n TiktokAnalyticsObject?: string\n}\n\nconst page = (): Page => window as unknown as Page\n\nlet tags: BrowserTag[] = []\nlet configured = false\nlet options: TagOptions = {}\nconst loaded = new Set<string>()\n\n/** gtag.js: 'idle' until fetched, 'wait' while on its way, then how it answered. */\nlet google: 'idle' | 'wait' | 'loaded' | 'failed' = 'idle'\nlet configAnswered = false\n\nconst held: Array<() => void> = []\nlet leaving = false\n\nfunction settled(): boolean {\n return configAnswered && google !== 'wait'\n}\n\nfunction flush(): void {\n if (settled() || leaving) held.splice(0).forEach((send) => send())\n}\n\nfunction script(src: string, onload?: () => void, onerror?: () => void): void {\n const s = document.createElement('script')\n s.async = true\n s.src = src\n if (onload) s.onload = onload\n if (onerror) s.onerror = onerror\n document.head.appendChild(s)\n}\n\n// ── Google ──────────────────────────────────────────────────────────────\n\nfunction gtagStub(): Call {\n const p = page()\n p.dataLayer = p.dataLayer || []\n if (!p.gtag) {\n // gtag.js reads the `arguments` object itself, so this is a function and not an arrow.\n p.gtag = function () {\n // eslint-disable-next-line prefer-rest-params\n p.dataLayer!.push(arguments)\n }\n }\n return p.gtag\n}\n\nconst g = (on: boolean) => (on ? 'granted' : 'denied')\n\n/** Google Consent Mode v2: denied until said otherwise, then the visitor's choice. */\nfunction consentMode(c: Choice, first: boolean): void {\n const gtag = gtagStub()\n const state = {\n analytics_storage: g(c.analytics),\n ad_storage: g(c.marketing),\n ad_user_data: g(c.marketing),\n ad_personalization: g(c.marketing && c.ads),\n }\n if (first) {\n gtag('consent', 'default', {\n analytics_storage: 'denied',\n ad_storage: 'denied',\n ad_user_data: 'denied',\n ad_personalization: 'denied',\n wait_for_update: 500,\n })\n }\n gtag('consent', 'update', state)\n}\n\nfunction loadGoogle(ids: string[]): void {\n const gtag = gtagStub()\n const fresh = ids.filter((id) => !loaded.has(id))\n if (!fresh.length) return\n if (google === 'idle') {\n google = 'wait'\n gtag('js', new Date())\n const done = (to: 'loaded' | 'failed') => () => {\n if (google !== 'wait') return\n google = to\n flush()\n }\n script(`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(fresh[0])}`, done('loaded'), done('failed'))\n // gtag.js answers once: loaded, failed (a blocker), or silent past 8 s.\n setTimeout(done('failed'), 8000)\n }\n for (const id of fresh) {\n loaded.add(id)\n gtag('config', id, options.domains ? { linker: { domains: options.domains } } : {})\n }\n}\n\n// ── The other pixels ────────────────────────────────────────────────────\n\nfunction loadMeta(id: string, c: Choice): void {\n const p = page()\n if (!p.fbq) {\n const n = (p.fbq = function (...a: unknown[]) {\n if (n.callMethod) n.callMethod(...a)\n else n.queue!.push(a)\n } as NonNullable<Page['fbq']>)\n if (!p._fbq) p._fbq = n\n n.push = n\n n.loaded = true\n n.version = '2.0'\n n.queue = []\n script('https://connect.facebook.net/en_US/fbevents.js')\n }\n if (!c.ads) p.fbq('dataProcessingOptions', ['LDU'], 0, 0)\n p.fbq('init', id)\n p.fbq('track', 'PageView')\n}\n\nfunction loadLinkedIn(id: string): void {\n const p = page()\n p._linkedin_data_partner_ids = p._linkedin_data_partner_ids || []\n p._linkedin_data_partner_ids.push(id)\n if (!p.lintrk) {\n const l = (p.lintrk = function (...a: unknown[]) {\n l.q!.push(a)\n } as NonNullable<Page['lintrk']>)\n l.q = []\n }\n script('https://snap.licdn.com/li.lms-analytics/insight.min.js')\n}\n\nfunction loadX(id: string): void {\n const p = page()\n if (!p.twq) {\n const s = (p.twq = function (...a: unknown[]) {\n if (s.exe) s.exe(...a)\n else s.queue!.push(a)\n } as NonNullable<Page['twq']>)\n s.version = '1.1'\n s.queue = []\n script('https://static.ads-twitter.com/uwt.js')\n }\n p.twq('config', id)\n}\n\nconst TIKTOK_METHODS = ['page', 'track', 'identify', 'instances', 'debug', 'on', 'off', 'once', 'ready', 'alias', 'group', 'enableCookie', 'disableCookie']\n\nfunction loadTikTok(id: string): void {\n const p = page()\n p.TiktokAnalyticsObject = 'ttq'\n const q = (p.ttq = p.ttq || ([] as unknown as NonNullable<Page['ttq']>)) as unknown as Record<string, unknown> & unknown[]\n if (!q._i) {\n q.methods = TIKTOK_METHODS\n for (const m of TIKTOK_METHODS) q[m] = (...a: unknown[]) => q.push([m, ...a])\n q._i = {}\n q._t = {}\n q._o = {}\n q.load = (sdk: string) => {\n ;(q._i as Record<string, unknown>)[sdk] = []\n ;(q._t as Record<string, number>)[sdk] = Date.now()\n script(`https://analytics.tiktok.com/i18n/pixel/events.js?sdkid=${encodeURIComponent(sdk)}&lib=ttq`)\n }\n }\n ;(q.load as Call)(id)\n ;(q.page as Call)()\n}\n\n// ── Which tag is allowed and running ────────────────────────────────────\n\nconst NEEDS: Record<string, keyof Choice> = {\n ga: 'analytics',\n gads: 'marketing',\n meta: 'marketing',\n linkedin: 'marketing',\n x: 'marketing',\n tiktok: 'marketing',\n}\n\n/** GA4 also counts a visit when only Marketing is allowed (Consent Mode keeps it cookieless). */\nconst allowed = (t: BrowserTag, c: Choice): boolean =>\n t.type === 'ga' ? c.analytics || c.marketing : Boolean(NEEDS[t.type] && c[NEEDS[t.type]])\n\nfunction apply(): void {\n if (typeof window === 'undefined' || !configured) return\n const c = read()\n capture(c)\n const on = tags.filter((t) => allowed(t, c))\n const ids = on.filter((t) => t.type === 'ga' || t.type === 'gads').map((t) => t.id)\n if (ids.length) {\n consentMode(c, !loaded.has('consent'))\n loaded.add('consent')\n loadGoogle(ids)\n }\n for (const t of on) {\n const k = `${t.type}:${t.id}`\n if (loaded.has(k)) continue\n if (t.type === 'meta') loadMeta(t.id, c)\n else if (t.type === 'linkedin') loadLinkedIn(t.id)\n else if (t.type === 'x') loadX(t.id)\n else if (t.type === 'tiktok') loadTikTok(t.id)\n else continue\n loaded.add(k)\n }\n flush()\n}\n\n/**\n * Starts the tag manager: fetches the site's tag set and loads what consent\n * allows, again on every consent change. Safe to call on every page load, and\n * a no-op on the server. Returns a function that stops listening.\n */\nexport function start(o: TagOptions = {}): () => void {\n if (typeof window === 'undefined') return () => undefined\n options = o\n addEventListener(CONSENT_EVENT, apply)\n addEventListener('pagehide', pagehide)\n if (!configured) {\n configured = true\n const base = (o.base ?? 'https://api.hanzo.ai').replace(/\\/$/, '')\n const q = new URLSearchParams()\n const host = o.host ?? window.location.hostname\n const key = o.key ?? SITE_KEY[host]\n if (key) q.set('key', key)\n q.set('host', host)\n const answer = (list: BrowserTag[]) => {\n tags = list\n configAnswered = true\n apply()\n }\n // A page never waits on its tag config: an unreachable cloud is an empty set.\n const cap = setTimeout(() => answer([]), 3000)\n fetch(`${base}/v1/project/tags?${q}`)\n .then((r) => (r.ok ? r.json() : { tags: [] }))\n .then((j: { tags?: BrowserTag[] }) => {\n clearTimeout(cap)\n answer(Array.isArray(j.tags) ? j.tags : [])\n })\n .catch(() => {\n clearTimeout(cap)\n answer([])\n })\n }\n return () => {\n removeEventListener(CONSENT_EVENT, apply)\n removeEventListener('pagehide', pagehide)\n }\n}\n\nfunction pagehide(): void {\n leaving = true\n flush()\n}\n\n/** The browser tags a moment can reach right now, as the `tags` property spells it. */\nexport function reach(): string {\n const c = read()\n const to: string[] = []\n for (const t of tags) {\n if (!allowed(t, c)) continue\n const running =\n t.type === 'ga'\n ? google === 'loaded' && c.analytics\n : t.type === 'gads'\n ? google === 'loaded' && c.marketing\n : loaded.has(`${t.type}:${t.id}`)\n if (running && !to.includes(t.type)) to.push(t.type)\n }\n return to.join(',')\n}\n\n// ── Firing an event ─────────────────────────────────────────────────────\n\ninterface Item {\n item_id: string\n item_name?: string\n item_category?: string\n item_variant?: string\n price?: number\n quantity?: number\n}\n\nconst META_STANDARD = new Set([\n 'AddPaymentInfo', 'AddToCart', 'AddToWishlist', 'CompleteRegistration', 'Contact', 'CustomizeProduct',\n 'Donate', 'FindLocation', 'InitiateCheckout', 'Lead', 'Purchase', 'Schedule', 'Search', 'StartTrial',\n 'SubmitApplication', 'Subscribe', 'ViewContent',\n])\n\nfunction shape(platform: 'meta' | 'tiktok' | 'x', p: Record<string, unknown>): Record<string, unknown> {\n const items = Array.isArray(p.items) ? (p.items as Item[]) : []\n const out: Record<string, unknown> = {}\n if (typeof p.value === 'number') out.value = p.value\n out.currency = typeof p.currency === 'string' ? p.currency : 'USD'\n if (!items.length) return out\n if (platform === 'meta') {\n out.content_type = 'product'\n out.content_ids = items.map((i) => i.item_id)\n out.contents = items.map((i) => ({ id: i.item_id, quantity: i.quantity ?? 1, item_price: i.price }))\n out.content_name = items[0].item_name\n out.num_items = items.reduce((n, i) => n + (i.quantity ?? 1), 0)\n } else if (platform === 'tiktok') {\n out.content_type = 'product'\n out.contents = items.map((i) => ({ content_id: i.item_id, content_name: i.item_name, quantity: i.quantity ?? 1, price: i.price }))\n } else {\n out.contents = items.map((i) => ({ content_id: i.item_id, content_name: i.item_name, content_price: i.price, num_items: i.quantity ?? 1 }))\n }\n return out\n}\n\n/** A test order states no amount: nothing sent for it can be summed into revenue. */\nfunction unpriced(p: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = { ...p, value: 0 }\n if (Array.isArray(p.items)) out.items = (p.items as Item[]).map((i) => ({ ...i, price: 0 }))\n return out\n}\n\n/**\n * Sends one moment to the browser tags named in `to`, under `id`. The names each\n * platform knows it by are the table in @hanzo/events; a platform the table\n * gives no name, or a rule-named platform with no rule for it, is not sent it.\n */\nexport function mirror(name: string, params: Record<string, unknown>, id: string, to = reach()): void {\n const p = page()\n const on = new Set(to.split(',').filter(Boolean))\n const ga4 = namesOn(name, 'ga4')\n const test = params.test === true\n if (test) params = unpriced(params)\n const transaction = typeof params.order_id === 'string' ? { transaction_id: params.order_id } : {}\n for (const t of tags) {\n if (!on.has(t.type)) continue\n const rule = t.events?.[name]\n if (t.type === 'ga') {\n for (const n of ga4) {\n p.gtag?.('event', n, { ...params, ...transaction, event_id: id, transport_type: 'beacon', ...(test ? { debug_mode: true } : {}) })\n }\n } else if (t.type === 'gads' && rule) {\n p.gtag?.('event', 'conversion', {\n send_to: rule,\n value: typeof params.value === 'number' ? params.value : undefined,\n currency: typeof params.currency === 'string' ? params.currency : 'USD',\n ...transaction,\n })\n } else if (t.type === 'meta') {\n for (const n of namesOn(name, 'meta')) {\n p.fbq?.(META_STANDARD.has(n) ? 'track' : 'trackCustom', n, shape('meta', params), { eventID: id })\n }\n } else if (t.type === 'tiktok') {\n for (const n of namesOn(name, 'tiktok')) p.ttq?.track?.(n, shape('tiktok', params), { event_id: id })\n } else if (t.type === 'linkedin' && rule && namesOn(name, 'linkedin').length) {\n p.lintrk?.('track', { conversion_id: Number(rule) })\n } else if (t.type === 'x' && rule && namesOn(name, 'x').length) {\n p.twq?.('event', rule, { ...shape('x', params), conversion_id: id })\n }\n }\n}\n\n/**\n * One moment, to every place it is counted, under one event_id: our stream\n * always hears it (with the consent, the click and the browser ids cloud\n * forwards on), and each browser tag that is running hears it too. A moment\n * that arrives while gtag.js is still on its way waits for it, so GA4 sees it\n * with a session; a page that is leaving sends what it holds as things stand.\n *\n * A paid order is stated by the SERVER on our stream (and forwarded server-side);\n * its browser copy is `track(stream, 'order_completed', {event_id: order, order_id:\n * order, …}, 'tags')`: the same id, the pixels only, so nothing counts twice.\n */\nexport function track(\n stream: Analytics | undefined,\n name: string,\n params: Record<string, unknown> = {},\n /** `'tags'` fires the browser pixels only: the server states this moment on our stream itself. */\n only?: 'tags',\n): void {\n if (typeof window === 'undefined') return\n if (!leaving && !settled()) {\n held.push(() => track(stream, name, params, only))\n return\n }\n const c = read()\n // A moment the server also states (a paid order) brings its own id, the order's,\n // so each platform sees the browser's copy and the server's as one.\n const event_id = typeof params.event_id === 'string' && params.event_id ? params.event_id : crypto.randomUUID()\n const to = reach()\n mirror(name, params, event_id, to)\n if (only === 'tags') return\n stream?.capture(name, {\n ...params,\n ...touch(c),\n event_id,\n consent: render(c),\n tags: to,\n userAgent: navigator.userAgent,\n url: window.location.href,\n })\n}\n\n/** What cloud needs to forward a moment a page states itself, as if the browser had sent it. */\nexport function visit(): Record<string, unknown> {\n const c = read()\n return { ...touch(c), consent: render(c), tags: reach(), userAgent: navigator.userAgent, url: window.location.href }\n}\n","// A plan as every ecommerce event names it: GA4's item shape, which the tag\n// manager hands Meta, TikTok and X, and which cloud's forwarder lifts from the\n// events the server states. One function, so a plan carries the same line from\n// the pricing page to the checkout to the order.\n//\n// `item_id` is the plan's id as the catalog spells it (free, dev, max, and the\n// team plans), `item_category` says who it is for, `item_variant` the term,\n// `price` the unit price for that term in US dollars and `quantity` the seats\n// (1 for an individual plan).\n\nexport interface CommerceItem {\n item_id: string\n item_name?: string\n item_category: 'individual' | 'team'\n item_variant: 'monthly' | 'annual'\n price: number\n quantity: number\n}\n\nexport interface PlanLine {\n id: string\n name?: string\n /** A team plan is sold per seat. */\n team?: boolean\n /** The term, as commerce (`month`, `year`) or the funnel (`monthly`, `annual`) says it. */\n interval: string\n price: number | null\n quantity?: number\n}\n\nexport function commerceItem(p: PlanLine): CommerceItem {\n const annual = /^(year|yearly|annual)$/i.test(p.interval)\n return {\n item_id: p.id,\n ...(p.name ? { item_name: p.name } : {}),\n item_category: p.team ? 'team' : 'individual',\n item_variant: annual ? 'annual' : 'monthly',\n price: p.price ?? 0,\n quantity: p.quantity ?? 1,\n }\n}\n\n/** What the whole order is worth: the unit price times the seats. */\nexport const worth = (i: CommerceItem): number => i.price * i.quantity\n","// Insights goals + cohorts, defined once as data so the console/insights UI and\n// every product agree on what \"a Signup\", \"a Sale\", and \"upgrade intent\" mean.\n// This is the machine-readable spec — the shared source of truth a sync step can\n// push into Insights, and what TAXONOMY.md documents.\n//\n// A goal answers \"what counts as a conversion\". A funnel answers \"by what path\".\n// The paths live in funnels.ts and a goal REFERENCES one by id: the steps are\n// written down exactly once.\n\nimport { EVENTS } from './events'\nimport { eventsOf, type FunnelId } from './funnels'\n\nexport interface GoalDef {\n /** Human label shown in Insights. */\n label: string\n /** The event whose occurrence counts as the goal conversion. */\n event: string\n /** The funnel leading to the goal — an id into FUNNELS (see funnels.ts). */\n funnelId?: FunnelId\n /** The ordered event names of `funnelId`, derived — never hand-written. */\n funnel?: string[]\n /** Optional property equality filter that qualifies the conversion. */\n filter?: { property: string; equals: string }\n}\n\nexport const GOALS: Record<'signup' | 'sale' | 'upgradeIntent' | 'activation', GoalDef> = {\n // Signup: the conversion is signup_completed, along the site signup funnel.\n signup: {\n label: 'Signup',\n event: EVENTS.SIGNUP_COMPLETED,\n funnelId: 'signup',\n funnel: eventsOf('signup'),\n },\n // Sale: a completed order qualified as a plan purchase (kind=plan).\n sale: {\n label: 'Sale',\n event: EVENTS.ORDER_COMPLETED,\n funnelId: 'upgrade',\n funnel: eventsOf('upgrade'),\n filter: { property: 'kind', equals: 'plan' },\n },\n // Upgrade intent: a plan click; pricing_viewed is the top of its funnel.\n upgradeIntent: {\n label: 'Upgrade Intent',\n event: EVENTS.PLAN_CLICKED,\n funnelId: 'upgrade',\n funnel: eventsOf('upgrade'),\n },\n // Activation: the ONE north-star conversion — an account that did the first\n // valuable thing (a successful API call, a live app, a chat answer).\n activation: {\n label: 'Activation',\n event: EVENTS.FIRST_ACTION,\n funnelId: 'apiActivation',\n funnel: eventsOf('apiActivation'),\n },\n}\n\nexport interface CohortDef {\n /** The hanzo.events column the cohort dimension maps to. */\n field: string\n label: string\n}\n\nexport const COHORTS: Record<'signupWeek' | 'channel' | 'refCode', CohortDef> = {\n signupWeek: { field: 'signup_week', label: 'Signup week' },\n channel: { field: 'channel', label: 'Acquisition channel' },\n refCode: { field: 'ref_code', label: 'Referral code' },\n}\n"]}
1
+ {"version":3,"sources":["../src/attribution.ts","../src/org.ts","../src/scrub.ts","../src/throwable.ts","../src/anon.js","../src/uid.ts","../src/storage.ts","../src/link.ts","../package.json","../src/version.ts","../src/core.ts","../src/exception.ts","../src/cookie.ts","../src/consent.ts","../src/touch.ts","../src/tags.ts","../src/items.ts","../src/goals.ts"],"names":["get","now","set","normalizeError","g","truncate","read","start","namesOn"],"mappings":"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","file":"index.mjs","sourcesContent":["// Pure attribution helpers: parse first-touch UTM/referrer/refCode from a URL,\n// derive the acquisition channel, and compute the ISO week for the signup cohort.\n// No I/O, no globals — trivially testable.\n\nimport type { Attribution } from './types'\n\nconst SOCIAL_HOSTS = [\n 'facebook.', 'instagram.', 'twitter.', 'x.com', 't.co', 'linkedin.',\n 'reddit.', 'youtube.', 'tiktok.', 'pinterest.', 'news.ycombinator.com',\n]\nconst SEARCH_HOSTS = ['google.', 'bing.', 'duckduckgo.', 'yahoo.', 'baidu.', 'ecosia.']\n\n/** parseAttribution reads UTM params + ref/refCode from a query string and pairs\n * them with the referrer. `search` is a location.search value (\"?utm_source=…\"). */\nexport function parseAttribution(search: string, referrer: string): Attribution {\n const q = new URLSearchParams(search || '')\n const get = (k: string) => {\n const v = q.get(k)\n return v ? v.trim() : undefined\n }\n const a: Attribution = {\n utm: {\n source: get('utm_source'),\n medium: get('utm_medium'),\n campaign: get('utm_campaign'),\n term: get('utm_term'),\n content: get('utm_content'),\n },\n referrer: referrer ? referrer.trim() : undefined,\n refCode: get('ref') || get('refCode') || get('ref_code') || undefined,\n }\n a.channel = deriveChannel(a)\n return a\n}\n\n/** deriveChannel classifies the visit: paid | referral | social | organic | direct. */\nexport function deriveChannel(a: Attribution): string {\n const medium = (a.utm.medium || '').toLowerCase()\n if (/(cpc|ppc|paid|paidsearch|display|cpm)/.test(medium)) return 'paid'\n if (a.utm.source || a.utm.campaign) return 'campaign'\n if (a.refCode) return 'referral'\n const host = hostOf(a.referrer)\n if (!host) return 'direct'\n if (SOCIAL_HOSTS.some((h) => host.includes(h))) return 'social'\n if (SEARCH_HOSTS.some((h) => host.includes(h))) return 'organic'\n return 'referral'\n}\n\n/** hostOf extracts a bare lowercase host from a URL; \"\" when unparseable. */\nexport function hostOf(raw?: string): string {\n if (!raw) return ''\n let s = raw.trim()\n const scheme = s.indexOf('://')\n if (scheme >= 0) s = s.slice(scheme + 3)\n const cut = s.search(/[/?#]/)\n if (cut >= 0) s = s.slice(0, cut)\n const at = s.indexOf('@')\n if (at >= 0) s = s.slice(at + 1)\n const colon = s.indexOf(':')\n if (colon >= 0) s = s.slice(0, colon)\n return s.toLowerCase().trim()\n}\n\n/** hasAttribution reports whether anything was captured (so we don't persist an\n * empty first-touch that would shadow a later real one). */\nexport function hasAttribution(a: Attribution): boolean {\n return Boolean(\n a.utm.source || a.utm.medium || a.utm.campaign || a.utm.term ||\n a.utm.content || a.refCode || (a.referrer && hostOf(a.referrer)),\n )\n}\n\n/** isoWeek returns the ISO-8601 week label, e.g. \"2026-W28\". */\nexport function isoWeek(d: Date): string {\n // Copy to UTC midnight; ISO week: Thursday-anchored.\n const date = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()))\n const day = date.getUTCDay() || 7\n date.setUTCDate(date.getUTCDate() + 4 - day)\n const yearStart = new Date(Date.UTC(date.getUTCFullYear(), 0, 1))\n const week = Math.ceil(((date.getTime() - yearStart.getTime()) / 86400000 + 1) / 7)\n return `${date.getUTCFullYear()}-W${String(week).padStart(2, '0')}`\n}\n","/**\n * Which org owns a host's telemetry.\n *\n * A surface should not have to LEARN its key. It already knows the domain it is\n * served from, and a domain belongs to exactly one brand, so the key is derivable\n * and asking a surface to carry one is asking it to restate something already\n * true. This module answers `orgOf(location.hostname)` and hands back that org's\n * publishable key, which is what lets a static export report correctly while\n * configuring nothing.\n *\n * This is the SAME question `hanzo.id` answers at runtime for the identity hosts\n * (`pkgs/shared/src/ingest.ts`): one image serves every brand, so the key cannot\n * be a property of the build. It was, and the bill is on record — Lux's, Zoo's,\n * Osage's and Pars' visitors were all filed in HANZO's project, because one\n * build-time key was inlined for every brand. That is the white-label boundary\n * crossed in the direction that shows up latest. The marketing sites carry the\n * identical defect in its other form: each commits its OWN key literal, so the\n * fleet holds N copies of a value with one source, and a site added tomorrow\n * reports nothing until somebody remembers to paste one in.\n *\n * A `pk-` is PUBLISHABLE: it authorizes a write into one org and mints no reading\n * principal. It is readable in devtools on every deployed page that sends an\n * event, so stating it here exposes nothing that serving the page did not. What\n * it does buy is that correct attribution becomes the DEFAULT rather than\n * something each surface opts into.\n *\n * Keyed by ORG, never by host: a brand's facts repeat on every alias it owns\n * (`lux.id`, `id.lux.network`), and a key stated per host would have to be\n * repeated too — so the day someone adds an alias and forgets the key, that host\n * silently stops reporting. Stated once per org, a new alias inherits its brand's\n * key by naming its brand's domain, which is all an alias ever says.\n */\n\n/** One publishable key per org. */\nexport type Keyring = Readonly<Record<string, string>>\n\n/**\n * Each org's registrable domains. A host matches a domain when it IS that domain\n * or a subdomain of it, so `explore.lux.network` needs no entry of its own.\n *\n * An org absent from this table resolves to undefined, and that is deliberate:\n * `osage`, `pars` and `bootnode` have no project of their own yet, and reporting\n * NOTHING is the honest answer. Filing them under a brand that is not theirs is\n * the defect this module exists to prevent — it is silent, it reads as working,\n * and it is only visible later in someone else's warehouse.\n */\nexport const ORG_DOMAIN: Readonly<Record<string, readonly string[]>> = Object.freeze({\n // A brand's domains are not a pattern — `hanzoskills.com` is Hanzo's and does\n // not end in `hanzo.ai`, while `hanzo.works` is a registrable domain of its own\n // rather than a subdomain of anything here. Each is stated because each is a\n // separate fact, which is the whole reason this is a table.\n hanzo: Object.freeze([\n 'hanzo.ai',\n 'hanzo.agency',\n 'hanzo.app',\n 'hanzo.bot',\n 'hanzo.chat',\n 'hanzo.codes',\n 'hanzo.id',\n 'hanzo.industries',\n 'hanzo.market',\n 'hanzo.network',\n 'hanzo.sh',\n 'hanzo.team',\n 'hanzo.ventures',\n 'hanzo.works',\n 'hanzoskills.com',\n ]),\n lux: Object.freeze([\n 'lux.network',\n 'lux.exchange',\n 'lux.market',\n 'lux.finance',\n 'lux.financial',\n 'lux.credit',\n 'lux.fund',\n 'lux.id',\n ]),\n zoo: Object.freeze(['zoo.ngo', 'zoo.network', 'zoolabs.id', 'zoolabs.io']),\n})\n\n/**\n * Each org's publishable key, and a copy: the values live in universe at\n * infra/k8s/id/configmap.yaml as SPA_INGEST_KEYRING, which serves them to the\n * identity hosts, and this table is what a statically exported page carries when\n * it cannot ask. The two must say the same thing. Add an org the day its project\n * exists, never before.\n *\n * A key is only as real as the project it names, and these had stopped naming\n * one: all three answered `403 ingest_key_unknown` against /v1/event, so every\n * page that fell back to this table reported nowhere while looking fine. The\n * copy drifted silently because nothing compares it to the keyring. If you\n * recreate a project, move BOTH.\n */\nexport const ORG_KEY: Keyring = Object.freeze({\n hanzo: 'pk-CmfLA2K6kvsPflrS9DSkt06H_kSoQB_21sjedt6VJdc',\n lux: 'pk-gUZp6ZVfhJzSwK-rb4oLbVkpCnMBx5uSCpxf_5yEhQk',\n zoo: 'pk-3TKpKnERV9AQSsBUERWkZejC1O1mUxc1jRzsP3MPbs4',\n})\n\n/** `pk-` is publishable; `sk-` is not, and there is no third thing. Checked at the\n * one point a key becomes something a page will send, so a mistyped entry fails\n * closed rather than putting a secret in every visitor's tab. */\nconst PUBLISHABLE = 'pk-'\n\n/** Strip the port and case a hostname the way a domain compares. */\nconst normalize = (host: string): string =>\n host.trim().toLowerCase().replace(/\\.$/, '').split(':')[0] ?? ''\n\n/**\n * The org that owns a host, or undefined when no brand claims it.\n *\n * Longest match wins, so a brand owning both a domain and a subdomain of another\n * brand's cannot be decided by table order. Pure and total.\n */\nexport function orgOf(host: string): string | undefined {\n const h = normalize(host)\n if (!h) return undefined\n let best: string | undefined\n let bestLen = 0\n for (const [org, domains] of Object.entries(ORG_DOMAIN)) {\n for (const d of domains) {\n if ((h === d || h.endsWith(`.${d}`)) && d.length > bestLen) {\n best = org\n bestLen = d.length\n }\n }\n }\n return best\n}\n\n/**\n * The publishable key for a host, or undefined when there is not exactly one to\n * give.\n *\n * Deliberately WITHOUT a fallback: returning Hanzo's key for an unrecognised host\n * is precisely the defect described above. Undefined is the honest answer and the\n * caller reports nothing.\n *\n * `keyring` is a parameter so the identity runtime — which receives its keyring\n * from `/config.json` because one image serves every brand — resolves through\n * this SAME function rather than a second copy of it.\n */\nexport function keyFor(host: string, keyring: Keyring = ORG_KEY): string | undefined {\n const org = orgOf(host)\n if (!org) return undefined\n const key = keyring[org]\n if (typeof key !== 'string') return undefined\n const trimmed = key.trim()\n return trimmed.startsWith(PUBLISHABLE) ? trimmed : undefined\n}\n\n/** The key for the page this code is running on; undefined off a browser. */\nexport function keyForPage(keyring: Keyring = ORG_KEY): string | undefined {\n if (typeof location === 'undefined') return undefined\n return keyFor(location.hostname, keyring)\n}\n","// Client-side redaction for error text — a faithful port of the server's\n// errortracking scrub (o11y pkg/modules/errortracking/implerrortracking/scrub.go),\n// applied BEFORE anything leaves the browser. Two layers, default-secure:\n//\n// - Secret shapes are ALWAYS redacted (sk-… keys, bearer/JWT tokens, DB DSNs,\n// PANs, cloud keys). There is no mode that ships a secret off-device.\n// - PII (email/IP) is scrubbed UNLESS capturePII is explicitly enabled.\n//\n// The server scrubs again — this is defense in depth, not a substitute — but the\n// point is that a Hanzo browser never emits a raw secret/email/IP in the first\n// place. Pure, no I/O.\n\nconst REDACTED = '[redacted]'\nconst EMAIL_MARK = '[email]'\nconst IP_MARK = '[ip]'\n\n// Secret patterns mirror scrub.go's secretPatterns. Order matters (broad DSN/PAN\n// rules run last). All are applied unconditionally.\nconst SECRET_PATTERNS: RegExp[] = [\n /-----BEGIN[ A-Z]*PRIVATE KEY-----[\\s\\S]*?-----END[ A-Z]*PRIVATE KEY-----/g,\n /eyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{6,}\\.[A-Za-z0-9_-]{6,}/g, // JWT\n /\\bbearer\\s+[A-Za-z0-9._~+/-]{12,}=*/gi, // bearer token\n /\\b(?:sk|pk|rk)-[A-Za-z0-9]{2,}-?[A-Za-z0-9]{12,}/g, // openai-style\n /\\b(?:sk|pk)_(?:live|test)_[A-Za-z0-9]{16,}/g, // stripe\n /\\bhk-[A-Za-z0-9]{16,}/g, // hanzo key\n /\\bAKIA[0-9A-Z]{16}\\b/g, // aws access key id\n /\\bASIA[0-9A-Z]{16}\\b/g, // aws sts key id\n /\\bAIza[0-9A-Za-z_-]{20,}/g, // google api key\n /\\bgh[posru]_[A-Za-z0-9]{20,}/g, // github token\n /\\bxox[baprs]-[A-Za-z0-9-]{10,}/g, // slack token\n // Creds in a URL/DSN. The repetition is BOUNDED on purpose: the unbounded form\n // ([^\\s:@/]+:[^\\s@/]+@) backtracks quadratically on colon-rich text with no\n // terminating '@' — an HTML error page pasted into an error message took 4.9s\n // at 32KB and >60s at 128KB, freezing the main thread from inside captureError.\n // Real userinfo is far below these caps, so bounding costs nothing.\n /[a-zA-Z][a-zA-Z0-9+.-]{0,32}:\\/\\/[^\\s:@/]{1,256}:[^\\s@/]{1,256}@/g,\n]\n\n/** Candidate card numbers. Gated by Luhn below — the bare digit-run pattern is a\n * false-positive cannon that redacts every millisecond epoch, order id and\n * phone number it sees (\"request 1753468800000 timed out\" became\n * \"request [redacted]timed out\"), which destroys the readability of the very\n * error messages this client exists to deliver. */\nconst RE_PAN = /\\b(?:\\d[ -]?){13,19}\\b/g\n\n/** luhn reports whether a digit string satisfies the Luhn checksum. Every real\n * card number does, so gating redaction on it removes the false positives\n * WITHOUT introducing a false negative — the safe direction for a redactor. */\nfunction luhn(digits: string): boolean {\n let sum = 0\n let alt = false\n for (let i = digits.length - 1; i >= 0; i--) {\n let d = digits.charCodeAt(i) - 48\n if (alt) {\n d *= 2\n if (d > 9) d -= 9\n }\n sum += d\n alt = !alt\n }\n return sum % 10 === 0\n}\n\n/** redactPAN removes digit runs that actually check out as card numbers. */\nfunction redactPAN(s: string): string {\n return s.replace(RE_PAN, (m) => {\n const digits = m.replace(/[ -]/g, '')\n if (digits.length < 13 || digits.length > 19) return m\n return luhn(digits) ? REDACTED : m\n })\n}\n\n// Bounded to the RFC 5321 maxima (local-part 64, domain 255) for the same reason\n// as the creds-in-URL rule: the unbounded form backtracks quadratically across a\n// long run of local-part-legal characters that never reaches an '@' — measured at\n// 20ms on an 8KB worst case, on the main thread, per captured error. No real\n// address is excluded by these caps.\nconst RE_EMAIL = /[A-Za-z0-9._%+-]{1,64}@[A-Za-z0-9.-]{1,255}\\.[A-Za-z]{2,24}/g\nconst RE_IPV4 = /\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b/g\nconst RE_IPV6 = /\\b(?:[0-9A-Fa-f]{1,4}:){2,7}[0-9A-Fa-f]{1,4}\\b/g\n\n// A CREDENTIAL IN A QUERY PARAM HAS NO SHAPE TO MATCH.\n//\n// Every pattern above recognises a secret by what it LOOKS like — a JWT's three\n// dots, `sk-`, `AKIA`, `ghp_`. An OAuth `code`, a `state`, a password-reset\n// nonce and an invite token are opaque random strings, indistinguishable from a\n// page id, so none of them match and all of them survive.\n//\n// That matters because the client stamps `url: window.location.href` on EVERY\n// event, not just pageviews. So one visit to `/callback?code=…&state=…` puts a\n// live authorization code on the wire, once per event, in cleartext — and the\n// code is exchangeable until it is redeemed.\n//\n// The fix is to redact by the NAME the value is filed under rather than by the\n// value's shape, which is the only signal available for an opaque token. The\n// name half is bounded (`{1,32}`) and the value half stops at the first\n// separator, so neither half can backtrack across a long string — the same\n// discipline the creds-in-URL pattern above documents.\nconst CREDENTIAL_PARAMS = [\n 'code', 'state', 'token', 'access_token', 'id_token', 'refresh_token',\n 'auth', 'authorization', 'secret', 'client_secret', 'password', 'passwd', 'pwd',\n 'api_key', 'apikey', 'key', 'session', 'session_id', 'sid',\n 'sig', 'signature', 'nonce', 'otp', 'invite', 'invitation',\n 'reset_token', 'confirmation_token', 'magic', 'ticket', 'assertion',\n]\nconst RE_CREDENTIAL_PARAM = new RegExp(\n '([?&#;](?:' + CREDENTIAL_PARAMS.join('|') + ')=)[^&#;\\\\s]{1,4096}',\n 'gi',\n)\n\n/** redactCredentialParams removes the VALUE of any query parameter whose NAME\n * says it carries a credential, leaving the name so the URL still reads. */\nexport function redactCredentialParams(s: string): string {\n return s.replace(RE_CREDENTIAL_PARAM, (_m, prefix: string) => prefix + REDACTED)\n}\n\n// A 256-bit secret written as unpadded base64url is exactly 43 characters of\n// [A-Za-z0-9_-] — the shape of a share-link secret, and of any other opaque key\n// minted the same way. The run must stand alone — nothing of the same alphabet\n// on either side, a percent-escape such as the `%23` of an encoded `#` counting\n// as a boundary — so it never fires inside a longer token, and it must mix upper\n// and lower case, which a random 32 bytes does with near certainty and an\n// ordinary word or slug does not. No lookbehind, so it runs on every engine the\n// client ships to.\nconst RE_SECRET43 = /(^|[^A-Za-z0-9_-]|%[0-9A-Fa-f]{2})((?=[A-Za-z0-9_-]{0,42}[a-z])(?=[A-Za-z0-9_-]{0,42}[A-Z])[A-Za-z0-9_-]{43})(?![A-Za-z0-9_-])/g\n\n/** redactSecrets removes known secret shapes. Always applied. */\nexport function redactSecrets(s: string): string {\n s = redactCredentialParams(s)\n for (const re of SECRET_PATTERNS) s = s.replace(re, REDACTED)\n s = s.replace(RE_SECRET43, (_m, lead: string) => lead + REDACTED)\n return redactPAN(s)\n}\n\n/** withoutFragment returns a URL with its fragment removed. A browser never\n * sends the fragment to any server — it is where an app keeps what must stay\n * on the device, a share link's secret among them — so the client does not\n * send it either. */\nexport function withoutFragment(url: string): string {\n const at = url.indexOf('#')\n return at < 0 ? url : url.slice(0, at)\n}\n\n/** scrubPII masks emails and IPs. Applied unless PII capture is enabled. */\nexport function scrubPII(s: string): string {\n s = s.replace(RE_EMAIL, EMAIL_MARK)\n s = s.replace(RE_IPV6, IP_MARK)\n s = s.replace(RE_IPV4, IP_MARK)\n return s\n}\n\n/** Longest free-text field this module will scrub. Every pattern here is a regex\n * run synchronously on the main thread, and the input is attacker-influenced —\n * `throw new Error(await res.text())` against an HTML error page is a one-line\n * way to hand us 128KB. Bounding the INPUT bounds the work regardless of which\n * pattern is pathological. 8KB is far beyond any real error message. */\nexport const MAX_SCRUB_LEN = 8192\n\n/** truncate caps a string at MAX_SCRUB_LEN, marking that it was cut so a reader\n * never mistakes a truncated message for the whole one. */\nexport function truncate(s: string, max = MAX_SCRUB_LEN): string {\n return s.length > max ? s.slice(0, max) + '… [truncated]' : s\n}\n\n/** scrubText applies the redaction policy to a free-text field. Input is capped\n * first: unbounded text is a denial-of-service surface, not just a size problem. */\nexport function scrubText(s: string | undefined, capturePII = false): string {\n if (!s) return s ?? ''\n s = truncate(s)\n s = redactSecrets(s)\n if (!capturePII) s = scrubPII(s)\n return s\n}\n","// Pure throwable parsing: coerce anything thrown into {name, message, stack} and\n// parse a browser stack into frames. No I/O, no globals.\n\nimport type { SentryFrame } from './types'\n\nconst MAX_FRAMES = 50\n/** Max stack lines examined, and max length of a line worth examining. Guards the\n * frame regexes against a hostile `stack` string (see framesFromStack). */\nconst MAX_LINES = 500\nconst MAX_LINE_LEN = 2048\n\nconst V8_FRAME = /^\\s*at\\s+(?:(.+?)\\s+\\()?(?:(.+?):(\\d+):(\\d+)|([^)]+))\\)?\\s*$/\nconst MOZ_FRAME = /^\\s*(?:(.*?)@)?(.+?):(\\d+):(\\d+)\\s*$/\n\n/** inApp marks a frame as the app's own code (vs vendor/runtime) for grouping. */\nfunction inApp(file: string): boolean {\n if (!file) return false\n return !(\n file.includes('node_modules') ||\n file.startsWith('webpack-internal') ||\n file.startsWith('webpack://') ||\n file.startsWith('chrome-extension://') ||\n file.startsWith('moz-extension://')\n )\n}\n\n/**\n * framesFromStack parses a browser Error.stack into Sentry frames, OLDEST-FIRST\n * (Sentry orders caller->callee; the crash site is last — matching the server's\n * pickCrashFrame). Handles both V8 (\"at fn (file:li:co)\") and\n * Firefox/Safari (\"fn@file:li:co\"). Unparseable lines are skipped.\n */\nexport function framesFromStack(stack: string | undefined): SentryFrame[] {\n if (!stack) return []\n // Both frame regexes use lazy nested quantifiers, which backtrack badly on a\n // long line that never matches. A stack is attacker-influenced (a thrown value\n // can carry any `stack` string), so bound the work: skip absurd lines and stop\n // after MAX_LINES. Only the innermost MAX_FRAMES are kept anyway.\n const lines = stack.split('\\n', MAX_LINES)\n const frames: SentryFrame[] = []\n for (const raw of lines) {\n if (raw.length > MAX_LINE_LEN) continue\n const line = raw.trimEnd()\n if (!line) continue\n // Header lines like \"TypeError: x is not a function\" match neither frame\n // regex (no \"at \" prefix, no trailing :line:col) and are skipped naturally.\n let fn: string | undefined\n let file = ''\n let lineno = 0\n let colno = 0\n const v = V8_FRAME.exec(line)\n if (v) {\n fn = v[1]\n if (v[2]) {\n file = v[2]\n lineno = Number(v[3]) || 0\n colno = Number(v[4]) || 0\n } else {\n file = (v[5] || '').trim()\n }\n } else {\n const f = MOZ_FRAME.exec(line)\n if (!f) continue\n fn = f[1]\n file = f[2]\n lineno = Number(f[3]) || 0\n colno = Number(f[4]) || 0\n }\n if (!file && !fn) continue\n frames.push({\n function: fn || '<anonymous>',\n filename: file,\n abs_path: file,\n lineno,\n colno,\n in_app: inApp(file),\n })\n }\n // Reverse to oldest-first and cap to the innermost MAX_FRAMES.\n frames.reverse()\n if (frames.length > MAX_FRAMES) return frames.slice(frames.length - MAX_FRAMES)\n return frames\n}\n\n/** normalizeError coerces an unknown throwable into {name, message, stack}. */\nexport function normalizeError(err: unknown): { name: string; message: string; stack?: string } {\n if (err instanceof Error) {\n // `name`, `message` and `stack` are ordinary getters, and the thrown object is\n // the least trustworthy input this library handles — any of them may throw.\n // Losing the whole report to a hostile getter is not acceptable.\n const name = read(err, 'name')\n const message = read(err, 'message')\n const stack = read(err, 'stack')\n return {\n name: typeof name === 'string' && name ? name : 'Error',\n message: typeof message === 'string' && message ? message : str(err),\n stack: typeof stack === 'string' ? stack : undefined,\n }\n }\n if (typeof err === 'string') return { name: 'Error', message: err }\n try {\n return { name: 'Error', message: JSON.stringify(err) ?? str(err) }\n } catch {\n return { name: 'Error', message: str(err) }\n }\n}\n\n/** read pulls a property off a possibly-hostile value without letting a throwing\n * getter escape. */\nfunction read(o: unknown, k: string): unknown {\n try {\n return (o as Record<string, unknown>)[k]\n } catch {\n return undefined\n }\n}\n\n/** str coerces to a string without letting a throwing toString/Symbol.toPrimitive\n * escape. */\nfunction str(v: unknown): string {\n try {\n return String(v)\n } catch {\n return '[unstringifiable]'\n }\n}\n","/*! anon.js — THE anonymous-identity chain. ONE implementation, two distributions.\n *\n * One browser is ONE person on every Hanzo surface, whichever client a page\n * happens to have loaded. There were once three implementations writing TWO keys —\n * `hz_anon_id` and `hz_id` — so the same visitor was several people depending on\n * which snippet the surface shipped.\n *\n * The two call sites:\n * 1. src/storage.ts — the bundled npm client; IMPORTS this file.\n * 2. hanzoai/cloud apps/analytics/tag.js — the tag served at\n * /v1/event.js; vendors this file and its tag.go serves the marked region\n * with the tag as one asset, so cloud holds no second copy either.\n *\n * (2) has no bundler and cannot import anything, which is why the chain lives in a\n * file that is plain ES5 rather than in a .ts: the region between the BEGIN and END\n * markers is COPIED VERBATIM. Keep it ES5, dependency-free, `hz`-prefixed (it is\n * spliced into other people's scopes) and unformatted — a reformat here is a diff\n * against the vendored copy. After editing, resync that copy:\n *\n * curl -fsSL https://unpkg.com/@hanzo/event/src/anon.js -o apps/analytics/anon.js\n */\n\n/* ── BEGIN hz anon chain — copied VERBATIM into hanzoai/cloud ──────────────── */\n\n/** The ONE anonymous-id key, on every surface and in every distribution.\n *\n * It names what it is, not who ships it: this value is visible to anyone who opens\n * their own cookie jar, and a vendor's name has no business there. Identity is IAM's\n * concern whether or not the visitor has said who they are. */\nvar HZ_ANON_KEY = 'iam-anon-id'\n\n/** Keys an id may already be living under. READ, never written.\n *\n * Each was canonical once — `hz_anon_id` most recently, and `hz_id` before it, when a\n * no-build tag wrote a second identity space and one page could hold two people.\n * Adopting an id already in the wild is what makes this a rename rather than an\n * erasure: minting over one detaches a returning visitor from their own history.\n * They are never written, so they leave with the cookies that hold them. */\nvar HZ_ANON_ADOPT = ['hz_anon_id', 'hz_id']\n\n/** The registrable domain the cookie is scoped to, so docs, cloud, console,\n * studio, pay, id and www all read the ONE id. localStorage cannot do this: it is\n * ORIGIN-scoped, which is what made one journey arrive as several strangers. */\nvar HZ_ANON_DOMAIN = 'hanzo.ai'\n\n/** Two years, rewritten on every read, so the cookie rolls forward with the\n * visitor instead of expiring two years after first touch. Safari caps a\n * SCRIPT-written cookie at 7 days no matter what this says, so the rewrite is\n * what keeps a returning Safari visitor: each read re-arms the 7-day window. */\nvar HZ_ANON_MAX_AGE = 2 * 365 * 24 * 60 * 60\n\n/** Last resort for a browser that refuses cookies AND localStorage: without it\n * every event in a page load would mint an id of its own. */\nvar hzAnonMemo\n\n/**\n * hzUuidv7 mints a time-ordered UUIDv7 (RFC 9562 §5.7) for `now` in epoch ms.\n *\n * It has to be v7, and this is the only minter any distribution may use. The\n * session rollups on the event plane derive a session's start instant FROM THE ID\n * and admit only ids whose version nibble is 7, so a crypto.randomUUID() (v4) id\n * is not merely unordered there — it is DISCARDED, silently, and the rollup stays\n * empty. Without crypto only the ENTROPY degrades; the shape is always a valid v7.\n */\nfunction hzUuidv7(now) {\n var b = new Uint8Array(16)\n var i\n var c = typeof crypto !== 'undefined' ? crypto : undefined\n if (c && typeof c.getRandomValues === 'function') c.getRandomValues(b)\n else for (i = 0; i < 16; i++) b[i] = (Math.random() * 256) | 0\n var t = Math.floor(now === undefined ? Date.now() : now)\n for (i = 5; i >= 0; i--) {\n b[i] = t % 256\n t = Math.floor(t / 256)\n }\n b[6] = 0x70 | (b[6] & 0x0f) // version 7\n b[8] = 0x80 | (b[8] & 0x3f) // variant 0b10\n var h = ''\n for (i = 0; i < 16; i++) {\n h += (b[i] + 0x100).toString(16).slice(1)\n if (i === 3 || i === 5 || i === 7 || i === 9) h += '-'\n }\n return h\n}\n\n/** The cookie jar, or null wherever there is no document to read one from. */\nfunction hzAnonJar() {\n try {\n if (typeof document === 'undefined' || typeof document.cookie !== 'string') return null\n return document\n } catch (e) {\n return null // sandboxed frame with an opaque origin\n }\n}\n\n/** localStorage, or null when the browser refuses it (Safari private mode). */\nfunction hzAnonStore() {\n try {\n if (typeof window === 'undefined' || !window.localStorage) return null\n return window.localStorage\n } catch (e) {\n return null\n }\n}\n\n/** One stored value, or '' — a jar can read as well as refuse to. */\nfunction hzAnonItem(store, name) {\n try {\n return (store && store.getItem(name)) || ''\n } catch (e) {\n return ''\n }\n}\n\n/** The value of cookie `name`, or ''. */\nfunction hzAnonCookie(name) {\n var d = hzAnonJar()\n if (!d) return ''\n var parts = d.cookie.split(';')\n for (var i = 0; i < parts.length; i++) {\n var eq = parts[i].indexOf('=')\n if (eq < 0 || parts[i].slice(0, eq).trim() !== name) continue\n var v = parts[i].slice(eq + 1).trim()\n if (!v) continue\n try {\n return decodeURIComponent(v)\n } catch (e) {\n return v // not percent-encoded — take it as written\n }\n }\n return ''\n}\n\n/** Writes `name` on the registrable domain, for as long as the browser allows. */\nfunction hzAnonWrite(name, value) {\n var d = hzAnonJar()\n if (!d) return\n var host = ''\n var secure = false\n try {\n if (typeof window !== 'undefined' && window.location) {\n host = window.location.hostname || ''\n // A Secure cookie is refused outright by a non-secure origin, which would\n // strand http://localhost dev on the localStorage path.\n secure = window.location.protocol === 'https:'\n }\n } catch (e) {\n /* location unreachable — write a host-only, non-secure cookie */\n }\n // encodeURIComponent leaves a UUID byte-identical while making any value that is\n // not one unable to forge a `;` and inject an attribute.\n var c = name + '=' + encodeURIComponent(value)\n c += '; Path=/; Max-Age=' + HZ_ANON_MAX_AGE + '; SameSite=Lax'\n // Off hanzo.ai (localhost, previews, other registrable domains) the attribute\n // would be rejected and the whole cookie dropped, so it stays host-only there.\n // Prefixing both sides with '.' matches the domain itself and its subdomains\n // while refusing a suffix that merely ends in the same letters (evilhanzo.ai).\n if (('.' + host).slice(-(HZ_ANON_DOMAIN.length + 1)) === '.' + HZ_ANON_DOMAIN) {\n c += '; Domain=' + HZ_ANON_DOMAIN\n }\n if (secure) c += '; Secure'\n try {\n d.cookie = c\n } catch (e) {\n /* cookies refused — localStorage still carries the id */\n }\n}\n\n/**\n * hzAnonId returns the stable anonymous id for this browser, '' during SSR.\n *\n * Resolution is strictly ADDITIVE — every id that already exists is ADOPTED, and\n * only a browser holding none of them is given a new one:\n *\n * cookie · localStorage iam-anon-id · adopted keys · in-memory · mint\n *\n * Minting over an id resets a returning visitor and detaches them from their own\n * history, so the order is the migration: the cookie is the shared home, the two\n * localStorage keys are what the three implementations wrote before it existed,\n * and each is read until nothing is left to adopt.\n *\n * localStorage keeps being written, so a rollback finds everyone where it left\n * them, and a browser that refuses cookies still holds one id per origin.\n */\n/**\n * hzAnonAdopted returns an id already living under a key that used to be canonical,\n * from the cookie jar first — that is the copy shared across subdomains, so a visitor\n * who arrived on one host is the same person on the next.\n */\nfunction hzAnonAdopted(s) {\n for (var i = 0; i < HZ_ANON_ADOPT.length; i++) {\n var id = hzAnonCookie(HZ_ANON_ADOPT[i]) || hzAnonItem(s, HZ_ANON_ADOPT[i])\n if (id) return id\n }\n return ''\n}\n\nfunction hzAnonId() {\n if (typeof window === 'undefined') return '' // SSR / prerender: no browser to identify\n var s = hzAnonStore()\n var id =\n hzAnonCookie(HZ_ANON_KEY) ||\n hzAnonItem(s, HZ_ANON_KEY) ||\n hzAnonAdopted(s) ||\n hzAnonMemo ||\n hzUuidv7()\n hzAnonMemo = id\n hzAnonWrite(HZ_ANON_KEY, id)\n try {\n if (s && s.getItem(HZ_ANON_KEY) !== id) s.setItem(HZ_ANON_KEY, id)\n } catch (e) {\n /* quota exhausted, or a private-mode jar that reads but refuses writes */\n }\n return id\n}\n\n/**\n * hzAnonAdopt makes `id` this browser's anonymous id, replacing whatever it held.\n *\n * A visitor who followed a link from another Hanzo host arrives carrying the id that\n * host minted; keeping the local one splits one journey into two strangers. The\n * caller has already checked the shape.\n */\nfunction hzAnonAdopt(id) {\n hzAnonMemo = id\n hzAnonWrite(HZ_ANON_KEY, id)\n try {\n var s = hzAnonStore()\n if (s) s.setItem(HZ_ANON_KEY, id)\n } catch (e) {\n /* quota exhausted or a read-only jar — the cookie and memo still carry it */\n }\n}\n\n/* ── END hz anon chain ─────────────────────────────────────────────────────── */\n\nexport { hzAnonId, hzAnonAdopt, hzUuidv7 }\n","// The ONE id minter for this client — UUIDv7 (RFC 9562 §5.7).\n//\n// The implementation is `hzUuidv7` in ./anon.js and this file only re-exports it.\n// It lives there because the anonymous-id chain has to mint too, and that chain is\n// inlined verbatim by the distribution that has no bundler (the tag\n// served at /v1/event.js) — a minter here as well would be a second implementation, and\n// the version nibble it produces is exactly the thing that must never diverge.\n//\n// WHY NOT crypto.randomUUID(): it mints v4, whose 122 bits are pure entropy and\n// carry no time. The session rollups on the event plane derive a session's start\n// instant FROM THE ID — their PARTITION BY and ORDER BY are\n// `fromUnixTimestamp(intDiv(toUInt64(bitShiftRight(session_id_v7, 80)), 1000))` —\n// so they admit only ids whose version nibble is 7\n// (`bitAnd(bitShiftRight(toUInt128(session_id), 76), 15) = 7`). A v4 session id is\n// not merely unordered there: it is DISCARDED by that predicate, silently, and the\n// rollup stays empty forever. Minting v7 is the whole reason those rollups can\n// exist; it also clusters index writes by time instead of scattering them across\n// the keyspace.\n//\n// Layout, 16 bytes big-endian:\n// 0..5 unix_ts_ms — 48-bit millisecond timestamp\n// 6 0111 (version 7) in the high nibble | rand_a\n// 7 rand_a\n// 8 10 (variant) in the high 2 bits | rand_b\n// 9..15 rand_b\n//\n// Never returns a non-UUID shape. The old minters fell back to `'a-' + base36`\n// when crypto was absent, and the plane casts a session id with\n// accurateCastOrNull(…, 'UUID') — a shape that does not parse becomes NULL and is\n// dropped by the same gate, so the fallback failed exactly like v4 did. Only the\n// ENTROPY degrades without crypto; the shape is always a valid v7 UUID.\n\n/**\n * uuidv7 mints a time-ordered UUIDv7 for `now` (epoch milliseconds).\n *\n * Two ids minted in the same millisecond sort arbitrarily between themselves; ids\n * from different milliseconds sort by time, lexically and numerically alike.\n */\nexport { hzUuidv7 as uuidv7 } from './anon.js'\n\n/** The millisecond timestamp a v7 id was minted at — the inverse of uuidv7. */\nexport function uuidv7Time(id: string): number {\n return parseInt(id.slice(0, 8) + id.slice(9, 13), 16)\n}\n","// SSR-safe browser storage for stable identifiers and first-touch state. Every\n// accessor no-ops (returns undefined) when there is no window/localStorage, so the\n// client imports cleanly in a Next.js server component.\n//\n// The anonymous id is the one value that must outlive an ORIGIN, and it is also\n// the one value the OTHER two distributions must agree with, so its chain lives in\n// ./anon.js and this file only calls it. Everything else here stays origin-local.\n\nimport { hzAnonAdopt, hzAnonId } from './anon.js'\nimport type { Attribution, Cohort } from './types'\nimport { uuidv7 } from './uid'\n\nconst KEY = {\n session: 'hz_session',\n firstTouch: 'hz_first_touch',\n cohort: 'hz_cohort',\n} as const\n\n/** 30-minute inactivity window defines a session (PostHog/GA convention). */\nconst SESSION_TTL_MS = 30 * 60 * 1000\n\nfunction ls(): Storage | undefined {\n try {\n if (typeof window === 'undefined' || !window.localStorage) return undefined\n return window.localStorage\n } catch {\n return undefined // Safari private mode / blocked storage\n }\n}\n\n/**\n * Stable anonymous id, shared by every *.hanzo.ai surface AND by every Hanzo\n * client on the page — the npm client and the hosted tag both run the one\n * chain in ./anon.js, so which snippet a surface loaded no longer decides who the\n * visitor is.\n *\n * It lives in a first-party cookie on the registrable domain because localStorage\n * is ORIGIN-scoped: docs, cloud and console each minted their own id for the same\n * person, so one marketing → docs → signup → checkout journey arrived as several\n * strangers — 463 anonymous identities carried 545 events in a week, about 1.2\n * events each.\n */\nexport function anonId(): string | undefined {\n return hzAnonId() || undefined // '' during SSR / prerender\n}\n\ninterface SessionState {\n id: string\n last: number\n}\n\n/**\n * Current session id, rotated after SESSION_TTL_MS of inactivity.\n *\n * Minted at `now`, so the v7 timestamp the id carries IS the session's start\n * instant — which is what the session rollups partition and order on. Passing the\n * caller's clock rather than reading Date.now() again keeps the id's embedded time\n * and the recorded `last` from disagreeing.\n */\nexport function sessionId(now = Date.now()): string | undefined {\n const s = ls()\n if (!s) return undefined\n let state: SessionState | null = null\n try {\n state = JSON.parse(s.getItem(KEY.session) || 'null')\n } catch {\n state = null\n }\n if (!state || now - state.last > SESSION_TTL_MS) {\n state = { id: uuidv7(now), last: now }\n } else {\n state.last = now\n }\n s.setItem(KEY.session, JSON.stringify(state))\n return state.id\n}\n\n/** Make `id` the current session, as if it had begun now. The session a link\n * carries is the one the visitor is already in, so the journey stays one session\n * across the hop instead of splitting at the host boundary. */\nexport function adoptSession(id: string, now = Date.now()): void {\n const s = ls()\n if (s) s.setItem(KEY.session, JSON.stringify({ id, last: now }))\n}\n\n/** Make `id` the browser's anonymous id, replacing the one it held. */\nexport function adoptAnonId(id: string): void {\n hzAnonAdopt(id)\n}\n\n/** Read the persisted first-touch attribution. */\nexport function getFirstTouch(): Attribution | undefined {\n const s = ls()\n if (!s) return undefined\n try {\n const v = s.getItem(KEY.firstTouch)\n return v ? (JSON.parse(v) as Attribution) : undefined\n } catch {\n return undefined\n }\n}\n\n/** Persist first-touch attribution ONCE — never overwrite an existing record. */\nexport function setFirstTouchOnce(a: Attribution): Attribution {\n const s = ls()\n const existing = getFirstTouch()\n if (existing) return existing\n if (s) s.setItem(KEY.firstTouch, JSON.stringify(a))\n return a\n}\n\n/** Read persisted cohort dimensions. */\nexport function getCohort(): Cohort | undefined {\n const s = ls()\n if (!s) return undefined\n try {\n const v = s.getItem(KEY.cohort)\n return v ? (JSON.parse(v) as Cohort) : undefined\n } catch {\n return undefined\n }\n}\n\n/** Merge + persist cohort dimensions (signupWeek set once). */\nexport function mergeCohort(patch: Cohort): Cohort {\n const s = ls()\n const cur = getCohort() || {}\n const next: Cohort = {\n signupWeek: cur.signupWeek || patch.signupWeek,\n channel: patch.channel || cur.channel,\n refCode: cur.refCode || patch.refCode,\n }\n if (s) s.setItem(KEY.cohort, JSON.stringify(next))\n return next\n}\n","// Cross-domain visitor continuity.\n//\n// Cookies and localStorage stop at the registrable domain, so a visitor who goes\n// hanzo.ai -> hanzo.id (sign-in) -> back arrived as separate people on each host, and\n// the journey across the sign-in redirect could not be read. A link between two\n// Hanzo hosts therefore carries the visitor's identity in three short query\n// parameters, and the destination adopts them before its first pageview and\n// removes them from the address bar.\n//\n// hz_aid anonymous id hz_sid session id hz_ft first-touch attribution\n//\n// They are appended ONLY when the destination host belongs to a brand in ORG_DOMAIN:\n// an id handed to a host outside the table would be handed to a stranger.\n\nimport { orgOf } from './org'\nimport type { Attribution } from './types'\n\nexport const LINK_PARAMS = { anon: 'hz_aid', session: 'hz_sid', firstTouch: 'hz_ft' } as const\n\n/** Ids are v7 UUIDs; anything else in a URL is someone else's input and is refused. */\nconst UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\nexport const isId = (v: string | null | undefined): v is string => !!v && UUID.test(v)\n\n/** What a link carries. Any field may be absent. */\nexport interface LinkState {\n anonId?: string\n sessionId?: string\n firstTouch?: Attribution\n}\n\n/** First touch as a compact tuple: utm source, medium, campaign, term, content, refCode,\n * referrer, channel. Short because it rides a URL; a tuple because keys cost bytes. */\nexport function encodeFirstTouch(a: Attribution): string {\n return JSON.stringify([\n a.utm.source, a.utm.medium, a.utm.campaign, a.utm.term, a.utm.content,\n a.refCode, a.referrer, a.channel,\n ].map((v) => v ?? ''))\n}\n\nexport function decodeFirstTouch(raw: string | null | undefined): Attribution | undefined {\n if (!raw || raw.length > 1024) return undefined\n try {\n const t: unknown = JSON.parse(raw)\n if (!Array.isArray(t) || t.length !== 8 || t.some((v) => typeof v !== 'string')) return undefined\n const [source, medium, campaign, term, content, refCode, referrer, channel] = t as string[]\n const u = (v: string) => v || undefined\n return {\n utm: { source: u(source), medium: u(medium), campaign: u(campaign), term: u(term), content: u(content) },\n refCode: u(refCode),\n referrer: u(referrer),\n channel: u(channel),\n }\n } catch {\n return undefined\n }\n}\n\n/** linkUrl returns `url` with the visitor's identity appended when its host is\n * Hanzo-owned and is not `fromHost`; otherwise `url` unchanged. Relative URLs\n * resolve against `base`. Never throws. */\nexport function linkUrl(url: string, state: LinkState, fromHost: string, base?: string): string {\n let u: URL\n try {\n u = new URL(url, base)\n } catch {\n return url\n }\n if (u.protocol !== 'https:' && u.protocol !== 'http:') return url\n if (!orgOf(u.hostname) || u.hostname === fromHost) return url\n const set = (k: string, v: string | undefined) => v && u.searchParams.set(k, v)\n if (isId(state.anonId)) set(LINK_PARAMS.anon, state.anonId)\n if (isId(state.sessionId)) set(LINK_PARAMS.session, state.sessionId)\n if (state.firstTouch) set(LINK_PARAMS.firstTouch, encodeFirstTouch(state.firstTouch))\n return u.toString()\n}\n\n/** readLink parses what a link carried out of a location.search value. Invalid\n * values are dropped, not repaired. */\nexport function readLink(search: string): LinkState {\n const q = new URLSearchParams(search || '')\n const a = q.get(LINK_PARAMS.anon)\n const s = q.get(LINK_PARAMS.session)\n return {\n anonId: isId(a) ? a : undefined,\n sessionId: isId(s) ? s : undefined,\n firstTouch: decodeFirstTouch(q.get(LINK_PARAMS.firstTouch)),\n }\n}\n\n/** stripLink returns the path, query and hash of `href` without the link parameters, or\n * undefined when there were none. */\nexport function stripLink(href: string): string | undefined {\n const u = new URL(href)\n let hit = false\n for (const k of Object.values(LINK_PARAMS)) {\n if (u.searchParams.has(k)) {\n u.searchParams.delete(k)\n hit = true\n }\n }\n return hit ? u.pathname + u.search + u.hash : undefined\n}\n","{\n \"name\": \"@hanzo/event\",\n \"version\": \"0.3.50\",\n \"description\": \"Hanzo Event \\u2014 the ONE telemetry client. Emits pageview/event/identify/group to the Hanzo Cloud event stream (POST /v1/event), AND reports errors to Sentry as real Sentry envelopes \\u2014 the error plane needs a DSN, without one nothing reaches Sentry. First-touch attribution, beacon-on-unload, auto error capture, client-side secret/PII scrubbing, a shared event + goal vocabulary. Subsumes @sentry.\",\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org/\",\n \"access\": \"public\",\n \"scope\": \"@hanzo\"\n },\n \"author\": \"Hanzo AI <dev@hanzo.ai>\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"sideEffects\": false,\n \"files\": [\n \"dist\",\n \"src\",\n \"README.md\",\n \"TAXONOMY.md\"\n ],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/hanzoai/ui.git\",\n \"directory\": \"pkg/event\"\n },\n \"keywords\": [\n \"analytics\",\n \"product-analytics\",\n \"telemetry\",\n \"events\",\n \"error-tracking\",\n \"sentry\",\n \"attribution\",\n \"funnel\",\n \"hanzo\"\n ],\n \"scripts\": {\n \"prepublishOnly\": \"node ../../scripts/guard-publish.mjs\",\n \"build\": \"tsup && tsc --emitDeclarationOnly --declaration --outDir dist && node ../../scripts/dts.mjs\",\n \"dev\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"typecheck\": \"tsc --noEmit -p tsconfig.json\",\n \"clean\": \"rm -rf dist\"\n },\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.mjs\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n },\n \"./react\": {\n \"import\": {\n \"types\": \"./dist/react.d.ts\",\n \"default\": \"./dist/react.mjs\"\n },\n \"require\": {\n \"types\": \"./dist/react.d.cts\",\n \"default\": \"./dist/react.cjs\"\n }\n }\n },\n \"peerDependencies\": {\n \"react\": \">=19.2.8\"\n },\n \"peerDependenciesMeta\": {\n \"react\": {\n \"optional\": true\n }\n },\n \"devDependencies\": {\n \"@types/node\": \"catalog:\",\n \"@types/react\": \"catalog:\",\n \"react\": \"catalog:\",\n \"tsup\": \"catalog:\",\n \"typescript\": \"catalog:\",\n \"vitest\": \"catalog:\"\n },\n \"dependencies\": {\n \"@hanzo/events\": \"catalog:\"\n }\n}\n","// The library version, stamped on every event (`libraryVersion`) and on the\n// Sentry `sdk` block. It lives alone so `sentry.ts` can read it without importing\n// `core.ts` — core imports sentry, so the reverse would be an import cycle.\n//\n// Read from package.json rather than restated, because a version restated is a\n// version that drifts: 0.3.38 and 0.3.39 both shipped while this file still said\n// 0.3.37, so every event those builds sent named a library that was two releases\n// behind. `resolveJsonModule` inlines the literal at build time, and tsup shakes\n// the rest of the manifest out.\nimport { version } from '../package.json'\n\nexport const VERSION: string = version\n","// The framework-agnostic event client. ONE API surface over TWO orthogonal\n// planes, sharing one session and one identity:\n//\n// 1. EVENT STREAM — buffered pageview/event/identify/group, flushed as ONE\n// batch to the Hanzo Cloud entry point:\n// POST {host}/v1/event body: { batch: [Event, …] } -> { accepted, dropped }\n// Cloud resolves the tenant server-side (validated session, or the signed\n// publishable key) and stamps it; the client NEVER sends the org.\n//\n// Errors ride the same pipe: a captured exception is ONE event of type 'error'\n// carrying {type, message, frames|stack, handled} plus release, environment,\n// site, product and level. The server files it on the error plane and groups it\n// into an issue. There is no second endpoint, DSN or envelope.\n//\n// Auth is orthogonal — the SAME body to the SAME endpoint, differing only in how the\n// caller proves its tenant:\n//\n// • cookie/session app (host:'') — same-origin credentials ride the request.\n// • bearer app (getToken) — Authorization: Bearer <jwt>.\n// • publishable-key app (ingestKey: 'pk-…') — ?ingest_key=pk-… on the query, on\n// the fetch and the beacon alike, with a text/plain body. Write-only and safe\n// to ship in a bundle; the endpoint resolves it to an org server-side. The query\n// is the carrier neither send needs a header for, which is what keeps both\n// CORS-simple and therefore sendable from a customer's own origin.\n//\n// The wire is the canonical `Event` (== the cloud CaptureEvent).\n\nimport {\n parseAttribution,\n hasAttribution,\n deriveChannel,\n} from './attribution'\nimport { keyForPage } from './org'\nimport { PAGEVIEW } from './events'\nimport { scrubText, withoutFragment } from './scrub'\nimport { framesFromStack, normalizeError as normalizeThrowable } from './throwable'\nimport {\n adoptAnonId,\n adoptSession,\n anonId,\n sessionId,\n getFirstTouch,\n setFirstTouchOnce,\n getCohort,\n mergeCohort,\n} from './storage'\nimport { uuidv7 } from './uid'\nimport { linkUrl, readLink, stripLink } from './link'\nimport type {\n AnalyticsConfig,\n Attribution,\n CaptureErrorOptions,\n Cohort,\n EventKind,\n Exception,\n Transport,\n WireEvent,\n} from './types'\nimport { VERSION } from './version'\n\nexport { VERSION }\n\nconst EVENT_PATH = '/v1/event' // the ONE canonical ingestion entry point\nconst DEFAULT_HOST = 'https://api.hanzo.ai' // the one edge; cookie apps pass host:''\n// The beacon body's type. text/plain is CORS-SAFELISTED, which is the whole\n// property: a safelisted type makes the POST a SIMPLE request, and a simple\n// request needs no preflight. An unloading document does not get a second round\n// trip, so cross-origin a preflighted beacon is never sent at all. The endpoint reads\n// the raw body and dispatches on its first non-space byte, so the type names the\n// CORS class and nothing else.\nconst BEACON_CONTENT_TYPE = 'text/plain'\n\n/** readEnv reads an inlined build-time variable, guarded for SSR. */\nfunction readEnv(name: string): string | undefined {\n try {\n if (typeof process !== 'undefined' && process.env) return process.env[name] || undefined\n } catch {\n /* no process */\n }\n return undefined\n}\n\n/** appendQuery adds a single query param to a URL string — used to carry a\n * publishable key on either send (?ingest_key=…). */\nfunction appendQuery(url: string, key: string, value: string): string {\n return url + (url.includes('?') ? '&' : '?') + key + '=' + encodeURIComponent(value)\n}\n\n/** Normalize anything thrown (Error | string | unknown) into an Exception. */\n/** normalizeError adapts the hostile-input-safe normalizer (sentry.ts) to the\n * stream's Exception shape: a thrown object may define `name`/`message`/`stack`\n * as throwing getters. */\nfunction normalizeError(err: unknown): Exception {\n const n = normalizeThrowable(err)\n const frames = framesFromStack(n.stack)\n .slice(-50)\n .map((f) => ({ function: f.function, file: f.filename, line: f.lineno, column: f.colno }))\n return { type: n.name, message: n.message, stack: n.stack, frames }\n}\n\n// React Native defines a `window` but no `document` (and no `window.location`),\n// so `typeof window !== 'undefined'` alone took the browser path there and\n// `init()` threw on `window.location.search`. Requiring `document` makes RN read\n// as non-browser: `init()` returns early (skips attribution + the visibility/\n// unload listeners RN doesn't have), while `capture()`/`flush()` — which are NOT\n// gated on this and post through plain `fetch` — still emit. So the client is\n// inert-safe under SSR/Node and live on RN, without a second transport.\n/** The screen and language a page view carries, for the readers that derive device and locale. */\nconst viewport = (): Record<string, string> =>\n isBrowser()\n ? { screen: `${window.screen?.width ?? 0}x${window.screen?.height ?? 0}`, language: navigator.language || '' }\n : {}\n\nconst isBrowser = () => typeof window !== 'undefined' && typeof document !== 'undefined'\n\n/** serializeBatch stringifies a batch, salvaging what it can. `properties` is\n * arbitrary caller data — a DOM node, a React synthetic event, an axios error are\n * all circular, and a getter on one can throw — so a whole batch must never be\n * lost to a single poisoned event. Falls back to per-event serialization, then to\n * keeping the event and dropping its properties. Returns null only when nothing\n * at all survives. */\nfunction serializeBatch(batch: WireEvent[]): string | null {\n try {\n return JSON.stringify({ batch })\n } catch {\n /* one bad event — salvage the rest below */\n }\n const parts: string[] = []\n for (const e of batch) {\n try {\n parts.push(JSON.stringify(e))\n } catch {\n try {\n // Keep the event (identity, session, type all matter); drop the payload\n // that could not be serialized, and say so rather than lying by omission.\n parts.push(JSON.stringify({ ...e, properties: { $unserializable: true } }))\n } catch {\n /* unsalvageable — drop this ONE event, never the batch */\n }\n }\n }\n return parts.length > 0 ? '{\"batch\":[' + parts.join(',') + ']}' : null\n}\n\n/** DefaultTransport: fetch(keepalive) for authenticated/normal sends;\n * navigator.sendBeacon for page-unload beacons.\n *\n * A publishable key rides the ?ingest_key query on BOTH, which is what keeps\n * both CORS-simple: the query is the one carrier neither send needs a header\n * for, and a simple request leaves the browser from any origin — permission is\n * asked to READ a cross-origin response, never to send one. That is what lets a\n * bundled client run on a customer's own page. A JWT is first-party by\n * construction, so it keeps Authorization and the session it travels with.\n *\n * `contentType` names the FETCH request's Content-Type (the error plane sets the\n * envelope type there, and keeps the header carrier with it). The beacon body is\n * always BEACON_CONTENT_TYPE: its type is a CORS class, not a payload\n * description, and a beacon that is not a simple request is never sent. */\nclass DefaultTransport implements Transport {\n send(\n url: string,\n body: string,\n opts: {\n beacon: boolean\n token?: string\n ingestKey?: string\n contentType?: string\n debug?: boolean\n },\n ): void {\n if (opts.beacon && isBrowser() && typeof navigator.sendBeacon === 'function') {\n const beaconUrl = opts.ingestKey ? appendQuery(url, 'ingest_key', opts.ingestKey) : url\n try {\n // The answer is whether the agent QUEUED the batch — false for a body past\n // the beacon size limit, or a full queue. Only a queued batch ends the\n // send; a refused one falls through to the keepalive fetch below.\n const queued = navigator.sendBeacon(\n beaconUrl,\n new Blob([body], { type: BEACON_CONTENT_TYPE }),\n )\n if (queued) return\n if (opts.debug) console.warn('[event] beacon refused, falling back to fetch')\n } catch {\n /* fall through to fetch */\n }\n }\n if (typeof fetch !== 'function') return\n // A publishable key makes the send a CORS SIMPLE request: the key rides the\n // query, the body is text/plain, and nothing asks for credentials. That is what\n // lets a bundled client run on a customer's own page — every send from there is\n // cross-origin, and an Authorization header or a JSON type preflights the POST\n // for an origin that cannot pass one. A JWT is first-party by construction, so\n // it keeps the header and the session it travels with, and so does the error\n // plane, which names its own envelope type.\n const simple = opts.ingestKey !== undefined && opts.token === undefined && opts.contentType === undefined\n const headers: Record<string, string> = {\n 'Content-Type': simple ? BEACON_CONTENT_TYPE : (opts.contentType ?? 'application/json'),\n }\n // A signed-in page sends the key (which project) in the query AND the person's bearer\n // (who) in the header; the bearer never replaces the key.\n const bearer = simple ? undefined : (opts.token ?? opts.ingestKey)\n if (bearer) headers.Authorization = `Bearer ${bearer}`\n void fetch(opts.ingestKey ? appendQuery(url, 'ingest_key', opts.ingestKey) : url, {\n method: 'POST',\n headers,\n body,\n keepalive: true,\n credentials: simple ? 'omit' : 'include',\n })\n .then((res) => {\n // Telemetry loss never throws into the app — but silence is how this\n // client lost the fleet's errors in the first place. Under `debug`, say\n // so. A rejected ingest (the CORS allowlist 403s non-production origins,\n // so local dev NEVER reports) is otherwise indistinguishable from success.\n if (!res.ok && opts.debug) {\n console.warn('[event] ingest rejected', res.status, url.split('?')[0])\n }\n })\n .catch((e: unknown) => {\n if (opts.debug) console.warn('[event] ingest failed', url.split('?')[0], e)\n })\n }\n}\n\nexport class Analytics {\n private cfg: Required<\n Pick<AnalyticsConfig, 'product' | 'batchSize' | 'flushIntervalMs' | 'enabled' | 'captureErrors'>\n > &\n AnalyticsConfig\n private transport: Transport\n private queue: WireEvent[] = []\n private timer: ReturnType<typeof setTimeout> | null = null\n private personId?: string\n private attribution: Attribution = { utm: {} }\n private cohort: Cohort = {}\n private started = false\n /** The view pageview() last counted — path + location. */\n private counted?: string\n /** Guards against an error thrown *inside* the error path re-entering it. */\n private reentrant = false\n\n constructor(config: AnalyticsConfig) {\n this.cfg = {\n host: DEFAULT_HOST,\n batchSize: 20,\n flushIntervalMs: 5000,\n enabled: true,\n captureErrors: true,\n ...config,\n // The publishable key resolves from ONE live source, never a literal baked\n // beside the code. Most specific first:\n // 1. an explicit `ingestKey` in config;\n // 2. NEXT_PUBLIC_PUBLISHABLE_KEY, the inlined build-time env the fleet\n // carries end to end — KMS `deploy/PUBLISHABLE_KEY` -> the PUBLISHABLE_KEY\n // build-arg -> the NEXT_PUBLIC_ prefix Next inlines.\n //\n // 3. the org that owns the HOST this page is served from (`org.ts`).\n //\n // Step 3 fires only when a surface configured NOTHING, so it never overrides\n // the KMS chain above — it replaces going dark with reporting to the right\n // brand. That is what a static export needs: `output: export` inlines no env,\n // so before this the only way to report was to commit a key literal, and the\n // fleet grew one copy per site of a value with a single source.\n //\n // A surface no brand claims still has no key, and the edge REFUSES an\n // unattributed event (401 `ingest_key_required`) — the reserved `$public`\n // tenant that once caught keyless beacons is retired, and anonymous ingest is\n // refused at every edge on every brand host. So there is no quiet fallback to\n // rely on: an event lands in the org a credential names, or it does not land.\n ingestKey:\n config.ingestKey ?? readEnv('NEXT_PUBLIC_PUBLISHABLE_KEY') ?? keyForPage(),\n }\n this.transport = config.transport ?? new DefaultTransport()\n }\n\n /** adopt gives this client a credential it does not have. The key belongs to\n * the stream, not to whichever caller happened to ask for the handle first,\n * so a later caller carrying one hands it over. Present fields are never overwritten: the first caller's key stays. */\n adopt(config: AnalyticsConfig): void {\n if (config.ingestKey && !this.cfg.ingestKey) this.cfg.ingestKey = config.ingestKey\n if (config.getToken && !this.cfg.getToken) this.cfg.getToken = config.getToken\n }\n\n /** init is idempotent and browser-only for its side effects: capture first-touch\n * attribution, hydrate cohort, register the unload flush, and (unless opted out)\n * auto-capture unhandled errors. Safe to call from a React effect on every\n * render. */\n init(): void {\n if (this.started || !this.cfg.enabled) return\n this.started = true\n if (!isBrowser()) return\n\n // A link from another Hanzo host carries the visitor with it. Adopt it FIRST, so\n // the first pageview is already the same person, session and first touch.\n const linked = readLink(window.location.search)\n if (linked.anonId) adoptAnonId(linked.anonId)\n if (linked.sessionId) adoptSession(linked.sessionId)\n const clean = stripLink(window.location.href)\n if (clean !== undefined) {\n try {\n window.history.replaceState(window.history.state, '', clean)\n } catch {\n /* a sandboxed frame may refuse; the params are then simply visible */\n }\n }\n\n const parsed = parseAttribution(window.location.search, document.referrer)\n // The first touch the link carries is the visit's real origin. Without it this\n // host's own \"first touch\" would be the referring Hanzo page, which says nothing.\n const first = linked.firstTouch && !getFirstTouch() ? setFirstTouchOnce(linked.firstTouch) : undefined\n this.attribution =\n first ?? (hasAttribution(parsed) ? setFirstTouchOnce(parsed) : getFirstTouch() ?? parsed)\n this.cohort = mergeCohort({\n channel: this.attribution.channel ?? deriveChannel(this.attribution),\n refCode: this.attribution.refCode,\n })\n\n const flushHidden = () => {\n if (document.visibilityState === 'hidden') this.flush(true)\n }\n window.addEventListener('visibilitychange', flushHidden)\n window.addEventListener('pagehide', () => this.flush(true))\n\n // Unhandled errors and rejected promises are reported as type:'error' events.\n if (this.cfg.captureErrors) {\n window.addEventListener('error', (e: ErrorEvent) => {\n this.captureError(e.error ?? e.message, { handled: false })\n })\n window.addEventListener('unhandledrejection', (e: PromiseRejectionEvent) => {\n this.captureError(e.reason, { handled: false })\n })\n }\n }\n\n /** link returns `url` carrying this visitor's anonymous id, session and first\n * touch when the destination is a Hanzo-owned host, so the journey continues\n * across the hop. Any other URL comes back unchanged. */\n link(url: string): string {\n if (!isBrowser()) return url\n if (!this.started) this.init()\n return linkUrl(\n url,\n { anonId: anonId(), sessionId: sessionId(), firstTouch: this.attribution },\n window.location.hostname,\n window.location.href,\n )\n }\n\n /** authorize decorates an OAuth authorize URL for the redirect to IAM and flushes\n * what is queued, because the page is about to unload. Assign the result to\n * `location`. */\n authorize(url: string): string {\n const out = this.link(url)\n this.flush(true)\n return out\n }\n\n /** identify binds the current visitor to a stable person id (post-login). */\n identify(personId: string, traits?: Record<string, unknown>): void {\n this.personId = personId\n this.enqueue('identify', undefined, { properties: traits })\n }\n\n /** group associates the visitor with an org/team (analytics grouping, not the\n * server tenant — the server still derives tenant from the session). */\n group(groupId: string, traits?: Record<string, unknown>): void {\n this.enqueue('group', undefined, { groupId, properties: traits })\n }\n\n /** pageview records a $pageview for the current (or given) location, once per\n * view. A view is the path plus the full location, so a query or hash change\n * is a new one and a repeat call for the same place is not. */\n pageview(path?: string, properties?: Record<string, unknown>): void {\n // No `url` here: build() reads window.location.href for every event, in the\n // same tick, so this recomputed it to the identical value. Only `path` is\n // passed, because a route change fires before window.location has caught up\n // and the caller's value has to win.\n const p = path ?? (isBrowser() ? window.location.pathname : undefined)\n // Counting a page once is the client's rule, not each caller's. A page holds\n // several emitters that each correctly believe they count the first view —\n // the provider's autoPageview, a router hook, a nav autocapture — and per\n // emitter state cannot see the others. On the stream they are one page.\n const view = (p ?? '') + '\\0' + (isBrowser() ? window.location.href : '')\n if (view === this.counted) return\n this.counted = view\n this.enqueue('pageview', PAGEVIEW, { path: p, properties: { ...viewport(), ...properties } })\n }\n\n /** capture records a named product event with optional properties. Commerce\n * fields (productId/quantity/revenue/currency) may be passed for order events. */\n capture(\n event: string,\n properties?: Record<string, unknown>,\n commerce?: Pick<WireEvent, 'productId' | 'quantity' | 'revenue' | 'currency'>,\n ): void {\n this.enqueue('event', event, { properties, ...commerce })\n }\n\n /** captureError reports a caught error, an unhandled rejection, a React render\n * error, or a manual report as ONE event of type 'error' on the one stream.\n * It carries the exception (type, message, frames, stack, handled) and the\n * release, environment, site, product and level that group and scope it, and\n * flushes promptly (a crash may unload the page moments later). Never throws\n * back into the app. */\n captureError(err: unknown, context?: CaptureErrorOptions): void {\n // A failure inside the error path must not recurse through the global handlers.\n if (this.reentrant) return\n this.reentrant = true\n try {\n const handled = context?.handled ?? true\n const ex = normalizeError(err)\n ex.handled = handled\n this.enqueue('error', undefined, {\n error: ex,\n level: context?.level ?? (handled ? 'error' : 'fatal'),\n release: this.cfg.release ?? readEnv('NEXT_PUBLIC_HANZO_RELEASE'),\n environment: this.cfg.environment ?? readEnv('NODE_ENV'),\n site: isBrowser() ? window.location.hostname : undefined,\n properties: context?.properties,\n })\n this.flush()\n } catch {\n /* the error path never takes the app down */\n } finally {\n this.reentrant = false\n }\n }\n\n /** setCohort persists cohort dimensions (e.g. signupWeek at signup) so they ride\n * every subsequent event. */\n setCohort(patch: Cohort): void {\n this.cohort = mergeCohort(patch)\n }\n\n /** flush drains the buffer to the server as ONE batch through the ONE ingest\n * endpoint POST /v1/event, body { batch: [Event…] }. beacon=true selects the\n * unload-safe transport. Auth is orthogonal to the wire:\n *\n * • publishable key set → rides ?ingest_key=pk-… on both sends, keeping each\n * a CORS-simple request that any origin may send.\n * • else a bearer JWT rides Authorization (fetch only — sendBeacon cannot\n * carry a header, so token apps fall back to keepalive fetch on unload).\n * • else a cookie app rides same-origin credentials (beacon carries the\n * cookie fine).\n */\n flush(beacon = false): void {\n if (!this.cfg.enabled || this.queue.length === 0) return\n const batch = this.queue\n this.queue = []\n this.clearTimer()\n\n // Two kinds of credential, and both ride when both are held: the publishable key\n // names the project, the bearer names the person. The bearer never replaces the key.\n const token = this.cfg.getToken?.() ?? undefined\n const key = this.cfg.ingestKey?.trim() || undefined\n // Only a bearer JWT blocks the beacon: sendBeacon cannot set an Authorization\n // header. A pk- rides ?ingest_key; a cookie rides credentials.\n const useBeacon = beacon && !token\n const body = serializeBatch(batch)\n if (body === null) {\n if (this.cfg.debug) console.debug('[event] flush → dropped, batch unserializable')\n return\n }\n if (this.cfg.debug) console.debug('[event] flush →', EVENT_PATH, batch.length)\n this.transport.send(this.cfg.host + EVENT_PATH, body, {\n beacon: useBeacon,\n token,\n ingestKey: key,\n debug: this.cfg.debug,\n })\n }\n\n // ── internals ────────────────────────────────────────────────────────────\n\n private enqueue(kind: EventKind, event: string | undefined, extra: Partial<WireEvent>): void {\n if (!this.cfg.enabled) return\n if (!this.started) this.init()\n this.queue.push(this.build(kind, event, extra))\n if (this.queue.length >= this.cfg.batchSize) this.flush()\n else this.schedule()\n }\n\n private build(kind: EventKind, event: string | undefined, extra: Partial<WireEvent>): WireEvent {\n const anon = anonId()\n const wire: WireEvent = {\n messageId: uuidv7(),\n type: kind,\n event,\n timestamp: new Date().toISOString(),\n distinctId: this.personId ?? anon,\n anonymousId: anon,\n personId: this.personId,\n sessionId: sessionId(),\n product: this.cfg.product,\n referrer: this.attribution.referrer,\n utm: this.attribution.utm,\n refCode: this.cohort.refCode ?? this.attribution.refCode,\n channel: this.cohort.channel ?? this.attribution.channel,\n signupWeek: this.cohort.signupWeek,\n // Where the event happened, stamped for every kind rather than only for\n // pageviews. An interaction is reported against the page it happened on,\n // and autocapture ($click/$input/$change) reaches the wire through\n // capture(), which supplies no location — so every click arrived with an\n // empty url and path, and `host`, derived from url, was empty with them.\n // That is unattributable to a page, which is the one thing a heatmap\n // needs. Read here, at the single point every event is built, so it\n // cannot go missing from a call site again.\n //\n // Before `...extra`: pageview() passes an explicit path for route\n // changes that fire before window.location has caught up, and that value\n // has to win over the one read here.\n url: isBrowser() ? window.location.href : undefined,\n path: isBrowser() ? window.location.pathname : undefined,\n library: '@hanzo/event',\n libraryVersion: VERSION,\n ...extra,\n }\n\n // A location is free text an attacker (or an ordinary product flow) controls,\n // and it is now stamped on EVERY event rather than only pageviews — so the\n // one field that is always a URL gets the same policy the error plane has\n // always applied to error text. A password-reset, invite or magic link puts\n // a JWT in the query and an address in `?email=`; without this, one click on\n // that page ships both to the warehouse in cleartext, and every later click\n // repeats it.\n //\n // AFTER `...extra`, deliberately. A call site can pass its own location —\n // pageview() passes `path`, and until this commit it passed `url` too — and\n // `extra` merges over the fields read above, so scrubbing at the read would\n // have left the highest-volume event emitting a raw location while looking\n // scrubbed. Applied to the ASSEMBLED record, the guarantee holds for every\n // call site, including ones not written yet.\n //\n // `scrubText` is the SAME policy as the error plane (secrets always,\n // PII unless capturePII) rather than a second URL-specific redactor: one\n // definition of \"must not leave the browser\", already tested, mirroring the\n // server's. Guarded on presence so an absent field stays absent instead of\n // becoming the empty string that `host` derivation reads as a page.\n //\n // The fragment goes first and whole: nothing after `#` is ever the server's\n // (see withoutFragment), so it is dropped rather than scrubbed.\n const capturePII = this.cfg.capturePII ?? false\n if (wire.url) wire.url = scrubText(withoutFragment(wire.url), capturePII)\n if (wire.path) wire.path = scrubText(withoutFragment(wire.path), capturePII)\n if (wire.referrer) wire.referrer = scrubText(withoutFragment(wire.referrer), capturePII)\n return wire\n }\n\n private schedule(): void {\n if (this.timer || !this.cfg.enabled) return\n this.timer = setTimeout(() => {\n this.timer = null\n this.flush()\n }, this.cfg.flushIntervalMs)\n }\n\n private clearTimer(): void {\n if (this.timer) {\n clearTimeout(this.timer)\n this.timer = null\n }\n }\n}\n\n// ── one stream, one client ──────────────────────────────────────────────────\n//\n// A page has ONE event stream per (host, product): one queue, one anon id, one\n// credential. Two clients on it split the batch and double the pageview, and\n// the half built by the caller that had no key is refused at the edge — so the\n// same page is both over- and under-counted, and neither number says so.\n//\n// Two callers ask for that stream on any real page and both are right to: the\n// app mounts a provider, and the component library mounts its own telemetry.\n// Neither can see the other, so the fix cannot live in either. It lives here,\n// where the stream is: asking twice returns the same client.\n//\n// The registry is on the PAGE, under a `Symbol.for` slot, not in module scope.\n// `@hanzo/event` and `@hanzo/event/react` are separate bundles that each carry\n// a copy of this module, so a module-scope map is per-copy and the two copies\n// never see each other's — which is exactly how the duplicate arises. A\n// well-known symbol is the one slot every copy resolves to the same value.\n//\n// Browser only. A server process serves many visitors, and one client shared\n// across requests would carry one visitor's personId into the next.\nconst CLIENTS = Symbol.for('hanzo.event.clients')\n\nfunction registry(): Map<string, Analytics> {\n const g = globalThis as unknown as Record<symbol, Map<string, Analytics> | undefined>\n const existing = g[CLIENTS]\n if (existing) return existing\n const fresh = new Map<string, Analytics>()\n g[CLIENTS] = fresh\n return fresh\n}\n\n/** resetClients drops the page's clients, so the next `createAnalytics` for a\n * stream builds a fresh one.\n *\n * A real page loads once and never needs this. A TEST RUNNER is what it exists\n * for: one document, many mounts, each meant to be its own page. The second one\n * gets a client that already counted this location, so its pageview is\n * correctly suppressed and the suite reads it as \"nothing was emitted\".\n *\n * It is exported so a suite calls this instead of reaching for the slot itself.\n * A consumer that deletes the registry from its own code path takes the\n * guarantee with it: `<Provider/>` unmount/remount is not a new page, and the\n * fresh client it would get counts the same view again. */\nexport function resetClients(): void {\n const g = globalThis as unknown as Record<symbol, Map<string, Analytics> | undefined>\n delete g[CLIENTS]\n}\n\n/** createAnalytics returns the client for a stream, building it on first ask.\n * This is the ONE way to get a client: `new Analytics` bypasses the registry\n * and is for tests and for a deliberately separate instance. */\nexport function createAnalytics(config: AnalyticsConfig): Analytics {\n // A disabled client emits nothing, so it can double nothing and does not take\n // the stream. Callers reach their answer at different moments — a provider\n // whose ownership resolves in an effect renders once saying `false` before it\n // has decided anything — and the client built in that moment must not become\n // the one the page keeps. Registering it would silence the page, and adopting\n // `enabled` from a later caller would let one surface overrule another's\n // reading of consent. Neither: it is simply not the stream's client.\n if (!isBrowser() || config.enabled === false) return new Analytics(config)\n const key = (config.host ?? DEFAULT_HOST) + '\\0' + config.product\n const clients = registry()\n const existing = clients.get(key)\n if (existing) {\n existing.adopt(config)\n return existing\n }\n const fresh = new Analytics(config)\n clients.set(key, fresh)\n return fresh\n}\n\n// Re-export the hydrate helpers so consumers can read persisted cohort/attribution\n// (e.g. to send refCode to the referrals API) without reaching into storage.\nexport { getCohort, getFirstTouch }\n","// The `$exception` product-event shape — pure builders, no I/O.\n//\n// An exception reaches TWO destinations, and they read different shapes:\n//\n// 1. The ERROR PLANE — a Sentry envelope to the DSN host (sentry.ts). Untouched\n// by this module.\n// 2. ERROR TRACKING in Hanzo Insights — reads the PRODUCT-EVENT plane\n// (`insights.events WHERE event = '$exception'`) and expects the PostHog\n// exception vocabulary: `$exception_list` plus the denormalized `$exception_*`\n// properties. This module builds that.\n//\n// WHY THE FULLY-DERIVED SHAPE. Upstream, a server stage (Cymbal) symbolicates\n// frames and computes `$exception_fingerprint`, `$exception_types`, `_values`,\n// `_sources`, `_functions`, then REPLACES the property bag. That stage is not in\n// Hanzo's path: the ingest endpoint writes `event.fact` and a materialized view projects it\n// into `insights.events`, so nothing between the client and the warehouse derives\n// anything. Whatever the product reads, the client has to have sent. Two\n// consequences are load-bearing rather than cosmetic:\n//\n// • The issue query drops any event whose `$exception_fingerprint` is null, so an\n// event without one is invisible no matter how well-formed the rest is.\n// • `stacktrace.type` must be the literal 'resolved'; on any other value the\n// renderer falls through both match arms and draws nothing under the header.\n//\n// If that server stage is ever put in front of this plane it replaces these\n// properties wholesale, so sending them stays correct either way.\n//\n// FRAME ORDER is bottom-up: frames[0] is the entry point and the LAST frame is the\n// throw site. framesFromStack (sentry.ts) already returns that order, which is why\n// this module reuses it rather than re-parsing.\n\nimport { framesFromStack, normalizeError } from './throwable'\nimport type {\n ExceptionEntry,\n ExceptionFrame,\n ExceptionProperties,\n SentryFrame,\n SentryLevel,\n} from './types'\n\n/** Cap on the frames carried per exception, matching the Sentry path's budget. */\nconst MAX_FRAMES = 50\n/** Cap on `value`, so one enormous message cannot dominate a batch. The product\n * truncates for display anyway; this bounds the wire. */\nconst MAX_VALUE = 4096\n\n/**\n * digest is a stable 32-hex-char (128-bit) content hash, computed synchronously.\n *\n * Grouping keys are needed on the capture path, which is synchronous and may be\n * running inside an unload handler — SubtleCrypto is async and unavailable on\n * insecure origins, so it cannot be used here. This is FNV-1a run over four seeds\n * and concatenated. It is a GROUPING key, never a security boundary: it is not\n * collision-resistant against a chosen-input adversary, and nothing authorizes or\n * authenticates on it. The product treats the value as opaque.\n */\nexport function digest(s: string): string {\n let out = ''\n for (const seed of [0x811c9dc5, 0x01000193, 0x9e3779b9, 0x85ebca6b]) {\n let h = seed >>> 0\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i)\n // FNV prime 16777619, via shifts to stay in 32-bit integer math.\n h = (h + (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24)) >>> 0\n }\n out += h.toString(16).padStart(8, '0')\n }\n return out\n}\n\n/**\n * frameOf converts one parsed stack frame into the shape the product renders.\n *\n * The product's frame vocabulary is the POST-symbolication one (`mangled_name`,\n * `source`, `line`, `column`), so that is what is emitted. `resolved` is false and\n * honest: a browser bundle is minified and no symbol set has been uploaded, so the\n * original name and line are genuinely unknown. Claiming `resolved: true` would\n * trade an accurate \"upload your symbol sets\" hint for a misleading \"source code is\n * not available\" error.\n */\nfunction frameOf(f: SentryFrame): ExceptionFrame {\n const source = f.filename ?? ''\n const name = f.function ?? '<anonymous>'\n const line = f.lineno ?? 0\n const column = f.colno ?? 0\n return {\n // Stable per code location, so the same frame groups and re-renders under one\n // key. The '/part' suffix is the product's format for one raw frame expanding\n // into several resolved ones; a browser frame is always part 0.\n raw_id: `${digest(`${source}|${name}|${line}|${column}`)}/0`,\n mangled_name: name,\n source,\n line,\n column,\n in_app: f.in_app ?? false,\n lang: 'javascript',\n resolved: false,\n resolve_failure: 'no symbol set uploaded for this release',\n resolved_name: null,\n module: null,\n }\n}\n\n/** truncate bounds a free-text field without splitting a surrogate pair. */\nfunction truncate(s: string, max: number): string {\n if (s.length <= max) return s\n let end = max\n const c = s.charCodeAt(end - 1)\n // A high surrogate at the cut point would leave a lone half.\n if (c >= 0xd800 && c <= 0xdbff) end--\n return s.slice(0, end)\n}\n\n/**\n * exceptionEntry builds the single `$exception_list` entry for a throwable.\n *\n * One entry, not a chain: `Error.cause` chaining is a distinct fact with its own\n * ordering rules, and emitting it wrongly is worse than not emitting it.\n */\nexport function exceptionEntry(\n err: unknown,\n opts: { handled: boolean; id: string },\n): ExceptionEntry {\n const n = normalizeError(err)\n const frames = framesFromStack(n.stack).slice(-MAX_FRAMES)\n const entry: ExceptionEntry = {\n id: opts.id,\n type: n.name,\n value: truncate(n.message, MAX_VALUE),\n mechanism: {\n type: 'generic',\n handled: opts.handled,\n // An exception the app reported by hand was constructed, not thrown by the\n // runtime at a real call site.\n synthetic: !(err instanceof Error),\n },\n }\n if (frames.length > 0) {\n // 'resolved' names the SHAPE of the frame list, not the symbolication state of\n // any frame — the renderer only walks frames on this exact value.\n entry.stacktrace = { type: 'resolved', frames: frames.map(frameOf) }\n }\n return entry\n}\n\n/**\n * fingerprint is the issue grouping key.\n *\n * Keyed on exception type plus each in-app frame's function and source — the same\n * pieces the server-side grouper records (\"Exception Type\", \"Resolved function\n * name\", \"Source file name\"). Deliberately NOT the message: `Loading chunk 3324\n * failed` and `Loading chunk 998 failed` are one bug, and grouping on message is\n * precisely the mistake that made every distinct error string its own event name.\n *\n * Falls back to the type alone when no in-app frame survived, which keeps\n * stackless errors (`Script error.`, cross-origin) in one issue instead of\n * scattering them.\n */\nexport function fingerprint(entry: ExceptionEntry): string {\n const frames = entry.stacktrace?.frames ?? []\n const pieces = frames\n .filter((f) => f.in_app)\n .map((f) => `${f.mangled_name}@${f.source}`)\n return digest([entry.type, ...pieces].join('\\n'))\n}\n\n/**\n * exceptionProperties builds the full `$exception_*` property bag for one captured\n * throwable — everything Error Tracking reads off the event.\n *\n * The denormalized arrays are ordered like `frames`: last element is the throw\n * site, which is the element the issue list indexes at -1 for its source/function\n * columns.\n */\nexport function exceptionProperties(\n err: unknown,\n opts: { handled: boolean; id: string; level?: SentryLevel },\n): ExceptionProperties {\n const entry = exceptionEntry(err, opts)\n const frames = entry.stacktrace?.frames ?? []\n const fp = fingerprint(entry)\n return {\n $exception_list: [entry],\n $exception_fingerprint: fp,\n // Records WHY this fingerprint holds. 'manual' is the honest value: the client\n // supplied the key rather than a server grouper deriving one.\n $exception_fingerprint_record: [{ type: 'manual' }],\n $exception_type: entry.type,\n $exception_message: entry.value,\n $exception_level: opts.level ?? 'error',\n $exception_handled: opts.handled,\n $exception_synthetic: entry.mechanism?.synthetic ?? false,\n $exception_types: [entry.type],\n $exception_values: [entry.value],\n $exception_sources: frames.map((f) => f.source).filter((s): s is string => !!s),\n $exception_functions: frames\n .map((f) => f.resolved_name ?? f.mangled_name)\n .filter((s): s is string => !!s),\n }\n}\n","// First-party cookies for consent, the ad click and the browser ids the ad\n// platforms match on. Set on the registrable domain so every subdomain of a site\n// reads the same choice and the same click; on localhost or an address it stays\n// on the host.\n\nconst DAY = 86_400\n\n/** The domain attribute for this host, or '' to keep the cookie on the host. */\nfunction domain(): string {\n const h = window.location.hostname\n if (h === 'localhost' || /^[\\d.]+$/.test(h) || h.includes(':')) return ''\n const parts = h.split('.')\n return parts.length > 2 ? `; Domain=.${parts.slice(-2).join('.')}` : `; Domain=.${h}`\n}\n\n/** Reads one cookie, or undefined. */\nexport function get(name: string): string | undefined {\n if (typeof document === 'undefined') return undefined\n const hit = document.cookie.split('; ').find((c) => c.startsWith(`${name}=`))\n return hit ? decodeURIComponent(hit.slice(name.length + 1)) : undefined\n}\n\n/** Writes one cookie for `days`. */\nexport function set(name: string, value: string, days: number): void {\n if (typeof document === 'undefined') return\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${name}=${encodeURIComponent(value)}; Max-Age=${days * DAY}; Path=/; SameSite=Lax${domain()}${secure}`\n}\n","// Cookie consent: what a visitor lets a site measure and share, and the rule for\n// what a visitor who has not chosen is presumed to allow.\n//\n// Three categories. Analytics is our own stream and GA4. Marketing is the ad\n// platforms measuring the conversions they bought (Google Ads, Meta, LinkedIn,\n// X, TikTok) and every server-side send. Ads is those platforms using the visit\n// for audiences; off, Google's ad_personalization is denied and Meta runs under\n// Limited Data Use.\n//\n// THE DEFAULT depends on where the visitor is. In the EU, UK and Switzerland,\n// and anywhere else that is not a US state, nothing is allowed until they say\n// so: a visitor with no stored choice has allowed nothing. In the US the default\n// is on and the choice is an opt-out (\"Do not sell or share my personal\n// information\"). Global Privacy Control, and Do Not Track, turn marketing and\n// ads off in every region whatever is stored: California reads GPC as the opt-out\n// of sale and sharing.\n//\n// There is no geo lookup. The page cannot ask a server where the visitor is, so\n// the zone is the browser's own time zone, and a zone that is not a US zone is\n// treated as opt-in. Wrong in the safe direction: a US visitor on a foreign\n// clock is asked, and a European is never presumed to have agreed.\n//\n// The choice is a first-party cookie, `hz_consent`, on the registrable domain\n// for 13 months: the granted categories, comma separated. cloud reads the same\n// string off each event's `consent` property.\n\nimport { get, set } from './cookie'\n\nexport const CONSENT_COOKIE = 'hz_consent'\n\n/** Fired on `window` whenever a choice is stored. */\nexport const CONSENT_EVENT = 'hzconsent'\n\nexport interface Choice {\n analytics: boolean\n marketing: boolean\n ads: boolean\n}\n\nexport type Region = 'opt-in' | 'opt-out'\n\ntype Nav = { doNotTrack?: string; msDoNotTrack?: string; globalPrivacyControl?: boolean }\n\nconst US =\n /^(America\\/(New_York|Chicago|Denver|Los_Angeles|Phoenix|Anchorage|Adak|Boise|Detroit|Juneau|Sitka|Nome|Yakutat|Menominee|Metlakatla|Indiana\\/.*|Kentucky\\/.*|North_Dakota\\/.*)|Pacific\\/Honolulu|US\\/.*)$/\n\n/** Whether the browser sends Global Privacy Control. */\nexport function gpc(): boolean {\n if (typeof navigator === 'undefined') return false\n return (navigator as unknown as Nav).globalPrivacyControl === true\n}\n\n/** Whether the browser sends Global Privacy Control or Do Not Track. */\nexport function refused(): boolean {\n if (typeof window === 'undefined') return false\n const n = navigator as unknown as Nav\n const dnt = n.doNotTrack ?? (window as unknown as Nav).doNotTrack ?? n.msDoNotTrack\n return gpc() || dnt === '1' || dnt === 'yes'\n}\n\n/** Which rule applies to this visitor. */\nexport function region(): Region {\n try {\n const zone = Intl.DateTimeFormat().resolvedOptions().timeZone ?? ''\n return US.test(zone) ? 'opt-out' : 'opt-in'\n } catch {\n return 'opt-in'\n }\n}\n\n/** Whether the visitor has stored a choice. */\nexport function stored(): boolean {\n return get(CONSENT_COOKIE) !== undefined\n}\n\n/** The visitor's choice: the stored one, else the regional default, with GPC applied. */\nexport function read(): Choice {\n const kept = get(CONSENT_COOKIE)\n const on =\n kept !== undefined\n ? kept.split(',')\n : region() === 'opt-in' || refused()\n ? []\n : ['analytics', 'marketing', 'ads']\n const has = (k: string) => on.includes(k)\n return { analytics: has('analytics'), marketing: has('marketing') && !gpc(), ads: has('ads') && !gpc() }\n}\n\n/** Whether the consent banner must be shown: an opt-in visitor who has not chosen. */\nexport function asks(): boolean {\n return typeof document !== 'undefined' && region() === 'opt-in' && !stored()\n}\n\n/** The choice as the `consent` property and the cookie spell it. */\nexport function render(c: Choice): string {\n return (['analytics', 'marketing', 'ads'] as const).filter((k) => c[k]).join(',')\n}\n\n/**\n * Stores a choice and tells the page. The tags react without a reload: a\n * category just allowed loads its libraries, and Google's consent state is\n * updated. An ad library already running cannot be unloaded, so a choice that\n * withdraws marketing takes effect for what has not loaded yet and for every\n * later page.\n */\nexport function save(c: Choice): void {\n const out: Choice = { analytics: c.analytics, marketing: c.marketing && !gpc(), ads: c.ads && !gpc() }\n set(CONSENT_COOKIE, render(out), 395)\n if (typeof window !== 'undefined') window.dispatchEvent(new Event(CONSENT_EVENT))\n}\n\n/** Accept every category. */\nexport const acceptAll = (): void => save({ analytics: true, marketing: true, ads: true })\n\n/** Refuse every optional category. */\nexport const rejectAll = (): void => save({ analytics: false, marketing: false, ads: false })\n","// The ad click a visitor arrived on, kept first-party so a conversion days later\n// is credited to it even when the ad tags never loaded.\n//\n// On every page load the click ids in the address are read: gclid, gbraid and\n// wbraid (Google), fbclid (Meta), li_fat_id (LinkedIn), twclid (X), ttclid\n// (TikTok). When any is there the whole set replaces the last one in `hz_touch`\n// with the time it was captured: the last click is the one credited. It is kept\n// 90 days, the lookback cloud applies before it offers a click to a platform\n// (apps/destination/touch.go).\n//\n// Beside it are the browser ids the platforms match on. `_fbc` is Meta's click\n// cookie, built from fbclid in the shape the Pixel would write it; `_fbp` is its\n// browser id. `cid` is GA4's client id: the last two fields of `_ga`, or a\n// first-party `hz_cid` of the same shape when gtag.js never ran.\n//\n// Nothing here runs without consent: the click and the Meta ids need Marketing,\n// the client id needs Analytics.\n\nimport type { Choice } from './consent'\nimport { get, set } from './cookie'\n\nexport const CLICK_IDS = ['gclid', 'gbraid', 'wbraid', 'fbclid', 'li_fat_id', 'twclid', 'ttclid'] as const\n\nconst DAYS = 90\nconst now = () => Math.floor(Date.now() / 1000)\nconst rand = () => Math.floor(Math.random() * 2 ** 31)\n\n/** Records this page's click and the browser ids. Call once per page load. */\nexport function capture(c: Choice): void {\n if (typeof window === 'undefined') return\n if (c.marketing) {\n const q = new URLSearchParams(window.location.search)\n const click: Record<string, string | number> = {}\n for (const k of CLICK_IDS) {\n const v = q.get(k)?.trim()\n if (v) click[k] = v\n }\n if (Object.keys(click).length) {\n click.clicked = now()\n set('hz_touch', JSON.stringify(click), DAYS)\n if (click.fbclid) set('_fbc', `fb.1.${Date.now()}.${click.fbclid}`, DAYS)\n }\n if (!get('_fbp')) set('_fbp', `fb.1.${Date.now()}.${rand()}`, DAYS)\n }\n if (c.analytics && !get('_ga') && !get('hz_cid')) set('hz_cid', `${rand()}.${now()}`, 730)\n}\n\n/** The properties an event carries for cloud to match it on. */\nexport function touch(c: Choice): Record<string, string | number> {\n const out: Record<string, string | number> = {}\n if (c.marketing) {\n try {\n Object.assign(out, JSON.parse(get('hz_touch') ?? '{}'))\n } catch {\n /* a cookie that does not parse names no click */\n }\n const fbc = get('_fbc')\n const fbp = get('_fbp')\n if (fbc) out.fbc = fbc\n if (fbp) out.fbp = fbp\n }\n if (c.analytics) {\n const ga = get('_ga')?.split('.')\n const cid = ga && ga.length >= 4 ? ga.slice(-2).join('.') : get('hz_cid')\n if (cid) out.cid = cid\n }\n return out\n}\n","// The tag manager: loads each ad and analytics platform's browser pixel, after\n// consent, from the site's tag configuration, and fires every event to each one\n// under one event_id.\n//\n// WHERE THE IDS COME FROM. Never from a site's code. The site's tag set is\n// cloud's `GET /v1/project/tags` (non-secret ids only), so connecting a\n// platform to a site is a configuration change and every surface gets it:\n//\n// { tags: [{ platform: 'ga4', type: 'ga', id: 'G-…' },\n// { platform: 'linkedin', type: 'linkedin', id: '1234',\n// events: { order_completed: '9876' } }, …] }\n//\n// `events` maps one of OUR event names to the platform's own conversion id for\n// it: a Google Ads `AW-…/label`, a LinkedIn conversion rule, an X event id.\n// Google Ads, LinkedIn and X name conversions by rule, not by event, and an\n// event with no rule there is not sent to that platform.\n//\n// WHAT LOADS WHEN. Nothing loads before consent. Analytics allows GA4;\n// Marketing allows Google Ads, Meta, LinkedIn, X and TikTok. A visitor who has\n// not chosen has allowed what their region presumes (consent.ts), so an EU\n// visitor's page makes no request to any platform until they accept. Google's\n// Consent Mode v2 is set denied before gtag.js is fetched and updated on every\n// choice. A choice that allows more loads the rest with no reload.\n//\n// ONE EVENT ID. `track` mints it, fires the browser pixels with it, and records\n// it on our stream with the list of pixels that fired (`tags`). Cloud forwards\n// the same moment server-side under the same id, and each platform keeps one\n// (Meta and TikTok by event_id, GA4 by transaction_id on a purchase); it sends\n// GA4 only what the page's own gtag did not, which is what `tags` says.\n//\n// WHAT EACH PLATFORM CALLS AN EVENT is the one table in @hanzo/events; cloud\n// reads the same table.\n\nimport { namesOn } from '@hanzo/events'\nimport { CONSENT_EVENT, read, render, type Choice } from './consent'\nimport { capture, touch } from './touch'\nimport type { Analytics } from './core'\n\nexport interface BrowserTag {\n platform: string\n type: string\n id: string\n events?: Record<string, string>\n}\n\nexport interface TagOptions {\n /** The site's publishable key; resolves its tag set. */\n key?: string\n /** The site's host, for a site whose key is the org's. */\n host?: string\n /** cloud's origin; defaults to https://api.hanzo.ai. */\n base?: string\n /** Domains one visit crosses, so GA4 keeps it one session. */\n domains?: string[]\n}\n\n/**\n * The publishable key of each site's project, which is how cloud finds the site's\n * tag set. A `pk-` is public by design (it ships in every page); it names a site,\n * never a platform id. A host absent here has no tag config unless `start` is\n * given a key.\n */\nexport const SITE_KEY: Readonly<Record<string, string>> = Object.freeze({\n 'hanzo.ai': 'pk-CmfLA2K6kvsPflrS9DSkt06H_kSoQB_21sjedt6VJdc',\n 'www.hanzo.ai': 'pk-CmfLA2K6kvsPflrS9DSkt06H_kSoQB_21sjedt6VJdc',\n 'hanzo.app': 'pk-wlnXN2a9_vmCm60yTFtQ629Q8TyuaxBNZbY1RWT72gQ',\n 'hanzo.team': 'pk-NCzD2FiHpZv8KUpkCX4olT1LJOJsMxBC_Z8NkiQsOFQ',\n 'pay.hanzo.ai': 'pk-eX6kv7JZNoiYn1WkeJH3tT_8OvkVYScmCXnLMwxTKf8',\n 'platform.hanzo.ai': 'pk-My1RpZLEUnTj8vAdPbWKYdDUuhxZJ4dVjHcwjZN4rZ8',\n 'docs.hanzo.ai': 'pk-jukhtjMT2ymoeBDAeFjINQWlBv-v9sNn1TPztiCrrwk',\n 'hanzo.bot': 'pk-W5d7Mn7ZukT7igyscIy6Pqe8JpA0Ge604Yn4xNR4JCU',\n 'hanzo.chat': 'pk-ATxWeB2jNyRSxDgqnkGoDj3CCbzrmTxSktUh9zlrO-E',\n 'hanzo.id': 'pk-_GVF3KlaqprlPHDumBMRFeFU1lIGOaarQfgimNVDIo8',\n 'hanzo.industries': 'pk-Vh1wvL2HqIAv9qpVvmrznTI9uMHrTD-jyIC-vnlBsgY',\n 'hanzo.market': 'pk-DN3xQFa0H61epUVg9OkiOYLzCdteNt9hE6f-S-ednjQ',\n 'hanzo.network': 'pk-YJ2eiA_7ckLStMPte8Ar8FsmRp_ycmeIeRbpGprZYmM',\n 'cloud.hanzo.ai': 'pk-RAfEGHPoNdCEU9fnA_cPd_Xo9Tci44rlYQV9xuJ1Ob0',\n})\n\ntype Call = (...args: unknown[]) => void\ntype Page = {\n dataLayer?: unknown[]\n gtag?: Call\n fbq?: Call & { queue?: unknown[]; callMethod?: Call; push?: unknown; loaded?: boolean; version?: string }\n _fbq?: unknown\n lintrk?: Call & { q?: unknown[] }\n _linkedin_data_partner_ids?: string[]\n twq?: Call & { queue?: unknown[]; exe?: Call; version?: string }\n ttq?: Record<string, Call> & { _i?: Record<string, unknown>; _t?: Record<string, number>; _o?: Record<string, unknown>; methods?: string[]; load?: Call; page?: Call; track?: Call }\n TiktokAnalyticsObject?: string\n}\n\nconst page = (): Page => window as unknown as Page\n\nlet tags: BrowserTag[] = []\nlet configured = false\nlet options: TagOptions = {}\nconst loaded = new Set<string>()\n\n/** gtag.js: 'idle' until fetched, 'wait' while on its way, then how it answered. */\nlet google: 'idle' | 'wait' | 'loaded' | 'failed' = 'idle'\nlet configAnswered = false\n\nconst held: Array<() => void> = []\nlet leaving = false\n\nfunction settled(): boolean {\n return configAnswered && google !== 'wait'\n}\n\nfunction flush(): void {\n if (settled() || leaving) held.splice(0).forEach((send) => send())\n}\n\n/**\n * Resolves once every tag this visitor's choice loads has taken the page view, or after\n * `limit` ms, whichever is first: the tag set has answered, gtag.js has loaded or failed,\n * and Meta's library has replaced the stub that queued the call. A page that is about to\n * leave waits on this so the visit is counted where it arrived. A tag the choice does not\n * load is not waited for.\n */\nexport function ready(limit = 3000): Promise<void> {\n if (typeof window === 'undefined') return Promise.resolve()\n const start = Date.now()\n const meta = () => {\n const fbq = page().fbq\n return ![...loaded].some((k) => k.startsWith('meta:')) || typeof fbq?.callMethod === 'function'\n }\n return new Promise((resolve) => {\n const tick = () => {\n if ((configured && settled() && meta()) || Date.now() - start >= limit) return resolve()\n setTimeout(tick, 100)\n }\n tick()\n })\n}\n\nfunction script(src: string, onload?: () => void, onerror?: () => void): void {\n const s = document.createElement('script')\n s.async = true\n s.src = src\n if (onload) s.onload = onload\n if (onerror) s.onerror = onerror\n document.head.appendChild(s)\n}\n\n// ── Google ──────────────────────────────────────────────────────────────\n\nfunction gtagStub(): Call {\n const p = page()\n p.dataLayer = p.dataLayer || []\n if (!p.gtag) {\n // gtag.js reads the `arguments` object itself, so this is a function and not an arrow.\n p.gtag = function () {\n // eslint-disable-next-line prefer-rest-params\n p.dataLayer!.push(arguments)\n }\n }\n return p.gtag\n}\n\nconst g = (on: boolean) => (on ? 'granted' : 'denied')\n\n/** Google Consent Mode v2: denied until said otherwise, then the visitor's choice. */\nfunction consentMode(c: Choice, first: boolean): void {\n const gtag = gtagStub()\n const state = {\n analytics_storage: g(c.analytics),\n ad_storage: g(c.marketing),\n ad_user_data: g(c.marketing),\n ad_personalization: g(c.marketing && c.ads),\n }\n if (first) {\n gtag('consent', 'default', {\n analytics_storage: 'denied',\n ad_storage: 'denied',\n ad_user_data: 'denied',\n ad_personalization: 'denied',\n wait_for_update: 500,\n })\n }\n gtag('consent', 'update', state)\n}\n\nfunction loadGoogle(ids: string[]): void {\n const gtag = gtagStub()\n const fresh = ids.filter((id) => !loaded.has(id))\n if (!fresh.length) return\n if (google === 'idle') {\n google = 'wait'\n gtag('js', new Date())\n const done = (to: 'loaded' | 'failed') => () => {\n if (google !== 'wait') return\n google = to\n flush()\n }\n script(`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(fresh[0])}`, done('loaded'), done('failed'))\n // gtag.js answers once: loaded, failed (a blocker), or silent past 8 s.\n setTimeout(done('failed'), 8000)\n }\n for (const id of fresh) {\n loaded.add(id)\n gtag('config', id, options.domains ? { linker: { domains: options.domains } } : {})\n }\n}\n\n// ── The other pixels ────────────────────────────────────────────────────\n\nfunction loadMeta(id: string, c: Choice): void {\n const p = page()\n if (!p.fbq) {\n const n = (p.fbq = function (...a: unknown[]) {\n if (n.callMethod) n.callMethod(...a)\n else n.queue!.push(a)\n } as NonNullable<Page['fbq']>)\n if (!p._fbq) p._fbq = n\n n.push = n\n n.loaded = true\n n.version = '2.0'\n n.queue = []\n script('https://connect.facebook.net/en_US/fbevents.js')\n }\n if (!c.ads) p.fbq('dataProcessingOptions', ['LDU'], 0, 0)\n p.fbq('init', id)\n p.fbq('track', 'PageView')\n}\n\nfunction loadLinkedIn(id: string): void {\n const p = page()\n p._linkedin_data_partner_ids = p._linkedin_data_partner_ids || []\n p._linkedin_data_partner_ids.push(id)\n if (!p.lintrk) {\n const l = (p.lintrk = function (...a: unknown[]) {\n l.q!.push(a)\n } as NonNullable<Page['lintrk']>)\n l.q = []\n }\n script('https://snap.licdn.com/li.lms-analytics/insight.min.js')\n}\n\nfunction loadX(id: string): void {\n const p = page()\n if (!p.twq) {\n const s = (p.twq = function (...a: unknown[]) {\n if (s.exe) s.exe(...a)\n else s.queue!.push(a)\n } as NonNullable<Page['twq']>)\n s.version = '1.1'\n s.queue = []\n script('https://static.ads-twitter.com/uwt.js')\n }\n p.twq('config', id)\n}\n\nconst TIKTOK_METHODS = ['page', 'track', 'identify', 'instances', 'debug', 'on', 'off', 'once', 'ready', 'alias', 'group', 'enableCookie', 'disableCookie']\n\nfunction loadTikTok(id: string): void {\n const p = page()\n p.TiktokAnalyticsObject = 'ttq'\n const q = (p.ttq = p.ttq || ([] as unknown as NonNullable<Page['ttq']>)) as unknown as Record<string, unknown> & unknown[]\n if (!q._i) {\n q.methods = TIKTOK_METHODS\n for (const m of TIKTOK_METHODS) q[m] = (...a: unknown[]) => q.push([m, ...a])\n q._i = {}\n q._t = {}\n q._o = {}\n q.load = (sdk: string) => {\n ;(q._i as Record<string, unknown>)[sdk] = []\n ;(q._t as Record<string, number>)[sdk] = Date.now()\n script(`https://analytics.tiktok.com/i18n/pixel/events.js?sdkid=${encodeURIComponent(sdk)}&lib=ttq`)\n }\n }\n ;(q.load as Call)(id)\n ;(q.page as Call)()\n}\n\n// ── Which tag is allowed and running ────────────────────────────────────\n\nconst NEEDS: Record<string, keyof Choice> = {\n ga: 'analytics',\n gads: 'marketing',\n meta: 'marketing',\n linkedin: 'marketing',\n x: 'marketing',\n tiktok: 'marketing',\n}\n\n/** GA4 also counts a visit when only Marketing is allowed (Consent Mode keeps it cookieless). */\nconst allowed = (t: BrowserTag, c: Choice): boolean =>\n t.type === 'ga' ? c.analytics || c.marketing : Boolean(NEEDS[t.type] && c[NEEDS[t.type]])\n\nfunction apply(): void {\n if (typeof window === 'undefined' || !configured) return\n const c = read()\n capture(c)\n const on = tags.filter((t) => allowed(t, c))\n const ids = on.filter((t) => t.type === 'ga' || t.type === 'gads').map((t) => t.id)\n if (ids.length) {\n consentMode(c, !loaded.has('consent'))\n loaded.add('consent')\n loadGoogle(ids)\n }\n for (const t of on) {\n const k = `${t.type}:${t.id}`\n if (loaded.has(k)) continue\n if (t.type === 'meta') loadMeta(t.id, c)\n else if (t.type === 'linkedin') loadLinkedIn(t.id)\n else if (t.type === 'x') loadX(t.id)\n else if (t.type === 'tiktok') loadTikTok(t.id)\n else continue\n loaded.add(k)\n }\n flush()\n}\n\n/**\n * Starts the tag manager: fetches the site's tag set and loads what consent\n * allows, again on every consent change. Safe to call on every page load, and\n * a no-op on the server. Returns a function that stops listening.\n */\nexport function start(o: TagOptions = {}): () => void {\n if (typeof window === 'undefined') return () => undefined\n options = o\n addEventListener(CONSENT_EVENT, apply)\n addEventListener('pagehide', pagehide)\n if (!configured) {\n configured = true\n const base = (o.base ?? 'https://api.hanzo.ai').replace(/\\/$/, '')\n const q = new URLSearchParams()\n const host = o.host ?? window.location.hostname\n const key = o.key ?? SITE_KEY[host]\n if (key) q.set('key', key)\n q.set('host', host)\n const answer = (list: BrowserTag[]) => {\n tags = list\n configAnswered = true\n apply()\n }\n // A page never waits on its tag config: an unreachable cloud is an empty set.\n const cap = setTimeout(() => answer([]), 3000)\n fetch(`${base}/v1/project/tags?${q}`)\n .then((r) => (r.ok ? r.json() : { tags: [] }))\n .then((j: { tags?: BrowserTag[] }) => {\n clearTimeout(cap)\n answer(Array.isArray(j.tags) ? j.tags : [])\n })\n .catch(() => {\n clearTimeout(cap)\n answer([])\n })\n }\n return () => {\n removeEventListener(CONSENT_EVENT, apply)\n removeEventListener('pagehide', pagehide)\n }\n}\n\nfunction pagehide(): void {\n leaving = true\n flush()\n}\n\n/** The browser tags a moment can reach right now, as the `tags` property spells it. */\nexport function reach(): string {\n const c = read()\n const to: string[] = []\n for (const t of tags) {\n if (!allowed(t, c)) continue\n const running =\n t.type === 'ga'\n ? google === 'loaded' && c.analytics\n : t.type === 'gads'\n ? google === 'loaded' && c.marketing\n : loaded.has(`${t.type}:${t.id}`)\n if (running && !to.includes(t.type)) to.push(t.type)\n }\n return to.join(',')\n}\n\n// ── Firing an event ─────────────────────────────────────────────────────\n\ninterface Item {\n item_id: string\n item_name?: string\n item_category?: string\n item_variant?: string\n price?: number\n quantity?: number\n}\n\nconst META_STANDARD = new Set([\n 'AddPaymentInfo', 'AddToCart', 'AddToWishlist', 'CompleteRegistration', 'Contact', 'CustomizeProduct',\n 'Donate', 'FindLocation', 'InitiateCheckout', 'Lead', 'Purchase', 'Schedule', 'Search', 'StartTrial',\n 'SubmitApplication', 'Subscribe', 'ViewContent',\n])\n\nfunction shape(platform: 'meta' | 'tiktok' | 'x', p: Record<string, unknown>): Record<string, unknown> {\n const items = Array.isArray(p.items) ? (p.items as Item[]) : []\n const out: Record<string, unknown> = {}\n if (typeof p.value === 'number') out.value = p.value\n out.currency = typeof p.currency === 'string' ? p.currency : 'USD'\n if (!items.length) return out\n if (platform === 'meta') {\n out.content_type = 'product'\n out.content_ids = items.map((i) => i.item_id)\n out.contents = items.map((i) => ({ id: i.item_id, quantity: i.quantity ?? 1, item_price: i.price }))\n out.content_name = items[0].item_name\n out.num_items = items.reduce((n, i) => n + (i.quantity ?? 1), 0)\n } else if (platform === 'tiktok') {\n out.content_type = 'product'\n out.contents = items.map((i) => ({ content_id: i.item_id, content_name: i.item_name, quantity: i.quantity ?? 1, price: i.price }))\n } else {\n out.contents = items.map((i) => ({ content_id: i.item_id, content_name: i.item_name, content_price: i.price, num_items: i.quantity ?? 1 }))\n }\n return out\n}\n\n/** A test order states no amount: nothing sent for it can be summed into revenue. */\nfunction unpriced(p: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = { ...p, value: 0 }\n if (Array.isArray(p.items)) out.items = (p.items as Item[]).map((i) => ({ ...i, price: 0 }))\n return out\n}\n\n/**\n * Sends one moment to the browser tags named in `to`, under `id`. The names each\n * platform knows it by are the table in @hanzo/events; a platform the table\n * gives no name, or a rule-named platform with no rule for it, is not sent it.\n */\nexport function mirror(name: string, params: Record<string, unknown>, id: string, to = reach()): void {\n const p = page()\n const on = new Set(to.split(',').filter(Boolean))\n const ga4 = namesOn(name, 'ga4')\n const test = params.test === true\n if (test) params = unpriced(params)\n const transaction = typeof params.order_id === 'string' ? { transaction_id: params.order_id } : {}\n for (const t of tags) {\n if (!on.has(t.type)) continue\n const rule = t.events?.[name]\n if (t.type === 'ga') {\n for (const n of ga4) {\n p.gtag?.('event', n, { ...params, ...transaction, event_id: id, transport_type: 'beacon', ...(test ? { debug_mode: true } : {}) })\n }\n } else if (t.type === 'gads' && rule) {\n p.gtag?.('event', 'conversion', {\n send_to: rule,\n value: typeof params.value === 'number' ? params.value : undefined,\n currency: typeof params.currency === 'string' ? params.currency : 'USD',\n ...transaction,\n })\n } else if (t.type === 'meta') {\n for (const n of namesOn(name, 'meta')) {\n p.fbq?.(META_STANDARD.has(n) ? 'track' : 'trackCustom', n, shape('meta', params), { eventID: id })\n }\n } else if (t.type === 'tiktok') {\n for (const n of namesOn(name, 'tiktok')) p.ttq?.track?.(n, shape('tiktok', params), { event_id: id })\n } else if (t.type === 'linkedin' && rule && namesOn(name, 'linkedin').length) {\n p.lintrk?.('track', { conversion_id: Number(rule) })\n } else if (t.type === 'x' && rule && namesOn(name, 'x').length) {\n p.twq?.('event', rule, { ...shape('x', params), conversion_id: id })\n }\n }\n}\n\n/**\n * One moment, to every place it is counted, under one event_id: our stream\n * always hears it (with the consent, the click and the browser ids cloud\n * forwards on), and each browser tag that is running hears it too. A moment\n * that arrives while gtag.js is still on its way waits for it, so GA4 sees it\n * with a session; a page that is leaving sends what it holds as things stand.\n *\n * A paid order is stated by the SERVER on our stream (and forwarded server-side);\n * its browser copy is `track(stream, 'order_completed', {event_id: order, order_id:\n * order, …}, 'tags')`: the same id, the pixels only, so nothing counts twice.\n */\nexport function track(\n stream: Analytics | undefined,\n name: string,\n params: Record<string, unknown> = {},\n /** `'tags'` fires the browser pixels only: the server states this moment on our stream itself. */\n only?: 'tags',\n): void {\n if (typeof window === 'undefined') return\n if (!leaving && !settled()) {\n held.push(() => track(stream, name, params, only))\n return\n }\n const c = read()\n // A moment the server also states (a paid order) brings its own id, the order's,\n // so each platform sees the browser's copy and the server's as one.\n const event_id = typeof params.event_id === 'string' && params.event_id ? params.event_id : crypto.randomUUID()\n const to = reach()\n mirror(name, params, event_id, to)\n if (only === 'tags') return\n stream?.capture(name, {\n ...params,\n ...touch(c),\n event_id,\n consent: render(c),\n tags: to,\n userAgent: navigator.userAgent,\n url: window.location.href,\n })\n}\n\n/** What cloud needs to forward a moment a page states itself, as if the browser had sent it. */\nexport function visit(): Record<string, unknown> {\n const c = read()\n return { ...touch(c), consent: render(c), tags: reach(), userAgent: navigator.userAgent, url: window.location.href }\n}\n","// A plan as every ecommerce event names it: GA4's item shape, which the tag\n// manager hands Meta, TikTok and X, and which cloud's forwarder lifts from the\n// events the server states. One function, so a plan carries the same line from\n// the pricing page to the checkout to the order.\n//\n// `item_id` is the plan's id as the catalog spells it (free, dev, max, and the\n// team plans), `item_category` says who it is for, `item_variant` the term,\n// `price` the unit price for that term in US dollars and `quantity` the seats\n// (1 for an individual plan).\n\nexport interface CommerceItem {\n item_id: string\n item_name?: string\n item_category: 'individual' | 'team'\n item_variant: 'monthly' | 'annual'\n price: number\n quantity: number\n}\n\nexport interface PlanLine {\n id: string\n name?: string\n /** A team plan is sold per seat. */\n team?: boolean\n /** The term, as commerce (`month`, `year`) or the funnel (`monthly`, `annual`) says it. */\n interval: string\n price: number | null\n quantity?: number\n}\n\nexport function commerceItem(p: PlanLine): CommerceItem {\n const annual = /^(year|yearly|annual)$/i.test(p.interval)\n return {\n item_id: p.id,\n ...(p.name ? { item_name: p.name } : {}),\n item_category: p.team ? 'team' : 'individual',\n item_variant: annual ? 'annual' : 'monthly',\n price: p.price ?? 0,\n quantity: p.quantity ?? 1,\n }\n}\n\n/** What the whole order is worth: the unit price times the seats. */\nexport const worth = (i: CommerceItem): number => i.price * i.quantity\n","// Insights goals + cohorts, defined once as data so the console/insights UI and\n// every product agree on what \"a Signup\", \"a Sale\", and \"upgrade intent\" mean.\n// This is the machine-readable spec — the shared source of truth a sync step can\n// push into Insights, and what TAXONOMY.md documents.\n//\n// A goal answers \"what counts as a conversion\". A funnel answers \"by what path\".\n// The paths live in funnels.ts and a goal REFERENCES one by id: the steps are\n// written down exactly once.\n\nimport { EVENTS } from './events'\nimport { eventsOf, type FunnelId } from './funnels'\n\nexport interface GoalDef {\n /** Human label shown in Insights. */\n label: string\n /** The event whose occurrence counts as the goal conversion. */\n event: string\n /** The funnel leading to the goal — an id into FUNNELS (see funnels.ts). */\n funnelId?: FunnelId\n /** The ordered event names of `funnelId`, derived — never hand-written. */\n funnel?: string[]\n /** Optional property equality filter that qualifies the conversion. */\n filter?: { property: string; equals: string }\n}\n\nexport const GOALS: Record<'signup' | 'sale' | 'upgradeIntent' | 'activation', GoalDef> = {\n // Signup: the conversion is signup_completed, along the site signup funnel.\n signup: {\n label: 'Signup',\n event: EVENTS.SIGNUP_COMPLETED,\n funnelId: 'signup',\n funnel: eventsOf('signup'),\n },\n // Sale: a completed order qualified as a plan purchase (kind=plan).\n sale: {\n label: 'Sale',\n event: EVENTS.ORDER_COMPLETED,\n funnelId: 'upgrade',\n funnel: eventsOf('upgrade'),\n filter: { property: 'kind', equals: 'plan' },\n },\n // Upgrade intent: a plan click; pricing_viewed is the top of its funnel.\n upgradeIntent: {\n label: 'Upgrade Intent',\n event: EVENTS.PLAN_CLICKED,\n funnelId: 'upgrade',\n funnel: eventsOf('upgrade'),\n },\n // Activation: the ONE north-star conversion — an account that did the first\n // valuable thing (a successful API call, a live app, a chat answer).\n activation: {\n label: 'Activation',\n event: EVENTS.FIRST_ACTION,\n funnelId: 'apiActivation',\n funnel: eventsOf('apiActivation'),\n },\n}\n\nexport interface CohortDef {\n /** The hanzo.events column the cohort dimension maps to. */\n field: string\n label: string\n}\n\nexport const COHORTS: Record<'signupWeek' | 'channel' | 'refCode', CohortDef> = {\n signupWeek: { field: 'signup_week', label: 'Signup week' },\n channel: { field: 'channel', label: 'Acquisition channel' },\n refCode: { field: 'ref_code', label: 'Referral code' },\n}\n"]}