@layers/client 2.1.0 → 2.1.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/dist/{index-C6l4kIMP.d.ts → index-CxcZfcCz.d.ts} +6 -2
- package/dist/{index-C6l4kIMP.d.ts.map → index-CxcZfcCz.d.ts.map} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{src-DnOWq7k2.js → src-Cr51bQPh.js} +41 -2
- package/dist/src-Cr51bQPh.js.map +1 -0
- package/package.json +1 -1
- package/dist/src-DnOWq7k2.js.map +0 -1
|
@@ -499,7 +499,7 @@ interface LayersConfig {
|
|
|
499
499
|
enableDebug?: boolean;
|
|
500
500
|
/** Base URL for the Layers ingest API. @default "https://in.layers.com" */
|
|
501
501
|
baseUrl?: string;
|
|
502
|
-
/** How often the event queue is flushed, in milliseconds. @default
|
|
502
|
+
/** How often the event queue is flushed, in milliseconds. @default 10000 */
|
|
503
503
|
flushIntervalMs?: number;
|
|
504
504
|
/** Number of queued events that triggers an automatic flush. @default 10 */
|
|
505
505
|
flushThreshold?: number;
|
|
@@ -560,6 +560,9 @@ declare class LayersClient {
|
|
|
560
560
|
private _isInitialized;
|
|
561
561
|
private _initListener;
|
|
562
562
|
private _debugOverlayActive;
|
|
563
|
+
private quickFlushTimer;
|
|
564
|
+
private quickFlushEnabled;
|
|
565
|
+
private quickFlushDisableTimer;
|
|
563
566
|
constructor(config: LayersConfig);
|
|
564
567
|
/** Initialize the client: detects device info, attaches lifecycle listeners, and fetches remote config. */
|
|
565
568
|
init(): Promise<void>;
|
|
@@ -681,6 +684,7 @@ declare class LayersClient {
|
|
|
681
684
|
private _trackedDeepLinkUrls;
|
|
682
685
|
private setupDeepLinkAutoTracking;
|
|
683
686
|
private trackInitTiming;
|
|
687
|
+
private scheduleQuickFlush;
|
|
684
688
|
private recordRecentEvent;
|
|
685
689
|
private initializeDeviceInfo;
|
|
686
690
|
private detectOS;
|
|
@@ -695,4 +699,4 @@ declare class LayersClient {
|
|
|
695
699
|
}
|
|
696
700
|
//#endregion
|
|
697
701
|
export { getAttribution as $, addToWishlistEvent as A, signUpEvent as B, DeepLinkData as C, StandardEventPayload as D, StandardEventName as E, purchaseEvent as F, viewItemEvent as G, subscribeEvent as H, registerEvent as I, getFbc as J, formatFbc as K, screenViewEvent as L, levelCompleteEvent as M, levelStartEvent as N, StandardEvents as O, loginEvent as P, AttributionData as Q, searchEvent as R, DebugOverlayState as S, setupDeepLinkListener as T, tutorialCompleteEvent as U, startTrialEvent as V, viewContentEvent as W, getPageUrl as X, getFbpCookie as Y, getTtpCookie as Z, trackPurchaseFailed as _, WebAttributionData as a, SKANPostbackPayload as at, trackSubscription as b, PurchaseFailedParams as c, DeviceContext as ct, SubscriptionParams as d, LayersError as dt, getAttributionProperties as et, WebCommerceTracker as f, UserProperties as ft, trackPurchase as g, trackOrder as h, LayersConfig as i, RemoteConfigResponse as it, initiateCheckoutEvent as j, addToCartEvent as k, PurchaseParams as l, Environment as lt, trackBeginCheckout as m, InitListener as n, ConsentPayload as nt, CartItem as o, UserPropertiesPayload as ot, trackAddToCart as p, getCapiProperties as q, LayersClient as r, EventsBatchPayload as rt, OrderParams as s, ConsentState as st, ErrorListener as t, BaseEvent as tt, RefundParams as u, EventProperties as ut, trackRefund as v, parseDeepLink as w, trackViewProduct as x, trackRemoveFromCart as y, shareEvent as z };
|
|
698
|
-
//# sourceMappingURL=index-
|
|
702
|
+
//# sourceMappingURL=index-CxcZfcCz.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-C6l4kIMP.d.ts","names":[],"sources":["../../wasm/src/types.ts","../../wasm/src/core.ts","../src/api-types.ts","../src/attribution.ts","../src/capi.ts","../src/standard-events.ts","../src/deep-links.ts","../src/debug-overlay.ts","../src/commerce.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-CxcZfcCz.d.ts","names":[],"sources":["../../wasm/src/types.ts","../../wasm/src/core.ts","../src/api-types.ts","../src/attribution.ts","../src/capi.ts","../src/standard-events.ts","../src/deep-links.ts","../src/debug-overlay.ts","../src/commerce.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as getAttribution, A as addToWishlistEvent, B as signUpEvent, C as DeepLinkData, D as StandardEventPayload, E as StandardEventName, F as purchaseEvent, G as viewItemEvent, H as subscribeEvent, I as registerEvent, J as getFbc, K as formatFbc, L as screenViewEvent, M as levelCompleteEvent, N as levelStartEvent, O as StandardEvents, P as loginEvent, Q as AttributionData, R as searchEvent, S as DebugOverlayState, T as setupDeepLinkListener, U as tutorialCompleteEvent, V as startTrialEvent, W as viewContentEvent, X as getPageUrl, Y as getFbpCookie, Z as getTtpCookie, _ as trackPurchaseFailed, a as WebAttributionData, at as SKANPostbackPayload, b as trackSubscription, c as PurchaseFailedParams, ct as DeviceContext, d as SubscriptionParams, dt as LayersError, et as getAttributionProperties, f as WebCommerceTracker, ft as UserProperties, g as trackPurchase, h as trackOrder, i as LayersConfig, it as RemoteConfigResponse, j as initiateCheckoutEvent, k as addToCartEvent, l as PurchaseParams, lt as Environment, m as trackBeginCheckout, n as InitListener, nt as ConsentPayload, o as CartItem, ot as UserPropertiesPayload, p as trackAddToCart, q as getCapiProperties, r as LayersClient, rt as EventsBatchPayload, s as OrderParams, st as ConsentState, t as ErrorListener, tt as BaseEvent, u as RefundParams, ut as EventProperties, v as trackRefund, w as parseDeepLink, x as trackViewProduct, y as trackRemoveFromCart, z as shareEvent } from "./index-
|
|
1
|
+
import { $ as getAttribution, A as addToWishlistEvent, B as signUpEvent, C as DeepLinkData, D as StandardEventPayload, E as StandardEventName, F as purchaseEvent, G as viewItemEvent, H as subscribeEvent, I as registerEvent, J as getFbc, K as formatFbc, L as screenViewEvent, M as levelCompleteEvent, N as levelStartEvent, O as StandardEvents, P as loginEvent, Q as AttributionData, R as searchEvent, S as DebugOverlayState, T as setupDeepLinkListener, U as tutorialCompleteEvent, V as startTrialEvent, W as viewContentEvent, X as getPageUrl, Y as getFbpCookie, Z as getTtpCookie, _ as trackPurchaseFailed, a as WebAttributionData, at as SKANPostbackPayload, b as trackSubscription, c as PurchaseFailedParams, ct as DeviceContext, d as SubscriptionParams, dt as LayersError, et as getAttributionProperties, f as WebCommerceTracker, ft as UserProperties, g as trackPurchase, h as trackOrder, i as LayersConfig, it as RemoteConfigResponse, j as initiateCheckoutEvent, k as addToCartEvent, l as PurchaseParams, lt as Environment, m as trackBeginCheckout, n as InitListener, nt as ConsentPayload, o as CartItem, ot as UserPropertiesPayload, p as trackAddToCart, q as getCapiProperties, r as LayersClient, rt as EventsBatchPayload, s as OrderParams, st as ConsentState, t as ErrorListener, tt as BaseEvent, u as RefundParams, ut as EventProperties, v as trackRefund, w as parseDeepLink, x as trackViewProduct, y as trackRemoveFromCart, z as shareEvent } from "./index-CxcZfcCz.js";
|
|
2
2
|
export { AttributionData, BaseEvent, CartItem, ConsentPayload, ConsentState, DebugOverlayState, DeepLinkData, DeviceContext, Environment, ErrorListener, EventProperties, EventsBatchPayload, InitListener, LayersClient, LayersConfig, LayersError, OrderParams, PurchaseFailedParams, PurchaseParams, RefundParams, RemoteConfigResponse, SKANPostbackPayload, StandardEventName, StandardEventPayload, StandardEvents, SubscriptionParams, UserProperties, UserPropertiesPayload, WebAttributionData, WebCommerceTracker, addToCartEvent, addToWishlistEvent, formatFbc, getAttribution, getAttributionProperties, getCapiProperties, getFbc, getFbpCookie, getPageUrl, getTtpCookie, initiateCheckoutEvent, levelCompleteEvent, levelStartEvent, loginEvent, parseDeepLink, purchaseEvent, registerEvent, screenViewEvent, searchEvent, setupDeepLinkListener, shareEvent, signUpEvent, startTrialEvent, subscribeEvent, trackAddToCart, trackBeginCheckout, trackOrder, trackPurchase, trackPurchaseFailed, trackRefund, trackRemoveFromCart, trackSubscription, trackViewProduct, tutorialCompleteEvent, viewContentEvent, viewItemEvent };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as parseDeepLink, C as shareEvent, D as tutorialCompleteEvent, E as subscribeEvent, F as getFbpCookie, I as getPageUrl, L as getTtpCookie, M as formatFbc, N as getCapiProperties, O as viewContentEvent, P as getFbc, R as getAttribution, S as searchEvent, T as startTrialEvent, _ as levelStartEvent, a as trackOrder, b as registerEvent, c as trackRefund, d as trackViewProduct, f as StandardEvents, g as levelCompleteEvent, h as initiateCheckoutEvent, i as trackBeginCheckout, j as setupDeepLinkListener, k as viewItemEvent, l as trackRemoveFromCart, m as addToWishlistEvent, n as LayersError, o as trackPurchase, p as addToCartEvent, r as trackAddToCart, s as trackPurchaseFailed, t as LayersClient, u as trackSubscription, v as loginEvent, w as signUpEvent, x as screenViewEvent, y as purchaseEvent, z as getAttributionProperties } from "./src-
|
|
1
|
+
import { A as parseDeepLink, C as shareEvent, D as tutorialCompleteEvent, E as subscribeEvent, F as getFbpCookie, I as getPageUrl, L as getTtpCookie, M as formatFbc, N as getCapiProperties, O as viewContentEvent, P as getFbc, R as getAttribution, S as searchEvent, T as startTrialEvent, _ as levelStartEvent, a as trackOrder, b as registerEvent, c as trackRefund, d as trackViewProduct, f as StandardEvents, g as levelCompleteEvent, h as initiateCheckoutEvent, i as trackBeginCheckout, j as setupDeepLinkListener, k as viewItemEvent, l as trackRemoveFromCart, m as addToWishlistEvent, n as LayersError, o as trackPurchase, p as addToCartEvent, r as trackAddToCart, s as trackPurchaseFailed, t as LayersClient, u as trackSubscription, v as loginEvent, w as signUpEvent, x as screenViewEvent, y as purchaseEvent, z as getAttributionProperties } from "./src-Cr51bQPh.js";
|
|
2
2
|
|
|
3
3
|
export { LayersClient, LayersError, StandardEvents, addToCartEvent, addToWishlistEvent, formatFbc, getAttribution, getAttributionProperties, getCapiProperties, getFbc, getFbpCookie, getPageUrl, getTtpCookie, initiateCheckoutEvent, levelCompleteEvent, levelStartEvent, loginEvent, parseDeepLink, purchaseEvent, registerEvent, screenViewEvent, searchEvent, setupDeepLinkListener, shareEvent, signUpEvent, startTrialEvent, subscribeEvent, trackAddToCart, trackBeginCheckout, trackOrder, trackPurchase, trackPurchaseFailed, trackRefund, trackRemoveFromCart, trackSubscription, trackViewProduct, tutorialCompleteEvent, viewContentEvent, viewItemEvent };
|
package/dist/react.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as LayersConfig, r as LayersClient, st as ConsentState, ut as EventProperties } from "./index-
|
|
1
|
+
import { i as LayersConfig, r as LayersClient, st as ConsentState, ut as EventProperties } from "./index-CxcZfcCz.js";
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
3
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
4
|
|
package/dist/react.js
CHANGED
|
@@ -734,6 +734,9 @@ var LayersClient = class LayersClient {
|
|
|
734
734
|
_isInitialized = false;
|
|
735
735
|
_initListener = null;
|
|
736
736
|
_debugOverlayActive = false;
|
|
737
|
+
quickFlushTimer = null;
|
|
738
|
+
quickFlushEnabled = true;
|
|
739
|
+
quickFlushDisableTimer = null;
|
|
737
740
|
constructor(config) {
|
|
738
741
|
this.enableDebug = config.enableDebug ?? false;
|
|
739
742
|
this.baseUrl = (config.baseUrl ?? "https://in.layers.com").replace(/\/$/, "");
|
|
@@ -747,7 +750,7 @@ var LayersClient = class LayersClient {
|
|
|
747
750
|
environment: config.environment ?? "production",
|
|
748
751
|
...config.baseUrl != null && { baseUrl: config.baseUrl },
|
|
749
752
|
...config.enableDebug != null && { enableDebug: config.enableDebug },
|
|
750
|
-
|
|
753
|
+
flushIntervalMs: config.flushIntervalMs ?? 1e4,
|
|
751
754
|
...config.flushThreshold != null && { flushThreshold: config.flushThreshold },
|
|
752
755
|
...config.maxQueueSize != null && { maxQueueSize: config.maxQueueSize },
|
|
753
756
|
sdkVersion: `client/${SDK_VERSION}`
|
|
@@ -788,6 +791,12 @@ var LayersClient = class LayersClient {
|
|
|
788
791
|
} catch (e) {
|
|
789
792
|
if (this.enableDebug) console.warn("[Layers] InitListener threw:", e);
|
|
790
793
|
}
|
|
794
|
+
this.core.flushAsync().catch(() => {});
|
|
795
|
+
const flushInterval = this.config.flushIntervalMs ?? 1e4;
|
|
796
|
+
this.quickFlushDisableTimer = setTimeout(() => {
|
|
797
|
+
this.quickFlushEnabled = false;
|
|
798
|
+
this.quickFlushDisableTimer = null;
|
|
799
|
+
}, flushInterval);
|
|
791
800
|
}
|
|
792
801
|
/**
|
|
793
802
|
* Record a custom analytics event with an optional property bag.
|
|
@@ -804,6 +813,7 @@ var LayersClient = class LayersClient {
|
|
|
804
813
|
const depthAfter = this.core.queueDepth();
|
|
805
814
|
if (depthAfter <= depthBefore && this.enableDebug) console.warn(`[Layers] track("${eventName}") — event may not have been queued (depth before=${String(depthBefore)}, after=${String(depthAfter)})`);
|
|
806
815
|
this.recordRecentEvent(eventName, properties);
|
|
816
|
+
this.scheduleQuickFlush();
|
|
807
817
|
} catch (e) {
|
|
808
818
|
this.emitError(e);
|
|
809
819
|
}
|
|
@@ -996,6 +1006,14 @@ var LayersClient = class LayersClient {
|
|
|
996
1006
|
this.core.shutdown();
|
|
997
1007
|
}
|
|
998
1008
|
cleanupListeners() {
|
|
1009
|
+
if (this.quickFlushTimer) {
|
|
1010
|
+
clearTimeout(this.quickFlushTimer);
|
|
1011
|
+
this.quickFlushTimer = null;
|
|
1012
|
+
}
|
|
1013
|
+
if (this.quickFlushDisableTimer) {
|
|
1014
|
+
clearTimeout(this.quickFlushDisableTimer);
|
|
1015
|
+
this.quickFlushDisableTimer = null;
|
|
1016
|
+
}
|
|
999
1017
|
if (typeof window !== "undefined") {
|
|
1000
1018
|
if (this.onlineListener) {
|
|
1001
1019
|
window.removeEventListener("online", this.onlineListener);
|
|
@@ -1176,6 +1194,14 @@ var LayersClient = class LayersClient {
|
|
|
1176
1194
|
}, this.appUserId);
|
|
1177
1195
|
} catch {}
|
|
1178
1196
|
}
|
|
1197
|
+
scheduleQuickFlush() {
|
|
1198
|
+
if (!this.quickFlushEnabled) return;
|
|
1199
|
+
if (this.quickFlushTimer) return;
|
|
1200
|
+
this.quickFlushTimer = setTimeout(() => {
|
|
1201
|
+
this.quickFlushTimer = null;
|
|
1202
|
+
if (this.core.queueDepth() > 0) this.core.flushAsync().catch(() => {});
|
|
1203
|
+
}, 2e3);
|
|
1204
|
+
}
|
|
1179
1205
|
recordRecentEvent(eventName, properties) {
|
|
1180
1206
|
const now = /* @__PURE__ */ new Date();
|
|
1181
1207
|
const time = `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}:${String(now.getSeconds()).padStart(2, "0")}`;
|
|
@@ -1272,6 +1298,19 @@ var LayersClient = class LayersClient {
|
|
|
1272
1298
|
};
|
|
1273
1299
|
document.addEventListener("visibilitychange", this.visibilityListener);
|
|
1274
1300
|
this.beforeUnloadListener = () => {
|
|
1301
|
+
if (typeof navigator !== "undefined" && navigator.sendBeacon) try {
|
|
1302
|
+
const payload = this.core.createBeaconPayload();
|
|
1303
|
+
if (payload) {
|
|
1304
|
+
const url = this.getBeaconUrl();
|
|
1305
|
+
if (navigator.sendBeacon(url, payload)) {
|
|
1306
|
+
this.core.clearBeaconEvents();
|
|
1307
|
+
return;
|
|
1308
|
+
}
|
|
1309
|
+
this.core.requeueBeaconEvents();
|
|
1310
|
+
}
|
|
1311
|
+
} catch {
|
|
1312
|
+
this.core.requeueBeaconEvents();
|
|
1313
|
+
}
|
|
1275
1314
|
this.core.flush();
|
|
1276
1315
|
};
|
|
1277
1316
|
window.addEventListener("beforeunload", this.beforeUnloadListener);
|
|
@@ -1302,4 +1341,4 @@ const SDK_VERSION = typeof __LAYERS_CLIENT_VERSION__ !== "undefined" ? __LAYERS_
|
|
|
1302
1341
|
|
|
1303
1342
|
//#endregion
|
|
1304
1343
|
export { parseDeepLink as A, shareEvent as C, tutorialCompleteEvent as D, subscribeEvent as E, getFbpCookie as F, getPageUrl as I, getTtpCookie as L, formatFbc as M, getCapiProperties as N, viewContentEvent as O, getFbc as P, getAttribution as R, searchEvent as S, startTrialEvent as T, levelStartEvent as _, trackOrder as a, registerEvent as b, trackRefund as c, trackViewProduct as d, StandardEvents as f, levelCompleteEvent as g, initiateCheckoutEvent as h, trackBeginCheckout as i, setupDeepLinkListener as j, viewItemEvent as k, trackRemoveFromCart as l, addToWishlistEvent as m, LayersError$1 as n, trackPurchase as o, addToCartEvent as p, trackAddToCart as r, trackPurchaseFailed as s, LayersClient as t, trackSubscription as u, loginEvent as v, signUpEvent as w, screenViewEvent as x, purchaseEvent as y, getAttributionProperties as z };
|
|
1305
|
-
//# sourceMappingURL=src-
|
|
1344
|
+
//# sourceMappingURL=src-Cr51bQPh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src-Cr51bQPh.js","names":["params: URLSearchParams","clickIdParam: string | undefined","clickIdValue: string | undefined","utms: Partial<Pick<AttributionData, (typeof UTM_PARAMS)[number]>>","data: AttributionData","props: Record<string, string>","props: Record<string, string>","overlayElement: HTMLDivElement | null","updateInterval: ReturnType<typeof setInterval> | null","lines: string[]","params: Record<string, string>","lastUrl: string","properties: EventProperties","props: EventProperties","appOpenProps: Record<string, unknown>","ctx: DeviceContext","data: WebAttributionData","merged: Record<string, unknown>","properties: Record<string, unknown>","context: DeviceContext","SDK_VERSION: string"],"sources":["../src/attribution.ts","../src/capi.ts","../src/debug-overlay.ts","../src/deep-links.ts","../src/standard-events.ts","../src/commerce.ts","../src/index.ts"],"sourcesContent":["const CLICK_ID_PARAMS = [\n 'fbclid',\n 'gclid',\n 'gbraid',\n 'wbraid',\n 'ttclid',\n 'msclkid',\n 'rclid'\n] as const;\nconst UTM_PARAMS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'] as const;\nconst STORAGE_KEY = 'layers_attribution';\nconst TTL_MS = 30 * 24 * 60 * 60 * 1000; // 30 days\n\nexport interface AttributionData {\n click_id_param?: string;\n click_id_value?: string;\n utm_source?: string;\n utm_medium?: string;\n utm_campaign?: string;\n utm_content?: string;\n utm_term?: string;\n referrer_url?: string;\n captured_at: number;\n}\n\n/**\n * Capture attribution signals from the current page URL and referrer.\n * Persists to localStorage with a 30-day TTL. Click IDs take priority:\n * if a new click ID is present, the entire record is overwritten.\n */\nexport function captureAttribution(): void {\n if (typeof window === 'undefined' || typeof localStorage === 'undefined') return;\n\n let params: URLSearchParams;\n try {\n params = new URLSearchParams(window.location.search);\n } catch {\n return;\n }\n\n // Check for click IDs first — any click ID overwrites the stored record\n let clickIdParam: string | undefined;\n let clickIdValue: string | undefined;\n for (const param of CLICK_ID_PARAMS) {\n const value = params.get(param);\n if (value) {\n clickIdParam = param;\n clickIdValue = value;\n break; // first match wins\n }\n }\n\n // Collect UTM params\n const utms: Partial<Pick<AttributionData, (typeof UTM_PARAMS)[number]>> = {};\n let hasUtm = false;\n for (const param of UTM_PARAMS) {\n const value = params.get(param);\n if (value) {\n utms[param] = value;\n hasUtm = true;\n }\n }\n\n const referrer =\n typeof document !== 'undefined' && document.referrer ? document.referrer : undefined;\n\n // Nothing to capture\n if (!clickIdParam && !hasUtm && !referrer) return;\n\n const existing = getAttribution();\n\n // If a new click ID is present, overwrite entirely\n if (clickIdParam) {\n const data: AttributionData = {\n click_id_param: clickIdParam,\n ...(clickIdValue != null && { click_id_value: clickIdValue }),\n ...utms,\n ...(referrer != null && { referrer_url: referrer }),\n captured_at: Date.now()\n };\n writeAttribution(data);\n return;\n }\n\n // If UTMs are present, overwrite (fresh campaign visit)\n if (hasUtm) {\n const data: AttributionData = {\n // Preserve existing click ID if no new one\n ...(existing?.click_id_param != null && { click_id_param: existing.click_id_param }),\n ...(existing?.click_id_value != null && { click_id_value: existing.click_id_value }),\n ...utms,\n ...(referrer != null && { referrer_url: referrer }),\n captured_at: Date.now()\n };\n writeAttribution(data);\n return;\n }\n\n // Only referrer and no existing attribution — store it\n if (!existing) {\n const data: AttributionData = {\n ...(referrer != null && { referrer_url: referrer }),\n captured_at: Date.now()\n };\n writeAttribution(data);\n }\n}\n\n/**\n * Read stored attribution data, returning null if missing or expired.\n */\nexport function getAttribution(): AttributionData | null {\n if (typeof localStorage === 'undefined') return null;\n\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (!raw) return null;\n\n const data: AttributionData = JSON.parse(raw);\n if (Date.now() - data.captured_at > TTL_MS) {\n localStorage.removeItem(STORAGE_KEY);\n return null;\n }\n return data;\n } catch {\n return null;\n }\n}\n\n/**\n * Return a flat property bag suitable for merging into event properties.\n * Keys are prefixed with `$attribution_` to avoid collisions.\n */\nexport function getAttributionProperties(): Record<string, string> {\n const data = getAttribution();\n if (!data) return {};\n\n const props: Record<string, string> = {};\n\n if (data.click_id_param) props['$attribution_click_id_param'] = data.click_id_param;\n if (data.click_id_value) props['$attribution_click_id_value'] = data.click_id_value;\n if (data.utm_source) props['$attribution_utm_source'] = data.utm_source;\n if (data.utm_medium) props['$attribution_utm_medium'] = data.utm_medium;\n if (data.utm_campaign) props['$attribution_utm_campaign'] = data.utm_campaign;\n if (data.utm_content) props['$attribution_utm_content'] = data.utm_content;\n if (data.utm_term) props['$attribution_utm_term'] = data.utm_term;\n if (data.referrer_url) props['$attribution_referrer_url'] = data.referrer_url;\n\n return props;\n}\n\nfunction writeAttribution(data: AttributionData): void {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(data));\n } catch {\n // localStorage full or unavailable — silently ignore\n }\n}\n","// CAPI (Conversions API) readiness utilities.\n// Captures Meta _fbp, TikTok _ttp cookies, page URL, and formats fbc from fbclid.\n\n/**\n * Read a named cookie from document.cookie.\n * Returns the cookie value or undefined if not found / unavailable.\n */\nfunction getCookie(name: string): string | undefined {\n if (typeof document === 'undefined' || !document.cookie) return undefined;\n\n // Cookies are separated by \"; \" — match the exact name to avoid\n // partial matches (e.g. \"x_fbp\" matching \"_fbp\").\n const prefix = `${name}=`;\n const cookies = document.cookie.split('; ');\n for (const cookie of cookies) {\n if (cookie.startsWith(prefix)) {\n return decodeURIComponent(cookie.slice(prefix.length));\n }\n }\n return undefined;\n}\n\n/**\n * Read Meta's _fbp cookie.\n * Format set by Meta Pixel: fb.1.{timestamp}.{random}\n */\nexport function getFbpCookie(): string | undefined {\n return getCookie('_fbp');\n}\n\n/**\n * Read TikTok's _ttp cookie.\n */\nexport function getTtpCookie(): string | undefined {\n return getCookie('_ttp');\n}\n\n/**\n * Capture the current page URL.\n * Required by Meta CAPI for every web event (event_source_url).\n */\nexport function getPageUrl(): string | undefined {\n if (typeof window === 'undefined') return undefined;\n try {\n return window.location.href;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Format an fbclid value into Meta's fbc cookie format.\n * Format: fb.1.{timestamp_ms}.{fbclid}\n *\n * @param fbclid - The raw fbclid parameter value from the URL\n * @param timestampMs - Optional timestamp in milliseconds (defaults to Date.now())\n */\nexport function formatFbc(fbclid: string, timestampMs?: number): string {\n const ts = timestampMs ?? Date.now();\n return `fb.1.${ts}.${fbclid}`;\n}\n\n/**\n * Get the fbc value. Checks in order:\n * 1. If an fbclid URL parameter is present, format it as fbc\n * 2. If an _fbc cookie exists, return it\n * 3. Return undefined\n */\nexport function getFbc(): string | undefined {\n // Check for fbclid in URL params\n if (typeof window !== 'undefined') {\n try {\n const params = new URLSearchParams(window.location.search);\n const fbclid = params.get('fbclid');\n if (fbclid) {\n return formatFbc(fbclid);\n }\n } catch {\n // URL parsing failed\n }\n }\n\n // Fall back to existing _fbc cookie\n return getCookie('_fbc');\n}\n\n/**\n * Build the full set of CAPI properties for an event.\n * All values are optional — only present keys are included.\n */\nexport function getCapiProperties(): Record<string, string> {\n const props: Record<string, string> = {};\n\n const fbp = getFbpCookie();\n if (fbp) props['$fbp'] = fbp;\n\n const ttp = getTtpCookie();\n if (ttp) props['$ttp'] = ttp;\n\n const pageUrl = getPageUrl();\n if (pageUrl) props['$page_url'] = pageUrl;\n\n const fbc = getFbc();\n if (fbc) props['$fbc'] = fbc;\n\n return props;\n}\n","// Lightweight DOM-based debug overlay for the Web SDK.\n// Shows: SDK version, queue depth, session ID, install ID, recent events.\n// Toggled via enableDebugOverlay() / disableDebugOverlay().\n\nexport interface DebugOverlayState {\n sdkVersion: string;\n queueDepth: number;\n sessionId: string;\n installId: string | null;\n appId: string;\n environment: string;\n isOnline: boolean;\n recentEvents: readonly string[];\n}\n\nexport type DebugOverlayStateProvider = () => DebugOverlayState;\n\nconst OVERLAY_ID = 'layers-debug-overlay';\nconst OVERLAY_STYLES = `\n position: fixed;\n bottom: 8px;\n right: 8px;\n width: 360px;\n max-height: 400px;\n background: rgba(0, 0, 0, 0.88);\n color: #e0e0e0;\n font-family: monospace;\n font-size: 11px;\n line-height: 1.5;\n padding: 12px;\n border-radius: 8px;\n z-index: 999999;\n overflow-y: auto;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);\n pointer-events: auto;\n`;\n\nlet overlayElement: HTMLDivElement | null = null;\nlet updateInterval: ReturnType<typeof setInterval> | null = null;\n\n/**\n * Create and display the debug overlay in the DOM.\n * Updates every second with the latest state from the provider.\n */\nexport function enableDebugOverlay(stateProvider: DebugOverlayStateProvider): void {\n if (typeof document === 'undefined') return;\n\n // Don't create a duplicate\n if (overlayElement) {\n disableDebugOverlay();\n }\n\n overlayElement = document.createElement('div');\n overlayElement.id = OVERLAY_ID;\n overlayElement.setAttribute('style', OVERLAY_STYLES);\n document.body.appendChild(overlayElement);\n\n const update = (): void => {\n if (!overlayElement) return;\n const state = stateProvider();\n overlayElement.innerHTML = renderOverlay(state);\n };\n\n update();\n updateInterval = setInterval(update, 1000);\n}\n\n/**\n * Remove the debug overlay from the DOM and stop updates.\n */\nexport function disableDebugOverlay(): void {\n if (updateInterval) {\n clearInterval(updateInterval);\n updateInterval = null;\n }\n if (overlayElement && overlayElement.parentNode) {\n overlayElement.parentNode.removeChild(overlayElement);\n }\n overlayElement = null;\n}\n\n/**\n * Returns whether the debug overlay is currently active.\n */\nexport function isDebugOverlayActive(): boolean {\n return overlayElement !== null;\n}\n\nfunction renderOverlay(state: DebugOverlayState): string {\n const statusDot = state.isOnline ? '🟢' : '🔴';\n const lines: string[] = [\n `<div style=\"font-size:13px;font-weight:bold;margin-bottom:8px;\">Layers Debug ${statusDot}</div>`,\n `<div><b>SDK:</b> ${escapeHtml(state.sdkVersion)}</div>`,\n `<div><b>App:</b> ${escapeHtml(state.appId)} (${escapeHtml(state.environment)})</div>`,\n `<div><b>Session:</b> ${escapeHtml(truncate(state.sessionId, 20))}</div>`,\n `<div><b>Install:</b> ${escapeHtml(truncate(state.installId ?? 'N/A', 20))}</div>`,\n `<div><b>Queue:</b> ${String(state.queueDepth)} events</div>`,\n `<div><b>Network:</b> ${state.isOnline ? 'Online' : 'Offline'}</div>`\n ];\n\n if (state.recentEvents.length > 0) {\n lines.push(\n `<div style=\"margin-top:8px;font-weight:bold;border-top:1px solid #444;padding-top:6px;\">Recent Events</div>`\n );\n for (const event of state.recentEvents.slice(0, 10)) {\n lines.push(`<div style=\"color:#aaa;\">${escapeHtml(event)}</div>`);\n }\n } else {\n lines.push(`<div style=\"margin-top:8px;color:#888;\">No events tracked yet</div>`);\n }\n\n return lines.join('');\n}\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n}\n\nfunction truncate(str: string, maxLen: number): string {\n if (str.length <= maxLen) return str;\n return `${str.slice(0, maxLen)}...`;\n}\n","// Deep link handling and parsing for the Web SDK.\n// Parses URL parameters for deep link data (scheme, host, path, query params)\n// and extracts attribution parameters (fbclid, gclid, ttclid, etc.).\n\nexport interface DeepLinkData {\n url: string;\n scheme: string;\n host: string;\n path: string;\n queryParams: Record<string, string>;\n timestamp: number;\n}\n\n/**\n * Parse a URL string into structured DeepLinkData.\n * Returns null if the URL cannot be parsed.\n */\nexport function parseDeepLink(url: string): DeepLinkData | null {\n try {\n const parsed = new URL(url);\n const params: Record<string, string> = {};\n parsed.searchParams.forEach((value, key) => {\n params[key] = value;\n });\n return {\n url,\n scheme: parsed.protocol.replace(':', ''),\n host: parsed.hostname,\n path: parsed.pathname,\n queryParams: params,\n timestamp: Date.now()\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Set up a listener for URL changes in a web browser context.\n * Listens for `popstate` and `hashchange` events and calls the callback\n * with parsed deep link data on each URL change.\n *\n * Returns an unsubscribe function to remove the listeners.\n */\nexport function setupDeepLinkListener(onDeepLink: (data: DeepLinkData) => void): () => void {\n if (typeof window === 'undefined' || !window.location) return () => {};\n\n let lastUrl: string;\n try {\n lastUrl = window.location.href;\n } catch {\n return () => {};\n }\n\n const handleUrlChange = (): void => {\n const currentUrl = window.location.href;\n if (currentUrl === lastUrl) return;\n lastUrl = currentUrl;\n\n const parsed = parseDeepLink(currentUrl);\n if (parsed) onDeepLink(parsed);\n };\n\n window.addEventListener('popstate', handleUrlChange);\n window.addEventListener('hashchange', handleUrlChange);\n\n // Also check the initial URL\n const initialData = parseDeepLink(window.location.href);\n if (initialData && Object.keys(initialData.queryParams).length > 0) {\n onDeepLink(initialData);\n }\n\n return () => {\n window.removeEventListener('popstate', handleUrlChange);\n window.removeEventListener('hashchange', handleUrlChange);\n };\n}\n","// Standard event types for Layers Analytics.\n// These 18 events match the canonical Layers event taxonomy\n// and are consistent across all SDK platforms.\nimport type { EventProperties } from '@layers/core-wasm';\n\n/**\n * Predefined standard event name constants.\n *\n * Usage:\n * ```ts\n * import { StandardEvents } from '@layers/client';\n * client.track(StandardEvents.PURCHASE, { amount: 9.99, currency: 'USD' });\n * ```\n */\nexport const StandardEvents = {\n APP_OPEN: 'app_open',\n LOGIN: 'login',\n SIGN_UP: 'sign_up',\n REGISTER: 'register',\n PURCHASE: 'purchase_success',\n ADD_TO_CART: 'add_to_cart',\n ADD_TO_WISHLIST: 'add_to_wishlist',\n INITIATE_CHECKOUT: 'initiate_checkout',\n BEGIN_CHECKOUT: 'begin_checkout',\n START_TRIAL: 'start_trial',\n SUBSCRIBE: 'subscribe',\n LEVEL_START: 'level_start',\n LEVEL_COMPLETE: 'level_complete',\n TUTORIAL_COMPLETE: 'tutorial_complete',\n SEARCH: 'search',\n VIEW_ITEM: 'view_item',\n VIEW_CONTENT: 'view_content',\n SHARE: 'share',\n DEEP_LINK: 'deep_link_opened',\n SCREEN_VIEW: 'screen_view'\n} as const;\n\n/** Union type of all standard event name strings. */\nexport type StandardEventName = (typeof StandardEvents)[keyof typeof StandardEvents];\n\n// ---------------------------------------------------------------------------\n// Typed helper functions for building standard event payloads.\n// Each returns { event: string; properties: EventProperties } suitable for\n// destructuring into a track() call.\n// ---------------------------------------------------------------------------\n\nexport interface StandardEventPayload {\n event: StandardEventName;\n properties: EventProperties;\n}\n\n/** Build a login event. */\nexport function loginEvent(method?: string): StandardEventPayload {\n const properties: EventProperties = {};\n if (method !== undefined) properties.method = method;\n return { event: StandardEvents.LOGIN, properties };\n}\n\n/** Build a sign-up event. */\nexport function signUpEvent(method?: string): StandardEventPayload {\n const properties: EventProperties = {};\n if (method !== undefined) properties.method = method;\n return { event: StandardEvents.SIGN_UP, properties };\n}\n\n/** Build a register event. */\nexport function registerEvent(method?: string): StandardEventPayload {\n const properties: EventProperties = {};\n if (method !== undefined) properties.method = method;\n return { event: StandardEvents.REGISTER, properties };\n}\n\n/** Build a purchase event. */\nexport function purchaseEvent(\n amount: number,\n currency = 'USD',\n itemId?: string\n): StandardEventPayload {\n const properties: EventProperties = { amount, currency };\n if (itemId !== undefined) properties.item_id = itemId;\n return { event: StandardEvents.PURCHASE, properties };\n}\n\n/** Build an add-to-cart event. */\nexport function addToCartEvent(itemId: string, price: number, quantity = 1): StandardEventPayload {\n return {\n event: StandardEvents.ADD_TO_CART,\n properties: { item_id: itemId, price, quantity }\n };\n}\n\n/** Build an add-to-wishlist event. */\nexport function addToWishlistEvent(\n itemId: string,\n name?: string,\n price?: number\n): StandardEventPayload {\n const properties: EventProperties = { item_id: itemId };\n if (name !== undefined) properties.name = name;\n if (price !== undefined) properties.price = price;\n return { event: StandardEvents.ADD_TO_WISHLIST, properties };\n}\n\n/** Build an initiate-checkout event. */\nexport function initiateCheckoutEvent(\n value: number,\n currency = 'USD',\n itemCount?: number\n): StandardEventPayload {\n const properties: EventProperties = { value, currency };\n if (itemCount !== undefined) properties.item_count = itemCount;\n return { event: StandardEvents.INITIATE_CHECKOUT, properties };\n}\n\n/** Build a start-trial event. */\nexport function startTrialEvent(plan?: string, durationDays?: number): StandardEventPayload {\n const properties: EventProperties = {};\n if (plan !== undefined) properties.plan = plan;\n if (durationDays !== undefined) properties.duration_days = durationDays;\n return { event: StandardEvents.START_TRIAL, properties };\n}\n\n/** Build a subscribe event. */\nexport function subscribeEvent(\n plan: string,\n amount: number,\n currency = 'USD'\n): StandardEventPayload {\n return {\n event: StandardEvents.SUBSCRIBE,\n properties: { plan, amount, currency }\n };\n}\n\n/** Build a level-start event. */\nexport function levelStartEvent(level: string): StandardEventPayload {\n return { event: StandardEvents.LEVEL_START, properties: { level } };\n}\n\n/** Build a level-complete event. */\nexport function levelCompleteEvent(level: string, score?: number): StandardEventPayload {\n const properties: EventProperties = { level };\n if (score !== undefined) properties.score = score;\n return { event: StandardEvents.LEVEL_COMPLETE, properties };\n}\n\n/** Build a tutorial-complete event. */\nexport function tutorialCompleteEvent(name?: string): StandardEventPayload {\n const properties: EventProperties = {};\n if (name !== undefined) properties.name = name;\n return { event: StandardEvents.TUTORIAL_COMPLETE, properties };\n}\n\n/** Build a search event. */\nexport function searchEvent(query: string, resultCount?: number): StandardEventPayload {\n const properties: EventProperties = { query };\n if (resultCount !== undefined) properties.result_count = resultCount;\n return { event: StandardEvents.SEARCH, properties };\n}\n\n/** Build a view-item event. */\nexport function viewItemEvent(\n itemId: string,\n name?: string,\n category?: string\n): StandardEventPayload {\n const properties: EventProperties = { item_id: itemId };\n if (name !== undefined) properties.name = name;\n if (category !== undefined) properties.category = category;\n return { event: StandardEvents.VIEW_ITEM, properties };\n}\n\n/** Build a view-content event. */\nexport function viewContentEvent(\n contentId: string,\n contentType?: string,\n name?: string\n): StandardEventPayload {\n const properties: EventProperties = { content_id: contentId };\n if (contentType !== undefined) properties.content_type = contentType;\n if (name !== undefined) properties.name = name;\n return { event: StandardEvents.VIEW_CONTENT, properties };\n}\n\n/** Build a share event. */\nexport function shareEvent(\n contentType: string,\n method?: string,\n contentId?: string\n): StandardEventPayload {\n const properties: EventProperties = { content_type: contentType };\n if (method !== undefined) properties.method = method;\n if (contentId !== undefined) properties.content_id = contentId;\n return { event: StandardEvents.SHARE, properties };\n}\n\n/** Build a screen-view event. */\nexport function screenViewEvent(name: string, screenClass?: string): StandardEventPayload {\n const properties: EventProperties = { screen_name: name };\n if (screenClass !== undefined) properties.screen_class = screenClass;\n return { event: StandardEvents.SCREEN_VIEW, properties };\n}\n","// Commerce module for @layers/client (Web SDK).\n// Cross-platform purchase, subscription, cart, and refund tracking helpers.\n// Each function accepts a WebCommerceTracker instance and tracks the appropriate\n// event with standardized properties consistent with the iOS CommerceModule,\n// Android CommerceModule, and RN commerce module.\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Event properties bag accepted by commerce functions. */\nexport type EventProperties = Record<string, unknown>;\n\n/** Minimal Layers SDK interface required by the commerce module. */\nexport interface WebCommerceTracker {\n track(event: string, properties?: Record<string, any>): void;\n}\n\n/** Purchase details for trackPurchase. */\nexport interface PurchaseParams {\n productId: string;\n /** Unit price of the item. Revenue is computed as `price * quantity`. */\n price: number;\n currency: string;\n transactionId?: string;\n quantity?: number;\n isRestored?: boolean;\n store?: string;\n properties?: EventProperties;\n}\n\n/** Subscription details for trackSubscription. */\nexport interface SubscriptionParams {\n productId: string;\n /** Unit price of the subscription. */\n price: number;\n currency: string;\n period?: string;\n transactionId?: string;\n isRenewal?: boolean;\n isTrial?: boolean;\n subscriptionGroupId?: string;\n originalTransactionId?: string;\n properties?: EventProperties;\n}\n\n/** Cart item for order and checkout tracking. */\nexport interface CartItem {\n productId: string;\n name: string;\n price: number;\n quantity?: number;\n category?: string;\n}\n\n/** Order details for trackOrder. */\nexport interface OrderParams {\n orderId: string;\n items: CartItem[];\n subtotal: number;\n currency?: string;\n tax?: number;\n shipping?: number;\n discount?: number;\n couponCode?: string;\n properties?: EventProperties;\n}\n\n/** Refund details for trackRefund. */\nexport interface RefundParams {\n transactionId: string;\n amount: number;\n currency: string;\n reason?: string;\n properties?: EventProperties;\n}\n\n/** Purchase failure details for trackPurchaseFailed. */\nexport interface PurchaseFailedParams {\n productId: string;\n currency: string;\n errorCode: string | number;\n errorMessage?: string;\n properties?: EventProperties;\n}\n\n// ---------------------------------------------------------------------------\n// Purchase tracking\n// ---------------------------------------------------------------------------\n\n/**\n * Track a successful purchase.\n *\n * ```ts\n * import { trackPurchase } from '@layers/client';\n *\n * trackPurchase(layers, {\n * productId: 'premium_monthly',\n * price: 9.99,\n * currency: 'USD',\n * transactionId: 'txn_abc123',\n * });\n * ```\n */\nexport function trackPurchase(layers: WebCommerceTracker, params: PurchaseParams): void {\n const quantity = params.quantity ?? 1;\n const props: EventProperties = {\n product_id: params.productId,\n price: params.price,\n currency: params.currency,\n quantity,\n revenue: params.price * quantity,\n ...params.properties\n };\n if (params.transactionId !== undefined) props.transaction_id = params.transactionId;\n if (params.isRestored !== undefined) props.is_restored = params.isRestored;\n if (params.store !== undefined) props.store = params.store;\n\n layers.track('purchase_success', props);\n}\n\n/**\n * Track a failed purchase attempt.\n */\nexport function trackPurchaseFailed(\n layers: WebCommerceTracker,\n params: PurchaseFailedParams\n): void {\n const props: EventProperties = {\n product_id: params.productId,\n currency: params.currency,\n error_code: params.errorCode,\n ...params.properties\n };\n if (params.errorMessage !== undefined) props.error_message = params.errorMessage;\n\n layers.track('purchase_failed', props);\n}\n\n// ---------------------------------------------------------------------------\n// Subscription tracking\n// ---------------------------------------------------------------------------\n\n/**\n * Track a subscription purchase or renewal.\n *\n * ```ts\n * import { trackSubscription } from '@layers/client';\n *\n * trackSubscription(layers, {\n * productId: 'pro_annual',\n * price: 49.99,\n * currency: 'USD',\n * period: 'P1Y',\n * });\n * ```\n */\nexport function trackSubscription(layers: WebCommerceTracker, params: SubscriptionParams): void {\n const props: EventProperties = {\n product_id: params.productId,\n price: params.price,\n currency: params.currency,\n quantity: 1,\n revenue: params.price,\n ...params.properties\n };\n if (params.transactionId !== undefined) props.transaction_id = params.transactionId;\n if (params.period !== undefined) props.period = params.period;\n if (params.isRenewal !== undefined) props.is_renewal = params.isRenewal;\n if (params.isTrial !== undefined) props.is_trial = params.isTrial;\n if (params.subscriptionGroupId !== undefined)\n props.subscription_group_id = params.subscriptionGroupId;\n if (params.originalTransactionId !== undefined)\n props.original_transaction_id = params.originalTransactionId;\n\n layers.track('subscribe', props);\n}\n\n// ---------------------------------------------------------------------------\n// Order / cart tracking\n// ---------------------------------------------------------------------------\n\n/**\n * Track a completed order with multiple line items.\n */\nexport function trackOrder(layers: WebCommerceTracker, params: OrderParams): void {\n const currency = params.currency ?? 'USD';\n let total = params.subtotal;\n if (params.tax !== undefined) total += params.tax;\n if (params.shipping !== undefined) total += params.shipping;\n if (params.discount !== undefined) total -= params.discount;\n\n const props: EventProperties = {\n order_id: params.orderId,\n subtotal: params.subtotal,\n total,\n currency,\n item_count: params.items.length,\n revenue: total,\n product_ids: params.items.map((i) => i.productId).join(','),\n ...params.properties\n };\n if (params.tax !== undefined) props.tax = params.tax;\n if (params.shipping !== undefined) props.shipping = params.shipping;\n if (params.discount !== undefined) props.discount = params.discount;\n if (params.couponCode !== undefined) props.coupon_code = params.couponCode;\n\n layers.track('purchase_success', props);\n}\n\n/**\n * Track an item being added to the cart.\n */\nexport function trackAddToCart(\n layers: WebCommerceTracker,\n item: CartItem,\n properties?: EventProperties\n): void {\n const quantity = item.quantity ?? 1;\n const props: EventProperties = {\n product_id: item.productId,\n product_name: item.name,\n price: item.price,\n quantity,\n value: item.price * quantity,\n ...properties\n };\n if (item.category !== undefined) props.category = item.category;\n\n layers.track('add_to_cart', props);\n}\n\n/**\n * Track an item being removed from the cart.\n */\nexport function trackRemoveFromCart(\n layers: WebCommerceTracker,\n item: CartItem,\n properties?: EventProperties\n): void {\n const quantity = item.quantity ?? 1;\n const props: EventProperties = {\n product_id: item.productId,\n product_name: item.name,\n price: item.price,\n quantity,\n ...properties\n };\n if (item.category !== undefined) props.category = item.category;\n\n layers.track('remove_from_cart', props);\n}\n\n/**\n * Track beginning the checkout flow.\n */\nexport function trackBeginCheckout(\n layers: WebCommerceTracker,\n items: CartItem[],\n currency = 'USD',\n properties?: EventProperties\n): void {\n const total = items.reduce((sum, item) => sum + item.price * (item.quantity ?? 1), 0);\n const props: EventProperties = {\n item_count: items.length,\n value: total,\n currency,\n product_ids: items.map((i) => i.productId).join(','),\n ...properties\n };\n\n layers.track('begin_checkout', props);\n}\n\n// ---------------------------------------------------------------------------\n// Product view tracking\n// ---------------------------------------------------------------------------\n\n/**\n * Track viewing a product detail page.\n */\nexport function trackViewProduct(\n layers: WebCommerceTracker,\n productId: string,\n name: string,\n price: number,\n currency = 'USD',\n category?: string,\n properties?: EventProperties\n): void {\n const props: EventProperties = {\n product_id: productId,\n product_name: name,\n price,\n currency,\n ...properties\n };\n if (category !== undefined) props.category = category;\n\n layers.track('view_item', props);\n}\n\n// ---------------------------------------------------------------------------\n// Refund tracking\n// ---------------------------------------------------------------------------\n\n/**\n * Track a refund.\n */\nexport function trackRefund(layers: WebCommerceTracker, params: RefundParams): void {\n const props: EventProperties = {\n transaction_id: params.transactionId,\n amount: params.amount,\n currency: params.currency,\n ...params.properties\n };\n if (params.reason !== undefined) props.reason = params.reason;\n\n layers.track('refund', props);\n}\n","// @layers/client — Web browser SDK.\n// Thin wrapper over @layers/core-wasm. Owns only:\n// - localStorage persistence\n// - window online/offline detection\n// - navigator device info\n// - visibilitychange / beforeunload flush\n// - Install ID persistence (localStorage)\n// - Deep link handling/parsing (popstate, hashchange)\n// - setAttributionData API\n// - Clipboard attribution check\n// - Install event gating (24h window)\n// - Debug overlay (DOM-based)\n// - Init timing measurement\n// - Full lifecycle events (app_open, app_background, app_foreground)\n// - Queue depth gating\nimport {\n FetchHttpClient,\n LayersCore,\n LayersError,\n createDefaultPersistence\n} from '@layers/core-wasm';\nimport type {\n ConsentState,\n DeviceContext,\n Environment,\n EventProperties,\n UserProperties\n} from '@layers/core-wasm';\n\nimport { captureAttribution, getAttributionProperties } from './attribution.js';\nimport { getCapiProperties } from './capi.js';\nimport {\n disableDebugOverlay as hideDebugOverlay,\n enableDebugOverlay as showDebugOverlay\n} from './debug-overlay.js';\nimport { parseDeepLink, setupDeepLinkListener } from './deep-links.js';\nimport type { DeepLinkData } from './deep-links.js';\n\nexport type {\n ConsentState,\n DeviceContext,\n Environment,\n EventProperties,\n UserProperties\n} from '@layers/core-wasm';\n\nexport { LayersError } from '@layers/core-wasm';\n\nexport * from './api-types.js';\nexport type { AttributionData } from './attribution.js';\nexport { getAttribution, getAttributionProperties } from './attribution.js';\nexport {\n getCapiProperties,\n getFbpCookie,\n getTtpCookie,\n getPageUrl,\n getFbc,\n formatFbc\n} from './capi.js';\n\nexport { StandardEvents } from './standard-events.js';\nexport type { StandardEventName, StandardEventPayload } from './standard-events.js';\nexport {\n loginEvent,\n signUpEvent,\n registerEvent,\n purchaseEvent,\n addToCartEvent,\n addToWishlistEvent,\n initiateCheckoutEvent,\n startTrialEvent,\n subscribeEvent,\n levelStartEvent,\n levelCompleteEvent,\n tutorialCompleteEvent,\n searchEvent,\n viewItemEvent,\n viewContentEvent,\n shareEvent,\n screenViewEvent\n} from './standard-events.js';\n\nexport type { DeepLinkData } from './deep-links.js';\nexport { parseDeepLink, setupDeepLinkListener } from './deep-links.js';\nexport type { DebugOverlayState } from './debug-overlay.js';\n\nexport type {\n WebCommerceTracker,\n PurchaseParams,\n SubscriptionParams,\n CartItem,\n OrderParams,\n RefundParams,\n PurchaseFailedParams\n} from './commerce.js';\nexport {\n trackPurchase,\n trackPurchaseFailed,\n trackSubscription,\n trackOrder,\n trackAddToCart,\n trackRemoveFromCart,\n trackBeginCheckout,\n trackViewProduct,\n trackRefund\n} from './commerce.js';\n\nexport interface LayersConfig {\n /** Unique application identifier issued by the Layers dashboard. */\n appId: string;\n /** Deployment environment label. @default \"production\" */\n environment?: Environment;\n /** Optional user identifier to associate events with from the start. */\n appUserId?: string;\n /** Enable verbose debug logging to the console. @default false */\n enableDebug?: boolean;\n /** Base URL for the Layers ingest API. @default \"https://in.layers.com\" */\n baseUrl?: string;\n /** How often the event queue is flushed, in milliseconds. @default 10000 */\n flushIntervalMs?: number;\n /** Number of queued events that triggers an automatic flush. @default 10 */\n flushThreshold?: number;\n /** Maximum number of events to hold in the queue before dropping. @default 1000 */\n maxQueueSize?: number;\n /**\n * Whether to automatically fire an `app_open` event during init().\n * Set to `false` if you want to fire the event manually.\n * @default true\n */\n autoTrackAppOpen?: boolean;\n /**\n * Whether to automatically track `deep_link_opened` events when the URL\n * changes (popstate/hashchange). The tracked event includes the parsed\n * URL components and all query parameters.\n * @default true\n */\n autoTrackDeepLinks?: boolean;\n}\n\n/**\n * Attribution data that will be attached to all subsequent events.\n * Matches the RN SDK's setAttributionData pattern.\n */\nexport interface WebAttributionData {\n deeplinkId?: string | null;\n gclid?: string | null;\n fbclid?: string | null;\n ttclid?: string | null;\n msclkid?: string | null;\n}\n\nexport type ErrorListener = (error: Error) => void;\n\n/**\n * Listener for SDK initialization timing metrics.\n *\n * @param mainThreadDurationMs Time spent in the synchronous portion of init.\n * @param totalDurationMs Total wall-clock time of the `init()` call,\n * including all async work (remote config fetch, etc.).\n */\nexport type InitListener = (mainThreadDurationMs: number, totalDurationMs: number) => void;\n\n// --- localStorage keys ---\nconst INSTALL_ID_KEY = 'layers_install_id';\nconst FIRST_LAUNCH_TRACKED_KEY = 'layers_first_launch_tracked';\nconst FIRST_INSTALL_TIME_KEY = 'layers_first_install_time';\nconst CLIPBOARD_CHECKED_KEY = 'layers_clipboard_checked';\nconst ATTRIBUTION_DATA_KEY = 'layers_attribution_data';\n\n/** Maximum age of an installation for install event gating (24 hours). */\nconst INSTALL_EVENT_MAX_DIFF_MS = 24 * 60 * 60 * 1000;\n\nexport class LayersClient {\n private core: LayersCore;\n private appUserId: string | undefined;\n private isOnline = true;\n private readonly enableDebug: boolean;\n private readonly baseUrl: string;\n private readonly config: LayersConfig;\n\n // Stored listener references for cleanup on shutdown\n private onlineListener: (() => void) | null = null;\n private offlineListener: (() => void) | null = null;\n private visibilityListener: (() => void) | null = null;\n private beforeUnloadListener: (() => void) | null = null;\n private deepLinkUnsubscribe: (() => void) | null = null;\n\n // Error listeners\n private readonly errorListeners: Set<ErrorListener> = new Set();\n\n // Install ID\n private _installId: string | null = null;\n\n // Whether the SDK had prior state (install_id existed) at initialization time.\n private _hadPriorSdkState = false;\n\n // Attribution data stored for attachment to subsequent events.\n private _attributionData: WebAttributionData | null = null;\n\n // Recent events buffer for debug overlay (circular, last N events)\n private static readonly MAX_RECENT_EVENTS = 20;\n private _recentEvents: string[] = [];\n private _isInitialized = false;\n\n // Init timing listener\n private _initListener: InitListener | null = null;\n\n // Debug overlay state\n private _debugOverlayActive = false;\n\n // Quick flush timer for debounced delivery of initial events.\n // Disabled after the first regular flush interval fires to avoid\n // reducing the effective flush interval for the entire session.\n private quickFlushTimer: ReturnType<typeof setTimeout> | null = null;\n private quickFlushEnabled = true;\n private quickFlushDisableTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(config: LayersConfig) {\n this.enableDebug = config.enableDebug ?? false;\n this.baseUrl = (config.baseUrl ?? 'https://in.layers.com').replace(/\\/$/, '');\n this.appUserId = config.appUserId;\n this.config = config;\n\n const persistence = createDefaultPersistence(config.appId);\n const httpClient = new FetchHttpClient();\n\n this.core = LayersCore.init({\n config: {\n appId: config.appId,\n environment: config.environment ?? 'production',\n ...(config.baseUrl != null && { baseUrl: config.baseUrl }),\n ...(config.enableDebug != null && { enableDebug: config.enableDebug }),\n flushIntervalMs: config.flushIntervalMs ?? 10_000,\n ...(config.flushThreshold != null && { flushThreshold: config.flushThreshold }),\n ...(config.maxQueueSize != null && { maxQueueSize: config.maxQueueSize }),\n sdkVersion: `client/${SDK_VERSION}`\n },\n httpClient,\n persistence\n });\n\n if (this.appUserId) {\n this.core.identify(this.appUserId);\n }\n }\n\n /** Initialize the client: detects device info, attaches lifecycle listeners, and fetches remote config. */\n async init(): Promise<void> {\n const initStartTime = typeof performance !== 'undefined' ? performance.now() : Date.now();\n\n // Synchronous init work\n this.initializeInstallId();\n this.initializeDeviceInfo();\n this.setupNetworkListener();\n this.setupLifecycleListeners();\n captureAttribution();\n this.restoreAttributionData();\n\n // Main thread init complete — record timing\n const mainThreadEndTime = typeof performance !== 'undefined' ? performance.now() : Date.now();\n const mainThreadDurationMs = Math.round(mainThreadEndTime - initStartTime);\n\n // Async init work\n await this.core.fetchRemoteConfig().catch(() => {\n // Remote config fetch is best-effort\n });\n\n // Clipboard attribution check (only on first init, gated by remote config)\n this.checkClipboardAttribution();\n\n // Install event gating + app_open\n if (this.config.autoTrackAppOpen !== false) {\n const appOpenProps: Record<string, unknown> = {};\n const isFirstLaunch = this.shouldTreatAsNewInstall();\n appOpenProps.is_first_launch = isFirstLaunch;\n\n if (isFirstLaunch) {\n this.storageSet(FIRST_LAUNCH_TRACKED_KEY, 'true');\n }\n\n this.track('app_open', appOpenProps);\n }\n\n // Auto-track deep link events\n if (this.config.autoTrackDeepLinks !== false) {\n this.setupDeepLinkAutoTracking();\n }\n\n this._isInitialized = true;\n\n // Measure total duration\n const totalEndTime = typeof performance !== 'undefined' ? performance.now() : Date.now();\n const totalDurationMs = Math.round(totalEndTime - initStartTime);\n\n // Track init timing event\n this.trackInitTiming(mainThreadDurationMs, totalDurationMs);\n\n if (this.enableDebug) {\n console.log(\n `[Layers] Init timing: mainThread=${String(mainThreadDurationMs)}ms, total=${String(totalDurationMs)}ms`\n );\n }\n\n // Notify init listener\n if (this._initListener) {\n try {\n this._initListener(mainThreadDurationMs, totalDurationMs);\n } catch (e) {\n if (this.enableDebug) {\n console.warn('[Layers] InitListener threw:', e);\n }\n }\n }\n\n // Flush immediately after init to ensure app_open is delivered\n // before user potentially closes the tab\n this.core.flushAsync().catch(() => {});\n\n // Disable quick flush after the first regular flush interval fires.\n // Quick flush is only needed during the initial window (before the\n // periodic flush timer has a chance to fire).\n const flushInterval = this.config.flushIntervalMs ?? 10_000;\n this.quickFlushDisableTimer = setTimeout(() => {\n this.quickFlushEnabled = false;\n this.quickFlushDisableTimer = null;\n }, flushInterval);\n }\n\n /**\n * Record a custom analytics event with an optional property bag.\n *\n * Events are batched and flushed automatically when the queue reaches\n * `flushThreshold` or the periodic flush timer fires.\n */\n track(eventName: string, properties?: EventProperties): void {\n if (this.enableDebug) {\n console.log(\n `[Layers] track(\"${eventName}\", ${Object.keys(properties ?? {}).length} properties)`\n );\n }\n try {\n const merged = this.mergeAllProperties(properties);\n const depthBefore = this.core.queueDepth();\n this.core.track(eventName, merged, this.appUserId);\n const depthAfter = this.core.queueDepth();\n\n // Queue depth gating: verify event was accepted by core\n if (depthAfter <= depthBefore && this.enableDebug) {\n console.warn(\n `[Layers] track(\"${eventName}\") — event may not have been queued ` +\n `(depth before=${String(depthBefore)}, after=${String(depthAfter)})`\n );\n }\n\n // Record for debug overlay\n this.recordRecentEvent(eventName, properties);\n\n // Schedule a debounced flush for quick delivery of initial events\n this.scheduleQuickFlush();\n } catch (e) {\n this.emitError(e);\n }\n }\n\n /**\n * Record a screen view event with an optional property bag.\n *\n * Events are batched and flushed automatically when the queue reaches\n * `flushThreshold` or the periodic flush timer fires.\n */\n screen(screenName: string, properties?: EventProperties): void {\n if (this.enableDebug) {\n console.log(\n `[Layers] screen(\"${screenName}\", ${Object.keys(properties ?? {}).length} properties)`\n );\n }\n try {\n const merged = this.mergeAllProperties(properties);\n const depthBefore = this.core.queueDepth();\n this.core.screen(screenName, merged, this.appUserId);\n const depthAfter = this.core.queueDepth();\n\n if (depthAfter <= depthBefore && this.enableDebug) {\n console.warn(\n `[Layers] screen(\"${screenName}\") — event may not have been queued ` +\n `(depth before=${String(depthBefore)}, after=${String(depthAfter)})`\n );\n }\n\n this.recordRecentEvent(`screen:${screenName}`, properties);\n } catch (e) {\n this.emitError(e);\n }\n }\n\n /** Set or update user-level properties that persist across sessions. */\n setUserProperties(properties: UserProperties): void {\n this.core.setUserProperties(properties);\n }\n\n /** Set user-level properties with \"set once\" semantics — only keys not previously set are applied. */\n setUserPropertiesOnce(properties: UserProperties): void {\n this.core.setUserPropertiesOnce(properties);\n }\n\n /** Update the user's consent state for analytics and advertising data collection. */\n setConsent(consent: ConsentState): void {\n this.core.setConsent(consent);\n }\n\n /**\n * Associate all subsequent events with a group (company, team, organization).\n * Pass `undefined` or empty string to clear the group association.\n */\n group(groupId: string | undefined, properties?: EventProperties): void {\n if (this.enableDebug) {\n console.log(\n `[Layers] group(${groupId ? `\"${groupId}\"` : 'undefined'}, ${Object.keys(properties ?? {}).length} properties)`\n );\n }\n try {\n this.core.group(groupId ?? '', properties);\n } catch (e) {\n this.emitError(e);\n }\n }\n\n /** Associate all subsequent events with the given user ID, or clear it with `undefined`. */\n setAppUserId(appUserId: string | undefined): void {\n if (this.enableDebug) {\n console.log(`[Layers] setAppUserId(${appUserId ? `\"${appUserId}\"` : 'undefined'})`);\n }\n this.appUserId = appUserId;\n if (appUserId) {\n this.core.identify(appUserId);\n } else {\n this.core.identify('');\n }\n }\n\n /** @deprecated Use setAppUserId instead */\n setUserId(userId: string): void {\n this.setAppUserId(userId);\n }\n\n /** Return the current app user ID, or `undefined` if not set. */\n getAppUserId(): string | undefined {\n return this.appUserId;\n }\n\n /** @deprecated Use getAppUserId instead */\n getUserId(): string | undefined {\n return this.appUserId;\n }\n\n /** Return the current anonymous session ID. */\n getSessionId(): string {\n return this.core.getSessionId();\n }\n\n /** Return the current consent state for analytics and advertising. */\n getConsentState(): ConsentState {\n return this.core.getConsentState();\n }\n\n /** Override device-level context fields (platform, OS, locale, etc.). */\n setDeviceInfo(deviceInfo: DeviceContext): void {\n this.core.setDeviceContext(deviceInfo);\n }\n\n /**\n * Return the install ID (persistent UUID stored in localStorage).\n * Generated on first init, persists across sessions.\n */\n getInstallId(): string | null {\n return this._installId;\n }\n\n /**\n * Return the number of events currently queued.\n */\n getQueueDepth(): number {\n return this.core.queueDepth();\n }\n\n /**\n * Store attribution data that will be attached to all subsequent events.\n *\n * The values are persisted in localStorage so they survive page reloads.\n * Pass `null` to clear a value.\n *\n * When set, `deeplinkId`, `gclid`, `fbclid`, `ttclid`, and/or `msclkid`\n * are included in every event's properties.\n */\n setAttributionData(data: WebAttributionData): void {\n this._attributionData = data;\n\n // Update the Rust core's DeviceContext with the deeplinkId so the\n // top-level event field is populated.\n try {\n const currentContext = this.core.getDeviceContext();\n const ctx: DeviceContext = { ...currentContext };\n if (data.deeplinkId) {\n ctx.deeplinkId = data.deeplinkId;\n } else {\n delete ctx.deeplinkId;\n }\n this.core.setDeviceContext(ctx);\n } catch {\n // DeviceContext update is best-effort\n }\n\n // Persist to localStorage\n try {\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem(ATTRIBUTION_DATA_KEY, JSON.stringify(data));\n }\n } catch {\n // localStorage write is best-effort\n }\n\n if (this.enableDebug) {\n console.log(`[Layers] setAttributionData(${JSON.stringify(data)})`);\n }\n }\n\n /**\n * Set a listener to receive SDK initialization timing metrics.\n * Must be called **before** `init()` to receive the callback.\n * Pass `null` to clear the listener.\n */\n setInitListener(listener: InitListener | null): void {\n this._initListener = listener;\n }\n\n /**\n * Enable the debug overlay — a lightweight DOM panel showing SDK state.\n * The overlay updates every second with queue depth, session info, and recent events.\n */\n enableDebugOverlay(): void {\n this._debugOverlayActive = true;\n showDebugOverlay(() => ({\n sdkVersion: SDK_VERSION,\n queueDepth: this.core.queueDepth(),\n sessionId: this.core.getSessionId(),\n installId: this._installId,\n appId: this.config.appId,\n environment: this.config.environment ?? 'production',\n isOnline: this.isOnline,\n recentEvents: this._recentEvents\n }));\n }\n\n /**\n * Disable and remove the debug overlay from the DOM.\n */\n disableDebugOverlay(): void {\n this._debugOverlayActive = false;\n hideDebugOverlay();\n }\n\n /** Whether the SDK has completed async initialization. */\n get isInitialized(): boolean {\n return this._isInitialized;\n }\n\n /** SDK version string. */\n getSdkVersion(): string {\n return SDK_VERSION;\n }\n\n /**\n * Returns the most recent tracked events (newest first).\n * Each entry is a formatted string like \"12:34:56 event_name (3 props)\".\n */\n getRecentEvents(): readonly string[] {\n return this._recentEvents;\n }\n\n /** Flush all queued events to the server. Falls back to synchronous persistence on failure. */\n async flush(): Promise<void> {\n try {\n await this.core.flushAsync();\n } catch (e) {\n this.emitError(e);\n this.core.flush();\n }\n }\n\n /** Immediately shut down the client, removing all event listeners. Queued events are persisted but not flushed. */\n shutdown(): void {\n this.cleanupListeners();\n if (this._debugOverlayActive) {\n this.disableDebugOverlay();\n }\n this._attributionData = null;\n this._initListener = null;\n this.core.shutdown();\n }\n\n /**\n * Async shutdown: flushes remaining events before shutting down.\n * @param timeoutMs Maximum time to wait for flush (default 3000ms).\n */\n async shutdownAsync(timeoutMs = 3000): Promise<void> {\n this.cleanupListeners();\n if (this._debugOverlayActive) {\n this.disableDebugOverlay();\n }\n this._attributionData = null;\n this._initListener = null;\n try {\n await Promise.race([\n this.core.flushAsync(),\n new Promise<void>((resolve) => setTimeout(resolve, timeoutMs))\n ]);\n } catch {\n // Best effort — proceed with shutdown\n }\n this.core.shutdown();\n }\n\n private cleanupListeners(): void {\n if (this.quickFlushTimer) {\n clearTimeout(this.quickFlushTimer);\n this.quickFlushTimer = null;\n }\n if (this.quickFlushDisableTimer) {\n clearTimeout(this.quickFlushDisableTimer);\n this.quickFlushDisableTimer = null;\n }\n if (typeof window !== 'undefined') {\n if (this.onlineListener) {\n window.removeEventListener('online', this.onlineListener);\n this.onlineListener = null;\n }\n if (this.offlineListener) {\n window.removeEventListener('offline', this.offlineListener);\n this.offlineListener = null;\n }\n if (this.beforeUnloadListener) {\n window.removeEventListener('beforeunload', this.beforeUnloadListener);\n this.beforeUnloadListener = null;\n }\n }\n if (typeof document !== 'undefined' && this.visibilityListener) {\n document.removeEventListener('visibilitychange', this.visibilityListener);\n this.visibilityListener = null;\n }\n if (this.deepLinkUnsubscribe) {\n this.deepLinkUnsubscribe();\n this.deepLinkUnsubscribe = null;\n }\n }\n\n /** End the current session and start a new one with a fresh session ID. */\n startNewSession(): void {\n this.core.startNewSession();\n }\n\n /**\n * Register an error listener. Errors from track/screen/flush\n * that would otherwise be silently dropped are forwarded here.\n */\n on(event: 'error', listener: ErrorListener): this {\n if (event === 'error') this.errorListeners.add(listener);\n return this;\n }\n\n /**\n * Remove a previously registered error listener.\n */\n off(event: 'error', listener: ErrorListener): this {\n if (event === 'error') this.errorListeners.delete(listener);\n return this;\n }\n\n private emitError(error: unknown): void {\n const err = error instanceof Error ? error : new Error(String(error));\n for (const listener of this.errorListeners) {\n try {\n listener(err);\n } catch {}\n }\n if (this.enableDebug && this.errorListeners.size === 0) {\n console.warn('[Layers]', err.message);\n }\n }\n\n // --- Install ID persistence ---\n\n private initializeInstallId(): void {\n if (typeof localStorage === 'undefined') return;\n\n try {\n const existing = localStorage.getItem(INSTALL_ID_KEY);\n if (existing) {\n this._installId = existing;\n this._hadPriorSdkState = true;\n } else {\n const newId = generateUUID();\n localStorage.setItem(INSTALL_ID_KEY, newId);\n this._installId = newId;\n this._hadPriorSdkState = false;\n\n // Store first install timestamp for install event gating\n if (!localStorage.getItem(FIRST_INSTALL_TIME_KEY)) {\n localStorage.setItem(FIRST_INSTALL_TIME_KEY, String(Date.now()));\n }\n }\n } catch {\n // localStorage unavailable — generate an in-memory ID\n this._installId = generateUUID();\n }\n }\n\n // --- Install event gating (24h window) ---\n\n private shouldTreatAsNewInstall(): boolean {\n // If first_launch was already tracked, this is not a first launch\n const flag = this.storageGet(FIRST_LAUNCH_TRACKED_KEY);\n if (flag === 'true') return false;\n\n // If SDK had prior state (install_id existed), trust the flag\n if (this._hadPriorSdkState) return true;\n\n // SDK has no prior state — check whether the install is recent\n const installTimeStr = this.storageGet(FIRST_INSTALL_TIME_KEY);\n if (installTimeStr) {\n const installTime = Number(installTimeStr);\n if (Number.isFinite(installTime)) {\n const elapsed = Date.now() - installTime;\n const isRecentInstall = elapsed <= INSTALL_EVENT_MAX_DIFF_MS;\n\n if (!isRecentInstall && this.enableDebug) {\n console.log(\n `[Layers] Install event gated: installed ${Math.round(elapsed / 1000)}s ago ` +\n `(threshold=${INSTALL_EVENT_MAX_DIFF_MS / 1000}s), ` +\n 'no prior SDK state — suppressing is_first_launch'\n );\n }\n\n return isRecentInstall;\n }\n }\n\n // If we can't read the install time, default to trusting it as a new install\n return true;\n }\n\n // --- Attribution data ---\n\n private restoreAttributionData(): void {\n try {\n if (typeof localStorage === 'undefined') return;\n const raw = localStorage.getItem(ATTRIBUTION_DATA_KEY);\n if (!raw) return;\n const data: WebAttributionData = JSON.parse(raw);\n this._attributionData = data;\n\n // Sync restored deeplinkId to the Rust core's DeviceContext\n if (data.deeplinkId) {\n try {\n const currentContext = this.core.getDeviceContext();\n this.core.setDeviceContext({ ...currentContext, deeplinkId: data.deeplinkId });\n } catch {\n // best-effort\n }\n }\n\n if (this.enableDebug && data) {\n console.log(`[Layers] Restored attribution data: ${JSON.stringify(data)}`);\n }\n } catch {\n // Restoration is best-effort\n }\n }\n\n /**\n * Merge attribution properties into event properties.\n * deeplink_id flows through DeviceContext; other fields flow through properties.\n */\n private mergeAttributionProperties(properties?: EventProperties): EventProperties | undefined {\n const data = this._attributionData;\n if (!data) return properties;\n\n const merged: Record<string, unknown> = { ...(properties ?? {}) };\n if (data.gclid) merged.gclid = data.gclid;\n if (data.fbclid) merged.fbclid = data.fbclid;\n if (data.ttclid) merged.ttclid = data.ttclid;\n if (data.msclkid) merged.msclkid = data.msclkid;\n return merged as EventProperties;\n }\n\n /** Merge CAPI, attribution (url-based), setAttributionData, and user properties. */\n private mergeAllProperties(properties?: EventProperties): EventProperties {\n const capiProps = getCapiProperties();\n const urlAttrProps = getAttributionProperties();\n const attrProps = this.mergeAttributionProperties(undefined) ?? {};\n return { ...capiProps, ...urlAttrProps, ...attrProps, ...properties } as EventProperties;\n }\n\n // --- Clipboard attribution check ---\n\n private checkClipboardAttribution(): void {\n if (typeof navigator === 'undefined' || typeof localStorage === 'undefined') return;\n\n // Only check on first init\n try {\n if (localStorage.getItem(CLIPBOARD_CHECKED_KEY) === 'true') return;\n } catch {\n return;\n }\n\n // Gate behind remote config\n let clipboardEnabled = false;\n try {\n const configJson = this.core.getRemoteConfigJson?.();\n if (configJson) {\n const config = JSON.parse(configJson);\n clipboardEnabled = config?.clipboard_attribution_enabled === true;\n }\n } catch {}\n\n // Mark as checked regardless of outcome\n this.storageSet(CLIPBOARD_CHECKED_KEY, 'true');\n\n if (!clipboardEnabled) return;\n\n // Read clipboard (async, best-effort)\n if (navigator.clipboard?.readText) {\n void navigator.clipboard\n .readText()\n .then((text) => {\n if (!text) return;\n // Check for Layers click URL pattern\n const match = text.match(/https?:\\/\\/(in\\.layers\\.com|link\\.layers\\.com)\\/c\\/([^?\\s]+)/);\n if (match) {\n this.track('clipboard_attribution', {\n clipboard_url: text,\n clipboard_click_id: match[2]!\n });\n if (this.enableDebug) {\n console.log(`[Layers] Clipboard attribution found: ${match[2]!}`);\n }\n }\n })\n .catch(() => {\n // Clipboard read failed (permission denied) — silently ignore\n });\n }\n }\n\n // --- Deep link auto-tracking ---\n\n private _trackedDeepLinkUrls = new Set<string>();\n\n private setupDeepLinkAutoTracking(): void {\n this.deepLinkUnsubscribe = setupDeepLinkListener((data: DeepLinkData) => {\n // Deduplicate\n if (this._trackedDeepLinkUrls.has(data.url)) return;\n this._trackedDeepLinkUrls.add(data.url);\n // Clear after a short delay so the same URL can be tracked again later\n setTimeout(() => this._trackedDeepLinkUrls.delete(data.url), 2000);\n\n try {\n const properties: Record<string, unknown> = {\n ...data.queryParams,\n url: data.url,\n scheme: data.scheme,\n host: data.host,\n path: data.path\n };\n this.track('deep_link_opened', properties);\n if (this.enableDebug) {\n console.log(`[Layers] auto-tracked deep_link_opened: ${data.url}`);\n }\n } catch (e) {\n this.emitError(e);\n }\n });\n }\n\n // --- Init timing ---\n\n private trackInitTiming(mainThreadDurationMs: number, totalDurationMs: number): void {\n try {\n this.core.track(\n 'layers_init_timing',\n {\n duration_ms: totalDurationMs,\n main_thread_duration_ms: mainThreadDurationMs\n },\n this.appUserId\n );\n } catch {\n // Init timing is best-effort\n }\n }\n\n // --- Debounced quick flush (for initial events) ---\n\n private scheduleQuickFlush(): void {\n if (!this.quickFlushEnabled) return; // only active during initial window\n if (this.quickFlushTimer) return; // already scheduled\n this.quickFlushTimer = setTimeout(() => {\n this.quickFlushTimer = null;\n if (this.core.queueDepth() > 0) {\n this.core.flushAsync().catch(() => {});\n }\n }, 2000); // 2 second debounce\n }\n\n // --- Recent events buffer (for debug overlay) ---\n\n private recordRecentEvent(eventName: string, properties?: EventProperties): void {\n const now = new Date();\n const time = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`;\n const propCount = Object.keys(properties ?? {}).length;\n const entry = `${time} ${eventName}${propCount > 0 ? ` (${String(propCount)} props)` : ''}`;\n this._recentEvents.unshift(entry);\n if (this._recentEvents.length > LayersClient.MAX_RECENT_EVENTS) {\n this._recentEvents.pop();\n }\n }\n\n // --- Platform-specific: browser device info ---\n\n private initializeDeviceInfo(): void {\n const context: DeviceContext = {\n platform: 'web',\n osVersion: this.detectOS(),\n appVersion: SDK_VERSION,\n deviceModel: this.detectDeviceModel(),\n locale: this.detectLocale(),\n screenSize: this.detectScreenSize(),\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n ...(this._installId != null && { installId: this._installId })\n };\n this.core.setDeviceContext(context);\n }\n\n private detectOS(): string {\n if (typeof navigator === 'undefined') return 'unknown';\n const ua = navigator.userAgent;\n if (ua.includes('Windows')) return 'Windows';\n if (ua.includes('Mac OS')) return 'macOS';\n if (ua.includes('Linux')) return 'Linux';\n if (ua.includes('Android')) return 'Android';\n if (ua.includes('iPhone') || ua.includes('iPad')) return 'iOS';\n return 'unknown';\n }\n\n private detectDeviceModel(): string {\n if (typeof navigator === 'undefined') return 'unknown';\n if ('userAgentData' in navigator) {\n const uaData = (navigator as { userAgentData?: { platform?: string } }).userAgentData;\n if (uaData?.platform) return uaData.platform;\n }\n return navigator.platform ?? 'unknown';\n }\n\n private detectLocale(): string {\n if (typeof navigator === 'undefined') return 'en-US';\n return navigator.language ?? 'en-US';\n }\n\n private detectScreenSize(): string {\n if (typeof window === 'undefined' || typeof screen === 'undefined') return 'unknown';\n return `${screen.width}x${screen.height}`;\n }\n\n // --- Platform-specific: network listener ---\n\n private setupNetworkListener(): void {\n if (typeof window === 'undefined') return;\n\n this.isOnline = navigator?.onLine ?? true;\n\n this.onlineListener = () => {\n this.isOnline = true;\n void this.core.flushAsync().catch(() => {});\n };\n this.offlineListener = () => {\n this.isOnline = false;\n };\n\n window.addEventListener('online', this.onlineListener);\n window.addEventListener('offline', this.offlineListener);\n }\n\n // --- Platform-specific: lifecycle listeners ---\n\n private getBeaconUrl(): string {\n return `${this.baseUrl}/events`;\n }\n\n private setupLifecycleListeners(): void {\n if (typeof window === 'undefined' || typeof document === 'undefined') return;\n\n // Track app_background / app_foreground on visibilitychange,\n // and flush on page hide using sendBeacon.\n this.visibilityListener = () => {\n if (document.visibilityState === 'hidden') {\n // Track app_background lifecycle event\n try {\n this.core.track('app_background', {}, this.appUserId);\n this.recordRecentEvent('app_background');\n } catch {\n // best-effort\n }\n\n if (\n typeof navigator !== 'undefined' &&\n navigator.sendBeacon &&\n this.core.queueDepth() > 0\n ) {\n try {\n const batch = this.core.createBeaconPayload();\n if (batch) {\n const sent = navigator.sendBeacon(this.getBeaconUrl(), batch);\n if (sent) {\n this.core.clearBeaconEvents();\n return;\n }\n // sendBeacon failed — requeue events before falling back to persistence\n this.core.requeueBeaconEvents();\n this.core.flush();\n return;\n }\n } catch {\n // sendBeacon threw — requeue any drained events before sync flush\n this.core.requeueBeaconEvents();\n }\n }\n this.core.flush();\n } else if (document.visibilityState === 'visible') {\n // Track app_foreground lifecycle event\n try {\n this.core.track('app_foreground', {}, this.appUserId);\n this.recordRecentEvent('app_foreground');\n } catch {\n // best-effort\n }\n\n // Flush queued events when returning to foreground\n if (this.isOnline) {\n void this.core.flushAsync().catch(() => {});\n }\n }\n };\n document.addEventListener('visibilitychange', this.visibilityListener);\n\n // Flush on beforeunload — try sendBeacon for reliable delivery, fall back to sync persistence\n this.beforeUnloadListener = () => {\n // Check sendBeacon availability BEFORE draining events to avoid losing them\n if (typeof navigator !== 'undefined' && navigator.sendBeacon) {\n try {\n const payload = this.core.createBeaconPayload();\n if (payload) {\n const url = this.getBeaconUrl();\n if (navigator.sendBeacon(url, payload)) {\n this.core.clearBeaconEvents();\n return;\n }\n // sendBeacon failed — requeue before falling back to persistence\n this.core.requeueBeaconEvents();\n }\n } catch {\n // sendBeacon threw — requeue any drained events\n this.core.requeueBeaconEvents();\n }\n }\n // Fall back to sync persistence (queue is intact if sendBeacon was unavailable)\n this.core.flush();\n };\n window.addEventListener('beforeunload', this.beforeUnloadListener);\n }\n\n // --- localStorage helpers ---\n\n private storageGet(key: string): string | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n }\n\n private storageSet(key: string, value: string): void {\n if (typeof localStorage === 'undefined') return;\n try {\n localStorage.setItem(key, value);\n } catch {\n // localStorage full or unavailable\n }\n }\n}\n\n// --- UUID generation ---\n\nfunction generateUUID(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = Math.floor(Math.random() * 16);\n const v = c === 'x' ? r : (r % 4) + 8;\n return v.toString(16);\n });\n}\n\n// SDK version injected at build time by tsdown define\ndeclare const __LAYERS_CLIENT_VERSION__: string;\nconst SDK_VERSION: string =\n typeof __LAYERS_CLIENT_VERSION__ !== 'undefined' ? __LAYERS_CLIENT_VERSION__ : '0.1.1-alpha.1';\n"],"mappings":";;;AAAA,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AACD,MAAM,aAAa;CAAC;CAAc;CAAc;CAAgB;CAAe;CAAW;AAC1F,MAAM,cAAc;AACpB,MAAM,SAAS,MAAU,KAAK,KAAK;;;;;;AAmBnC,SAAgB,qBAA2B;AACzC,KAAI,OAAO,WAAW,eAAe,OAAO,iBAAiB,YAAa;CAE1E,IAAIA;AACJ,KAAI;AACF,WAAS,IAAI,gBAAgB,OAAO,SAAS,OAAO;SAC9C;AACN;;CAIF,IAAIC;CACJ,IAAIC;AACJ,MAAK,MAAM,SAAS,iBAAiB;EACnC,MAAM,QAAQ,OAAO,IAAI,MAAM;AAC/B,MAAI,OAAO;AACT,kBAAe;AACf,kBAAe;AACf;;;CAKJ,MAAMC,OAAoE,EAAE;CAC5E,IAAI,SAAS;AACb,MAAK,MAAM,SAAS,YAAY;EAC9B,MAAM,QAAQ,OAAO,IAAI,MAAM;AAC/B,MAAI,OAAO;AACT,QAAK,SAAS;AACd,YAAS;;;CAIb,MAAM,WACJ,OAAO,aAAa,eAAe,SAAS,WAAW,SAAS,WAAW;AAG7E,KAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,SAAU;CAE3C,MAAM,WAAW,gBAAgB;AAGjC,KAAI,cAAc;AAQhB,mBAP8B;GAC5B,gBAAgB;GAChB,GAAI,gBAAgB,QAAQ,EAAE,gBAAgB,cAAc;GAC5D,GAAG;GACH,GAAI,YAAY,QAAQ,EAAE,cAAc,UAAU;GAClD,aAAa,KAAK,KAAK;GACxB,CACqB;AACtB;;AAIF,KAAI,QAAQ;AASV,mBAR8B;GAE5B,GAAI,UAAU,kBAAkB,QAAQ,EAAE,gBAAgB,SAAS,gBAAgB;GACnF,GAAI,UAAU,kBAAkB,QAAQ,EAAE,gBAAgB,SAAS,gBAAgB;GACnF,GAAG;GACH,GAAI,YAAY,QAAQ,EAAE,cAAc,UAAU;GAClD,aAAa,KAAK,KAAK;GACxB,CACqB;AACtB;;AAIF,KAAI,CAAC,SAKH,kBAJ8B;EAC5B,GAAI,YAAY,QAAQ,EAAE,cAAc,UAAU;EAClD,aAAa,KAAK,KAAK;EACxB,CACqB;;;;;AAO1B,SAAgB,iBAAyC;AACvD,KAAI,OAAO,iBAAiB,YAAa,QAAO;AAEhD,KAAI;EACF,MAAM,MAAM,aAAa,QAAQ,YAAY;AAC7C,MAAI,CAAC,IAAK,QAAO;EAEjB,MAAMC,OAAwB,KAAK,MAAM,IAAI;AAC7C,MAAI,KAAK,KAAK,GAAG,KAAK,cAAc,QAAQ;AAC1C,gBAAa,WAAW,YAAY;AACpC,UAAO;;AAET,SAAO;SACD;AACN,SAAO;;;;;;;AAQX,SAAgB,2BAAmD;CACjE,MAAM,OAAO,gBAAgB;AAC7B,KAAI,CAAC,KAAM,QAAO,EAAE;CAEpB,MAAMC,QAAgC,EAAE;AAExC,KAAI,KAAK,eAAgB,OAAM,iCAAiC,KAAK;AACrE,KAAI,KAAK,eAAgB,OAAM,iCAAiC,KAAK;AACrE,KAAI,KAAK,WAAY,OAAM,6BAA6B,KAAK;AAC7D,KAAI,KAAK,WAAY,OAAM,6BAA6B,KAAK;AAC7D,KAAI,KAAK,aAAc,OAAM,+BAA+B,KAAK;AACjE,KAAI,KAAK,YAAa,OAAM,8BAA8B,KAAK;AAC/D,KAAI,KAAK,SAAU,OAAM,2BAA2B,KAAK;AACzD,KAAI,KAAK,aAAc,OAAM,+BAA+B,KAAK;AAEjE,QAAO;;AAGT,SAAS,iBAAiB,MAA6B;AACrD,KAAI;AACF,eAAa,QAAQ,aAAa,KAAK,UAAU,KAAK,CAAC;SACjD;;;;;;;;;ACnJV,SAAS,UAAU,MAAkC;AACnD,KAAI,OAAO,aAAa,eAAe,CAAC,SAAS,OAAQ,QAAO;CAIhE,MAAM,SAAS,GAAG,KAAK;CACvB,MAAM,UAAU,SAAS,OAAO,MAAM,KAAK;AAC3C,MAAK,MAAM,UAAU,QACnB,KAAI,OAAO,WAAW,OAAO,CAC3B,QAAO,mBAAmB,OAAO,MAAM,OAAO,OAAO,CAAC;;;;;;AAU5D,SAAgB,eAAmC;AACjD,QAAO,UAAU,OAAO;;;;;AAM1B,SAAgB,eAAmC;AACjD,QAAO,UAAU,OAAO;;;;;;AAO1B,SAAgB,aAAiC;AAC/C,KAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,KAAI;AACF,SAAO,OAAO,SAAS;SACjB;AACN;;;;;;;;;;AAWJ,SAAgB,UAAU,QAAgB,aAA8B;AAEtE,QAAO,QADI,eAAe,KAAK,KAAK,CAClB,GAAG;;;;;;;;AASvB,SAAgB,SAA6B;AAE3C,KAAI,OAAO,WAAW,YACpB,KAAI;EAEF,MAAM,SADS,IAAI,gBAAgB,OAAO,SAAS,OAAO,CACpC,IAAI,SAAS;AACnC,MAAI,OACF,QAAO,UAAU,OAAO;SAEpB;AAMV,QAAO,UAAU,OAAO;;;;;;AAO1B,SAAgB,oBAA4C;CAC1D,MAAMC,QAAgC,EAAE;CAExC,MAAM,MAAM,cAAc;AAC1B,KAAI,IAAK,OAAM,UAAU;CAEzB,MAAM,MAAM,cAAc;AAC1B,KAAI,IAAK,OAAM,UAAU;CAEzB,MAAM,UAAU,YAAY;AAC5B,KAAI,QAAS,OAAM,eAAe;CAElC,MAAM,MAAM,QAAQ;AACpB,KAAI,IAAK,OAAM,UAAU;AAEzB,QAAO;;;;;ACxFT,MAAM,aAAa;AACnB,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;AAmBvB,IAAIC,iBAAwC;AAC5C,IAAIC,iBAAwD;;;;;AAM5D,SAAgB,mBAAmB,eAAgD;AACjF,KAAI,OAAO,aAAa,YAAa;AAGrC,KAAI,eACF,sBAAqB;AAGvB,kBAAiB,SAAS,cAAc,MAAM;AAC9C,gBAAe,KAAK;AACpB,gBAAe,aAAa,SAAS,eAAe;AACpD,UAAS,KAAK,YAAY,eAAe;CAEzC,MAAM,eAAqB;AACzB,MAAI,CAAC,eAAgB;AAErB,iBAAe,YAAY,cADb,eAAe,CACkB;;AAGjD,SAAQ;AACR,kBAAiB,YAAY,QAAQ,IAAK;;;;;AAM5C,SAAgB,sBAA4B;AAC1C,KAAI,gBAAgB;AAClB,gBAAc,eAAe;AAC7B,mBAAiB;;AAEnB,KAAI,kBAAkB,eAAe,WACnC,gBAAe,WAAW,YAAY,eAAe;AAEvD,kBAAiB;;AAUnB,SAAS,cAAc,OAAkC;CAEvD,MAAMC,QAAkB;EACtB,gFAFgB,MAAM,WAAW,cAAc,YAE2C;EAC1F,oBAAoB,WAAW,MAAM,WAAW,CAAC;EACjD,oBAAoB,WAAW,MAAM,MAAM,CAAC,IAAI,WAAW,MAAM,YAAY,CAAC;EAC9E,wBAAwB,WAAW,SAAS,MAAM,WAAW,GAAG,CAAC,CAAC;EAClE,wBAAwB,WAAW,SAAS,MAAM,aAAa,OAAO,GAAG,CAAC,CAAC;EAC3E,sBAAsB,OAAO,MAAM,WAAW,CAAC;EAC/C,wBAAwB,MAAM,WAAW,WAAW,UAAU;EAC/D;AAED,KAAI,MAAM,aAAa,SAAS,GAAG;AACjC,QAAM,KACJ,8GACD;AACD,OAAK,MAAM,SAAS,MAAM,aAAa,MAAM,GAAG,GAAG,CACjD,OAAM,KAAK,4BAA4B,WAAW,MAAM,CAAC,QAAQ;OAGnE,OAAM,KAAK,sEAAsE;AAGnF,QAAO,MAAM,KAAK,GAAG;;AAGvB,SAAS,WAAW,KAAqB;AACvC,QAAO,IACJ,QAAQ,MAAM,QAAQ,CACtB,QAAQ,MAAM,OAAO,CACrB,QAAQ,MAAM,OAAO,CACrB,QAAQ,MAAM,SAAS;;AAG5B,SAAS,SAAS,KAAa,QAAwB;AACrD,KAAI,IAAI,UAAU,OAAQ,QAAO;AACjC,QAAO,GAAG,IAAI,MAAM,GAAG,OAAO,CAAC;;;;;;;;;AC3GjC,SAAgB,cAAc,KAAkC;AAC9D,KAAI;EACF,MAAM,SAAS,IAAI,IAAI,IAAI;EAC3B,MAAMC,SAAiC,EAAE;AACzC,SAAO,aAAa,SAAS,OAAO,QAAQ;AAC1C,UAAO,OAAO;IACd;AACF,SAAO;GACL;GACA,QAAQ,OAAO,SAAS,QAAQ,KAAK,GAAG;GACxC,MAAM,OAAO;GACb,MAAM,OAAO;GACb,aAAa;GACb,WAAW,KAAK,KAAK;GACtB;SACK;AACN,SAAO;;;;;;;;;;AAWX,SAAgB,sBAAsB,YAAsD;AAC1F,KAAI,OAAO,WAAW,eAAe,CAAC,OAAO,SAAU,cAAa;CAEpE,IAAIC;AACJ,KAAI;AACF,YAAU,OAAO,SAAS;SACpB;AACN,eAAa;;CAGf,MAAM,wBAA8B;EAClC,MAAM,aAAa,OAAO,SAAS;AACnC,MAAI,eAAe,QAAS;AAC5B,YAAU;EAEV,MAAM,SAAS,cAAc,WAAW;AACxC,MAAI,OAAQ,YAAW,OAAO;;AAGhC,QAAO,iBAAiB,YAAY,gBAAgB;AACpD,QAAO,iBAAiB,cAAc,gBAAgB;CAGtD,MAAM,cAAc,cAAc,OAAO,SAAS,KAAK;AACvD,KAAI,eAAe,OAAO,KAAK,YAAY,YAAY,CAAC,SAAS,EAC/D,YAAW,YAAY;AAGzB,cAAa;AACX,SAAO,oBAAoB,YAAY,gBAAgB;AACvD,SAAO,oBAAoB,cAAc,gBAAgB;;;;;;;;;;;;;;;AC5D7D,MAAa,iBAAiB;CAC5B,UAAU;CACV,OAAO;CACP,SAAS;CACT,UAAU;CACV,UAAU;CACV,aAAa;CACb,iBAAiB;CACjB,mBAAmB;CACnB,gBAAgB;CAChB,aAAa;CACb,WAAW;CACX,aAAa;CACb,gBAAgB;CAChB,mBAAmB;CACnB,QAAQ;CACR,WAAW;CACX,cAAc;CACd,OAAO;CACP,WAAW;CACX,aAAa;CACd;;AAiBD,SAAgB,WAAW,QAAuC;CAChE,MAAMC,aAA8B,EAAE;AACtC,KAAI,WAAW,OAAW,YAAW,SAAS;AAC9C,QAAO;EAAE,OAAO,eAAe;EAAO;EAAY;;;AAIpD,SAAgB,YAAY,QAAuC;CACjE,MAAMA,aAA8B,EAAE;AACtC,KAAI,WAAW,OAAW,YAAW,SAAS;AAC9C,QAAO;EAAE,OAAO,eAAe;EAAS;EAAY;;;AAItD,SAAgB,cAAc,QAAuC;CACnE,MAAMA,aAA8B,EAAE;AACtC,KAAI,WAAW,OAAW,YAAW,SAAS;AAC9C,QAAO;EAAE,OAAO,eAAe;EAAU;EAAY;;;AAIvD,SAAgB,cACd,QACA,WAAW,OACX,QACsB;CACtB,MAAMA,aAA8B;EAAE;EAAQ;EAAU;AACxD,KAAI,WAAW,OAAW,YAAW,UAAU;AAC/C,QAAO;EAAE,OAAO,eAAe;EAAU;EAAY;;;AAIvD,SAAgB,eAAe,QAAgB,OAAe,WAAW,GAAyB;AAChG,QAAO;EACL,OAAO,eAAe;EACtB,YAAY;GAAE,SAAS;GAAQ;GAAO;GAAU;EACjD;;;AAIH,SAAgB,mBACd,QACA,MACA,OACsB;CACtB,MAAMA,aAA8B,EAAE,SAAS,QAAQ;AACvD,KAAI,SAAS,OAAW,YAAW,OAAO;AAC1C,KAAI,UAAU,OAAW,YAAW,QAAQ;AAC5C,QAAO;EAAE,OAAO,eAAe;EAAiB;EAAY;;;AAI9D,SAAgB,sBACd,OACA,WAAW,OACX,WACsB;CACtB,MAAMA,aAA8B;EAAE;EAAO;EAAU;AACvD,KAAI,cAAc,OAAW,YAAW,aAAa;AACrD,QAAO;EAAE,OAAO,eAAe;EAAmB;EAAY;;;AAIhE,SAAgB,gBAAgB,MAAe,cAA6C;CAC1F,MAAMA,aAA8B,EAAE;AACtC,KAAI,SAAS,OAAW,YAAW,OAAO;AAC1C,KAAI,iBAAiB,OAAW,YAAW,gBAAgB;AAC3D,QAAO;EAAE,OAAO,eAAe;EAAa;EAAY;;;AAI1D,SAAgB,eACd,MACA,QACA,WAAW,OACW;AACtB,QAAO;EACL,OAAO,eAAe;EACtB,YAAY;GAAE;GAAM;GAAQ;GAAU;EACvC;;;AAIH,SAAgB,gBAAgB,OAAqC;AACnE,QAAO;EAAE,OAAO,eAAe;EAAa,YAAY,EAAE,OAAO;EAAE;;;AAIrE,SAAgB,mBAAmB,OAAe,OAAsC;CACtF,MAAMA,aAA8B,EAAE,OAAO;AAC7C,KAAI,UAAU,OAAW,YAAW,QAAQ;AAC5C,QAAO;EAAE,OAAO,eAAe;EAAgB;EAAY;;;AAI7D,SAAgB,sBAAsB,MAAqC;CACzE,MAAMA,aAA8B,EAAE;AACtC,KAAI,SAAS,OAAW,YAAW,OAAO;AAC1C,QAAO;EAAE,OAAO,eAAe;EAAmB;EAAY;;;AAIhE,SAAgB,YAAY,OAAe,aAA4C;CACrF,MAAMA,aAA8B,EAAE,OAAO;AAC7C,KAAI,gBAAgB,OAAW,YAAW,eAAe;AACzD,QAAO;EAAE,OAAO,eAAe;EAAQ;EAAY;;;AAIrD,SAAgB,cACd,QACA,MACA,UACsB;CACtB,MAAMA,aAA8B,EAAE,SAAS,QAAQ;AACvD,KAAI,SAAS,OAAW,YAAW,OAAO;AAC1C,KAAI,aAAa,OAAW,YAAW,WAAW;AAClD,QAAO;EAAE,OAAO,eAAe;EAAW;EAAY;;;AAIxD,SAAgB,iBACd,WACA,aACA,MACsB;CACtB,MAAMA,aAA8B,EAAE,YAAY,WAAW;AAC7D,KAAI,gBAAgB,OAAW,YAAW,eAAe;AACzD,KAAI,SAAS,OAAW,YAAW,OAAO;AAC1C,QAAO;EAAE,OAAO,eAAe;EAAc;EAAY;;;AAI3D,SAAgB,WACd,aACA,QACA,WACsB;CACtB,MAAMA,aAA8B,EAAE,cAAc,aAAa;AACjE,KAAI,WAAW,OAAW,YAAW,SAAS;AAC9C,KAAI,cAAc,OAAW,YAAW,aAAa;AACrD,QAAO;EAAE,OAAO,eAAe;EAAO;EAAY;;;AAIpD,SAAgB,gBAAgB,MAAc,aAA4C;CACxF,MAAMA,aAA8B,EAAE,aAAa,MAAM;AACzD,KAAI,gBAAgB,OAAW,YAAW,eAAe;AACzD,QAAO;EAAE,OAAO,eAAe;EAAa;EAAY;;;;;;;;;;;;;;;;;;;AChG1D,SAAgB,cAAc,QAA4B,QAA8B;CACtF,MAAM,WAAW,OAAO,YAAY;CACpC,MAAMC,QAAyB;EAC7B,YAAY,OAAO;EACnB,OAAO,OAAO;EACd,UAAU,OAAO;EACjB;EACA,SAAS,OAAO,QAAQ;EACxB,GAAG,OAAO;EACX;AACD,KAAI,OAAO,kBAAkB,OAAW,OAAM,iBAAiB,OAAO;AACtE,KAAI,OAAO,eAAe,OAAW,OAAM,cAAc,OAAO;AAChE,KAAI,OAAO,UAAU,OAAW,OAAM,QAAQ,OAAO;AAErD,QAAO,MAAM,oBAAoB,MAAM;;;;;AAMzC,SAAgB,oBACd,QACA,QACM;CACN,MAAMA,QAAyB;EAC7B,YAAY,OAAO;EACnB,UAAU,OAAO;EACjB,YAAY,OAAO;EACnB,GAAG,OAAO;EACX;AACD,KAAI,OAAO,iBAAiB,OAAW,OAAM,gBAAgB,OAAO;AAEpE,QAAO,MAAM,mBAAmB,MAAM;;;;;;;;;;;;;;;;AAqBxC,SAAgB,kBAAkB,QAA4B,QAAkC;CAC9F,MAAMA,QAAyB;EAC7B,YAAY,OAAO;EACnB,OAAO,OAAO;EACd,UAAU,OAAO;EACjB,UAAU;EACV,SAAS,OAAO;EAChB,GAAG,OAAO;EACX;AACD,KAAI,OAAO,kBAAkB,OAAW,OAAM,iBAAiB,OAAO;AACtE,KAAI,OAAO,WAAW,OAAW,OAAM,SAAS,OAAO;AACvD,KAAI,OAAO,cAAc,OAAW,OAAM,aAAa,OAAO;AAC9D,KAAI,OAAO,YAAY,OAAW,OAAM,WAAW,OAAO;AAC1D,KAAI,OAAO,wBAAwB,OACjC,OAAM,wBAAwB,OAAO;AACvC,KAAI,OAAO,0BAA0B,OACnC,OAAM,0BAA0B,OAAO;AAEzC,QAAO,MAAM,aAAa,MAAM;;;;;AAUlC,SAAgB,WAAW,QAA4B,QAA2B;CAChF,MAAM,WAAW,OAAO,YAAY;CACpC,IAAI,QAAQ,OAAO;AACnB,KAAI,OAAO,QAAQ,OAAW,UAAS,OAAO;AAC9C,KAAI,OAAO,aAAa,OAAW,UAAS,OAAO;AACnD,KAAI,OAAO,aAAa,OAAW,UAAS,OAAO;CAEnD,MAAMA,QAAyB;EAC7B,UAAU,OAAO;EACjB,UAAU,OAAO;EACjB;EACA;EACA,YAAY,OAAO,MAAM;EACzB,SAAS;EACT,aAAa,OAAO,MAAM,KAAK,MAAM,EAAE,UAAU,CAAC,KAAK,IAAI;EAC3D,GAAG,OAAO;EACX;AACD,KAAI,OAAO,QAAQ,OAAW,OAAM,MAAM,OAAO;AACjD,KAAI,OAAO,aAAa,OAAW,OAAM,WAAW,OAAO;AAC3D,KAAI,OAAO,aAAa,OAAW,OAAM,WAAW,OAAO;AAC3D,KAAI,OAAO,eAAe,OAAW,OAAM,cAAc,OAAO;AAEhE,QAAO,MAAM,oBAAoB,MAAM;;;;;AAMzC,SAAgB,eACd,QACA,MACA,YACM;CACN,MAAM,WAAW,KAAK,YAAY;CAClC,MAAMA,QAAyB;EAC7B,YAAY,KAAK;EACjB,cAAc,KAAK;EACnB,OAAO,KAAK;EACZ;EACA,OAAO,KAAK,QAAQ;EACpB,GAAG;EACJ;AACD,KAAI,KAAK,aAAa,OAAW,OAAM,WAAW,KAAK;AAEvD,QAAO,MAAM,eAAe,MAAM;;;;;AAMpC,SAAgB,oBACd,QACA,MACA,YACM;CACN,MAAM,WAAW,KAAK,YAAY;CAClC,MAAMA,QAAyB;EAC7B,YAAY,KAAK;EACjB,cAAc,KAAK;EACnB,OAAO,KAAK;EACZ;EACA,GAAG;EACJ;AACD,KAAI,KAAK,aAAa,OAAW,OAAM,WAAW,KAAK;AAEvD,QAAO,MAAM,oBAAoB,MAAM;;;;;AAMzC,SAAgB,mBACd,QACA,OACA,WAAW,OACX,YACM;CACN,MAAM,QAAQ,MAAM,QAAQ,KAAK,SAAS,MAAM,KAAK,SAAS,KAAK,YAAY,IAAI,EAAE;CACrF,MAAMA,QAAyB;EAC7B,YAAY,MAAM;EAClB,OAAO;EACP;EACA,aAAa,MAAM,KAAK,MAAM,EAAE,UAAU,CAAC,KAAK,IAAI;EACpD,GAAG;EACJ;AAED,QAAO,MAAM,kBAAkB,MAAM;;;;;AAUvC,SAAgB,iBACd,QACA,WACA,MACA,OACA,WAAW,OACX,UACA,YACM;CACN,MAAMA,QAAyB;EAC7B,YAAY;EACZ,cAAc;EACd;EACA;EACA,GAAG;EACJ;AACD,KAAI,aAAa,OAAW,OAAM,WAAW;AAE7C,QAAO,MAAM,aAAa,MAAM;;;;;AAUlC,SAAgB,YAAY,QAA4B,QAA4B;CAClF,MAAMA,QAAyB;EAC7B,gBAAgB,OAAO;EACvB,QAAQ,OAAO;EACf,UAAU,OAAO;EACjB,GAAG,OAAO;EACX;AACD,KAAI,OAAO,WAAW,OAAW,OAAM,SAAS,OAAO;AAEvD,QAAO,MAAM,UAAU,MAAM;;;;;AC3J/B,MAAM,iBAAiB;AACvB,MAAM,2BAA2B;AACjC,MAAM,yBAAyB;AAC/B,MAAM,wBAAwB;AAC9B,MAAM,uBAAuB;;AAG7B,MAAM,4BAA4B,OAAU,KAAK;AAEjD,IAAa,eAAb,MAAa,aAAa;CACxB,AAAQ;CACR,AAAQ;CACR,AAAQ,WAAW;CACnB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CAGjB,AAAQ,iBAAsC;CAC9C,AAAQ,kBAAuC;CAC/C,AAAQ,qBAA0C;CAClD,AAAQ,uBAA4C;CACpD,AAAQ,sBAA2C;CAGnD,AAAiB,iCAAqC,IAAI,KAAK;CAG/D,AAAQ,aAA4B;CAGpC,AAAQ,oBAAoB;CAG5B,AAAQ,mBAA8C;CAGtD,OAAwB,oBAAoB;CAC5C,AAAQ,gBAA0B,EAAE;CACpC,AAAQ,iBAAiB;CAGzB,AAAQ,gBAAqC;CAG7C,AAAQ,sBAAsB;CAK9B,AAAQ,kBAAwD;CAChE,AAAQ,oBAAoB;CAC5B,AAAQ,yBAA+D;CAEvE,YAAY,QAAsB;AAChC,OAAK,cAAc,OAAO,eAAe;AACzC,OAAK,WAAW,OAAO,WAAW,yBAAyB,QAAQ,OAAO,GAAG;AAC7E,OAAK,YAAY,OAAO;AACxB,OAAK,SAAS;EAEd,MAAM,cAAc,yBAAyB,OAAO,MAAM;EAC1D,MAAM,aAAa,IAAI,iBAAiB;AAExC,OAAK,OAAO,WAAW,KAAK;GAC1B,QAAQ;IACN,OAAO,OAAO;IACd,aAAa,OAAO,eAAe;IACnC,GAAI,OAAO,WAAW,QAAQ,EAAE,SAAS,OAAO,SAAS;IACzD,GAAI,OAAO,eAAe,QAAQ,EAAE,aAAa,OAAO,aAAa;IACrE,iBAAiB,OAAO,mBAAmB;IAC3C,GAAI,OAAO,kBAAkB,QAAQ,EAAE,gBAAgB,OAAO,gBAAgB;IAC9E,GAAI,OAAO,gBAAgB,QAAQ,EAAE,cAAc,OAAO,cAAc;IACxE,YAAY,UAAU;IACvB;GACD;GACA;GACD,CAAC;AAEF,MAAI,KAAK,UACP,MAAK,KAAK,SAAS,KAAK,UAAU;;;CAKtC,MAAM,OAAsB;EAC1B,MAAM,gBAAgB,OAAO,gBAAgB,cAAc,YAAY,KAAK,GAAG,KAAK,KAAK;AAGzF,OAAK,qBAAqB;AAC1B,OAAK,sBAAsB;AAC3B,OAAK,sBAAsB;AAC3B,OAAK,yBAAyB;AAC9B,sBAAoB;AACpB,OAAK,wBAAwB;EAG7B,MAAM,oBAAoB,OAAO,gBAAgB,cAAc,YAAY,KAAK,GAAG,KAAK,KAAK;EAC7F,MAAM,uBAAuB,KAAK,MAAM,oBAAoB,cAAc;AAG1E,QAAM,KAAK,KAAK,mBAAmB,CAAC,YAAY,GAE9C;AAGF,OAAK,2BAA2B;AAGhC,MAAI,KAAK,OAAO,qBAAqB,OAAO;GAC1C,MAAMC,eAAwC,EAAE;GAChD,MAAM,gBAAgB,KAAK,yBAAyB;AACpD,gBAAa,kBAAkB;AAE/B,OAAI,cACF,MAAK,WAAW,0BAA0B,OAAO;AAGnD,QAAK,MAAM,YAAY,aAAa;;AAItC,MAAI,KAAK,OAAO,uBAAuB,MACrC,MAAK,2BAA2B;AAGlC,OAAK,iBAAiB;EAGtB,MAAM,eAAe,OAAO,gBAAgB,cAAc,YAAY,KAAK,GAAG,KAAK,KAAK;EACxF,MAAM,kBAAkB,KAAK,MAAM,eAAe,cAAc;AAGhE,OAAK,gBAAgB,sBAAsB,gBAAgB;AAE3D,MAAI,KAAK,YACP,SAAQ,IACN,oCAAoC,OAAO,qBAAqB,CAAC,YAAY,OAAO,gBAAgB,CAAC,IACtG;AAIH,MAAI,KAAK,cACP,KAAI;AACF,QAAK,cAAc,sBAAsB,gBAAgB;WAClD,GAAG;AACV,OAAI,KAAK,YACP,SAAQ,KAAK,gCAAgC,EAAE;;AAOrD,OAAK,KAAK,YAAY,CAAC,YAAY,GAAG;EAKtC,MAAM,gBAAgB,KAAK,OAAO,mBAAmB;AACrD,OAAK,yBAAyB,iBAAiB;AAC7C,QAAK,oBAAoB;AACzB,QAAK,yBAAyB;KAC7B,cAAc;;;;;;;;CASnB,MAAM,WAAmB,YAAoC;AAC3D,MAAI,KAAK,YACP,SAAQ,IACN,mBAAmB,UAAU,KAAK,OAAO,KAAK,cAAc,EAAE,CAAC,CAAC,OAAO,cACxE;AAEH,MAAI;GACF,MAAM,SAAS,KAAK,mBAAmB,WAAW;GAClD,MAAM,cAAc,KAAK,KAAK,YAAY;AAC1C,QAAK,KAAK,MAAM,WAAW,QAAQ,KAAK,UAAU;GAClD,MAAM,aAAa,KAAK,KAAK,YAAY;AAGzC,OAAI,cAAc,eAAe,KAAK,YACpC,SAAQ,KACN,mBAAmB,UAAU,oDACV,OAAO,YAAY,CAAC,UAAU,OAAO,WAAW,CAAC,GACrE;AAIH,QAAK,kBAAkB,WAAW,WAAW;AAG7C,QAAK,oBAAoB;WAClB,GAAG;AACV,QAAK,UAAU,EAAE;;;;;;;;;CAUrB,OAAO,YAAoB,YAAoC;AAC7D,MAAI,KAAK,YACP,SAAQ,IACN,oBAAoB,WAAW,KAAK,OAAO,KAAK,cAAc,EAAE,CAAC,CAAC,OAAO,cAC1E;AAEH,MAAI;GACF,MAAM,SAAS,KAAK,mBAAmB,WAAW;GAClD,MAAM,cAAc,KAAK,KAAK,YAAY;AAC1C,QAAK,KAAK,OAAO,YAAY,QAAQ,KAAK,UAAU;GACpD,MAAM,aAAa,KAAK,KAAK,YAAY;AAEzC,OAAI,cAAc,eAAe,KAAK,YACpC,SAAQ,KACN,oBAAoB,WAAW,oDACZ,OAAO,YAAY,CAAC,UAAU,OAAO,WAAW,CAAC,GACrE;AAGH,QAAK,kBAAkB,UAAU,cAAc,WAAW;WACnD,GAAG;AACV,QAAK,UAAU,EAAE;;;;CAKrB,kBAAkB,YAAkC;AAClD,OAAK,KAAK,kBAAkB,WAAW;;;CAIzC,sBAAsB,YAAkC;AACtD,OAAK,KAAK,sBAAsB,WAAW;;;CAI7C,WAAW,SAA6B;AACtC,OAAK,KAAK,WAAW,QAAQ;;;;;;CAO/B,MAAM,SAA6B,YAAoC;AACrE,MAAI,KAAK,YACP,SAAQ,IACN,kBAAkB,UAAU,IAAI,QAAQ,KAAK,YAAY,IAAI,OAAO,KAAK,cAAc,EAAE,CAAC,CAAC,OAAO,cACnG;AAEH,MAAI;AACF,QAAK,KAAK,MAAM,WAAW,IAAI,WAAW;WACnC,GAAG;AACV,QAAK,UAAU,EAAE;;;;CAKrB,aAAa,WAAqC;AAChD,MAAI,KAAK,YACP,SAAQ,IAAI,yBAAyB,YAAY,IAAI,UAAU,KAAK,YAAY,GAAG;AAErF,OAAK,YAAY;AACjB,MAAI,UACF,MAAK,KAAK,SAAS,UAAU;MAE7B,MAAK,KAAK,SAAS,GAAG;;;CAK1B,UAAU,QAAsB;AAC9B,OAAK,aAAa,OAAO;;;CAI3B,eAAmC;AACjC,SAAO,KAAK;;;CAId,YAAgC;AAC9B,SAAO,KAAK;;;CAId,eAAuB;AACrB,SAAO,KAAK,KAAK,cAAc;;;CAIjC,kBAAgC;AAC9B,SAAO,KAAK,KAAK,iBAAiB;;;CAIpC,cAAc,YAAiC;AAC7C,OAAK,KAAK,iBAAiB,WAAW;;;;;;CAOxC,eAA8B;AAC5B,SAAO,KAAK;;;;;CAMd,gBAAwB;AACtB,SAAO,KAAK,KAAK,YAAY;;;;;;;;;;;CAY/B,mBAAmB,MAAgC;AACjD,OAAK,mBAAmB;AAIxB,MAAI;GAEF,MAAMC,MAAqB,EAAE,GADN,KAAK,KAAK,kBAAkB,EACH;AAChD,OAAI,KAAK,WACP,KAAI,aAAa,KAAK;OAEtB,QAAO,IAAI;AAEb,QAAK,KAAK,iBAAiB,IAAI;UACzB;AAKR,MAAI;AACF,OAAI,OAAO,iBAAiB,YAC1B,cAAa,QAAQ,sBAAsB,KAAK,UAAU,KAAK,CAAC;UAE5D;AAIR,MAAI,KAAK,YACP,SAAQ,IAAI,+BAA+B,KAAK,UAAU,KAAK,CAAC,GAAG;;;;;;;CASvE,gBAAgB,UAAqC;AACnD,OAAK,gBAAgB;;;;;;CAOvB,qBAA2B;AACzB,OAAK,sBAAsB;AAC3B,4BAAwB;GACtB,YAAY;GACZ,YAAY,KAAK,KAAK,YAAY;GAClC,WAAW,KAAK,KAAK,cAAc;GACnC,WAAW,KAAK;GAChB,OAAO,KAAK,OAAO;GACnB,aAAa,KAAK,OAAO,eAAe;GACxC,UAAU,KAAK;GACf,cAAc,KAAK;GACpB,EAAE;;;;;CAML,sBAA4B;AAC1B,OAAK,sBAAsB;AAC3B,uBAAkB;;;CAIpB,IAAI,gBAAyB;AAC3B,SAAO,KAAK;;;CAId,gBAAwB;AACtB,SAAO;;;;;;CAOT,kBAAqC;AACnC,SAAO,KAAK;;;CAId,MAAM,QAAuB;AAC3B,MAAI;AACF,SAAM,KAAK,KAAK,YAAY;WACrB,GAAG;AACV,QAAK,UAAU,EAAE;AACjB,QAAK,KAAK,OAAO;;;;CAKrB,WAAiB;AACf,OAAK,kBAAkB;AACvB,MAAI,KAAK,oBACP,MAAK,qBAAqB;AAE5B,OAAK,mBAAmB;AACxB,OAAK,gBAAgB;AACrB,OAAK,KAAK,UAAU;;;;;;CAOtB,MAAM,cAAc,YAAY,KAAqB;AACnD,OAAK,kBAAkB;AACvB,MAAI,KAAK,oBACP,MAAK,qBAAqB;AAE5B,OAAK,mBAAmB;AACxB,OAAK,gBAAgB;AACrB,MAAI;AACF,SAAM,QAAQ,KAAK,CACjB,KAAK,KAAK,YAAY,EACtB,IAAI,SAAe,YAAY,WAAW,SAAS,UAAU,CAAC,CAC/D,CAAC;UACI;AAGR,OAAK,KAAK,UAAU;;CAGtB,AAAQ,mBAAyB;AAC/B,MAAI,KAAK,iBAAiB;AACxB,gBAAa,KAAK,gBAAgB;AAClC,QAAK,kBAAkB;;AAEzB,MAAI,KAAK,wBAAwB;AAC/B,gBAAa,KAAK,uBAAuB;AACzC,QAAK,yBAAyB;;AAEhC,MAAI,OAAO,WAAW,aAAa;AACjC,OAAI,KAAK,gBAAgB;AACvB,WAAO,oBAAoB,UAAU,KAAK,eAAe;AACzD,SAAK,iBAAiB;;AAExB,OAAI,KAAK,iBAAiB;AACxB,WAAO,oBAAoB,WAAW,KAAK,gBAAgB;AAC3D,SAAK,kBAAkB;;AAEzB,OAAI,KAAK,sBAAsB;AAC7B,WAAO,oBAAoB,gBAAgB,KAAK,qBAAqB;AACrE,SAAK,uBAAuB;;;AAGhC,MAAI,OAAO,aAAa,eAAe,KAAK,oBAAoB;AAC9D,YAAS,oBAAoB,oBAAoB,KAAK,mBAAmB;AACzE,QAAK,qBAAqB;;AAE5B,MAAI,KAAK,qBAAqB;AAC5B,QAAK,qBAAqB;AAC1B,QAAK,sBAAsB;;;;CAK/B,kBAAwB;AACtB,OAAK,KAAK,iBAAiB;;;;;;CAO7B,GAAG,OAAgB,UAA+B;AAChD,MAAI,UAAU,QAAS,MAAK,eAAe,IAAI,SAAS;AACxD,SAAO;;;;;CAMT,IAAI,OAAgB,UAA+B;AACjD,MAAI,UAAU,QAAS,MAAK,eAAe,OAAO,SAAS;AAC3D,SAAO;;CAGT,AAAQ,UAAU,OAAsB;EACtC,MAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;AACrE,OAAK,MAAM,YAAY,KAAK,eAC1B,KAAI;AACF,YAAS,IAAI;UACP;AAEV,MAAI,KAAK,eAAe,KAAK,eAAe,SAAS,EACnD,SAAQ,KAAK,YAAY,IAAI,QAAQ;;CAMzC,AAAQ,sBAA4B;AAClC,MAAI,OAAO,iBAAiB,YAAa;AAEzC,MAAI;GACF,MAAM,WAAW,aAAa,QAAQ,eAAe;AACrD,OAAI,UAAU;AACZ,SAAK,aAAa;AAClB,SAAK,oBAAoB;UACpB;IACL,MAAM,QAAQ,cAAc;AAC5B,iBAAa,QAAQ,gBAAgB,MAAM;AAC3C,SAAK,aAAa;AAClB,SAAK,oBAAoB;AAGzB,QAAI,CAAC,aAAa,QAAQ,uBAAuB,CAC/C,cAAa,QAAQ,wBAAwB,OAAO,KAAK,KAAK,CAAC,CAAC;;UAG9D;AAEN,QAAK,aAAa,cAAc;;;CAMpC,AAAQ,0BAAmC;AAGzC,MADa,KAAK,WAAW,yBAAyB,KACzC,OAAQ,QAAO;AAG5B,MAAI,KAAK,kBAAmB,QAAO;EAGnC,MAAM,iBAAiB,KAAK,WAAW,uBAAuB;AAC9D,MAAI,gBAAgB;GAClB,MAAM,cAAc,OAAO,eAAe;AAC1C,OAAI,OAAO,SAAS,YAAY,EAAE;IAChC,MAAM,UAAU,KAAK,KAAK,GAAG;IAC7B,MAAM,kBAAkB,WAAW;AAEnC,QAAI,CAAC,mBAAmB,KAAK,YAC3B,SAAQ,IACN,2CAA2C,KAAK,MAAM,UAAU,IAAK,CAAC,mBACtD,4BAA4B,IAAK,sDAElD;AAGH,WAAO;;;AAKX,SAAO;;CAKT,AAAQ,yBAA+B;AACrC,MAAI;AACF,OAAI,OAAO,iBAAiB,YAAa;GACzC,MAAM,MAAM,aAAa,QAAQ,qBAAqB;AACtD,OAAI,CAAC,IAAK;GACV,MAAMC,OAA2B,KAAK,MAAM,IAAI;AAChD,QAAK,mBAAmB;AAGxB,OAAI,KAAK,WACP,KAAI;IACF,MAAM,iBAAiB,KAAK,KAAK,kBAAkB;AACnD,SAAK,KAAK,iBAAiB;KAAE,GAAG;KAAgB,YAAY,KAAK;KAAY,CAAC;WACxE;AAKV,OAAI,KAAK,eAAe,KACtB,SAAQ,IAAI,uCAAuC,KAAK,UAAU,KAAK,GAAG;UAEtE;;;;;;CASV,AAAQ,2BAA2B,YAA2D;EAC5F,MAAM,OAAO,KAAK;AAClB,MAAI,CAAC,KAAM,QAAO;EAElB,MAAMC,SAAkC,EAAE,GAAI,cAAc,EAAE,EAAG;AACjE,MAAI,KAAK,MAAO,QAAO,QAAQ,KAAK;AACpC,MAAI,KAAK,OAAQ,QAAO,SAAS,KAAK;AACtC,MAAI,KAAK,OAAQ,QAAO,SAAS,KAAK;AACtC,MAAI,KAAK,QAAS,QAAO,UAAU,KAAK;AACxC,SAAO;;;CAIT,AAAQ,mBAAmB,YAA+C;EACxE,MAAM,YAAY,mBAAmB;EACrC,MAAM,eAAe,0BAA0B;EAC/C,MAAM,YAAY,KAAK,2BAA2B,OAAU,IAAI,EAAE;AAClE,SAAO;GAAE,GAAG;GAAW,GAAG;GAAc,GAAG;GAAW,GAAG;GAAY;;CAKvE,AAAQ,4BAAkC;AACxC,MAAI,OAAO,cAAc,eAAe,OAAO,iBAAiB,YAAa;AAG7E,MAAI;AACF,OAAI,aAAa,QAAQ,sBAAsB,KAAK,OAAQ;UACtD;AACN;;EAIF,IAAI,mBAAmB;AACvB,MAAI;GACF,MAAM,aAAa,KAAK,KAAK,uBAAuB;AACpD,OAAI,WAEF,oBADe,KAAK,MAAM,WAAW,EACV,kCAAkC;UAEzD;AAGR,OAAK,WAAW,uBAAuB,OAAO;AAE9C,MAAI,CAAC,iBAAkB;AAGvB,MAAI,UAAU,WAAW,SACvB,CAAK,UAAU,UACZ,UAAU,CACV,MAAM,SAAS;AACd,OAAI,CAAC,KAAM;GAEX,MAAM,QAAQ,KAAK,MAAM,+DAA+D;AACxF,OAAI,OAAO;AACT,SAAK,MAAM,yBAAyB;KAClC,eAAe;KACf,oBAAoB,MAAM;KAC3B,CAAC;AACF,QAAI,KAAK,YACP,SAAQ,IAAI,yCAAyC,MAAM,KAAM;;IAGrE,CACD,YAAY,GAEX;;CAMR,AAAQ,uCAAuB,IAAI,KAAa;CAEhD,AAAQ,4BAAkC;AACxC,OAAK,sBAAsB,uBAAuB,SAAuB;AAEvE,OAAI,KAAK,qBAAqB,IAAI,KAAK,IAAI,CAAE;AAC7C,QAAK,qBAAqB,IAAI,KAAK,IAAI;AAEvC,oBAAiB,KAAK,qBAAqB,OAAO,KAAK,IAAI,EAAE,IAAK;AAElE,OAAI;IACF,MAAMC,aAAsC;KAC1C,GAAG,KAAK;KACR,KAAK,KAAK;KACV,QAAQ,KAAK;KACb,MAAM,KAAK;KACX,MAAM,KAAK;KACZ;AACD,SAAK,MAAM,oBAAoB,WAAW;AAC1C,QAAI,KAAK,YACP,SAAQ,IAAI,2CAA2C,KAAK,MAAM;YAE7D,GAAG;AACV,SAAK,UAAU,EAAE;;IAEnB;;CAKJ,AAAQ,gBAAgB,sBAA8B,iBAA+B;AACnF,MAAI;AACF,QAAK,KAAK,MACR,sBACA;IACE,aAAa;IACb,yBAAyB;IAC1B,EACD,KAAK,UACN;UACK;;CAOV,AAAQ,qBAA2B;AACjC,MAAI,CAAC,KAAK,kBAAmB;AAC7B,MAAI,KAAK,gBAAiB;AAC1B,OAAK,kBAAkB,iBAAiB;AACtC,QAAK,kBAAkB;AACvB,OAAI,KAAK,KAAK,YAAY,GAAG,EAC3B,MAAK,KAAK,YAAY,CAAC,YAAY,GAAG;KAEvC,IAAK;;CAKV,AAAQ,kBAAkB,WAAmB,YAAoC;EAC/E,MAAM,sBAAM,IAAI,MAAM;EACtB,MAAM,OAAO,GAAG,OAAO,IAAI,UAAU,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,OAAO,IAAI,YAAY,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,OAAO,IAAI,YAAY,CAAC,CAAC,SAAS,GAAG,IAAI;EACjJ,MAAM,YAAY,OAAO,KAAK,cAAc,EAAE,CAAC,CAAC;EAChD,MAAM,QAAQ,GAAG,KAAK,GAAG,YAAY,YAAY,IAAI,KAAK,OAAO,UAAU,CAAC,WAAW;AACvF,OAAK,cAAc,QAAQ,MAAM;AACjC,MAAI,KAAK,cAAc,SAAS,aAAa,kBAC3C,MAAK,cAAc,KAAK;;CAM5B,AAAQ,uBAA6B;EACnC,MAAMC,UAAyB;GAC7B,UAAU;GACV,WAAW,KAAK,UAAU;GAC1B,YAAY;GACZ,aAAa,KAAK,mBAAmB;GACrC,QAAQ,KAAK,cAAc;GAC3B,YAAY,KAAK,kBAAkB;GACnC,UAAU,KAAK,gBAAgB,CAAC,iBAAiB,CAAC;GAClD,GAAI,KAAK,cAAc,QAAQ,EAAE,WAAW,KAAK,YAAY;GAC9D;AACD,OAAK,KAAK,iBAAiB,QAAQ;;CAGrC,AAAQ,WAAmB;AACzB,MAAI,OAAO,cAAc,YAAa,QAAO;EAC7C,MAAM,KAAK,UAAU;AACrB,MAAI,GAAG,SAAS,UAAU,CAAE,QAAO;AACnC,MAAI,GAAG,SAAS,SAAS,CAAE,QAAO;AAClC,MAAI,GAAG,SAAS,QAAQ,CAAE,QAAO;AACjC,MAAI,GAAG,SAAS,UAAU,CAAE,QAAO;AACnC,MAAI,GAAG,SAAS,SAAS,IAAI,GAAG,SAAS,OAAO,CAAE,QAAO;AACzD,SAAO;;CAGT,AAAQ,oBAA4B;AAClC,MAAI,OAAO,cAAc,YAAa,QAAO;AAC7C,MAAI,mBAAmB,WAAW;GAChC,MAAM,SAAU,UAAwD;AACxE,OAAI,QAAQ,SAAU,QAAO,OAAO;;AAEtC,SAAO,UAAU,YAAY;;CAG/B,AAAQ,eAAuB;AAC7B,MAAI,OAAO,cAAc,YAAa,QAAO;AAC7C,SAAO,UAAU,YAAY;;CAG/B,AAAQ,mBAA2B;AACjC,MAAI,OAAO,WAAW,eAAe,OAAO,WAAW,YAAa,QAAO;AAC3E,SAAO,GAAG,OAAO,MAAM,GAAG,OAAO;;CAKnC,AAAQ,uBAA6B;AACnC,MAAI,OAAO,WAAW,YAAa;AAEnC,OAAK,WAAW,WAAW,UAAU;AAErC,OAAK,uBAAuB;AAC1B,QAAK,WAAW;AAChB,GAAK,KAAK,KAAK,YAAY,CAAC,YAAY,GAAG;;AAE7C,OAAK,wBAAwB;AAC3B,QAAK,WAAW;;AAGlB,SAAO,iBAAiB,UAAU,KAAK,eAAe;AACtD,SAAO,iBAAiB,WAAW,KAAK,gBAAgB;;CAK1D,AAAQ,eAAuB;AAC7B,SAAO,GAAG,KAAK,QAAQ;;CAGzB,AAAQ,0BAAgC;AACtC,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YAAa;AAItE,OAAK,2BAA2B;AAC9B,OAAI,SAAS,oBAAoB,UAAU;AAEzC,QAAI;AACF,UAAK,KAAK,MAAM,kBAAkB,EAAE,EAAE,KAAK,UAAU;AACrD,UAAK,kBAAkB,iBAAiB;YAClC;AAIR,QACE,OAAO,cAAc,eACrB,UAAU,cACV,KAAK,KAAK,YAAY,GAAG,EAEzB,KAAI;KACF,MAAM,QAAQ,KAAK,KAAK,qBAAqB;AAC7C,SAAI,OAAO;AAET,UADa,UAAU,WAAW,KAAK,cAAc,EAAE,MAAM,EACnD;AACR,YAAK,KAAK,mBAAmB;AAC7B;;AAGF,WAAK,KAAK,qBAAqB;AAC/B,WAAK,KAAK,OAAO;AACjB;;YAEI;AAEN,UAAK,KAAK,qBAAqB;;AAGnC,SAAK,KAAK,OAAO;cACR,SAAS,oBAAoB,WAAW;AAEjD,QAAI;AACF,UAAK,KAAK,MAAM,kBAAkB,EAAE,EAAE,KAAK,UAAU;AACrD,UAAK,kBAAkB,iBAAiB;YAClC;AAKR,QAAI,KAAK,SACP,CAAK,KAAK,KAAK,YAAY,CAAC,YAAY,GAAG;;;AAIjD,WAAS,iBAAiB,oBAAoB,KAAK,mBAAmB;AAGtE,OAAK,6BAA6B;AAEhC,OAAI,OAAO,cAAc,eAAe,UAAU,WAChD,KAAI;IACF,MAAM,UAAU,KAAK,KAAK,qBAAqB;AAC/C,QAAI,SAAS;KACX,MAAM,MAAM,KAAK,cAAc;AAC/B,SAAI,UAAU,WAAW,KAAK,QAAQ,EAAE;AACtC,WAAK,KAAK,mBAAmB;AAC7B;;AAGF,UAAK,KAAK,qBAAqB;;WAE3B;AAEN,SAAK,KAAK,qBAAqB;;AAInC,QAAK,KAAK,OAAO;;AAEnB,SAAO,iBAAiB,gBAAgB,KAAK,qBAAqB;;CAKpE,AAAQ,WAAW,KAA4B;AAC7C,MAAI,OAAO,iBAAiB,YAAa,QAAO;AAChD,MAAI;AACF,UAAO,aAAa,QAAQ,IAAI;UAC1B;AACN,UAAO;;;CAIX,AAAQ,WAAW,KAAa,OAAqB;AACnD,MAAI,OAAO,iBAAiB,YAAa;AACzC,MAAI;AACF,gBAAa,QAAQ,KAAK,MAAM;UAC1B;;;AAQZ,SAAS,eAAuB;AAC9B,KAAI,OAAO,WAAW,eAAe,OAAO,WAC1C,QAAO,OAAO,YAAY;AAE5B,QAAO,uCAAuC,QAAQ,UAAU,MAAM;EACpE,MAAM,IAAI,KAAK,MAAM,KAAK,QAAQ,GAAG,GAAG;AAExC,UADU,MAAM,MAAM,IAAK,IAAI,IAAK,GAC3B,SAAS,GAAG;GACrB;;AAKJ,MAAMC,cACJ,OAAO,8BAA8B,cAAc,4BAA4B"}
|
package/package.json
CHANGED
package/dist/src-DnOWq7k2.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"src-DnOWq7k2.js","names":["params: URLSearchParams","clickIdParam: string | undefined","clickIdValue: string | undefined","utms: Partial<Pick<AttributionData, (typeof UTM_PARAMS)[number]>>","data: AttributionData","props: Record<string, string>","props: Record<string, string>","overlayElement: HTMLDivElement | null","updateInterval: ReturnType<typeof setInterval> | null","lines: string[]","params: Record<string, string>","lastUrl: string","properties: EventProperties","props: EventProperties","appOpenProps: Record<string, unknown>","ctx: DeviceContext","data: WebAttributionData","merged: Record<string, unknown>","properties: Record<string, unknown>","context: DeviceContext","SDK_VERSION: string"],"sources":["../src/attribution.ts","../src/capi.ts","../src/debug-overlay.ts","../src/deep-links.ts","../src/standard-events.ts","../src/commerce.ts","../src/index.ts"],"sourcesContent":["const CLICK_ID_PARAMS = [\n 'fbclid',\n 'gclid',\n 'gbraid',\n 'wbraid',\n 'ttclid',\n 'msclkid',\n 'rclid'\n] as const;\nconst UTM_PARAMS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'] as const;\nconst STORAGE_KEY = 'layers_attribution';\nconst TTL_MS = 30 * 24 * 60 * 60 * 1000; // 30 days\n\nexport interface AttributionData {\n click_id_param?: string;\n click_id_value?: string;\n utm_source?: string;\n utm_medium?: string;\n utm_campaign?: string;\n utm_content?: string;\n utm_term?: string;\n referrer_url?: string;\n captured_at: number;\n}\n\n/**\n * Capture attribution signals from the current page URL and referrer.\n * Persists to localStorage with a 30-day TTL. Click IDs take priority:\n * if a new click ID is present, the entire record is overwritten.\n */\nexport function captureAttribution(): void {\n if (typeof window === 'undefined' || typeof localStorage === 'undefined') return;\n\n let params: URLSearchParams;\n try {\n params = new URLSearchParams(window.location.search);\n } catch {\n return;\n }\n\n // Check for click IDs first — any click ID overwrites the stored record\n let clickIdParam: string | undefined;\n let clickIdValue: string | undefined;\n for (const param of CLICK_ID_PARAMS) {\n const value = params.get(param);\n if (value) {\n clickIdParam = param;\n clickIdValue = value;\n break; // first match wins\n }\n }\n\n // Collect UTM params\n const utms: Partial<Pick<AttributionData, (typeof UTM_PARAMS)[number]>> = {};\n let hasUtm = false;\n for (const param of UTM_PARAMS) {\n const value = params.get(param);\n if (value) {\n utms[param] = value;\n hasUtm = true;\n }\n }\n\n const referrer =\n typeof document !== 'undefined' && document.referrer ? document.referrer : undefined;\n\n // Nothing to capture\n if (!clickIdParam && !hasUtm && !referrer) return;\n\n const existing = getAttribution();\n\n // If a new click ID is present, overwrite entirely\n if (clickIdParam) {\n const data: AttributionData = {\n click_id_param: clickIdParam,\n ...(clickIdValue != null && { click_id_value: clickIdValue }),\n ...utms,\n ...(referrer != null && { referrer_url: referrer }),\n captured_at: Date.now()\n };\n writeAttribution(data);\n return;\n }\n\n // If UTMs are present, overwrite (fresh campaign visit)\n if (hasUtm) {\n const data: AttributionData = {\n // Preserve existing click ID if no new one\n ...(existing?.click_id_param != null && { click_id_param: existing.click_id_param }),\n ...(existing?.click_id_value != null && { click_id_value: existing.click_id_value }),\n ...utms,\n ...(referrer != null && { referrer_url: referrer }),\n captured_at: Date.now()\n };\n writeAttribution(data);\n return;\n }\n\n // Only referrer and no existing attribution — store it\n if (!existing) {\n const data: AttributionData = {\n ...(referrer != null && { referrer_url: referrer }),\n captured_at: Date.now()\n };\n writeAttribution(data);\n }\n}\n\n/**\n * Read stored attribution data, returning null if missing or expired.\n */\nexport function getAttribution(): AttributionData | null {\n if (typeof localStorage === 'undefined') return null;\n\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (!raw) return null;\n\n const data: AttributionData = JSON.parse(raw);\n if (Date.now() - data.captured_at > TTL_MS) {\n localStorage.removeItem(STORAGE_KEY);\n return null;\n }\n return data;\n } catch {\n return null;\n }\n}\n\n/**\n * Return a flat property bag suitable for merging into event properties.\n * Keys are prefixed with `$attribution_` to avoid collisions.\n */\nexport function getAttributionProperties(): Record<string, string> {\n const data = getAttribution();\n if (!data) return {};\n\n const props: Record<string, string> = {};\n\n if (data.click_id_param) props['$attribution_click_id_param'] = data.click_id_param;\n if (data.click_id_value) props['$attribution_click_id_value'] = data.click_id_value;\n if (data.utm_source) props['$attribution_utm_source'] = data.utm_source;\n if (data.utm_medium) props['$attribution_utm_medium'] = data.utm_medium;\n if (data.utm_campaign) props['$attribution_utm_campaign'] = data.utm_campaign;\n if (data.utm_content) props['$attribution_utm_content'] = data.utm_content;\n if (data.utm_term) props['$attribution_utm_term'] = data.utm_term;\n if (data.referrer_url) props['$attribution_referrer_url'] = data.referrer_url;\n\n return props;\n}\n\nfunction writeAttribution(data: AttributionData): void {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(data));\n } catch {\n // localStorage full or unavailable — silently ignore\n }\n}\n","// CAPI (Conversions API) readiness utilities.\n// Captures Meta _fbp, TikTok _ttp cookies, page URL, and formats fbc from fbclid.\n\n/**\n * Read a named cookie from document.cookie.\n * Returns the cookie value or undefined if not found / unavailable.\n */\nfunction getCookie(name: string): string | undefined {\n if (typeof document === 'undefined' || !document.cookie) return undefined;\n\n // Cookies are separated by \"; \" — match the exact name to avoid\n // partial matches (e.g. \"x_fbp\" matching \"_fbp\").\n const prefix = `${name}=`;\n const cookies = document.cookie.split('; ');\n for (const cookie of cookies) {\n if (cookie.startsWith(prefix)) {\n return decodeURIComponent(cookie.slice(prefix.length));\n }\n }\n return undefined;\n}\n\n/**\n * Read Meta's _fbp cookie.\n * Format set by Meta Pixel: fb.1.{timestamp}.{random}\n */\nexport function getFbpCookie(): string | undefined {\n return getCookie('_fbp');\n}\n\n/**\n * Read TikTok's _ttp cookie.\n */\nexport function getTtpCookie(): string | undefined {\n return getCookie('_ttp');\n}\n\n/**\n * Capture the current page URL.\n * Required by Meta CAPI for every web event (event_source_url).\n */\nexport function getPageUrl(): string | undefined {\n if (typeof window === 'undefined') return undefined;\n try {\n return window.location.href;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Format an fbclid value into Meta's fbc cookie format.\n * Format: fb.1.{timestamp_ms}.{fbclid}\n *\n * @param fbclid - The raw fbclid parameter value from the URL\n * @param timestampMs - Optional timestamp in milliseconds (defaults to Date.now())\n */\nexport function formatFbc(fbclid: string, timestampMs?: number): string {\n const ts = timestampMs ?? Date.now();\n return `fb.1.${ts}.${fbclid}`;\n}\n\n/**\n * Get the fbc value. Checks in order:\n * 1. If an fbclid URL parameter is present, format it as fbc\n * 2. If an _fbc cookie exists, return it\n * 3. Return undefined\n */\nexport function getFbc(): string | undefined {\n // Check for fbclid in URL params\n if (typeof window !== 'undefined') {\n try {\n const params = new URLSearchParams(window.location.search);\n const fbclid = params.get('fbclid');\n if (fbclid) {\n return formatFbc(fbclid);\n }\n } catch {\n // URL parsing failed\n }\n }\n\n // Fall back to existing _fbc cookie\n return getCookie('_fbc');\n}\n\n/**\n * Build the full set of CAPI properties for an event.\n * All values are optional — only present keys are included.\n */\nexport function getCapiProperties(): Record<string, string> {\n const props: Record<string, string> = {};\n\n const fbp = getFbpCookie();\n if (fbp) props['$fbp'] = fbp;\n\n const ttp = getTtpCookie();\n if (ttp) props['$ttp'] = ttp;\n\n const pageUrl = getPageUrl();\n if (pageUrl) props['$page_url'] = pageUrl;\n\n const fbc = getFbc();\n if (fbc) props['$fbc'] = fbc;\n\n return props;\n}\n","// Lightweight DOM-based debug overlay for the Web SDK.\n// Shows: SDK version, queue depth, session ID, install ID, recent events.\n// Toggled via enableDebugOverlay() / disableDebugOverlay().\n\nexport interface DebugOverlayState {\n sdkVersion: string;\n queueDepth: number;\n sessionId: string;\n installId: string | null;\n appId: string;\n environment: string;\n isOnline: boolean;\n recentEvents: readonly string[];\n}\n\nexport type DebugOverlayStateProvider = () => DebugOverlayState;\n\nconst OVERLAY_ID = 'layers-debug-overlay';\nconst OVERLAY_STYLES = `\n position: fixed;\n bottom: 8px;\n right: 8px;\n width: 360px;\n max-height: 400px;\n background: rgba(0, 0, 0, 0.88);\n color: #e0e0e0;\n font-family: monospace;\n font-size: 11px;\n line-height: 1.5;\n padding: 12px;\n border-radius: 8px;\n z-index: 999999;\n overflow-y: auto;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);\n pointer-events: auto;\n`;\n\nlet overlayElement: HTMLDivElement | null = null;\nlet updateInterval: ReturnType<typeof setInterval> | null = null;\n\n/**\n * Create and display the debug overlay in the DOM.\n * Updates every second with the latest state from the provider.\n */\nexport function enableDebugOverlay(stateProvider: DebugOverlayStateProvider): void {\n if (typeof document === 'undefined') return;\n\n // Don't create a duplicate\n if (overlayElement) {\n disableDebugOverlay();\n }\n\n overlayElement = document.createElement('div');\n overlayElement.id = OVERLAY_ID;\n overlayElement.setAttribute('style', OVERLAY_STYLES);\n document.body.appendChild(overlayElement);\n\n const update = (): void => {\n if (!overlayElement) return;\n const state = stateProvider();\n overlayElement.innerHTML = renderOverlay(state);\n };\n\n update();\n updateInterval = setInterval(update, 1000);\n}\n\n/**\n * Remove the debug overlay from the DOM and stop updates.\n */\nexport function disableDebugOverlay(): void {\n if (updateInterval) {\n clearInterval(updateInterval);\n updateInterval = null;\n }\n if (overlayElement && overlayElement.parentNode) {\n overlayElement.parentNode.removeChild(overlayElement);\n }\n overlayElement = null;\n}\n\n/**\n * Returns whether the debug overlay is currently active.\n */\nexport function isDebugOverlayActive(): boolean {\n return overlayElement !== null;\n}\n\nfunction renderOverlay(state: DebugOverlayState): string {\n const statusDot = state.isOnline ? '🟢' : '🔴';\n const lines: string[] = [\n `<div style=\"font-size:13px;font-weight:bold;margin-bottom:8px;\">Layers Debug ${statusDot}</div>`,\n `<div><b>SDK:</b> ${escapeHtml(state.sdkVersion)}</div>`,\n `<div><b>App:</b> ${escapeHtml(state.appId)} (${escapeHtml(state.environment)})</div>`,\n `<div><b>Session:</b> ${escapeHtml(truncate(state.sessionId, 20))}</div>`,\n `<div><b>Install:</b> ${escapeHtml(truncate(state.installId ?? 'N/A', 20))}</div>`,\n `<div><b>Queue:</b> ${String(state.queueDepth)} events</div>`,\n `<div><b>Network:</b> ${state.isOnline ? 'Online' : 'Offline'}</div>`\n ];\n\n if (state.recentEvents.length > 0) {\n lines.push(\n `<div style=\"margin-top:8px;font-weight:bold;border-top:1px solid #444;padding-top:6px;\">Recent Events</div>`\n );\n for (const event of state.recentEvents.slice(0, 10)) {\n lines.push(`<div style=\"color:#aaa;\">${escapeHtml(event)}</div>`);\n }\n } else {\n lines.push(`<div style=\"margin-top:8px;color:#888;\">No events tracked yet</div>`);\n }\n\n return lines.join('');\n}\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n}\n\nfunction truncate(str: string, maxLen: number): string {\n if (str.length <= maxLen) return str;\n return `${str.slice(0, maxLen)}...`;\n}\n","// Deep link handling and parsing for the Web SDK.\n// Parses URL parameters for deep link data (scheme, host, path, query params)\n// and extracts attribution parameters (fbclid, gclid, ttclid, etc.).\n\nexport interface DeepLinkData {\n url: string;\n scheme: string;\n host: string;\n path: string;\n queryParams: Record<string, string>;\n timestamp: number;\n}\n\n/**\n * Parse a URL string into structured DeepLinkData.\n * Returns null if the URL cannot be parsed.\n */\nexport function parseDeepLink(url: string): DeepLinkData | null {\n try {\n const parsed = new URL(url);\n const params: Record<string, string> = {};\n parsed.searchParams.forEach((value, key) => {\n params[key] = value;\n });\n return {\n url,\n scheme: parsed.protocol.replace(':', ''),\n host: parsed.hostname,\n path: parsed.pathname,\n queryParams: params,\n timestamp: Date.now()\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Set up a listener for URL changes in a web browser context.\n * Listens for `popstate` and `hashchange` events and calls the callback\n * with parsed deep link data on each URL change.\n *\n * Returns an unsubscribe function to remove the listeners.\n */\nexport function setupDeepLinkListener(onDeepLink: (data: DeepLinkData) => void): () => void {\n if (typeof window === 'undefined' || !window.location) return () => {};\n\n let lastUrl: string;\n try {\n lastUrl = window.location.href;\n } catch {\n return () => {};\n }\n\n const handleUrlChange = (): void => {\n const currentUrl = window.location.href;\n if (currentUrl === lastUrl) return;\n lastUrl = currentUrl;\n\n const parsed = parseDeepLink(currentUrl);\n if (parsed) onDeepLink(parsed);\n };\n\n window.addEventListener('popstate', handleUrlChange);\n window.addEventListener('hashchange', handleUrlChange);\n\n // Also check the initial URL\n const initialData = parseDeepLink(window.location.href);\n if (initialData && Object.keys(initialData.queryParams).length > 0) {\n onDeepLink(initialData);\n }\n\n return () => {\n window.removeEventListener('popstate', handleUrlChange);\n window.removeEventListener('hashchange', handleUrlChange);\n };\n}\n","// Standard event types for Layers Analytics.\n// These 18 events match the canonical Layers event taxonomy\n// and are consistent across all SDK platforms.\nimport type { EventProperties } from '@layers/core-wasm';\n\n/**\n * Predefined standard event name constants.\n *\n * Usage:\n * ```ts\n * import { StandardEvents } from '@layers/client';\n * client.track(StandardEvents.PURCHASE, { amount: 9.99, currency: 'USD' });\n * ```\n */\nexport const StandardEvents = {\n APP_OPEN: 'app_open',\n LOGIN: 'login',\n SIGN_UP: 'sign_up',\n REGISTER: 'register',\n PURCHASE: 'purchase_success',\n ADD_TO_CART: 'add_to_cart',\n ADD_TO_WISHLIST: 'add_to_wishlist',\n INITIATE_CHECKOUT: 'initiate_checkout',\n BEGIN_CHECKOUT: 'begin_checkout',\n START_TRIAL: 'start_trial',\n SUBSCRIBE: 'subscribe',\n LEVEL_START: 'level_start',\n LEVEL_COMPLETE: 'level_complete',\n TUTORIAL_COMPLETE: 'tutorial_complete',\n SEARCH: 'search',\n VIEW_ITEM: 'view_item',\n VIEW_CONTENT: 'view_content',\n SHARE: 'share',\n DEEP_LINK: 'deep_link_opened',\n SCREEN_VIEW: 'screen_view'\n} as const;\n\n/** Union type of all standard event name strings. */\nexport type StandardEventName = (typeof StandardEvents)[keyof typeof StandardEvents];\n\n// ---------------------------------------------------------------------------\n// Typed helper functions for building standard event payloads.\n// Each returns { event: string; properties: EventProperties } suitable for\n// destructuring into a track() call.\n// ---------------------------------------------------------------------------\n\nexport interface StandardEventPayload {\n event: StandardEventName;\n properties: EventProperties;\n}\n\n/** Build a login event. */\nexport function loginEvent(method?: string): StandardEventPayload {\n const properties: EventProperties = {};\n if (method !== undefined) properties.method = method;\n return { event: StandardEvents.LOGIN, properties };\n}\n\n/** Build a sign-up event. */\nexport function signUpEvent(method?: string): StandardEventPayload {\n const properties: EventProperties = {};\n if (method !== undefined) properties.method = method;\n return { event: StandardEvents.SIGN_UP, properties };\n}\n\n/** Build a register event. */\nexport function registerEvent(method?: string): StandardEventPayload {\n const properties: EventProperties = {};\n if (method !== undefined) properties.method = method;\n return { event: StandardEvents.REGISTER, properties };\n}\n\n/** Build a purchase event. */\nexport function purchaseEvent(\n amount: number,\n currency = 'USD',\n itemId?: string\n): StandardEventPayload {\n const properties: EventProperties = { amount, currency };\n if (itemId !== undefined) properties.item_id = itemId;\n return { event: StandardEvents.PURCHASE, properties };\n}\n\n/** Build an add-to-cart event. */\nexport function addToCartEvent(itemId: string, price: number, quantity = 1): StandardEventPayload {\n return {\n event: StandardEvents.ADD_TO_CART,\n properties: { item_id: itemId, price, quantity }\n };\n}\n\n/** Build an add-to-wishlist event. */\nexport function addToWishlistEvent(\n itemId: string,\n name?: string,\n price?: number\n): StandardEventPayload {\n const properties: EventProperties = { item_id: itemId };\n if (name !== undefined) properties.name = name;\n if (price !== undefined) properties.price = price;\n return { event: StandardEvents.ADD_TO_WISHLIST, properties };\n}\n\n/** Build an initiate-checkout event. */\nexport function initiateCheckoutEvent(\n value: number,\n currency = 'USD',\n itemCount?: number\n): StandardEventPayload {\n const properties: EventProperties = { value, currency };\n if (itemCount !== undefined) properties.item_count = itemCount;\n return { event: StandardEvents.INITIATE_CHECKOUT, properties };\n}\n\n/** Build a start-trial event. */\nexport function startTrialEvent(plan?: string, durationDays?: number): StandardEventPayload {\n const properties: EventProperties = {};\n if (plan !== undefined) properties.plan = plan;\n if (durationDays !== undefined) properties.duration_days = durationDays;\n return { event: StandardEvents.START_TRIAL, properties };\n}\n\n/** Build a subscribe event. */\nexport function subscribeEvent(\n plan: string,\n amount: number,\n currency = 'USD'\n): StandardEventPayload {\n return {\n event: StandardEvents.SUBSCRIBE,\n properties: { plan, amount, currency }\n };\n}\n\n/** Build a level-start event. */\nexport function levelStartEvent(level: string): StandardEventPayload {\n return { event: StandardEvents.LEVEL_START, properties: { level } };\n}\n\n/** Build a level-complete event. */\nexport function levelCompleteEvent(level: string, score?: number): StandardEventPayload {\n const properties: EventProperties = { level };\n if (score !== undefined) properties.score = score;\n return { event: StandardEvents.LEVEL_COMPLETE, properties };\n}\n\n/** Build a tutorial-complete event. */\nexport function tutorialCompleteEvent(name?: string): StandardEventPayload {\n const properties: EventProperties = {};\n if (name !== undefined) properties.name = name;\n return { event: StandardEvents.TUTORIAL_COMPLETE, properties };\n}\n\n/** Build a search event. */\nexport function searchEvent(query: string, resultCount?: number): StandardEventPayload {\n const properties: EventProperties = { query };\n if (resultCount !== undefined) properties.result_count = resultCount;\n return { event: StandardEvents.SEARCH, properties };\n}\n\n/** Build a view-item event. */\nexport function viewItemEvent(\n itemId: string,\n name?: string,\n category?: string\n): StandardEventPayload {\n const properties: EventProperties = { item_id: itemId };\n if (name !== undefined) properties.name = name;\n if (category !== undefined) properties.category = category;\n return { event: StandardEvents.VIEW_ITEM, properties };\n}\n\n/** Build a view-content event. */\nexport function viewContentEvent(\n contentId: string,\n contentType?: string,\n name?: string\n): StandardEventPayload {\n const properties: EventProperties = { content_id: contentId };\n if (contentType !== undefined) properties.content_type = contentType;\n if (name !== undefined) properties.name = name;\n return { event: StandardEvents.VIEW_CONTENT, properties };\n}\n\n/** Build a share event. */\nexport function shareEvent(\n contentType: string,\n method?: string,\n contentId?: string\n): StandardEventPayload {\n const properties: EventProperties = { content_type: contentType };\n if (method !== undefined) properties.method = method;\n if (contentId !== undefined) properties.content_id = contentId;\n return { event: StandardEvents.SHARE, properties };\n}\n\n/** Build a screen-view event. */\nexport function screenViewEvent(name: string, screenClass?: string): StandardEventPayload {\n const properties: EventProperties = { screen_name: name };\n if (screenClass !== undefined) properties.screen_class = screenClass;\n return { event: StandardEvents.SCREEN_VIEW, properties };\n}\n","// Commerce module for @layers/client (Web SDK).\n// Cross-platform purchase, subscription, cart, and refund tracking helpers.\n// Each function accepts a WebCommerceTracker instance and tracks the appropriate\n// event with standardized properties consistent with the iOS CommerceModule,\n// Android CommerceModule, and RN commerce module.\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Event properties bag accepted by commerce functions. */\nexport type EventProperties = Record<string, unknown>;\n\n/** Minimal Layers SDK interface required by the commerce module. */\nexport interface WebCommerceTracker {\n track(event: string, properties?: Record<string, any>): void;\n}\n\n/** Purchase details for trackPurchase. */\nexport interface PurchaseParams {\n productId: string;\n /** Unit price of the item. Revenue is computed as `price * quantity`. */\n price: number;\n currency: string;\n transactionId?: string;\n quantity?: number;\n isRestored?: boolean;\n store?: string;\n properties?: EventProperties;\n}\n\n/** Subscription details for trackSubscription. */\nexport interface SubscriptionParams {\n productId: string;\n /** Unit price of the subscription. */\n price: number;\n currency: string;\n period?: string;\n transactionId?: string;\n isRenewal?: boolean;\n isTrial?: boolean;\n subscriptionGroupId?: string;\n originalTransactionId?: string;\n properties?: EventProperties;\n}\n\n/** Cart item for order and checkout tracking. */\nexport interface CartItem {\n productId: string;\n name: string;\n price: number;\n quantity?: number;\n category?: string;\n}\n\n/** Order details for trackOrder. */\nexport interface OrderParams {\n orderId: string;\n items: CartItem[];\n subtotal: number;\n currency?: string;\n tax?: number;\n shipping?: number;\n discount?: number;\n couponCode?: string;\n properties?: EventProperties;\n}\n\n/** Refund details for trackRefund. */\nexport interface RefundParams {\n transactionId: string;\n amount: number;\n currency: string;\n reason?: string;\n properties?: EventProperties;\n}\n\n/** Purchase failure details for trackPurchaseFailed. */\nexport interface PurchaseFailedParams {\n productId: string;\n currency: string;\n errorCode: string | number;\n errorMessage?: string;\n properties?: EventProperties;\n}\n\n// ---------------------------------------------------------------------------\n// Purchase tracking\n// ---------------------------------------------------------------------------\n\n/**\n * Track a successful purchase.\n *\n * ```ts\n * import { trackPurchase } from '@layers/client';\n *\n * trackPurchase(layers, {\n * productId: 'premium_monthly',\n * price: 9.99,\n * currency: 'USD',\n * transactionId: 'txn_abc123',\n * });\n * ```\n */\nexport function trackPurchase(layers: WebCommerceTracker, params: PurchaseParams): void {\n const quantity = params.quantity ?? 1;\n const props: EventProperties = {\n product_id: params.productId,\n price: params.price,\n currency: params.currency,\n quantity,\n revenue: params.price * quantity,\n ...params.properties\n };\n if (params.transactionId !== undefined) props.transaction_id = params.transactionId;\n if (params.isRestored !== undefined) props.is_restored = params.isRestored;\n if (params.store !== undefined) props.store = params.store;\n\n layers.track('purchase_success', props);\n}\n\n/**\n * Track a failed purchase attempt.\n */\nexport function trackPurchaseFailed(\n layers: WebCommerceTracker,\n params: PurchaseFailedParams\n): void {\n const props: EventProperties = {\n product_id: params.productId,\n currency: params.currency,\n error_code: params.errorCode,\n ...params.properties\n };\n if (params.errorMessage !== undefined) props.error_message = params.errorMessage;\n\n layers.track('purchase_failed', props);\n}\n\n// ---------------------------------------------------------------------------\n// Subscription tracking\n// ---------------------------------------------------------------------------\n\n/**\n * Track a subscription purchase or renewal.\n *\n * ```ts\n * import { trackSubscription } from '@layers/client';\n *\n * trackSubscription(layers, {\n * productId: 'pro_annual',\n * price: 49.99,\n * currency: 'USD',\n * period: 'P1Y',\n * });\n * ```\n */\nexport function trackSubscription(layers: WebCommerceTracker, params: SubscriptionParams): void {\n const props: EventProperties = {\n product_id: params.productId,\n price: params.price,\n currency: params.currency,\n quantity: 1,\n revenue: params.price,\n ...params.properties\n };\n if (params.transactionId !== undefined) props.transaction_id = params.transactionId;\n if (params.period !== undefined) props.period = params.period;\n if (params.isRenewal !== undefined) props.is_renewal = params.isRenewal;\n if (params.isTrial !== undefined) props.is_trial = params.isTrial;\n if (params.subscriptionGroupId !== undefined)\n props.subscription_group_id = params.subscriptionGroupId;\n if (params.originalTransactionId !== undefined)\n props.original_transaction_id = params.originalTransactionId;\n\n layers.track('subscribe', props);\n}\n\n// ---------------------------------------------------------------------------\n// Order / cart tracking\n// ---------------------------------------------------------------------------\n\n/**\n * Track a completed order with multiple line items.\n */\nexport function trackOrder(layers: WebCommerceTracker, params: OrderParams): void {\n const currency = params.currency ?? 'USD';\n let total = params.subtotal;\n if (params.tax !== undefined) total += params.tax;\n if (params.shipping !== undefined) total += params.shipping;\n if (params.discount !== undefined) total -= params.discount;\n\n const props: EventProperties = {\n order_id: params.orderId,\n subtotal: params.subtotal,\n total,\n currency,\n item_count: params.items.length,\n revenue: total,\n product_ids: params.items.map((i) => i.productId).join(','),\n ...params.properties\n };\n if (params.tax !== undefined) props.tax = params.tax;\n if (params.shipping !== undefined) props.shipping = params.shipping;\n if (params.discount !== undefined) props.discount = params.discount;\n if (params.couponCode !== undefined) props.coupon_code = params.couponCode;\n\n layers.track('purchase_success', props);\n}\n\n/**\n * Track an item being added to the cart.\n */\nexport function trackAddToCart(\n layers: WebCommerceTracker,\n item: CartItem,\n properties?: EventProperties\n): void {\n const quantity = item.quantity ?? 1;\n const props: EventProperties = {\n product_id: item.productId,\n product_name: item.name,\n price: item.price,\n quantity,\n value: item.price * quantity,\n ...properties\n };\n if (item.category !== undefined) props.category = item.category;\n\n layers.track('add_to_cart', props);\n}\n\n/**\n * Track an item being removed from the cart.\n */\nexport function trackRemoveFromCart(\n layers: WebCommerceTracker,\n item: CartItem,\n properties?: EventProperties\n): void {\n const quantity = item.quantity ?? 1;\n const props: EventProperties = {\n product_id: item.productId,\n product_name: item.name,\n price: item.price,\n quantity,\n ...properties\n };\n if (item.category !== undefined) props.category = item.category;\n\n layers.track('remove_from_cart', props);\n}\n\n/**\n * Track beginning the checkout flow.\n */\nexport function trackBeginCheckout(\n layers: WebCommerceTracker,\n items: CartItem[],\n currency = 'USD',\n properties?: EventProperties\n): void {\n const total = items.reduce((sum, item) => sum + item.price * (item.quantity ?? 1), 0);\n const props: EventProperties = {\n item_count: items.length,\n value: total,\n currency,\n product_ids: items.map((i) => i.productId).join(','),\n ...properties\n };\n\n layers.track('begin_checkout', props);\n}\n\n// ---------------------------------------------------------------------------\n// Product view tracking\n// ---------------------------------------------------------------------------\n\n/**\n * Track viewing a product detail page.\n */\nexport function trackViewProduct(\n layers: WebCommerceTracker,\n productId: string,\n name: string,\n price: number,\n currency = 'USD',\n category?: string,\n properties?: EventProperties\n): void {\n const props: EventProperties = {\n product_id: productId,\n product_name: name,\n price,\n currency,\n ...properties\n };\n if (category !== undefined) props.category = category;\n\n layers.track('view_item', props);\n}\n\n// ---------------------------------------------------------------------------\n// Refund tracking\n// ---------------------------------------------------------------------------\n\n/**\n * Track a refund.\n */\nexport function trackRefund(layers: WebCommerceTracker, params: RefundParams): void {\n const props: EventProperties = {\n transaction_id: params.transactionId,\n amount: params.amount,\n currency: params.currency,\n ...params.properties\n };\n if (params.reason !== undefined) props.reason = params.reason;\n\n layers.track('refund', props);\n}\n","// @layers/client — Web browser SDK.\n// Thin wrapper over @layers/core-wasm. Owns only:\n// - localStorage persistence\n// - window online/offline detection\n// - navigator device info\n// - visibilitychange / beforeunload flush\n// - Install ID persistence (localStorage)\n// - Deep link handling/parsing (popstate, hashchange)\n// - setAttributionData API\n// - Clipboard attribution check\n// - Install event gating (24h window)\n// - Debug overlay (DOM-based)\n// - Init timing measurement\n// - Full lifecycle events (app_open, app_background, app_foreground)\n// - Queue depth gating\nimport {\n FetchHttpClient,\n LayersCore,\n LayersError,\n createDefaultPersistence\n} from '@layers/core-wasm';\nimport type {\n ConsentState,\n DeviceContext,\n Environment,\n EventProperties,\n UserProperties\n} from '@layers/core-wasm';\n\nimport { captureAttribution, getAttributionProperties } from './attribution.js';\nimport { getCapiProperties } from './capi.js';\nimport {\n disableDebugOverlay as hideDebugOverlay,\n enableDebugOverlay as showDebugOverlay\n} from './debug-overlay.js';\nimport { parseDeepLink, setupDeepLinkListener } from './deep-links.js';\nimport type { DeepLinkData } from './deep-links.js';\n\nexport type {\n ConsentState,\n DeviceContext,\n Environment,\n EventProperties,\n UserProperties\n} from '@layers/core-wasm';\n\nexport { LayersError } from '@layers/core-wasm';\n\nexport * from './api-types.js';\nexport type { AttributionData } from './attribution.js';\nexport { getAttribution, getAttributionProperties } from './attribution.js';\nexport {\n getCapiProperties,\n getFbpCookie,\n getTtpCookie,\n getPageUrl,\n getFbc,\n formatFbc\n} from './capi.js';\n\nexport { StandardEvents } from './standard-events.js';\nexport type { StandardEventName, StandardEventPayload } from './standard-events.js';\nexport {\n loginEvent,\n signUpEvent,\n registerEvent,\n purchaseEvent,\n addToCartEvent,\n addToWishlistEvent,\n initiateCheckoutEvent,\n startTrialEvent,\n subscribeEvent,\n levelStartEvent,\n levelCompleteEvent,\n tutorialCompleteEvent,\n searchEvent,\n viewItemEvent,\n viewContentEvent,\n shareEvent,\n screenViewEvent\n} from './standard-events.js';\n\nexport type { DeepLinkData } from './deep-links.js';\nexport { parseDeepLink, setupDeepLinkListener } from './deep-links.js';\nexport type { DebugOverlayState } from './debug-overlay.js';\n\nexport type {\n WebCommerceTracker,\n PurchaseParams,\n SubscriptionParams,\n CartItem,\n OrderParams,\n RefundParams,\n PurchaseFailedParams\n} from './commerce.js';\nexport {\n trackPurchase,\n trackPurchaseFailed,\n trackSubscription,\n trackOrder,\n trackAddToCart,\n trackRemoveFromCart,\n trackBeginCheckout,\n trackViewProduct,\n trackRefund\n} from './commerce.js';\n\nexport interface LayersConfig {\n /** Unique application identifier issued by the Layers dashboard. */\n appId: string;\n /** Deployment environment label. @default \"production\" */\n environment?: Environment;\n /** Optional user identifier to associate events with from the start. */\n appUserId?: string;\n /** Enable verbose debug logging to the console. @default false */\n enableDebug?: boolean;\n /** Base URL for the Layers ingest API. @default \"https://in.layers.com\" */\n baseUrl?: string;\n /** How often the event queue is flushed, in milliseconds. @default 30000 */\n flushIntervalMs?: number;\n /** Number of queued events that triggers an automatic flush. @default 10 */\n flushThreshold?: number;\n /** Maximum number of events to hold in the queue before dropping. @default 1000 */\n maxQueueSize?: number;\n /**\n * Whether to automatically fire an `app_open` event during init().\n * Set to `false` if you want to fire the event manually.\n * @default true\n */\n autoTrackAppOpen?: boolean;\n /**\n * Whether to automatically track `deep_link_opened` events when the URL\n * changes (popstate/hashchange). The tracked event includes the parsed\n * URL components and all query parameters.\n * @default true\n */\n autoTrackDeepLinks?: boolean;\n}\n\n/**\n * Attribution data that will be attached to all subsequent events.\n * Matches the RN SDK's setAttributionData pattern.\n */\nexport interface WebAttributionData {\n deeplinkId?: string | null;\n gclid?: string | null;\n fbclid?: string | null;\n ttclid?: string | null;\n msclkid?: string | null;\n}\n\nexport type ErrorListener = (error: Error) => void;\n\n/**\n * Listener for SDK initialization timing metrics.\n *\n * @param mainThreadDurationMs Time spent in the synchronous portion of init.\n * @param totalDurationMs Total wall-clock time of the `init()` call,\n * including all async work (remote config fetch, etc.).\n */\nexport type InitListener = (mainThreadDurationMs: number, totalDurationMs: number) => void;\n\n// --- localStorage keys ---\nconst INSTALL_ID_KEY = 'layers_install_id';\nconst FIRST_LAUNCH_TRACKED_KEY = 'layers_first_launch_tracked';\nconst FIRST_INSTALL_TIME_KEY = 'layers_first_install_time';\nconst CLIPBOARD_CHECKED_KEY = 'layers_clipboard_checked';\nconst ATTRIBUTION_DATA_KEY = 'layers_attribution_data';\n\n/** Maximum age of an installation for install event gating (24 hours). */\nconst INSTALL_EVENT_MAX_DIFF_MS = 24 * 60 * 60 * 1000;\n\nexport class LayersClient {\n private core: LayersCore;\n private appUserId: string | undefined;\n private isOnline = true;\n private readonly enableDebug: boolean;\n private readonly baseUrl: string;\n private readonly config: LayersConfig;\n\n // Stored listener references for cleanup on shutdown\n private onlineListener: (() => void) | null = null;\n private offlineListener: (() => void) | null = null;\n private visibilityListener: (() => void) | null = null;\n private beforeUnloadListener: (() => void) | null = null;\n private deepLinkUnsubscribe: (() => void) | null = null;\n\n // Error listeners\n private readonly errorListeners: Set<ErrorListener> = new Set();\n\n // Install ID\n private _installId: string | null = null;\n\n // Whether the SDK had prior state (install_id existed) at initialization time.\n private _hadPriorSdkState = false;\n\n // Attribution data stored for attachment to subsequent events.\n private _attributionData: WebAttributionData | null = null;\n\n // Recent events buffer for debug overlay (circular, last N events)\n private static readonly MAX_RECENT_EVENTS = 20;\n private _recentEvents: string[] = [];\n private _isInitialized = false;\n\n // Init timing listener\n private _initListener: InitListener | null = null;\n\n // Debug overlay state\n private _debugOverlayActive = false;\n\n constructor(config: LayersConfig) {\n this.enableDebug = config.enableDebug ?? false;\n this.baseUrl = (config.baseUrl ?? 'https://in.layers.com').replace(/\\/$/, '');\n this.appUserId = config.appUserId;\n this.config = config;\n\n const persistence = createDefaultPersistence(config.appId);\n const httpClient = new FetchHttpClient();\n\n this.core = LayersCore.init({\n config: {\n appId: config.appId,\n environment: config.environment ?? 'production',\n ...(config.baseUrl != null && { baseUrl: config.baseUrl }),\n ...(config.enableDebug != null && { enableDebug: config.enableDebug }),\n ...(config.flushIntervalMs != null && { flushIntervalMs: config.flushIntervalMs }),\n ...(config.flushThreshold != null && { flushThreshold: config.flushThreshold }),\n ...(config.maxQueueSize != null && { maxQueueSize: config.maxQueueSize }),\n sdkVersion: `client/${SDK_VERSION}`\n },\n httpClient,\n persistence\n });\n\n if (this.appUserId) {\n this.core.identify(this.appUserId);\n }\n }\n\n /** Initialize the client: detects device info, attaches lifecycle listeners, and fetches remote config. */\n async init(): Promise<void> {\n const initStartTime = typeof performance !== 'undefined' ? performance.now() : Date.now();\n\n // Synchronous init work\n this.initializeInstallId();\n this.initializeDeviceInfo();\n this.setupNetworkListener();\n this.setupLifecycleListeners();\n captureAttribution();\n this.restoreAttributionData();\n\n // Main thread init complete — record timing\n const mainThreadEndTime = typeof performance !== 'undefined' ? performance.now() : Date.now();\n const mainThreadDurationMs = Math.round(mainThreadEndTime - initStartTime);\n\n // Async init work\n await this.core.fetchRemoteConfig().catch(() => {\n // Remote config fetch is best-effort\n });\n\n // Clipboard attribution check (only on first init, gated by remote config)\n this.checkClipboardAttribution();\n\n // Install event gating + app_open\n if (this.config.autoTrackAppOpen !== false) {\n const appOpenProps: Record<string, unknown> = {};\n const isFirstLaunch = this.shouldTreatAsNewInstall();\n appOpenProps.is_first_launch = isFirstLaunch;\n\n if (isFirstLaunch) {\n this.storageSet(FIRST_LAUNCH_TRACKED_KEY, 'true');\n }\n\n this.track('app_open', appOpenProps);\n }\n\n // Auto-track deep link events\n if (this.config.autoTrackDeepLinks !== false) {\n this.setupDeepLinkAutoTracking();\n }\n\n this._isInitialized = true;\n\n // Measure total duration\n const totalEndTime = typeof performance !== 'undefined' ? performance.now() : Date.now();\n const totalDurationMs = Math.round(totalEndTime - initStartTime);\n\n // Track init timing event\n this.trackInitTiming(mainThreadDurationMs, totalDurationMs);\n\n if (this.enableDebug) {\n console.log(\n `[Layers] Init timing: mainThread=${String(mainThreadDurationMs)}ms, total=${String(totalDurationMs)}ms`\n );\n }\n\n // Notify init listener\n if (this._initListener) {\n try {\n this._initListener(mainThreadDurationMs, totalDurationMs);\n } catch (e) {\n if (this.enableDebug) {\n console.warn('[Layers] InitListener threw:', e);\n }\n }\n }\n }\n\n /**\n * Record a custom analytics event with an optional property bag.\n *\n * Events are batched and flushed automatically when the queue reaches\n * `flushThreshold` or the periodic flush timer fires.\n */\n track(eventName: string, properties?: EventProperties): void {\n if (this.enableDebug) {\n console.log(\n `[Layers] track(\"${eventName}\", ${Object.keys(properties ?? {}).length} properties)`\n );\n }\n try {\n const merged = this.mergeAllProperties(properties);\n const depthBefore = this.core.queueDepth();\n this.core.track(eventName, merged, this.appUserId);\n const depthAfter = this.core.queueDepth();\n\n // Queue depth gating: verify event was accepted by core\n if (depthAfter <= depthBefore && this.enableDebug) {\n console.warn(\n `[Layers] track(\"${eventName}\") — event may not have been queued ` +\n `(depth before=${String(depthBefore)}, after=${String(depthAfter)})`\n );\n }\n\n // Record for debug overlay\n this.recordRecentEvent(eventName, properties);\n } catch (e) {\n this.emitError(e);\n }\n }\n\n /**\n * Record a screen view event with an optional property bag.\n *\n * Events are batched and flushed automatically when the queue reaches\n * `flushThreshold` or the periodic flush timer fires.\n */\n screen(screenName: string, properties?: EventProperties): void {\n if (this.enableDebug) {\n console.log(\n `[Layers] screen(\"${screenName}\", ${Object.keys(properties ?? {}).length} properties)`\n );\n }\n try {\n const merged = this.mergeAllProperties(properties);\n const depthBefore = this.core.queueDepth();\n this.core.screen(screenName, merged, this.appUserId);\n const depthAfter = this.core.queueDepth();\n\n if (depthAfter <= depthBefore && this.enableDebug) {\n console.warn(\n `[Layers] screen(\"${screenName}\") — event may not have been queued ` +\n `(depth before=${String(depthBefore)}, after=${String(depthAfter)})`\n );\n }\n\n this.recordRecentEvent(`screen:${screenName}`, properties);\n } catch (e) {\n this.emitError(e);\n }\n }\n\n /** Set or update user-level properties that persist across sessions. */\n setUserProperties(properties: UserProperties): void {\n this.core.setUserProperties(properties);\n }\n\n /** Set user-level properties with \"set once\" semantics — only keys not previously set are applied. */\n setUserPropertiesOnce(properties: UserProperties): void {\n this.core.setUserPropertiesOnce(properties);\n }\n\n /** Update the user's consent state for analytics and advertising data collection. */\n setConsent(consent: ConsentState): void {\n this.core.setConsent(consent);\n }\n\n /**\n * Associate all subsequent events with a group (company, team, organization).\n * Pass `undefined` or empty string to clear the group association.\n */\n group(groupId: string | undefined, properties?: EventProperties): void {\n if (this.enableDebug) {\n console.log(\n `[Layers] group(${groupId ? `\"${groupId}\"` : 'undefined'}, ${Object.keys(properties ?? {}).length} properties)`\n );\n }\n try {\n this.core.group(groupId ?? '', properties);\n } catch (e) {\n this.emitError(e);\n }\n }\n\n /** Associate all subsequent events with the given user ID, or clear it with `undefined`. */\n setAppUserId(appUserId: string | undefined): void {\n if (this.enableDebug) {\n console.log(`[Layers] setAppUserId(${appUserId ? `\"${appUserId}\"` : 'undefined'})`);\n }\n this.appUserId = appUserId;\n if (appUserId) {\n this.core.identify(appUserId);\n } else {\n this.core.identify('');\n }\n }\n\n /** @deprecated Use setAppUserId instead */\n setUserId(userId: string): void {\n this.setAppUserId(userId);\n }\n\n /** Return the current app user ID, or `undefined` if not set. */\n getAppUserId(): string | undefined {\n return this.appUserId;\n }\n\n /** @deprecated Use getAppUserId instead */\n getUserId(): string | undefined {\n return this.appUserId;\n }\n\n /** Return the current anonymous session ID. */\n getSessionId(): string {\n return this.core.getSessionId();\n }\n\n /** Return the current consent state for analytics and advertising. */\n getConsentState(): ConsentState {\n return this.core.getConsentState();\n }\n\n /** Override device-level context fields (platform, OS, locale, etc.). */\n setDeviceInfo(deviceInfo: DeviceContext): void {\n this.core.setDeviceContext(deviceInfo);\n }\n\n /**\n * Return the install ID (persistent UUID stored in localStorage).\n * Generated on first init, persists across sessions.\n */\n getInstallId(): string | null {\n return this._installId;\n }\n\n /**\n * Return the number of events currently queued.\n */\n getQueueDepth(): number {\n return this.core.queueDepth();\n }\n\n /**\n * Store attribution data that will be attached to all subsequent events.\n *\n * The values are persisted in localStorage so they survive page reloads.\n * Pass `null` to clear a value.\n *\n * When set, `deeplinkId`, `gclid`, `fbclid`, `ttclid`, and/or `msclkid`\n * are included in every event's properties.\n */\n setAttributionData(data: WebAttributionData): void {\n this._attributionData = data;\n\n // Update the Rust core's DeviceContext with the deeplinkId so the\n // top-level event field is populated.\n try {\n const currentContext = this.core.getDeviceContext();\n const ctx: DeviceContext = { ...currentContext };\n if (data.deeplinkId) {\n ctx.deeplinkId = data.deeplinkId;\n } else {\n delete ctx.deeplinkId;\n }\n this.core.setDeviceContext(ctx);\n } catch {\n // DeviceContext update is best-effort\n }\n\n // Persist to localStorage\n try {\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem(ATTRIBUTION_DATA_KEY, JSON.stringify(data));\n }\n } catch {\n // localStorage write is best-effort\n }\n\n if (this.enableDebug) {\n console.log(`[Layers] setAttributionData(${JSON.stringify(data)})`);\n }\n }\n\n /**\n * Set a listener to receive SDK initialization timing metrics.\n * Must be called **before** `init()` to receive the callback.\n * Pass `null` to clear the listener.\n */\n setInitListener(listener: InitListener | null): void {\n this._initListener = listener;\n }\n\n /**\n * Enable the debug overlay — a lightweight DOM panel showing SDK state.\n * The overlay updates every second with queue depth, session info, and recent events.\n */\n enableDebugOverlay(): void {\n this._debugOverlayActive = true;\n showDebugOverlay(() => ({\n sdkVersion: SDK_VERSION,\n queueDepth: this.core.queueDepth(),\n sessionId: this.core.getSessionId(),\n installId: this._installId,\n appId: this.config.appId,\n environment: this.config.environment ?? 'production',\n isOnline: this.isOnline,\n recentEvents: this._recentEvents\n }));\n }\n\n /**\n * Disable and remove the debug overlay from the DOM.\n */\n disableDebugOverlay(): void {\n this._debugOverlayActive = false;\n hideDebugOverlay();\n }\n\n /** Whether the SDK has completed async initialization. */\n get isInitialized(): boolean {\n return this._isInitialized;\n }\n\n /** SDK version string. */\n getSdkVersion(): string {\n return SDK_VERSION;\n }\n\n /**\n * Returns the most recent tracked events (newest first).\n * Each entry is a formatted string like \"12:34:56 event_name (3 props)\".\n */\n getRecentEvents(): readonly string[] {\n return this._recentEvents;\n }\n\n /** Flush all queued events to the server. Falls back to synchronous persistence on failure. */\n async flush(): Promise<void> {\n try {\n await this.core.flushAsync();\n } catch (e) {\n this.emitError(e);\n this.core.flush();\n }\n }\n\n /** Immediately shut down the client, removing all event listeners. Queued events are persisted but not flushed. */\n shutdown(): void {\n this.cleanupListeners();\n if (this._debugOverlayActive) {\n this.disableDebugOverlay();\n }\n this._attributionData = null;\n this._initListener = null;\n this.core.shutdown();\n }\n\n /**\n * Async shutdown: flushes remaining events before shutting down.\n * @param timeoutMs Maximum time to wait for flush (default 3000ms).\n */\n async shutdownAsync(timeoutMs = 3000): Promise<void> {\n this.cleanupListeners();\n if (this._debugOverlayActive) {\n this.disableDebugOverlay();\n }\n this._attributionData = null;\n this._initListener = null;\n try {\n await Promise.race([\n this.core.flushAsync(),\n new Promise<void>((resolve) => setTimeout(resolve, timeoutMs))\n ]);\n } catch {\n // Best effort — proceed with shutdown\n }\n this.core.shutdown();\n }\n\n private cleanupListeners(): void {\n if (typeof window !== 'undefined') {\n if (this.onlineListener) {\n window.removeEventListener('online', this.onlineListener);\n this.onlineListener = null;\n }\n if (this.offlineListener) {\n window.removeEventListener('offline', this.offlineListener);\n this.offlineListener = null;\n }\n if (this.beforeUnloadListener) {\n window.removeEventListener('beforeunload', this.beforeUnloadListener);\n this.beforeUnloadListener = null;\n }\n }\n if (typeof document !== 'undefined' && this.visibilityListener) {\n document.removeEventListener('visibilitychange', this.visibilityListener);\n this.visibilityListener = null;\n }\n if (this.deepLinkUnsubscribe) {\n this.deepLinkUnsubscribe();\n this.deepLinkUnsubscribe = null;\n }\n }\n\n /** End the current session and start a new one with a fresh session ID. */\n startNewSession(): void {\n this.core.startNewSession();\n }\n\n /**\n * Register an error listener. Errors from track/screen/flush\n * that would otherwise be silently dropped are forwarded here.\n */\n on(event: 'error', listener: ErrorListener): this {\n if (event === 'error') this.errorListeners.add(listener);\n return this;\n }\n\n /**\n * Remove a previously registered error listener.\n */\n off(event: 'error', listener: ErrorListener): this {\n if (event === 'error') this.errorListeners.delete(listener);\n return this;\n }\n\n private emitError(error: unknown): void {\n const err = error instanceof Error ? error : new Error(String(error));\n for (const listener of this.errorListeners) {\n try {\n listener(err);\n } catch {}\n }\n if (this.enableDebug && this.errorListeners.size === 0) {\n console.warn('[Layers]', err.message);\n }\n }\n\n // --- Install ID persistence ---\n\n private initializeInstallId(): void {\n if (typeof localStorage === 'undefined') return;\n\n try {\n const existing = localStorage.getItem(INSTALL_ID_KEY);\n if (existing) {\n this._installId = existing;\n this._hadPriorSdkState = true;\n } else {\n const newId = generateUUID();\n localStorage.setItem(INSTALL_ID_KEY, newId);\n this._installId = newId;\n this._hadPriorSdkState = false;\n\n // Store first install timestamp for install event gating\n if (!localStorage.getItem(FIRST_INSTALL_TIME_KEY)) {\n localStorage.setItem(FIRST_INSTALL_TIME_KEY, String(Date.now()));\n }\n }\n } catch {\n // localStorage unavailable — generate an in-memory ID\n this._installId = generateUUID();\n }\n }\n\n // --- Install event gating (24h window) ---\n\n private shouldTreatAsNewInstall(): boolean {\n // If first_launch was already tracked, this is not a first launch\n const flag = this.storageGet(FIRST_LAUNCH_TRACKED_KEY);\n if (flag === 'true') return false;\n\n // If SDK had prior state (install_id existed), trust the flag\n if (this._hadPriorSdkState) return true;\n\n // SDK has no prior state — check whether the install is recent\n const installTimeStr = this.storageGet(FIRST_INSTALL_TIME_KEY);\n if (installTimeStr) {\n const installTime = Number(installTimeStr);\n if (Number.isFinite(installTime)) {\n const elapsed = Date.now() - installTime;\n const isRecentInstall = elapsed <= INSTALL_EVENT_MAX_DIFF_MS;\n\n if (!isRecentInstall && this.enableDebug) {\n console.log(\n `[Layers] Install event gated: installed ${Math.round(elapsed / 1000)}s ago ` +\n `(threshold=${INSTALL_EVENT_MAX_DIFF_MS / 1000}s), ` +\n 'no prior SDK state — suppressing is_first_launch'\n );\n }\n\n return isRecentInstall;\n }\n }\n\n // If we can't read the install time, default to trusting it as a new install\n return true;\n }\n\n // --- Attribution data ---\n\n private restoreAttributionData(): void {\n try {\n if (typeof localStorage === 'undefined') return;\n const raw = localStorage.getItem(ATTRIBUTION_DATA_KEY);\n if (!raw) return;\n const data: WebAttributionData = JSON.parse(raw);\n this._attributionData = data;\n\n // Sync restored deeplinkId to the Rust core's DeviceContext\n if (data.deeplinkId) {\n try {\n const currentContext = this.core.getDeviceContext();\n this.core.setDeviceContext({ ...currentContext, deeplinkId: data.deeplinkId });\n } catch {\n // best-effort\n }\n }\n\n if (this.enableDebug && data) {\n console.log(`[Layers] Restored attribution data: ${JSON.stringify(data)}`);\n }\n } catch {\n // Restoration is best-effort\n }\n }\n\n /**\n * Merge attribution properties into event properties.\n * deeplink_id flows through DeviceContext; other fields flow through properties.\n */\n private mergeAttributionProperties(properties?: EventProperties): EventProperties | undefined {\n const data = this._attributionData;\n if (!data) return properties;\n\n const merged: Record<string, unknown> = { ...(properties ?? {}) };\n if (data.gclid) merged.gclid = data.gclid;\n if (data.fbclid) merged.fbclid = data.fbclid;\n if (data.ttclid) merged.ttclid = data.ttclid;\n if (data.msclkid) merged.msclkid = data.msclkid;\n return merged as EventProperties;\n }\n\n /** Merge CAPI, attribution (url-based), setAttributionData, and user properties. */\n private mergeAllProperties(properties?: EventProperties): EventProperties {\n const capiProps = getCapiProperties();\n const urlAttrProps = getAttributionProperties();\n const attrProps = this.mergeAttributionProperties(undefined) ?? {};\n return { ...capiProps, ...urlAttrProps, ...attrProps, ...properties } as EventProperties;\n }\n\n // --- Clipboard attribution check ---\n\n private checkClipboardAttribution(): void {\n if (typeof navigator === 'undefined' || typeof localStorage === 'undefined') return;\n\n // Only check on first init\n try {\n if (localStorage.getItem(CLIPBOARD_CHECKED_KEY) === 'true') return;\n } catch {\n return;\n }\n\n // Gate behind remote config\n let clipboardEnabled = false;\n try {\n const configJson = this.core.getRemoteConfigJson?.();\n if (configJson) {\n const config = JSON.parse(configJson);\n clipboardEnabled = config?.clipboard_attribution_enabled === true;\n }\n } catch {}\n\n // Mark as checked regardless of outcome\n this.storageSet(CLIPBOARD_CHECKED_KEY, 'true');\n\n if (!clipboardEnabled) return;\n\n // Read clipboard (async, best-effort)\n if (navigator.clipboard?.readText) {\n void navigator.clipboard\n .readText()\n .then((text) => {\n if (!text) return;\n // Check for Layers click URL pattern\n const match = text.match(/https?:\\/\\/(in\\.layers\\.com|link\\.layers\\.com)\\/c\\/([^?\\s]+)/);\n if (match) {\n this.track('clipboard_attribution', {\n clipboard_url: text,\n clipboard_click_id: match[2]!\n });\n if (this.enableDebug) {\n console.log(`[Layers] Clipboard attribution found: ${match[2]!}`);\n }\n }\n })\n .catch(() => {\n // Clipboard read failed (permission denied) — silently ignore\n });\n }\n }\n\n // --- Deep link auto-tracking ---\n\n private _trackedDeepLinkUrls = new Set<string>();\n\n private setupDeepLinkAutoTracking(): void {\n this.deepLinkUnsubscribe = setupDeepLinkListener((data: DeepLinkData) => {\n // Deduplicate\n if (this._trackedDeepLinkUrls.has(data.url)) return;\n this._trackedDeepLinkUrls.add(data.url);\n // Clear after a short delay so the same URL can be tracked again later\n setTimeout(() => this._trackedDeepLinkUrls.delete(data.url), 2000);\n\n try {\n const properties: Record<string, unknown> = {\n ...data.queryParams,\n url: data.url,\n scheme: data.scheme,\n host: data.host,\n path: data.path\n };\n this.track('deep_link_opened', properties);\n if (this.enableDebug) {\n console.log(`[Layers] auto-tracked deep_link_opened: ${data.url}`);\n }\n } catch (e) {\n this.emitError(e);\n }\n });\n }\n\n // --- Init timing ---\n\n private trackInitTiming(mainThreadDurationMs: number, totalDurationMs: number): void {\n try {\n this.core.track(\n 'layers_init_timing',\n {\n duration_ms: totalDurationMs,\n main_thread_duration_ms: mainThreadDurationMs\n },\n this.appUserId\n );\n } catch {\n // Init timing is best-effort\n }\n }\n\n // --- Recent events buffer (for debug overlay) ---\n\n private recordRecentEvent(eventName: string, properties?: EventProperties): void {\n const now = new Date();\n const time = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`;\n const propCount = Object.keys(properties ?? {}).length;\n const entry = `${time} ${eventName}${propCount > 0 ? ` (${String(propCount)} props)` : ''}`;\n this._recentEvents.unshift(entry);\n if (this._recentEvents.length > LayersClient.MAX_RECENT_EVENTS) {\n this._recentEvents.pop();\n }\n }\n\n // --- Platform-specific: browser device info ---\n\n private initializeDeviceInfo(): void {\n const context: DeviceContext = {\n platform: 'web',\n osVersion: this.detectOS(),\n appVersion: SDK_VERSION,\n deviceModel: this.detectDeviceModel(),\n locale: this.detectLocale(),\n screenSize: this.detectScreenSize(),\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n ...(this._installId != null && { installId: this._installId })\n };\n this.core.setDeviceContext(context);\n }\n\n private detectOS(): string {\n if (typeof navigator === 'undefined') return 'unknown';\n const ua = navigator.userAgent;\n if (ua.includes('Windows')) return 'Windows';\n if (ua.includes('Mac OS')) return 'macOS';\n if (ua.includes('Linux')) return 'Linux';\n if (ua.includes('Android')) return 'Android';\n if (ua.includes('iPhone') || ua.includes('iPad')) return 'iOS';\n return 'unknown';\n }\n\n private detectDeviceModel(): string {\n if (typeof navigator === 'undefined') return 'unknown';\n if ('userAgentData' in navigator) {\n const uaData = (navigator as { userAgentData?: { platform?: string } }).userAgentData;\n if (uaData?.platform) return uaData.platform;\n }\n return navigator.platform ?? 'unknown';\n }\n\n private detectLocale(): string {\n if (typeof navigator === 'undefined') return 'en-US';\n return navigator.language ?? 'en-US';\n }\n\n private detectScreenSize(): string {\n if (typeof window === 'undefined' || typeof screen === 'undefined') return 'unknown';\n return `${screen.width}x${screen.height}`;\n }\n\n // --- Platform-specific: network listener ---\n\n private setupNetworkListener(): void {\n if (typeof window === 'undefined') return;\n\n this.isOnline = navigator?.onLine ?? true;\n\n this.onlineListener = () => {\n this.isOnline = true;\n void this.core.flushAsync().catch(() => {});\n };\n this.offlineListener = () => {\n this.isOnline = false;\n };\n\n window.addEventListener('online', this.onlineListener);\n window.addEventListener('offline', this.offlineListener);\n }\n\n // --- Platform-specific: lifecycle listeners ---\n\n private getBeaconUrl(): string {\n return `${this.baseUrl}/events`;\n }\n\n private setupLifecycleListeners(): void {\n if (typeof window === 'undefined' || typeof document === 'undefined') return;\n\n // Track app_background / app_foreground on visibilitychange,\n // and flush on page hide using sendBeacon.\n this.visibilityListener = () => {\n if (document.visibilityState === 'hidden') {\n // Track app_background lifecycle event\n try {\n this.core.track('app_background', {}, this.appUserId);\n this.recordRecentEvent('app_background');\n } catch {\n // best-effort\n }\n\n if (\n typeof navigator !== 'undefined' &&\n navigator.sendBeacon &&\n this.core.queueDepth() > 0\n ) {\n try {\n const batch = this.core.createBeaconPayload();\n if (batch) {\n const sent = navigator.sendBeacon(this.getBeaconUrl(), batch);\n if (sent) {\n this.core.clearBeaconEvents();\n return;\n }\n // sendBeacon failed — requeue events before falling back to persistence\n this.core.requeueBeaconEvents();\n this.core.flush();\n return;\n }\n } catch {\n // sendBeacon threw — requeue any drained events before sync flush\n this.core.requeueBeaconEvents();\n }\n }\n this.core.flush();\n } else if (document.visibilityState === 'visible') {\n // Track app_foreground lifecycle event\n try {\n this.core.track('app_foreground', {}, this.appUserId);\n this.recordRecentEvent('app_foreground');\n } catch {\n // best-effort\n }\n\n // Flush queued events when returning to foreground\n if (this.isOnline) {\n void this.core.flushAsync().catch(() => {});\n }\n }\n };\n document.addEventListener('visibilitychange', this.visibilityListener);\n\n // Flush on beforeunload — synchronous persistence as last resort\n this.beforeUnloadListener = () => {\n this.core.flush();\n };\n window.addEventListener('beforeunload', this.beforeUnloadListener);\n }\n\n // --- localStorage helpers ---\n\n private storageGet(key: string): string | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n }\n\n private storageSet(key: string, value: string): void {\n if (typeof localStorage === 'undefined') return;\n try {\n localStorage.setItem(key, value);\n } catch {\n // localStorage full or unavailable\n }\n }\n}\n\n// --- UUID generation ---\n\nfunction generateUUID(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = Math.floor(Math.random() * 16);\n const v = c === 'x' ? r : (r % 4) + 8;\n return v.toString(16);\n });\n}\n\n// SDK version injected at build time by tsdown define\ndeclare const __LAYERS_CLIENT_VERSION__: string;\nconst SDK_VERSION: string =\n typeof __LAYERS_CLIENT_VERSION__ !== 'undefined' ? __LAYERS_CLIENT_VERSION__ : '0.1.1-alpha.1';\n"],"mappings":"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"}
|