@usermaven/sdk-js 1.4.4 → 1.5.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/README.md CHANGED
@@ -1,51 +1,164 @@
1
- # Usermaven JavaScript SDK (usermaven.js)
1
+ # Usermaven SDK
2
2
 
3
- Usermaven.js is a JavaScript SDK for [Usermaven](https://usermaven.com).
3
+ Usermaven SDK is a powerful and flexible JavaScript/TypeScript library for tracking user behavior and events in web applications. It supports both client-side and server-side usage, with a focus on privacy, configurability, and robustness.
4
4
 
5
- ## Capabilities
5
+ ## Features
6
6
 
7
- - Autocapturing via `autocapture`, `capture_pageview`, `properties_string_max_length` and `property_blacklist` options.
7
+ - Cross-platform compatibility (browser and server-side)
8
+ - Flexible event tracking with custom payloads
9
+ - Automatic tracking of page views, form submissions, and user interactions
10
+ - Privacy-focused with configurable data sanitization
11
+ - Robust error handling and retry mechanisms
12
+ - Extensible architecture for custom tracking features
13
+ - Performance optimizations including event batching and debouncing
8
14
 
9
- ## Maintainers Guide
15
+ ## Installation
10
16
 
11
- This section is indented only for package maintainers.
17
+ ### NPM or Yarn
12
18
 
13
- ### Building and local debug
19
+ You can install the Usermaven SDK using npm:
14
20
 
15
- * _**ATTENTION**_: Use `yarn` for everything except publishing
16
- * To spin off a local development server run `yarn devserver`, then open [http://localhost:8081](http://localhost:8081)
17
- * The server listens to all changes to src and rebuilds npm and `lib.js` automatically. Open test cases HTML files to see
18
- usermaven in action
19
- * http://localhost:8081/test-case/embed.html - embedded Usermaven
20
- - * <http://localhost:8081/test-case/embed_strict_mode.html> - embedded strict mode for Usermaven
21
- * http://localhost:8081/test-case/autocapture.html - embedded Usermaven with autocapturing events
22
- * `yarn test` runs [Playwright](https://playwright.dev/) test
23
- * `yarn build` builds both npm package and `lib.js` browser bundle
24
- * `npm publish --public` to publish the package (change version in `package.json` manually). You need to run `npm login` with your personal
25
- npmjs account beforehand (make sure you have access to Usermaven team)
26
- * In order to check usermaven sdk locally.
27
- * `cd dist/npm` --- navigate to npm directory
28
- * `npm link` --- creates a symbolic link to be accessed globally
29
- * `cd ../../__tests__/sdk/` --- navigate to sdk test project
30
- * `npm i` --- install npm dependencies
31
- * `npm link @usermaven/sdk-js` --- use npm package locally whose symlink is just published
32
- * `npm start` --- start the application and monitor events
21
+ ```bash
22
+ npm install @usermaven/sdk-js
23
+ ```
33
24
 
34
- ### Checking Cross Domain Session locally
35
- Setup a custom domain and sub-domain locally to test cross domain session persistence.
25
+ Or using yarn:
36
26
 
37
27
  ```bash
38
- sudo nano /etc/hosts
28
+ yarn add @usermaven/sdk-js
39
29
  ```
40
- Add the following lines in the hosts file
41
- ```bash
42
- 127.0.0.1 localhost.com
43
- 127.0.0.1 app.localhost.com
30
+
31
+ ### UMD (Universal Module Definition)
32
+
33
+ For quick integration without a module bundler, you can include the SDK directly in your HTML using a script tag:
34
+
35
+ ```html
36
+ <script src="https://cdn.usermaven.com/sdk/v1/lib.js"
37
+ data-key="your-api-key"
38
+ data-tracking-host="https://events.yourdomain.com"
39
+ data-log-level="debug"
40
+ data-autocapture="true"
41
+ data-form-tracking="true"
42
+ data-auto-pageview="true"></script>
44
43
  ```
45
44
 
46
- You will be able to access the domains at [localhost domain](http://localhost.com:8081/test-case/embed.html) and [localhost sub-domain](http://app.localhost.com:8081/test-case/embed.html)
45
+ Replace `https://cdn.usermaven.com/sdk/v1/lib.js` with the actual URL where the Usermaven SDK is hosted.
46
+
47
+ ## Basic Usage
48
+
49
+ ### Using as a module
50
+
51
+ ```javascript
52
+ import { usermavenClient } from '@usermaven/sdk-js';
53
+
54
+ const client = usermavenClient({
55
+ apiKey: 'your-api-key',
56
+ trackingHost: 'https://events.yourdomain.com',
57
+ // Add other configuration options as needed
58
+ });
59
+
60
+ // Track an event
61
+ client.track('button_click', {
62
+ buttonId: 'submit-form',
63
+ pageUrl: window.location.href
64
+ });
65
+
66
+ // Identify a user
67
+ client.id({
68
+ id: 'user123',
69
+ email: 'user@example.com',
70
+ name: 'John Doe'
71
+ });
72
+
73
+ // Track a page view
74
+ client.pageview();
75
+ ```
76
+
77
+ ### Using via UMD
78
+
79
+ When you include the SDK via a script tag, it automatically initializes with the configuration provided in the data attributes. You can then use the global `usermaven` function to interact with the SDK:
80
+
81
+ ```html
82
+ <script>
83
+ // Track an event
84
+ usermaven('track', 'button_click', {
85
+ buttonId: 'submit-form',
86
+ pageUrl: window.location.href
87
+ });
88
+
89
+ // Identify a user
90
+ usermaven('id', {
91
+ id: 'user123',
92
+ email: 'user@example.com',
93
+ name: 'John Doe'
94
+ });
95
+
96
+ // Track a page view (if not set to automatic in the script tag)
97
+ usermaven('pageview');
98
+ </script>
99
+ ```
100
+
101
+ ## Advanced Configuration
102
+
103
+ The SDK supports various configuration options to customize its behavior. When using as a module:
104
+
105
+ ```javascript
106
+ const client = usermavenClient({
107
+ apiKey: 'your-api-key',
108
+ trackingHost: 'https://events.yourdomain.com',
109
+ cookieDomain: '.yourdomain.com',
110
+ logLevel: 'DEBUG',
111
+ useBeaconApi: true,
112
+ autocapture: true,
113
+ formTracking: 'all',
114
+ autoPageview: true,
115
+ // ... other options
116
+ });
117
+ ```
118
+
119
+ When using via UMD, you can set these options using data attributes on the script tag:
120
+
121
+ ```html
122
+ <script src="https://cdn.usermaven.com/sdk/v1/lib.js"
123
+ data-key="your-api-key"
124
+ data-tracking-host="https://events.yourdomain.com"
125
+ data-log-level="debug"
126
+ data-autocapture="true"
127
+ data-form-tracking="all"
128
+ data-auto-pageview="true"
129
+ data-use-beacon-api="true"
130
+ data-cookie-domain=".yourdomain.com"></script>
131
+ ```
132
+
133
+ Refer to the `Config` interface in `src/core/config.ts` for a full list of configuration options.
134
+
135
+ ## Server-Side Usage
136
+
137
+ The SDK can also be used in server-side environments:
138
+
139
+ ```javascript
140
+ const { usermavenClient } = require('@usermaven/sdk-js');
141
+
142
+ const client = usermavenClient({
143
+ apiKey: 'your-api-key',
144
+ trackingHost: 'https://events.yourdomain.com'
145
+ });
146
+
147
+ client.track('server_event', {
148
+ userId: 'user123',
149
+ action: 'item_purchased'
150
+ });
151
+ ```
152
+
153
+ ## Development
154
+
155
+ To set up the project for development:
156
+
157
+ 1. Clone the repository
158
+ 2. Install dependencies: `npm install`
159
+ 3. Run tests: `npm test`
160
+ 4. Build the project: `npm run build`
47
161
 
48
- ### Publishing new version
162
+ ## Contributing
49
163
 
50
- * Login with your *personal* credentials with `npm login`
51
- * Run `yarn install && yarn build && yarn test && npm publish --access public`
164
+ Contributions are welcome! Please read our contributing guidelines and code of conduct before submitting pull requests.
@@ -0,0 +1,54 @@
1
+ import { Config, CompanyProps, EventPayload, UserProps } from './types';
2
+ import { Logger } from '../utils/logger';
3
+ export declare class UsermavenClient {
4
+ private config;
5
+ private logger;
6
+ private cookieManager?;
7
+ private transport;
8
+ private persistence;
9
+ private autoCapture?;
10
+ private formTracking?;
11
+ private pageviewTracking?;
12
+ private retryQueue;
13
+ private anonymousId;
14
+ private namespace;
15
+ private rageClick?;
16
+ constructor(config: Config);
17
+ private initializeBrowserFeatures;
18
+ /**
19
+ * Recursively merge the provided configuration with the existing defaultConfig
20
+ * @param config
21
+ * @param defaultConfig
22
+ */
23
+ mergeConfig(config: Partial<Config>, defaultConfig: Partial<Config>): Config;
24
+ init(config: Config): void;
25
+ private manageCrossDomainLinking;
26
+ private findClosestLink;
27
+ private initializeTransport;
28
+ private initializePersistence;
29
+ private getOrCreateAnonymousId;
30
+ id(userData: UserProps, doNotSendEvent?: boolean): Promise<void>;
31
+ track(typeName: string, payload?: EventPayload, directSend?: boolean): void;
32
+ private trackInternal;
33
+ rawTrack(payload: any): void;
34
+ group(props: CompanyProps, doNotSendEvent?: boolean): Promise<void>;
35
+ private createEventPayload;
36
+ private processAutocaptureAttributes;
37
+ getCookie(name: string): string | null;
38
+ private getThirdPartyIds;
39
+ private getUtmParams;
40
+ pageview(): void;
41
+ private setupPageLeaveTracking;
42
+ getConfig(): Config;
43
+ getLogger(): Logger;
44
+ reset(resetAnonId?: boolean): Promise<void>;
45
+ set(properties: Record<string, any>, opts?: {
46
+ eventType?: string;
47
+ persist?: boolean;
48
+ }): void;
49
+ setUserId(userId: string): void;
50
+ unset(propertyName: string, options?: {
51
+ eventType?: string;
52
+ persist?: boolean;
53
+ }): void;
54
+ }
@@ -0,0 +1,3 @@
1
+ import { Config } from './types';
2
+ export type Policy = 'strict' | 'keep' | 'comply';
3
+ export declare const defaultConfig: Partial<Config>;
@@ -0,0 +1,128 @@
1
+ import { LogLevel } from '../utils/logger';
2
+ export interface EventPayload {
3
+ [key: string]: any;
4
+ }
5
+ export interface UserProps extends EventPayload {
6
+ id?: string;
7
+ email?: string;
8
+ company?: {
9
+ id?: string;
10
+ name?: string;
11
+ created_at?: string;
12
+ custom?: {
13
+ [key: string]: any;
14
+ };
15
+ };
16
+ [key: string]: any;
17
+ }
18
+ export interface Transport {
19
+ send(payload: any): Promise<void>;
20
+ }
21
+ export type Policy = 'strict' | 'keep' | 'comply';
22
+ export interface CompanyProps {
23
+ id: string;
24
+ name: string;
25
+ created_at: string;
26
+ [key: string]: any;
27
+ }
28
+ /**
29
+ * Environment where the event have happened.
30
+ */
31
+ export type ClientProperties = {
32
+ screen_resolution: string;
33
+ user_agent: string;
34
+ referer: string;
35
+ url: string;
36
+ page_title: string;
37
+ doc_path: string;
38
+ doc_host: string;
39
+ doc_search: string;
40
+ vp_size: string;
41
+ user_language: string;
42
+ doc_encoding: string;
43
+ };
44
+ export type Property = any;
45
+ export type Properties = Record<string, Property>;
46
+ export interface AutoCaptureCustomProperty {
47
+ name: string;
48
+ css_selector: string;
49
+ event_selectors: string[];
50
+ }
51
+ type CamelCaseConfig = {
52
+ key: string;
53
+ trackingHost: string;
54
+ cookieDomain?: string;
55
+ cookieName?: string;
56
+ logLevel?: LogLevel;
57
+ useBeaconApi?: boolean;
58
+ forceUseFetch?: boolean;
59
+ autocapture?: boolean;
60
+ rageClick?: boolean;
61
+ formTracking?: boolean | 'all' | 'tagged' | 'none';
62
+ autoPageview?: boolean;
63
+ disableEventPersistence?: boolean;
64
+ gaHook?: boolean;
65
+ segmentHook?: boolean;
66
+ randomizeUrl?: boolean;
67
+ capture3rdPartyCookies?: string[] | false;
68
+ idMethod?: 'cookie' | 'localStorage';
69
+ privacyPolicy?: 'strict';
70
+ ipPolicy?: Policy;
71
+ cookiePolicy?: Policy;
72
+ customHeaders?: Record<string, string> | (() => Record<string, string>);
73
+ minSendTimeout?: number;
74
+ maxSendTimeout?: number;
75
+ maxSendAttempts?: number;
76
+ propertiesStringMaxLength?: number | null;
77
+ propertyBlacklist?: string[];
78
+ exclude?: string;
79
+ namespace?: string;
80
+ crossDomainLinking?: boolean;
81
+ domains?: string;
82
+ maskAllText?: boolean;
83
+ maskAllElementAttributes?: boolean;
84
+ };
85
+ type SnakeCaseConfig = {
86
+ key: string;
87
+ tracking_host: string;
88
+ cookie_domain?: string;
89
+ cookie_name?: string;
90
+ log_level?: LogLevel;
91
+ use_beacon_api?: boolean;
92
+ force_use_fetch?: boolean;
93
+ autocapture?: boolean;
94
+ rage_click?: boolean;
95
+ form_tracking?: boolean | 'all' | 'tagged' | 'none';
96
+ auto_pageview?: boolean;
97
+ disable_event_persistence?: boolean;
98
+ ga_hook?: boolean;
99
+ segment_hook?: boolean;
100
+ randomize_url?: boolean;
101
+ capture_3rd_party_cookies?: string[] | false;
102
+ id_method?: 'cookie' | 'localStorage';
103
+ privacy_policy?: 'strict';
104
+ ip_policy?: Policy;
105
+ cookie_policy?: Policy;
106
+ custom_headers?: Record<string, string> | (() => Record<string, string>);
107
+ min_send_timeout?: number;
108
+ max_send_timeout?: number;
109
+ max_send_attempts?: number;
110
+ properties_string_max_length?: number | null;
111
+ property_blacklist?: string[];
112
+ exclude?: string;
113
+ namespace?: string;
114
+ cross_domain_linking?: boolean;
115
+ domains?: string;
116
+ mask_all_text?: boolean;
117
+ mask_all_element_attributes?: boolean;
118
+ };
119
+ export type Config = Partial<CamelCaseConfig & SnakeCaseConfig> & {
120
+ key: string;
121
+ trackingHost?: string;
122
+ tracking_host?: string;
123
+ } & ({
124
+ trackingHost: string;
125
+ } | {
126
+ tracking_host: string;
127
+ });
128
+ export {};
@@ -0,0 +1,15 @@
1
+ import { UsermavenClient } from '../core/client';
2
+ export declare class RageClick {
3
+ private client;
4
+ private clicks;
5
+ private threshold;
6
+ private timeWindow;
7
+ private distanceThreshold;
8
+ constructor(client: UsermavenClient);
9
+ private initializeEventListener;
10
+ private handleClick;
11
+ private shouldCaptureElement;
12
+ click(x: number, y: number, timestamp: number): void;
13
+ private checkRageClick;
14
+ private sendRageClickEvent;
15
+ }
@@ -0,0 +1,19 @@
1
+ import { UsermavenClient } from '../core/client';
2
+ export declare class ScrollDepth {
3
+ private client;
4
+ private maxScrollDepth;
5
+ private milestones;
6
+ private lastScrollDepth;
7
+ private documentElement;
8
+ private debouncedHandleScroll;
9
+ constructor(client: UsermavenClient);
10
+ private initializeEventListener;
11
+ track(): void;
12
+ send(eventType?: string): void;
13
+ private handleScroll;
14
+ private getScrollDepth;
15
+ private getWindowHeight;
16
+ private getDocumentHeight;
17
+ private getScrollDistance;
18
+ private checkMilestones;
19
+ }
@@ -0,0 +1,5 @@
1
+ import { UsermavenClient } from './core/client';
2
+ import { Config, UserProps, EventPayload, ClientProperties } from './core/types';
3
+ import { LogLevel } from './utils/logger';
4
+ declare function usermavenClient(config: Partial<Config>): UsermavenClient;
5
+ export { usermavenClient, UsermavenClient, Config as UsermavenOptions, UserProps, EventPayload, LogLevel, ClientProperties };
package/dist/lib.js ADDED
@@ -0,0 +1,2 @@
1
+ (function(f,g){typeof exports=="object"&&typeof module<"u"?g(exports):typeof define=="function"&&define.amd?define(["exports"],g):(f=typeof globalThis<"u"?globalThis:f||self,g(f.Usermaven={}))})(this,function(f){"use strict";var g=(i=>(i[i.DEBUG=0]="DEBUG",i[i.INFO=1]="INFO",i[i.WARN=2]="WARN",i[i.ERROR=3]="ERROR",i))(g||{});class X{constructor(e){this.level=e}debug(e,...t){this.level<=0&&console.debug("[Usermaven Debug]:",e,...t)}info(e,...t){this.level<=1&&console.info("[Usermaven Info]:",e,...t)}warn(e,...t){this.level<=2&&console.warn("[Usermaven Warning]:",e,...t)}error(e,...t){this.level<=3&&console.error("[Usermaven Error]:",e,...t)}}function d(i=0){return new X(i)}const L={logLevel:g.ERROR,useBeaconApi:!1,forceUseFetch:!1,trackingHost:"t.usermaven.com",autocapture:!1,rageClick:!1,formTracking:!1,autoPageview:!1,disableEventPersistence:!1,gaHook:!1,segmentHook:!1,randomizeUrl:!1,capture3rdPartyCookies:["_ga","_fbp","_ym_uid","ajs_user_id","ajs_anonymous_id"],idMethod:"cookie",ipPolicy:"keep",cookiePolicy:"keep",minSendTimeout:0,maxSendTimeout:2e3,maxSendAttempts:4,propertiesStringMaxLength:null,propertyBlacklist:[],crossDomainLinking:!0,maskAllText:!1,maskAllElementAttributes:!1};class K{constructor(e){this.domain=e,this.cookieDomain=this.getCookieDomain()}set(e,t,s=365,n=!0,r=!1){const o=new Date;o.setTime(o.getTime()+s*24*60*60*1e3);const c=`expires=${o.toUTCString()}`,l=n?"; Secure":"",a=r?"; HttpOnly":"";document.cookie=`${e}=${t};${c};path=/;domain=${this.cookieDomain}${l}${a}`}get(e){const t=e+"=",s=document.cookie.split(";");for(let n=0;n<s.length;n++){let r=s[n].trim();if(r.indexOf(t)===0)return decodeURIComponent(r.substring(t.length))}return null}delete(e,t="/"){document.cookie=`${e}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${t};domain=${this.cookieDomain}`}getCookieDomain(){return typeof window>"u"||this.domain?this.domain||"":this.extractRoot(window.location.hostname)}extractRoot(e){if(this.isIpAddress(e)||e==="localhost")return e;let t=this.extractTopLevelDomain(e);return t||(t=this.extractRootDomain(e)),"."+t}isIpAddress(e){const t=e.split(".");return t.length===4&&t.every(s=>!isNaN(Number(s)))}extractHostname(e){let t;return e.indexOf("//")>-1?t=e.split("/")[2]:t=e.split("/")[0],t=t.split(":")[0],t=t.split("?")[0],t}extractRootDomain(e){let t=this.extractHostname(e);const s=t.split("."),n=s.length;return n>2&&(s[n-1].length==2?(t=s[n-2]+"."+s[n-1],s[n-2].length==2&&(t=s[n-3]+"."+t)):t=s[n-2]+"."+s[n-1]),t}extractTopLevelDomain(e){const t=/[a-z0-9][a-z0-9-]+\.[a-z.]{2,6}$/i,s=e.match(t);return s?s[0]:""}}const G=Object.prototype.hasOwnProperty,P=Array.prototype.forEach,A={};function Y(i,e,t){if(Array.isArray(i)){if(P&&i.forEach===P)i.forEach(e,t);else if("length"in i&&i.length===+i.length){for(let s=0,n=i.length;s<n;s++)if(s in i&&e.call(t,i[s],s)===A)return}}}const x=function(i){return i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")},Z=function(i){for(const e in i)typeof i[e]=="function"&&(i[e]=i[e].bind(i))};function m(i,e,t){if(i!=null){if(P&&Array.isArray(i)&&i.forEach===P)i.forEach(e,t);else if("length"in i&&i.length===+i.length){for(let s=0,n=i.length;s<n;s++)if(s in i&&e.call(t,i[s],s)===A)return}else for(const s in i)if(G.call(i,s)&&e.call(t,i[s],s)===A)return}}const j=function(i,...e){return Y(e,function(t){for(const s in t)t[s]!==void 0&&(i[s]=t[s])}),i};function v(i,e){return i.indexOf(e)!==-1}const ee=function(i){try{return/^\s*\bfunction\b/.test(i)}catch{return!1}},te=function(i){return i===void 0},w=function(){const i=function(s,n,r,o,c){if(!s){d().error("No valid element provided to register_event");return}if(s.addEventListener&&!o)s.addEventListener(n,r,!!c);else{const l="on"+n,a=s[l];s[l]=e(s,r,a)}};function e(s,n,r){return function(o){if(o=o||t(window.event),!o)return;let c=!0,l;ee(r)&&(l=r(o));const a=n.call(s,o);return(l===!1||a===!1)&&(c=!1),c}}function t(s){return s&&(s.preventDefault=t.preventDefault,s.stopPropagation=t.stopPropagation),s}return t.preventDefault=function(){this.returnValue=!1},t.stopPropagation=function(){this.cancelBubble=!0},i}(),ie=function(i){return function(...e){try{return i.apply(this,e)}catch(t){d().error("Implementation error. Please turn on debug and contact support@usermaven.com.",t)}}},I=function(i){for(const e in i)typeof i[e]=="function"&&(i[e]=ie(i[e]))};function D(i){for(let e in i)(i[e]===""||i[e]===null||i[e]===void 0||typeof i[e]=="object"&&Object.keys(i[e]).length===0)&&delete i[e];return i}function u(){try{return typeof window<"u"&&window.document!==void 0&&window.document.createElement!==void 0}catch{return d().warn("window is not available"),!1}}function y(i=5){const e=new Uint8Array(i);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(36).padStart(2,"0")).join("").slice(0,i)}function se(i){return i.replace(/([-_][a-z])/g,e=>e.toUpperCase().replace("-","").replace("_",""))}function H(i){return typeof i!="object"||i===null?i:Array.isArray(i)?i.map(H):Object.keys(i).reduce((e,t)=>{const s=se(t);return e[s]=H(i[t]),e},{})}function E(i){switch(typeof i.className){case"string":return i.className;case"object":return("baseVal"in i.className?i.className.baseVal:null)||i.getAttribute("class")||"";default:return""}}function U(i){let e="";return O(i)&&!M(i)&&i.childNodes&&i.childNodes.length&&m(i.childNodes,function(t){z(t)&&t.textContent&&(e+=x(t.textContent).split(/(\s+)/).filter(S).join("").replace(/[\r\n]/g," ").replace(/[ ]+/g," ").substring(0,255))}),x(e)}function F(i){return!!i&&i.nodeType===1}function p(i,e){return!!i&&!!i.tagName&&i.tagName.toLowerCase()===e.toLowerCase()}function z(i){return!!i&&i.nodeType===3}function N(i){return!!i&&i.nodeType===11}const $=["a","button","form","input","select","textarea","label"];function ne(i,e){if(!i||p(i,"html")||!F(i))return!1;let t=i;for(;t&&!p(t,"body");){if(t.classList&&t.classList.contains("um-no-capture"))return!1;t.parentNode&&N(t.parentNode)?t=t.parentNode.host:t=t.parentNode}let s=!1;for(t=i;t&&!p(t,"body");){if(t.parentNode&&N(t.parentNode)){t=t.parentNode.host,t&&$.indexOf(t.tagName.toLowerCase())>-1&&(s=!0);continue}const o=t.parentNode;if(!o)break;if($.indexOf(o.tagName.toLowerCase())>-1)s=!0;else{const c=window.getComputedStyle(o);c&&c.getPropertyValue("cursor")==="pointer"&&(s=!0)}t=o}const n=window.getComputedStyle(i);if(n&&n.getPropertyValue("cursor")==="pointer"&&e.type==="click")return!0;const r=i.tagName.toLowerCase();switch(r){case"html":return!1;case"form":return e.type==="submit";case"input":return e.type==="change"||e.type==="click";case"select":case"textarea":return e.type==="change"||e.type==="click";default:return s?e.type==="click":e.type==="click"&&($.indexOf(r)>-1||i.getAttribute("contenteditable")==="true")}}function O(i){for(let s=i;s.parentNode&&!p(s,"body");s=s.parentNode){const n=E(s).split(" ");if(v(n,"ph-sensitive")||v(n,"ph-no-capture"))return!1}if(v(E(i).split(" "),"ph-include"))return!0;const e=i.type||"";if(typeof e=="string")switch(e.toLowerCase()){case"hidden":return!1;case"password":return!1}const t=i.name||i.id||"";return!(typeof t=="string"&&/^cc|cardnum|ccnum|creditcard|csc|cvc|cvv|exp|pass|pwd|routing|seccode|securitycode|securitynum|socialsec|socsec|ssn/i.test(t.replace(/[^a-zA-Z0-9]/g,"")))}function M(i){const e=["button","checkbox","submit","reset"];return!!(p(i,"input")&&!e.includes(i.type)||p(i,"select")||p(i,"textarea")||i.getAttribute("contenteditable")==="true")}function S(i){return!(i===null||te(i)||typeof i=="string"&&(i=x(i),/^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/.test((i||"").replace(/[- ]/g,""))||/(^\d{3}-?\d{2}-?\d{4}$)/.test(i)))}function re(i){return typeof i=="string"?i.substring(0,10)==="_ngcontent"||i.substring(0,7)==="_nghost":!1}function R(){return y(10)}function oe(i){return/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(String(i).toLowerCase())}function ae(i,e){let t;return function(...s){const n=()=>{clearTimeout(t),i(...s)};clearTimeout(t),t=setTimeout(n,e)}}function ce(i){const e={},t=i.replace(/^\?/,"").split("&");for(let s=0;s<t.length;s++){const n=t[s].split("=");n[0]!==""&&(e[decodeURIComponent(n[0])]=decodeURIComponent(n[1]||""))}return e}function q(i){return typeof i=="string"||i instanceof String}function _(i){return i!==null&&typeof i=="object"&&i.constructor===Object}function le(i){if(i===null)return g.ERROR;const e=i.toUpperCase(),t=g[e];return t||t===0?t:g.ERROR}class ue{constructor(e){this.maxScrollDepth=0,this.milestones=[25,50,75,90],this.lastScrollDepth=0,this.client=e,this.documentElement=document.documentElement,this.debouncedHandleScroll=ae(this.handleScroll.bind(this),250),this.initializeEventListener()}initializeEventListener(){window.addEventListener("scroll",this.debouncedHandleScroll)}track(){const e=this.getScrollDepth();e>this.lastScrollDepth&&(this.lastScrollDepth=e,this.checkMilestones(e))}send(e="$scroll"){if(!this.lastScrollDepth)return;const t={percent:this.lastScrollDepth,window_height:this.getWindowHeight(),document_height:this.getDocumentHeight(),scroll_distance:this.getScrollDistance()};this.client.track(e,t)}handleScroll(){this.track()}getScrollDepth(){const e=this.getWindowHeight(),t=this.getDocumentHeight(),s=this.getScrollDistance(),n=t-e;return Math.min(100,Math.floor(s/n*100))}getWindowHeight(){return window.innerHeight||this.documentElement.clientHeight||document.body.clientHeight||0}getDocumentHeight(){return Math.max(document.body.scrollHeight||0,this.documentElement.scrollHeight||0,document.body.offsetHeight||0,this.documentElement.offsetHeight||0,document.body.clientHeight||0,this.documentElement.clientHeight||0)}getScrollDistance(){return window.pageYOffset||this.documentElement.scrollTop||document.body.scrollTop||0}checkMilestones(e){this.milestones.filter(s=>e>=s).forEach(s=>{this.send(),this.milestones=this.milestones.filter(n=>n!==s)})}}const T=class T{constructor(e,t,s=d()){this.logger=s,this.scrollDepth=null,this.customProperties=[],this.client=e,this.options=t,this.scrollDepth=new ue(e),Z(this),I(this)}init(){if(!(document&&document.body)){this.logger.debug("Document not ready yet, trying again in 500 milliseconds..."),setTimeout(()=>this.init(),500);return}this.addDomEventHandlers()}addDomEventHandlers(){const e=t=>{t=t||window.event,this.captureEvent(t)};w(document,"submit",e,!1,!0),w(document,"change",e,!1,!0),w(document,"click",e,!1,!0),w(document,"visibilitychange",e,!1,!0),w(document,"scroll",e,!1,!0),w(window,"popstate",e,!1,!0)}isPageRefresh(){if("PerformanceNavigationTiming"in window){const e=performance.getEntriesByType("navigation");if(e.length>0)return e[0].type==="reload"}return performance.navigation&&performance.navigation.type===1}captureEvent(e){var s,n;let t=this.getEventTarget(e);if(z(t)&&(t=t.parentNode||null),e.type==="scroll")return(s=this.scrollDepth)==null||s.track(),!0;if(e.type==="visibilitychange"&&document.visibilityState==="hidden"||e.type==="popstate")return this.isPageRefresh()||(n=this.scrollDepth)==null||n.send(),!0;if(t&&ne(t,e)){const r=[t];let o=t;for(;o.parentNode&&!p(o,"body");){if(N(o.parentNode)){r.push(o.parentNode.host),o=o.parentNode.host;continue}r.push(o.parentNode),o=o.parentNode}const c=[];let l,a=!1;if(m(r,b=>{const ke=O(b);b.tagName.toLowerCase()==="a"&&(l=b.getAttribute("href"),l=ke&&S(l)&&l);const ve=E(b).split(" ");v(ve,"ph-no-capture")&&(a=!0),c.push(this.getPropertiesFromElement(b,this.options.maskAllElementAttributes??!1,this.options.maskAllText??!1))}),this.options.maskAllText||(c[0].$el_text=U(t)),l&&(c[0].attr__href=l),a)return!1;const h=j(this.getDefaultProperties(e.type),{$elements:c},this.getCustomProperties(r));return this.client.track("$autocapture",h),!0}}getCustomProperties(e){const t={};return m(this.customProperties,s=>{m(s.event_selectors,n=>{const r=document.querySelectorAll(n);m(r,o=>{v(e,o)&&O(o)&&(t[s.name]=this.extractCustomPropertyValue(s))})})}),t}extractCustomPropertyValue(e){const t=[];return m(document.querySelectorAll(e.css_selector),function(s){let n;["input","select"].indexOf(s.tagName.toLowerCase())>-1?n=s.value:s.textContent&&(n=s.textContent),S(n)&&t.push(n)}),t.join(", ")}getEventTarget(e){var t;return typeof e.target>"u"?e.srcElement||null:(t=e.target)!=null&&t.shadowRoot?e.composedPath()[0]||null:e.target||null}getPropertiesFromElement(e,t,s){const n=e.tagName.toLowerCase(),r={tag_name:n};$.indexOf(n)>-1&&!s&&(r.$el_text=U(e));const o=E(e);o.length>0&&(r.classes=o.split(" ").filter(function(h){return h!==""})),m(e.attributes,function(h){M(e)&&["name","id","class"].indexOf(h.name)===-1||!t&&S(h.value)&&!re(h.name)&&(r["attr__"+h.name]=h.value)});let c=1,l=1,a=e;for(;a=this.previousElementSibling(a);)c++,a.tagName===e.tagName&&l++;return r.nth_child=c,r.nth_of_type=l,r}previousElementSibling(e){if(e.previousElementSibling)return e.previousElementSibling;{let t=e;do t=t.previousSibling;while(t&&!F(t));return t}}getDefaultProperties(e){return{$event_type:e,$ce_version:1}}encodeHtml(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}static enabledForProject(e,t=10,s=10){if(!e)return!1;let n=0;for(let r=0;r<e.length;r++)n+=e.charCodeAt(r);return n%t<s}};T.FORCE_CAPTURE_ATTR="data-um-force-capture",T.PREVENT_CAPTURE_ATTR="data-um-no-capture";let C=T;class he{constructor(e){this.client=e,this.lastPageUrl=window.location.href,this.trackInitialPageview(),this.initializePageviewTracking()}trackInitialPageview(){this.trackPageview()}initializePageviewTracking(){window.addEventListener("popstate",this.handlePageview.bind(this));const e=history.pushState;history.pushState=(...t)=>{e.apply(history,t),this.handlePageview()},window.addEventListener("hashchange",this.handlePageview.bind(this)),setInterval(this.checkForUrlChange.bind(this),1e3)}handlePageview(){this.trackPageview()}checkForUrlChange(){window.location.href!==this.lastPageUrl&&this.trackPageview()}trackPageview(){const e=window.location.href;e!==this.lastPageUrl&&(this.lastPageUrl=e,this.client.track("pageview",{url:e,referrer:document.referrer,title:document.title}))}}class de{constructor(e,t,s=d()){this.trackingHost=e,this.logger=s,this.config=t}async send(e){const t=this.config.key,s=this.constructUrl(t),n=new Blob([JSON.stringify(e)],{type:"application/json"});if(navigator.sendBeacon(s,n))this.logger.debug(`Successfully queued ${e.length} event(s) via Beacon API`);else throw new Error("Failed to queue events via Beacon API")}constructUrl(e){const t=this.config.cookiePolicy!=="keep"?`&cookie_policy=${this.config.cookiePolicy}`:"",s=this.config.ipPolicy!=="keep"?`&ip_policy=${this.config.ipPolicy}`:"",n=u()?"/api/v1/event":"/api/v1/s2s/event";return this.config.randomizeUrl?`${this.trackingHost}/api.${y()}?p_${y()}=${e}${t}${s}`:`${this.trackingHost}${n}?token=${e}${t}${s}`}}class B{constructor(e,t,s=d()){this.trackingHost=e,this.logger=s,this.config=t}async send(e){const t=this.config.key,s=this.constructUrl(t),n=JSON.stringify(e),r={"Content-Type":"application/json",...this.getCustomHeaders()},o=await fetch(s,{method:"POST",headers:r,body:n});if(!o.ok)throw new Error(`HTTP error! status: ${o.status}`);this.logger.debug(`Successfully sent ${e.length} event(s)`),this.postHandle(o.status,await o.text())}constructUrl(e){const t=this.config.cookiePolicy!=="keep"?`&cookie_policy=${this.config.cookiePolicy}`:"",s=this.config.ipPolicy!=="keep"?`&ip_policy=${this.config.ipPolicy}`:"",n=u()?"/api/v1/event":"/api/v1/s2s/event";return this.config.randomizeUrl?`${this.trackingHost}/api.${y()}?p_${y()}=${e}${t}${s}`:`${this.trackingHost}${n}?token=${e}${t}${s}`}getCustomHeaders(){return typeof this.config.customHeaders=="function"?this.config.customHeaders():this.config.customHeaders?this.config.customHeaders:{}}postHandle(e,t){this.logger.debug(`Response received. Status: ${e}, Body: ${t}`)}}class ge{constructor(e,t,s=d()){this.trackingHost=e,this.logger=s,this.config=t}send(e){return new Promise((t,s)=>{const n=new XMLHttpRequest,r=this.config.key,o=this.constructUrl(r);n.open("POST",o,!0),n.setRequestHeader("Content-Type","application/json");const c=this.getCustomHeaders();Object.keys(c).forEach(l=>{n.setRequestHeader(l,c[l])}),n.onload=()=>{n.status>=200&&n.status<300?(this.logger.debug(`Successfully sent ${e.length} event(s)`),t()):s(new Error(`HTTP error! status: ${n.status}`))},n.onerror=()=>{s(new Error("Network error"))},n.send(JSON.stringify(e))})}constructUrl(e){const t=this.config.cookiePolicy!=="keep"?`&cookie_policy=${this.config.cookiePolicy}`:"",s=this.config.ipPolicy!=="keep"?`&ip_policy=${this.config.ipPolicy}`:"",n=u()?"/api/v1/event":"/api/v1/s2s/event";return this.config.randomizeUrl?`${this.trackingHost}/api.${y()}?p_${y()}=${e}${t}${s}`:`${this.trackingHost}${n}?token=${e}${t}${s}`}getCustomHeaders(){return typeof this.config.customHeaders=="function"?this.config.customHeaders():this.config.customHeaders?this.config.customHeaders:{}}postHandle(e,t){this.logger.debug(`Response received. Status: ${e}, Body: ${t}`)}}class V{constructor(e,t){this.storage={},this.prefix=`usermaven_${e}_`,this.load(),this.logger=t||d()}set(e,t){this.storage[e]=t,this.save()}get(e){return this.storage[e]}remove(e){delete this.storage[e],this.save()}clear(){this.storage={},this.save()}save(){if(!u()){this.logger.warn("localStorage is not available in this environment");return}try{localStorage.setItem(this.prefix+"data",JSON.stringify(this.storage))}catch(e){this.logger.error("Error saving to localStorage:",e)}}load(){if(!u()){this.logger.warn("localStorage is not available in this environment");return}try{const e=localStorage.getItem(this.prefix+"data");e&&(this.storage=JSON.parse(e))}catch(e){this.logger.error("Error loading from localStorage:",e)}}}class fe{constructor(){this.storage={}}set(e,t){this.storage[e]=t}get(e){return this.storage[e]}remove(e){delete this.storage[e]}save(){}clear(){this.storage={}}}class J{constructor(e,t=3,s=1e3,n=10,r=1e3,o=d(),c="default"){this.transport=e,this.maxRetries=t,this.retryInterval=s,this.batchSize=n,this.batchInterval=r,this.logger=o,this.queue=[],this.processing=!1,this.batchTimeoutId=null,this.isOnline=!0,this.persistence=new V(`offline_queue_${c}`),u()&&(this.isOnline=navigator.onLine,this.loadQueueFromStorage(),this.initNetworkListeners(),this.scheduleBatch())}add(e){const t={payload:e,retries:0,timestamp:Date.now()};this.queue.push(t),u()?this.saveQueueToStorage():this.processBatch()}initNetworkListeners(){u()&&(window.addEventListener("online",()=>{this.isOnline=!0,this.processBatch()}),window.addEventListener("offline",()=>{this.isOnline=!1}))}scheduleBatch(){u()&&(this.batchTimeoutId!==null&&clearTimeout(this.batchTimeoutId),this.batchTimeoutId=window.setTimeout(()=>this.processBatch(),this.batchInterval))}async processBatch(){if((!u()||this.isOnline)&&!this.processing&&this.queue.length>0){this.processing=!0;const e=this.queue.splice(0,this.batchSize),t=e.map(s=>s.payload);try{await this.transport.send(t),this.logger.debug(`Successfully sent batch of ${e.length} payloads`),u()&&this.saveQueueToStorage()}catch(s){this.logger.error("Failed to send batch",s),await this.handleBatchFailure(e)}this.processing=!1}u()&&this.scheduleBatch()}async handleBatchFailure(e){for(const t of e)t.retries<this.maxRetries?(t.retries++,this.queue.unshift(t),this.logger.warn(`Retry attempt ${t.retries} for payload`)):this.logger.error("Max retries reached, discarding payload",t.payload);u()&&(this.saveQueueToStorage(),await new Promise(t=>setTimeout(t,this.retryInterval)))}loadQueueFromStorage(){if(u()){const e=this.persistence.get("queue");e&&(this.queue=JSON.parse(e))}}saveQueueToStorage(){u()&&this.persistence.set("queue",JSON.stringify(this.queue))}}class pe{constructor(e){this.clicks=[],this.threshold=3,this.timeWindow=2e3,this.distanceThreshold=30,this.client=e,this.initializeEventListener(),I(this)}initializeEventListener(){document.addEventListener("click",this.handleClick.bind(this))}handleClick(e){const t=e.target;this.shouldCaptureElement(t)&&this.click(e.clientX,e.clientY,Date.now())}shouldCaptureElement(e){return!e.closest(".um-no-capture")}click(e,t,s){const n={x:e,y:t,timestamp:s};this.clicks.push(n),this.clicks=this.clicks.filter(r=>s-r.timestamp<this.timeWindow),this.clicks.length>=this.threshold&&this.checkRageClick()}checkRageClick(){const e=this.clicks[0],s=(this.clicks[this.clicks.length-1].timestamp-e.timestamp)/1e3;this.clicks.every((r,o)=>{if(o===0)return!0;const c=this.clicks[o-1];return Math.sqrt(Math.pow(r.x-c.x,2)+Math.pow(r.y-c.y,2))<this.distanceThreshold})&&this.sendRageClickEvent(s)}sendRageClickEvent(e){const t=this.clicks[this.clicks.length-1];document.elementFromPoint(t.x,t.y)&&this.client.track("$rage_click",{no_of_clicks:this.clicks.length,time:e.toFixed(2)}),this.clicks=[]}}class me{constructor(e,t,s=d()){this.trackingHost=e,this.logger=s,this.config=t}async send(e){const t=this.config.key,s=new(void 0)(this.constructUrl(t)),n={hostname:s.hostname,port:443,path:`${s.pathname}${s.search}`,method:"POST",headers:{"Content-Type":"application/json",...this.getCustomHeaders()}};return new Promise((r,o)=>{const c=(void 0)(n,l=>{l.on("data",a=>{}),l.on("end",()=>{const a=l.statusCode||0;a>=200&&a<300?(this.logger.debug(`Successfully sent ${e.length} event(s)`),r()):o(new Error(`HTTP error! status: ${a}`))})});c.on("error",l=>{o(l)}),c.write(JSON.stringify(e)),c.end()})}constructUrl(e){const t=this.config.cookiePolicy!=="keep"?`&cookie_policy=${this.config.cookiePolicy}`:"",s=this.config.ipPolicy!=="keep"?`&ip_policy=${this.config.ipPolicy}`:"";return`${this.trackingHost}/api/v1/s2s/event?token=${e}${t}${s}`}getCustomHeaders(){return typeof this.config.customHeaders=="function"?this.config.customHeaders():this.config.customHeaders?this.config.customHeaders:{}}}class k{constructor(e,t="all",s={}){this.instance=e,this.trackingType=t,this.options=s,document.readyState==="loading"?document.addEventListener("DOMContentLoaded",this.initialize.bind(this)):this.initialize()}initialize(){this.trackingType!=="none"&&this.setupFormTracking()}setupFormTracking(){var e;this.formElements=this.trackingType==="tagged"?document.querySelectorAll("form[data-um-form]"):document.querySelectorAll("form"),(e=this.formElements)==null||e.forEach(t=>{t.addEventListener("submit",this.handleFormSubmit.bind(this))})}handleFormSubmit(e){const t=e.target,s=this._getFormDetails(t);this.instance.track("$form",D(s)),this.options.trackFieldChanges&&this.trackFieldChanges(t)}trackFieldChanges(e){e.querySelectorAll("input, select, textarea").forEach(s=>{s.addEventListener("change",n=>{const r=this._getFieldProps(n.target,0);this.instance.track("$form_field_change",D(r))})})}static getInstance(e,t="all",s={}){return k.instance||(k.instance=new k(e,t,s)),k.instance}_getFormDetails(e){const t={form_id:e.id,form_name:e.name||"",form_action:e.action,form_method:e.method,form_class:e.className,form_attributes:this._getElementAttributes(e)},s=e.querySelectorAll("input, select, textarea");return Array.from(s).filter(r=>!r.classList.contains("um-no-capture")).forEach((r,o)=>{const c=this._getFieldProps(r,o);Object.assign(t,c)}),t}_getFieldProps(e,t){const s=Object.keys(e.dataset).length?JSON.stringify(e.dataset):void 0,n=this.getSafeText(e);return{[`field_${t+1}_tag`]:e.tagName.toLowerCase(),[`field_${t+1}_type`]:e instanceof HTMLInputElement?e.type:void 0,[`field_${t+1}_data_attributes`]:s,[`field_${t+1}_id`]:e.id,[`field_${t+1}_value`]:n,[`field_${t+1}_class`]:e.className,[`field_${t+1}_name`]:e.name,[`field_${t+1}_attributes`]:this._getElementAttributes(e)}}_getElementAttributes(e){return Object.keys(e.dataset).length?JSON.parse(JSON.stringify(e.dataset)):{}}getSafeText(e){let t="";return"value"in e&&e.type!=="password"?t=e.value:e.hasChildNodes()?t=Array.from(e.childNodes).filter(n=>n.nodeType===Node.TEXT_NODE).map(n=>n.textContent).join(""):t=e.textContent||"",this._scrubPotentiallySensitiveValues(t)}_scrubPotentiallySensitiveValues(e){return this._shouldCaptureValue(e)?e:"<redacted>"}_shouldCaptureValue(e){return!(this._isNullish(e)||this._isString(e)&&(e=this._trim(e),/^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/.test((e||"").replace(/[- ]/g,""))||/(^\d{3}-?\d{2}-?\d{4}$)/.test(e)))}_isNullish(e){return e==null}_isString(e){return typeof e=="string"||e instanceof String}_trim(e){if(typeof String.prototype.trim=="function")return e.trim();let t=0,s=e.length-1;const n=[" ",`
2
+ `,"\r"," ","\f","\v"," "," "," "," "," "," "," "," "," "," "," "," "," ","\u2028","\u2029"," "," "," "].join("");for(;t<=s&&n.indexOf(e[t])>-1;)t++;for(;s>=t&&n.indexOf(e[s])>-1;)s--;return e.slice(t,s+1)}}class Q{constructor(e){this.config=this.mergeConfig(e,L),this.logger=d(this.config.logLevel),this.namespace=e.namespace||"default",this.transport=this.initializeTransport(this.config),this.persistence=this.initializePersistence(),this.retryQueue=new J(this.transport,this.config.maxSendAttempts||3,this.config.minSendTimeout||1e3,10,200,this.logger,this.namespace),u()&&this.initializeBrowserFeatures(),this.anonymousId=this.getOrCreateAnonymousId(),this.logger.info(`Usermaven client initialized for namespace: ${this.namespace}`)}initializeBrowserFeatures(){if(this.cookieManager=new K(this.config.cookieDomain),this.config.autocapture&&C.enabledForProject(this.config.key)&&(this.autoCapture=new C(this,this.config,this.logger),this.autoCapture.init()),this.config.formTracking){const e=this.config.formTracking===!0?"all":this.config.formTracking;this.formTracking=k.getInstance(this,e||"none",{trackFieldChanges:!1})}this.config.autoPageview&&(this.pageviewTracking=new he(this)),this.config.crossDomainLinking&&this.manageCrossDomainLinking(),this.config.rageClick&&(this.rageClick=new pe(this)),this.setupPageLeaveTracking()}mergeConfig(e,t){const s=JSON.parse(JSON.stringify(e));let n={...t,...s};return Object.keys(t).forEach(r=>{_(t[r])&&(n[r]=this.mergeConfig(e[r],t[r]))}),n}init(e){this.config={...this.config,...e},this.logger=d(this.config.logLevel),this.namespace=e.namespace||this.namespace,this.transport=this.initializeTransport(e),this.persistence=this.initializePersistence(),this.retryQueue=new J(this.transport,this.config.maxSendAttempts||3,this.config.minSendTimeout||1e3,10,250,this.logger,this.namespace),u()&&this.initializeBrowserFeatures(),this.anonymousId=this.getOrCreateAnonymousId(),this.logger.info(`Usermaven client reinitialized for namespace: ${this.namespace}`)}manageCrossDomainLinking(){if(!this.config.crossDomainLinking||!this.config.domains)return;const e=this.config.domains.split(",").map(s=>s.trim()),t=this.config.cookieName||`__eventn_id_${this.config.key}`;document.addEventListener("click",s=>{var c;const n=this.findClosestLink(s.target);if(!n)return;const r=n.getAttribute("href");if(!r||!r.startsWith("http"))return;const o=new URL(r);if(o.hostname!==window.location.hostname&&e.includes(o.hostname)){const l=(c=this.cookieManager)==null?void 0:c.get(t);l&&(o.searchParams.append("_um",l),n.setAttribute("href",o.toString()))}}),this.logger.debug("Cross-domain linking initialized")}findClosestLink(e){for(;e&&e.tagName!=="A";)e=e.parentElement;return e}initializeTransport(e){const t="https://events.usermaven.com";if(!u())return new me(e.trackingHost||t,e);const s="XMLHttpRequest"in window,n=typeof fetch<"u",r=typeof navigator<"u"&&"sendBeacon"in navigator;if(e.useBeaconApi&&r)return new de(e.trackingHost||t,e,this.logger);if(e.forceUseFetch&&n)return new B(e.trackingHost||t,e,this.logger);if(s)return new ge(e.trackingHost||t,e,this.logger);if(n)return new B(e.trackingHost||t,e,this.logger);throw new Error("No suitable transport method available")}initializePersistence(){return this.config.disableEventPersistence||!u()?new fe:new V(`${this.namespace}_${this.config.key}`,this.logger)}getOrCreateAnonymousId(){var s,n;if(!u())return R();if(this.config.privacyPolicy==="strict"||this.config.cookiePolicy==="strict")return"";const e=this.config.cookieName||`__eventn_id_${this.config.key}`;let t=(s=this.cookieManager)==null?void 0:s.get(e);if(!t){if(this.config.crossDomainLinking){const c=new URLSearchParams(window.location.search).get("_um"),a=window.location.hash.substring(1).split("~"),h=a.length>1?a[1]:void 0;t=c||h||R()}t||(t=R());const r=365*10;(n=this.cookieManager)==null||n.set(e,t,r,document.location.protocol!=="http:",!1)}return t}async id(e,t=!1){if(!_(e))throw new Error("User data must be an object");if(e.email&&!oe(e.email))throw new Error("Invalid email provided");if(!e.id||!q(e.id))throw new Error("User ID must be a string");const s=e.id;if(this.persistence.set("userId",s),this.persistence.set("userProps",e),!t){const n={...e,anonymous_id:this.anonymousId};await this.track("user_identify",n)}this.logger.info("User identified:",e)}track(e,t,s=!1){this.trackInternal(e,t,s)}trackInternal(e,t,s=!1){if(!q(e))throw new Error("Event name must be a string");if(t!==void 0&&(typeof t!="object"||t===null||Array.isArray(t)))throw new Error("Event payload must be a non-null object and not an array");const n=this.createEventPayload(e,t);try{if(s){this.transport.send(n),this.logger.debug(`Event sent: ${e}`,[n]);return}this.retryQueue.add(n),this.logger.debug(`Event tracked: ${e}`,[n])}catch(r){throw this.logger.error(`Failed to track event: ${e}`,r),new Error(`Failed to track event: ${e}`)}}rawTrack(e){if(!_(e))throw new Error("Event payload must be an object");this.track("raw",e)}async group(e,t=!1){if(!_(e))throw new Error("Company properties must be an object");if(!e.id||!e.name||!e.created_at)throw new Error("Company properties must include id, name, and created_at");this.persistence.set("companyProps",e),t||await this.track("group",e),this.logger.info("Company identified:",e)}createEventPayload(e,t){const s=this.persistence.get("userProps")||{},n=this.persistence.get("companyProps")||(s==null?void 0:s.company)||{},r=this.persistence.get("userId"),o=this.persistence.get("global_props")||{},c=this.persistence.get(`props_${e}`)||{};let l=t||{};const a={event_id:"",user:{anonymous_id:this.anonymousId,id:r,...s},...n&&{company:n},ids:this.getThirdPartyIds(),utc_time:new Date().toISOString(),local_tz_offset:new Date().getTimezoneOffset(),api_key:this.config.key,src:"usermaven",event_type:e,namespace:this.namespace,...o,...c};if(e==="$autocapture"){const h=this.processAutocaptureAttributes(t||{});a.autocapture_attributes=h}else e!=="user_identify"&&e!=="group"&&(Array.isArray(this.config.propertyBlacklist)&&this.config.propertyBlacklist.forEach(h=>{delete l[h]}),a.event_attributes=l);return u()&&(a.referer=document.referrer,a.url=window.location.href,a.page_title=document.title,a.doc_path=window.location.pathname,a.doc_host=window.location.hostname,a.doc_search=window.location.search,a.screen_resolution=`${window.screen.width}x${window.screen.height}`,a.vp_size=`${window.innerWidth}x${window.innerHeight}`,a.user_agent=navigator.userAgent,a.user_language=navigator.language,a.doc_encoding=document.characterSet,a.utm=this.getUtmParams()),a}processAutocaptureAttributes(e){let t={};const s=e.$elements||[];return s.length&&(t={...s[0]}),t.el_text=t.$el_text||"",t.event_type=e.$event_type||"",["$ce_version","$event_type","$initial_referrer","$initial_referring_domain","$referrer","$referring_domain","$elements"].forEach(n=>{delete t[n]}),delete t.$el_text,delete t.nth_child,delete t.nth_of_type,t}getCookie(e){var t;return((t=this.cookieManager)==null?void 0:t.get(e))||null}getThirdPartyIds(){const e={};if(u()){const t=this.getCookie("_fbp");t&&(e.fbp=t)}return e}getUtmParams(){const e={},t=ce(window.location.search);return["utm_source","utm_medium","utm_campaign","utm_term","utm_content"].forEach(n=>{t[n]&&(e[n.replace("utm_","")]=t[n])}),e}pageview(){u()?this.track("pageview",{url:window.location.href,referrer:document.referrer,title:document.title},!0):this.logger.warn("Pageview tracking is not available in server-side environments")}setupPageLeaveTracking(){if(!u())return;let e=!1,t=!1;const s=()=>{!e&&!t&&(e=!0,this.track("$pageleave",{url:window.location.href,referrer:document.referrer,title:document.title}))};window.addEventListener("beforeunload",r=>{t=!0,setTimeout(()=>{t=!1},100)}),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&!t&&s()});const n=history.pushState;history.pushState=function(){return s(),n.apply(this,arguments)},window.addEventListener("popstate",s)}getConfig(){return this.config}getLogger(){return this.logger}async reset(e=!1){if(this.persistence.clear(),e&&this.cookieManager){const t=this.config.cookieName||`__eventn_id_${this.config.key}`;this.cookieManager.delete(t),this.anonymousId=this.getOrCreateAnonymousId()}this.logger.info("core state reset",{resetAnonId:e,namespace:this.namespace})}set(e,t){if(!_(e))throw new Error("Properties must be an object");const s=t==null?void 0:t.eventType,n=(t==null?void 0:t.persist)??!0;if(s){let r=this.persistence.get(`props_${s}`)||{};r={...r,...e},this.persistence.set(`props_${s}`,r)}else{let r=this.persistence.get("global_props")||{};r={...r,...e},this.persistence.set("global_props",r)}n&&this.persistence.save(),this.logger.debug("Properties set",{properties:e,eventType:s||"global",persist:n})}setUserId(e){this.persistence.set("userId",e);let t=this.persistence.get("userProps")||{};t.id=e,this.persistence.set("userProps",t),this.persistence.save()}unset(e,t){const s=t==null?void 0:t.eventType,n=(t==null?void 0:t.persist)??!0;if(s){let r=this.persistence.get(`props_${s}`)||{};delete r[e],this.persistence.set(`props_${s}`,r)}else{let r=this.persistence.get("global_props")||{};delete r[e],this.persistence.set("global_props",r)}n&&this.persistence.save(),this.logger.debug(`Property unset: ${e}`,`Event type: ${s||"global"}`)}}function W(i){const e=JSON.parse(JSON.stringify(i)),t=H(e),s={...L,...t};if(!s.key)throw new Error("API key is required!");if(!s.trackingHost)throw new Error("Tracking host is required!");return new Q(s)}function ye(i){var n;const e={key:i.getAttribute("data-key")||void 0,trackingHost:i.getAttribute("data-tracking-host")||"https://events.usermaven.com",logLevel:le(i.getAttribute("data-log-level")),autocapture:i.getAttribute("data-autocapture")==="true",formTracking:i.getAttribute("data-form-tracking")==="false"?!1:i.getAttribute("data-form-tracking")==="true"?"all":i.getAttribute("data-form-tracking"),autoPageview:i.getAttribute("data-auto-pageview")==="true",useBeaconApi:i.getAttribute("data-use-beacon-api")==="true",forceUseFetch:i.getAttribute("data-force-use-fetch")==="true",gaHook:i.getAttribute("data-ga-hook")==="true",segmentHook:i.getAttribute("data-segment-hook")==="true",randomizeUrl:i.getAttribute("data-randomize-url")==="true",capture3rdPartyCookies:i.getAttribute("data-capture-3rd-party-cookies")==="false"?!1:void 0,idMethod:i.getAttribute("data-id-method")||void 0,privacyPolicy:i.getAttribute("data-privacy-policy")==="strict"?"strict":void 0,ipPolicy:i.getAttribute("data-ip-policy")||void 0,cookiePolicy:i.getAttribute("data-cookie-policy")||void 0,minSendTimeout:parseInt(i.getAttribute("data-min-send-timeout")||"",10)||void 0,maxSendTimeout:parseInt(i.getAttribute("data-max-send-timeout")||"",10)||void 0,maxSendAttempts:parseInt(i.getAttribute("data-max-send-attempts")||"",10)||void 0,propertiesStringMaxLength:parseInt(i.getAttribute("data-properties-string-max-length")||"",10)||null,propertyBlacklist:((n=i.getAttribute("data-property-blacklist"))==null?void 0:n.split(","))||void 0,exclude:i.getAttribute("data-exclude")||void 0,namespace:i.getAttribute("data-namespace")||void 0,crossDomainLinking:i.getAttribute("data-cross-domain-linking")!=="false",domains:i.getAttribute("data-domains")||void 0,maskAllText:i.getAttribute("data-mask-all-text")==="true",maskAllElementAttributes:i.getAttribute("data-mask-all-element-attributes")==="true"},t=W(e),s=e.namespace||"usermaven";u()&&t.pageview(),we(s,t)}function we(i,e){let t=!1;const s=[],n=[];function r(){for(;s.length>0;){const a=s.shift();a&&window[i].apply(null,a)}}function o(){n.forEach(a=>a()),n.length=0}window[i]=function(...a){const h=a[0];if(h==="onLoad"){typeof a[1]=="function"&&(t?a[1]():n.push(a[1]));return}if(!t){s.push(a);return}if(typeof e[h]=="function")return e[h].apply(e,a.slice(1));console.error(`Method ${h} not found on UsermavenClient`)};const c=`${i}Q`,l=window[c]||[];for(window[c]=l,l.push=function(...a){return window[i].apply(null,a),Array.prototype.push.apply(this,a)},setTimeout(()=>{t=!0,r(),o(),console.log(`Usermaven client for namespace ${i} is ready`)},0);l.length>0;){const a=l.shift();a&&s.push(a)}}u()&&function(i,e){const t=i.currentScript;function s(){t&&t.src.includes("lib.js")&&ye(t)}typeof e<"u"&&(i.readyState==="loading"?i.addEventListener("DOMContentLoaded",s):s())}(document,window),f.LogLevel=g,f.UsermavenClient=Q,f.usermavenClient=W,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1,13 @@
1
+ import { Logger } from '../utils/logger';
2
+ export declare class LocalStoragePersistence {
3
+ private storage;
4
+ private prefix;
5
+ private logger;
6
+ constructor(apiKey: string, logger?: Logger);
7
+ set(key: string, value: any): void;
8
+ get(key: string): any;
9
+ remove(key: string): void;
10
+ clear(): void;
11
+ save(): void;
12
+ private load;
13
+ }
@@ -0,0 +1,8 @@
1
+ export declare class MemoryPersistence {
2
+ private storage;
3
+ set(key: string, value: any): void;
4
+ get(key: string): any;
5
+ remove(key: string): void;
6
+ save(): void;
7
+ clear(): void;
8
+ }
@@ -0,0 +1,25 @@
1
+ import { UsermavenClient } from '../core/client';
2
+ import { Config } from '../core/types';
3
+ declare class AutoCapture {
4
+ private logger;
5
+ private client;
6
+ private options;
7
+ private scrollDepth;
8
+ private customProperties;
9
+ static readonly FORCE_CAPTURE_ATTR = "data-um-force-capture";
10
+ static readonly PREVENT_CAPTURE_ATTR = "data-um-no-capture";
11
+ constructor(client: UsermavenClient, options: Config, logger?: import('../utils/logger').Logger);
12
+ init(): void;
13
+ private addDomEventHandlers;
14
+ private isPageRefresh;
15
+ private captureEvent;
16
+ private getCustomProperties;
17
+ private extractCustomPropertyValue;
18
+ private getEventTarget;
19
+ private getPropertiesFromElement;
20
+ private previousElementSibling;
21
+ private getDefaultProperties;
22
+ private encodeHtml;
23
+ static enabledForProject(token: string, numBuckets?: number, numEnabledBuckets?: number): boolean;
24
+ }
25
+ export default AutoCapture;
@@ -0,0 +1,27 @@
1
+ import { UsermavenClient } from '../core/client';
2
+ export default class FormTracking {
3
+ private instance;
4
+ private formElements?;
5
+ private trackingType;
6
+ private options;
7
+ private static instance;
8
+ private constructor();
9
+ private initialize;
10
+ private setupFormTracking;
11
+ private handleFormSubmit;
12
+ private trackFieldChanges;
13
+ static getInstance(instance: UsermavenClient, trackingType?: 'all' | 'tagged' | 'none', options?: FormTrackingOptions): FormTracking;
14
+ private _getFormDetails;
15
+ private _getFieldProps;
16
+ private _getElementAttributes;
17
+ private getSafeText;
18
+ private _scrubPotentiallySensitiveValues;
19
+ private _shouldCaptureValue;
20
+ private _isNullish;
21
+ private _isString;
22
+ private _trim;
23
+ }
24
+ interface FormTrackingOptions {
25
+ trackFieldChanges?: boolean;
26
+ }
27
+ export {};
@@ -0,0 +1,11 @@
1
+ import { UsermavenClient } from '../core/client';
2
+ export declare class PageviewTracking {
3
+ private client;
4
+ private lastPageUrl;
5
+ constructor(client: UsermavenClient);
6
+ private trackInitialPageview;
7
+ private initializePageviewTracking;
8
+ private handlePageview;
9
+ private checkForUrlChange;
10
+ private trackPageview;
11
+ }
@@ -0,0 +1,9 @@
1
+ import { Transport, Config } from '../core/types';
2
+ export declare class BeaconTransport implements Transport {
3
+ private trackingHost;
4
+ private logger;
5
+ private config;
6
+ constructor(trackingHost: string, config: Config, logger?: import('../utils/logger').Logger);
7
+ send(payloads: any[]): Promise<void>;
8
+ private constructUrl;
9
+ }
@@ -0,0 +1,12 @@
1
+ import { Transport, Config } from '../core/types';
2
+ import { Logger } from '../utils/logger';
3
+ export declare class FetchTransport implements Transport {
4
+ private trackingHost;
5
+ private logger;
6
+ private config;
7
+ constructor(trackingHost: string, config: Config, logger?: Logger);
8
+ send(payloads: any[]): Promise<void>;
9
+ private constructUrl;
10
+ private getCustomHeaders;
11
+ private postHandle;
12
+ }
@@ -0,0 +1,10 @@
1
+ import { Transport, Config } from '../core/types';
2
+ export declare class HttpsTransport implements Transport {
3
+ private trackingHost;
4
+ private logger;
5
+ private config;
6
+ constructor(trackingHost: string, config: Config, logger?: import('../utils/logger').Logger);
7
+ send(payloads: any[]): Promise<void>;
8
+ private constructUrl;
9
+ private getCustomHeaders;
10
+ }
@@ -0,0 +1,3 @@
1
+ export interface Transport {
2
+ send(payload: any | any[]): Promise<void>;
3
+ }