@cross-deck/web 1.2.0 → 1.3.1
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.
- package/CHANGELOG.md +64 -1
- package/dist/crossdeck.umd.min.js +2 -2
- package/dist/crossdeck.umd.min.js.map +1 -1
- package/dist/error-codes.json +1 -1
- package/dist/index.cjs +212 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +20 -2
- package/dist/index.d.ts +20 -2
- package/dist/index.mjs +212 -55
- package/dist/index.mjs.map +1 -1
- package/dist/react.cjs +212 -55
- package/dist/react.cjs.map +1 -1
- package/dist/react.mjs +212 -55
- package/dist/react.mjs.map +1 -1
- package/dist/vue.cjs +212 -55
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.mjs +212 -55
- package/dist/vue.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,69 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@cross-deck/web` will be documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
4
|
|
|
5
|
+
## [1.3.1] — 2026-05-24
|
|
6
|
+
|
|
7
|
+
Patch fix for the 1.3.0 dist-load contract. 1.3.0 introduced
|
|
8
|
+
`import { version } from "../package.json"` to keep the runtime
|
|
9
|
+
`Crossdeck-Sdk-Version` header in lockstep with the published bundle.
|
|
10
|
+
Esbuild inlined the JSON correctly so the published bundle still
|
|
11
|
+
shipped the right version on the wire, but the `dist-loading` test
|
|
12
|
+
that dynamic-imports the built `.mjs` files was hitting Vitest's 5s
|
|
13
|
+
default test timeout while Node evaluated the bundle.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **Removed the runtime JSON import.** `SDK_VERSION` is now sourced
|
|
18
|
+
from a generated `src/_version.ts` file (produced by
|
|
19
|
+
`scripts/sync-sdk-versions.mjs` from `package.json`). The wire
|
|
20
|
+
contract is unchanged; the build artefact no longer carries a
|
|
21
|
+
JSON-module dependency that Node ESM requires
|
|
22
|
+
`with { type: "json" }` to load from a `.mjs` file.
|
|
23
|
+
- **dist-loading test timeout bumped to 60s.** The dynamic-imports of
|
|
24
|
+
100KB+ bundles are genuinely slow on cold Node (~45s measured for
|
|
25
|
+
`vue.mjs`); the assertions themselves are sub-millisecond.
|
|
26
|
+
|
|
27
|
+
1.3.0 was never published to npm; the only consumers are the public
|
|
28
|
+
GitHub repo's v1.3.0 tag (left in place for traceability). 1.3.1 is
|
|
29
|
+
the first 1.3.x line to reach npm.
|
|
30
|
+
|
|
31
|
+
## [1.3.0] — 2026-05-24
|
|
32
|
+
|
|
33
|
+
KPMG bank-grade audit closure. Six review batches landed five SDK PRs and a backend wiring fix that closes every P0 plus 12 of 13 P1 findings. No public method renames; one internal contract change (`ErrorTracker.beforeSend` is now a getter); behavioural changes to the queue and the PII scrub that strictly improve correctness. Default-safe: existing `Crossdeck.init({...})` callsites keep working exactly the same. The wire `Crossdeck-Sdk-Version` header now reads from `package.json` so it cannot drift from the published bundle.
|
|
34
|
+
|
|
35
|
+
### Fixed (P0)
|
|
36
|
+
|
|
37
|
+
- **PII scrub now walks NESTED objects.** Pre-fix `scrubPiiFromProperties` only scrubbed top-level keys plus 1-deep arrays of strings; nested plain objects passed through unchanged. Every `error.*` event ships nested `frames[]` / `breadcrumbs[]` / `context{}` / `http{}` — the leak surface was broad. New impl recurses into plain objects + arrays-of-objects. `Date` / `Map` / `Set` / `Error` instances + class instances pass through untouched (the property validator owns those shapes).
|
|
38
|
+
- **PII scrub sentinel tokens aligned with the backend.** `[email]` / `[card]` → `<email>` / `<card>`, matching `backend/src/api/lib/scrub.ts`. The same event scrubbed by SDK + backend now carries the same sentinel — dashboard aggregation works again.
|
|
39
|
+
- **`setErrorBeforeSend` installed AFTER init() now actually fires.** Pre-fix the `ErrorTracker` captured `beforeSend` by value at construction, so any hook a customer installed later was silently inert and their PII-redaction escape hatch ran on zero errors. Contract is now a getter; the tracker resolves the current hook on every report.
|
|
40
|
+
- **Event queue durability hole during flush.** Pre-fix the buffer was spliced + the persistent blob saved EMPTY before awaiting the network call — a hard-crash mid-flight wiped the persisted batch and the events were lost forever. New `pendingBatch` slot keeps the in-flight batch in the persisted blob until the server confirms it. Side benefit: retries now reuse the same `Idempotency-Key` (Stripe pattern, brings web in lockstep with node).
|
|
41
|
+
- **`identify()` cross-customer cache leak.** Pre-fix the entitlement-cache clear was gated on `priorCdcust && new && prior !== new`, missing two real scenarios where a previous user's entitlements leaked to a new login (ITP / partial cookie eviction wiped cdcust but left the cache; rehydration from a pre-persisted-identity legacy install). New contract: clear when the resolved cdcust differs OR the cache is non-empty under an unknown identity.
|
|
42
|
+
- **Error-capture self-skip derived from `baseUrl`.** Pre-fix hardcoded to `api.cross-deck.com`; customers on staging / regional / self-hosted relay base URLs recursed (5xx → captureHttp → enqueue → /events → captureHttp → ∞). Now strict-hostname compare against `selfHostname` extracted from `init({ baseUrl })`. Case-insensitive. Closes a subtle substring-match bypass (`api.cross-deck.com.attacker.example` would have matched).
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- **`onPermanentFailure` callback on the event queue.** Fires when the queue drops a batch because the server returned a permanent 4xx (anything except 408 / 429). Loud `console.error` independent of debug mode, plus the new `sdk.flush_permanent_failure` debug signal. Pre-fix the queue retried 4xx forever with the same Idempotency-Key, silently growing the backlog while customers thought events were landing.
|
|
47
|
+
- **`onPermanentFailure({ status, droppedCount, lastError })`** is also exposed on the underlying `EventQueueConfig` for embedders wiring their own diagnostics surface.
|
|
48
|
+
- **Event-validation regression: DAG sibling sharing.** Two sibling properties pointing at the SAME sub-object no longer trip a false `[circular_reference]` flag. The validator now uses an ancestor-only stack instead of a shared `WeakSet` — real cycles still flag, legitimate DAGs pass through verbatim.
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
|
|
52
|
+
- **`SDK_VERSION` is now imported from `package.json`.** The `Crossdeck-Sdk-Version` header always matches the published bundle. Pre-fix the constant drifted independently — the published 1.2.0 bundle reported `@cross-deck/web@1.1.0` on the wire because nobody bumped the literal.
|
|
53
|
+
- **4xx hard-stop on the event queue.** Status codes other than 408 / 429 in the 4xx range are NOT retryable; the queue drops the batch and surfaces it via `onPermanentFailure`. 408 / 429 / 5xx / network errors stay retryable. RFC-correct.
|
|
54
|
+
- **`Retry-After` is honoured even above `maxMs`.** Pre-fix the policy clamped server-supplied `Retry-After` to `maxMs` (60s default) — a `Retry-After: 120` got truncated to 60s and we hammered the rate limit twice as fast as asked. New 24h absolute sanity cap against server bugs / HTTP-date clock-skew.
|
|
55
|
+
- **`reset()` clears the clock-skew snapshot.** `diagnostics().clock.skewMs` no longer echoes the prior session's skew after logout.
|
|
56
|
+
- **`pageviewId` nulls on session boundary.** Pre-fix it survived 30-min idle resets and corrupted post-resume event → pageview correlation.
|
|
57
|
+
- **`init()` re-entry tears down prior listeners** (`uninstallUnloadFlush`, autoTracker, webVitals, errors). Pre-fix duplicate `pagehide` / `beforeunload` / `visibilitychange` listeners accumulated across HMR / config-swap calls.
|
|
58
|
+
- **PII scrub regex now uses `.replace()` unconditionally.** Dropped the `.test()`-gating that carried `lastIndex` state between calls; the gate could false-skip strings that actually matched. Same fix on both SDKs.
|
|
59
|
+
- **`isLocalHostname()` matches `0.0.0.0` and IPv6 `fe80::/10`** so webpack-dev-server / Vite dev defaults and cross-device Safari Web Inspector hostnames stop polluting live analytics.
|
|
60
|
+
- **Self-skip applies to breadcrumbs too**, not just `captureHttp`. Error reports no longer carry noisy `POST https://api.cross-deck.com/v1/events` crumb entries.
|
|
61
|
+
- **`syncPurchases` body spread bug.** Pre-fix `{ rail: input.rail ?? "apple", ...input }` — the `...input` ran LAST and overrode the default when the caller passed `rail: undefined` explicitly. Reversed: `{ ...input, rail }`.
|
|
62
|
+
- **Bundle-size budgets raised** to fit the durability + permanent-failure surface (~1.5 KB gzipped of bank-grade code). `core ESM` 33 → 35 KB, `core CJS` 34 → 36 KB, `react / vue ESM` 33 → 35 KB, UMD 18 → 19 KB. Still well under single-pillar competitor ceilings.
|
|
63
|
+
|
|
64
|
+
### Wiring (backend, paired)
|
|
65
|
+
|
|
66
|
+
- **`v1-events` ingest now honours the per-project `piiAllowList`.** The admin management surface (`v1-pii-allow-list.ts`) was persisted + audit-logged but the hot ingest path never read it. The new `backend/src/api/lib/pii-allow-list-cache.ts` (60s TTL, single-flight) feeds the project's allow-list to `scrubProperties()` on every batch. `HARD_LOCKED_PATTERNS` are always stripped from the effective list regardless of what's in storage. (Backend-only — listed here so SDK consumers know defence-in-depth is fully closed.)
|
|
67
|
+
|
|
5
68
|
## [1.1.0] — 2026-05-18
|
|
6
69
|
|
|
7
70
|
### Added
|
|
@@ -132,7 +195,7 @@ duplicate reporting.
|
|
|
132
195
|
|
|
133
196
|
- **`Crossdeck.consent({ analytics, marketing, errors })`** — three independent consent dimensions, each defaulting to `true` (granted). Gates `track()`, `identify()`, paid-traffic click IDs, referrer URLs, and Web Vitals appropriately. `Crossdeck.consentStatus()` returns the current snapshot.
|
|
134
197
|
- **`respectDnt: true`** in `init()` — opt-in DNT support. When the browser exposes `navigator.doNotTrack === "1"`, ALL three consent dimensions are locked OFF permanently (no subsequent `consent()` call can flip them back on).
|
|
135
|
-
- **`scrubPii: true`** (default-on) in `init()` — Stripe-grade regex pass over every event property value, URL path, and title before flush. Email-shaped →
|
|
198
|
+
- **`scrubPii: true`** (default-on) in `init()` — Stripe-grade regex pass over every event property value, URL path, and title before flush. Email-shaped → `<email>`, card-number-shaped → `<card>` (tokens aligned with the backend's defence-in-depth scrubber). The walk is recursive: nested plain objects + arrays-of-objects are visited. Caller's input is never mutated. Disable for pipelines that do their own redaction.
|
|
136
199
|
- **`Crossdeck.forget(): Promise<void>`** — GDPR / CCPA right to be forgotten. Calls the new `/v1/identity/forget` endpoint and wipes ALL local state. Idempotent. Server-side failure does NOT block local wipe.
|
|
137
200
|
- **`@cross-deck/web/vue` subpackage** — Vue 3 composables (`useEntitlement(key)` → `Ref<boolean>`, `useEntitlements()` → `Ref<string[]>`) that mirror the React subpackage's contract. Subscribes to the entitlement cache via `onEntitlementsChange`. SSR-safe.
|
|
138
201
|
- **UMD CDN bundle** — `dist/crossdeck.umd.min.js`, registered via `unpkg` / `jsdelivr` package.json fields. Exposes `window.Crossdeck` for no-build-step consumers (plain HTML, Webflow, docs). 13 KB gzipped.
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var Crossdeck=(()=>{var re=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var Re=Object.getOwnPropertyNames;var Ae=Object.prototype.hasOwnProperty;var Pe=(r,e)=>{for(var t in e)re(r,t,{get:e[t],enumerable:!0})},De=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Re(e))!Ae.call(r,s)&&s!==t&&re(r,s,{get:()=>e[s],enumerable:!(n=Ie(e,s))||n.enumerable});return r};var Fe=r=>De(re({},"__esModule",{value:!0}),r);var gt={};Pe(gt,{CROSSDECK_ERROR_CODES:()=>he,Crossdeck:()=>Ce,CrossdeckClient:()=>O,CrossdeckError:()=>y,DEFAULT_BASE_URL:()=>j,MemoryStorage:()=>w,SDK_NAME:()=>R,SDK_VERSION:()=>N,getErrorCode:()=>xe});var y=class r extends Error{constructor(e){super(e.message),this.name="CrossdeckError",this.type=e.type,this.code=e.code,this.requestId=e.requestId,this.status=e.status,this.retryAfterMs=e.retryAfterMs,Object.setPrototypeOf(this,r.prototype)}};async function ge(r){let e=r.headers.get("x-request-id")??void 0,t=Le(r.headers.get("retry-after")),n;try{n=await r.json()}catch{n=null}let s=n?.error;return s&&typeof s.type=="string"&&typeof s.code=="string"?new y({type:s.type,code:s.code,message:s.message??`HTTP ${r.status}`,requestId:s.request_id??e,status:r.status,retryAfterMs:t}):new y({type:Oe(r.status),code:`http_${r.status}`,message:`HTTP ${r.status} ${r.statusText||""}`.trim(),requestId:e,status:r.status,retryAfterMs:t})}function Le(r){if(!r)return;let e=r.trim();if(!e)return;if(/^\d+(\.\d+)?$/.test(e)){let s=Number(e);return!Number.isFinite(s)||s<0?void 0:Math.round(s*1e3)}if(!/[a-zA-Z,/:]/.test(e))return;let t=Date.parse(e);if(!Number.isFinite(t))return;let n=t-Date.now();return n>0?n:0}function Oe(r){return r===401?"authentication_error":r===403?"permission_error":r===429?"rate_limit_error":r>=400&&r<500?"invalid_request_error":"internal_error"}var R="@cross-deck/web",N="1.1.0",j="https://api.cross-deck.com/v1",Me=15e3,$=class{constructor(e){this.config=e}async request(e,t,n={}){if(this.config.localDevMode)return Ue(t);let s=this.buildUrl(t,n.query),i={Authorization:`Bearer ${this.config.publicKey}`,"Crossdeck-Sdk-Version":`${R}@${this.config.sdkVersion}`,Accept:"application/json"};n.idempotencyKey&&(i["Idempotency-Key"]=n.idempotencyKey);let c;n.body!==void 0&&(i["Content-Type"]="application/json",c=JSON.stringify(n.body));let o=n.timeoutMs??this.config.timeoutMs??Me,a=typeof AbortController<"u"&&o>0?new AbortController:null,l=null;a&&o>0&&(l=setTimeout(()=>a.abort(),o));let u;try{u=await fetch(s,{method:e,headers:i,body:c,keepalive:n.keepalive===!0,signal:a?.signal})}catch(d){let p=a?.signal?.aborted===!0;throw new y({type:"network_error",code:p?"request_timeout":"fetch_failed",message:p?`Request to ${t} aborted after ${o}ms`:d instanceof Error?d.message:"fetch failed"})}finally{l!==null&&clearTimeout(l)}if(!u.ok)throw await ge(u);if(u.status!==204)try{return await u.json()}catch{throw new y({type:"internal_error",code:"invalid_json_response",message:"Server returned a 2xx with an unparseable body.",requestId:u.headers.get("x-request-id")??void 0,status:u.status})}}get isLocalDevMode(){return this.config.localDevMode===!0}buildUrl(e,t){let n=this.config.baseUrl.replace(/\/+$/,""),s=e.startsWith("/")?e:`/${e}`,i=n+s;if(t){let c=new URLSearchParams;for(let[a,l]of Object.entries(t))typeof l=="string"&&l.length>0&&c.append(a,l);let o=c.toString();o&&(i+=(i.includes("?")?"&":"?")+o)}return i}},q=null;function Ue(r){return r.startsWith("/sdk/heartbeat")?{object:"heartbeat",ok:!0,projectId:"proj_local_dev",appId:"app_local_dev",platform:"web",env:"sandbox",serverTime:Date.now()}:r.startsWith("/identity/alias")?(q||(q=`cdcust_local_${typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID().replace(/-/g,"").slice(0,16):Math.random().toString(36).slice(2,18)}`),{object:"alias_result",crossdeckCustomerId:q,linked:[],mergePending:!1,env:"sandbox"}):r.startsWith("/entitlements")?{object:"list",data:[],crossdeckCustomerId:q??"",env:"sandbox"}:r.startsWith("/events")?{object:"list",received:0,env:"sandbox"}:{}}var A="anon_id",P="cdcust_id",B=class{constructor(e,t,n){this.primary=e;this.prefix=t;this.secondary=n??null;let s=e.getItem(t+A),i=e.getItem(t+P),c=this.secondary?.getItem(t+A)??null,o=this.secondary?.getItem(t+P)??null,a=s??c,l=i??o;this.state={anonymousId:a??this.mintAnonymousId(),crossdeckCustomerId:l},(!s||!c)&&this.writeBoth(t+A,this.state.anonymousId),l&&(!i||!o)&&this.writeBoth(t+P,l)}get anonymousId(){return this.state.anonymousId}get crossdeckCustomerId(){return this.state.crossdeckCustomerId}setCrossdeckCustomerId(e){this.state.crossdeckCustomerId=e,this.writeBoth(this.prefix+P,e)}reset(){this.deleteBoth(this.prefix+A),this.deleteBoth(this.prefix+P),this.state={anonymousId:this.mintAnonymousId(),crossdeckCustomerId:null},this.writeBoth(this.prefix+A,this.state.anonymousId)}mintAnonymousId(){let e=Date.now().toString(36),t=k(10);return`anon_${e}${t}`}writeBoth(e,t){try{this.primary.setItem(e,t)}catch{}if(this.secondary)try{this.secondary.setItem(e,t)}catch{}}deleteBoth(e){try{this.primary.removeItem(e)}catch{}if(this.secondary)try{this.secondary.removeItem(e)}catch{}}};function k(r){let e="0123456789abcdefghijklmnopqrstuvwxyz",t=[],n=globalThis.crypto;if(n?.getRandomValues){let s=new Uint8Array(r);n.getRandomValues(s);for(let i=0;i<r;i++)t.push(e[s[i]%e.length]??"0")}else for(let s=0;s<r;s++)t.push(e[Math.floor(Math.random()*e.length)]??"0");return t.join("")}var W=class{constructor(e,t="crossdeck:entitlements",n=864e5){this.all=[];this.lastUpdated=0;this.lastRefreshFailedAt=0;this.listeners=new Set;this.listenerErrorCount=0;this.storage=e,this.storageKey=t,this.staleAfterMs=n,this.hydrate()}isEntitled(e){let t=Date.now()/1e3;return this.all.some(n=>n.key===e&&n.isActive&&(n.validUntil==null||n.validUntil>t))}list(){return this.all.slice()}get freshness(){return this.lastUpdated}get isStale(){return this.lastRefreshFailedAt>this.lastUpdated?!0:this.lastUpdated>0&&Date.now()-this.lastUpdated>this.staleAfterMs}get refreshFailedAt(){return this.lastRefreshFailedAt}get listenerErrors(){return this.listenerErrorCount}markRefreshFailed(){this.lastRefreshFailedAt=Date.now()}setFromList(e){this.all=e.slice(),this.lastUpdated=Date.now(),this.lastRefreshFailedAt=0,this.persist(),this.notify()}clear(){if(this.all=[],this.lastUpdated=0,this.lastRefreshFailedAt=0,this.storage)try{this.storage.removeItem(this.storageKey)}catch{}this.notify()}subscribe(e){this.listeners.add(e);let t=!1;return()=>{t||(t=!0,this.listeners.delete(e))}}hydrate(){if(this.storage)try{let e=this.storage.getItem(this.storageKey);if(!e)return;let t=JSON.parse(e);t&&t.v===1&&Array.isArray(t.entitlements)&&(this.all=t.entitlements,this.lastUpdated=typeof t.lastUpdated=="number"?t.lastUpdated:0)}catch{}}persist(){if(this.storage)try{let e={v:1,entitlements:this.all,lastUpdated:this.lastUpdated};this.storage.setItem(this.storageKey,JSON.stringify(e))}catch{}}notify(){if(this.listeners.size===0)return;let e=this.all.slice(),t=[...this.listeners];for(let n of t)try{n(e)}catch{this.listenerErrorCount+=1}}};function Ve(r,e,t={},n=Math.random){let s=t.baseMs??1e3,i=t.maxMs??6e4,c=t.factor??2,o=Math.min(r,30),l=Math.min(i,s*Math.pow(c,o))*n();return e!==void 0&&e>l?Math.min(i,e):Math.max(0,Math.round(l))}var H=class{constructor(e={}){this.options=e;this.attempts=0}get consecutiveFailures(){return this.attempts}get isWarning(){return this.attempts>=(this.options.failuresBeforeWarn??8)}nextDelay(e,t=Math.random){let n=Ve(this.attempts,e,this.options,t);return this.attempts+=1,n}recordSuccess(){this.attempts=0}};var D=1e3,K=class{constructor(e){this.cfg=e;this.buffer=[];this.dropped=0;this.inFlight=0;this.lastFlushAt=0;this.lastError=null;this.cancelTimer=null;this.firstFlushFired=!1;this.nextRetryAt=null;if(this.retry=new H(e.retry??{}),this.persistent=e.persistentStore??null,this.persistent){let t=this.persistent.load();t.length>0&&(t.length>D?(this.dropped+=t.length-D,this.buffer=t.slice(t.length-D)):this.buffer=t,this.cfg.onBufferChange?.(this.buffer.length),this.scheduleIdleFlush())}}enqueue(e){if(this.buffer.push(e),this.buffer.length>D){let t=this.buffer.length-D;this.buffer.splice(0,t),this.dropped+=t,this.cfg.onDrop?.(t)}this.cfg.onBufferChange?.(this.buffer.length),this.persistent?.save(this.buffer),this.buffer.length>=this.cfg.batchSize?this.flush():this.scheduleIdleFlush()}async flush(e={}){if(this.buffer.length===0)return null;this.cancelTimerIfSet(),this.nextRetryAt=null;let t=this.buffer.splice(0),n=this.mintBatchId();this.inFlight+=t.length,this.persistent?.save(this.buffer),this.cfg.onBufferChange?.(this.buffer.length);try{let s=this.cfg.envelope(),i=await this.cfg.http.request("POST","/events",{body:{appId:s.appId,environment:s.environment,sdk:s.sdk,events:t},keepalive:e.keepalive===!0,idempotencyKey:n});return this.lastFlushAt=Date.now(),this.lastError=null,this.inFlight-=t.length,this.retry.recordSuccess(),this.persistent?.save(this.buffer),this.firstFlushFired||(this.firstFlushFired=!0,this.cfg.onFirstFlushSuccess?.()),i}catch(s){this.buffer.unshift(...t),this.inFlight-=t.length;let i=s instanceof Error?s.message:String(s);this.lastError=i,this.persistent?.save(this.buffer),this.cfg.onBufferChange?.(this.buffer.length);let c=qe(s),o=this.retry.nextDelay(c);return this.scheduleRetry(o),this.cfg.onRetryScheduled?.({delayMs:o,consecutiveFailures:this.retry.consecutiveFailures,retryAfterMs:c,lastError:i}),null}}reset(){this.cancelTimerIfSet(),this.nextRetryAt=null,this.buffer=[],this.dropped=0,this.inFlight=0,this.lastError=null,this.retry.recordSuccess(),this.persistent?.clear(),this.cfg.onBufferChange?.(0)}getStats(){return{buffered:this.buffer.length,dropped:this.dropped,inFlight:this.inFlight,lastFlushAt:this.lastFlushAt,lastError:this.lastError,consecutiveFailures:this.retry.consecutiveFailures,nextRetryAt:this.nextRetryAt}}scheduleIdleFlush(){this.cancelTimerIfSet();let e=this.cfg.scheduler??me;this.cancelTimer=e(()=>{this.flush()},this.cfg.intervalMs)}scheduleRetry(e){this.cancelTimerIfSet(),this.nextRetryAt=Date.now()+e;let t=this.cfg.scheduler??me;this.cancelTimer=t(()=>{this.flush()},e)}cancelTimerIfSet(){this.cancelTimer&&(this.cancelTimer(),this.cancelTimer=null)}mintBatchId(){return`batch_${Date.now().toString(36)}${k(10)}`}};function qe(r){if(r&&typeof r=="object"&&"retryAfterMs"in r){let e=r.retryAfterMs;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}}function me(r,e){let t=setTimeout(r,e);if(typeof t.unref=="function")try{t.unref()}catch{}return()=>clearTimeout(t)}var z=class{constructor(e){this.options=e;this.writeScheduled=!1;this.pendingSnapshot=null;this.key=`${e.prefix}queue.v1`}load(){let e;try{e=this.options.storage.getItem(this.key)}catch{return[]}if(!e)return[];try{let t=JSON.parse(e);return!t||t.version!==1||!Array.isArray(t.events)?[]:t.events}catch{return[]}}save(e){this.pendingSnapshot=e.slice(),!this.writeScheduled&&(this.writeScheduled=!0,queueMicrotask(()=>this.flushWrite()))}saveSync(e){this.pendingSnapshot=e.slice(),this.flushWrite()}clear(){this.pendingSnapshot=null,this.writeScheduled=!1;try{this.options.storage.removeItem(this.key)}catch{}}flushWrite(){this.writeScheduled=!1;let e=this.pendingSnapshot;if(this.pendingSnapshot=null,e===null)return;if(e.length===0){try{this.options.storage.removeItem(this.key)}catch{}return}let t={version:1,events:e};try{this.options.storage.setItem(this.key,JSON.stringify(t))}catch{}}};var w=class{constructor(){this.store=new Map}getItem(e){return this.store.get(e)??null}setItem(e,t){this.store.set(e,t)}removeItem(e){this.store.delete(e)}},X=class{constructor(e){this.maxAgeSec=e?.maxAgeSec??63072e3,this.secure=e?.secure??$e(),this.sameSite=e?.sameSite??"Lax"}getItem(e){if(!ne())return null;let t=globalThis.document,n=t.cookie?t.cookie.split(/;\s*/):[],s=encodeURIComponent(e)+"=";for(let i of n)if(i.startsWith(s))try{return decodeURIComponent(i.slice(s.length))}catch{return null}return null}setItem(e,t){if(!ne())return;let n=globalThis.document,s=[`${encodeURIComponent(e)}=${encodeURIComponent(t)}`,"Path=/",`Max-Age=${this.maxAgeSec}`,`SameSite=${this.sameSite}`];this.secure&&s.push("Secure");try{n.cookie=s.join("; ")}catch{}}removeItem(e){if(!ne())return;let t=globalThis.document,n=[`${encodeURIComponent(e)}=`,"Path=/","Max-Age=0",`SameSite=${this.sameSite}`];this.secure&&n.push("Secure");try{t.cookie=n.join("; ")}catch{}}};function ye(){try{let r=globalThis.localStorage;if(r){let e="__crossdeck_probe__";return r.setItem(e,"1"),r.removeItem(e),r}}catch{}return new w}function $e(){try{return globalThis.location?.protocol==="https:"}catch{return!1}}function ne(){return typeof globalThis.document<"u"}function Ne(){return typeof globalThis.window<"u"&&typeof globalThis.document<"u"&&typeof globalThis.navigator<"u"}function be(r){let e={};if(r?.appVersion&&(e.appVersion=r.appVersion),!Ne())return e;let t=globalThis.window,n=globalThis.navigator,s=globalThis.document;try{typeof n.language=="string"&&(e.locale=n.language)}catch{}try{e.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}try{t.screen&&(e.screenWidth=t.screen.width,e.screenHeight=t.screen.height),e.viewportWidth=t.innerWidth,e.viewportHeight=t.innerHeight,e.devicePixelRatio=t.devicePixelRatio}catch{}try{let i=n.userAgent??"",c=je(i);Object.assign(e,c)}catch{}try{let i=n.userAgentData;if(i?.platform&&!e.os&&(e.os=i.platform),i?.brands&&!e.browser){let c=i.brands.find(o=>!/Not[ .;A]*Brand/i.test(o.brand)&&!/Chromium/i.test(o.brand));c&&(e.browser=c.brand,e.browserVersion=c.version)}}catch{}return e}function je(r){let e={};if(/iPad|iPhone|iPod/.test(r)){e.os="iOS";let t=r.match(/OS (\d+[._]\d+(?:[._]\d+)?)/);t?.[1]&&(e.osVersion=t[1].replace(/_/g,"."))}else if(/Android/.test(r)){e.os="Android";let t=r.match(/Android (\d+(?:\.\d+)*)/);t?.[1]&&(e.osVersion=t[1])}else if(/Windows/.test(r)){e.os="Windows";let t=r.match(/Windows NT (\d+\.\d+)/);t?.[1]&&(e.osVersion=t[1])}else if(/Mac OS X|Macintosh/.test(r)){e.os="macOS";let t=r.match(/Mac OS X (\d+[._]\d+(?:[._]\d+)?)/);t?.[1]&&(e.osVersion=t[1].replace(/_/g,"."))}else/Linux/.test(r)&&(e.os="Linux");return/Edg\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Edge",e.browserVersion=r.match(/Edg\/(\d+(?:\.\d+)*)/)?.[1]):/Firefox\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Firefox",e.browserVersion=r.match(/Firefox\/(\d+(?:\.\d+)*)/)?.[1]):/OPR\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Opera",e.browserVersion=r.match(/OPR\/(\d+(?:\.\d+)*)/)?.[1]):/Chrome\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Chrome",e.browserVersion=r.match(/Chrome\/(\d+(?:\.\d+)*)/)?.[1]):/Version\/(\d+(?:\.\d+)*).*Safari/.test(r)&&(e.browser="Safari",e.browserVersion=r.match(/Version\/(\d+(?:\.\d+)*)/)?.[1]),e}var _={sessions:!0,pageViews:!0,deviceInfo:!0,clicks:!0,webVitals:!0,errors:!0},Be=1800*1e3,se={utm_source:"",utm_medium:"",utm_campaign:"",utm_content:"",utm_term:"",referrer:"",gclid:"",fbclid:"",msclkid:"",ttclid:"",li_fat_id:"",twclid:""},F=class{constructor(e,t){this.cfg=e;this.track=t;this.session=null;this.cleanups=[];this.pageviewId=null}install(){ve()&&(this.cfg.sessions&&this.installSessionTracking(),this.cfg.pageViews&&this.installPageViewTracking(),this.cfg.clicks&&this.installClickTracking())}uninstall(){for(;this.cleanups.length;){let e=this.cleanups.pop();try{e?.()}catch{}}this.session&&!this.session.endedSent&&this.emitSessionEnd(),this.session=null}resetSession(){this.session&&!this.session.endedSent&&this.emitSessionEnd(),this.session=this.startNewSession(),this.emitSessionStart()}get currentSessionId(){return this.session?.sessionId??null}get currentPageviewId(){return this.pageviewId}get currentAcquisition(){return this.session?.acquisition??se}installSessionTracking(){this.session=this.startNewSession(),this.emitSessionStart();let e=()=>{if(!this.session)return;let i=globalThis.document;i.visibilityState==="hidden"?this.session.hiddenAt=Date.now():i.visibilityState==="visible"&&((this.session.hiddenAt?Date.now()-this.session.hiddenAt:0)>=Be?(this.emitSessionEnd(),this.session=this.startNewSession(),this.emitSessionStart()):this.session.hiddenAt=null)},t=()=>this.emitSessionEnd(),n=globalThis.window,s=globalThis.document;s.addEventListener("visibilitychange",e),n.addEventListener("pagehide",t),n.addEventListener("beforeunload",t),this.cleanups.push(()=>{s.removeEventListener("visibilitychange",e),n.removeEventListener("pagehide",t),n.removeEventListener("beforeunload",t)})}startNewSession(){return{sessionId:Ye(),startedAt:Date.now(),hiddenAt:null,endedSent:!1,acquisition:Ze()}}emitSessionStart(){this.session&&this.track("session.started",{sessionId:this.session.sessionId})}emitSessionEnd(){if(!this.session||this.session.endedSent)return;let e=Date.now()-this.session.startedAt;this.track("session.ended",{sessionId:this.session.sessionId,durationMs:e}),this.session.endedSent=!0}installPageViewTracking(){let e=globalThis.window,t=globalThis.document,n=0,s="",i=250,c=(p=!1)=>{let f=e.location,h=f.href,m=Date.now();!p&&h===s&&m-n<i||(n=m,s=h,this.pageviewId=`pv_${Date.now().toString(36)}${k(10)}`,this.track("page.viewed",{pageviewId:this.pageviewId,path:f.pathname,url:h,search:f.search||void 0,hash:f.hash||void 0,title:t.title,referrer:t.referrer||void 0}))};c();let o=e.history.pushState,a=e.history.replaceState;function l(p,f,h){o.apply(this,[p,f,h]),queueMicrotask(c)}function u(p,f,h){a.apply(this,[p,f,h]),queueMicrotask(c)}e.history.pushState=l,e.history.replaceState=u;let d=()=>c(!0);e.addEventListener("popstate",d),this.cleanups.push(()=>{e.history.pushState===l&&(e.history.pushState=o),e.history.replaceState===u&&(e.history.replaceState=a),e.removeEventListener("popstate",d)})}installClickTracking(){let e=globalThis.window,t=globalThis.document,n=0,s=null,i=100,c=64,o=a=>{let l=a.target;if(!l||!(l instanceof Element))return;let u=Date.now();if(l===s&&u-n<i)return;n=u,s=l;let p=We(l)||l;if(He(p)||Ke(p)||ze(p))return;let f=p.tagName.toLowerCase(),h=Qe(Xe(p),c),m=p.href||void 0,g=p.target||void 0,v=p.id||void 0,E=p.getAttribute("role")||void 0,M=p.getAttribute("aria-label")||void 0,U=Ge(p),b=Je(p),S=f==="a"&&!!m,I=p.getAttribute("data-cd-event"),T={selector:U,tag:f,text:h,elementId:v,role:E,ariaLabel:M,href:m,isLink:S,linkTarget:g,viewportX:a.clientX,viewportY:a.clientY,pageX:a.pageX,pageY:a.pageY,...b};for(let V of Object.keys(T))(T[V]===void 0||T[V]===null||T[V]==="")&&delete T[V];this.track(I||"element.clicked",T)};t.addEventListener("click",o,{capture:!0,passive:!0}),this.cleanups.push(()=>{t.removeEventListener("click",o,{capture:!0})})}};function We(r){return r.closest("[data-cd-event]")||r.closest("[data-cd-noTrack]")||r.closest("button, a, [role='button'], [role='link'], input[type='button'], input[type='submit']")||null}function He(r){if(!(r instanceof HTMLElement))return!1;let e=r.tagName.toLowerCase();if(e==="textarea"||e==="select")return!0;if(e==="input"){let t=(r.type||"").toLowerCase();return t!=="button"&&t!=="submit"&&t!=="image"&&t!=="reset"}return!1}function Ke(r){return!!r.closest("[data-cd-noTrack], [data-cd-no-track], .cd-noTrack, .cd-no-track")}function ze(r){return!!r.closest('input[type="password"]')}function Xe(r){let e=l=>l.replace(/\s+/g," ").trim(),t=r.getAttribute("data-cd-track")||r.getAttribute("data-track")||r.getAttribute("data-testid");if(t){let l=e(t);if(l)return l}let n=r.getAttribute("aria-label");if(n){let l=e(n);if(l)return l}let s=r.getAttribute("aria-labelledby");if(s&&typeof r.ownerDocument?.getElementById=="function"){let l=[];for(let u of s.split(/\s+/)){let d=r.ownerDocument.getElementById(u),p=d?.textContent?e(d.textContent):"";p&&l.push(p)}if(l.length>0)return l.join(" ")}if(r instanceof HTMLInputElement&&r.value){let l=e(r.value);if(l)return l}let i=e(r.textContent||"");if(i)return i;let c=r.getAttribute("title");if(c){let l=e(c);if(l)return l}let o=r.querySelector("img[alt]");if(o){let l=o.getAttribute("alt")??"",u=e(l);if(u)return u}let a=r.querySelector("svg title");if(a?.textContent){let l=e(a.textContent);if(l)return l}return""}function Qe(r,e){return r.length<=e?r:r.slice(0,e-1)+"\u2026"}function Ge(r){let e=[],t=r,n=0;for(;t&&t.nodeName.toLowerCase()!=="body"&&n<5;){let s=t.nodeName.toLowerCase();if(t.id){e.unshift(`${s}#${t.id}`);break}if(t.classList.length>0){let i=Array.from(t.classList).filter(c=>!c.startsWith("cd-")).slice(0,2).join(".");i&&(s+=`.${i}`)}e.unshift(s),t=t.parentElement,n++}return e.join(" > ")}function Je(r){let e={};if(!(r instanceof HTMLElement))return e;for(let t of r.getAttributeNames()){if(!t.startsWith("data-")||t==="data-cd-noTrack"||t==="data-cd-no-track"||t==="data-cd-event")continue;let n=r.getAttribute(t)||"",s=t.replace(/^data-cd-prop-/,"").replace(/^data-/,"");e[s]=n}return e}function ve(){return typeof globalThis.window<"u"&&typeof globalThis.document<"u"}function Ye(){return`sess_${Date.now().toString(36)}${k(10)}`}function Ze(){if(!ve())return{...se};let r={...se};try{let e=globalThis.window,t=new URLSearchParams(e.location.search??"");r.utm_source=t.get("utm_source")??"",r.utm_medium=t.get("utm_medium")??"",r.utm_campaign=t.get("utm_campaign")??"",r.utm_content=t.get("utm_content")??"",r.utm_term=t.get("utm_term")??"",r.gclid=t.get("gclid")??"",r.fbclid=t.get("fbclid")??"",r.msclkid=t.get("msclkid")??"",r.ttclid=t.get("ttclid")??"",r.li_fat_id=t.get("li_fat_id")??"",r.twclid=t.get("twclid")??""}catch{}try{let e=globalThis.document;typeof e.referrer=="string"&&(r.referrer=e.referrer)}catch{}return r}var et=[/^email$/i,/^password$/i,/^token$/i,/^secret$/i,/^card$/i,/^phone$/i,/password/i,/credit_?card/i];function ke(r){if(!r)return[];let e=[];for(let t of Object.keys(r))et.some(n=>n.test(t))&&e.push(t);return e}var Q=class{constructor(){this.enabled=!1;this.seen=new Set}emit(e,t,n){if(!this.enabled)return;if(tt.has(e)){if(this.seen.has(e))return;this.seen.add(e)}let s=n?` ${rt(n)}`:"";console.info(`[crossdeck:${e}] ${t}${s}`)}},tt=new Set(["sdk.configured","sdk.first_event_sent","sdk.environment_mismatch"]);function rt(r){try{return JSON.stringify(r)}catch{return"[unserialisable context]"}}function L(r,e={}){let t=[];if(!r)return{properties:{},warnings:t};let n=e.maxStringLength??1024,s=e.maxBatchPropertyBytes??8192,i=e.maxDepth??5,c=new WeakSet,o=(u,d,p)=>{if(p>i)return t.push({kind:"depth_exceeded",key:d}),{keep:!0,value:"[depth-exceeded]"};if(u===null)return{keep:!0,value:null};let f=typeof u;if(f==="string"){let h=u;return h.length>n?(t.push({kind:"truncated_string",key:d}),{keep:!0,value:h.slice(0,n-1)+"\u2026"}):{keep:!0,value:h}}if(f==="number")return Number.isFinite(u)?{keep:!0,value:u}:(t.push({kind:"non_serialisable",key:d}),{keep:!0,value:null});if(f==="boolean")return{keep:!0,value:u};if(f==="bigint")return t.push({kind:"coerced_bigint",key:d}),{keep:!0,value:u.toString()};if(f==="function")return t.push({kind:"dropped_function",key:d}),{keep:!1,value:void 0};if(f==="symbol")return t.push({kind:"dropped_symbol",key:d}),{keep:!1,value:void 0};if(f==="undefined")return t.push({kind:"dropped_undefined",key:d}),{keep:!1,value:void 0};if(u instanceof Date)return t.push({kind:"coerced_date",key:d}),{keep:!0,value:Number.isFinite(u.getTime())?u.toISOString():null};if(u instanceof Error)return t.push({kind:"coerced_error",key:d}),{keep:!0,value:{name:u.name,message:u.message,stack:typeof u.stack=="string"?u.stack.slice(0,n):void 0}};if(u instanceof Map){t.push({kind:"coerced_map",key:d});let h={};for(let[m,g]of u.entries()){let v=typeof m=="string"?m:String(m),E=o(g,`${d}.${v}`,p+1);E.keep&&(h[v]=E.value)}return{keep:!0,value:h}}if(u instanceof Set){t.push({kind:"coerced_set",key:d});let h=[],m=0;for(let g of u.values()){let v=o(g,`${d}[${m}]`,p+1);v.keep&&h.push(v.value),m++}return{keep:!0,value:h}}if(Array.isArray(u)){if(c.has(u))return t.push({kind:"circular_reference",key:d}),{keep:!0,value:"[circular]"};c.add(u);let h=[];for(let m=0;m<u.length;m++){let g=o(u[m],`${d}[${m}]`,p+1);g.keep&&h.push(g.value)}return{keep:!0,value:h}}if(f==="object"){let h=u;if(c.has(h))return t.push({kind:"circular_reference",key:d}),{keep:!0,value:"[circular]"};c.add(h);let m={};for(let g of Object.keys(h)){let v=o(h[g],`${d}.${g}`,p+1);v.keep&&(m[g]=v.value)}return{keep:!0,value:m}}t.push({kind:"non_serialisable",key:d});try{return{keep:!0,value:String(u)}}catch{return{keep:!1,value:void 0}}},a={};for(let u of Object.keys(r)){let d=o(r[u],u,0);d.keep&&(a[u]=d.value)}let l=we(a);if(l&&ie(l)>s){t.push({kind:"size_cap_exceeded",key:"*"});let u=Object.keys(a).map(p=>({k:p,size:ie(we(a[p])??"")})).sort((p,f)=>f.size-p.size),d=ie(l);for(let{k:p}of u){if(d<=s)break;d-=u.find(f=>f.k===p).size,delete a[p]}a.__truncated=!0}return{properties:a,warnings:t}}function we(r){try{return JSON.stringify(r)??null}catch{return null}}function ie(r){return typeof TextEncoder<"u"?new TextEncoder().encode(r).length:r.length*4}var G="super_props",oe="groups",J=class{constructor(e,t){this.storage=e;this.prefix=t;this.superProps={};this.groups={};this.superProps=_e(e,t+G)??{},this.groups=_e(e,t+oe)??{}}register(e){for(let[t,n]of Object.entries(e))n===null?delete this.superProps[t]:n!==void 0&&(this.superProps[t]=n);return ae(this.storage,this.prefix+G,this.superProps),{...this.superProps}}unregister(e){e in this.superProps&&(delete this.superProps[e],ae(this.storage,this.prefix+G,this.superProps))}getSuperProperties(){return{...this.superProps}}setGroup(e,t,n){t===null?delete this.groups[e]:this.groups[e]=n!==void 0?{id:t,traits:n}:{id:t},ae(this.storage,this.prefix+oe,this.groups)}getGroups(){return JSON.parse(JSON.stringify(this.groups))}getGroupIds(){let e={};for(let[t,n]of Object.entries(this.groups))e[t]=n.id;return e}clear(){this.superProps={},this.groups={};try{this.storage.removeItem(this.prefix+G)}catch{}try{this.storage.removeItem(this.prefix+oe)}catch{}}};function _e(r,e){let t;try{t=r.getItem(e)}catch{return null}if(!t)return null;try{return JSON.parse(t)}catch{return null}}function ae(r,e,t){try{r.setItem(e,JSON.stringify(t))}catch{}}var Y=class{constructor(e,t){this.cfg=e;this.report=t;this.observers=[];this.flushed=new Set;this.cls=0;this.clsEntries=[];this.inp=0;this.cleanups=[]}install(){if(!this.cfg.enabled||typeof PerformanceObserver>"u"||typeof globalThis>"u"||!("document"in globalThis))return;let e=globalThis.document;try{let i=new PerformanceObserver(c=>{for(let o of c.getEntries()){let a=o;a.responseStart>0&&!this.flushed.has("ttfb")&&(this.flushed.add("ttfb"),this.report("webvitals.ttfb",{valueMs:Math.round(a.responseStart-a.startTime)}))}});i.observe({type:"navigation",buffered:!0}),this.observers.push(i)}catch{}try{let i=new PerformanceObserver(c=>{for(let o of c.getEntries())o.name==="first-contentful-paint"&&!this.flushed.has("fcp")&&(this.flushed.add("fcp"),this.report("webvitals.fcp",{valueMs:Math.round(o.startTime)}))});i.observe({type:"paint",buffered:!0}),this.observers.push(i)}catch{}let t=0;try{let i=new PerformanceObserver(c=>{let o=c.getEntries(),a=o[o.length-1];a&&(t=a.startTime)});i.observe({type:"largest-contentful-paint",buffered:!0}),this.observers.push(i)}catch{}try{let i=new PerformanceObserver(c=>{for(let o of c.getEntries()){let a=o;typeof a.value=="number"&&!a.hadRecentInput&&(this.cls+=a.value,this.clsEntries.push(o))}});i.observe({type:"layout-shift",buffered:!0}),this.observers.push(i)}catch{}try{let i=new PerformanceObserver(c=>{for(let o of c.getEntries()){let a=o;a.interactionId&&a.duration>this.inp&&(this.inp=a.duration)}});try{i.observe({type:"event",buffered:!0,durationThreshold:16})}catch{i.observe({type:"first-input",buffered:!0})}this.observers.push(i)}catch{}let n=()=>{t>0&&!this.flushed.has("lcp")&&(this.flushed.add("lcp"),this.report("webvitals.lcp",{valueMs:Math.round(t)})),this.cls>0&&!this.flushed.has("cls")&&(this.flushed.add("cls"),this.report("webvitals.cls",{value:Math.round(this.cls*1e3)/1e3})),this.inp>0&&!this.flushed.has("inp")&&(this.flushed.add("inp"),this.report("webvitals.inp",{valueMs:Math.round(this.inp)}))},s=()=>{e.visibilityState==="hidden"&&n()};e.addEventListener("visibilitychange",s),globalThis.window.addEventListener("pagehide",n),this.cleanups.push(()=>{e.removeEventListener("visibilitychange",s),globalThis.window.removeEventListener("pagehide",n)})}uninstall(){for(let e of this.observers)try{e.disconnect()}catch{}this.observers=[];for(let e of this.cleanups.splice(0))try{e()}catch{}}};var nt={analytics:!0,marketing:!0,errors:!0},Z=class{constructor(e){this.state={...nt};this.dntDenied=!1;e?.respectDnt&&this.detectDnt()&&(this.dntDenied=!0,this.state={analytics:!1,marketing:!1,errors:!1})}set(e){if(this.dntDenied)return{...this.state};for(let t of Object.keys(e)){let n=e[t];typeof n=="boolean"&&(this.state[t]=n)}return{...this.state}}get(){return{...this.state}}get analytics(){return this.state.analytics}get marketing(){return this.state.marketing}get errors(){return this.state.errors}get isDntDenied(){return this.dntDenied}detectDnt(){try{let e=globalThis.navigator;return e?[e.doNotTrack,e.msDoNotTrack,globalThis.doNotTrack].some(n=>n==="1"||n==="yes"):!1}catch{return!1}}},ce=/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,ue=/\b\d(?:[ -]?\d){12,18}\b/g,st="[email]",it="[card]";function Se(r){if(!r)return r;let e=r;return ce.test(e)&&(e=e.replace(ce,st)),ce.lastIndex=0,ue.test(e)&&(e=e.replace(ue,it)),ue.lastIndex=0,e}function Ee(r){let e={};for(let t of Object.keys(r)){let n=r[t];typeof n=="string"?e[t]=Se(n):Array.isArray(n)?e[t]=n.map(s=>typeof s=="string"?Se(s):s):e[t]=n}return e}var ee=class{constructor(e=50){this.maxSize=e;this.items=[]}add(e){this.items.push(e),this.items.length>this.maxSize&&this.items.shift()}snapshot(){return this.items.slice()}clear(){this.items=[]}get size(){return this.items.length}};function de(r){if(!r||typeof r!="string")return[];let e=r.split(`
|
|
2
|
-
`),t=[];for(let n of e){let s=n.trim();if(!s)continue;let i=ot(s);i&&t.push(i)}return t}function ot(r){let e=/^at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)$/.exec(r);return e?le({function:e[1],filename:e[2],lineno:parseInt(e[3],10),colno:parseInt(e[4],10),raw:r}):(e=/^at\s+(.+?):(\d+):(\d+)$/.exec(r),e?le({function:"?",filename:e[1],lineno:parseInt(e[2],10),colno:parseInt(e[3],10),raw:r}):(e=/^(.*?)@(.+?):(\d+):(\d+)$/.exec(r),e?le({function:e[1]||"?",filename:e[2],lineno:parseInt(e[3],10),colno:parseInt(e[4],10),raw:r}):/^\w*Error/.test(r)||!r.includes(":")?null:{function:"?",filename:"",lineno:0,colno:0,in_app:!0,raw:r}))}function le(r){return{function:r.function||"?",filename:r.filename,lineno:Number.isFinite(r.lineno)?r.lineno:0,colno:Number.isFinite(r.colno)?r.colno:0,in_app:at(r.filename),raw:r.raw}}function at(r){return r?!(/^(?:chrome|moz|safari|webkit)-extension:\/\//.test(r)||/\bcdn\.jsdelivr\.net\b/.test(r)||/\bunpkg\.com\b/.test(r)||/\bgoogletagmanager\.com\b/.test(r)||/\bgoogle-analytics\.com\b/.test(r)||/\b@cross-deck\/web\b/.test(r)||/\/crossdeck\.umd\.min\.js$/.test(r)):!0}function C(r,e,t){let n=e.filter(i=>i.in_app).slice(0,3),s=[(r||"").slice(0,200),...n.map(i=>`${i.function}@${i.filename}:${i.lineno}`)];if(n.length===0&&t){let i=[t.errorType??"",t.filename??"",t.lineno??"",t.colno??""].join(":");i!==":::"&&s.push(i)}return ct(s.join("|"))}function ct(r){let e=5381;for(let t=0;t<r.length;t++)e=(e<<5)+e+r.charCodeAt(t)|0;return(e>>>0).toString(16).padStart(8,"0")}var Te={enabled:!0,onError:!0,onUnhandledRejection:!0,wrapFetch:!0,wrapXhr:!0,captureConsole:!1,ignoreErrors:["ResizeObserver loop limit exceeded","ResizeObserver loop completed with undelivered notifications","Non-Error promise rejection captured"],allowUrls:[],denyUrls:[/^chrome-extension:\/\//,/^moz-extension:\/\//,/^safari-extension:\/\//,/^webkit-extension:\/\//,/^safari-web-extension:\/\//],sampleRate:1,maxPerFingerprintPerMinute:5,maxPerSession:100},te=class{constructor(e){this.opts=e;this.installed=!1;this.cleanups=[];this._reporting=!1;this.sessionCount=0;this.fingerprintWindow=new Map}install(){if(this.installed||!this.opts.config.enabled||typeof globalThis>"u"||!("window"in globalThis))return;let e=globalThis.window;this.opts.config.onError&&this.installOnErrorListener(e),this.opts.config.onUnhandledRejection&&this.installRejectionListener(e),this.opts.config.wrapFetch&&this.installFetchWrap(e),this.opts.config.wrapXhr&&this.installXhrWrap(e),this.opts.config.captureConsole&&this.installConsoleWrap(),this.installed=!0}uninstall(){for(let e of this.cleanups.splice(0))try{e()}catch{}this.installed=!1}captureError(e,t){if(this.opts.isConsented())try{let n=this.buildFromUnknown(e,"error.handled",t?.level??"error");t?.context&&(n.context={...n.context,...t.context}),t?.tags&&(n.tags={...n.tags,...t.tags}),this.maybeReport(n)}catch{}}captureMessage(e,t="info"){if(this.opts.isConsented())try{let n={timestamp:Date.now(),kind:"error.message",level:t,message:e,errorType:null,frames:[],rawStack:null,filename:null,lineno:null,colno:null,fingerprint:C(e,[]),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:this.opts.getContext(),tags:this.opts.getTags()};this.maybeReport(n)}catch{}}installOnErrorListener(e){let t=n=>{if(!this._reporting&&this.opts.isConsented())try{this._reporting=!0;let s=this.buildFromErrorEvent(n);this.maybeReport(s)}catch{}finally{this._reporting=!1}};e.addEventListener("error",t,!0),this.cleanups.push(()=>e.removeEventListener("error",t,!0))}installRejectionListener(e){let t=n=>{if(!this._reporting&&this.opts.isConsented())try{this._reporting=!0;let s=this.buildFromUnknown(n.reason,"error.unhandledrejection","error");this.maybeReport(s)}catch{}finally{this._reporting=!1}};e.addEventListener("unhandledrejection",t),this.cleanups.push(()=>e.removeEventListener("unhandledrejection",t))}installFetchWrap(e){let t=e.fetch?.bind(e);if(!t)return;let n=async(...s)=>{let i=s[0],c=s[1]??{},o=typeof i=="string"?i:i?.url??"",a=(c.method||"GET").toUpperCase(),l=Date.now();this.opts.breadcrumbs.add({timestamp:l,category:"http",message:`${a} ${o}`,data:{url:o,method:a}});try{let u=await t(...s);return u.status>=500&&this.opts.isConsented()&&(o.includes("api.cross-deck.com")||this.captureHttp({url:o,method:a,status:u.status,statusText:u.statusText})),u}catch(u){throw this.opts.isConsented()&&!o.includes("api.cross-deck.com")&&this.captureHttp({url:o,method:a,status:0,statusText:u instanceof Error?u.message:"network error"}),u}};e.fetch=n,this.cleanups.push(()=>{e.fetch===n&&(e.fetch=t)})}installXhrWrap(e){let n=e.XMLHttpRequest?.prototype;if(!n)return;let s=n.open,i=n.send,c=this;n.open=function(o,a,...l){return this._cdMethod=o,this._cdUrl=a,s.apply(this,[o,a,...l])},n.send=function(o){let a=this,l=()=>{try{if(a.status>=500&&c.opts.isConsented()){let u=a._cdUrl??"";u.includes("api.cross-deck.com")||c.captureHttp({url:u,method:(a._cdMethod??"GET").toUpperCase(),status:a.status,statusText:a.statusText})}}catch{}};return a.addEventListener("loadend",l),i.apply(this,[o??null])},this.cleanups.push(()=>{n.open=s,n.send=i})}installConsoleWrap(){let e=globalThis.console;if(!e)return;let t=e.error.bind(e);e.error=(...n)=>{try{this.opts.isConsented()&&this.captureMessage(n.map(s=>lt(s)).join(" "),"error")}catch{}return t(...n)},this.cleanups.push(()=>{e.error=t})}buildFromErrorEvent(e){let t=e.error,n=e.filename||null,s=typeof e.lineno=="number"&&e.lineno>0?e.lineno:null,i=typeof e.colno=="number"&&e.colno>0?e.colno:null;if(t==null&&!n&&s==null&&(e.message==="Script error."||e.message==="Script error"||!e.message)){let f="Cross-origin script error (browser hid details \u2014 script needs crossorigin attribute + CORS headers)";return{timestamp:Date.now(),kind:"error.unhandled",level:"error",message:f,errorType:"ScriptError",frames:[],rawStack:null,filename:null,lineno:null,colno:null,fingerprint:C(f,[]),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:this.opts.getContext(),tags:{...this.opts.getTags(),cross_origin:"true"}}}let o=fe(t),a=(o.message||e.message||"Unknown error").slice(0,1024),l=t instanceof Error?t.stack??null:null,u=de(l),d=o.errorType??null,p=o.extras?{...this.opts.getContext(),__error_extras:o.extras}:this.opts.getContext();return{timestamp:Date.now(),kind:"error.unhandled",level:"error",message:a,errorType:d,frames:u,rawStack:l,filename:n,lineno:s,colno:i,fingerprint:C(a,u,{filename:n,lineno:s,colno:i,errorType:d}),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:p,tags:this.opts.getTags()}}buildFromUnknown(e,t,n){let s=fe(e),i=(s.message||"Unknown error").slice(0,1024),c=e instanceof Error?e.stack??null:null,o=de(c),a=s.errorType??null,l=s.extras?{...this.opts.getContext(),__error_extras:s.extras}:this.opts.getContext();return{timestamp:Date.now(),kind:t,level:n,message:i,errorType:a,frames:o,rawStack:c,filename:null,lineno:null,colno:null,fingerprint:C(i,o,{errorType:a}),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:l,tags:this.opts.getTags()}}captureHttp(e){try{let t=`HTTP ${e.status} ${e.method} ${e.url}`,n={timestamp:Date.now(),kind:"error.http",level:"error",message:t,errorType:"HTTPError",frames:[],rawStack:null,filename:e.url,lineno:null,colno:null,fingerprint:C(`HTTP ${e.status} ${e.method}`,[],{filename:e.url,errorType:"HTTPError"}),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:this.opts.getContext(),tags:this.opts.getTags(),http:e};this.maybeReport(n)}catch{}}maybeReport(e){if(this.sessionCount>=this.opts.config.maxPerSession||this.shouldIgnore(e)||!this.passesUrlGate(e)||!this.passesSample(e)||!this.passesRateLimit(e))return;let t=e;if(this.opts.beforeSend){try{t=this.opts.beforeSend(e)}catch{t=e}if(!t)return}this.sessionCount+=1;try{this.opts.report(t)}catch{}}shouldIgnore(e){for(let t of this.opts.config.ignoreErrors)if(typeof t=="string"&&e.message.includes(t)||t instanceof RegExp&&t.test(e.message))return!0;return!1}passesUrlGate(e){let n=(e.frames.find(s=>s.filename)??null)?.filename??e.filename??"";if(!n)return!0;for(let s of this.opts.config.denyUrls)if(typeof s=="string"&&n.includes(s)||s instanceof RegExp&&s.test(n))return!1;if(this.opts.config.allowUrls.length>0){for(let s of this.opts.config.allowUrls)if(typeof s=="string"&&n.includes(s)||s instanceof RegExp&&s.test(n))return!0;return!1}return!0}passesSample(e){return this.opts.config.sampleRate>=1?!0:this.opts.config.sampleRate<=0?!1:parseInt(e.fingerprint.slice(0,2),16)/255<this.opts.config.sampleRate}passesRateLimit(e){let n=Date.now(),s=this.opts.config.maxPerFingerprintPerMinute,c=(this.fingerprintWindow.get(e.fingerprint)??[]).filter(o=>n-o<6e4);return c.length>=s?(this.fingerprintWindow.set(e.fingerprint,c),!1):(c.push(n),this.fingerprintWindow.set(e.fingerprint,c),!0)}};function fe(r){if(r===null)return{message:"(thrown: null)",errorType:null,extras:null};if(r===void 0)return{message:"(thrown: undefined)",errorType:null,extras:null};if(typeof r=="string")return{message:r,errorType:null,extras:null};if(typeof r=="number"||typeof r=="boolean"||typeof r=="bigint")return{message:String(r),errorType:typeof r,extras:null};if(typeof r=="symbol")return{message:r.toString(),errorType:"symbol",extras:null};if(typeof r=="function")return{message:`(thrown function: ${r.name||"anonymous"})`,errorType:"function",extras:null};if(r instanceof Error){let e=r.name||r.constructor?.name||"Error",t=typeof r.message=="string"&&r.message.length>0?r.message:x(r)||e,n={},s=ut(r);s.length>0&&(n.cause=s);for(let i of["code","status","statusCode","errno","response","data","detail","details"]){let c=r[i];c!==void 0&&typeof c!="function"&&(n[i]=pe(c))}for(let i of Object.keys(r)){if(i==="message"||i==="stack"||i==="name"||i==="cause"||i in n)continue;let c=r[i];typeof c!="function"&&(n[i]=pe(c))}return{message:t,errorType:e,extras:Object.keys(n).length>0?n:null}}if(typeof Response<"u"&&r instanceof Response)return{message:`HTTP ${r.status} ${r.statusText||""}${r.url?` ${r.url}`:""}`.trim(),errorType:"Response",extras:{status:r.status,statusText:r.statusText,url:r.url,type:r.type}};if(typeof r=="object"){let e=r,t=e.constructor&&typeof e.constructor=="function"&&e.constructor.name||null,n=typeof e.message=="string"&&e.message?e.message:null,s=typeof e.name=="string"&&e.name?e.name:null,i=null;try{let d=JSON.stringify(e);i=d==="{}"?null:d}catch{i=null}let c=x(e),o=n??i??(c&&c!=="[object Object]"?c:null)??(t?`(thrown ${t} with no message)`:"(thrown object with no message)"),a=s??t??null,l={},u=0;for(let d of Object.keys(e)){if(u>=20)break;if(d==="message"||d==="name")continue;let p=e[d];typeof p!="function"&&(l[d]=pe(p),u++)}return{message:o,errorType:a,extras:Object.keys(l).length>0?l:null}}return{message:x(r)||"(unstringifiable thrown value)",errorType:null,extras:null}}function ut(r){let e=[],t=r.cause,n=0;for(;t!=null&&n<5;)t instanceof Error?(e.push({name:t.name||"Error",message:t.message||""}),t=t.cause):(e.push({name:"non-Error",message:x(t)}),t=null),n++;return e}function x(r){try{let e=Object.prototype.toString.call(r);if(e!=="[object Object]")return e;let t=r?.toString;if(typeof t=="function"&&t!==Object.prototype.toString){let n=t.call(r);if(typeof n=="string")return n}return e}catch{return"(throwing toString)"}}function pe(r){if(r==null)return r;let e=typeof r;if(e==="string"||e==="number"||e==="boolean")return r;if(e==="bigint")return String(r);try{let t=JSON.stringify(r);return t===void 0?x(r):JSON.parse(t)}catch{return x(r)}}function lt(r){return fe(r).message}var O=class{constructor(){this.state=null}init(e){if(!e.publicKey||!e.publicKey.startsWith("cd_pub_"))throw new y({type:"configuration_error",code:"invalid_public_key",message:"Crossdeck.init requires a publishable key starting with cd_pub_."});if(!e.appId)throw new y({type:"configuration_error",code:"missing_app_id",message:"Crossdeck.init requires an appId. Find yours in the Crossdeck dashboard."});if(e.environment!=="production"&&e.environment!=="sandbox")throw new y({type:"configuration_error",code:"invalid_environment",message:'Crossdeck.init requires environment: "production" | "sandbox".'});let t=dt(e.publicKey);if(t&&t!==e.environment)throw new y({type:"configuration_error",code:"environment_mismatch",message:`Crossdeck.init: environment "${e.environment}" disagrees with key prefix (${t}). Reconcile the publishable key with the environment declaration.`});let n=pt(),s=e.storage??ye(),i=e.persistIdentity??!0,c=ft(e.autoTrack),o={appId:e.appId,publicKey:e.publicKey,environment:e.environment,baseUrl:e.baseUrl??j,persistIdentity:i,storagePrefix:e.storagePrefix??"crossdeck:",autoHeartbeat:e.autoHeartbeat??!0,eventFlushBatchSize:e.eventFlushBatchSize??20,eventFlushIntervalMs:e.eventFlushIntervalMs??1500,sdkVersion:e.sdkVersion??N,autoTrack:c,appVersion:e.appVersion??null},a=new Q;a.enabled=e.debug===!0;let l=new $({publicKey:o.publicKey,baseUrl:o.baseUrl,sdkVersion:o.sdkVersion,localDevMode:n});n&&console.log("[crossdeck] Localhost detected \u2014 running in dev mode (no network calls). Set publicKey: 'cd_pub_test_\u2026' and deploy to a real domain to test against the Crossdeck Sandbox.");let u=i?s:new w,p=i&&!e.storage&&typeof globalThis.document<"u"?new X:void 0,f=new B(u,o.storagePrefix,p),h=new W(u,o.storagePrefix+"entitlements"),m=i?new z({storage:u,prefix:o.storagePrefix}):null;m&&a.emit("sdk.queue_restored","Restored persisted event queue from a prior session.");let g=new K({http:l,batchSize:o.eventFlushBatchSize,intervalMs:o.eventFlushIntervalMs,envelope:()=>({appId:o.appId,environment:o.environment,sdk:{name:R,version:o.sdkVersion}}),persistentStore:m??void 0,onFirstFlushSuccess:()=>{a.emit("sdk.first_event_sent","First telemetry event received. View it in Live Events.",{appId:o.appId,environment:o.environment})},onRetryScheduled:b=>{a.emit("sdk.flush_retry_scheduled",`Event flush failed (${b.lastError}). Retrying in ${b.delayMs}ms (attempt ${b.consecutiveFailures}).`,{...b})}}),v=c.deviceInfo?be({appVersion:o.appVersion??void 0}):o.appVersion?{appVersion:o.appVersion}:{},E=new J(i?u:new w,o.storagePrefix),M=new Z({respectDnt:e.respectDnt===!0});M.isDntDenied&&a.emit("sdk.consent_dnt_applied","Do Not Track detected \u2014 all tracking dimensions denied at init.");let U=new ee(50);if(this.state={http:l,identity:f,entitlements:h,events:g,autoTracker:null,webVitals:null,errors:null,breadcrumbs:U,errorContext:{},errorTags:{},errorBeforeSend:null,superProps:E,consent:M,scrubPii:e.scrubPii!==!1,deviceInfo:v,options:o,debug:a,developerUserId:null,uninstallUnloadFlush:null,lastServerTime:null,lastClientTime:null},a.emit("sdk.configured",`Crossdeck connected to ${o.appId} in ${o.environment} mode.`,{appId:o.appId,environment:o.environment,sdkVersion:o.sdkVersion}),c.sessions||c.pageViews){let b=new F(c,(S,I)=>this.track(S,I));this.state.autoTracker=b,b.install()}if(c.webVitals){let b=new Y({enabled:!0},(S,I)=>this.track(S,I));this.state.webVitals=b,b.install()}if(c.errors){let b=new te({config:{...Te,enabled:!0},breadcrumbs:U,report:S=>this.reportError(S),getContext:()=>({...this.state.errorContext}),getTags:()=>({...this.state.errorTags}),beforeSend:this.state.errorBeforeSend,isConsented:()=>this.state.consent.errors});this.state.errors=b,b.install()}this.state.uninstallUnloadFlush=ht(()=>{this.flush({keepalive:!0}).catch(()=>{})}),o.autoHeartbeat&&!n&&this.heartbeat().catch(()=>{})}start(e){typeof console<"u"&&console.warn("[crossdeck] Crossdeck.start() is deprecated \u2014 use Crossdeck.init() instead. The signature is the same."),this.init(e)}async identify(e,t){let n=this.requireStarted();if(!e)throw new y({type:"invalid_request_error",code:"missing_user_id",message:"identify(userId) requires a non-empty userId."});if(!n.consent.analytics)return n.debug.emit("sdk.consent_denied","identify() skipped \u2014 consent denied for analytics."),{object:"alias_result",crossdeckCustomerId:n.identity.crossdeckCustomerId??"",linked:[],mergePending:!1,env:n.options.environment};let s=t?.traits!==void 0?L(t.traits):null,i=s&&Object.keys(s.properties).length>0?s.properties:void 0;if(n.debug.enabled&&s&&s.warnings.length>0)for(let l of s.warnings)n.debug.emit("sdk.property_coerced",`identify() traits key ${JSON.stringify(l.key)} was ${l.kind.replace(/_/g," ")} during validation.`,{key:l.key,kind:l.kind});let c={userId:e,anonymousId:n.identity.anonymousId};t?.email&&(c.email=t.email),i&&(c.traits=i);let o=await n.http.request("POST","/identity/alias",{body:c}),a=n.identity.crossdeckCustomerId;return a&&o.crossdeckCustomerId&&a!==o.crossdeckCustomerId&&n.entitlements.clear(),n.identity.setCrossdeckCustomerId(o.crossdeckCustomerId),n.developerUserId=e,o}register(e){let t=this.requireStarted(),n=L(e);return t.superProps.register(n.properties)}unregister(e){this.requireStarted().superProps.unregister(e)}getSuperProperties(){return this.state?this.state.superProps.getSuperProperties():{}}group(e,t,n){let s=this.requireStarted();if(!e)throw new y({type:"invalid_request_error",code:"missing_group_type",message:"group(type, id) requires a non-empty type."});let i=n?L(n).properties:void 0;s.superProps.setGroup(e,t,i)}getGroups(){return this.state?this.state.superProps.getGroups():{}}consent(e){let t=this.requireStarted(),n=t.consent.set(e);return t.debug.emit("sdk.consent_changed","Consent state updated.",{...n}),n}consentStatus(){return this.state?this.state.consent.get():{analytics:!0,marketing:!0,errors:!0}}captureError(e,t){this.state?.errors&&this.state.errors.captureError(e,t)}captureMessage(e,t="info"){this.state?.errors&&this.state.errors.captureMessage(e,t)}setTag(e,t){this.state&&(this.state.errorTags[e]=t)}setTags(e){this.state&&Object.assign(this.state.errorTags,e)}setContext(e,t){this.state&&(this.state.errorContext[e]=t)}addBreadcrumb(e){this.state&&this.state.breadcrumbs.add(e)}setErrorBeforeSend(e){this.state&&(this.state.errorBeforeSend=e)}reportError(e){let t={fingerprint:e.fingerprint,level:e.level,errorType:e.errorType,message:e.message,stack:e.rawStack??void 0,frames:e.frames,filename:e.filename??void 0,lineno:e.lineno??void 0,colno:e.colno??void 0,tags:e.tags,context:e.context,breadcrumbs:e.breadcrumbs,http:e.http};for(let n of Object.keys(t))t[n]===void 0&&delete t[n];this.track(e.kind,t)}async forget(){let e=this.requireStarted(),t=this.identityQueryParams();try{await e.http.request("POST","/identity/forget",{body:{...t}})}catch(n){e.debug.emit("sdk.consent_denied",`forget() server call failed (${n instanceof Error?n.message:String(n)}). Local state wiped anyway.`)}this.reset()}async getEntitlements(){let e=this.requireStarted(),t=this.identityQueryParams(),n;try{n=await e.http.request("GET","/entitlements",{query:t})}catch(s){throw e.entitlements.markRefreshFailed(),s}return n.crossdeckCustomerId&&e.identity.setCrossdeckCustomerId(n.crossdeckCustomerId),e.entitlements.setFromList(n.data),n.data}isEntitled(e){return this.requireStarted().entitlements.isEntitled(e)}listEntitlements(){return this.requireStarted().entitlements.list()}onEntitlementsChange(e){return this.requireStarted().entitlements.subscribe(e)}track(e,t){let n=this.requireStarted();if(!e)throw new y({type:"invalid_request_error",code:"missing_event_name",message:"track(name) requires a non-empty name."});let s=e.startsWith("error."),i=e.startsWith("webvitals.");if(!(s||i?n.consent.errors:n.consent.analytics)){n.debug.enabled&&n.debug.emit("sdk.consent_denied",`Dropped event "${e}" \u2014 consent denied for ${i?"errors":"analytics"}.`);return}if(n.debug.enabled&&t){let g=ke(t);g.length>0&&n.debug.emit("sdk.sensitive_property_warning",`Event "${e}" has potentially sensitive property names: ${g.join(", ")}. Crossdeck is privacy-first \u2014 avoid sending PII unless intentional.`,{eventName:e,flagged:g})}n.debug.enabled&&!n.developerUserId&&!n.identity.crossdeckCustomerId&&n.debug.emit("sdk.no_identity","Using anonymous user until identify(userId) is called.");let o=L(t);if(n.debug.enabled&&o.warnings.length>0)for(let g of o.warnings)n.debug.emit("sdk.property_coerced",`Event "${e}" property ${JSON.stringify(g.key)} was ${g.kind.replace(/_/g," ")} during validation.`,{eventName:e,key:g.key,kind:g.kind});let a={...n.deviceInfo},l=n.autoTracker?.currentSessionId;l&&(a.sessionId=l);let u=n.autoTracker?.currentPageviewId;u&&(a.pageviewId=u);let d=n.autoTracker?.currentAcquisition;d&&(d.utm_source&&(a.utm_source=d.utm_source),d.utm_medium&&(a.utm_medium=d.utm_medium),d.utm_campaign&&(a.utm_campaign=d.utm_campaign),d.utm_content&&(a.utm_content=d.utm_content),d.utm_term&&(a.utm_term=d.utm_term),d.referrer&&n.consent.marketing&&(a.referrer=d.referrer),n.consent.marketing&&(d.gclid&&(a.gclid=d.gclid),d.fbclid&&(a.fbclid=d.fbclid),d.msclkid&&(a.msclkid=d.msclkid),d.ttclid&&(a.ttclid=d.ttclid),d.li_fat_id&&(a.li_fat_id=d.li_fat_id),d.twclid&&(a.twclid=d.twclid)));let p=n.superProps.getSuperProperties();for(let g of Object.keys(p))g in a||(a[g]=p[g]);let f=n.superProps.getGroupIds();Object.keys(f).length>0&&(a.$groups=f),Object.assign(a,o.properties);let h=n.scrubPii?Ee(a):a,m={eventId:this.mintEventId(),name:e,timestamp:Date.now(),properties:h};if(Object.assign(m,this.identityHintForEvent()),n.events.enqueue(m),!s&&!i){let g=e.startsWith("page.")?"navigation":e.startsWith("element.")||e==="session.started"?"ui.click":"custom";n.breadcrumbs.add({timestamp:m.timestamp,category:g,message:e,data:t?{...t}:void 0})}}async flush(e={}){await this.requireStarted().events.flush(e)}async flushEvents(){return this.flush()}async syncPurchases(e){let t=this.requireStarted();if(!e.signedTransactionInfo)throw new y({type:"invalid_request_error",code:"missing_signed_transaction_info",message:"syncPurchases requires a signedTransactionInfo string from StoreKit 2."});let n=await t.http.request("POST","/purchases/sync",{body:{rail:e.rail??"apple",...e}});return t.identity.setCrossdeckCustomerId(n.crossdeckCustomerId),t.entitlements.setFromList(n.entitlements),t.debug.emit("sdk.purchase_evidence_sent","StoreKit transaction forwarded. Waiting for backend verification.",{rail:e.rail??"apple"}),n}async purchaseApple(e){return this.syncPurchases({rail:"apple",...e})}setDebugMode(e){let t=this.requireStarted();t.debug.enabled=e,e&&t.debug.emit("sdk.configured",`Debug mode enabled for ${t.options.appId} in ${t.options.environment} mode.`,{appId:t.options.appId,environment:t.options.environment})}async heartbeat(){let e=this.requireStarted(),t=await e.http.request("GET","/sdk/heartbeat");return typeof t?.serverTime=="number"&&Number.isFinite(t.serverTime)&&(e.lastServerTime=t.serverTime,e.lastClientTime=Date.now()),t}reset(){if(this.state){if(this.state.developerUserId)try{this.track("user.signed_out",{auto:!0})}catch{}if(this.state.autoTracker?.uninstall(),this.state.identity.reset(),this.state.entitlements.clear(),this.state.events.reset(),this.state.superProps.clear(),this.state.breadcrumbs.clear(),this.state.errorContext={},this.state.errorTags={},this.state.developerUserId=null,this.state.autoTracker){let e=new F(this.state.options.autoTrack,(t,n)=>this.track(t,n));this.state.autoTracker=e,e.install()}}}diagnostics(){if(!this.state)return{started:!1,anonymousId:null,crossdeckCustomerId:null,developerUserId:null,sdkVersion:null,baseUrl:null,clock:{lastServerTime:null,lastClientTime:null,skewMs:null},entitlements:{count:0,lastUpdated:0,stale:!1,listenerErrors:0},events:{buffered:0,dropped:0,inFlight:0,lastFlushAt:0,lastError:null,consecutiveFailures:0,nextRetryAt:null}};let e=this.state,t=e.lastServerTime!==null&&e.lastClientTime!==null?e.lastClientTime-e.lastServerTime:null;return{started:!0,anonymousId:e.identity.anonymousId,crossdeckCustomerId:e.identity.crossdeckCustomerId,developerUserId:e.developerUserId,sdkVersion:e.options.sdkVersion,baseUrl:e.options.baseUrl,clock:{lastServerTime:e.lastServerTime,lastClientTime:e.lastClientTime,skewMs:t},entitlements:{count:e.entitlements.list().length,lastUpdated:e.entitlements.freshness,stale:e.entitlements.isStale,listenerErrors:e.entitlements.listenerErrors},events:e.events.getStats()}}requireStarted(){if(!this.state)throw new y({type:"configuration_error",code:"not_initialized",message:"Call Crossdeck.init({ appId, publicKey, environment }) before any other method."});return this.state}identityQueryParams(){let e=this.requireStarted();return e.identity.crossdeckCustomerId?{customerId:e.identity.crossdeckCustomerId}:e.developerUserId?{userId:e.developerUserId}:{anonymousId:e.identity.anonymousId}}identityHintForEvent(){let e=this.requireStarted(),t={anonymousId:e.identity.anonymousId};return e.developerUserId&&(t.developerUserId=e.developerUserId),e.identity.crossdeckCustomerId&&(t.crossdeckCustomerId=e.identity.crossdeckCustomerId),t}mintEventId(){return`evt_${Date.now().toString(36)}${k(8)}`}},Ce=new O;function dt(r){return r.startsWith("cd_pub_test_")?"sandbox":r.startsWith("cd_pub_live_")?"production":null}function pt(){let r=globalThis.window;if(r?.__CROSSDECK_FORCE_LIVE__===!0)return!1;let e=r?.location?.hostname;return e?!!(e==="localhost"||e==="127.0.0.1"||e==="::1"||e==="[::1]"||e.endsWith(".local")||/^10\./.test(e)||/^192\.168\./.test(e)||/^172\.(1[6-9]|2\d|3[0-1])\./.test(e)):!1}function ft(r){return r===!1?{sessions:!1,pageViews:!1,deviceInfo:!1,clicks:!1,webVitals:!1,errors:!1}:r===void 0||r===!0?{..._}:{sessions:r.sessions??_.sessions,pageViews:r.pageViews??_.pageViews,deviceInfo:r.deviceInfo??_.deviceInfo,clicks:r.clicks??_.clicks,webVitals:r.webVitals??_.webVitals,errors:r.errors??_.errors}}function ht(r){let e=globalThis.window,t=globalThis.document;if(!e||!t)return()=>{};let n=()=>{t.visibilityState==="hidden"&&r()},s=()=>r();return t.addEventListener("visibilitychange",n),e.addEventListener("pagehide",s),e.addEventListener("beforeunload",s),()=>{t.removeEventListener("visibilitychange",n),e.removeEventListener("pagehide",s),e.removeEventListener("beforeunload",s)}}var he=Object.freeze([{code:"invalid_public_key",type:"configuration_error",description:"The publishable key passed to Crossdeck.init() doesn't start with cd_pub_.",resolution:"Copy the key from your Crossdeck dashboard \u2192 API keys page.",retryable:!1},{code:"missing_app_id",type:"configuration_error",description:"Crossdeck.init() was called without an appId.",resolution:"Add appId to your init options \u2014 find it in the dashboard's Apps page.",retryable:!1},{code:"invalid_environment",type:"configuration_error",description:"Crossdeck.init() requires environment: 'production' | 'sandbox'.",resolution:'Pass the literal string "production" or "sandbox" \u2014 no other values are accepted.',retryable:!1},{code:"environment_mismatch",type:"configuration_error",description:"The publishable key's env prefix doesn't match the declared environment option.",resolution:"Either change `environment` to match the key prefix (cd_pub_test_ \u2194 sandbox, cd_pub_live_ \u2194 production), or swap the key for one minted in the right env.",retryable:!1},{code:"not_initialized",type:"configuration_error",description:"An SDK method was called before Crossdeck.init().",resolution:"Call Crossdeck.init({ appId, publicKey, environment }) once at app startup before any other method.",retryable:!1},{code:"missing_user_id",type:"invalid_request_error",description:"identify() was called with an empty userId.",resolution:"Pass a stable, non-empty user identifier from your auth layer \u2014 never a hardcoded placeholder.",retryable:!1},{code:"missing_event_name",type:"invalid_request_error",description:"track() was called without an event name.",resolution:"Pass a non-empty string as the first argument.",retryable:!1},{code:"missing_group_type",type:"invalid_request_error",description:"group() was called without a group type.",resolution:'Pass a non-empty type (e.g. "org", "team") as the first argument.',retryable:!1},{code:"missing_signed_transaction_info",type:"invalid_request_error",description:"syncPurchases() was called without StoreKit 2 signed transaction info.",resolution:"Pass the JWS string from Transaction.currentEntitlements / Transaction.updates.",retryable:!1},{code:"fetch_failed",type:"network_error",description:"The underlying fetch() call failed (typically a network outage or DNS issue).",resolution:"Check the user's network. The SDK will retry automatically with exponential backoff.",retryable:!0},{code:"request_timeout",type:"network_error",description:"A request was aborted after the configured timeoutMs (default 15s).",resolution:"Check the user's connection. Increase timeoutMs in init options if the user is on a known-slow network.",retryable:!0},{code:"invalid_json_response",type:"internal_error",description:"The server returned a 2xx with an unparseable body.",resolution:"Likely a transient backend bug. Retry; if it persists, contact support with the requestId.",retryable:!0}]);function xe(r){return he.find(e=>e.code===r)}return Fe(gt);})();
|
|
1
|
+
"use strict";var Crossdeck=(()=>{var re=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var Re=Object.getOwnPropertyNames;var Ae=Object.prototype.hasOwnProperty;var Pe=(r,e)=>{for(var t in e)re(r,t,{get:e[t],enumerable:!0})},De=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Re(e))!Ae.call(r,s)&&s!==t&&re(r,s,{get:()=>e[s],enumerable:!(n=Ie(e,s))||n.enumerable});return r};var Fe=r=>De(re({},"__esModule",{value:!0}),r);var vt={};Pe(vt,{CROSSDECK_ERROR_CODES:()=>he,Crossdeck:()=>Ce,CrossdeckClient:()=>M,CrossdeckError:()=>b,DEFAULT_BASE_URL:()=>N,MemoryStorage:()=>_,SDK_NAME:()=>C,SDK_VERSION:()=>A,getErrorCode:()=>xe});var b=class r extends Error{constructor(e){super(e.message),this.name="CrossdeckError",this.type=e.type,this.code=e.code,this.requestId=e.requestId,this.status=e.status,this.retryAfterMs=e.retryAfterMs,Object.setPrototypeOf(this,r.prototype)}};async function ge(r){let e=r.headers.get("x-request-id")??void 0,t=Le(r.headers.get("retry-after")),n;try{n=await r.json()}catch{n=null}let s=n?.error;return s&&typeof s.type=="string"&&typeof s.code=="string"?new b({type:s.type,code:s.code,message:s.message??`HTTP ${r.status}`,requestId:s.request_id??e,status:r.status,retryAfterMs:t}):new b({type:Oe(r.status),code:`http_${r.status}`,message:`HTTP ${r.status} ${r.statusText||""}`.trim(),requestId:e,status:r.status,retryAfterMs:t})}function Le(r){if(!r)return;let e=r.trim();if(!e)return;if(/^\d+(\.\d+)?$/.test(e)){let s=Number(e);return!Number.isFinite(s)||s<0?void 0:Math.round(s*1e3)}if(!/[a-zA-Z,/:]/.test(e))return;let t=Date.parse(e);if(!Number.isFinite(t))return;let n=t-Date.now();return n>0?n:0}function Oe(r){return r===401?"authentication_error":r===403?"permission_error":r===429?"rate_limit_error":r>=400&&r<500?"invalid_request_error":"internal_error"}var A="1.3.0",C="@cross-deck/web";var N="https://api.cross-deck.com/v1",Me=15e3,B=class{constructor(e){this.config=e}async request(e,t,n={}){if(this.config.localDevMode)return Ue(t);let s=this.buildUrl(t,n.query),i={Authorization:`Bearer ${this.config.publicKey}`,"Crossdeck-Sdk-Version":`${C}@${this.config.sdkVersion}`,Accept:"application/json"};n.idempotencyKey&&(i["Idempotency-Key"]=n.idempotencyKey);let c;n.body!==void 0&&(i["Content-Type"]="application/json",c=JSON.stringify(n.body));let o=n.timeoutMs??this.config.timeoutMs??Me,a=typeof AbortController<"u"&&o>0?new AbortController:null,d=null;a&&o>0&&(d=setTimeout(()=>a.abort(),o));let u;try{u=await fetch(s,{method:e,headers:i,body:c,keepalive:n.keepalive===!0,signal:a?.signal})}catch(l){let p=a?.signal?.aborted===!0;throw new b({type:"network_error",code:p?"request_timeout":"fetch_failed",message:p?`Request to ${t} aborted after ${o}ms`:l instanceof Error?l.message:"fetch failed"})}finally{d!==null&&clearTimeout(d)}if(!u.ok)throw await ge(u);if(u.status!==204)try{return await u.json()}catch{throw new b({type:"internal_error",code:"invalid_json_response",message:"Server returned a 2xx with an unparseable body.",requestId:u.headers.get("x-request-id")??void 0,status:u.status})}}get isLocalDevMode(){return this.config.localDevMode===!0}buildUrl(e,t){let n=this.config.baseUrl.replace(/\/+$/,""),s=e.startsWith("/")?e:`/${e}`,i=n+s;if(t){let c=new URLSearchParams;for(let[a,d]of Object.entries(t))typeof d=="string"&&d.length>0&&c.append(a,d);let o=c.toString();o&&(i+=(i.includes("?")?"&":"?")+o)}return i}},$=null;function Ue(r){return r.startsWith("/sdk/heartbeat")?{object:"heartbeat",ok:!0,projectId:"proj_local_dev",appId:"app_local_dev",platform:"web",env:"sandbox",serverTime:Date.now()}:r.startsWith("/identity/alias")?($||($=`cdcust_local_${typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID().replace(/-/g,"").slice(0,16):Math.random().toString(36).slice(2,18)}`),{object:"alias_result",crossdeckCustomerId:$,linked:[],mergePending:!1,env:"sandbox"}):r.startsWith("/entitlements")?{object:"list",data:[],crossdeckCustomerId:$??"",env:"sandbox"}:r.startsWith("/events")?{object:"list",received:0,env:"sandbox"}:{}}var P="anon_id",D="cdcust_id",j=class{constructor(e,t,n){this.primary=e;this.prefix=t;this.secondary=n??null;let s=e.getItem(t+P),i=e.getItem(t+D),c=this.secondary?.getItem(t+P)??null,o=this.secondary?.getItem(t+D)??null,a=s??c,d=i??o;this.state={anonymousId:a??this.mintAnonymousId(),crossdeckCustomerId:d},(!s||!c)&&this.writeBoth(t+P,this.state.anonymousId),d&&(!i||!o)&&this.writeBoth(t+D,d)}get anonymousId(){return this.state.anonymousId}get crossdeckCustomerId(){return this.state.crossdeckCustomerId}setCrossdeckCustomerId(e){this.state.crossdeckCustomerId=e,this.writeBoth(this.prefix+D,e)}reset(){this.deleteBoth(this.prefix+P),this.deleteBoth(this.prefix+D),this.state={anonymousId:this.mintAnonymousId(),crossdeckCustomerId:null},this.writeBoth(this.prefix+P,this.state.anonymousId)}mintAnonymousId(){let e=Date.now().toString(36),t=w(10);return`anon_${e}${t}`}writeBoth(e,t){try{this.primary.setItem(e,t)}catch{}if(this.secondary)try{this.secondary.setItem(e,t)}catch{}}deleteBoth(e){try{this.primary.removeItem(e)}catch{}if(this.secondary)try{this.secondary.removeItem(e)}catch{}}};function w(r){let e="0123456789abcdefghijklmnopqrstuvwxyz",t=[],n=globalThis.crypto;if(n?.getRandomValues){let s=new Uint8Array(r);n.getRandomValues(s);for(let i=0;i<r;i++)t.push(e[s[i]%e.length]??"0")}else for(let s=0;s<r;s++)t.push(e[Math.floor(Math.random()*e.length)]??"0");return t.join("")}var H=class{constructor(e,t="crossdeck:entitlements",n=864e5){this.all=[];this.lastUpdated=0;this.lastRefreshFailedAt=0;this.listeners=new Set;this.listenerErrorCount=0;this.storage=e,this.storageKey=t,this.staleAfterMs=n,this.hydrate()}isEntitled(e){let t=Date.now()/1e3;return this.all.some(n=>n.key===e&&n.isActive&&(n.validUntil==null||n.validUntil>t))}list(){return this.all.slice()}get freshness(){return this.lastUpdated}get isStale(){return this.lastRefreshFailedAt>this.lastUpdated?!0:this.lastUpdated>0&&Date.now()-this.lastUpdated>this.staleAfterMs}get refreshFailedAt(){return this.lastRefreshFailedAt}get listenerErrors(){return this.listenerErrorCount}markRefreshFailed(){this.lastRefreshFailedAt=Date.now()}setFromList(e){this.all=e.slice(),this.lastUpdated=Date.now(),this.lastRefreshFailedAt=0,this.persist(),this.notify()}clear(){if(this.all=[],this.lastUpdated=0,this.lastRefreshFailedAt=0,this.storage)try{this.storage.removeItem(this.storageKey)}catch{}this.notify()}subscribe(e){this.listeners.add(e);let t=!1;return()=>{t||(t=!0,this.listeners.delete(e))}}hydrate(){if(this.storage)try{let e=this.storage.getItem(this.storageKey);if(!e)return;let t=JSON.parse(e);t&&t.v===1&&Array.isArray(t.entitlements)&&(this.all=t.entitlements,this.lastUpdated=typeof t.lastUpdated=="number"?t.lastUpdated:0)}catch{}}persist(){if(this.storage)try{let e={v:1,entitlements:this.all,lastUpdated:this.lastUpdated};this.storage.setItem(this.storageKey,JSON.stringify(e))}catch{}}notify(){if(this.listeners.size===0)return;let e=this.all.slice(),t=[...this.listeners];for(let n of t)try{n(e)}catch{this.listenerErrorCount+=1}}};function Ve(r,e,t={},n=Math.random){let s=t.baseMs??1e3,i=t.maxMs??6e4,c=t.factor??2,o=Math.min(r,30),d=Math.min(i,s*Math.pow(c,o))*n();if(e!==void 0){let l=Math.min(864e5,e);if(l>d)return l}return Math.max(0,Math.round(d))}var K=class{constructor(e={}){this.options=e;this.attempts=0}get consecutiveFailures(){return this.attempts}get isWarning(){return this.attempts>=(this.options.failuresBeforeWarn??8)}nextDelay(e,t=Math.random){let n=Ve(this.attempts,e,this.options,t);return this.attempts+=1,n}recordSuccess(){this.attempts=0}};var F=1e3,W=class{constructor(e){this.cfg=e;this.buffer=[];this.pendingBatch=null;this.pendingBatchId=null;this.dropped=0;this.inFlight=0;this.lastFlushAt=0;this.lastError=null;this.cancelTimer=null;this.firstFlushFired=!1;this.nextRetryAt=null;if(this.retry=new K(e.retry??{}),this.persistent=e.persistentStore??null,this.persistent){let t=this.persistent.load();t.length>0&&(t.length>F?(this.dropped+=t.length-F,this.buffer=t.slice(t.length-F)):this.buffer=t,this.cfg.onBufferChange?.(this.buffer.length),this.scheduleIdleFlush())}}enqueue(e){if(this.buffer.push(e),this.buffer.length>F){let t=this.buffer.length-F;this.buffer.splice(0,t),this.dropped+=t,this.cfg.onDrop?.(t)}this.cfg.onBufferChange?.(this.buffer.length),this.persistAll(),this.buffer.length>=this.cfg.batchSize?this.flush():this.scheduleIdleFlush()}async flush(e={}){let t,n;if(this.pendingBatch!==null&&this.pendingBatchId!==null)t=this.pendingBatch,n=this.pendingBatchId;else{if(this.buffer.length===0)return null;t=this.buffer.splice(0),n=this.mintBatchId(),this.pendingBatch=t,this.pendingBatchId=n,this.inFlight+=t.length,this.cfg.onBufferChange?.(this.buffer.length),this.persistAll()}this.cancelTimerIfSet(),this.nextRetryAt=null;try{let s=this.cfg.envelope(),i=await this.cfg.http.request("POST","/events",{body:{appId:s.appId,environment:s.environment,sdk:s.sdk,events:t},keepalive:e.keepalive===!0,idempotencyKey:n});return this.lastFlushAt=Date.now(),this.lastError=null,this.inFlight-=t.length,this.pendingBatch=null,this.pendingBatchId=null,this.retry.recordSuccess(),this.persistAll(),this.firstFlushFired||(this.firstFlushFired=!0,this.cfg.onFirstFlushSuccess?.()),i}catch(s){let i=s instanceof Error?s.message:String(s);if(this.lastError=i,$e(s)){let a=t.length;return this.pendingBatch=null,this.pendingBatchId=null,this.inFlight-=a,this.dropped+=a,this.persistAll(),this.cfg.onDrop?.(a),this.cfg.onPermanentFailure?.({status:s.status??0,droppedCount:a,lastError:i}),null}let c=qe(s),o=this.retry.nextDelay(c);return this.scheduleRetry(o),this.cfg.onRetryScheduled?.({delayMs:o,consecutiveFailures:this.retry.consecutiveFailures,retryAfterMs:c,lastError:i}),null}}reset(){this.cancelTimerIfSet(),this.nextRetryAt=null,this.buffer=[],this.pendingBatch=null,this.pendingBatchId=null,this.dropped=0,this.inFlight=0,this.lastError=null,this.retry.recordSuccess(),this.persistent?.clear(),this.cfg.onBufferChange?.(0)}getStats(){return{buffered:this.buffer.length,dropped:this.dropped,inFlight:this.inFlight,lastFlushAt:this.lastFlushAt,lastError:this.lastError,consecutiveFailures:this.retry.consecutiveFailures,nextRetryAt:this.nextRetryAt}}get pendingIdempotencyKey(){return this.pendingBatchId}persistAll(){if(this.persistent){if(this.pendingBatch===null){this.persistent.save(this.buffer);return}this.persistent.save([...this.pendingBatch,...this.buffer])}}scheduleIdleFlush(){this.cancelTimerIfSet();let e=this.cfg.scheduler??me;this.cancelTimer=e(()=>{this.flush()},this.cfg.intervalMs)}scheduleRetry(e){this.cancelTimerIfSet(),this.nextRetryAt=Date.now()+e;let t=this.cfg.scheduler??me;this.cancelTimer=t(()=>{this.flush()},e)}cancelTimerIfSet(){this.cancelTimer&&(this.cancelTimer(),this.cancelTimer=null)}mintBatchId(){return`batch_${Date.now().toString(36)}${w(10)}`}};function qe(r){if(r&&typeof r=="object"&&"retryAfterMs"in r){let e=r.retryAfterMs;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}}function $e(r){if(!r||typeof r!="object")return!1;let e=r.status;return!(typeof e!="number"||!Number.isFinite(e)||e<400||e>=500||e===408||e===429)}function me(r,e){let t=setTimeout(r,e);if(typeof t.unref=="function")try{t.unref()}catch{}return()=>clearTimeout(t)}var z=class{constructor(e){this.options=e;this.writeScheduled=!1;this.pendingSnapshot=null;this.key=`${e.prefix}queue.v1`}load(){let e;try{e=this.options.storage.getItem(this.key)}catch{return[]}if(!e)return[];try{let t=JSON.parse(e);return!t||t.version!==1||!Array.isArray(t.events)?[]:t.events}catch{return[]}}save(e){this.pendingSnapshot=e.slice(),!this.writeScheduled&&(this.writeScheduled=!0,queueMicrotask(()=>this.flushWrite()))}saveSync(e){this.pendingSnapshot=e.slice(),this.flushWrite()}clear(){this.pendingSnapshot=null,this.writeScheduled=!1;try{this.options.storage.removeItem(this.key)}catch{}}flushWrite(){this.writeScheduled=!1;let e=this.pendingSnapshot;if(this.pendingSnapshot=null,e===null)return;if(e.length===0){try{this.options.storage.removeItem(this.key)}catch{}return}let t={version:1,events:e};try{this.options.storage.setItem(this.key,JSON.stringify(t))}catch{}}};var _=class{constructor(){this.store=new Map}getItem(e){return this.store.get(e)??null}setItem(e,t){this.store.set(e,t)}removeItem(e){this.store.delete(e)}},X=class{constructor(e){this.maxAgeSec=e?.maxAgeSec??63072e3,this.secure=e?.secure??Be(),this.sameSite=e?.sameSite??"Lax"}getItem(e){if(!ne())return null;let t=globalThis.document,n=t.cookie?t.cookie.split(/;\s*/):[],s=encodeURIComponent(e)+"=";for(let i of n)if(i.startsWith(s))try{return decodeURIComponent(i.slice(s.length))}catch{return null}return null}setItem(e,t){if(!ne())return;let n=globalThis.document,s=[`${encodeURIComponent(e)}=${encodeURIComponent(t)}`,"Path=/",`Max-Age=${this.maxAgeSec}`,`SameSite=${this.sameSite}`];this.secure&&s.push("Secure");try{n.cookie=s.join("; ")}catch{}}removeItem(e){if(!ne())return;let t=globalThis.document,n=[`${encodeURIComponent(e)}=`,"Path=/","Max-Age=0",`SameSite=${this.sameSite}`];this.secure&&n.push("Secure");try{t.cookie=n.join("; ")}catch{}}};function ye(){try{let r=globalThis.localStorage;if(r){let e="__crossdeck_probe__";return r.setItem(e,"1"),r.removeItem(e),r}}catch{}return new _}function Be(){try{return globalThis.location?.protocol==="https:"}catch{return!1}}function ne(){return typeof globalThis.document<"u"}function Ne(){return typeof globalThis.window<"u"&&typeof globalThis.document<"u"&&typeof globalThis.navigator<"u"}function be(r){let e={};if(r?.appVersion&&(e.appVersion=r.appVersion),!Ne())return e;let t=globalThis.window,n=globalThis.navigator,s=globalThis.document;try{typeof n.language=="string"&&(e.locale=n.language)}catch{}try{e.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}try{t.screen&&(e.screenWidth=t.screen.width,e.screenHeight=t.screen.height),e.viewportWidth=t.innerWidth,e.viewportHeight=t.innerHeight,e.devicePixelRatio=t.devicePixelRatio}catch{}try{let i=n.userAgent??"",c=je(i);Object.assign(e,c)}catch{}try{let i=n.userAgentData;if(i?.platform&&!e.os&&(e.os=i.platform),i?.brands&&!e.browser){let c=i.brands.find(o=>!/Not[ .;A]*Brand/i.test(o.brand)&&!/Chromium/i.test(o.brand));c&&(e.browser=c.brand,e.browserVersion=c.version)}}catch{}return e}function je(r){let e={};if(/iPad|iPhone|iPod/.test(r)){e.os="iOS";let t=r.match(/OS (\d+[._]\d+(?:[._]\d+)?)/);t?.[1]&&(e.osVersion=t[1].replace(/_/g,"."))}else if(/Android/.test(r)){e.os="Android";let t=r.match(/Android (\d+(?:\.\d+)*)/);t?.[1]&&(e.osVersion=t[1])}else if(/Windows/.test(r)){e.os="Windows";let t=r.match(/Windows NT (\d+\.\d+)/);t?.[1]&&(e.osVersion=t[1])}else if(/Mac OS X|Macintosh/.test(r)){e.os="macOS";let t=r.match(/Mac OS X (\d+[._]\d+(?:[._]\d+)?)/);t?.[1]&&(e.osVersion=t[1].replace(/_/g,"."))}else/Linux/.test(r)&&(e.os="Linux");return/Edg\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Edge",e.browserVersion=r.match(/Edg\/(\d+(?:\.\d+)*)/)?.[1]):/Firefox\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Firefox",e.browserVersion=r.match(/Firefox\/(\d+(?:\.\d+)*)/)?.[1]):/OPR\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Opera",e.browserVersion=r.match(/OPR\/(\d+(?:\.\d+)*)/)?.[1]):/Chrome\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Chrome",e.browserVersion=r.match(/Chrome\/(\d+(?:\.\d+)*)/)?.[1]):/Version\/(\d+(?:\.\d+)*).*Safari/.test(r)&&(e.browser="Safari",e.browserVersion=r.match(/Version\/(\d+(?:\.\d+)*)/)?.[1]),e}var E={sessions:!0,pageViews:!0,deviceInfo:!0,clicks:!0,webVitals:!0,errors:!0},He=1800*1e3,se={utm_source:"",utm_medium:"",utm_campaign:"",utm_content:"",utm_term:"",referrer:"",gclid:"",fbclid:"",msclkid:"",ttclid:"",li_fat_id:"",twclid:""},L=class{constructor(e,t){this.cfg=e;this.track=t;this.session=null;this.cleanups=[];this.pageviewId=null}install(){ve()&&(this.cfg.sessions&&this.installSessionTracking(),this.cfg.pageViews&&this.installPageViewTracking(),this.cfg.clicks&&this.installClickTracking())}uninstall(){for(;this.cleanups.length;){let e=this.cleanups.pop();try{e?.()}catch{}}this.session&&!this.session.endedSent&&this.emitSessionEnd(),this.session=null}resetSession(){this.session&&!this.session.endedSent&&this.emitSessionEnd(),this.pageviewId=null,this.session=this.startNewSession(),this.emitSessionStart()}get currentSessionId(){return this.session?.sessionId??null}get currentPageviewId(){return this.pageviewId}get currentAcquisition(){return this.session?.acquisition??se}installSessionTracking(){this.session=this.startNewSession(),this.emitSessionStart();let e=()=>{if(!this.session)return;let i=globalThis.document;i.visibilityState==="hidden"?this.session.hiddenAt=Date.now():i.visibilityState==="visible"&&((this.session.hiddenAt?Date.now()-this.session.hiddenAt:0)>=He?(this.emitSessionEnd(),this.pageviewId=null,this.session=this.startNewSession(),this.emitSessionStart()):this.session.hiddenAt=null)},t=()=>this.emitSessionEnd(),n=globalThis.window,s=globalThis.document;s.addEventListener("visibilitychange",e),n.addEventListener("pagehide",t),n.addEventListener("beforeunload",t),this.cleanups.push(()=>{s.removeEventListener("visibilitychange",e),n.removeEventListener("pagehide",t),n.removeEventListener("beforeunload",t)})}startNewSession(){return{sessionId:Ze(),startedAt:Date.now(),hiddenAt:null,endedSent:!1,acquisition:et()}}emitSessionStart(){this.session&&this.track("session.started",{sessionId:this.session.sessionId})}emitSessionEnd(){if(!this.session||this.session.endedSent)return;let e=Date.now()-this.session.startedAt;this.track("session.ended",{sessionId:this.session.sessionId,durationMs:e}),this.session.endedSent=!0}installPageViewTracking(){let e=globalThis.window,t=globalThis.document,n=0,s="",i=250,c=(p=!1)=>{let h=e.location,f=h.href,m=Date.now();!p&&f===s&&m-n<i||(n=m,s=f,this.pageviewId=`pv_${Date.now().toString(36)}${w(10)}`,this.track("page.viewed",{pageviewId:this.pageviewId,path:h.pathname,url:f,search:h.search||void 0,hash:h.hash||void 0,title:t.title,referrer:t.referrer||void 0}))};c();let o=e.history.pushState,a=e.history.replaceState;function d(p,h,f){o.apply(this,[p,h,f]),queueMicrotask(c)}function u(p,h,f){a.apply(this,[p,h,f]),queueMicrotask(c)}e.history.pushState=d,e.history.replaceState=u;let l=()=>c(!0);e.addEventListener("popstate",l),this.cleanups.push(()=>{e.history.pushState===d&&(e.history.pushState=o),e.history.replaceState===u&&(e.history.replaceState=a),e.removeEventListener("popstate",l)})}installClickTracking(){let e=globalThis.window,t=globalThis.document,n=0,s=null,i=100,c=64,o=a=>{let d=a.target;if(!d||!(d instanceof Element))return;let u=Date.now();if(d===s&&u-n<i)return;n=u,s=d;let p=Ke(d)||d;if(We(p)||ze(p)||Xe(p))return;let h=p.tagName.toLowerCase(),f=Ge(Qe(p),c),m=p.href||void 0,g=p.target||void 0,v=p.id||void 0,S=p.getAttribute("role")||void 0,U=p.getAttribute("aria-label")||void 0,V=Je(p),y=Ye(p),k=h==="a"&&!!m,R=p.getAttribute("data-cd-event"),T={selector:V,tag:h,text:f,elementId:v,role:S,ariaLabel:U,href:m,isLink:k,linkTarget:g,viewportX:a.clientX,viewportY:a.clientY,pageX:a.pageX,pageY:a.pageY,...y};for(let q of Object.keys(T))(T[q]===void 0||T[q]===null||T[q]==="")&&delete T[q];this.track(R||"element.clicked",T)};t.addEventListener("click",o,{capture:!0,passive:!0}),this.cleanups.push(()=>{t.removeEventListener("click",o,{capture:!0})})}};function Ke(r){return r.closest("[data-cd-event]")||r.closest("[data-cd-noTrack]")||r.closest("button, a, [role='button'], [role='link'], input[type='button'], input[type='submit']")||null}function We(r){if(!(r instanceof HTMLElement))return!1;let e=r.tagName.toLowerCase();if(e==="textarea"||e==="select")return!0;if(e==="input"){let t=(r.type||"").toLowerCase();return t!=="button"&&t!=="submit"&&t!=="image"&&t!=="reset"}return!1}function ze(r){return!!r.closest("[data-cd-noTrack], [data-cd-no-track], .cd-noTrack, .cd-no-track")}function Xe(r){return!!r.closest('input[type="password"]')}function Qe(r){let e=d=>d.replace(/\s+/g," ").trim(),t=r.getAttribute("data-cd-track")||r.getAttribute("data-track")||r.getAttribute("data-testid");if(t){let d=e(t);if(d)return d}let n=r.getAttribute("aria-label");if(n){let d=e(n);if(d)return d}let s=r.getAttribute("aria-labelledby");if(s&&typeof r.ownerDocument?.getElementById=="function"){let d=[];for(let u of s.split(/\s+/)){let l=r.ownerDocument.getElementById(u),p=l?.textContent?e(l.textContent):"";p&&d.push(p)}if(d.length>0)return d.join(" ")}if(r instanceof HTMLInputElement&&r.value){let d=e(r.value);if(d)return d}let i=e(r.textContent||"");if(i)return i;let c=r.getAttribute("title");if(c){let d=e(c);if(d)return d}let o=r.querySelector("img[alt]");if(o){let d=o.getAttribute("alt")??"",u=e(d);if(u)return u}let a=r.querySelector("svg title");if(a?.textContent){let d=e(a.textContent);if(d)return d}return""}function Ge(r,e){return r.length<=e?r:r.slice(0,e-1)+"\u2026"}function Je(r){let e=[],t=r,n=0;for(;t&&t.nodeName.toLowerCase()!=="body"&&n<5;){let s=t.nodeName.toLowerCase();if(t.id){e.unshift(`${s}#${t.id}`);break}if(t.classList.length>0){let i=Array.from(t.classList).filter(c=>!c.startsWith("cd-")).slice(0,2).join(".");i&&(s+=`.${i}`)}e.unshift(s),t=t.parentElement,n++}return e.join(" > ")}function Ye(r){let e={};if(!(r instanceof HTMLElement))return e;for(let t of r.getAttributeNames()){if(!t.startsWith("data-")||t==="data-cd-noTrack"||t==="data-cd-no-track"||t==="data-cd-event")continue;let n=r.getAttribute(t)||"",s=t.replace(/^data-cd-prop-/,"").replace(/^data-/,"");e[s]=n}return e}function ve(){return typeof globalThis.window<"u"&&typeof globalThis.document<"u"}function Ze(){return`sess_${Date.now().toString(36)}${w(10)}`}function et(){if(!ve())return{...se};let r={...se};try{let e=globalThis.window,t=new URLSearchParams(e.location.search??"");r.utm_source=t.get("utm_source")??"",r.utm_medium=t.get("utm_medium")??"",r.utm_campaign=t.get("utm_campaign")??"",r.utm_content=t.get("utm_content")??"",r.utm_term=t.get("utm_term")??"",r.gclid=t.get("gclid")??"",r.fbclid=t.get("fbclid")??"",r.msclkid=t.get("msclkid")??"",r.ttclid=t.get("ttclid")??"",r.li_fat_id=t.get("li_fat_id")??"",r.twclid=t.get("twclid")??""}catch{}try{let e=globalThis.document;typeof e.referrer=="string"&&(r.referrer=e.referrer)}catch{}return r}var tt=[/^email$/i,/^password$/i,/^token$/i,/^secret$/i,/^card$/i,/^phone$/i,/password/i,/credit_?card/i];function ke(r){if(!r)return[];let e=[];for(let t of Object.keys(r))tt.some(n=>n.test(t))&&e.push(t);return e}var Q=class{constructor(){this.enabled=!1;this.seen=new Set}emit(e,t,n){if(!this.enabled)return;if(rt.has(e)){if(this.seen.has(e))return;this.seen.add(e)}let s=n?` ${nt(n)}`:"";console.info(`[crossdeck:${e}] ${t}${s}`)}},rt=new Set(["sdk.configured","sdk.first_event_sent","sdk.environment_mismatch"]);function nt(r){try{return JSON.stringify(r)}catch{return"[unserialisable context]"}}function O(r,e={}){let t=[];if(!r)return{properties:{},warnings:t};let n=e.maxStringLength??1024,s=e.maxBatchPropertyBytes??8192,i=e.maxDepth??5,c=new Set,o=(u,l,p)=>{if(p>i)return t.push({kind:"depth_exceeded",key:l}),{keep:!0,value:"[depth-exceeded]"};if(u===null)return{keep:!0,value:null};let h=typeof u;if(h==="string"){let f=u;return f.length>n?(t.push({kind:"truncated_string",key:l}),{keep:!0,value:f.slice(0,n-1)+"\u2026"}):{keep:!0,value:f}}if(h==="number")return Number.isFinite(u)?{keep:!0,value:u}:(t.push({kind:"non_serialisable",key:l}),{keep:!0,value:null});if(h==="boolean")return{keep:!0,value:u};if(h==="bigint")return t.push({kind:"coerced_bigint",key:l}),{keep:!0,value:u.toString()};if(h==="function")return t.push({kind:"dropped_function",key:l}),{keep:!1,value:void 0};if(h==="symbol")return t.push({kind:"dropped_symbol",key:l}),{keep:!1,value:void 0};if(h==="undefined")return t.push({kind:"dropped_undefined",key:l}),{keep:!1,value:void 0};if(u instanceof Date)return t.push({kind:"coerced_date",key:l}),{keep:!0,value:Number.isFinite(u.getTime())?u.toISOString():null};if(u instanceof Error)return t.push({kind:"coerced_error",key:l}),{keep:!0,value:{name:u.name,message:u.message,stack:typeof u.stack=="string"?u.stack.slice(0,n):void 0}};if(u instanceof Map){t.push({kind:"coerced_map",key:l});let f={};for(let[m,g]of u.entries()){let v=typeof m=="string"?m:String(m),S=o(g,`${l}.${v}`,p+1);S.keep&&(f[v]=S.value)}return{keep:!0,value:f}}if(u instanceof Set){t.push({kind:"coerced_set",key:l});let f=[],m=0;for(let g of u.values()){let v=o(g,`${l}[${m}]`,p+1);v.keep&&f.push(v.value),m++}return{keep:!0,value:f}}if(Array.isArray(u)){if(c.has(u))return t.push({kind:"circular_reference",key:l}),{keep:!0,value:"[circular]"};c.add(u);let f=[];for(let m=0;m<u.length;m++){let g=o(u[m],`${l}[${m}]`,p+1);g.keep&&f.push(g.value)}return c.delete(u),{keep:!0,value:f}}if(h==="object"){let f=u;if(c.has(f))return t.push({kind:"circular_reference",key:l}),{keep:!0,value:"[circular]"};c.add(f);let m={};for(let g of Object.keys(f)){let v=o(f[g],`${l}.${g}`,p+1);v.keep&&(m[g]=v.value)}return c.delete(f),{keep:!0,value:m}}t.push({kind:"non_serialisable",key:l});try{return{keep:!0,value:String(u)}}catch{return{keep:!1,value:void 0}}},a={};for(let u of Object.keys(r)){let l=o(r[u],u,0);l.keep&&(a[u]=l.value)}let d=we(a);if(d&&ie(d)>s){t.push({kind:"size_cap_exceeded",key:"*"});let u=Object.keys(a).map(p=>({k:p,size:ie(we(a[p])??"")})).sort((p,h)=>h.size-p.size),l=ie(d);for(let{k:p}of u){if(l<=s)break;l-=u.find(h=>h.k===p).size,delete a[p]}a.__truncated=!0}return{properties:a,warnings:t}}function we(r){try{return JSON.stringify(r)??null}catch{return null}}function ie(r){return typeof TextEncoder<"u"?new TextEncoder().encode(r).length:r.length*4}var G="super_props",oe="groups",J=class{constructor(e,t){this.storage=e;this.prefix=t;this.superProps={};this.groups={};this.superProps=_e(e,t+G)??{},this.groups=_e(e,t+oe)??{}}register(e){for(let[t,n]of Object.entries(e))n===null?delete this.superProps[t]:n!==void 0&&(this.superProps[t]=n);return ae(this.storage,this.prefix+G,this.superProps),{...this.superProps}}unregister(e){e in this.superProps&&(delete this.superProps[e],ae(this.storage,this.prefix+G,this.superProps))}getSuperProperties(){return{...this.superProps}}setGroup(e,t,n){t===null?delete this.groups[e]:this.groups[e]=n!==void 0?{id:t,traits:n}:{id:t},ae(this.storage,this.prefix+oe,this.groups)}getGroups(){return JSON.parse(JSON.stringify(this.groups))}getGroupIds(){let e={};for(let[t,n]of Object.entries(this.groups))e[t]=n.id;return e}clear(){this.superProps={},this.groups={};try{this.storage.removeItem(this.prefix+G)}catch{}try{this.storage.removeItem(this.prefix+oe)}catch{}}};function _e(r,e){let t;try{t=r.getItem(e)}catch{return null}if(!t)return null;try{return JSON.parse(t)}catch{return null}}function ae(r,e,t){try{r.setItem(e,JSON.stringify(t))}catch{}}var Y=class{constructor(e,t){this.cfg=e;this.report=t;this.observers=[];this.flushed=new Set;this.cls=0;this.clsEntries=[];this.inp=0;this.cleanups=[]}install(){if(!this.cfg.enabled||typeof PerformanceObserver>"u"||typeof globalThis>"u"||!("document"in globalThis))return;let e=globalThis.document;try{let i=new PerformanceObserver(c=>{for(let o of c.getEntries()){let a=o;a.responseStart>0&&!this.flushed.has("ttfb")&&(this.flushed.add("ttfb"),this.report("webvitals.ttfb",{valueMs:Math.round(a.responseStart-a.startTime)}))}});i.observe({type:"navigation",buffered:!0}),this.observers.push(i)}catch{}try{let i=new PerformanceObserver(c=>{for(let o of c.getEntries())o.name==="first-contentful-paint"&&!this.flushed.has("fcp")&&(this.flushed.add("fcp"),this.report("webvitals.fcp",{valueMs:Math.round(o.startTime)}))});i.observe({type:"paint",buffered:!0}),this.observers.push(i)}catch{}let t=0;try{let i=new PerformanceObserver(c=>{let o=c.getEntries(),a=o[o.length-1];a&&(t=a.startTime)});i.observe({type:"largest-contentful-paint",buffered:!0}),this.observers.push(i)}catch{}try{let i=new PerformanceObserver(c=>{for(let o of c.getEntries()){let a=o;typeof a.value=="number"&&!a.hadRecentInput&&(this.cls+=a.value,this.clsEntries.push(o))}});i.observe({type:"layout-shift",buffered:!0}),this.observers.push(i)}catch{}try{let i=new PerformanceObserver(c=>{for(let o of c.getEntries()){let a=o;a.interactionId&&a.duration>this.inp&&(this.inp=a.duration)}});try{i.observe({type:"event",buffered:!0,durationThreshold:16})}catch{i.observe({type:"first-input",buffered:!0})}this.observers.push(i)}catch{}let n=()=>{t>0&&!this.flushed.has("lcp")&&(this.flushed.add("lcp"),this.report("webvitals.lcp",{valueMs:Math.round(t)})),this.cls>0&&!this.flushed.has("cls")&&(this.flushed.add("cls"),this.report("webvitals.cls",{value:Math.round(this.cls*1e3)/1e3})),this.inp>0&&!this.flushed.has("inp")&&(this.flushed.add("inp"),this.report("webvitals.inp",{valueMs:Math.round(this.inp)}))},s=()=>{e.visibilityState==="hidden"&&n()};e.addEventListener("visibilitychange",s),globalThis.window.addEventListener("pagehide",n),this.cleanups.push(()=>{e.removeEventListener("visibilitychange",s),globalThis.window.removeEventListener("pagehide",n)})}uninstall(){for(let e of this.observers)try{e.disconnect()}catch{}this.observers=[];for(let e of this.cleanups.splice(0))try{e()}catch{}}};var st={analytics:!0,marketing:!0,errors:!0},Z=class{constructor(e){this.state={...st};this.dntDenied=!1;e?.respectDnt&&this.detectDnt()&&(this.dntDenied=!0,this.state={analytics:!1,marketing:!1,errors:!1})}set(e){if(this.dntDenied)return{...this.state};for(let t of Object.keys(e)){let n=e[t];typeof n=="boolean"&&(this.state[t]=n)}return{...this.state}}get(){return{...this.state}}get analytics(){return this.state.analytics}get marketing(){return this.state.marketing}get errors(){return this.state.errors}get isDntDenied(){return this.dntDenied}detectDnt(){try{let e=globalThis.navigator;return e?[e.doNotTrack,e.msDoNotTrack,globalThis.doNotTrack].some(n=>n==="1"||n==="yes"):!1}catch{return!1}}},it=/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,ot=/\b\d(?:[ -]?\d){12,18}\b/g,at="<email>",ct="<card>";function ut(r){return r&&r.replace(it,at).replace(ot,ct)}function ce(r){let e={};for(let t of Object.keys(r))e[t]=Ee(r[t]);return e}function Ee(r){return typeof r=="string"?ut(r):Array.isArray(r)?r.map(Ee):r&&typeof r=="object"&&r.constructor===Object?ce(r):r}var ee=class{constructor(e=50){this.maxSize=e;this.items=[]}add(e){this.items.push(e),this.items.length>this.maxSize&&this.items.shift()}snapshot(){return this.items.slice()}clear(){this.items=[]}get size(){return this.items.length}};function le(r){if(!r||typeof r!="string")return[];let e=r.split(`
|
|
2
|
+
`),t=[];for(let n of e){let s=n.trim();if(!s)continue;let i=lt(s);i&&t.push(i)}return t}function lt(r){let e=/^at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)$/.exec(r);return e?ue({function:e[1],filename:e[2],lineno:parseInt(e[3],10),colno:parseInt(e[4],10),raw:r}):(e=/^at\s+(.+?):(\d+):(\d+)$/.exec(r),e?ue({function:"?",filename:e[1],lineno:parseInt(e[2],10),colno:parseInt(e[3],10),raw:r}):(e=/^(.*?)@(.+?):(\d+):(\d+)$/.exec(r),e?ue({function:e[1]||"?",filename:e[2],lineno:parseInt(e[3],10),colno:parseInt(e[4],10),raw:r}):/^\w*Error/.test(r)||!r.includes(":")?null:{function:"?",filename:"",lineno:0,colno:0,in_app:!0,raw:r}))}function ue(r){return{function:r.function||"?",filename:r.filename,lineno:Number.isFinite(r.lineno)?r.lineno:0,colno:Number.isFinite(r.colno)?r.colno:0,in_app:dt(r.filename),raw:r.raw}}function dt(r){return r?!(/^(?:chrome|moz|safari|webkit)-extension:\/\//.test(r)||/\bcdn\.jsdelivr\.net\b/.test(r)||/\bunpkg\.com\b/.test(r)||/\bgoogletagmanager\.com\b/.test(r)||/\bgoogle-analytics\.com\b/.test(r)||/\b@cross-deck\/web\b/.test(r)||/\/crossdeck\.umd\.min\.js$/.test(r)):!0}function x(r,e,t){let n=e.filter(i=>i.in_app).slice(0,3),s=[(r||"").slice(0,200),...n.map(i=>`${i.function}@${i.filename}:${i.lineno}`)];if(n.length===0&&t){let i=[t.errorType??"",t.filename??"",t.lineno??"",t.colno??""].join(":");i!==":::"&&s.push(i)}return pt(s.join("|"))}function pt(r){let e=5381;for(let t=0;t<r.length;t++)e=(e<<5)+e+r.charCodeAt(t)|0;return(e>>>0).toString(16).padStart(8,"0")}var Se={enabled:!0,onError:!0,onUnhandledRejection:!0,wrapFetch:!0,wrapXhr:!0,captureConsole:!1,ignoreErrors:["ResizeObserver loop limit exceeded","ResizeObserver loop completed with undelivered notifications","Non-Error promise rejection captured"],allowUrls:[],denyUrls:[/^chrome-extension:\/\//,/^moz-extension:\/\//,/^safari-extension:\/\//,/^webkit-extension:\/\//,/^safari-web-extension:\/\//],sampleRate:1,maxPerFingerprintPerMinute:5,maxPerSession:100},te=class{constructor(e){this.opts=e;this.installed=!1;this.cleanups=[];this._reporting=!1;this.sessionCount=0;this.fingerprintWindow=new Map}install(){if(this.installed||!this.opts.config.enabled||typeof globalThis>"u"||!("window"in globalThis))return;let e=globalThis.window;this.opts.config.onError&&this.installOnErrorListener(e),this.opts.config.onUnhandledRejection&&this.installRejectionListener(e),this.opts.config.wrapFetch&&this.installFetchWrap(e),this.opts.config.wrapXhr&&this.installXhrWrap(e),this.opts.config.captureConsole&&this.installConsoleWrap(),this.installed=!0}uninstall(){for(let e of this.cleanups.splice(0))try{e()}catch{}this.installed=!1}captureError(e,t){if(this.opts.isConsented())try{let n=this.buildFromUnknown(e,"error.handled",t?.level??"error");t?.context&&(n.context={...n.context,...t.context}),t?.tags&&(n.tags={...n.tags,...t.tags}),this.maybeReport(n)}catch{}}captureMessage(e,t="info"){if(this.opts.isConsented())try{let n={timestamp:Date.now(),kind:"error.message",level:t,message:e,errorType:null,frames:[],rawStack:null,filename:null,lineno:null,colno:null,fingerprint:x(e,[]),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:this.opts.getContext(),tags:this.opts.getTags()};this.maybeReport(n)}catch{}}installOnErrorListener(e){let t=n=>{if(!this._reporting&&this.opts.isConsented())try{this._reporting=!0;let s=this.buildFromErrorEvent(n);this.maybeReport(s)}catch{}finally{this._reporting=!1}};e.addEventListener("error",t,!0),this.cleanups.push(()=>e.removeEventListener("error",t,!0))}installRejectionListener(e){let t=n=>{if(!this._reporting&&this.opts.isConsented())try{this._reporting=!0;let s=this.buildFromUnknown(n.reason,"error.unhandledrejection","error");this.maybeReport(s)}catch{}finally{this._reporting=!1}};e.addEventListener("unhandledrejection",t),this.cleanups.push(()=>e.removeEventListener("unhandledrejection",t))}installFetchWrap(e){let t=e.fetch?.bind(e);if(!t)return;let n=async(...s)=>{let i=s[0],c=s[1]??{},o=typeof i=="string"?i:i?.url??"",a=(c.method||"GET").toUpperCase(),d=Date.now();pe(o,this.opts.selfHostname)||this.opts.breadcrumbs.add({timestamp:d,category:"http",message:`${a} ${o}`,data:{url:o,method:a}});try{let u=await t(...s);return u.status>=500&&this.opts.isConsented()&&(pe(o,this.opts.selfHostname)||this.captureHttp({url:o,method:a,status:u.status,statusText:u.statusText})),u}catch(u){throw this.opts.isConsented()&&!o.includes("api.cross-deck.com")&&this.captureHttp({url:o,method:a,status:0,statusText:u instanceof Error?u.message:"network error"}),u}};e.fetch=n,this.cleanups.push(()=>{e.fetch===n&&(e.fetch=t)})}installXhrWrap(e){let n=e.XMLHttpRequest?.prototype;if(!n)return;let s=n.open,i=n.send,c=this;n.open=function(o,a,...d){return this._cdMethod=o,this._cdUrl=a,s.apply(this,[o,a,...d])},n.send=function(o){let a=this,d=()=>{try{if(a.status>=500&&c.opts.isConsented()){let u=a._cdUrl??"";pe(u,c.opts.selfHostname)||c.captureHttp({url:u,method:(a._cdMethod??"GET").toUpperCase(),status:a.status,statusText:a.statusText})}}catch{}};return a.addEventListener("loadend",d),i.apply(this,[o??null])},this.cleanups.push(()=>{n.open=s,n.send=i})}installConsoleWrap(){let e=globalThis.console;if(!e)return;let t=e.error.bind(e);e.error=(...n)=>{try{this.opts.isConsented()&&this.captureMessage(n.map(s=>ht(s)).join(" "),"error")}catch{}return t(...n)},this.cleanups.push(()=>{e.error=t})}buildFromErrorEvent(e){let t=e.error,n=e.filename||null,s=typeof e.lineno=="number"&&e.lineno>0?e.lineno:null,i=typeof e.colno=="number"&&e.colno>0?e.colno:null;if(t==null&&!n&&s==null&&(e.message==="Script error."||e.message==="Script error"||!e.message)){let h="Cross-origin script error (browser hid details \u2014 script needs crossorigin attribute + CORS headers)";return{timestamp:Date.now(),kind:"error.unhandled",level:"error",message:h,errorType:"ScriptError",frames:[],rawStack:null,filename:null,lineno:null,colno:null,fingerprint:x(h,[]),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:this.opts.getContext(),tags:{...this.opts.getTags(),cross_origin:"true"}}}let o=fe(t),a=(o.message||e.message||"Unknown error").slice(0,1024),d=t instanceof Error?t.stack??null:null,u=le(d),l=o.errorType??null,p=o.extras?{...this.opts.getContext(),__error_extras:o.extras}:this.opts.getContext();return{timestamp:Date.now(),kind:"error.unhandled",level:"error",message:a,errorType:l,frames:u,rawStack:d,filename:n,lineno:s,colno:i,fingerprint:x(a,u,{filename:n,lineno:s,colno:i,errorType:l}),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:p,tags:this.opts.getTags()}}buildFromUnknown(e,t,n){let s=fe(e),i=(s.message||"Unknown error").slice(0,1024),c=e instanceof Error?e.stack??null:null,o=le(c),a=s.errorType??null,d=s.extras?{...this.opts.getContext(),__error_extras:s.extras}:this.opts.getContext();return{timestamp:Date.now(),kind:t,level:n,message:i,errorType:a,frames:o,rawStack:c,filename:null,lineno:null,colno:null,fingerprint:x(i,o,{errorType:a}),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:d,tags:this.opts.getTags()}}captureHttp(e){try{let t=`HTTP ${e.status} ${e.method} ${e.url}`,n={timestamp:Date.now(),kind:"error.http",level:"error",message:t,errorType:"HTTPError",frames:[],rawStack:null,filename:e.url,lineno:null,colno:null,fingerprint:x(`HTTP ${e.status} ${e.method}`,[],{filename:e.url,errorType:"HTTPError"}),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:this.opts.getContext(),tags:this.opts.getTags(),http:e};this.maybeReport(n)}catch{}}maybeReport(e){if(this.sessionCount>=this.opts.config.maxPerSession||this.shouldIgnore(e)||!this.passesUrlGate(e)||!this.passesSample(e)||!this.passesRateLimit(e))return;let t=e,n=this.opts.beforeSend?.();if(n){try{t=n(e)}catch{t=e}if(!t)return}this.sessionCount+=1;try{this.opts.report(t)}catch{}}shouldIgnore(e){for(let t of this.opts.config.ignoreErrors)if(typeof t=="string"&&e.message.includes(t)||t instanceof RegExp&&t.test(e.message))return!0;return!1}passesUrlGate(e){let n=(e.frames.find(s=>s.filename)??null)?.filename??e.filename??"";if(!n)return!0;for(let s of this.opts.config.denyUrls)if(typeof s=="string"&&n.includes(s)||s instanceof RegExp&&s.test(n))return!1;if(this.opts.config.allowUrls.length>0){for(let s of this.opts.config.allowUrls)if(typeof s=="string"&&n.includes(s)||s instanceof RegExp&&s.test(n))return!0;return!1}return!0}passesSample(e){return this.opts.config.sampleRate>=1?!0:this.opts.config.sampleRate<=0?!1:parseInt(e.fingerprint.slice(0,2),16)/255<this.opts.config.sampleRate}passesRateLimit(e){let n=Date.now(),s=this.opts.config.maxPerFingerprintPerMinute,c=(this.fingerprintWindow.get(e.fingerprint)??[]).filter(o=>n-o<6e4);return c.length>=s?(this.fingerprintWindow.set(e.fingerprint,c),!1):(c.push(n),this.fingerprintWindow.set(e.fingerprint,c),!0)}};function fe(r){if(r===null)return{message:"(thrown: null)",errorType:null,extras:null};if(r===void 0)return{message:"(thrown: undefined)",errorType:null,extras:null};if(typeof r=="string")return{message:r,errorType:null,extras:null};if(typeof r=="number"||typeof r=="boolean"||typeof r=="bigint")return{message:String(r),errorType:typeof r,extras:null};if(typeof r=="symbol")return{message:r.toString(),errorType:"symbol",extras:null};if(typeof r=="function")return{message:`(thrown function: ${r.name||"anonymous"})`,errorType:"function",extras:null};if(r instanceof Error){let e=r.name||r.constructor?.name||"Error",t=typeof r.message=="string"&&r.message.length>0?r.message:I(r)||e,n={},s=ft(r);s.length>0&&(n.cause=s);for(let i of["code","status","statusCode","errno","response","data","detail","details"]){let c=r[i];c!==void 0&&typeof c!="function"&&(n[i]=de(c))}for(let i of Object.keys(r)){if(i==="message"||i==="stack"||i==="name"||i==="cause"||i in n)continue;let c=r[i];typeof c!="function"&&(n[i]=de(c))}return{message:t,errorType:e,extras:Object.keys(n).length>0?n:null}}if(typeof Response<"u"&&r instanceof Response)return{message:`HTTP ${r.status} ${r.statusText||""}${r.url?` ${r.url}`:""}`.trim(),errorType:"Response",extras:{status:r.status,statusText:r.statusText,url:r.url,type:r.type}};if(typeof r=="object"){let e=r,t=e.constructor&&typeof e.constructor=="function"&&e.constructor.name||null,n=typeof e.message=="string"&&e.message?e.message:null,s=typeof e.name=="string"&&e.name?e.name:null,i=null;try{let l=JSON.stringify(e);i=l==="{}"?null:l}catch{i=null}let c=I(e),o=n??i??(c&&c!=="[object Object]"?c:null)??(t?`(thrown ${t} with no message)`:"(thrown object with no message)"),a=s??t??null,d={},u=0;for(let l of Object.keys(e)){if(u>=20)break;if(l==="message"||l==="name")continue;let p=e[l];typeof p!="function"&&(d[l]=de(p),u++)}return{message:o,errorType:a,extras:Object.keys(d).length>0?d:null}}return{message:I(r)||"(unstringifiable thrown value)",errorType:null,extras:null}}function ft(r){let e=[],t=r.cause,n=0;for(;t!=null&&n<5;)t instanceof Error?(e.push({name:t.name||"Error",message:t.message||""}),t=t.cause):(e.push({name:"non-Error",message:I(t)}),t=null),n++;return e}function I(r){try{let e=Object.prototype.toString.call(r);if(e!=="[object Object]")return e;let t=r?.toString;if(typeof t=="function"&&t!==Object.prototype.toString){let n=t.call(r);if(typeof n=="string")return n}return e}catch{return"(throwing toString)"}}function de(r){if(r==null)return r;let e=typeof r;if(e==="string"||e==="number"||e==="boolean")return r;if(e==="bigint")return String(r);try{let t=JSON.stringify(r);return t===void 0?I(r):JSON.parse(t)}catch{return I(r)}}function ht(r){return fe(r).message}function Te(r){if(!r||typeof r!="string")return null;try{return new URL(r).hostname.toLowerCase()}catch{return null}}function pe(r,e){if(!e||!r)return!1;try{return new URL(r).hostname.toLowerCase()===e}catch{return!1}}var M=class{constructor(){this.state=null}init(e){if(this.state){try{this.state.uninstallUnloadFlush?.()}catch{}try{this.state.autoTracker?.uninstall()}catch{}try{this.state.webVitals?.uninstall()}catch{}try{this.state.errors?.uninstall()}catch{}}if(!e.publicKey||!e.publicKey.startsWith("cd_pub_"))throw new b({type:"configuration_error",code:"invalid_public_key",message:"Crossdeck.init requires a publishable key starting with cd_pub_."});if(!e.appId)throw new b({type:"configuration_error",code:"missing_app_id",message:"Crossdeck.init requires an appId. Find yours in the Crossdeck dashboard."});if(e.environment!=="production"&&e.environment!=="sandbox")throw new b({type:"configuration_error",code:"invalid_environment",message:'Crossdeck.init requires environment: "production" | "sandbox".'});let t=gt(e.publicKey);if(t&&t!==e.environment)throw new b({type:"configuration_error",code:"environment_mismatch",message:`Crossdeck.init: environment "${e.environment}" disagrees with key prefix (${t}). Reconcile the publishable key with the environment declaration.`});let n=mt(),s=e.storage??ye(),i=e.persistIdentity??!0,c=yt(e.autoTrack),o={appId:e.appId,publicKey:e.publicKey,environment:e.environment,baseUrl:e.baseUrl??N,persistIdentity:i,storagePrefix:e.storagePrefix??"crossdeck:",autoHeartbeat:e.autoHeartbeat??!0,eventFlushBatchSize:e.eventFlushBatchSize??20,eventFlushIntervalMs:e.eventFlushIntervalMs??1500,sdkVersion:e.sdkVersion??A,autoTrack:c,appVersion:e.appVersion??null},a=new Q;a.enabled=e.debug===!0;let d=new B({publicKey:o.publicKey,baseUrl:o.baseUrl,sdkVersion:o.sdkVersion,localDevMode:n});n&&console.log("[crossdeck] Localhost detected \u2014 running in dev mode (no network calls). Set publicKey: 'cd_pub_test_\u2026' and deploy to a real domain to test against the Crossdeck Sandbox.");let u=i?s:new _,p=i&&!e.storage&&typeof globalThis.document<"u"?new X:void 0,h=new j(u,o.storagePrefix,p),f=new H(u,o.storagePrefix+"entitlements"),m=i?new z({storage:u,prefix:o.storagePrefix}):null;m&&a.emit("sdk.queue_restored","Restored persisted event queue from a prior session.");let g=new W({http:d,batchSize:o.eventFlushBatchSize,intervalMs:o.eventFlushIntervalMs,envelope:()=>({appId:o.appId,environment:o.environment,sdk:{name:C,version:o.sdkVersion}}),persistentStore:m??void 0,onFirstFlushSuccess:()=>{a.emit("sdk.first_event_sent","First telemetry event received. View it in Live Events.",{appId:o.appId,environment:o.environment})},onRetryScheduled:y=>{a.emit("sdk.flush_retry_scheduled",`Event flush failed (${y.lastError}). Retrying in ${y.delayMs}ms (attempt ${y.consecutiveFailures}).`,{...y})},onPermanentFailure:y=>{let k=`[crossdeck] Event batch DROPPED (status ${y.status}): ${y.lastError}. ${y.droppedCount} event(s) lost \u2014 check your publishable key + app config.`;console.error(k),a.emit("sdk.flush_permanent_failure",k,{...y})}}),v=c.deviceInfo?be({appVersion:o.appVersion??void 0}):o.appVersion?{appVersion:o.appVersion}:{},S=new J(i?u:new _,o.storagePrefix),U=new Z({respectDnt:e.respectDnt===!0});U.isDntDenied&&a.emit("sdk.consent_dnt_applied","Do Not Track detected \u2014 all tracking dimensions denied at init.");let V=new ee(50);if(this.state={http:d,identity:h,entitlements:f,events:g,autoTracker:null,webVitals:null,errors:null,breadcrumbs:V,errorContext:{},errorTags:{},errorBeforeSend:null,superProps:S,consent:U,scrubPii:e.scrubPii!==!1,deviceInfo:v,options:o,debug:a,developerUserId:null,uninstallUnloadFlush:null,lastServerTime:null,lastClientTime:null},a.emit("sdk.configured",`Crossdeck connected to ${o.appId} in ${o.environment} mode.`,{appId:o.appId,environment:o.environment,sdkVersion:o.sdkVersion}),c.sessions||c.pageViews){let y=new L(c,(k,R)=>this.track(k,R));this.state.autoTracker=y,y.install()}if(c.webVitals){let y=new Y({enabled:!0},(k,R)=>this.track(k,R));this.state.webVitals=y,y.install()}if(c.errors){let y=new te({config:{...Se,enabled:!0},breadcrumbs:V,report:k=>this.reportError(k),getContext:()=>({...this.state.errorContext}),getTags:()=>({...this.state.errorTags}),beforeSend:()=>this.state.errorBeforeSend,isConsented:()=>this.state.consent.errors,selfHostname:Te(o.baseUrl)});this.state.errors=y,y.install()}this.state.uninstallUnloadFlush=bt(()=>{this.flush({keepalive:!0}).catch(()=>{})}),o.autoHeartbeat&&!n&&this.heartbeat().catch(()=>{})}start(e){typeof console<"u"&&console.warn("[crossdeck] Crossdeck.start() is deprecated \u2014 use Crossdeck.init() instead. The signature is the same."),this.init(e)}async identify(e,t){let n=this.requireStarted();if(!e)throw new b({type:"invalid_request_error",code:"missing_user_id",message:"identify(userId) requires a non-empty userId."});if(!n.consent.analytics)return n.debug.emit("sdk.consent_denied","identify() skipped \u2014 consent denied for analytics."),{object:"alias_result",crossdeckCustomerId:n.identity.crossdeckCustomerId??"",linked:[],mergePending:!1,env:n.options.environment};let s=t?.traits!==void 0?O(t.traits):null,i=s&&Object.keys(s.properties).length>0?s.properties:void 0;if(n.debug.enabled&&s&&s.warnings.length>0)for(let u of s.warnings)n.debug.emit("sdk.property_coerced",`identify() traits key ${JSON.stringify(u.key)} was ${u.kind.replace(/_/g," ")} during validation.`,{key:u.key,kind:u.kind});let c={userId:e,anonymousId:n.identity.anonymousId};t?.email&&(c.email=t.email),i&&(c.traits=i);let o=await n.http.request("POST","/identity/alias",{body:c}),a=n.identity.crossdeckCustomerId,d=n.entitlements.list().length>0;return(a&&o.crossdeckCustomerId&&a!==o.crossdeckCustomerId||!a&&d)&&n.entitlements.clear(),n.identity.setCrossdeckCustomerId(o.crossdeckCustomerId),n.developerUserId=e,o}register(e){let t=this.requireStarted(),n=O(e);return t.superProps.register(n.properties)}unregister(e){this.requireStarted().superProps.unregister(e)}getSuperProperties(){return this.state?this.state.superProps.getSuperProperties():{}}group(e,t,n){let s=this.requireStarted();if(!e)throw new b({type:"invalid_request_error",code:"missing_group_type",message:"group(type, id) requires a non-empty type."});let i=n?O(n).properties:void 0;s.superProps.setGroup(e,t,i)}getGroups(){return this.state?this.state.superProps.getGroups():{}}consent(e){let t=this.requireStarted(),n=t.consent.set(e);return t.debug.emit("sdk.consent_changed","Consent state updated.",{...n}),n}consentStatus(){return this.state?this.state.consent.get():{analytics:!0,marketing:!0,errors:!0}}captureError(e,t){this.state?.errors&&this.state.errors.captureError(e,t)}captureMessage(e,t="info"){this.state?.errors&&this.state.errors.captureMessage(e,t)}setTag(e,t){this.state&&(this.state.errorTags[e]=t)}setTags(e){this.state&&Object.assign(this.state.errorTags,e)}setContext(e,t){this.state&&(this.state.errorContext[e]=t)}addBreadcrumb(e){this.state&&this.state.breadcrumbs.add(e)}setErrorBeforeSend(e){this.state&&(this.state.errorBeforeSend=e)}reportError(e){let t={fingerprint:e.fingerprint,level:e.level,errorType:e.errorType,message:e.message,stack:e.rawStack??void 0,frames:e.frames,filename:e.filename??void 0,lineno:e.lineno??void 0,colno:e.colno??void 0,tags:e.tags,context:e.context,breadcrumbs:e.breadcrumbs,http:e.http};for(let n of Object.keys(t))t[n]===void 0&&delete t[n];this.track(e.kind,t)}async forget(){let e=this.requireStarted(),t=this.identityQueryParams();try{await e.http.request("POST","/identity/forget",{body:{...t}})}catch(n){e.debug.emit("sdk.consent_denied",`forget() server call failed (${n instanceof Error?n.message:String(n)}). Local state wiped anyway.`)}this.reset()}async getEntitlements(){let e=this.requireStarted(),t=this.identityQueryParams(),n;try{n=await e.http.request("GET","/entitlements",{query:t})}catch(s){throw e.entitlements.markRefreshFailed(),s}return n.crossdeckCustomerId&&e.identity.setCrossdeckCustomerId(n.crossdeckCustomerId),e.entitlements.setFromList(n.data),n.data}isEntitled(e){return this.requireStarted().entitlements.isEntitled(e)}listEntitlements(){return this.requireStarted().entitlements.list()}onEntitlementsChange(e){return this.requireStarted().entitlements.subscribe(e)}track(e,t){let n=this.requireStarted();if(!e)throw new b({type:"invalid_request_error",code:"missing_event_name",message:"track(name) requires a non-empty name."});let s=e.startsWith("error."),i=e.startsWith("webvitals.");if(!(s||i?n.consent.errors:n.consent.analytics)){n.debug.enabled&&n.debug.emit("sdk.consent_denied",`Dropped event "${e}" \u2014 consent denied for ${i?"errors":"analytics"}.`);return}if(n.debug.enabled&&t){let g=ke(t);g.length>0&&n.debug.emit("sdk.sensitive_property_warning",`Event "${e}" has potentially sensitive property names: ${g.join(", ")}. Crossdeck is privacy-first \u2014 avoid sending PII unless intentional.`,{eventName:e,flagged:g})}n.debug.enabled&&!n.developerUserId&&!n.identity.crossdeckCustomerId&&n.debug.emit("sdk.no_identity","Using anonymous user until identify(userId) is called.");let o=O(t);if(n.debug.enabled&&o.warnings.length>0)for(let g of o.warnings)n.debug.emit("sdk.property_coerced",`Event "${e}" property ${JSON.stringify(g.key)} was ${g.kind.replace(/_/g," ")} during validation.`,{eventName:e,key:g.key,kind:g.kind});let a={...n.deviceInfo},d=n.autoTracker?.currentSessionId;d&&(a.sessionId=d);let u=n.autoTracker?.currentPageviewId;u&&(a.pageviewId=u);let l=n.autoTracker?.currentAcquisition;l&&(l.utm_source&&(a.utm_source=l.utm_source),l.utm_medium&&(a.utm_medium=l.utm_medium),l.utm_campaign&&(a.utm_campaign=l.utm_campaign),l.utm_content&&(a.utm_content=l.utm_content),l.utm_term&&(a.utm_term=l.utm_term),l.referrer&&n.consent.marketing&&(a.referrer=l.referrer),n.consent.marketing&&(l.gclid&&(a.gclid=l.gclid),l.fbclid&&(a.fbclid=l.fbclid),l.msclkid&&(a.msclkid=l.msclkid),l.ttclid&&(a.ttclid=l.ttclid),l.li_fat_id&&(a.li_fat_id=l.li_fat_id),l.twclid&&(a.twclid=l.twclid)));let p=n.superProps.getSuperProperties();for(let g of Object.keys(p))g in a||(a[g]=p[g]);let h=n.superProps.getGroupIds();Object.keys(h).length>0&&(a.$groups=h),Object.assign(a,o.properties);let f=n.scrubPii?ce(a):a,m={eventId:this.mintEventId(),name:e,timestamp:Date.now(),properties:f};if(Object.assign(m,this.identityHintForEvent()),n.events.enqueue(m),!s&&!i){let g=e.startsWith("page.")?"navigation":e.startsWith("element.")||e==="session.started"?"ui.click":"custom";n.breadcrumbs.add({timestamp:m.timestamp,category:g,message:e,data:t?{...t}:void 0})}}async flush(e={}){await this.requireStarted().events.flush(e)}async flushEvents(){return this.flush()}async syncPurchases(e){let t=this.requireStarted();if(!e.signedTransactionInfo)throw new b({type:"invalid_request_error",code:"missing_signed_transaction_info",message:"syncPurchases requires a signedTransactionInfo string from StoreKit 2."});let n=e.rail??"apple",s=await t.http.request("POST","/purchases/sync",{body:{...e,rail:n}});return t.identity.setCrossdeckCustomerId(s.crossdeckCustomerId),t.entitlements.setFromList(s.entitlements),t.debug.emit("sdk.purchase_evidence_sent","StoreKit transaction forwarded. Waiting for backend verification.",{rail:e.rail??"apple"}),s}async purchaseApple(e){return this.syncPurchases({rail:"apple",...e})}setDebugMode(e){let t=this.requireStarted();t.debug.enabled=e,e&&t.debug.emit("sdk.configured",`Debug mode enabled for ${t.options.appId} in ${t.options.environment} mode.`,{appId:t.options.appId,environment:t.options.environment})}async heartbeat(){let e=this.requireStarted(),t=await e.http.request("GET","/sdk/heartbeat");return typeof t?.serverTime=="number"&&Number.isFinite(t.serverTime)&&(e.lastServerTime=t.serverTime,e.lastClientTime=Date.now()),t}reset(){if(this.state){if(this.state.developerUserId)try{this.track("user.signed_out",{auto:!0})}catch{}if(this.state.autoTracker?.uninstall(),this.state.identity.reset(),this.state.entitlements.clear(),this.state.events.reset(),this.state.superProps.clear(),this.state.breadcrumbs.clear(),this.state.errorContext={},this.state.errorTags={},this.state.developerUserId=null,this.state.lastServerTime=null,this.state.lastClientTime=null,this.state.autoTracker){let e=new L(this.state.options.autoTrack,(t,n)=>this.track(t,n));this.state.autoTracker=e,e.install()}}}diagnostics(){if(!this.state)return{started:!1,anonymousId:null,crossdeckCustomerId:null,developerUserId:null,sdkVersion:null,baseUrl:null,clock:{lastServerTime:null,lastClientTime:null,skewMs:null},entitlements:{count:0,lastUpdated:0,stale:!1,listenerErrors:0},events:{buffered:0,dropped:0,inFlight:0,lastFlushAt:0,lastError:null,consecutiveFailures:0,nextRetryAt:null}};let e=this.state,t=e.lastServerTime!==null&&e.lastClientTime!==null?e.lastClientTime-e.lastServerTime:null;return{started:!0,anonymousId:e.identity.anonymousId,crossdeckCustomerId:e.identity.crossdeckCustomerId,developerUserId:e.developerUserId,sdkVersion:e.options.sdkVersion,baseUrl:e.options.baseUrl,clock:{lastServerTime:e.lastServerTime,lastClientTime:e.lastClientTime,skewMs:t},entitlements:{count:e.entitlements.list().length,lastUpdated:e.entitlements.freshness,stale:e.entitlements.isStale,listenerErrors:e.entitlements.listenerErrors},events:e.events.getStats()}}requireStarted(){if(!this.state)throw new b({type:"configuration_error",code:"not_initialized",message:"Call Crossdeck.init({ appId, publicKey, environment }) before any other method."});return this.state}identityQueryParams(){let e=this.requireStarted();return e.identity.crossdeckCustomerId?{customerId:e.identity.crossdeckCustomerId}:e.developerUserId?{userId:e.developerUserId}:{anonymousId:e.identity.anonymousId}}identityHintForEvent(){let e=this.requireStarted(),t={anonymousId:e.identity.anonymousId};return e.developerUserId&&(t.developerUserId=e.developerUserId),e.identity.crossdeckCustomerId&&(t.crossdeckCustomerId=e.identity.crossdeckCustomerId),t}mintEventId(){return`evt_${Date.now().toString(36)}${w(8)}`}},Ce=new M;function gt(r){return r.startsWith("cd_pub_test_")?"sandbox":r.startsWith("cd_pub_live_")?"production":null}function mt(){let r=globalThis.window;if(r?.__CROSSDECK_FORCE_LIVE__===!0)return!1;let e=r?.location?.hostname;return e?!!(e==="localhost"||e==="127.0.0.1"||e==="0.0.0.0"||e==="::1"||e==="[::1]"||/^\[?fe80::/i.test(e)||e.endsWith(".local")||/^10\./.test(e)||/^192\.168\./.test(e)||/^172\.(1[6-9]|2\d|3[0-1])\./.test(e)):!1}function yt(r){return r===!1?{sessions:!1,pageViews:!1,deviceInfo:!1,clicks:!1,webVitals:!1,errors:!1}:r===void 0||r===!0?{...E}:{sessions:r.sessions??E.sessions,pageViews:r.pageViews??E.pageViews,deviceInfo:r.deviceInfo??E.deviceInfo,clicks:r.clicks??E.clicks,webVitals:r.webVitals??E.webVitals,errors:r.errors??E.errors}}function bt(r){let e=globalThis.window,t=globalThis.document;if(!e||!t)return()=>{};let n=()=>{t.visibilityState==="hidden"&&r()},s=()=>r();return t.addEventListener("visibilitychange",n),e.addEventListener("pagehide",s),e.addEventListener("beforeunload",s),()=>{t.removeEventListener("visibilitychange",n),e.removeEventListener("pagehide",s),e.removeEventListener("beforeunload",s)}}var he=Object.freeze([{code:"invalid_public_key",type:"configuration_error",description:"The publishable key passed to Crossdeck.init() doesn't start with cd_pub_.",resolution:"Copy the key from your Crossdeck dashboard \u2192 API keys page.",retryable:!1},{code:"missing_app_id",type:"configuration_error",description:"Crossdeck.init() was called without an appId.",resolution:"Add appId to your init options \u2014 find it in the dashboard's Apps page.",retryable:!1},{code:"invalid_environment",type:"configuration_error",description:"Crossdeck.init() requires environment: 'production' | 'sandbox'.",resolution:'Pass the literal string "production" or "sandbox" \u2014 no other values are accepted.',retryable:!1},{code:"environment_mismatch",type:"configuration_error",description:"The publishable key's env prefix doesn't match the declared environment option.",resolution:"Either change `environment` to match the key prefix (cd_pub_test_ \u2194 sandbox, cd_pub_live_ \u2194 production), or swap the key for one minted in the right env.",retryable:!1},{code:"not_initialized",type:"configuration_error",description:"An SDK method was called before Crossdeck.init().",resolution:"Call Crossdeck.init({ appId, publicKey, environment }) once at app startup before any other method.",retryable:!1},{code:"missing_user_id",type:"invalid_request_error",description:"identify() was called with an empty userId.",resolution:"Pass a stable, non-empty user identifier from your auth layer \u2014 never a hardcoded placeholder.",retryable:!1},{code:"missing_event_name",type:"invalid_request_error",description:"track() was called without an event name.",resolution:"Pass a non-empty string as the first argument.",retryable:!1},{code:"missing_group_type",type:"invalid_request_error",description:"group() was called without a group type.",resolution:'Pass a non-empty type (e.g. "org", "team") as the first argument.',retryable:!1},{code:"missing_signed_transaction_info",type:"invalid_request_error",description:"syncPurchases() was called without StoreKit 2 signed transaction info.",resolution:"Pass the JWS string from Transaction.currentEntitlements / Transaction.updates.",retryable:!1},{code:"fetch_failed",type:"network_error",description:"The underlying fetch() call failed (typically a network outage or DNS issue).",resolution:"Check the user's network. The SDK will retry automatically with exponential backoff.",retryable:!0},{code:"request_timeout",type:"network_error",description:"A request was aborted after the configured timeoutMs (default 15s).",resolution:"Check the user's connection. Increase timeoutMs in init options if the user is on a known-slow network.",retryable:!0},{code:"invalid_json_response",type:"internal_error",description:"The server returned a 2xx with an unparseable body.",resolution:"Likely a transient backend bug. Retry; if it persists, contact support with the requestId.",retryable:!0}]);function xe(r){return he.find(e=>e.code===r)}return Fe(vt);})();
|
|
3
3
|
//# sourceMappingURL=crossdeck.umd.min.js.map
|