@sensorswave/js-sdk 1.4.0 → 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 +122 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/types/Api.d.ts +19 -0
- package/dist/types/web/src/basic/element-info.d.ts +1 -0
- package/dist/types/web/src/index.d.ts +3 -1
- package/dist/types/web/src/plugins/exposure.d.ts +42 -0
- package/dist/types/web/src/utils/exposure.d.ts +22 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,6 +58,8 @@ SensorsWave.trackEvent('ButtonClick', {
|
|
|
58
58
|
| abRefreshInterval | number | 600000 (10 minutes) | The interval in milliseconds for refreshing A/B test configuration |
|
|
59
59
|
| enableErrorTrack | boolean | false | Whether to automatically capture error-level exceptions (`$Exception`): uncaught JS errors, unhandled promise rejections and resource load failures. Independent of `autoCapture`. Effective in web environment |
|
|
60
60
|
| enableCrashTrack | boolean | false | Whether to enable app crash tracking (fatal level). Only effective in app host environments (iOS/Android/HarmonyOS WebView); NOT effective in this pure web SDK (the option is reserved to keep one unified config spec across SDKs) |
|
|
61
|
+
| enableExposureTrack | boolean | false | Whether to enable element exposure tracking. Elements are registered declaratively via `data-sw-exposure-*` attributes or programmatically via `addExposureView()`. Requires `IntersectionObserver` + `MutationObserver` (unsupported browsers silently skip initialization). Independent of `autoCapture` |
|
|
62
|
+
| exposureConfig | object | `{ visibleRatio: 0, stayDuration: 0, repeated: true }` | Global exposure defaults: `visibleRatio` (visible-area ratio, 0–1), `stayDuration` (seconds of continuous visibility), `repeated` (re-expose on re-entry). Lowest precedence — can be overridden per element |
|
|
61
63
|
| batchSend | boolean | false | Whether to use batch sending (sends events in batches up to 10 events every 5 seconds) |
|
|
62
64
|
| anonId | string | '' | User-provided anonymous ID. When set, it overrides the SDK-generated anonymous ID and persists locally (cookie), so it is reused on subsequent visits even if not passed again |
|
|
63
65
|
|
|
@@ -135,6 +137,45 @@ try {
|
|
|
135
137
|
}
|
|
136
138
|
```
|
|
137
139
|
|
|
140
|
+
#### addExposureView
|
|
141
|
+
|
|
142
|
+
Register an element for exposure tracking. The event name is supplied by the caller (required) — there is no preset exposure event name.
|
|
143
|
+
|
|
144
|
+
Only effective when `enableExposureTrack: true` was set in `init()` (and the consent guard passes: SDK initialized and not opted out). See [Exposure Tracking](#exposure-tracking) for the full trigger algorithm and declarative alternative.
|
|
145
|
+
|
|
146
|
+
**Parameters:**
|
|
147
|
+
- `ele` (HTMLElement, required): The element to watch
|
|
148
|
+
- `option` (Object, required):
|
|
149
|
+
- `eventName` (string, required): The exposure event name
|
|
150
|
+
- `config` (Object, optional): Per-element exposure config — `visibleRatio` (0–1), `stayDuration` (seconds), `repeated` (boolean). Keys not specified fall back to the existing registration / global `exposureConfig` / built-in defaults
|
|
151
|
+
- `properties` (Object, optional): Custom properties attached to the exposure event. May override the `$element_*` properties of the same name
|
|
152
|
+
- `listener` (Object, optional): `shouldExpose(ele, props)` — return `false` to skip this exposure; `didExpose(ele, props)` — called after the event is sent
|
|
153
|
+
|
|
154
|
+
**Example:**
|
|
155
|
+
```javascript
|
|
156
|
+
SensorsWave.addExposureView(document.getElementById('banner'), {
|
|
157
|
+
eventName: 'home_top_banner',
|
|
158
|
+
config: { visibleRatio: 0.5, stayDuration: 2, repeated: true },
|
|
159
|
+
properties: { position: 'top' },
|
|
160
|
+
listener: {
|
|
161
|
+
shouldExpose: function (ele, props) { return true; },
|
|
162
|
+
didExpose: function (ele, props) { console.log('exposed', props); }
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### removeExposureView
|
|
168
|
+
|
|
169
|
+
Remove an element's exposure listener and cancel any pending dwell timer.
|
|
170
|
+
|
|
171
|
+
**Parameters:**
|
|
172
|
+
- `ele` (HTMLElement, required): The element to unregister
|
|
173
|
+
|
|
174
|
+
**Example:**
|
|
175
|
+
```javascript
|
|
176
|
+
SensorsWave.removeExposureView(document.getElementById('banner'));
|
|
177
|
+
```
|
|
178
|
+
|
|
138
179
|
### User Profile
|
|
139
180
|
|
|
140
181
|
#### profileSet
|
|
@@ -522,6 +563,86 @@ Notes:
|
|
|
522
563
|
- No collapsing or char-length truncation — the 30-frame parse limit bounds the payload, each frame is kept individually
|
|
523
564
|
- Synthetic frames (no `Error` object, e.g. cross-origin `"Script error."` built from `filename:lineno:colno`) are also emitted as a single-element array
|
|
524
565
|
|
|
566
|
+
## Exposure Tracking
|
|
567
|
+
|
|
568
|
+
The SDK can report an event when an element has been continuously visible in the viewport for a configured ratio and duration. Enable it with `enableExposureTrack: true` in `init()`.
|
|
569
|
+
|
|
570
|
+
- The event name is supplied by the caller (required) — exposure events are custom events, not preset `$`-events
|
|
571
|
+
- Requires `IntersectionObserver` + `MutationObserver`; in unsupported browsers the feature silently skips initialization
|
|
572
|
+
- Dwell time does not accumulate while the tab is in the background (visibility is paused on `hidden`, resumed on `visible`)
|
|
573
|
+
- In SPAs (`isSinglePageApp: true`), declarative registrations are re-scanned on each route change, while elements registered via `addExposureView()` are preserved
|
|
574
|
+
|
|
575
|
+
### Registration
|
|
576
|
+
|
|
577
|
+
Three ways to register elements (they can be combined):
|
|
578
|
+
|
|
579
|
+
1. **Global defaults** — pass `exposureConfig` in `init()`:
|
|
580
|
+
|
|
581
|
+
```javascript
|
|
582
|
+
SensorsWave.init('your-source-token', {
|
|
583
|
+
apiHost: 'https://your-api-host',
|
|
584
|
+
enableExposureTrack: true,
|
|
585
|
+
exposureConfig: { visibleRatio: 0, stayDuration: 2, repeated: true }
|
|
586
|
+
});
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
2. **Declarative attributes** — mark elements with `data-sw-exposure-*` attributes; they are auto-discovered on page load, on SPA route changes and whenever the DOM changes:
|
|
590
|
+
|
|
591
|
+
```html
|
|
592
|
+
<div
|
|
593
|
+
data-sw-exposure-event-name="home_top_banner"
|
|
594
|
+
data-sw-exposure-config-visible-ratio="0.5"
|
|
595
|
+
data-sw-exposure-config-stay-duration="2"
|
|
596
|
+
data-sw-exposure-config-repeated="true"
|
|
597
|
+
data-sw-exposure-property-position="top"
|
|
598
|
+
></div>
|
|
599
|
+
|
|
600
|
+
<!-- Or set everything in one JSON attribute (lower precedence than the individual attributes); config keys are camelCase -->
|
|
601
|
+
<div
|
|
602
|
+
data-sw-exposure-event-name="promo_card"
|
|
603
|
+
data-sw-exposure-option='{"config":{"visibleRatio":0.8},"properties":{"slot":"card"}}'
|
|
604
|
+
></div>
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
| Attribute | Required | Description |
|
|
608
|
+
|-----------|----------|-------------|
|
|
609
|
+
| data-sw-exposure-event-name | yes | The exposure event name (must be non-empty) |
|
|
610
|
+
| data-sw-exposure-config-visible-ratio | no | Visible-area ratio, `0`–`1` |
|
|
611
|
+
| data-sw-exposure-config-stay-duration | no | Required continuous-visibility duration in seconds |
|
|
612
|
+
| data-sw-exposure-config-repeated | no | `"true"` / `"false"` — whether re-entry re-triggers |
|
|
613
|
+
| data-sw-exposure-property-* | no | Custom property for this element's exposure event. Values are strings. Note: HTML lowercases attribute names, so `data-sw-exposure-property-BannerType` yields the property key `bannertype` — use lowercase / kebab-case keys |
|
|
614
|
+
| data-sw-exposure-option | no | JSON `{ "config": {...}, "properties": {...} }` — a single-attribute alternative with lower precedence than the individual attributes |
|
|
615
|
+
|
|
616
|
+
3. **JS API** — `addExposureView()` / `removeExposureView()` (see [addExposureView](#addexposureview)).
|
|
617
|
+
|
|
618
|
+
Config precedence (highest → lowest): element individual attributes → element `data-sw-exposure-option` → `addExposureView` config → global `exposureConfig` → built-in defaults (`{ visibleRatio: 0, stayDuration: 0, repeated: true }`). Config keys are camelCase in both JS and the option JSON; the individual `data-sw-exposure-config-*` attributes use kebab-case (HTML lowercases attribute names, so camelCase attribute names cannot be read back).
|
|
619
|
+
|
|
620
|
+
### Trigger Algorithm
|
|
621
|
+
|
|
622
|
+
For each registered element, an `IntersectionObserver` (viewport root, `threshold = visibleRatio`, one observer instance per distinct `visibleRatio`) drives the following:
|
|
623
|
+
|
|
624
|
+
1. The element enters the viewport with `intersectionRatio >= visibleRatio` → a dwell timer of `stayDuration` seconds starts. Leaving the viewport cancels the timer, so `stayDuration` means *continuous* visibility. Timers never start while the page is in a hidden tab (background tabs are ignored until they become visible)
|
|
625
|
+
2. When the timer fires, the SDK re-validates the element (non-zero size, still attached to the document, not opted out) and consults `shouldExpose`
|
|
626
|
+
3. The event is sent with the `$element_*` properties plus custom properties, then `didExpose` runs
|
|
627
|
+
4. `repeated: true` re-arms immediately: the element re-exposes when it leaves and re-enters the viewport (not on a timer). `repeated: false` exposes once per registration
|
|
628
|
+
|
|
629
|
+
> Note: `visibleRatio` must be achievable — an element taller than the viewport can never be more than `viewport height / element height` visible, so an `visibleRatio` close to `1` will never trigger for tall elements.
|
|
630
|
+
|
|
631
|
+
### Exposure Event Properties
|
|
632
|
+
|
|
633
|
+
| Property | Description |
|
|
634
|
+
|----------|-------------|
|
|
635
|
+
| $element_type | Tag name, lowercased |
|
|
636
|
+
| $element_name | `name` attribute |
|
|
637
|
+
| $element_id | `id` attribute |
|
|
638
|
+
| $element_class_name | `class` attribute |
|
|
639
|
+
| $element_target_url | `href` attribute |
|
|
640
|
+
| $element_content | Text content (255-char cap; `input` uses the value for button/submit types) |
|
|
641
|
+
| $element_selector | CSS-like selector chain |
|
|
642
|
+
| $element_path | DOM path chain |
|
|
643
|
+
|
|
644
|
+
Custom `properties` are merged on top and may override the `$element_*` properties of the same name. Note: exposure has no click context, so there are no `$page_x` / `$page_y` properties.
|
|
645
|
+
|
|
525
646
|
## Supported Event Types
|
|
526
647
|
|
|
527
648
|
The SDK automatically captures the following event types when `autoCapture` is enabled:
|
|
@@ -534,6 +655,7 @@ The SDK automatically captures the following event types when `autoCapture` is e
|
|
|
534
655
|
Additional automatic events:
|
|
535
656
|
|
|
536
657
|
- **Exception** (`$Exception`): Triggered when an error-level exception is captured — uncaught JS errors, unhandled promise rejections, and resource load failures (only when `enableErrorTrack` is true), or reported manually via `trackException()`
|
|
658
|
+
- **Exposure**: Triggered when a registered element has been continuously visible for `stayDuration` seconds at `visibleRatio` ratio (only when `enableExposureTrack` is true). The event name is supplied by the caller via `data-sw-exposure-event-name` or `addExposureView()` — it is not a preset event
|
|
537
659
|
|
|
538
660
|
Custom events can be tracked using the `trackEvent()` or `track()` methods.
|
|
539
661
|
|
package/dist/index.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";class t{constructor(){this.listeners={}}on(t,e,n=!1){if(t&&e){if(!s(e))throw new Error("listener must be a function");this.listeners[t]=this.listeners[t]||[],this.listeners[t].push({listener:e,once:n})}}off(t,e){const n=this.listeners[t];if(!n?.length)return;"number"==typeof e&&n.splice(e,1);const i=n.findIndex(t=>t.listener===e);-1!==i&&n.splice(i,1)}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((n,i)=>{n.listener.call(this,...e),n.listener.once&&this.off(t,i)})}once(t,e){this.on(t,e,!0)}removeAllListeners(t){t?this.listeners[t]=[]:this.listeners={}}}const e={get:function(t){const e=t+"=",n=document.cookie.split(";");for(let i=0,s=n.length;i<s;i++){let t=n[i];for(;" "==t.charAt(0);)t=t.substring(1,t.length);if(0==t.indexOf(e))return h(t.substring(e.length,t.length))}return null},set:function({name:t,value:e,expires:n,samesite:i,secure:s,domain:r}){let o="",a="",c="",u="";if(0!==(n=null==n||void 0===n?365:n)){const t=new Date;"s"===String(n).slice(-1)?t.setTime(t.getTime()+1e3*Number(String(n).slice(0,-1))):t.setTime(t.getTime()+24*n*60*60*1e3),o="; expires="+t.toUTCString()}function l(t){return t?t.replace(/\r\n/g,""):""}i&&(c="; SameSite="+i),s&&(a="; secure");const h=l(t),d=l(e),p=l(r);p&&(u="; domain="+p),h&&d&&(document.cookie=h+"="+encodeURIComponent(d)+o+"; path=/"+u+c+a)},remove:function(t){this.set({name:t,value:"",expires:-1})},isSupport:function({samesite:t,secure:e}={}){if(!navigator.cookieEnabled)return!1;const n="sensorswave_cookie_support_test";return this.set({name:n,value:"1",samesite:t,secure:e}),"1"===this.get(n)&&(this.remove(n),!0)}},n=Object.prototype.toString;function i(t){return"[object Object]"===n.call(t)}function s(t){const e=n.call(t);return"[object Function]"==e||"[object AsyncFunction]"==e}function r(t){return"[object Array]"==n.call(t)}function o(t){return"[object String]"==n.call(t)}function a(t){return void 0===t}const c=Object.prototype.hasOwnProperty;function u(t){if(i(t)){for(let e in t)if(c.call(t,e))return!1;return!0}return!1}function l(t){return!(!t||1!==t.nodeType)}function h(t){let e=t;try{e=decodeURIComponent(t)}catch(n){e=t}return e}function d(t){try{return JSON.parse(t)}catch(e){return""}}const p=function(){let t=Date.now();return function(e){return Math.ceil((t=(9301*t+49297)%233280,t/233280*e))}}();function g(){if("function"==typeof Uint32Array){let t;if("undefined"!=typeof crypto&&(t=crypto),t&&i(t)&&t.getRandomValues)return t.getRandomValues(new Uint32Array(1))[0]/Math.pow(2,32)}return p(1e19)/1e19}const f=function(){function t(t){return("0".repeat(t)+Date.now().toString(16)).slice(-t)}return function(){let e=String(screen.height*screen.width);e=e&&/\d{4,}/.test(e)?e.slice(-4):String(31242*g()).replace(".","").slice(0,4);return t(8)+"-"+g().toString(16).replace(".","").slice(-4)+"-"+function(){const t=navigator.userAgent;let e,n=[],i=0;function s(t,e){let i=0;for(let s=0;s<e.length;s++)i|=n[s]<<8*s;return(t^i)>>>0}for(let r=0;r<t.length;r++)e=t.charCodeAt(r),n.unshift(255&e),n.length>=4&&(i=s(i,n),n=[]);return n.length>0&&(i=s(i,n)),("0000"+i.toString(16)).slice(-4)}()+"-"+e+"-"+t(12)||(String(g())+String(g())+String(g())).slice(2,15)}}();function m(t,e){e&&"string"==typeof e||(e="");let n=null;try{n=new URL(t).hostname}catch(i){}return n||e}function E(t){let e=[];try{e=atob(t).split("").map(function(t){return"%"+("00"+t.charCodeAt(0).toString(16)).slice(-2)})}catch(n){e=[]}try{return decodeURIComponent(e.join(""))}catch(n){return e.join("")}}function _(t){let e="";try{e=btoa(encodeURIComponent(t).replace(/%([0-9A-F]{2})/g,function(t,e){return String.fromCharCode(parseInt(e,16))}))}catch(n){e=t}return e}const I={get:function(t){return window.localStorage.getItem(t)},parse:function(t){let e;try{e=JSON.parse(I.get(t))||null}catch(n){console.warn(n)}return e},set:function(t,e){try{window.localStorage.setItem(t,e)}catch(n){console.warn(n)}},remove:function(t){window.localStorage.removeItem(t)},isSupport:function(){let t=!0;try{const e="__local_store_support__",n="testIsSupportStorage";I.set(e,n),I.get(e)!==n&&(t=!1),I.remove(e)}catch(e){t=!1}return t}};function S(t){return t.trim()}function w(t){if(!t||"string"!=typeof t)return"";try{return new URL(t,window.location.origin).pathname}catch(e){return""}}const O={},v="1.4.0",b="init-ready",y="spa-switch",A="ff-ready",R="$PageLeave",T="$Exception";var C=(t=>(t[t.FEATURE_GATE=1]="FEATURE_GATE",t[t.FEATURE_CONFIG=2]="FEATURE_CONFIG",t[t.EXPERIMENT=3]="EXPERIMENT",t))(C||{});const N={crossSubdomain:!1,requests:[],_sessionState:{},_abData:[],_trace_id:"",commonProps:{},_state:{anon_id:"",login_id:"",identities:{}},getIdentityCookieID(){return this._state.identities?.$identity_cookie_id||""},getCommonProps:function(){return this.commonProps||{}},setCommonProps:function(t){this.commonProps=t},getAnonId(){return this._state.anon_id||this.getIdentityCookieID()||f()},getLoginId(){return this._state.login_id},getTraceId(){return this._trace_id||f()},set:function(t,e){this._state[t]=e,this.save()},getCookieName:function(){return"sensorswave2025jssdkcross"},getABLSName:function(){return"sensorswave2025jssdkablatest"},save:function(){let t=JSON.parse(JSON.stringify(this._state));t.identities&&(t.identities=_(JSON.stringify(t.identities)));const n=JSON.stringify(t);e.set({name:this.getCookieName(),value:n,expires:365})},init:function(t){let n,s;this.crossSubdomain=t,e.isSupport()&&(n=e.get(this.getCookieName()),s=d(n)),N._state={...s||{}},N._state.identities&&(N._state.identities=d(E(N._state.identities))),N._state.identities&&i(N._state.identities)&&!u(N._state.identities)||(N._state.identities={$identity_cookie_id:f()}),N.save()},setLoginId(t){"number"==typeof t&&(t=String(t)),void 0!==t&&t&&(N.set("login_id",t),N.save())},clearLoginId(){this._state.login_id="",this.save()},resetAnonId(){this._state.anon_id="",this._state.identities={$identity_cookie_id:f()},this.save()},setAnonId(t){"number"==typeof t&&(t=String(t)),"string"==typeof t&&t?(N.set("anon_id",t),N.save()):console.warn("[SensorsWave store] Invalid anonId, ignored:",t)},saveABData(t){if(!t||u(t))return;this._abData=t;let e=JSON.parse(JSON.stringify(this._abData));e=_(JSON.stringify(e));try{localStorage.setItem(this.getABLSName(),JSON.stringify({time:Date.now(),data:e,anon_id:this.getAnonId(),login_id:this.getLoginId()}))}catch(n){console.warn("Failed to save abdata to localStorage",n)}},getABData(t=6e5){try{let e=localStorage.getItem(this.getABLSName());if(e){const{time:n,data:i,login_id:s,anon_id:r}=d(e)||{};if(n&&i&&Date.now()-n<t&&r===this.getAnonId()&&(!s||s===this.getLoginId())){const t=d(E(i));return this._abData=Array.isArray(t)?t:[],this._abData}localStorage.removeItem(this.getABLSName())}}catch(e){this._abData=[]}return this._abData||[]}};function P(t){return!(t>=400&&t<500)||408===t||429===t}function k(t){var e;if(t.data)return{contentType:"application/json",body:(e=t.data,JSON.stringify(e,(t,e)=>"bigint"==typeof e?e.toString():e,undefined))}}const L=[];function $(t){const e={...t};e.timeout=e.timeout||6e4;const n=e.transport??"fetch",i=L.find(t=>t.transport===n)?.method??L[0]?.method;if(!i)throw new Error("No available transport method for HTTP request");i(e)}function F(t){return o(t=t||document.referrer)&&(t=h(t=t.trim()))||""}function B(t){const e=m(t=t||F());if(!e)return"";const n={baidu:[/^.*\.baidu\.com$/],bing:[/^.*\.bing\.com$/],google:[/^www\.google\.com$/,/^www\.google\.com\.[a-z]{2}$/,/^www\.google\.[a-z]{2}$/],sm:[/^m\.sm\.cn$/],so:[/^.+\.so\.com$/],sogou:[/^.*\.sogou\.com$/],yahoo:[/^.*\.yahoo\.com$/],duckduckgo:[/^.*\.duckduckgo\.com$/]};for(let i of Object.keys(n)){let t=n[i];for(let n=0,s=t.length;n<s;n++)if(t[n].test(e))return i}return""}function x(t,e){return-1!==t.indexOf(e)}"function"==typeof fetch&&L.push({transport:"fetch",method:function(t){if("undefined"==typeof fetch)return void console.error("fetch API is not available");const e=k(t),n=new Headers;t.headers&&Object.keys(t.headers).forEach(e=>{n.append(e,t.headers[e])}),e?.contentType&&n.append("Content-Type",e.contentType),fetch(t.url,{method:t.method||"GET",headers:n,body:e?.body}).then(e=>e.text().then(n=>{const i={statusCode:e.status,text:n};if(200===e.status)try{i.json=JSON.parse(n)}catch(s){console.error("Failed to parse response:",s)}t.callback?.(i)})).catch(e=>{console.error("Request failed:",e),t.callback?.({statusCode:0,text:String(e)})})}}),"undefined"!=typeof XMLHttpRequest&&L.push({transport:"XHR",method:function(t){if("undefined"==typeof XMLHttpRequest)return void console.error("XMLHttpRequest is not available");const e=new XMLHttpRequest;e.open(t.method||"GET",t.url,!0);const n=k(t);t.headers&&Object.keys(t.headers).forEach(n=>{e.setRequestHeader(n,t.headers[n])}),n?.contentType&&e.setRequestHeader("Content-Type",n.contentType),e.timeout=t.timeout||6e4,e.withCredentials=!0,e.onreadystatechange=()=>{if(4===e.readyState){const i={statusCode:e.status,text:e.responseText};if(200===e.status)try{i.json=JSON.parse(e.responseText)}catch(n){console.error("Failed to parse JSON response:",n)}t.callback?.(i)}},e.send(n?.body)}});const M={FACEBOOK:"Facebook",MOBILE:"Mobile",IOS:"iOS",ANDROID:"Android",TABLET:"Tablet",ANDROID_TABLET:"Android Tablet",IPAD:"iPad",APPLE:"Apple",APPLE_WATCH:"Apple Watch",SAFARI:"Safari",BLACKBERRY:"BlackBerry",SAMSUNG_BROWSER:"SamsungBrowser",SAMSUNG_INTERNET:"Samsung Internet",CHROME:"Chrome",CHROME_OS:"Chrome OS",CHROME_IOS:"Chrome iOS",INTERNET_EXPLORER:"Internet Explorer",INTERNET_EXPLORER_MOBILE:"Internet Explorer Mobile",OPERA:"Opera",OPERA_MINI:"Opera Mini",EDGE:"Edge",MICROSOFT_EDGE:"Microsoft Edge",FIREFOX:"Firefox",FIREFOX_IOS:"Firefox iOS",NINTENDO:"Nintendo",PLAYSTATION:"PlayStation",XBOX:"Xbox",ANDROID_MOBILE:"Android Mobile",MOBILE_SAFARI:"Mobile Safari",WINDOWS:"Windows",WINDOWS_PHONE:"Windows Phone",NOKIA:"Nokia",OUYA:"Ouya",GENERIC_MOBILE:"Generic mobile",GENERIC_TABLET:"Generic tablet",KONQUEROR:"Konqueror",UC_BROWSER:"UC Browser",HUAWEI:"Huawei",XIAOMI:"Xiaomi",OPPO:"OPPO",VIVO:"vivo"},D="(\\d+(\\.\\d+)?)",H=new RegExp("Version/"+D),U=new RegExp(M.XBOX,"i"),X=new RegExp(M.PLAYSTATION+" \\w+","i"),j=new RegExp(M.NINTENDO+" \\w+","i"),q=new RegExp(M.BLACKBERRY+"|PlayBook|BB10","i"),W=new RegExp("(HUAWEI|honor|HONOR)","i"),G=new RegExp("(Xiaomi|Redmi)","i"),z=new RegExp("(OPPO|realme)","i"),Y=new RegExp("(vivo|IQOO)","i"),K={"NT3.51":"NT 3.11","NT4.0":"NT 4.0","5.0":"2000",5.1:"XP",5.2:"XP","6.0":"Vista",6.1:"7",6.2:"8",6.3:"8.1",6.4:"10","10.0":"10"};function J(t,e){return e=e||"",x(t," OPR/")&&x(t,"Mini")?M.OPERA_MINI:x(t," OPR/")?M.OPERA:q.test(t)?M.BLACKBERRY:x(t,"IE"+M.MOBILE)||x(t,"WPDesktop")?M.INTERNET_EXPLORER_MOBILE:x(t,M.SAMSUNG_BROWSER)?M.SAMSUNG_INTERNET:x(t,M.EDGE)||x(t,"Edg/")?M.MICROSOFT_EDGE:x(t,"FBIOS")?M.FACEBOOK+" "+M.MOBILE:x(t,"UCWEB")||x(t,"UCBrowser")?M.UC_BROWSER:x(t,"CriOS")?M.CHROME_IOS:x(t,"CrMo")||x(t,M.CHROME)?M.CHROME:x(t,M.ANDROID)&&x(t,M.SAFARI)?M.ANDROID_MOBILE:x(t,"FxiOS")?M.FIREFOX_IOS:x(t.toLowerCase(),M.KONQUEROR.toLowerCase())?M.KONQUEROR:function(t,e){return e&&x(e,M.APPLE)||x(n=t,M.SAFARI)&&!x(n,M.CHROME)&&!x(n,M.ANDROID);var n}(t,e)?x(t,M.MOBILE)?M.MOBILE_SAFARI:M.SAFARI:x(t,M.FIREFOX)?M.FIREFOX:x(t,"MSIE")||x(t,"Trident/")?M.INTERNET_EXPLORER:x(t,"Gecko")?M.FIREFOX:""}const Z={[M.INTERNET_EXPLORER_MOBILE]:[new RegExp("rv:"+D)],[M.MICROSOFT_EDGE]:[new RegExp(M.EDGE+"?\\/"+D)],[M.CHROME]:[new RegExp("("+M.CHROME+"|CrMo)\\/"+D)],[M.CHROME_IOS]:[new RegExp("CriOS\\/"+D)],[M.UC_BROWSER]:[new RegExp("(UCBrowser|UCWEB)\\/"+D)],[M.SAFARI]:[H],[M.MOBILE_SAFARI]:[H],[M.OPERA]:[new RegExp("("+M.OPERA+"|OPR)\\/"+D)],[M.FIREFOX]:[new RegExp(M.FIREFOX+"\\/"+D)],[M.FIREFOX_IOS]:[new RegExp("FxiOS\\/"+D)],[M.KONQUEROR]:[new RegExp("Konqueror[:/]?"+D,"i")],[M.BLACKBERRY]:[new RegExp(M.BLACKBERRY+" "+D),H],[M.ANDROID_MOBILE]:[new RegExp("android\\s"+D,"i")],[M.SAMSUNG_INTERNET]:[new RegExp(M.SAMSUNG_BROWSER+"\\/"+D)],[M.INTERNET_EXPLORER]:[new RegExp("(rv:|MSIE )"+D)],Mozilla:[new RegExp("rv:"+D)]};function Q(t,e){const n=J(t,e),i=Z[n];if(a(i))return null;for(let s=0;s<i.length;s++){const e=i[s],n=t.match(e);if(n)return parseFloat(n[n.length-2])}return null}const V=[[new RegExp(M.XBOX+"; "+M.XBOX+" (.*?)[);]","i"),t=>[M.XBOX,t&&t[1]||""]],[new RegExp(M.NINTENDO,"i"),[M.NINTENDO,""]],[new RegExp(M.PLAYSTATION,"i"),[M.PLAYSTATION,""]],[q,[M.BLACKBERRY,""]],[new RegExp(M.WINDOWS,"i"),(t,e)=>{if(/Phone/.test(e)||/WPDesktop/.test(e))return[M.WINDOWS_PHONE,""];if(new RegExp(M.MOBILE).test(e)&&!/IEMobile\b/.test(e))return[M.WINDOWS+" "+M.MOBILE,""];const n=/Windows NT ([0-9.]+)/i.exec(e);if(n&&n[1]){const t=n[1];let i=K[t]||"";return/arm/i.test(e)&&(i="RT"),[M.WINDOWS,i]}return[M.WINDOWS,""]}],[/((iPhone|iPad|iPod).*?OS (\d+)_(\d+)_?(\d+)?|iPhone)/,t=>{if(t&&t[3]){const e=[t[3],t[4],t[5]||"0"];return[M.IOS,e.join(".")]}return[M.IOS,""]}],[/(watch.*\/(\d+\.\d+\.\d+)|watch os,(\d+\.\d+),)/i,t=>{let e="";return t&&t.length>=3&&(e=a(t[2])?t[3]:t[2]),["watchOS",e]}],[new RegExp("("+M.ANDROID+" (\\d+)\\.(\\d+)\\.?(\\d+)?|"+M.ANDROID+")","i"),t=>{if(t&&t[2]){const e=[t[2],t[3],t[4]||"0"];return[M.ANDROID,e.join(".")]}return[M.ANDROID,""]}],[/Mac OS X (\d+)[_.](\d+)[_.]?(\d+)?/i,t=>{const e=["Mac OS X",""];if(t&&t[1]){const n=[t[1],t[2],t[3]||"0"];e[1]=n.join(".")}return e}],[/Mac/i,["Mac OS X",""]],[/CrOS/,[M.CHROME_OS,""]],[/Linux|debian/i,["Linux",""]]];function tt(){const t=window.innerHeight||document.documentElement.clientHeight||document.body&&document.body.clientHeight||0,e=window.innerWidth||document.documentElement.clientWidth||document.body&&document.body.clientWidth||0,n=navigator.userAgent,i=function(t){for(let e=0;e<V.length;e++){const[n,i]=V[e],s=n.exec(t),r=s&&("function"==typeof i?i(s,t):i);if(r)return r}return["",""]}(n)||["",""];return{$browser:J(n),$browser_version:Q(n),$url:location?.href.substring(0,1e3),$host:location?.host,$viewport_height:t,$viewport_width:e,$lib:"webjs",$lib_version:v,$search_engine:B(),$referrer:F(),$referrer_host:m(r=r||F()),$title:document.title,$language:navigator.language,$model:(s=n,(j.test(s)?M.NINTENDO:X.test(s)?M.PLAYSTATION:U.test(s)?M.XBOX:new RegExp(M.OUYA,"i").test(s)?M.OUYA:new RegExp("("+M.WINDOWS_PHONE+"|WPDesktop)","i").test(s)?M.WINDOWS_PHONE:/iPad/.test(s)?M.IPAD:/iPod/.test(s)?"iPod Touch":/iPhone/.test(s)?"iPhone":/(watch)(?: ?os[,/]|\d,\d\/)[\d.]+/i.test(s)?M.APPLE_WATCH:q.test(s)?M.BLACKBERRY:/(kobo)\s(ereader|touch)/i.test(s)?"Kobo":new RegExp(M.NOKIA,"i").test(s)?M.NOKIA:/(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i.test(s)||/(kf[a-z]+)( bui|\)).+silk\//i.test(s)?"Kindle Fire":W.test(s)?M.HUAWEI:G.test(s)?M.XIAOMI:z.test(s)?M.OPPO:Y.test(s)?M.VIVO:/(Android|ZTE)/i.test(s)?!new RegExp(M.MOBILE).test(s)||/(9138B|TB782B|Nexus [97]|pixel c|HUAWEISHT|BTV|noble nook|smart ultra 6)/i.test(s)?/pixel[\daxl ]{1,6}/i.test(s)&&!/pixel c/i.test(s)||/(huaweimed-al00|tah-|APA|SM-G92|i980|zte|U304AA)/i.test(s)||/lmy47v/i.test(s)&&!/QTAQZ3/i.test(s)?M.ANDROID:M.ANDROID_TABLET:M.ANDROID:new RegExp("(pda|"+M.MOBILE+")","i").test(s)?M.GENERIC_MOBILE:new RegExp(M.TABLET,"i").test(s)&&!new RegExp(M.TABLET+" pc","i").test(s)?M.GENERIC_TABLET:"")||""),$os:i?.[0]||"",$os_version:i?.[1]||"",$pathname:location?.pathname,$screen_height:Number(screen.height)||0,$screen_width:Number(screen.width)||0,$timezone_offset:60*-(new Date).getTimezoneOffset()};var s,r}const et=new class{constructor(){this.STORAGE_KEY="sensorswave_unsent_events",this.MAX_QUEUE_SIZE=200,this.MAX_RETRY_COUNT=1,this.MAX_AGE_MS=6048e5,this.queue=[],this.loadFromStorage(),this.cleanupExpiredItems()}loadFromStorage(){try{const t=localStorage.getItem(this.STORAGE_KEY);t&&(this.queue=d(t)||[])}catch(t){console.warn("Failed to load queue from localStorage:",t),this.queue=[]}}cleanupExpiredItems(){const t=Date.now(),e=this.queue.filter(e=>t-e.timestamp<this.MAX_AGE_MS);e.length!==this.queue.length&&(this.queue=e,this.saveToStorage())}saveToStorage(){try{this.cleanupExpiredItems(),this.queue.length>this.MAX_QUEUE_SIZE&&(this.queue=this.queue.slice(-this.MAX_QUEUE_SIZE)),localStorage.setItem(this.STORAGE_KEY,JSON.stringify(this.queue))}catch(t){console.warn("Failed to save queue to localStorage:",t)}}enqueue(t,e,n,i=this.MAX_RETRY_COUNT){try{const s={id:f(),url:t,data:e,headers:n,timestamp:Date.now(),retryCount:0,maxRetries:i};return this.queue.push(s),this.saveToStorage(),s.id}catch(s){return console.warn("Failed to enqueue request:",s),""}}dequeue(t){try{this.queue=this.queue.filter(e=>e.id!==t),this.saveToStorage()}catch(e){console.warn("Failed to dequeue request:",e)}}getAll(){try{return this.cleanupExpiredItems(),[...this.queue]}catch(t){return console.warn("Failed to get queue items:",t),[]}}incrementRetryCount(t){const e=this.queue.find(e=>e.id===t);return!(!e||e.retryCount>=e.maxRetries||(e.retryCount++,this.saveToStorage(),0))}clear(){this.queue=[];try{localStorage.removeItem(this.STORAGE_KEY)}catch(t){console.warn("Failed to clear queue from localStorage:",t)}}getItemById(t){return this.queue.find(e=>e.id===t)}};class nt{constructor(t={}){this.flushTimer=null,this.isFlushing=!1,this.paused=!1,this.destroyed=!1,this.config={maxBatchSize:t.maxBatchSize||20,flushInterval:t.flushInterval||5e3},this.startFlushTimer()}pause(){this.paused=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null)}resume(){this.paused&&(this.paused=!1,this.startFlushTimer())}isPaused(){return this.paused}add(){et.getAll().length>=this.config.maxBatchSize&&this.triggerFlush()}triggerFlush(){this.paused||this.isFlushing||(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.isFlushing=!0,this.flush())}flush(){const t=et.getAll();if(0===t.length)return this.isFlushing=!1,void this.startFlushTimer();const e=t.slice(0,this.config.maxBatchSize),n=[],i=[];e.forEach(t=>{Array.isArray(t.data)?n.push(...t.data):n.push(t.data),i.push(t.id)});const s=e[e.length-1],r=s.url,o=s.headers;O.instance&&O.instance.config.debug&&console.log(JSON.stringify(n,null,2)),$({url:r,method:"POST",data:n,headers:o,callback:t=>{200===t.statusCode?i.forEach(t=>{et.dequeue(t)}):P(t.statusCode)?console.error("Failed to send batch events:",t):i.forEach(t=>{et.dequeue(t)}),this.isFlushing=!1,this.startFlushTimer()}})}startFlushTimer(){this.destroyed||(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.flushTimer=setInterval(()=>{et.getAll().length>0&&this.triggerFlush()},this.config.flushInterval))}destroy(){this.destroyed=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.paused||this.flush()}}let it=null;function st(){const t=O.instance;return!(!t||!t.__innerInited)||(console.warn("[SensorsWave] SDK is not initialized. Please call init() first."),!1)}function rt(){const t=O.instance;return!t||"function"!=typeof t.hasOptedOutCapturing||!t.hasOptedOutCapturing()}let ot=null;function at(){return I.isSupport()?(ot||(it||(it=new nt({maxBatchSize:20,flushInterval:5e3})),ot=it),ot):null}function ct(t,e,n){if(rt())return $({url:t,method:"POST",data:e.data,headers:e.headers,callback:t=>{if(200!==t.statusCode){if(!P(t.statusCode))return void(n&&et.dequeue(n));if(n&&et.incrementRetryCount(n)){const t=et.getItemById(n);if(t){const e=Math.min(1e3*Math.pow(2,t.retryCount),3e4);setTimeout(()=>{ct(t.url,{data:t.data,headers:t.headers},t.id)},e)}}}else n&&et.dequeue(n),e.callback&&e.callback(t.json)}})}function ut(t){return`${t.apiHost}/in/track`}function lt(t){return`${t.apiHost}/ab/evalall`}function ht(t){return{"Content-Type":"application/json",SourceToken:t.sourceToken}}function dt(t,e,n){O.instance&&O.instance.config.debug&&console.log(JSON.stringify(e.data,null,2));const i=et.enqueue(t,e.data,e.headers);return ct(t,{...e,callback:void 0},i)}function pt(){try{const t=sessionStorage.getItem("sensorswave_utm");if(!t)return{};const e=JSON.parse(t),n={};return Object.entries(e).forEach(([t,e])=>{null!=e&&""!==e&&(n[`$${t}`]=e)}),n}catch(t){return{}}}function gt(t){const e={};return Object.entries(t).forEach(([t,n])=>{if("function"==typeof n)try{const i=n();e[t]=i}catch(i){console.warn("[SensorsWave] Failed to resolve dynamic property:",t,i)}else e[t]=n}),e}function ft(t={},e=!0){const n={...e?tt():{},...gt(N.getCommonProps()),...t},i=pt();return Object.keys(i).length>0&&Object.assign(n,i),n}function mt(t,e,n=!0){if(!st())return;if(!rt())return;const i={time:Date.now(),trace_id:N.getTraceId(),event:t.event,properties:ft(t.properties,n)},s=pt();Object.keys(s).length>0&&(i.user_properties||(i.user_properties={}),i.user_properties.$set||(i.user_properties.$set={}),Object.assign(i.user_properties.$set,s)),t.user_properties&&(t.user_properties.$set&&(i.user_properties=i.user_properties||{},i.user_properties.$set={...i.user_properties.$set||{},...t.user_properties.$set},delete t.user_properties.$set),i.user_properties={...i.user_properties,...t.user_properties});const r=N.getLoginId(),o=N.getAnonId();r&&(i.login_id=r),o&&(i.anon_id=o);const a=ut(e),c=ht(e),u=!1!==e.batchSend&&at();u?(et.enqueue(a,[i],c),u.add()):dt(a,{data:[i],headers:c})}function Et({userProps:t,opts:e}){if(!st())return;if(!rt())return;const n=N.getLoginId(),i=N.getAnonId();if(!n&&!i)return;const s={time:Date.now(),trace_id:N.getTraceId(),event:"$UserSet",login_id:n,anon_id:i,user_properties:t,properties:ft()},r=ut(e),o=ht(e),a=at();if(!a)return dt(r,{data:[s],headers:o});et.enqueue(r,[s],o),a.add()}function _t(t){return t.typ===C.FEATURE_GATE||t.typ===C.FEATURE_CONFIG?`$feature_${t.id}`:t.typ===C.EXPERIMENT?`$exp_${t.id}`:""}function It(t){const e=t.typ;return[C.FEATURE_GATE,C.EXPERIMENT,C.FEATURE_CONFIG].includes(e)?{[_t(t)]:t.vid}:{}}function St(t){const e=t.typ;return e===C.FEATURE_GATE||e===C.FEATURE_CONFIG?{$feature_key:t.key,$feature_variant:t.vid}:e===C.EXPERIMENT?{$exp_key:t.key,$exp_variant:t.vid}:{}}function wt({isUnset:t=!1,data:e,opts:n}){if(!st())return;if(!rt())return;if(!e||u(e)||e.disable_impress)return;const i=N.getLoginId(),s=N.getAnonId();if(!i&&!s)return;const r=e.typ===C.EXPERIMENT?"$ExpImpress":"$FeatureImpress";let o={};return o=t?{$unset:{[_t(e)]:null}}:{$set:{...It(e)}},mt({event:r,properties:St(e),user_properties:o},n)}const Ot="sensorswave_opt_out";class vt{constructor(t){this.persist=t}read(){if(this.persist)try{const t=I.get(Ot);return"0"===t||"1"!==t&&void 0}catch{return}}write(t){if(this.persist)try{I.set(Ot,t?"0":"1")}catch{}}}class bt{constructor({plugins:t,emitter:e,config:n,sdk:i}){this.plugins=[],this.pluginInsMap={},this.emitter=e,this.config=n,this.sdk=i,this.registerBuiltInPlugins(t),this.created(),this.emitter.on(b,()=>{this.init()})}registerBuiltInPlugins(t){for(let e=0,n=t.length;e<n;e++)this.registerPlugin(t[e])}registerPlugin(t){this.plugins.push(t)}getPlugins(){return this.plugins}getPlugin(t){return this.pluginInsMap[t]}created(){for(let t=0,e=this.plugins.length;t<e;t++){const e=this.plugins[t];if(!e.NAME)throw new Error('Plugin should be defined with "NAME"');const n=new e({emitter:this.emitter,config:this.config,sdk:this.sdk});this.pluginInsMap[e.NAME]=n}}init(){for(const t of Object.keys(this.pluginInsMap)){const e=this.pluginInsMap[t];e.init&&e.init()}}destroy(){for(const t of Object.keys(this.pluginInsMap)){const e=this.pluginInsMap[t];e.destroy&&"function"==typeof e.destroy&&e.destroy()}this.pluginInsMap={},this.plugins=[]}}const yt=class{constructor({emitter:t,config:e,sdk:n}){this.boundSend=null,this.hashEvent=null,this.spaSwitchHandler=null,this.emitter=t,this.config=e,this.sdk=n}init(){const t=this.config;this.boundSend=()=>{mt({event:"$PageView",properties:{}},t)},this.sdk&&!0===this.sdk._postConsentInit||setTimeout(()=>{this.boundSend()},0),t.isSinglePageApp&&this.addSinglePageListener()}addSinglePageListener(){this.spaSwitchHandler=t=>{t!==location.href&&this.boundSend()},this.emitter.on(y,this.spaSwitchHandler)}destroy(){this.spaSwitchHandler&&(this.emitter.off(y,this.spaSwitchHandler),this.spaSwitchHandler=null),this.hashEvent&&this.boundSend&&(window.removeEventListener(this.hashEvent,this.boundSend),this.hashEvent=null),this.boundSend=null}};yt.NAME="pageview";let At=yt;const Rt=class{constructor({emitter:t,config:e,sdk:n}){this.startTime=Date.now(),this.pageShowStatus=!0,this.pageHiddenStatus=!1,this.timer=null,this.currentPageUrl=document.referrer,this.url=location.href,this.title=document.title||"",this.heartbeatIntervalTime=5e3,this.heartbeatIntervalTimer=null,this.pageId=null,this.storageName="sensorswavewebjssdkpageleave",this.maxDuration=432e3,this.eventListeners=[],this._skipFirstPageEnd=!1,this.emitter=t,this.config=e,this.sdk=n}__canCapture(){return!this.sdk||"function"!=typeof this.sdk.hasOptedOutCapturing||!this.sdk.hasOptedOutCapturing()}init(){this.pageId=Number(String(g()).slice(2,5)+String(g()).slice(2,4)+String(Date.now()).slice(-4)),this.addEventListener(),this.sdk&&!0===this.sdk._postConsentInit&&(this._skipFirstPageEnd=!0),!0===document.hidden?this.pageShowStatus=!1:this.addHeartBeatInterval()}log(t){console.log(t)}refreshPageEndTimer(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.timer=setTimeout(()=>{this.pageHiddenStatus=!1},5e3)}hiddenStatusHandler(){this.timer&&clearTimeout(this.timer),this.timer=null,this.pageHiddenStatus=!1}pageStartHandler(){this.startTime=Date.now(),1==!document.hidden?this.pageShowStatus=!0:this.pageShowStatus=!1,this.url=location.href,this.title=document.title,this._skipFirstPageEnd=!1}pageEndHandler(){if(!0===this.pageHiddenStatus)return;if(!this.__canCapture())return;const t=this.getPageLeaveProperties();!1===this.pageShowStatus&&delete t.$event_duration,this.pageShowStatus=!1,this.pageHiddenStatus=!0,mt({event:R,properties:t},this.config),this.refreshPageEndTimer(),this.delHeartBeatData()}addEventListener(){this.addPageStartListener(),this.addPageSwitchListener(),this.addSinglePageListener(),this.addPageEndListener()}addPageStartListener(){if("onpageshow"in window){const t=()=>{this.pageStartHandler(),this.hiddenStatusHandler()};window.addEventListener("pageshow",t),this.eventListeners.push({target:window,event:"pageshow",handler:t})}}addSinglePageListener(){this.config.isSinglePageApp&&this.emitter.on(y,t=>{t!==location.href&&(this.url=t,this.pageEndHandler(),this.stopHeartBeatInterval(),this.currentPageUrl=this.url,this.pageStartHandler(),this.hiddenStatusHandler(),this.addHeartBeatInterval())})}addPageEndListener(){["pagehide","beforeunload"].forEach(t=>{if(`on${t}`in window){const e=()=>{if(this._skipFirstPageEnd)return this._skipFirstPageEnd=!1,void this.stopHeartBeatInterval();this.pageEndHandler(),this.stopHeartBeatInterval()};window.addEventListener(t,e),this.eventListeners.push({target:window,event:t,handler:e})}})}addPageSwitchListener(){const t=()=>{"visible"===document.visibilityState?(this.pageStartHandler(),this.hiddenStatusHandler(),this.addHeartBeatInterval()):(this.url=location.href,this.title=document.title,this.stopHeartBeatInterval())};document.addEventListener("visibilitychange",t),this.eventListeners.push({target:document,event:"visibilitychange",handler:t})}addHeartBeatInterval(){I.isSupport()&&this.startHeartBeatInterval()}startHeartBeatInterval(){this.heartbeatIntervalTimer&&this.stopHeartBeatInterval(),this.sdk&&!0===this.sdk._postConsentInit&&!0===this._skipFirstPageEnd||(this.heartbeatIntervalTimer=setInterval(()=>{this.saveHeartBeatData()},this.heartbeatIntervalTime),this.saveHeartBeatData("is_first_heartbeat"),this.reissueHeartBeatData())}stopHeartBeatInterval(){this.heartbeatIntervalTimer&&clearInterval(this.heartbeatIntervalTimer),this.heartbeatIntervalTimer=null}saveHeartBeatData(t){if(!this.__canCapture())return;const e=this.getPageLeaveProperties();e.$time=Date.now(),"is_first_heartbeat"===t&&(e.$event_duration=3);const n={type:"track",event:R,properties:e,time:e.$time};n.heartbeat_interval_time=this.heartbeatIntervalTime,I.isSupport()&&I.set(`${this.storageName}-${this.pageId}`,JSON.stringify(n))}delHeartBeatData(t){I.isSupport()&&I.remove(t||`${this.storageName}-${this.pageId}`)}reissueHeartBeatData(){if(this.__canCapture())for(let t=window.localStorage.length-1;t>=0;t--){const e=window.localStorage.key(t);if(e&&e!==`${this.storageName}-${this.pageId}`&&0===e.indexOf(`${this.storageName}-`)){const t=I.parse(e);i(t)&&Date.now()-t.time>t.heartbeat_interval_time+5e3&&(delete t.heartbeat_interval_time,t._flush_time=(new Date).getTime(),mt({event:R,properties:t?.properties},this.config),this.delHeartBeatData(e))}}}getPageLeaveProperties(){let t=(Date.now()-this.startTime)/1e3;(isNaN(t)||t<0||t>this.maxDuration)&&(t=0),t=Number(t.toFixed(3));const e={$title:this.title,$url:this.url?.substring(0,1e3),$pathname:w(this.url)};return 0!==t&&(e.$event_duration=t),e}destroy(){this.eventListeners.forEach(({target:t,event:e,handler:n})=>{t.removeEventListener(e,n)}),this.eventListeners=[],this.timer&&(clearTimeout(this.timer),this.timer=null),this.heartbeatIntervalTimer&&(clearInterval(this.heartbeatIntervalTimer),this.heartbeatIntervalTimer=null)}};Rt.NAME="pageleave";let Tt=Rt;const Ct=class{constructor({emitter:t,config:e,sdk:n}){this.eventSended=!1,this.emitter=t,this.config=e,this.sdk=n}init(){if(this.sdk&&!0===this.sdk._postConsentInit)return;const t=()=>{let e=0;const n={};if(window.performance){e=function(){let t=0;if("function"==typeof performance.getEntriesByType){const e=performance.getEntriesByType("navigation");e.length>0&&(t=e[0].domContentLoadedEventEnd||0)}return t}();const t=function(){if(performance.getEntries&&"function"==typeof performance.getEntries){const t=performance.getEntries();let e=0;for(const n of t)"transferSize"in n&&(e+=n.transferSize);if("number"==typeof e&&e>=0&&e<10737418240)return Number((e/1024).toFixed(3))}}();t&&(n.$page_resource_size=t)}else console.warn("Performance API is not supported.");e>0&&!Number.isFinite(e)&&(n.$event_duration=Number((e/1e3).toFixed(3))),this.eventSended||(this.eventSended=!0,mt({event:"$PageLoad",properties:n},this.config)),window.removeEventListener("load",t)};"complete"===document.readyState?t():window.addEventListener&&window.addEventListener("load",t)}};Ct.NAME="pageload";let Nt=Ct;function Pt(t,e){if(!l(t))return!1;const n=o(t.tagName)?t.tagName.toLowerCase():"",i={};i.$element_type=n,i.$element_name=t.getAttribute("name")||"",i.$element_id=t.getAttribute("id")||"",i.$element_class_name=o(t.className)?t.className:"",i.$element_target_url=t.getAttribute("href")||"",i.$element_content=function(t,e){return o(e)&&"input"===e.toLowerCase()?("button"===(n=t).type||"submit"===n.type)&&n.value||"":function(t,e){let n="",i="";return t.textContent?n=S(t.textContent):t.innerText&&(n=S(t.innerText)),n&&(n=n.replace(/[\r\n]/g," ").replace(/[ ]+/g," ").substring(0,255)),i=n||"","input"!==e&&"INPUT"!==e||(i=t.value||""),i}(t,e);var n}(t,n)||"",i.$element_selector=kt(t)||"",i.$element_path=function(t){let e=[];for(;t.parentNode&&l(t);){if(!o(t.tagName))return"";if(t.id&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(t.id)){e.unshift(t.tagName.toLowerCase()+"#"+t.id);break}if(t===document.body){e.unshift("body");break}e.unshift(t.tagName.toLowerCase()),t=t.parentNode}return e.join(" > ")}(t)||"";const s=function(t,e){const n=e.pageX||e.clientX+Lt().scrollLeft||e.offsetX+$t(t).targetEleX,i=e.pageY||e.clientY+Lt().scrollTop||e.offsetY+$t(t).targetEleY;return{$page_x:Ft(n),$page_y:Ft(i)}}(t,e);return i.$page_x=s.$page_x,i.$page_y=s.$page_y,i}function kt(t,e=[]){if(!(t&&t.parentNode&&t.parentNode.children&&o(t.tagName)))return"";e=Array.isArray(e)?e:[];const n=t.nodeName.toLowerCase();return t&&"body"!==n&&1==t.nodeType?(e.unshift(function(t){if(!t||!l(t)||!o(t.tagName))return"";let e=t.parentNode&&9==t.parentNode.nodeType?-1:function(t){if(!t.parentNode)return-1;let e=0;const n=t.tagName,i=t.parentNode.children;for(let s=0,r=i.length;s<r;s++)if(i[s].tagName===n){if(t===i[s])return e;e++}return-1}(t);return t.getAttribute&&t.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(t.getAttribute("id"))?"#"+t.getAttribute("id"):t.tagName.toLowerCase()+(~e?":nth-of-type("+(e+1)+")":"")}(t)),t.getAttribute&&t.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(t.getAttribute("id"))?e.join(" > "):kt(t.parentNode,e)):(e.unshift("body"),e.join(" > "))}function Lt(){return{scrollLeft:document.body.scrollLeft||document.documentElement.scrollLeft||0,scrollTop:document.body.scrollTop||document.documentElement.scrollTop||0}}function $t(t){if(document.documentElement.getBoundingClientRect){const e=t.getBoundingClientRect();return{targetEleX:e.left+Lt().scrollLeft||0,targetEleY:e.top+Lt().scrollTop||0}}return{targetEleX:0,targetEleY:0}}function Ft(t){return Number(Number(t).toFixed(3))}const Bt=class{constructor({emitter:t,config:e}){this.isInitialized=!1,this.boundHandleClick=null,this.emitter=t,this.config=e}init(){this.isInitialized||(this.boundHandleClick=this.handleClick.bind(this),document.addEventListener("click",this.boundHandleClick,!0),this.isInitialized=!0)}handleClick(t){const e=t.target;if(!e)return;if(!["A","INPUT","BUTTON","TEXTAREA"].includes(e.tagName))return;if("true"===e.getAttribute("sensorswave-disable"))return;mt({event:"$WebClick",properties:Pt(e,t)||{}},this.config)}destroy(){this.boundHandleClick&&(document.removeEventListener("click",this.boundHandleClick,!0),this.boundHandleClick=null),this.isInitialized=!1}};Bt.NAME="webclick";let xt=Bt;const Mt=class{constructor({emitter:t,config:e,sdk:n}){this.updateInterval=null,this.fetchingPromise=null,this.emitter=t,this.config=e,this.sdk=n}init(){const t=this.config;if(t.enableAB){if(this.sdk&&"function"==typeof this.sdk.hasOptedOutCapturing&&this.sdk.hasOptedOutCapturing())return;this.fastFetch().then(()=>{this.emitter.emit(A)}),t.abRefreshInterval<3e4&&(t.abRefreshInterval=3e4),this.updateInterval=setInterval(()=>{this.fetchNewData().catch(console.warn)},t.abRefreshInterval)}}async fastFetch(){const t=N.getABData(this.config.abRefreshInterval);return t&&t.length?(this.emitter.emit(A),Promise.resolve(t)):this.fetchNewData()}async fetchNewData(){return this.fetchingPromise||(this.fetchingPromise=new Promise(t=>{!function({opts:t,cb:e}){if(!st())return void(e&&e({}));if(!rt())return void(e&&e({}));const n=N.getLoginId(),i=N.getAnonId();if(!n&&!i)return void(e&&e({}));const s={user:{login_id:n||"",anon_id:i||"",props:{...tt(),...gt(N.getCommonProps())}},sdk:"webjs",sdk_version:v};$({url:lt(t),method:"POST",data:s,headers:ht(t),callback:t=>{200!==t.statusCode?(console.error("Failed to fetch feature flags"),e&&e({})):e&&e(t.json)}})}({opts:this.config,cb:e=>{N.saveABData(e?.data?.results||[]),t(e),this.fetchingPromise=null}})})),this.fetchingPromise}async getFeatureGate(t){return await this.fastFetch().catch(console.warn),N.getABData(this.config.abRefreshInterval).find(e=>e.typ===C.FEATURE_GATE&&e.key==t)}async checkFeatureGate(t){const e=await this.getFeatureGate(t);return!!e&&(!e.hasOwnProperty("vid")&&e.key?(wt({isUnset:!0,data:e,opts:this.config}),!1):(wt({data:e,opts:this.config}),"fail"!==e.vid))}async getExperiment(t){await this.fastFetch().catch(console.warn);const e=N.getABData(this.config.abRefreshInterval).find(e=>e.typ===C.EXPERIMENT&&e.key===t);return e?!e.hasOwnProperty("vid")&&e.key?(wt({isUnset:!0,data:e,opts:this.config}),{}):(wt({data:e,opts:this.config}),e?.value||{}):{}}async getFeatureConfig(t){await this.fastFetch().catch(console.warn);const e=N.getABData(this.config.abRefreshInterval).find(e=>e.typ===C.FEATURE_CONFIG&&e.key===t);if(!e)return{};if(!e.hasOwnProperty("vid")&&e.key)return wt({isUnset:!0,data:e,opts:this.config}),{};wt({data:e,opts:this.config});const n=e?.value;if(n){if(i(n))return n;try{return JSON.parse(n)}catch{return n}}return{}}destroy(){this.updateInterval&&(clearInterval(this.updateInterval),this.updateInterval=null),this.fetchingPromise=null}};Mt.NAME="abtest";let Dt=Mt;const Ht=["utm_source","utm_medium","utm_campaign","utm_content","utm_term"],Ut="sensorswave_utm",Xt=class t{constructor({sdk:t,emitter:e,config:n}){this.sdk=t,this.emitter=e,this.config=n}init(){if(this.sdk&&!0===this.sdk._postConsentInit){let e=t.readFromSessionStorage();return e&&0!==Object.keys(e).length||(e=t.captureAndStore(this.config?.debug)),void this.scheduleInitialUTM(e)}const e=t.getUTMFromURL();t.saveToSessionStorage(e,this.config?.debug),this.scheduleInitialUTM(e)}scheduleInitialUTM(t){setTimeout(()=>{this.sendInitialUTM(t)},0)}static getUTMFromURL(){try{const t=new URLSearchParams(window.location.search),e={};return Ht.forEach(n=>{const i=t.get(n);i&&(e[n]=i)}),e}catch(e){return t.getUTMFromURLFallback()}}static getUTMFromURLFallback(){const t={};return window.location.search.substring(1).split("&").forEach(e=>{const[n,i]=e.split("="),s=decodeURIComponent(n),r=i?decodeURIComponent(i):"";Ht.includes(s)&&(t[s]=r)}),t}static readFromSessionStorage(){try{const t=sessionStorage.getItem(Ut);if(!t)return{};const e=JSON.parse(t);return e&&"object"==typeof e?e:{}}catch(t){return{}}}static saveToSessionStorage(t,e=!1){try{sessionStorage.setItem(Ut,JSON.stringify(t))}catch(n){e&&console.warn("[SensorsWave UTM] Failed to save to sessionStorage:",n)}}static captureAndStore(e=!1){const n=t.getUTMFromURL();return t.saveToSessionStorage(n,e),n}sendInitialUTM(t){const e={};Ht.forEach(n=>{e[`$initial_${n}`]=null!=t[n]?t[n]:""});try{this.sdk.profileSetOnce(e)}catch(n){this.config.debug&&console.warn("[SensorsWave UTM] Failed to send initial UTM:",n)}}destroy(){}};Xt.NAME="UTM";let jt=Xt;const qt=1e3,Wt=/^\s*(?:async\s+)?at\s+(?:(.+)\s+\()?(.+?):(\d+):(\d+)\)?$/,Gt=/^(?:(.*)@)?(.+?):(\d+):(\d+)$/;function zt(t){let e=t;try{const t=location.origin;t&&0===e.indexOf(t)&&(e=e.substring(t.length))}catch(s){}const n=e.indexOf("?");n>-1&&(e=e.substring(0,n));const i=e.indexOf("#");return i>-1&&(e=e.substring(0,i)),e}function Yt(t){return t.map(t=>({platform:"web:javascript",filename:zt(t.file),function:t.fn||"?",lineno:Number(t.line),colno:Number(t.col),abs_path:Kt(t.file,1e3)}))}function Kt(t,e){return t.length>e?t.substring(0,e):t}function Jt(t){let e;if("string"==typeof t)e=t;else if(null!==t&&"object"==typeof t){try{e=JSON.stringify(t)}catch(n){e=Object.prototype.toString.call(t)}e||(e=Object.prototype.toString.call(t))}else e=String(t);return Kt(e,qt)}function Zt(t){const{frames:e,headerType:n}=function(t){const e=[];let n="";if(!t||"string"!=typeof t)return{frames:e,headerType:n};const i=t.split(/\r?\n/);for(let s=0;s<i.length;s++){const t=i[s];if(!t||t.length>1024)continue;const r=t.match(Wt),o=r?null:t.match(Gt),a=r||o;if(a)e.push({fn:a[1]||"?",file:a[2],line:a[3],col:a[4]});else if(0===s){const e=t.indexOf(":");e>0&&(n=t.substring(0,e).trim())}if(e.length>=30)break}return{frames:e,headerType:n}}(t&&t.stack);let i=t&&t.name||n||"Error";return i=Kt(String(i),200),{$exception_level:"error",$exception_type:i,$exception_message:Kt(String(t&&t.message||""),qt),$exception_frames:Yt(e)}}function Qt(t,e,n,i){let s=[];return e&&(s=[{platform:"web:javascript",filename:zt(e),function:"?",lineno:n||0,colno:i||0,abs_path:Kt(e,1e3)}]),{$exception_level:"error",$exception_type:"Error",$exception_message:Kt(String(t||""),qt),$exception_frames:s}}class Vt{constructor(t=10,e=1,n=1e4){this.buckets=new Map,this.bucketSize=t,this.refillRate=e,this.refillInterval=n}allow(t){const e=Date.now();let n=this.buckets.get(t);if(n){if(e>n.lastRefill){const t=Math.floor((e-n.lastRefill)/this.refillInterval)*this.refillRate;t>0&&(n.tokens=Math.min(this.bucketSize,n.tokens+t),n.lastRefill+=t/this.refillRate*this.refillInterval)}}else n={tokens:this.bucketSize,lastRefill:e},this.buckets.set(t,n);return n.tokens>=1&&(n.tokens-=1,!0)}reset(){this.buckets.clear()}}const te=class{constructor({emitter:t,config:e}){this.isInitialized=!1,this.boundHandleError=null,this.boundHandleRejection=null,this.rateLimiter=new Vt,this.emitter=t,this.config=e}init(){this.isInitialized||(this.boundHandleError=this.handleError.bind(this),this.boundHandleRejection=this.handleRejection.bind(this),window.addEventListener("error",this.boundHandleError,!0),window.addEventListener("unhandledrejection",this.boundHandleRejection),this.isInitialized=!0)}handleError(t){try{const e=t.target;let n;if(e&&e!==window&&e.tagName)n=function(t){const e=t,n=(e.tagName||"").toLowerCase(),i=Kt(String(e.src||e.href||""),qt);return{$exception_level:"error",$exception_type:"ResourceLoadError",$exception_message:`Failed to load <${n}>${i?` from ${i}`:""}`,$exception_frames:[]}}(e);else{const e=t;n=e.error instanceof Error?Zt(e.error):Qt(String(e.message||""),e.filename,e.lineno,e.colno)}this.send(n)}catch(e){}}handleRejection(t){try{const e=t.reason;this.send(function(t){return t instanceof Error?Zt(t):{$exception_level:"error",$exception_type:"UnhandledRejection",$exception_message:Jt(t),$exception_frames:[]}}(e))}catch(e){}}send(t){t.$exception_message&&this.rateLimiter.allow(t.$exception_type)&&mt({event:T,properties:t},this.config)}destroy(){this.boundHandleError&&(window.removeEventListener("error",this.boundHandleError,!0),this.boundHandleError=null),this.boundHandleRejection&&(window.removeEventListener("unhandledrejection",this.boundHandleRejection),this.boundHandleRejection=null),this.rateLimiter.reset(),this.isInitialized=!1}};te.NAME="exception";let ee=te;const ne=[],ie={debug:!1,sourceToken:"",apiHost:"",autoCapture:!0,isSinglePageApp:!1,crossSubdomainCookie:!0,enableAB:!1,abRefreshInterval:6e5,enableClickTrack:!1,batchSend:!1,enableErrorTrack:!1,enableCrashTrack:!1,optOutCapturing:!1,persistOptOut:!1},se=new class{constructor(){this.__innerInited=!1,this.inited=!1,this.config={},this.eventEmitter=new t,this.pluginCore={},this.commonProps={},this.spaCleanup=null,this._optOutCapturing=!1,this.consentStorage=new vt(!1),this._setupAfterConsentDone=!1,this._postConsentInit=!1,O.instance=this}init(t,e={}){return this.inited?this:(O.instance=this,e.sourceToken=t,this.mergeConfig(e),this.consentStorage=new vt(!0===this.config.persistOptOut),this._optOutCapturing?this.consentStorage.write(!0):!0===this.config.optOutCapturing?(this._optOutCapturing=!0,this.consentStorage.write(!0)):!0===this.consentStorage.read()&&(this._optOutCapturing=!0),this.eventEmitter.emit("init-param",this.config),this.__innerInited=!0,this._optOutCapturing?(jt.captureAndStore(this.config.debug),this.eventEmitter.emit(b),this.inited=!0,this):(this.__setupAfterConsent(),this.eventEmitter.emit(b),this.inited=!0,this))}__setupAfterConsent(){if(this._setupAfterConsentDone)return;this._setupAfterConsentDone=!0;const t=this.config;ne.length=0,N.init(t.crossSubdomainCookie),t.anonId&&N.setAnonId(t.anonId),function(){if(window._swFailedRequestsInitialized)return;window._swFailedRequestsInitialized=!0;const t=O.instance;t&&"function"==typeof t.hasOptedOutCapturing&&t.hasOptedOutCapturing()||t&&!0===t._postConsentInit||function(){const t=et.getAll();if(0!==t.length)for(let e=0,n=t.length;e<n;e+=10){const n=t.slice(e,e+10),i=[],s=[];n.forEach(t=>{Array.isArray(t.data)?i.push(...t.data):i.push(t.data),s.push(t.id)});const r=n[n.length-1],o=r.url,a=r.headers;$({url:o,method:"POST",data:i,headers:a,callback:t=>{200!==t.statusCode?(console.error("Failed to send batch stored requests:",t),P(t.statusCode)||s.forEach(t=>{et.dequeue(t)})):s.forEach(t=>{et.dequeue(t)})}})}}()}(),ne.push(jt),t.autoCapture&&this.autoTrack(),t.enableAB&&ne.push(Dt),t.enableClickTrack&&ne.push(xt),t.enableCrashTrack&&t.debug&&console.warn("[SensorsWave] enableCrashTrack 仅在 app 宿主环境生效,当前 Web 环境不采集 crash"),t.enableErrorTrack&&ne.push(ee),this.pluginCore=new bt({plugins:ne,emitter:this.eventEmitter,config:t,sdk:this}),this.spaCleanup=function(t){let e=location.href;const n=window.history.pushState,i=window.history.replaceState,r=function(){t(e),e=location.href};return s(window.history.pushState)&&(window.history.pushState=function(...i){n.apply(window.history,i),t(e),e=location.href}),s(window.history.replaceState)&&(window.history.replaceState=function(...n){i.apply(window.history,n),t(e),e=location.href}),window.addEventListener("popstate",r),function(){s(window.history.pushState)&&(window.history.pushState=n),s(window.history.replaceState)&&(window.history.replaceState=i),window.removeEventListener("popstate",r)}}(t=>{this.eventEmitter.emit(y,t)})}mergeConfig(t){this.config={...ie,...t}}__canCapture(){return this.inited&&!this._optOutCapturing}track(t){this.__canCapture()&&function(t,e){if(!st())return;if(!rt())return;const n={...t};n.time||(n.time=Date.now()),n.login_id||(n.login_id=N.getLoginId()),n.anon_id||(n.anon_id=N.getAnonId()),n.trace_id||(n.trace_id=N.getTraceId()),n.properties={...tt(),...gt(N.getCommonProps()),...n.properties};const i=ut(e),s=ht(e),r=!1!==e.batchSend&&at();if(!r)return dt(i,{data:[n],headers:s});et.enqueue(i,[n],s),r.add()}(t,this.config)}trackEvent(t,e){this.__canCapture()&&mt({event:t,properties:e},this.config)}trackException(t,e){if(!this.__canCapture())return;const n={...e||{},...t instanceof Error?Zt(t):Qt(String(t))};mt({event:T,properties:n},this.config)}autoTrack(){ne.push(At,Nt,Tt)}profileSet(t){this.__canCapture()&&Et({userProps:{$set:t},opts:this.config})}profileSetOnce(t){this.__canCapture()&&Et({userProps:{$set_once:t},opts:this.config})}profileIncrement(t){this.__canCapture()&&Et({userProps:{$increment:t},opts:this.config})}profileAppend(t){this.__canCapture()&&Et({userProps:{$append:t},opts:this.config})}profileUnion(t){this.__canCapture()&&Et({userProps:{$union:t},opts:this.config})}profileUnset(t){if(!this.__canCapture())return;const e={};r(t)?t.forEach(function(t){e[t]=null}):e[t]=null,Et({userProps:{$unset:e},opts:this.config})}profileDelete(){this.__canCapture()&&Et({userProps:{$delete:!0},opts:this.config})}registerCommonProperties(t){if(!i(t))return console.warn("Commmon Properties must be an object!");this.commonProps=t,N.setCommonProps(this.commonProps)}clearCommonProperties(t){if(!r(t))return console.warn("Commmon Properties to be cleared must be an array!");t.forEach(t=>{delete this.commonProps[t]}),N.setCommonProps(this.commonProps)}identify(t){this.__canCapture()&&(N.setLoginId(t),function(t){if(!st())return;if(!rt())return;const e=N.getLoginId(),n=N.getAnonId();if(!e||!n)return;const i={time:Date.now(),trace_id:N.getTraceId(),event:"$Identify",login_id:e,anon_id:n,properties:ft()},s=ut(t),r=ht(t),o=at();if(!o)return dt(s,{data:[i],headers:r});et.enqueue(s,[i],r),o.add()}(this.config))}setLoginId(t){this.__canCapture()&&N.setLoginId(t)}getAnonId(){return this.__canCapture()?N.getAnonId():""}setAnonId(t){this.__canCapture()&&N.setAnonId(t)}getLoginId(){return this.__canCapture()?N.getLoginId():""}reset(t=!1){this.__canCapture()&&(N.clearLoginId(),t&&N.resetAnonId())}checkFeatureGate(t){if(!this.__canCapture())return Promise.resolve(!1);const e=this.pluginCore.getPlugin(Dt.NAME);return this.config.enableAB&&e?e.checkFeatureGate(t):Promise.reject("AB is disabled")}getExperiment(t){if(!this.__canCapture())return Promise.resolve({});const e=this.pluginCore.getPlugin(Dt.NAME);return this.config.enableAB&&e?e.getExperiment(t):Promise.reject("AB is disabled")}getFeatureConfig(t){if(!this.__canCapture())return Promise.resolve({});const e=this.pluginCore.getPlugin(Dt.NAME);return this.config.enableAB&&e?e.getFeatureConfig(t):Promise.reject("AB is disabled")}optOutCapturing(){this._optOutCapturing=!0,this.consentStorage.write(!0),ot&&ot.pause()}optInCapturing(){if(this._optOutCapturing=!1,this.consentStorage.write(!1),ot&&ot.resume(),this.inited&&!this._setupAfterConsentDone){this._postConsentInit=!0;try{this.__setupAfterConsent(),this.eventEmitter.emit(b)}finally{this._postConsentInit=!1}}}hasOptedOutCapturing(){return this._optOutCapturing}destroy(){ot&&(ot.destroy(),ot=null),"undefined"!=typeof window&&(window._swFailedRequestsInitialized=!1),this.inited=!1,this.__innerInited=!1,this.spaCleanup&&"function"==typeof this.spaCleanup&&(this.spaCleanup(),this.spaCleanup=null),this.pluginCore&&"function"==typeof this.pluginCore.destroy&&this.pluginCore.destroy(),this.pluginCore={},this.eventEmitter&&this.eventEmitter.removeAllListeners(),this.consentStorage=new vt(!0===this.config?.persistOptOut),this._optOutCapturing=!1,this._setupAfterConsentDone=!1,this._postConsentInit=!1,O.instance===this&&(O.instance=null)}};module.exports=se;
|
|
1
|
+
"use strict";class e{constructor(){this.listeners={}}on(e,t,i=!1){if(e&&t){if(!s(t))throw new Error("listener must be a function");this.listeners[e]=this.listeners[e]||[],this.listeners[e].push({listener:t,once:i})}}off(e,t){const i=this.listeners[e];if(!i?.length)return;"number"==typeof t&&i.splice(t,1);const n=i.findIndex(e=>e.listener===t);-1!==n&&i.splice(n,1)}emit(e,...t){this.listeners[e]&&this.listeners[e].forEach((i,n)=>{i.listener.call(this,...t),i.listener.once&&this.off(e,n)})}once(e,t){this.on(e,t,!0)}removeAllListeners(e){e?this.listeners[e]=[]:this.listeners={}}}const t={get:function(e){const t=e+"=",i=document.cookie.split(";");for(let n=0,s=i.length;n<s;n++){let e=i[n];for(;" "==e.charAt(0);)e=e.substring(1,e.length);if(0==e.indexOf(t))return h(e.substring(t.length,e.length))}return null},set:function({name:e,value:t,expires:i,samesite:n,secure:s,domain:r}){let o="",a="",c="",u="";if(0!==(i=null==i||void 0===i?365:i)){const e=new Date;"s"===String(i).slice(-1)?e.setTime(e.getTime()+1e3*Number(String(i).slice(0,-1))):e.setTime(e.getTime()+24*i*60*60*1e3),o="; expires="+e.toUTCString()}function l(e){return e?e.replace(/\r\n/g,""):""}n&&(c="; SameSite="+n),s&&(a="; secure");const h=l(e),d=l(t),p=l(r);p&&(u="; domain="+p),h&&d&&(document.cookie=h+"="+encodeURIComponent(d)+o+"; path=/"+u+c+a)},remove:function(e){this.set({name:e,value:"",expires:-1})},isSupport:function({samesite:e,secure:t}={}){if(!navigator.cookieEnabled)return!1;const i="sensorswave_cookie_support_test";return this.set({name:i,value:"1",samesite:e,secure:t}),"1"===this.get(i)&&(this.remove(i),!0)}},i=Object.prototype.toString;function n(e){return"[object Object]"===i.call(e)}function s(e){const t=i.call(e);return"[object Function]"==t||"[object AsyncFunction]"==t}function r(e){return"[object Array]"==i.call(e)}function o(e){return"[object String]"==i.call(e)}function a(e){return void 0===e}const c=Object.prototype.hasOwnProperty;function u(e){if(n(e)){for(let t in e)if(c.call(e,t))return!1;return!0}return!1}function l(e){return!(!e||1!==e.nodeType)}function h(e){let t=e;try{t=decodeURIComponent(e)}catch(i){t=e}return t}function d(e){try{return JSON.parse(e)}catch(t){return""}}const p=function(){let e=Date.now();return function(t){return Math.ceil((e=(9301*e+49297)%233280,e/233280*t))}}();function g(){if("function"==typeof Uint32Array){let e;if("undefined"!=typeof crypto&&(e=crypto),e&&n(e)&&e.getRandomValues)return e.getRandomValues(new Uint32Array(1))[0]/Math.pow(2,32)}return p(1e19)/1e19}const f=function(){function e(e){return("0".repeat(e)+Date.now().toString(16)).slice(-e)}return function(){let t=String(screen.height*screen.width);t=t&&/\d{4,}/.test(t)?t.slice(-4):String(31242*g()).replace(".","").slice(0,4);return e(8)+"-"+g().toString(16).replace(".","").slice(-4)+"-"+function(){const e=navigator.userAgent;let t,i=[],n=0;function s(e,t){let n=0;for(let s=0;s<t.length;s++)n|=i[s]<<8*s;return(e^n)>>>0}for(let r=0;r<e.length;r++)t=e.charCodeAt(r),i.unshift(255&t),i.length>=4&&(n=s(n,i),i=[]);return i.length>0&&(n=s(n,i)),("0000"+n.toString(16)).slice(-4)}()+"-"+t+"-"+e(12)||(String(g())+String(g())+String(g())).slice(2,15)}}();function m(e,t){t&&"string"==typeof t||(t="");let i=null;try{i=new URL(e).hostname}catch(n){}return i||t}function E(e){let t=[];try{t=atob(e).split("").map(function(e){return"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)})}catch(i){t=[]}try{return decodeURIComponent(t.join(""))}catch(i){return t.join("")}}function v(e){let t="";try{t=btoa(encodeURIComponent(e).replace(/%([0-9A-F]{2})/g,function(e,t){return String.fromCharCode(parseInt(t,16))}))}catch(i){t=e}return t}const b={get:function(e){return window.localStorage.getItem(e)},parse:function(e){let t;try{t=JSON.parse(b.get(e))||null}catch(i){console.warn(i)}return t},set:function(e,t){try{window.localStorage.setItem(e,t)}catch(i){console.warn(i)}},remove:function(e){window.localStorage.removeItem(e)},isSupport:function(){let e=!0;try{const t="__local_store_support__",i="testIsSupportStorage";b.set(t,i),b.get(t)!==i&&(e=!1),b.remove(t)}catch(t){e=!1}return e}};function _(e){return e.trim()}function I(e){if(!e||"string"!=typeof e)return"";try{return new URL(e,window.location.origin).pathname}catch(t){return""}}const S={},w="1.5.1",O="init-ready",y="spa-switch",A="ff-ready",R="$PageLeave",T="$Exception";var C=(e=>(e[e.FEATURE_GATE=1]="FEATURE_GATE",e[e.FEATURE_CONFIG=2]="FEATURE_CONFIG",e[e.EXPERIMENT=3]="EXPERIMENT",e))(C||{});const N={crossSubdomain:!1,requests:[],_sessionState:{},_abData:[],_trace_id:"",commonProps:{},_state:{anon_id:"",login_id:"",identities:{}},getIdentityCookieID(){return this._state.identities?.$identity_cookie_id||""},getCommonProps:function(){return this.commonProps||{}},setCommonProps:function(e){this.commonProps=e},getAnonId(){return this._state.anon_id||this.getIdentityCookieID()||f()},getLoginId(){return this._state.login_id},getTraceId(){return this._trace_id||f()},set:function(e,t){this._state[e]=t,this.save()},getCookieName:function(){return"sensorswave2025jssdkcross"},getABLSName:function(){return"sensorswave2025jssdkablatest"},save:function(){let e=JSON.parse(JSON.stringify(this._state));e.identities&&(e.identities=v(JSON.stringify(e.identities)));const i=JSON.stringify(e);t.set({name:this.getCookieName(),value:i,expires:365})},init:function(e){let i,s;this.crossSubdomain=e,t.isSupport()&&(i=t.get(this.getCookieName()),s=d(i)),N._state={...s||{}},N._state.identities&&(N._state.identities=d(E(N._state.identities))),N._state.identities&&n(N._state.identities)&&!u(N._state.identities)||(N._state.identities={$identity_cookie_id:f()}),N.save()},setLoginId(e){"number"==typeof e&&(e=String(e)),void 0!==e&&e&&(N.set("login_id",e),N.save())},clearLoginId(){this._state.login_id="",this.save()},resetAnonId(){this._state.anon_id="",this._state.identities={$identity_cookie_id:f()},this.save()},setAnonId(e){"number"==typeof e&&(e=String(e)),"string"==typeof e&&e?(N.set("anon_id",e),N.save()):console.warn("[SensorsWave store] Invalid anonId, ignored:",e)},saveABData(e){if(!e||u(e))return;this._abData=e;let t=JSON.parse(JSON.stringify(this._abData));t=v(JSON.stringify(t));try{localStorage.setItem(this.getABLSName(),JSON.stringify({time:Date.now(),data:t,anon_id:this.getAnonId(),login_id:this.getLoginId()}))}catch(i){console.warn("Failed to save abdata to localStorage",i)}},getABData(e=6e5){try{let t=localStorage.getItem(this.getABLSName());if(t){const{time:i,data:n,login_id:s,anon_id:r}=d(t)||{};if(i&&n&&Date.now()-i<e&&r===this.getAnonId()&&(!s||s===this.getLoginId())){const e=d(E(n));return this._abData=Array.isArray(e)?e:[],this._abData}localStorage.removeItem(this.getABLSName())}}catch(t){this._abData=[]}return this._abData||[]}};function P(e){return!(e>=400&&e<500)||408===e||429===e}function k(e){var t;if(e.data)return{contentType:"application/json",body:(t=e.data,JSON.stringify(t,(e,t)=>"bigint"==typeof t?t.toString():t,undefined))}}const x=[];function L(e){const t={...e};t.timeout=t.timeout||6e4;const i=t.transport??"fetch",n=x.find(e=>e.transport===i)?.method??x[0]?.method;if(!n)throw new Error("No available transport method for HTTP request");n(t)}function M(e){return o(e=e||document.referrer)&&(e=h(e=e.trim()))||""}function $(e){const t=m(e=e||M());if(!t)return"";const i={baidu:[/^.*\.baidu\.com$/],bing:[/^.*\.bing\.com$/],google:[/^www\.google\.com$/,/^www\.google\.com\.[a-z]{2}$/,/^www\.google\.[a-z]{2}$/],sm:[/^m\.sm\.cn$/],so:[/^.+\.so\.com$/],sogou:[/^.*\.sogou\.com$/],yahoo:[/^.*\.yahoo\.com$/],duckduckgo:[/^.*\.duckduckgo\.com$/]};for(let n of Object.keys(i)){let e=i[n];for(let i=0,s=e.length;i<s;i++)if(e[i].test(t))return n}return""}function D(e,t){return-1!==e.indexOf(t)}"function"==typeof fetch&&x.push({transport:"fetch",method:function(e){if("undefined"==typeof fetch)return void console.error("fetch API is not available");const t=k(e),i=new Headers;e.headers&&Object.keys(e.headers).forEach(t=>{i.append(t,e.headers[t])}),t?.contentType&&i.append("Content-Type",t.contentType),fetch(e.url,{method:e.method||"GET",headers:i,body:t?.body}).then(t=>t.text().then(i=>{const n={statusCode:t.status,text:i};if(200===t.status)try{n.json=JSON.parse(i)}catch(s){console.error("Failed to parse response:",s)}e.callback?.(n)})).catch(t=>{console.error("Request failed:",t),e.callback?.({statusCode:0,text:String(t)})})}}),"undefined"!=typeof XMLHttpRequest&&x.push({transport:"XHR",method:function(e){if("undefined"==typeof XMLHttpRequest)return void console.error("XMLHttpRequest is not available");const t=new XMLHttpRequest;t.open(e.method||"GET",e.url,!0);const i=k(e);e.headers&&Object.keys(e.headers).forEach(i=>{t.setRequestHeader(i,e.headers[i])}),i?.contentType&&t.setRequestHeader("Content-Type",i.contentType),t.timeout=e.timeout||6e4,t.withCredentials=!0,t.onreadystatechange=()=>{if(4===t.readyState){const n={statusCode:t.status,text:t.responseText};if(200===t.status)try{n.json=JSON.parse(t.responseText)}catch(i){console.error("Failed to parse JSON response:",i)}e.callback?.(n)}},t.send(i?.body)}});const F={FACEBOOK:"Facebook",MOBILE:"Mobile",IOS:"iOS",ANDROID:"Android",TABLET:"Tablet",ANDROID_TABLET:"Android Tablet",IPAD:"iPad",APPLE:"Apple",APPLE_WATCH:"Apple Watch",SAFARI:"Safari",BLACKBERRY:"BlackBerry",SAMSUNG_BROWSER:"SamsungBrowser",SAMSUNG_INTERNET:"Samsung Internet",CHROME:"Chrome",CHROME_OS:"Chrome OS",CHROME_IOS:"Chrome iOS",INTERNET_EXPLORER:"Internet Explorer",INTERNET_EXPLORER_MOBILE:"Internet Explorer Mobile",OPERA:"Opera",OPERA_MINI:"Opera Mini",EDGE:"Edge",MICROSOFT_EDGE:"Microsoft Edge",FIREFOX:"Firefox",FIREFOX_IOS:"Firefox iOS",NINTENDO:"Nintendo",PLAYSTATION:"PlayStation",XBOX:"Xbox",ANDROID_MOBILE:"Android Mobile",MOBILE_SAFARI:"Mobile Safari",WINDOWS:"Windows",WINDOWS_PHONE:"Windows Phone",NOKIA:"Nokia",OUYA:"Ouya",GENERIC_MOBILE:"Generic mobile",GENERIC_TABLET:"Generic tablet",KONQUEROR:"Konqueror",UC_BROWSER:"UC Browser",HUAWEI:"Huawei",XIAOMI:"Xiaomi",OPPO:"OPPO",VIVO:"vivo"},B="(\\d+(\\.\\d+)?)",H=new RegExp("Version/"+B),U=new RegExp(F.XBOX,"i"),W=new RegExp(F.PLAYSTATION+" \\w+","i"),X=new RegExp(F.NINTENDO+" \\w+","i"),j=new RegExp(F.BLACKBERRY+"|PlayBook|BB10","i"),q=new RegExp("(HUAWEI|honor|HONOR)","i"),G=new RegExp("(Xiaomi|Redmi)","i"),z=new RegExp("(OPPO|realme)","i"),V=new RegExp("(vivo|IQOO)","i"),Y={"NT3.51":"NT 3.11","NT4.0":"NT 4.0","5.0":"2000",5.1:"XP",5.2:"XP","6.0":"Vista",6.1:"7",6.2:"8",6.3:"8.1",6.4:"10","10.0":"10"};function K(e,t){return t=t||"",D(e," OPR/")&&D(e,"Mini")?F.OPERA_MINI:D(e," OPR/")?F.OPERA:j.test(e)?F.BLACKBERRY:D(e,"IE"+F.MOBILE)||D(e,"WPDesktop")?F.INTERNET_EXPLORER_MOBILE:D(e,F.SAMSUNG_BROWSER)?F.SAMSUNG_INTERNET:D(e,F.EDGE)||D(e,"Edg/")?F.MICROSOFT_EDGE:D(e,"FBIOS")?F.FACEBOOK+" "+F.MOBILE:D(e,"UCWEB")||D(e,"UCBrowser")?F.UC_BROWSER:D(e,"CriOS")?F.CHROME_IOS:D(e,"CrMo")||D(e,F.CHROME)?F.CHROME:D(e,F.ANDROID)&&D(e,F.SAFARI)?F.ANDROID_MOBILE:D(e,"FxiOS")?F.FIREFOX_IOS:D(e.toLowerCase(),F.KONQUEROR.toLowerCase())?F.KONQUEROR:function(e,t){return t&&D(t,F.APPLE)||D(i=e,F.SAFARI)&&!D(i,F.CHROME)&&!D(i,F.ANDROID);var i}(e,t)?D(e,F.MOBILE)?F.MOBILE_SAFARI:F.SAFARI:D(e,F.FIREFOX)?F.FIREFOX:D(e,"MSIE")||D(e,"Trident/")?F.INTERNET_EXPLORER:D(e,"Gecko")?F.FIREFOX:""}const J={[F.INTERNET_EXPLORER_MOBILE]:[new RegExp("rv:"+B)],[F.MICROSOFT_EDGE]:[new RegExp(F.EDGE+"?\\/"+B)],[F.CHROME]:[new RegExp("("+F.CHROME+"|CrMo)\\/"+B)],[F.CHROME_IOS]:[new RegExp("CriOS\\/"+B)],[F.UC_BROWSER]:[new RegExp("(UCBrowser|UCWEB)\\/"+B)],[F.SAFARI]:[H],[F.MOBILE_SAFARI]:[H],[F.OPERA]:[new RegExp("("+F.OPERA+"|OPR)\\/"+B)],[F.FIREFOX]:[new RegExp(F.FIREFOX+"\\/"+B)],[F.FIREFOX_IOS]:[new RegExp("FxiOS\\/"+B)],[F.KONQUEROR]:[new RegExp("Konqueror[:/]?"+B,"i")],[F.BLACKBERRY]:[new RegExp(F.BLACKBERRY+" "+B),H],[F.ANDROID_MOBILE]:[new RegExp("android\\s"+B,"i")],[F.SAMSUNG_INTERNET]:[new RegExp(F.SAMSUNG_BROWSER+"\\/"+B)],[F.INTERNET_EXPLORER]:[new RegExp("(rv:|MSIE )"+B)],Mozilla:[new RegExp("rv:"+B)]};function Z(e,t){const i=K(e,t),n=J[i];if(a(n))return null;for(let s=0;s<n.length;s++){const t=n[s],i=e.match(t);if(i)return parseFloat(i[i.length-2])}return null}const Q=[[new RegExp(F.XBOX+"; "+F.XBOX+" (.*?)[);]","i"),e=>[F.XBOX,e&&e[1]||""]],[new RegExp(F.NINTENDO,"i"),[F.NINTENDO,""]],[new RegExp(F.PLAYSTATION,"i"),[F.PLAYSTATION,""]],[j,[F.BLACKBERRY,""]],[new RegExp(F.WINDOWS,"i"),(e,t)=>{if(/Phone/.test(t)||/WPDesktop/.test(t))return[F.WINDOWS_PHONE,""];if(new RegExp(F.MOBILE).test(t)&&!/IEMobile\b/.test(t))return[F.WINDOWS+" "+F.MOBILE,""];const i=/Windows NT ([0-9.]+)/i.exec(t);if(i&&i[1]){const e=i[1];let n=Y[e]||"";return/arm/i.test(t)&&(n="RT"),[F.WINDOWS,n]}return[F.WINDOWS,""]}],[/((iPhone|iPad|iPod).*?OS (\d+)_(\d+)_?(\d+)?|iPhone)/,e=>{if(e&&e[3]){const t=[e[3],e[4],e[5]||"0"];return[F.IOS,t.join(".")]}return[F.IOS,""]}],[/(watch.*\/(\d+\.\d+\.\d+)|watch os,(\d+\.\d+),)/i,e=>{let t="";return e&&e.length>=3&&(t=a(e[2])?e[3]:e[2]),["watchOS",t]}],[new RegExp("("+F.ANDROID+" (\\d+)\\.(\\d+)\\.?(\\d+)?|"+F.ANDROID+")","i"),e=>{if(e&&e[2]){const t=[e[2],e[3],e[4]||"0"];return[F.ANDROID,t.join(".")]}return[F.ANDROID,""]}],[/Mac OS X (\d+)[_.](\d+)[_.]?(\d+)?/i,e=>{const t=["Mac OS X",""];if(e&&e[1]){const i=[e[1],e[2],e[3]||"0"];t[1]=i.join(".")}return t}],[/Mac/i,["Mac OS X",""]],[/CrOS/,[F.CHROME_OS,""]],[/Linux|debian/i,["Linux",""]]];function ee(){const e=window.innerHeight||document.documentElement.clientHeight||document.body&&document.body.clientHeight||0,t=window.innerWidth||document.documentElement.clientWidth||document.body&&document.body.clientWidth||0,i=navigator.userAgent,n=function(e){for(let t=0;t<Q.length;t++){const[i,n]=Q[t],s=i.exec(e),r=s&&("function"==typeof n?n(s,e):n);if(r)return r}return["",""]}(i)||["",""];return{$browser:K(i),$browser_version:Z(i),$url:location?.href.substring(0,1e3),$host:location?.host,$viewport_height:e,$viewport_width:t,$lib:"webjs",$lib_version:w,$search_engine:$(),$referrer:M(),$referrer_host:m(r=r||M()),$title:document.title,$language:navigator.language,$model:(s=i,(X.test(s)?F.NINTENDO:W.test(s)?F.PLAYSTATION:U.test(s)?F.XBOX:new RegExp(F.OUYA,"i").test(s)?F.OUYA:new RegExp("("+F.WINDOWS_PHONE+"|WPDesktop)","i").test(s)?F.WINDOWS_PHONE:/iPad/.test(s)?F.IPAD:/iPod/.test(s)?"iPod Touch":/iPhone/.test(s)?"iPhone":/(watch)(?: ?os[,/]|\d,\d\/)[\d.]+/i.test(s)?F.APPLE_WATCH:j.test(s)?F.BLACKBERRY:/(kobo)\s(ereader|touch)/i.test(s)?"Kobo":new RegExp(F.NOKIA,"i").test(s)?F.NOKIA:/(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i.test(s)||/(kf[a-z]+)( bui|\)).+silk\//i.test(s)?"Kindle Fire":q.test(s)?F.HUAWEI:G.test(s)?F.XIAOMI:z.test(s)?F.OPPO:V.test(s)?F.VIVO:/(Android|ZTE)/i.test(s)?!new RegExp(F.MOBILE).test(s)||/(9138B|TB782B|Nexus [97]|pixel c|HUAWEISHT|BTV|noble nook|smart ultra 6)/i.test(s)?/pixel[\daxl ]{1,6}/i.test(s)&&!/pixel c/i.test(s)||/(huaweimed-al00|tah-|APA|SM-G92|i980|zte|U304AA)/i.test(s)||/lmy47v/i.test(s)&&!/QTAQZ3/i.test(s)?F.ANDROID:F.ANDROID_TABLET:F.ANDROID:new RegExp("(pda|"+F.MOBILE+")","i").test(s)?F.GENERIC_MOBILE:new RegExp(F.TABLET,"i").test(s)&&!new RegExp(F.TABLET+" pc","i").test(s)?F.GENERIC_TABLET:"")||""),$os:n?.[0]||"",$os_version:n?.[1]||"",$pathname:location?.pathname,$screen_height:Number(screen.height)||0,$screen_width:Number(screen.width)||0,$timezone_offset:60*-(new Date).getTimezoneOffset()};var s,r}const te=new class{constructor(){this.STORAGE_KEY="sensorswave_unsent_events",this.MAX_QUEUE_SIZE=200,this.MAX_RETRY_COUNT=1,this.MAX_AGE_MS=6048e5,this.queue=[],this.loadFromStorage(),this.cleanupExpiredItems()}loadFromStorage(){try{const e=localStorage.getItem(this.STORAGE_KEY);e&&(this.queue=d(e)||[])}catch(e){console.warn("Failed to load queue from localStorage:",e),this.queue=[]}}cleanupExpiredItems(){const e=Date.now(),t=this.queue.filter(t=>e-t.timestamp<this.MAX_AGE_MS);t.length!==this.queue.length&&(this.queue=t,this.saveToStorage())}saveToStorage(){try{this.cleanupExpiredItems(),this.queue.length>this.MAX_QUEUE_SIZE&&(this.queue=this.queue.slice(-this.MAX_QUEUE_SIZE)),localStorage.setItem(this.STORAGE_KEY,JSON.stringify(this.queue))}catch(e){console.warn("Failed to save queue to localStorage:",e)}}enqueue(e,t,i,n=this.MAX_RETRY_COUNT){try{const s={id:f(),url:e,data:t,headers:i,timestamp:Date.now(),retryCount:0,maxRetries:n};return this.queue.push(s),this.saveToStorage(),s.id}catch(s){return console.warn("Failed to enqueue request:",s),""}}dequeue(e){try{this.queue=this.queue.filter(t=>t.id!==e),this.saveToStorage()}catch(t){console.warn("Failed to dequeue request:",t)}}getAll(){try{return this.cleanupExpiredItems(),[...this.queue]}catch(e){return console.warn("Failed to get queue items:",e),[]}}incrementRetryCount(e){const t=this.queue.find(t=>t.id===e);return!(!t||t.retryCount>=t.maxRetries||(t.retryCount++,this.saveToStorage(),0))}clear(){this.queue=[];try{localStorage.removeItem(this.STORAGE_KEY)}catch(e){console.warn("Failed to clear queue from localStorage:",e)}}getItemById(e){return this.queue.find(t=>t.id===e)}};class ie{constructor(e={}){this.flushTimer=null,this.isFlushing=!1,this.paused=!1,this.destroyed=!1,this.config={maxBatchSize:e.maxBatchSize||20,flushInterval:e.flushInterval||5e3},this.startFlushTimer()}pause(){this.paused=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null)}resume(){this.paused&&(this.paused=!1,this.startFlushTimer())}isPaused(){return this.paused}add(){te.getAll().length>=this.config.maxBatchSize&&this.triggerFlush()}triggerFlush(){this.paused||this.isFlushing||(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.isFlushing=!0,this.flush())}flush(){const e=te.getAll();if(0===e.length)return this.isFlushing=!1,void this.startFlushTimer();const t=e.slice(0,this.config.maxBatchSize),i=[],n=[];t.forEach(e=>{Array.isArray(e.data)?i.push(...e.data):i.push(e.data),n.push(e.id)});const s=t[t.length-1],r=s.url,o=s.headers;S.instance&&S.instance.config.debug&&console.log(JSON.stringify(i,null,2)),L({url:r,method:"POST",data:i,headers:o,callback:e=>{200===e.statusCode?n.forEach(e=>{te.dequeue(e)}):P(e.statusCode)?console.error("Failed to send batch events:",e):n.forEach(e=>{te.dequeue(e)}),this.isFlushing=!1,this.startFlushTimer()}})}startFlushTimer(){this.destroyed||(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.flushTimer=setInterval(()=>{te.getAll().length>0&&this.triggerFlush()},this.config.flushInterval))}destroy(){this.destroyed=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.paused||this.flush()}}let ne=null;function se(){const e=S.instance;return!(!e||!e.__innerInited)||(console.warn("[SensorsWave] SDK is not initialized. Please call init() first."),!1)}function re(){const e=S.instance;return!e||"function"!=typeof e.hasOptedOutCapturing||!e.hasOptedOutCapturing()}let oe=null;function ae(){return b.isSupport()?(oe||(ne||(ne=new ie({maxBatchSize:20,flushInterval:5e3})),oe=ne),oe):null}function ce(e,t,i){if(re())return L({url:e,method:"POST",data:t.data,headers:t.headers,callback:e=>{if(200!==e.statusCode){if(!P(e.statusCode))return void(i&&te.dequeue(i));if(i&&te.incrementRetryCount(i)){const e=te.getItemById(i);if(e){const t=Math.min(1e3*Math.pow(2,e.retryCount),3e4);setTimeout(()=>{ce(e.url,{data:e.data,headers:e.headers},e.id)},t)}}}else i&&te.dequeue(i),t.callback&&t.callback(e.json)}})}function ue(e){return`${e.apiHost}/in/track`}function le(e){return`${e.apiHost}/ab/evalall`}function he(e){return{"Content-Type":"application/json",SourceToken:e.sourceToken}}function de(e,t,i){S.instance&&S.instance.config.debug&&console.log(JSON.stringify(t.data,null,2));const n=te.enqueue(e,t.data,t.headers);return ce(e,{...t,callback:void 0},n)}function pe(){try{const e=sessionStorage.getItem("sensorswave_utm");if(!e)return{};const t=JSON.parse(e),i={};return Object.entries(t).forEach(([e,t])=>{null!=t&&""!==t&&(i[`$${e}`]=t)}),i}catch(e){return{}}}function ge(e){const t={};return Object.entries(e).forEach(([e,i])=>{if("function"==typeof i)try{const n=i();t[e]=n}catch(n){console.warn("[SensorsWave] Failed to resolve dynamic property:",e,n)}else t[e]=i}),t}function fe(e={},t=!0){const i={...t?ee():{},...ge(N.getCommonProps()),...e},n=pe();return Object.keys(n).length>0&&Object.assign(i,n),i}function me(e,t,i=!0){if(!se())return;if(!re())return;const n={time:Date.now(),trace_id:N.getTraceId(),event:e.event,properties:fe(e.properties,i)},s=pe();Object.keys(s).length>0&&(n.user_properties||(n.user_properties={}),n.user_properties.$set||(n.user_properties.$set={}),Object.assign(n.user_properties.$set,s)),e.user_properties&&(e.user_properties.$set&&(n.user_properties=n.user_properties||{},n.user_properties.$set={...n.user_properties.$set||{},...e.user_properties.$set},delete e.user_properties.$set),n.user_properties={...n.user_properties,...e.user_properties});const r=N.getLoginId(),o=N.getAnonId();r&&(n.login_id=r),o&&(n.anon_id=o);const a=ue(t),c=he(t),u=!1!==t.batchSend&&ae();u?(te.enqueue(a,[n],c),u.add()):de(a,{data:[n],headers:c})}function Ee({userProps:e,opts:t}){if(!se())return;if(!re())return;const i=N.getLoginId(),n=N.getAnonId();if(!i&&!n)return;const s={time:Date.now(),trace_id:N.getTraceId(),event:"$UserSet",login_id:i,anon_id:n,user_properties:e,properties:fe()},r=ue(t),o=he(t),a=ae();if(!a)return de(r,{data:[s],headers:o});te.enqueue(r,[s],o),a.add()}function ve(e){return e.typ===C.FEATURE_GATE||e.typ===C.FEATURE_CONFIG?`$feature_${e.id}`:e.typ===C.EXPERIMENT?`$exp_${e.id}`:""}function be(e){const t=e.typ;return[C.FEATURE_GATE,C.EXPERIMENT,C.FEATURE_CONFIG].includes(t)?{[ve(e)]:e.vid}:{}}function _e(e){const t=e.typ;return t===C.FEATURE_GATE||t===C.FEATURE_CONFIG?{$feature_key:e.key,$feature_variant:e.vid}:t===C.EXPERIMENT?{$exp_key:e.key,$exp_variant:e.vid}:{}}function Ie({isUnset:e=!1,data:t,opts:i}){if(!se())return;if(!re())return;if(!t||u(t)||t.disable_impress)return;const n=N.getLoginId(),s=N.getAnonId();if(!n&&!s)return;const r=t.typ===C.EXPERIMENT?"$ExpImpress":"$FeatureImpress";let o={};return o=e?{$unset:{[ve(t)]:null}}:{$set:{...be(t)}},me({event:r,properties:_e(t),user_properties:o},i)}const Se="sensorswave_opt_out";class we{constructor(e){this.persist=e}read(){if(this.persist)try{const e=b.get(Se);return"0"===e||"1"!==e&&void 0}catch{return}}write(e){if(this.persist)try{b.set(Se,e?"0":"1")}catch{}}}class Oe{constructor({plugins:e,emitter:t,config:i,sdk:n}){this.plugins=[],this.pluginInsMap={},this.emitter=t,this.config=i,this.sdk=n,this.registerBuiltInPlugins(e),this.created(),this.emitter.on(O,()=>{this.init()})}registerBuiltInPlugins(e){for(let t=0,i=e.length;t<i;t++)this.registerPlugin(e[t])}registerPlugin(e){this.plugins.push(e)}getPlugins(){return this.plugins}getPlugin(e){return this.pluginInsMap[e]}created(){for(let e=0,t=this.plugins.length;e<t;e++){const t=this.plugins[e];if(!t.NAME)throw new Error('Plugin should be defined with "NAME"');const i=new t({emitter:this.emitter,config:this.config,sdk:this.sdk});this.pluginInsMap[t.NAME]=i}}init(){for(const e of Object.keys(this.pluginInsMap)){const t=this.pluginInsMap[e];t.init&&t.init()}}destroy(){for(const e of Object.keys(this.pluginInsMap)){const t=this.pluginInsMap[e];t.destroy&&"function"==typeof t.destroy&&t.destroy()}this.pluginInsMap={},this.plugins=[]}}const ye=class{constructor({emitter:e,config:t,sdk:i}){this.boundSend=null,this.hashEvent=null,this.spaSwitchHandler=null,this.emitter=e,this.config=t,this.sdk=i}init(){const e=this.config;this.boundSend=()=>{me({event:"$PageView",properties:{}},e)},this.sdk&&!0===this.sdk._postConsentInit||setTimeout(()=>{this.boundSend()},0),e.isSinglePageApp&&this.addSinglePageListener()}addSinglePageListener(){this.spaSwitchHandler=e=>{e!==location.href&&this.boundSend()},this.emitter.on(y,this.spaSwitchHandler)}destroy(){this.spaSwitchHandler&&(this.emitter.off(y,this.spaSwitchHandler),this.spaSwitchHandler=null),this.hashEvent&&this.boundSend&&(window.removeEventListener(this.hashEvent,this.boundSend),this.hashEvent=null),this.boundSend=null}};ye.NAME="pageview";let Ae=ye;const Re=class{constructor({emitter:e,config:t,sdk:i}){this.startTime=Date.now(),this.pageShowStatus=!0,this.pageHiddenStatus=!1,this.timer=null,this.currentPageUrl=document.referrer,this.url=location.href,this.title=document.title||"",this.heartbeatIntervalTime=5e3,this.heartbeatIntervalTimer=null,this.pageId=null,this.storageName="sensorswavewebjssdkpageleave",this.maxDuration=432e3,this.eventListeners=[],this._skipFirstPageEnd=!1,this.emitter=e,this.config=t,this.sdk=i}__canCapture(){return!this.sdk||"function"!=typeof this.sdk.hasOptedOutCapturing||!this.sdk.hasOptedOutCapturing()}init(){this.pageId=Number(String(g()).slice(2,5)+String(g()).slice(2,4)+String(Date.now()).slice(-4)),this.addEventListener(),this.sdk&&!0===this.sdk._postConsentInit&&(this._skipFirstPageEnd=!0),!0===document.hidden?this.pageShowStatus=!1:this.addHeartBeatInterval()}log(e){console.log(e)}refreshPageEndTimer(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.timer=setTimeout(()=>{this.pageHiddenStatus=!1},5e3)}hiddenStatusHandler(){this.timer&&clearTimeout(this.timer),this.timer=null,this.pageHiddenStatus=!1}pageStartHandler(){this.startTime=Date.now(),1==!document.hidden?this.pageShowStatus=!0:this.pageShowStatus=!1,this.url=location.href,this.title=document.title,this._skipFirstPageEnd=!1}pageEndHandler(){if(!0===this.pageHiddenStatus)return;if(!this.__canCapture())return;const e=this.getPageLeaveProperties();!1===this.pageShowStatus&&delete e.$event_duration,this.pageShowStatus=!1,this.pageHiddenStatus=!0,me({event:R,properties:e},this.config),this.refreshPageEndTimer(),this.delHeartBeatData()}addEventListener(){this.addPageStartListener(),this.addPageSwitchListener(),this.addSinglePageListener(),this.addPageEndListener()}addPageStartListener(){if("onpageshow"in window){const e=()=>{this.pageStartHandler(),this.hiddenStatusHandler()};window.addEventListener("pageshow",e),this.eventListeners.push({target:window,event:"pageshow",handler:e})}}addSinglePageListener(){this.config.isSinglePageApp&&this.emitter.on(y,e=>{e!==location.href&&(this.url=e,this.pageEndHandler(),this.stopHeartBeatInterval(),this.currentPageUrl=this.url,this.pageStartHandler(),this.hiddenStatusHandler(),this.addHeartBeatInterval())})}addPageEndListener(){["pagehide","beforeunload"].forEach(e=>{if(`on${e}`in window){const t=()=>{if(this._skipFirstPageEnd)return this._skipFirstPageEnd=!1,void this.stopHeartBeatInterval();this.pageEndHandler(),this.stopHeartBeatInterval()};window.addEventListener(e,t),this.eventListeners.push({target:window,event:e,handler:t})}})}addPageSwitchListener(){const e=()=>{"visible"===document.visibilityState?(this.pageStartHandler(),this.hiddenStatusHandler(),this.addHeartBeatInterval()):(this.url=location.href,this.title=document.title,this.stopHeartBeatInterval(),this.delHeartBeatData())};document.addEventListener("visibilitychange",e),this.eventListeners.push({target:document,event:"visibilitychange",handler:e})}addHeartBeatInterval(){b.isSupport()&&this.startHeartBeatInterval()}startHeartBeatInterval(){this.heartbeatIntervalTimer&&this.stopHeartBeatInterval(),this.sdk&&!0===this.sdk._postConsentInit&&!0===this._skipFirstPageEnd||(this.heartbeatIntervalTimer=setInterval(()=>{this.saveHeartBeatData()},this.heartbeatIntervalTime),this.saveHeartBeatData("is_first_heartbeat"),this.reissueHeartBeatData())}stopHeartBeatInterval(){this.heartbeatIntervalTimer&&clearInterval(this.heartbeatIntervalTimer),this.heartbeatIntervalTimer=null}saveHeartBeatData(e){if(!this.__canCapture())return;const t=this.getPageLeaveProperties();t.$time=Date.now(),"is_first_heartbeat"===e&&(t.$event_duration=3);const i={type:"track",event:R,properties:t,time:t.$time};i.heartbeat_interval_time=this.heartbeatIntervalTime,b.isSupport()&&b.set(`${this.storageName}-${this.pageId}`,JSON.stringify(i))}delHeartBeatData(e){b.isSupport()&&b.remove(e||`${this.storageName}-${this.pageId}`)}reissueHeartBeatData(){if(this.__canCapture())for(let e=window.localStorage.length-1;e>=0;e--){const t=window.localStorage.key(e);if(t&&t!==`${this.storageName}-${this.pageId}`&&0===t.indexOf(`${this.storageName}-`)){const e=b.parse(t);n(e)&&Date.now()-e.time>e.heartbeat_interval_time+5e3&&(delete e.heartbeat_interval_time,e._flush_time=(new Date).getTime(),me({event:R,properties:e?.properties},this.config),this.delHeartBeatData(t))}}}getPageLeaveProperties(){let e=(Date.now()-this.startTime)/1e3;(isNaN(e)||e<0||e>this.maxDuration)&&(e=0),e=Number(e.toFixed(3));const t={$title:this.title,$url:this.url?.substring(0,1e3),$pathname:I(this.url)};return 0!==e&&(t.$event_duration=e),t}destroy(){this.eventListeners.forEach(({target:e,event:t,handler:i})=>{e.removeEventListener(t,i)}),this.eventListeners=[],this.timer&&(clearTimeout(this.timer),this.timer=null),this.heartbeatIntervalTimer&&(clearInterval(this.heartbeatIntervalTimer),this.heartbeatIntervalTimer=null)}};Re.NAME="pageleave";let Te=Re;const Ce=class{constructor({emitter:e,config:t,sdk:i}){this.eventSended=!1,this.emitter=e,this.config=t,this.sdk=i}init(){if(this.sdk&&!0===this.sdk._postConsentInit)return;const e=()=>{let t=0;const i={};if(window.performance){t=function(){let e=0;if("function"==typeof performance.getEntriesByType){const t=performance.getEntriesByType("navigation");t.length>0&&(e=t[0].domContentLoadedEventEnd||0)}return e}();const e=function(){if(performance.getEntries&&"function"==typeof performance.getEntries){const e=performance.getEntries();let t=0;for(const i of e)"transferSize"in i&&(t+=i.transferSize);if("number"==typeof t&&t>=0&&t<10737418240)return Number((t/1024).toFixed(3))}}();e&&(i.$page_resource_size=e)}else console.warn("Performance API is not supported.");t>0&&!Number.isFinite(t)&&(i.$event_duration=Number((t/1e3).toFixed(3))),this.eventSended||(this.eventSended=!0,me({event:"$PageLoad",properties:i},this.config)),window.removeEventListener("load",e)};"complete"===document.readyState?e():window.addEventListener&&window.addEventListener("load",e)}};Ce.NAME="pageload";let Ne=Ce;function Pe(e){if(!l(e))return!1;const t=o(e.tagName)?e.tagName.toLowerCase():"",i={};return i.$element_type=t,i.$element_name=e.getAttribute("name")||"",i.$element_id=e.getAttribute("id")||"",i.$element_class_name=o(e.className)?e.className:"",i.$element_target_url=e.getAttribute("href")||"",i.$element_content=function(e,t){return o(t)&&"input"===t.toLowerCase()?("button"===(i=e).type||"submit"===i.type)&&i.value||"":function(e,t){let i="",n="";return e.textContent?i=_(e.textContent):e.innerText&&(i=_(e.innerText)),i&&(i=i.replace(/[\r\n]/g," ").replace(/[ ]+/g," ").substring(0,255)),n=i||"","input"!==t&&"INPUT"!==t||(n=e.value||""),n}(e,t);var i}(e,t)||"",i.$element_selector=ke(e)||"",i.$element_path=function(e){let t=[];for(;e.parentNode&&l(e);){if(!o(e.tagName))return"";if(e.id&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.id)){t.unshift(e.tagName.toLowerCase()+"#"+e.id);break}if(e===document.body){t.unshift("body");break}t.unshift(e.tagName.toLowerCase()),e=e.parentNode}return t.join(" > ")}(e)||"",i}function ke(e,t=[]){if(!(e&&e.parentNode&&e.parentNode.children&&o(e.tagName)))return"";t=Array.isArray(t)?t:[];const i=e.nodeName.toLowerCase();return e&&"body"!==i&&1==e.nodeType?(t.unshift(function(e){if(!e||!l(e)||!o(e.tagName))return"";let t=e.parentNode&&9==e.parentNode.nodeType?-1:function(e){if(!e.parentNode)return-1;let t=0;const i=e.tagName,n=e.parentNode.children;for(let s=0,r=n.length;s<r;s++)if(n[s].tagName===i){if(e===n[s])return t;t++}return-1}(e);return e.getAttribute&&e.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.getAttribute("id"))?"#"+e.getAttribute("id"):e.tagName.toLowerCase()+(~t?":nth-of-type("+(t+1)+")":"")}(e)),e.getAttribute&&e.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.getAttribute("id"))?t.join(" > "):ke(e.parentNode,t)):(t.unshift("body"),t.join(" > "))}function xe(){return{scrollLeft:document.body.scrollLeft||document.documentElement.scrollLeft||0,scrollTop:document.body.scrollTop||document.documentElement.scrollTop||0}}function Le(e){if(document.documentElement.getBoundingClientRect){const t=e.getBoundingClientRect();return{targetEleX:t.left+xe().scrollLeft||0,targetEleY:t.top+xe().scrollTop||0}}return{targetEleX:0,targetEleY:0}}function Me(e){return Number(Number(e).toFixed(3))}const $e=class{constructor({emitter:e,config:t}){this.isInitialized=!1,this.boundHandleClick=null,this.emitter=e,this.config=t}init(){this.isInitialized||(this.boundHandleClick=this.handleClick.bind(this),document.addEventListener("click",this.boundHandleClick,!0),this.isInitialized=!0)}handleClick(e){const t=e.target;if(!t)return;if(!["A","INPUT","BUTTON","TEXTAREA"].includes(t.tagName))return;if("true"===t.getAttribute("sensorswave-disable"))return;const i=function(e,t){const i=Pe(e);if(!i)return!1;const n=function(e,t){const i=t.pageX||t.clientX+xe().scrollLeft||t.offsetX+Le(e).targetEleX,n=t.pageY||t.clientY+xe().scrollTop||t.offsetY+Le(e).targetEleY;return{$page_x:Me(i),$page_y:Me(n)}}(e,t);return i.$page_x=n.$page_x,i.$page_y=n.$page_y,i}(t,e);me({event:"$WebClick",properties:i||{}},this.config)}destroy(){this.boundHandleClick&&(document.removeEventListener("click",this.boundHandleClick,!0),this.boundHandleClick=null),this.isInitialized=!1}};$e.NAME="webclick";let De=$e;const Fe=class{constructor({emitter:e,config:t,sdk:i}){this.updateInterval=null,this.fetchingPromise=null,this.emitter=e,this.config=t,this.sdk=i}init(){const e=this.config;if(e.enableAB){if(this.sdk&&"function"==typeof this.sdk.hasOptedOutCapturing&&this.sdk.hasOptedOutCapturing())return;this.fastFetch().then(()=>{this.emitter.emit(A)}),e.abRefreshInterval<3e4&&(e.abRefreshInterval=3e4),this.updateInterval=setInterval(()=>{this.fetchNewData().catch(console.warn)},e.abRefreshInterval)}}async fastFetch(){const e=N.getABData(this.config.abRefreshInterval);return e&&e.length?(this.emitter.emit(A),Promise.resolve(e)):this.fetchNewData()}async fetchNewData(){return this.fetchingPromise||(this.fetchingPromise=new Promise(e=>{!function({opts:e,cb:t}){if(!se())return void(t&&t({}));if(!re())return void(t&&t({}));const i=N.getLoginId(),n=N.getAnonId();if(!i&&!n)return void(t&&t({}));const s={user:{login_id:i||"",anon_id:n||"",props:{...ee(),...ge(N.getCommonProps())}},sdk:"webjs",sdk_version:w};L({url:le(e),method:"POST",data:s,headers:he(e),callback:e=>{200!==e.statusCode?(console.error("Failed to fetch feature flags"),t&&t({})):t&&t(e.json)}})}({opts:this.config,cb:t=>{N.saveABData(t?.data?.results||[]),e(t),this.fetchingPromise=null}})})),this.fetchingPromise}async getFeatureGate(e){return await this.fastFetch().catch(console.warn),N.getABData(this.config.abRefreshInterval).find(t=>t.typ===C.FEATURE_GATE&&t.key==e)}async checkFeatureGate(e){const t=await this.getFeatureGate(e);return!!t&&(!t.hasOwnProperty("vid")&&t.key?(Ie({isUnset:!0,data:t,opts:this.config}),!1):(Ie({data:t,opts:this.config}),"fail"!==t.vid))}async getExperiment(e){await this.fastFetch().catch(console.warn);const t=N.getABData(this.config.abRefreshInterval).find(t=>t.typ===C.EXPERIMENT&&t.key===e);return t?!t.hasOwnProperty("vid")&&t.key?(Ie({isUnset:!0,data:t,opts:this.config}),{}):(Ie({data:t,opts:this.config}),t?.value||{}):{}}async getFeatureConfig(e){await this.fastFetch().catch(console.warn);const t=N.getABData(this.config.abRefreshInterval).find(t=>t.typ===C.FEATURE_CONFIG&&t.key===e);if(!t)return{};if(!t.hasOwnProperty("vid")&&t.key)return Ie({isUnset:!0,data:t,opts:this.config}),{};Ie({data:t,opts:this.config});const i=t?.value;if(i){if(n(i))return i;try{return JSON.parse(i)}catch{return i}}return{}}destroy(){this.updateInterval&&(clearInterval(this.updateInterval),this.updateInterval=null),this.fetchingPromise=null}};Fe.NAME="abtest";let Be=Fe;const He=["utm_source","utm_medium","utm_campaign","utm_content","utm_term"],Ue="sensorswave_utm",We=class e{constructor({sdk:e,emitter:t,config:i}){this.sdk=e,this.emitter=t,this.config=i}init(){if(this.sdk&&!0===this.sdk._postConsentInit){let t=e.readFromSessionStorage();return t&&0!==Object.keys(t).length||(t=e.captureAndStore(this.config?.debug)),void this.scheduleInitialUTM(t)}const t=e.getUTMFromURL();e.saveToSessionStorage(t,this.config?.debug),this.scheduleInitialUTM(t)}scheduleInitialUTM(e){setTimeout(()=>{this.sendInitialUTM(e)},0)}static getUTMFromURL(){try{const e=new URLSearchParams(window.location.search),t={};return He.forEach(i=>{const n=e.get(i);n&&(t[i]=n)}),t}catch(t){return e.getUTMFromURLFallback()}}static getUTMFromURLFallback(){const e={};return window.location.search.substring(1).split("&").forEach(t=>{const[i,n]=t.split("="),s=decodeURIComponent(i),r=n?decodeURIComponent(n):"";He.includes(s)&&(e[s]=r)}),e}static readFromSessionStorage(){try{const e=sessionStorage.getItem(Ue);if(!e)return{};const t=JSON.parse(e);return t&&"object"==typeof t?t:{}}catch(e){return{}}}static saveToSessionStorage(e,t=!1){try{sessionStorage.setItem(Ue,JSON.stringify(e))}catch(i){t&&console.warn("[SensorsWave UTM] Failed to save to sessionStorage:",i)}}static captureAndStore(t=!1){const i=e.getUTMFromURL();return e.saveToSessionStorage(i,t),i}sendInitialUTM(e){const t={};He.forEach(i=>{t[`$initial_${i}`]=null!=e[i]?e[i]:""});try{this.sdk.profileSetOnce(t)}catch(i){this.config.debug&&console.warn("[SensorsWave UTM] Failed to send initial UTM:",i)}}destroy(){}};We.NAME="UTM";let Xe=We;const je=1e3,qe=/^\s*(?:async\s+)?at\s+(?:(.+)\s+\()?(.+?):(\d+):(\d+)\)?$/,Ge=/^(?:(.*)@)?(.+?):(\d+):(\d+)$/;function ze(e){let t=e;try{const e=location.origin;e&&0===t.indexOf(e)&&(t=t.substring(e.length))}catch(s){}const i=t.indexOf("?");i>-1&&(t=t.substring(0,i));const n=t.indexOf("#");return n>-1&&(t=t.substring(0,n)),t}function Ve(e){return e.map(e=>({platform:"web:javascript",filename:ze(e.file),function:e.fn||"?",lineno:Number(e.line),colno:Number(e.col),abs_path:Ye(e.file,1e3)}))}function Ye(e,t){return e.length>t?e.substring(0,t):e}function Ke(e){let t;if("string"==typeof e)t=e;else if(null!==e&&"object"==typeof e){try{t=JSON.stringify(e)}catch(i){t=Object.prototype.toString.call(e)}t||(t=Object.prototype.toString.call(e))}else t=String(e);return Ye(t,je)}function Je(e){const{frames:t,headerType:i}=function(e){const t=[];let i="";if(!e||"string"!=typeof e)return{frames:t,headerType:i};const n=e.split(/\r?\n/);for(let s=0;s<n.length;s++){const e=n[s];if(!e||e.length>1024)continue;const r=e.match(qe),o=r?null:e.match(Ge),a=r||o;if(a)t.push({fn:a[1]||"?",file:a[2],line:a[3],col:a[4]});else if(0===s){const t=e.indexOf(":");t>0&&(i=e.substring(0,t).trim())}if(t.length>=30)break}return{frames:t,headerType:i}}(e&&e.stack);let n=e&&e.name||i||"Error";return n=Ye(String(n),200),{$exception_level:"error",$exception_type:n,$exception_message:Ye(String(e&&e.message||""),je),$exception_frames:Ve(t)}}function Ze(e,t,i,n){let s=[];return t&&(s=[{platform:"web:javascript",filename:ze(t),function:"?",lineno:i||0,colno:n||0,abs_path:Ye(t,1e3)}]),{$exception_level:"error",$exception_type:"Error",$exception_message:Ye(String(e||""),je),$exception_frames:s}}class Qe{constructor(e=10,t=1,i=1e4){this.buckets=new Map,this.bucketSize=e,this.refillRate=t,this.refillInterval=i}allow(e){const t=Date.now();let i=this.buckets.get(e);if(i){if(t>i.lastRefill){const e=Math.floor((t-i.lastRefill)/this.refillInterval)*this.refillRate;e>0&&(i.tokens=Math.min(this.bucketSize,i.tokens+e),i.lastRefill+=e/this.refillRate*this.refillInterval)}}else i={tokens:this.bucketSize,lastRefill:t},this.buckets.set(e,i);return i.tokens>=1&&(i.tokens-=1,!0)}reset(){this.buckets.clear()}}const et=class{constructor({emitter:e,config:t}){this.isInitialized=!1,this.boundHandleError=null,this.boundHandleRejection=null,this.rateLimiter=new Qe,this.emitter=e,this.config=t}init(){this.isInitialized||(this.boundHandleError=this.handleError.bind(this),this.boundHandleRejection=this.handleRejection.bind(this),window.addEventListener("error",this.boundHandleError,!0),window.addEventListener("unhandledrejection",this.boundHandleRejection),this.isInitialized=!0)}handleError(e){try{const t=e.target;let i;if(t&&t!==window&&t.tagName)i=function(e){const t=e,i=(t.tagName||"").toLowerCase(),n=Ye(String(t.src||t.href||""),je);return{$exception_level:"error",$exception_type:"ResourceLoadError",$exception_message:`Failed to load <${i}>${n?` from ${n}`:""}`,$exception_frames:[]}}(t);else{const t=e;i=t.error instanceof Error?Je(t.error):Ze(String(t.message||""),t.filename,t.lineno,t.colno)}this.send(i)}catch(t){}}handleRejection(e){try{const t=e.reason;this.send(function(e){return e instanceof Error?Je(e):{$exception_level:"error",$exception_type:"UnhandledRejection",$exception_message:Ke(e),$exception_frames:[]}}(t))}catch(t){}}send(e){e.$exception_message&&this.rateLimiter.allow(e.$exception_type)&&me({event:T,properties:e},this.config)}destroy(){this.boundHandleError&&(window.removeEventListener("error",this.boundHandleError,!0),this.boundHandleError=null),this.boundHandleRejection&&(window.removeEventListener("unhandledrejection",this.boundHandleRejection),this.boundHandleRejection=null),this.rateLimiter.reset(),this.isInitialized=!1}};et.NAME="exception";let tt=et;const it="data-sw-exposure-event-name",nt="data-sw-exposure-config-",st=`[${it}]`,rt={visibleRatio:0,stayDuration:0,repeated:!0};function ot(e,t){const i={};if(!n(e))return i;const s=e;if(void 0!==s.visibleRatio){const e=Number(s.visibleRatio);!isNaN(e)&&e>=0&&e<=1?i.visibleRatio=e:t&&t("[exposure] parameter config.visibleRatio 非法(值域 0~1),已忽略:",s.visibleRatio)}if(void 0!==s.stayDuration){const e=Number(s.stayDuration);!isNaN(e)&&e>=0?i.stayDuration=e:t&&t("[exposure] parameter config.stayDuration 非法(须 >= 0),已忽略:",s.stayDuration)}if(void 0!==s.repeated){const e=s.repeated;!0===e||"true"===e?i.repeated=!0:!1===e||"false"===e?i.repeated=!1:t&&t("[exposure] parameter config.repeated 非法(须为布尔),已忽略:",e)}return i}function at(...e){const t={...rt};for(let i=0;i<e.length;i++){const s=e[i];if(!n(s))continue;const r=s;void 0!==r.visibleRatio&&(t.visibleRatio=r.visibleRatio),void 0!==r.stayDuration&&(t.stayDuration=r.stayDuration),void 0!==r.repeated&&(t.repeated=r.repeated)}return t}function ct(e){const t=(e.getAttribute(it)||"").trim();let i={},s={};const r=e.getAttribute("data-sw-exposure-option");if(r){const e=d(r);n(e)&&(n(e.config)&&(i=e.config),n(e.properties)&&(s=e.properties))}const a=e.getAttribute(nt+"visible-ratio");null!==a&&(i.visibleRatio=a);const c=e.getAttribute(nt+"stay-duration");null!==c&&(i.stayDuration=c);const u=e.getAttribute(nt+"repeated");null!==u&&(i.repeated=u);const l=e.attributes;for(let n=0;n<l.length;n++){const e=l[n],t=e.name;if(o(t)&&0===t.indexOf("data-sw-exposure-property-")){const i=t.substring(26);i&&(s[i]=e.value)}}return{eventName:t,config:ot(i),properties:s}}const ut=class{constructor({emitter:e,config:t,sdk:i}){this.isInitialized=!1,this.observers=new Map,this.records=new Map,this.mutationObserver=null,this.boundHandleIntersection=null,this.boundHandleMutation=null,this.boundHandleVisibility=null,this.boundHandleReady=null,this.boundHandleSpa=null,this.eventListeners=[],this.globalConfig={...rt},this.log=function(){},this.emitter=e,this.config=t,this.sdk=i}init(){this.isInitialized||(function(){try{return"undefined"!=typeof window&&"IntersectionObserver"in window&&"MutationObserver"in window}catch(e){return!1}}()?(this.log=!0==(!0===this.config.debug)&&"undefined"!=typeof console&&console.log?function(...e){console.log("[SensorsWave][exposure]",...e)}:function(){},this.globalConfig=at(this.globalConfig,ot(this.config.exposureConfig,this.log)),this.boundHandleIntersection=this.handleIntersection.bind(this),this.boundHandleMutation=this.handleMutation.bind(this),this.boundHandleVisibility=this.handleVisibility.bind(this),"loading"===document.readyState?(this.boundHandleReady=()=>{this.scanDocument(),this.observeMutations()},document.addEventListener("DOMContentLoaded",this.boundHandleReady),this.eventListeners.push({target:document,event:"DOMContentLoaded",handler:this.boundHandleReady})):(this.scanDocument(),this.observeMutations()),!0===this.config.isSinglePageApp&&(this.boundHandleSpa=e=>{this.handleSpaSwitch(e)},this.emitter.on(y,this.boundHandleSpa)),document.addEventListener("visibilitychange",this.boundHandleVisibility),this.eventListeners.push({target:document,event:"visibilitychange",handler:this.boundHandleVisibility}),!0===document.hidden&&this.stop(),this.isInitialized=!0):console.warn("[SensorsWave][exposure] 当前浏览器不支持 IntersectionObserver / MutationObserver,曝光采集未初始化"))}addExposureView(e,t){this.isInitialized?l(e)?n(t)&&o(t.eventName)&&t.eventName.trim()?this.addOrUpdateWatchEle(e,{eventName:t.eventName.trim(),config:n(t.config)?ot(t.config,this.log):void 0,properties:n(t.properties)?{...t.properties}:{},listener:n(t.listener)?{...t.listener}:{}},"api"):this.log("addExposureView parameter option.eventName 缺失:",t):this.log("addExposureView parameter element 非法:",e):this.log("曝光插件未初始化(enableExposureTrack 未开启或浏览器不支持)")}removeExposureView(e){this.isInitialized?l(e)?this.removeWatchEle(e):this.log("removeExposureView parameter element 非法:",e):this.log("曝光插件未初始化")}scanDocument(e){try{const t=e||document;if(!t.querySelectorAll)return;const i=t.querySelectorAll(st);for(let e=0;e<i.length;e++){const t=i[e];this.addOrUpdateWatchEle(t,ct(t),"attr")}}catch(t){}}addOrUpdateWatchEle(e,t,i){if(!e||!l(e))return void this.log("parameter element error:",e);if(!o(t.eventName)||!t.eventName.trim())return void this.log("parameter option.eventName error:",t);const n=this.records.get(e);if(n&&"api"===n.source&&"attr"===i)return void this.log("声明式属性变更被忽略:元素已由 addExposureView 注册",e);const s=at(this.globalConfig,n&&n.config,t.config);if(n&&n.config.visibleRatio===s.visibleRatio)return n.eventName=t.eventName,n.source=i,n.config=s,n.properties={...t.properties||{}},n.listener=t.listener||{},void(n.hasSent=!1);n&&this.removeWatchEle(e);const r={ele:e,eventName:t.eventName,source:i,config:s,properties:{...t.properties||{}},listener:t.listener||{},timer:null,hasSent:!1};this.records.set(e,r),this.getIntersection(s.visibleRatio).observe(e)}getIntersection(e){let t=this.observers.get(e);return!t&&this.boundHandleIntersection&&(t=new IntersectionObserver(this.boundHandleIntersection,{threshold:e}),this.observers.set(e,t)),t}removeWatchEle(e){const t=this.records.get(e);if(!t)return;const i=this.observers.get(t.config.visibleRatio);i&&l(e)&&i.unobserve(e),t.timer&&(clearTimeout(t.timer),t.timer=null),this.records.delete(e)}handleIntersection(e){try{for(const t of e){const e=t.target,i=this.records.get(e);i&&(!0===t.isIntersecting&&t.intersectionRatio>=i.config.visibleRatio?!0!==document.hidden&&(i.timer&&clearTimeout(i.timer),i.timer=setTimeout(()=>{this.fireExposure(e)},1e3*i.config.stayDuration)):i.timer&&(clearTimeout(i.timer),i.timer=null))}}catch(t){}}fireExposure(e){try{const i=this.records.get(e);if(i&&(i.timer=null),!i||i.hasSent)return;let n={width:0,height:0};try{n=e.getBoundingClientRect()}catch(t){}if(!n.width||!n.height)return;if(!e.isConnected)return void this.removeWatchEle(e);if(this.sdk&&"function"==typeof this.sdk.hasOptedOutCapturing&&this.sdk.hasOptedOutCapturing())return;const r={...Pe(e),...i.properties},{shouldExpose:o,didExpose:a}=i.listener||{};if(o&&s(o))try{if(!1===o(e,r))return}catch(t){return}if(me({event:i.eventName,properties:r},this.config),i.hasSent=!0,i.config.repeated&&(i.hasSent=!1),a&&s(a))try{a(e,r)}catch(t){}}catch(t){}}observeMutations(){!this.mutationObserver&&this.boundHandleMutation&&(this.mutationObserver=new MutationObserver(this.boundHandleMutation),this.mutationObserver.observe(document.body,{attributes:!0,childList:!0,subtree:!0}))}handleMutation(e){try{for(const t of e)if("childList"===t.type){if(t.removedNodes.length>0)for(const e of Array.from(t.removedNodes)){if(1!==e.nodeType)continue;this.removeWatchEle(e);const t=e.querySelectorAll(st);for(let e=0;e<t.length;e++)this.removeWatchEle(t[e])}if(t.addedNodes.length>0)for(const e of Array.from(t.addedNodes))1===e.nodeType&&(e.hasAttribute(it)&&this.addOrUpdateWatchEle(e,ct(e),"attr"),this.scanDocument(e))}else"attributes"===t.type&&this.handleAttrChange(t)}catch(t){}}handleAttrChange(e){const t=e.attributeName;if(!t||0!==t.indexOf("data-sw-exposure"))return;const i=e.target;t!==it||(i.getAttribute(t)||"").trim()?(i.getAttribute(it)||"").trim()&&this.addOrUpdateWatchEle(i,ct(i),"attr"):this.removeWatchEle(i)}handleSpaSwitch(e){try{if(e===location.href)return;this.stop();for(const[e,t]of Array.from(this.records))"attr"===t.source&&this.records.delete(e);this.start(),this.scanDocument()}catch(t){}}stop(){for(const e of Array.from(this.records.values())){const t=this.observers.get(e.config.visibleRatio);t&&t.unobserve(e.ele),e.timer&&(clearTimeout(e.timer),e.timer=null)}}start(){for(const e of Array.from(this.records.values())){if(!e.ele.isConnected){this.records.delete(e.ele);continue}const t=this.observers.get(e.config.visibleRatio);t&&t.observe(e.ele)}}handleVisibility(){try{"visible"===document.visibilityState?this.start():this.stop()}catch(e){}}destroy(){this.observers.forEach(e=>{try{e.disconnect()}catch(t){}}),this.observers.clear(),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null);for(const e of Array.from(this.records.values()))e.timer&&(clearTimeout(e.timer),e.timer=null);this.records.clear(),this.eventListeners.forEach(({target:e,event:t,handler:i})=>{e.removeEventListener(t,i)}),this.eventListeners=[],this.boundHandleSpa&&(this.emitter.off(y,this.boundHandleSpa),this.boundHandleSpa=null),this.boundHandleIntersection=null,this.boundHandleMutation=null,this.boundHandleVisibility=null,this.boundHandleReady=null,this.globalConfig={...rt},this.log=function(){},this.isInitialized=!1}};ut.NAME="exposure";let lt=ut;const ht=[],dt={debug:!1,sourceToken:"",apiHost:"",autoCapture:!0,isSinglePageApp:!1,crossSubdomainCookie:!0,enableAB:!1,abRefreshInterval:6e5,enableClickTrack:!1,enableExposureTrack:!1,batchSend:!1,enableErrorTrack:!1,enableCrashTrack:!1,optOutCapturing:!1,persistOptOut:!1},pt=new class{constructor(){this.__innerInited=!1,this.inited=!1,this.config={},this.eventEmitter=new e,this.pluginCore={},this.commonProps={},this.spaCleanup=null,this._optOutCapturing=!1,this.consentStorage=new we(!1),this._setupAfterConsentDone=!1,this._postConsentInit=!1,S.instance=this}init(e,t={}){return this.inited?this:(S.instance=this,t.sourceToken=e,this.mergeConfig(t),this.consentStorage=new we(!0===this.config.persistOptOut),this._optOutCapturing?this.consentStorage.write(!0):!0===this.config.optOutCapturing?(this._optOutCapturing=!0,this.consentStorage.write(!0)):!0===this.consentStorage.read()&&(this._optOutCapturing=!0),this.eventEmitter.emit("init-param",this.config),this.__innerInited=!0,this._optOutCapturing?(Xe.captureAndStore(this.config.debug),this.eventEmitter.emit(O),this.inited=!0,this):(this.__setupAfterConsent(),this.eventEmitter.emit(O),this.inited=!0,this))}__setupAfterConsent(){if(this._setupAfterConsentDone)return;this._setupAfterConsentDone=!0;const e=this.config;ht.length=0,N.init(e.crossSubdomainCookie),e.anonId&&N.setAnonId(e.anonId),function(){if(window._swFailedRequestsInitialized)return;window._swFailedRequestsInitialized=!0;const e=S.instance;e&&"function"==typeof e.hasOptedOutCapturing&&e.hasOptedOutCapturing()||e&&!0===e._postConsentInit||function(){const e=te.getAll();if(0!==e.length)for(let t=0,i=e.length;t<i;t+=10){const i=e.slice(t,t+10),n=[],s=[];i.forEach(e=>{Array.isArray(e.data)?n.push(...e.data):n.push(e.data),s.push(e.id)});const r=i[i.length-1],o=r.url,a=r.headers;L({url:o,method:"POST",data:n,headers:a,callback:e=>{200!==e.statusCode?(console.error("Failed to send batch stored requests:",e),P(e.statusCode)||s.forEach(e=>{te.dequeue(e)})):s.forEach(e=>{te.dequeue(e)})}})}}()}(),ht.push(Xe),e.autoCapture&&this.autoTrack(),e.enableAB&&ht.push(Be),e.enableClickTrack&&ht.push(De),e.enableCrashTrack&&e.debug&&console.warn("[SensorsWave] enableCrashTrack 仅在 app 宿主环境生效,当前 Web 环境不采集 crash"),e.enableErrorTrack&&ht.push(tt),e.enableExposureTrack&&ht.push(lt),this.pluginCore=new Oe({plugins:ht,emitter:this.eventEmitter,config:e,sdk:this}),this.spaCleanup=function(e){let t=location.href;const i=window.history.pushState,n=window.history.replaceState,r=function(){e(t),t=location.href};return s(window.history.pushState)&&(window.history.pushState=function(...n){i.apply(window.history,n),e(t),t=location.href}),s(window.history.replaceState)&&(window.history.replaceState=function(...i){n.apply(window.history,i),e(t),t=location.href}),window.addEventListener("popstate",r),function(){s(window.history.pushState)&&(window.history.pushState=i),s(window.history.replaceState)&&(window.history.replaceState=n),window.removeEventListener("popstate",r)}}(e=>{this.eventEmitter.emit(y,e)})}mergeConfig(e){this.config={...dt,...e}}__canCapture(){return this.inited&&!this._optOutCapturing}track(e){this.__canCapture()&&function(e,t){if(!se())return;if(!re())return;const i={...e};i.time||(i.time=Date.now()),i.login_id||(i.login_id=N.getLoginId()),i.anon_id||(i.anon_id=N.getAnonId()),i.trace_id||(i.trace_id=N.getTraceId()),i.properties={...ee(),...ge(N.getCommonProps()),...i.properties};const n=ue(t),s=he(t),r=!1!==t.batchSend&&ae();if(!r)return de(n,{data:[i],headers:s});te.enqueue(n,[i],s),r.add()}(e,this.config)}trackEvent(e,t){this.__canCapture()&&me({event:e,properties:t},this.config)}trackException(e,t){if(!this.__canCapture())return;const i={...t||{},...e instanceof Error?Je(e):Ze(String(e))};me({event:T,properties:i},this.config)}addExposureView(e,t){if(!this.__canCapture())return;const i=this.pluginCore.getPlugin(lt.NAME);i?i.addExposureView(e,t):console.warn("[SensorsWave] addExposureView 需在 init 时配置 enableExposureTrack: true")}removeExposureView(e){if(!this.__canCapture())return;const t=this.pluginCore.getPlugin(lt.NAME);t&&t.removeExposureView(e)}autoTrack(){ht.push(Ae,Ne,Te)}profileSet(e){this.__canCapture()&&Ee({userProps:{$set:e},opts:this.config})}profileSetOnce(e){this.__canCapture()&&Ee({userProps:{$set_once:e},opts:this.config})}profileIncrement(e){this.__canCapture()&&Ee({userProps:{$increment:e},opts:this.config})}profileAppend(e){this.__canCapture()&&Ee({userProps:{$append:e},opts:this.config})}profileUnion(e){this.__canCapture()&&Ee({userProps:{$union:e},opts:this.config})}profileUnset(e){if(!this.__canCapture())return;const t={};r(e)?e.forEach(function(e){t[e]=null}):t[e]=null,Ee({userProps:{$unset:t},opts:this.config})}profileDelete(){this.__canCapture()&&Ee({userProps:{$delete:!0},opts:this.config})}registerCommonProperties(e){if(!n(e))return console.warn("Commmon Properties must be an object!");this.commonProps=e,N.setCommonProps(this.commonProps)}clearCommonProperties(e){if(!r(e))return console.warn("Commmon Properties to be cleared must be an array!");e.forEach(e=>{delete this.commonProps[e]}),N.setCommonProps(this.commonProps)}identify(e){this.__canCapture()&&(N.setLoginId(e),function(e){if(!se())return;if(!re())return;const t=N.getLoginId(),i=N.getAnonId();if(!t||!i)return;const n={time:Date.now(),trace_id:N.getTraceId(),event:"$Identify",login_id:t,anon_id:i,properties:fe()},s=ue(e),r=he(e),o=ae();if(!o)return de(s,{data:[n],headers:r});te.enqueue(s,[n],r),o.add()}(this.config))}setLoginId(e){this.__canCapture()&&N.setLoginId(e)}getAnonId(){return this.__canCapture()?N.getAnonId():""}setAnonId(e){this.__canCapture()&&N.setAnonId(e)}getLoginId(){return this.__canCapture()?N.getLoginId():""}reset(e=!1){this.__canCapture()&&(N.clearLoginId(),e&&N.resetAnonId())}checkFeatureGate(e){if(!this.__canCapture())return Promise.resolve(!1);const t=this.pluginCore.getPlugin(Be.NAME);return this.config.enableAB&&t?t.checkFeatureGate(e):Promise.reject("AB is disabled")}getExperiment(e){if(!this.__canCapture())return Promise.resolve({});const t=this.pluginCore.getPlugin(Be.NAME);return this.config.enableAB&&t?t.getExperiment(e):Promise.reject("AB is disabled")}getFeatureConfig(e){if(!this.__canCapture())return Promise.resolve({});const t=this.pluginCore.getPlugin(Be.NAME);return this.config.enableAB&&t?t.getFeatureConfig(e):Promise.reject("AB is disabled")}optOutCapturing(){this._optOutCapturing=!0,this.consentStorage.write(!0),oe&&oe.pause()}optInCapturing(){if(this._optOutCapturing=!1,this.consentStorage.write(!1),oe&&oe.resume(),this.inited&&!this._setupAfterConsentDone){this._postConsentInit=!0;try{this.__setupAfterConsent(),this.eventEmitter.emit(O)}finally{this._postConsentInit=!1}}}hasOptedOutCapturing(){return this._optOutCapturing}destroy(){oe&&(oe.destroy(),oe=null),"undefined"!=typeof window&&(window._swFailedRequestsInitialized=!1),this.inited=!1,this.__innerInited=!1,this.spaCleanup&&"function"==typeof this.spaCleanup&&(this.spaCleanup(),this.spaCleanup=null),this.pluginCore&&"function"==typeof this.pluginCore.destroy&&this.pluginCore.destroy(),this.pluginCore={},this.eventEmitter&&this.eventEmitter.removeAllListeners(),this.consentStorage=new we(!0===this.config?.persistOptOut),this._optOutCapturing=!1,this._setupAfterConsentDone=!1,this._postConsentInit=!1,S.instance===this&&(S.instance=null)}};module.exports=pt;
|
package/dist/index.es.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class t{constructor(){this.listeners={}}on(t,e,n=!1){if(t&&e){if(!s(e))throw new Error("listener must be a function");this.listeners[t]=this.listeners[t]||[],this.listeners[t].push({listener:e,once:n})}}off(t,e){const n=this.listeners[t];if(!n?.length)return;"number"==typeof e&&n.splice(e,1);const i=n.findIndex(t=>t.listener===e);-1!==i&&n.splice(i,1)}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((n,i)=>{n.listener.call(this,...e),n.listener.once&&this.off(t,i)})}once(t,e){this.on(t,e,!0)}removeAllListeners(t){t?this.listeners[t]=[]:this.listeners={}}}const e={get:function(t){const e=t+"=",n=document.cookie.split(";");for(let i=0,s=n.length;i<s;i++){let t=n[i];for(;" "==t.charAt(0);)t=t.substring(1,t.length);if(0==t.indexOf(e))return h(t.substring(e.length,t.length))}return null},set:function({name:t,value:e,expires:n,samesite:i,secure:s,domain:r}){let o="",a="",c="",u="";if(0!==(n=null==n||void 0===n?365:n)){const t=/* @__PURE__ */new Date;"s"===String(n).slice(-1)?t.setTime(t.getTime()+1e3*Number(String(n).slice(0,-1))):t.setTime(t.getTime()+24*n*60*60*1e3),o="; expires="+t.toUTCString()}function l(t){return t?t.replace(/\r\n/g,""):""}i&&(c="; SameSite="+i),s&&(a="; secure");const h=l(t),d=l(e),p=l(r);p&&(u="; domain="+p),h&&d&&(document.cookie=h+"="+encodeURIComponent(d)+o+"; path=/"+u+c+a)},remove:function(t){this.set({name:t,value:"",expires:-1})},isSupport:function({samesite:t,secure:e}={}){if(!navigator.cookieEnabled)return!1;const n="sensorswave_cookie_support_test";return this.set({name:n,value:"1",samesite:t,secure:e}),"1"===this.get(n)&&(this.remove(n),!0)}},n=Object.prototype.toString;function i(t){return"[object Object]"===n.call(t)}function s(t){const e=n.call(t);return"[object Function]"==e||"[object AsyncFunction]"==e}function r(t){return"[object Array]"==n.call(t)}function o(t){return"[object String]"==n.call(t)}function a(t){return void 0===t}const c=Object.prototype.hasOwnProperty;function u(t){if(i(t)){for(let e in t)if(c.call(t,e))return!1;return!0}return!1}function l(t){return!(!t||1!==t.nodeType)}function h(t){let e=t;try{e=decodeURIComponent(t)}catch(n){e=t}return e}function d(t){try{return JSON.parse(t)}catch(e){return""}}const p=function(){let t=Date.now();return function(e){return Math.ceil((t=(9301*t+49297)%233280,t/233280*e))}}();function g(){if("function"==typeof Uint32Array){let t;if("undefined"!=typeof crypto&&(t=crypto),t&&i(t)&&t.getRandomValues)return t.getRandomValues(new Uint32Array(1))[0]/Math.pow(2,32)}return p(1e19)/1e19}const f=/* @__PURE__ */function(){function t(t){return("0".repeat(t)+Date.now().toString(16)).slice(-t)}return function(){let e=String(screen.height*screen.width);e=e&&/\d{4,}/.test(e)?e.slice(-4):String(31242*g()).replace(".","").slice(0,4);return t(8)+"-"+g().toString(16).replace(".","").slice(-4)+"-"+function(){const t=navigator.userAgent;let e,n=[],i=0;function s(t,e){let i=0;for(let s=0;s<e.length;s++)i|=n[s]<<8*s;return(t^i)>>>0}for(let r=0;r<t.length;r++)e=t.charCodeAt(r),n.unshift(255&e),n.length>=4&&(i=s(i,n),n=[]);return n.length>0&&(i=s(i,n)),("0000"+i.toString(16)).slice(-4)}()+"-"+e+"-"+t(12)||(String(g())+String(g())+String(g())).slice(2,15)}}();function m(t,e){e&&"string"==typeof e||(e="");let n=null;try{n=new URL(t).hostname}catch(i){}return n||e}function E(t){let e=[];try{e=atob(t).split("").map(function(t){return"%"+("00"+t.charCodeAt(0).toString(16)).slice(-2)})}catch(n){e=[]}try{return decodeURIComponent(e.join(""))}catch(n){return e.join("")}}function _(t){let e="";try{e=btoa(encodeURIComponent(t).replace(/%([0-9A-F]{2})/g,function(t,e){return String.fromCharCode(parseInt(e,16))}))}catch(n){e=t}return e}const I={get:function(t){return window.localStorage.getItem(t)},parse:function(t){let e;try{e=JSON.parse(I.get(t))||null}catch(n){console.warn(n)}return e},set:function(t,e){try{window.localStorage.setItem(t,e)}catch(n){console.warn(n)}},remove:function(t){window.localStorage.removeItem(t)},isSupport:function(){let t=!0;try{const e="__local_store_support__",n="testIsSupportStorage";I.set(e,n),I.get(e)!==n&&(t=!1),I.remove(e)}catch(e){t=!1}return t}};function S(t){return t.trim()}function w(t){if(!t||"string"!=typeof t)return"";try{return new URL(t,window.location.origin).pathname}catch(e){return""}}const O={},v="1.4.0",b="init-ready",y="spa-switch",A="ff-ready",R="$PageLeave",T="$Exception";var C=/* @__PURE__ */(t=>(t[t.FEATURE_GATE=1]="FEATURE_GATE",t[t.FEATURE_CONFIG=2]="FEATURE_CONFIG",t[t.EXPERIMENT=3]="EXPERIMENT",t))(C||{});const N={crossSubdomain:!1,requests:[],_sessionState:{},_abData:[],_trace_id:"",commonProps:{},_state:{anon_id:"",login_id:"",identities:{}},getIdentityCookieID(){return this._state.identities?.$identity_cookie_id||""},getCommonProps:function(){return this.commonProps||{}},setCommonProps:function(t){this.commonProps=t},getAnonId(){return this._state.anon_id||this.getIdentityCookieID()||f()},getLoginId(){return this._state.login_id},getTraceId(){return this._trace_id||f()},set:function(t,e){this._state[t]=e,this.save()},getCookieName:function(){return"sensorswave2025jssdkcross"},getABLSName:function(){return"sensorswave2025jssdkablatest"},save:function(){let t=JSON.parse(JSON.stringify(this._state));t.identities&&(t.identities=_(JSON.stringify(t.identities)));const n=JSON.stringify(t);e.set({name:this.getCookieName(),value:n,expires:365})},init:function(t){let n,s;this.crossSubdomain=t,e.isSupport()&&(n=e.get(this.getCookieName()),s=d(n)),N._state={...s||{}},N._state.identities&&(N._state.identities=d(E(N._state.identities))),N._state.identities&&i(N._state.identities)&&!u(N._state.identities)||(N._state.identities={$identity_cookie_id:f()}),N.save()},setLoginId(t){"number"==typeof t&&(t=String(t)),void 0!==t&&t&&(N.set("login_id",t),N.save())},clearLoginId(){this._state.login_id="",this.save()},resetAnonId(){this._state.anon_id="",this._state.identities={$identity_cookie_id:f()},this.save()},setAnonId(t){"number"==typeof t&&(t=String(t)),"string"==typeof t&&t?(N.set("anon_id",t),N.save()):console.warn("[SensorsWave store] Invalid anonId, ignored:",t)},saveABData(t){if(!t||u(t))return;this._abData=t;let e=JSON.parse(JSON.stringify(this._abData));e=_(JSON.stringify(e));try{localStorage.setItem(this.getABLSName(),JSON.stringify({time:Date.now(),data:e,anon_id:this.getAnonId(),login_id:this.getLoginId()}))}catch(n){console.warn("Failed to save abdata to localStorage",n)}},getABData(t=6e5){try{let e=localStorage.getItem(this.getABLSName());if(e){const{time:n,data:i,login_id:s,anon_id:r}=d(e)||{};if(n&&i&&Date.now()-n<t&&r===this.getAnonId()&&(!s||s===this.getLoginId())){const t=d(E(i));return this._abData=Array.isArray(t)?t:[],this._abData}localStorage.removeItem(this.getABLSName())}}catch(e){this._abData=[]}return this._abData||[]}};function P(t){return!(t>=400&&t<500)||408===t||429===t}function k(t){var e;if(t.data)return{contentType:"application/json",body:(e=t.data,JSON.stringify(e,(t,e)=>"bigint"==typeof e?e.toString():e,undefined))}}const L=[];function $(t){const e={...t};e.timeout=e.timeout||6e4;const n=e.transport??"fetch",i=L.find(t=>t.transport===n)?.method??L[0]?.method;if(!i)throw new Error("No available transport method for HTTP request");i(e)}function F(t){return o(t=t||document.referrer)&&(t=h(t=t.trim()))||""}function B(t){const e=m(t=t||F());if(!e)return"";const n={baidu:[/^.*\.baidu\.com$/],bing:[/^.*\.bing\.com$/],google:[/^www\.google\.com$/,/^www\.google\.com\.[a-z]{2}$/,/^www\.google\.[a-z]{2}$/],sm:[/^m\.sm\.cn$/],so:[/^.+\.so\.com$/],sogou:[/^.*\.sogou\.com$/],yahoo:[/^.*\.yahoo\.com$/],duckduckgo:[/^.*\.duckduckgo\.com$/]};for(let i of Object.keys(n)){let t=n[i];for(let n=0,s=t.length;n<s;n++)if(t[n].test(e))return i}return""}function x(t,e){return-1!==t.indexOf(e)}"function"==typeof fetch&&L.push({transport:"fetch",method:function(t){if("undefined"==typeof fetch)return void console.error("fetch API is not available");const e=k(t),n=new Headers;t.headers&&Object.keys(t.headers).forEach(e=>{n.append(e,t.headers[e])}),e?.contentType&&n.append("Content-Type",e.contentType),fetch(t.url,{method:t.method||"GET",headers:n,body:e?.body}).then(e=>e.text().then(n=>{const i={statusCode:e.status,text:n};if(200===e.status)try{i.json=JSON.parse(n)}catch(s){console.error("Failed to parse response:",s)}t.callback?.(i)})).catch(e=>{console.error("Request failed:",e),t.callback?.({statusCode:0,text:String(e)})})}}),"undefined"!=typeof XMLHttpRequest&&L.push({transport:"XHR",method:function(t){if("undefined"==typeof XMLHttpRequest)return void console.error("XMLHttpRequest is not available");const e=new XMLHttpRequest;e.open(t.method||"GET",t.url,!0);const n=k(t);t.headers&&Object.keys(t.headers).forEach(n=>{e.setRequestHeader(n,t.headers[n])}),n?.contentType&&e.setRequestHeader("Content-Type",n.contentType),e.timeout=t.timeout||6e4,e.withCredentials=!0,e.onreadystatechange=()=>{if(4===e.readyState){const i={statusCode:e.status,text:e.responseText};if(200===e.status)try{i.json=JSON.parse(e.responseText)}catch(n){console.error("Failed to parse JSON response:",n)}t.callback?.(i)}},e.send(n?.body)}});const M={FACEBOOK:"Facebook",MOBILE:"Mobile",IOS:"iOS",ANDROID:"Android",TABLET:"Tablet",ANDROID_TABLET:"Android Tablet",IPAD:"iPad",APPLE:"Apple",APPLE_WATCH:"Apple Watch",SAFARI:"Safari",BLACKBERRY:"BlackBerry",SAMSUNG_BROWSER:"SamsungBrowser",SAMSUNG_INTERNET:"Samsung Internet",CHROME:"Chrome",CHROME_OS:"Chrome OS",CHROME_IOS:"Chrome iOS",INTERNET_EXPLORER:"Internet Explorer",INTERNET_EXPLORER_MOBILE:"Internet Explorer Mobile",OPERA:"Opera",OPERA_MINI:"Opera Mini",EDGE:"Edge",MICROSOFT_EDGE:"Microsoft Edge",FIREFOX:"Firefox",FIREFOX_IOS:"Firefox iOS",NINTENDO:"Nintendo",PLAYSTATION:"PlayStation",XBOX:"Xbox",ANDROID_MOBILE:"Android Mobile",MOBILE_SAFARI:"Mobile Safari",WINDOWS:"Windows",WINDOWS_PHONE:"Windows Phone",NOKIA:"Nokia",OUYA:"Ouya",GENERIC_MOBILE:"Generic mobile",GENERIC_TABLET:"Generic tablet",KONQUEROR:"Konqueror",UC_BROWSER:"UC Browser",HUAWEI:"Huawei",XIAOMI:"Xiaomi",OPPO:"OPPO",VIVO:"vivo"},D="(\\d+(\\.\\d+)?)",H=new RegExp("Version/"+D),U=new RegExp(M.XBOX,"i"),X=new RegExp(M.PLAYSTATION+" \\w+","i"),j=new RegExp(M.NINTENDO+" \\w+","i"),q=new RegExp(M.BLACKBERRY+"|PlayBook|BB10","i"),W=new RegExp("(HUAWEI|honor|HONOR)","i"),G=new RegExp("(Xiaomi|Redmi)","i"),z=new RegExp("(OPPO|realme)","i"),Y=new RegExp("(vivo|IQOO)","i"),K={"NT3.51":"NT 3.11","NT4.0":"NT 4.0","5.0":"2000",5.1:"XP",5.2:"XP","6.0":"Vista",6.1:"7",6.2:"8",6.3:"8.1",6.4:"10","10.0":"10"};function J(t,e){return e=e||"",x(t," OPR/")&&x(t,"Mini")?M.OPERA_MINI:x(t," OPR/")?M.OPERA:q.test(t)?M.BLACKBERRY:x(t,"IE"+M.MOBILE)||x(t,"WPDesktop")?M.INTERNET_EXPLORER_MOBILE:x(t,M.SAMSUNG_BROWSER)?M.SAMSUNG_INTERNET:x(t,M.EDGE)||x(t,"Edg/")?M.MICROSOFT_EDGE:x(t,"FBIOS")?M.FACEBOOK+" "+M.MOBILE:x(t,"UCWEB")||x(t,"UCBrowser")?M.UC_BROWSER:x(t,"CriOS")?M.CHROME_IOS:x(t,"CrMo")||x(t,M.CHROME)?M.CHROME:x(t,M.ANDROID)&&x(t,M.SAFARI)?M.ANDROID_MOBILE:x(t,"FxiOS")?M.FIREFOX_IOS:x(t.toLowerCase(),M.KONQUEROR.toLowerCase())?M.KONQUEROR:function(t,e){return e&&x(e,M.APPLE)||x(n=t,M.SAFARI)&&!x(n,M.CHROME)&&!x(n,M.ANDROID);var n}(t,e)?x(t,M.MOBILE)?M.MOBILE_SAFARI:M.SAFARI:x(t,M.FIREFOX)?M.FIREFOX:x(t,"MSIE")||x(t,"Trident/")?M.INTERNET_EXPLORER:x(t,"Gecko")?M.FIREFOX:""}const Z={[M.INTERNET_EXPLORER_MOBILE]:[new RegExp("rv:"+D)],[M.MICROSOFT_EDGE]:[new RegExp(M.EDGE+"?\\/"+D)],[M.CHROME]:[new RegExp("("+M.CHROME+"|CrMo)\\/"+D)],[M.CHROME_IOS]:[new RegExp("CriOS\\/"+D)],[M.UC_BROWSER]:[new RegExp("(UCBrowser|UCWEB)\\/"+D)],[M.SAFARI]:[H],[M.MOBILE_SAFARI]:[H],[M.OPERA]:[new RegExp("("+M.OPERA+"|OPR)\\/"+D)],[M.FIREFOX]:[new RegExp(M.FIREFOX+"\\/"+D)],[M.FIREFOX_IOS]:[new RegExp("FxiOS\\/"+D)],[M.KONQUEROR]:[new RegExp("Konqueror[:/]?"+D,"i")],[M.BLACKBERRY]:[new RegExp(M.BLACKBERRY+" "+D),H],[M.ANDROID_MOBILE]:[new RegExp("android\\s"+D,"i")],[M.SAMSUNG_INTERNET]:[new RegExp(M.SAMSUNG_BROWSER+"\\/"+D)],[M.INTERNET_EXPLORER]:[new RegExp("(rv:|MSIE )"+D)],Mozilla:[new RegExp("rv:"+D)]};function Q(t,e){const n=J(t,e),i=Z[n];if(a(i))return null;for(let s=0;s<i.length;s++){const e=i[s],n=t.match(e);if(n)return parseFloat(n[n.length-2])}return null}const V=[[new RegExp(M.XBOX+"; "+M.XBOX+" (.*?)[);]","i"),t=>[M.XBOX,t&&t[1]||""]],[new RegExp(M.NINTENDO,"i"),[M.NINTENDO,""]],[new RegExp(M.PLAYSTATION,"i"),[M.PLAYSTATION,""]],[q,[M.BLACKBERRY,""]],[new RegExp(M.WINDOWS,"i"),(t,e)=>{if(/Phone/.test(e)||/WPDesktop/.test(e))return[M.WINDOWS_PHONE,""];if(new RegExp(M.MOBILE).test(e)&&!/IEMobile\b/.test(e))return[M.WINDOWS+" "+M.MOBILE,""];const n=/Windows NT ([0-9.]+)/i.exec(e);if(n&&n[1]){const t=n[1];let i=K[t]||"";return/arm/i.test(e)&&(i="RT"),[M.WINDOWS,i]}return[M.WINDOWS,""]}],[/((iPhone|iPad|iPod).*?OS (\d+)_(\d+)_?(\d+)?|iPhone)/,t=>{if(t&&t[3]){const e=[t[3],t[4],t[5]||"0"];return[M.IOS,e.join(".")]}return[M.IOS,""]}],[/(watch.*\/(\d+\.\d+\.\d+)|watch os,(\d+\.\d+),)/i,t=>{let e="";return t&&t.length>=3&&(e=a(t[2])?t[3]:t[2]),["watchOS",e]}],[new RegExp("("+M.ANDROID+" (\\d+)\\.(\\d+)\\.?(\\d+)?|"+M.ANDROID+")","i"),t=>{if(t&&t[2]){const e=[t[2],t[3],t[4]||"0"];return[M.ANDROID,e.join(".")]}return[M.ANDROID,""]}],[/Mac OS X (\d+)[_.](\d+)[_.]?(\d+)?/i,t=>{const e=["Mac OS X",""];if(t&&t[1]){const n=[t[1],t[2],t[3]||"0"];e[1]=n.join(".")}return e}],[/Mac/i,["Mac OS X",""]],[/CrOS/,[M.CHROME_OS,""]],[/Linux|debian/i,["Linux",""]]];function tt(){const t=window.innerHeight||document.documentElement.clientHeight||document.body&&document.body.clientHeight||0,e=window.innerWidth||document.documentElement.clientWidth||document.body&&document.body.clientWidth||0,n=navigator.userAgent,i=function(t){for(let e=0;e<V.length;e++){const[n,i]=V[e],s=n.exec(t),r=s&&("function"==typeof i?i(s,t):i);if(r)return r}return["",""]}(n)||["",""];return{$browser:J(n),$browser_version:Q(n),$url:location?.href.substring(0,1e3),$host:location?.host,$viewport_height:t,$viewport_width:e,$lib:"webjs",$lib_version:v,$search_engine:B(),$referrer:F(),$referrer_host:m(r=r||F()),$title:document.title,$language:navigator.language,$model:(s=n,(j.test(s)?M.NINTENDO:X.test(s)?M.PLAYSTATION:U.test(s)?M.XBOX:new RegExp(M.OUYA,"i").test(s)?M.OUYA:new RegExp("("+M.WINDOWS_PHONE+"|WPDesktop)","i").test(s)?M.WINDOWS_PHONE:/iPad/.test(s)?M.IPAD:/iPod/.test(s)?"iPod Touch":/iPhone/.test(s)?"iPhone":/(watch)(?: ?os[,/]|\d,\d\/)[\d.]+/i.test(s)?M.APPLE_WATCH:q.test(s)?M.BLACKBERRY:/(kobo)\s(ereader|touch)/i.test(s)?"Kobo":new RegExp(M.NOKIA,"i").test(s)?M.NOKIA:/(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i.test(s)||/(kf[a-z]+)( bui|\)).+silk\//i.test(s)?"Kindle Fire":W.test(s)?M.HUAWEI:G.test(s)?M.XIAOMI:z.test(s)?M.OPPO:Y.test(s)?M.VIVO:/(Android|ZTE)/i.test(s)?!new RegExp(M.MOBILE).test(s)||/(9138B|TB782B|Nexus [97]|pixel c|HUAWEISHT|BTV|noble nook|smart ultra 6)/i.test(s)?/pixel[\daxl ]{1,6}/i.test(s)&&!/pixel c/i.test(s)||/(huaweimed-al00|tah-|APA|SM-G92|i980|zte|U304AA)/i.test(s)||/lmy47v/i.test(s)&&!/QTAQZ3/i.test(s)?M.ANDROID:M.ANDROID_TABLET:M.ANDROID:new RegExp("(pda|"+M.MOBILE+")","i").test(s)?M.GENERIC_MOBILE:new RegExp(M.TABLET,"i").test(s)&&!new RegExp(M.TABLET+" pc","i").test(s)?M.GENERIC_TABLET:"")||""),$os:i?.[0]||"",$os_version:i?.[1]||"",$pathname:location?.pathname,$screen_height:Number(screen.height)||0,$screen_width:Number(screen.width)||0,$timezone_offset:60*-/* @__PURE__ */(new Date).getTimezoneOffset()};var s,r}const et=new class{constructor(){this.STORAGE_KEY="sensorswave_unsent_events",this.MAX_QUEUE_SIZE=200,this.MAX_RETRY_COUNT=1,this.MAX_AGE_MS=6048e5,this.queue=[],this.loadFromStorage(),this.cleanupExpiredItems()}loadFromStorage(){try{const t=localStorage.getItem(this.STORAGE_KEY);t&&(this.queue=d(t)||[])}catch(t){console.warn("Failed to load queue from localStorage:",t),this.queue=[]}}cleanupExpiredItems(){const t=Date.now(),e=this.queue.filter(e=>t-e.timestamp<this.MAX_AGE_MS);e.length!==this.queue.length&&(this.queue=e,this.saveToStorage())}saveToStorage(){try{this.cleanupExpiredItems(),this.queue.length>this.MAX_QUEUE_SIZE&&(this.queue=this.queue.slice(-this.MAX_QUEUE_SIZE)),localStorage.setItem(this.STORAGE_KEY,JSON.stringify(this.queue))}catch(t){console.warn("Failed to save queue to localStorage:",t)}}enqueue(t,e,n,i=this.MAX_RETRY_COUNT){try{const s={id:f(),url:t,data:e,headers:n,timestamp:Date.now(),retryCount:0,maxRetries:i};return this.queue.push(s),this.saveToStorage(),s.id}catch(s){return console.warn("Failed to enqueue request:",s),""}}dequeue(t){try{this.queue=this.queue.filter(e=>e.id!==t),this.saveToStorage()}catch(e){console.warn("Failed to dequeue request:",e)}}getAll(){try{return this.cleanupExpiredItems(),[...this.queue]}catch(t){return console.warn("Failed to get queue items:",t),[]}}incrementRetryCount(t){const e=this.queue.find(e=>e.id===t);return!(!e||e.retryCount>=e.maxRetries||(e.retryCount++,this.saveToStorage(),0))}clear(){this.queue=[];try{localStorage.removeItem(this.STORAGE_KEY)}catch(t){console.warn("Failed to clear queue from localStorage:",t)}}getItemById(t){return this.queue.find(e=>e.id===t)}};class nt{constructor(t={}){this.flushTimer=null,this.isFlushing=!1,this.paused=!1,this.destroyed=!1,this.config={maxBatchSize:t.maxBatchSize||20,flushInterval:t.flushInterval||5e3},this.startFlushTimer()}pause(){this.paused=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null)}resume(){this.paused&&(this.paused=!1,this.startFlushTimer())}isPaused(){return this.paused}add(){et.getAll().length>=this.config.maxBatchSize&&this.triggerFlush()}triggerFlush(){this.paused||this.isFlushing||(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.isFlushing=!0,this.flush())}flush(){const t=et.getAll();if(0===t.length)return this.isFlushing=!1,void this.startFlushTimer();const e=t.slice(0,this.config.maxBatchSize),n=[],i=[];e.forEach(t=>{Array.isArray(t.data)?n.push(...t.data):n.push(t.data),i.push(t.id)});const s=e[e.length-1],r=s.url,o=s.headers;O.instance&&O.instance.config.debug&&console.log(JSON.stringify(n,null,2)),$({url:r,method:"POST",data:n,headers:o,callback:t=>{200===t.statusCode?i.forEach(t=>{et.dequeue(t)}):P(t.statusCode)?console.error("Failed to send batch events:",t):i.forEach(t=>{et.dequeue(t)}),this.isFlushing=!1,this.startFlushTimer()}})}startFlushTimer(){this.destroyed||(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.flushTimer=setInterval(()=>{et.getAll().length>0&&this.triggerFlush()},this.config.flushInterval))}destroy(){this.destroyed=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.paused||this.flush()}}let it=null;function st(){const t=O.instance;return!(!t||!t.__innerInited)||(console.warn("[SensorsWave] SDK is not initialized. Please call init() first."),!1)}function rt(){const t=O.instance;return!t||"function"!=typeof t.hasOptedOutCapturing||!t.hasOptedOutCapturing()}let ot=null;function at(){return I.isSupport()?(ot||(it||(it=new nt({maxBatchSize:20,flushInterval:5e3})),ot=it),ot):null}function ct(t,e,n){if(rt())return $({url:t,method:"POST",data:e.data,headers:e.headers,callback:t=>{if(200!==t.statusCode){if(!P(t.statusCode))return void(n&&et.dequeue(n));if(n&&et.incrementRetryCount(n)){const t=et.getItemById(n);if(t){const e=Math.min(1e3*Math.pow(2,t.retryCount),3e4);setTimeout(()=>{ct(t.url,{data:t.data,headers:t.headers},t.id)},e)}}}else n&&et.dequeue(n),e.callback&&e.callback(t.json)}})}function ut(t){return`${t.apiHost}/in/track`}function lt(t){return`${t.apiHost}/ab/evalall`}function ht(t){return{"Content-Type":"application/json",SourceToken:t.sourceToken}}function dt(t,e,n){O.instance&&O.instance.config.debug&&console.log(JSON.stringify(e.data,null,2));const i=et.enqueue(t,e.data,e.headers);return ct(t,{...e,callback:void 0},i)}function pt(){try{const t=sessionStorage.getItem("sensorswave_utm");if(!t)return{};const e=JSON.parse(t),n={};return Object.entries(e).forEach(([t,e])=>{null!=e&&""!==e&&(n[`$${t}`]=e)}),n}catch(t){return{}}}function gt(t){const e={};return Object.entries(t).forEach(([t,n])=>{if("function"==typeof n)try{const i=n();e[t]=i}catch(i){console.warn("[SensorsWave] Failed to resolve dynamic property:",t,i)}else e[t]=n}),e}function ft(t={},e=!0){const n={...e?tt():{},...gt(N.getCommonProps()),...t},i=pt();return Object.keys(i).length>0&&Object.assign(n,i),n}function mt(t,e,n=!0){if(!st())return;if(!rt())return;const i={time:Date.now(),trace_id:N.getTraceId(),event:t.event,properties:ft(t.properties,n)},s=pt();Object.keys(s).length>0&&(i.user_properties||(i.user_properties={}),i.user_properties.$set||(i.user_properties.$set={}),Object.assign(i.user_properties.$set,s)),t.user_properties&&(t.user_properties.$set&&(i.user_properties=i.user_properties||{},i.user_properties.$set={...i.user_properties.$set||{},...t.user_properties.$set},delete t.user_properties.$set),i.user_properties={...i.user_properties,...t.user_properties});const r=N.getLoginId(),o=N.getAnonId();r&&(i.login_id=r),o&&(i.anon_id=o);const a=ut(e),c=ht(e),u=!1!==e.batchSend&&at();u?(et.enqueue(a,[i],c),u.add()):dt(a,{data:[i],headers:c})}function Et({userProps:t,opts:e}){if(!st())return;if(!rt())return;const n=N.getLoginId(),i=N.getAnonId();if(!n&&!i)return;const s={time:Date.now(),trace_id:N.getTraceId(),event:"$UserSet",login_id:n,anon_id:i,user_properties:t,properties:ft()},r=ut(e),o=ht(e),a=at();if(!a)return dt(r,{data:[s],headers:o});et.enqueue(r,[s],o),a.add()}function _t(t){return t.typ===C.FEATURE_GATE||t.typ===C.FEATURE_CONFIG?`$feature_${t.id}`:t.typ===C.EXPERIMENT?`$exp_${t.id}`:""}function It(t){const e=t.typ;return[C.FEATURE_GATE,C.EXPERIMENT,C.FEATURE_CONFIG].includes(e)?{[_t(t)]:t.vid}:{}}function St(t){const e=t.typ;return e===C.FEATURE_GATE||e===C.FEATURE_CONFIG?{$feature_key:t.key,$feature_variant:t.vid}:e===C.EXPERIMENT?{$exp_key:t.key,$exp_variant:t.vid}:{}}function wt({isUnset:t=!1,data:e,opts:n}){if(!st())return;if(!rt())return;if(!e||u(e)||e.disable_impress)return;const i=N.getLoginId(),s=N.getAnonId();if(!i&&!s)return;const r=e.typ===C.EXPERIMENT?"$ExpImpress":"$FeatureImpress";let o={};return o=t?{$unset:{[_t(e)]:null}}:{$set:{...It(e)}},mt({event:r,properties:St(e),user_properties:o},n)}const Ot="sensorswave_opt_out";class vt{constructor(t){this.persist=t}read(){if(this.persist)try{const t=I.get(Ot);return"0"===t||"1"!==t&&void 0}catch{return}}write(t){if(this.persist)try{I.set(Ot,t?"0":"1")}catch{}}}class bt{constructor({plugins:t,emitter:e,config:n,sdk:i}){this.plugins=[],this.pluginInsMap={},this.emitter=e,this.config=n,this.sdk=i,this.registerBuiltInPlugins(t),this.created(),this.emitter.on(b,()=>{this.init()})}registerBuiltInPlugins(t){for(let e=0,n=t.length;e<n;e++)this.registerPlugin(t[e])}registerPlugin(t){this.plugins.push(t)}getPlugins(){return this.plugins}getPlugin(t){return this.pluginInsMap[t]}created(){for(let t=0,e=this.plugins.length;t<e;t++){const e=this.plugins[t];if(!e.NAME)throw new Error('Plugin should be defined with "NAME"');const n=new e({emitter:this.emitter,config:this.config,sdk:this.sdk});this.pluginInsMap[e.NAME]=n}}init(){for(const t of Object.keys(this.pluginInsMap)){const e=this.pluginInsMap[t];e.init&&e.init()}}destroy(){for(const t of Object.keys(this.pluginInsMap)){const e=this.pluginInsMap[t];e.destroy&&"function"==typeof e.destroy&&e.destroy()}this.pluginInsMap={},this.plugins=[]}}const yt=class{constructor({emitter:t,config:e,sdk:n}){this.boundSend=null,this.hashEvent=null,this.spaSwitchHandler=null,this.emitter=t,this.config=e,this.sdk=n}init(){const t=this.config;this.boundSend=()=>{mt({event:"$PageView",properties:{}},t)},this.sdk&&!0===this.sdk._postConsentInit||setTimeout(()=>{this.boundSend()},0),t.isSinglePageApp&&this.addSinglePageListener()}addSinglePageListener(){this.spaSwitchHandler=t=>{t!==location.href&&this.boundSend()},this.emitter.on(y,this.spaSwitchHandler)}destroy(){this.spaSwitchHandler&&(this.emitter.off(y,this.spaSwitchHandler),this.spaSwitchHandler=null),this.hashEvent&&this.boundSend&&(window.removeEventListener(this.hashEvent,this.boundSend),this.hashEvent=null),this.boundSend=null}};yt.NAME="pageview";let At=yt;const Rt=class{constructor({emitter:t,config:e,sdk:n}){this.startTime=Date.now(),this.pageShowStatus=!0,this.pageHiddenStatus=!1,this.timer=null,this.currentPageUrl=document.referrer,this.url=location.href,this.title=document.title||"",this.heartbeatIntervalTime=5e3,this.heartbeatIntervalTimer=null,this.pageId=null,this.storageName="sensorswavewebjssdkpageleave",this.maxDuration=432e3,this.eventListeners=[],this._skipFirstPageEnd=!1,this.emitter=t,this.config=e,this.sdk=n}__canCapture(){return!this.sdk||"function"!=typeof this.sdk.hasOptedOutCapturing||!this.sdk.hasOptedOutCapturing()}init(){this.pageId=Number(String(g()).slice(2,5)+String(g()).slice(2,4)+String(Date.now()).slice(-4)),this.addEventListener(),this.sdk&&!0===this.sdk._postConsentInit&&(this._skipFirstPageEnd=!0),!0===document.hidden?this.pageShowStatus=!1:this.addHeartBeatInterval()}log(t){console.log(t)}refreshPageEndTimer(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.timer=setTimeout(()=>{this.pageHiddenStatus=!1},5e3)}hiddenStatusHandler(){this.timer&&clearTimeout(this.timer),this.timer=null,this.pageHiddenStatus=!1}pageStartHandler(){this.startTime=Date.now(),1==!document.hidden?this.pageShowStatus=!0:this.pageShowStatus=!1,this.url=location.href,this.title=document.title,this._skipFirstPageEnd=!1}pageEndHandler(){if(!0===this.pageHiddenStatus)return;if(!this.__canCapture())return;const t=this.getPageLeaveProperties();!1===this.pageShowStatus&&delete t.$event_duration,this.pageShowStatus=!1,this.pageHiddenStatus=!0,mt({event:R,properties:t},this.config),this.refreshPageEndTimer(),this.delHeartBeatData()}addEventListener(){this.addPageStartListener(),this.addPageSwitchListener(),this.addSinglePageListener(),this.addPageEndListener()}addPageStartListener(){if("onpageshow"in window){const t=()=>{this.pageStartHandler(),this.hiddenStatusHandler()};window.addEventListener("pageshow",t),this.eventListeners.push({target:window,event:"pageshow",handler:t})}}addSinglePageListener(){this.config.isSinglePageApp&&this.emitter.on(y,t=>{t!==location.href&&(this.url=t,this.pageEndHandler(),this.stopHeartBeatInterval(),this.currentPageUrl=this.url,this.pageStartHandler(),this.hiddenStatusHandler(),this.addHeartBeatInterval())})}addPageEndListener(){["pagehide","beforeunload"].forEach(t=>{if(`on${t}`in window){const e=()=>{if(this._skipFirstPageEnd)return this._skipFirstPageEnd=!1,void this.stopHeartBeatInterval();this.pageEndHandler(),this.stopHeartBeatInterval()};window.addEventListener(t,e),this.eventListeners.push({target:window,event:t,handler:e})}})}addPageSwitchListener(){const t=()=>{"visible"===document.visibilityState?(this.pageStartHandler(),this.hiddenStatusHandler(),this.addHeartBeatInterval()):(this.url=location.href,this.title=document.title,this.stopHeartBeatInterval())};document.addEventListener("visibilitychange",t),this.eventListeners.push({target:document,event:"visibilitychange",handler:t})}addHeartBeatInterval(){I.isSupport()&&this.startHeartBeatInterval()}startHeartBeatInterval(){this.heartbeatIntervalTimer&&this.stopHeartBeatInterval(),this.sdk&&!0===this.sdk._postConsentInit&&!0===this._skipFirstPageEnd||(this.heartbeatIntervalTimer=setInterval(()=>{this.saveHeartBeatData()},this.heartbeatIntervalTime),this.saveHeartBeatData("is_first_heartbeat"),this.reissueHeartBeatData())}stopHeartBeatInterval(){this.heartbeatIntervalTimer&&clearInterval(this.heartbeatIntervalTimer),this.heartbeatIntervalTimer=null}saveHeartBeatData(t){if(!this.__canCapture())return;const e=this.getPageLeaveProperties();e.$time=Date.now(),"is_first_heartbeat"===t&&(e.$event_duration=3);const n={type:"track",event:R,properties:e,time:e.$time};n.heartbeat_interval_time=this.heartbeatIntervalTime,I.isSupport()&&I.set(`${this.storageName}-${this.pageId}`,JSON.stringify(n))}delHeartBeatData(t){I.isSupport()&&I.remove(t||`${this.storageName}-${this.pageId}`)}reissueHeartBeatData(){if(this.__canCapture())for(let t=window.localStorage.length-1;t>=0;t--){const e=window.localStorage.key(t);if(e&&e!==`${this.storageName}-${this.pageId}`&&0===e.indexOf(`${this.storageName}-`)){const t=I.parse(e);i(t)&&Date.now()-t.time>t.heartbeat_interval_time+5e3&&(delete t.heartbeat_interval_time,t._flush_time=/* @__PURE__ */(new Date).getTime(),mt({event:R,properties:t?.properties},this.config),this.delHeartBeatData(e))}}}getPageLeaveProperties(){let t=(Date.now()-this.startTime)/1e3;(isNaN(t)||t<0||t>this.maxDuration)&&(t=0),t=Number(t.toFixed(3));const e={$title:this.title,$url:this.url?.substring(0,1e3),$pathname:w(this.url)};return 0!==t&&(e.$event_duration=t),e}destroy(){this.eventListeners.forEach(({target:t,event:e,handler:n})=>{t.removeEventListener(e,n)}),this.eventListeners=[],this.timer&&(clearTimeout(this.timer),this.timer=null),this.heartbeatIntervalTimer&&(clearInterval(this.heartbeatIntervalTimer),this.heartbeatIntervalTimer=null)}};Rt.NAME="pageleave";let Tt=Rt;const Ct=class{constructor({emitter:t,config:e,sdk:n}){this.eventSended=!1,this.emitter=t,this.config=e,this.sdk=n}init(){if(this.sdk&&!0===this.sdk._postConsentInit)return;const t=()=>{let e=0;const n={};if(window.performance){e=function(){let t=0;if("function"==typeof performance.getEntriesByType){const e=performance.getEntriesByType("navigation");e.length>0&&(t=e[0].domContentLoadedEventEnd||0)}return t}();const t=function(){if(performance.getEntries&&"function"==typeof performance.getEntries){const t=performance.getEntries();let e=0;for(const n of t)"transferSize"in n&&(e+=n.transferSize);if("number"==typeof e&&e>=0&&e<10737418240)return Number((e/1024).toFixed(3))}}();t&&(n.$page_resource_size=t)}else console.warn("Performance API is not supported.");e>0&&!Number.isFinite(e)&&(n.$event_duration=Number((e/1e3).toFixed(3))),this.eventSended||(this.eventSended=!0,mt({event:"$PageLoad",properties:n},this.config)),window.removeEventListener("load",t)};"complete"===document.readyState?t():window.addEventListener&&window.addEventListener("load",t)}};Ct.NAME="pageload";let Nt=Ct;function Pt(t,e){if(!l(t))return!1;const n=o(t.tagName)?t.tagName.toLowerCase():"",i={};i.$element_type=n,i.$element_name=t.getAttribute("name")||"",i.$element_id=t.getAttribute("id")||"",i.$element_class_name=o(t.className)?t.className:"",i.$element_target_url=t.getAttribute("href")||"",i.$element_content=function(t,e){return o(e)&&"input"===e.toLowerCase()?("button"===(n=t).type||"submit"===n.type)&&n.value||"":function(t,e){let n="",i="";return t.textContent?n=S(t.textContent):t.innerText&&(n=S(t.innerText)),n&&(n=n.replace(/[\r\n]/g," ").replace(/[ ]+/g," ").substring(0,255)),i=n||"","input"!==e&&"INPUT"!==e||(i=t.value||""),i}(t,e);var n}(t,n)||"",i.$element_selector=kt(t)||"",i.$element_path=function(t){let e=[];for(;t.parentNode&&l(t);){if(!o(t.tagName))return"";if(t.id&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(t.id)){e.unshift(t.tagName.toLowerCase()+"#"+t.id);break}if(t===document.body){e.unshift("body");break}e.unshift(t.tagName.toLowerCase()),t=t.parentNode}return e.join(" > ")}(t)||"";const s=function(t,e){const n=e.pageX||e.clientX+Lt().scrollLeft||e.offsetX+$t(t).targetEleX,i=e.pageY||e.clientY+Lt().scrollTop||e.offsetY+$t(t).targetEleY;return{$page_x:Ft(n),$page_y:Ft(i)}}(t,e);return i.$page_x=s.$page_x,i.$page_y=s.$page_y,i}function kt(t,e=[]){if(!(t&&t.parentNode&&t.parentNode.children&&o(t.tagName)))return"";e=Array.isArray(e)?e:[];const n=t.nodeName.toLowerCase();return t&&"body"!==n&&1==t.nodeType?(e.unshift(function(t){if(!t||!l(t)||!o(t.tagName))return"";let e=t.parentNode&&9==t.parentNode.nodeType?-1:function(t){if(!t.parentNode)return-1;let e=0;const n=t.tagName,i=t.parentNode.children;for(let s=0,r=i.length;s<r;s++)if(i[s].tagName===n){if(t===i[s])return e;e++}return-1}(t);return t.getAttribute&&t.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(t.getAttribute("id"))?"#"+t.getAttribute("id"):t.tagName.toLowerCase()+(~e?":nth-of-type("+(e+1)+")":"")}(t)),t.getAttribute&&t.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(t.getAttribute("id"))?e.join(" > "):kt(t.parentNode,e)):(e.unshift("body"),e.join(" > "))}function Lt(){return{scrollLeft:document.body.scrollLeft||document.documentElement.scrollLeft||0,scrollTop:document.body.scrollTop||document.documentElement.scrollTop||0}}function $t(t){if(document.documentElement.getBoundingClientRect){const e=t.getBoundingClientRect();return{targetEleX:e.left+Lt().scrollLeft||0,targetEleY:e.top+Lt().scrollTop||0}}return{targetEleX:0,targetEleY:0}}function Ft(t){return Number(Number(t).toFixed(3))}const Bt=class{constructor({emitter:t,config:e}){this.isInitialized=!1,this.boundHandleClick=null,this.emitter=t,this.config=e}init(){this.isInitialized||(this.boundHandleClick=this.handleClick.bind(this),document.addEventListener("click",this.boundHandleClick,!0),this.isInitialized=!0)}handleClick(t){const e=t.target;if(!e)return;if(!["A","INPUT","BUTTON","TEXTAREA"].includes(e.tagName))return;if("true"===e.getAttribute("sensorswave-disable"))return;mt({event:"$WebClick",properties:Pt(e,t)||{}},this.config)}destroy(){this.boundHandleClick&&(document.removeEventListener("click",this.boundHandleClick,!0),this.boundHandleClick=null),this.isInitialized=!1}};Bt.NAME="webclick";let xt=Bt;const Mt=class{constructor({emitter:t,config:e,sdk:n}){this.updateInterval=null,this.fetchingPromise=null,this.emitter=t,this.config=e,this.sdk=n}init(){const t=this.config;if(t.enableAB){if(this.sdk&&"function"==typeof this.sdk.hasOptedOutCapturing&&this.sdk.hasOptedOutCapturing())return;this.fastFetch().then(()=>{this.emitter.emit(A)}),t.abRefreshInterval<3e4&&(t.abRefreshInterval=3e4),this.updateInterval=setInterval(()=>{this.fetchNewData().catch(console.warn)},t.abRefreshInterval)}}async fastFetch(){const t=N.getABData(this.config.abRefreshInterval);return t&&t.length?(this.emitter.emit(A),Promise.resolve(t)):this.fetchNewData()}async fetchNewData(){return this.fetchingPromise||(this.fetchingPromise=new Promise(t=>{!function({opts:t,cb:e}){if(!st())return void(e&&e({}));if(!rt())return void(e&&e({}));const n=N.getLoginId(),i=N.getAnonId();if(!n&&!i)return void(e&&e({}));const s={user:{login_id:n||"",anon_id:i||"",props:{...tt(),...gt(N.getCommonProps())}},sdk:"webjs",sdk_version:v};$({url:lt(t),method:"POST",data:s,headers:ht(t),callback:t=>{200!==t.statusCode?(console.error("Failed to fetch feature flags"),e&&e({})):e&&e(t.json)}})}({opts:this.config,cb:e=>{N.saveABData(e?.data?.results||[]),t(e),this.fetchingPromise=null}})})),this.fetchingPromise}async getFeatureGate(t){return await this.fastFetch().catch(console.warn),N.getABData(this.config.abRefreshInterval).find(e=>e.typ===C.FEATURE_GATE&&e.key==t)}async checkFeatureGate(t){const e=await this.getFeatureGate(t);return!!e&&(!e.hasOwnProperty("vid")&&e.key?(wt({isUnset:!0,data:e,opts:this.config}),!1):(wt({data:e,opts:this.config}),"fail"!==e.vid))}async getExperiment(t){await this.fastFetch().catch(console.warn);const e=N.getABData(this.config.abRefreshInterval).find(e=>e.typ===C.EXPERIMENT&&e.key===t);return e?!e.hasOwnProperty("vid")&&e.key?(wt({isUnset:!0,data:e,opts:this.config}),{}):(wt({data:e,opts:this.config}),e?.value||{}):{}}async getFeatureConfig(t){await this.fastFetch().catch(console.warn);const e=N.getABData(this.config.abRefreshInterval).find(e=>e.typ===C.FEATURE_CONFIG&&e.key===t);if(!e)return{};if(!e.hasOwnProperty("vid")&&e.key)return wt({isUnset:!0,data:e,opts:this.config}),{};wt({data:e,opts:this.config});const n=e?.value;if(n){if(i(n))return n;try{return JSON.parse(n)}catch{return n}}return{}}destroy(){this.updateInterval&&(clearInterval(this.updateInterval),this.updateInterval=null),this.fetchingPromise=null}};Mt.NAME="abtest";let Dt=Mt;const Ht=["utm_source","utm_medium","utm_campaign","utm_content","utm_term"],Ut="sensorswave_utm",Xt=class t{constructor({sdk:t,emitter:e,config:n}){this.sdk=t,this.emitter=e,this.config=n}init(){if(this.sdk&&!0===this.sdk._postConsentInit){let e=t.readFromSessionStorage();return e&&0!==Object.keys(e).length||(e=t.captureAndStore(this.config?.debug)),void this.scheduleInitialUTM(e)}const e=t.getUTMFromURL();t.saveToSessionStorage(e,this.config?.debug),this.scheduleInitialUTM(e)}scheduleInitialUTM(t){setTimeout(()=>{this.sendInitialUTM(t)},0)}static getUTMFromURL(){try{const t=new URLSearchParams(window.location.search),e={};return Ht.forEach(n=>{const i=t.get(n);i&&(e[n]=i)}),e}catch(e){return t.getUTMFromURLFallback()}}static getUTMFromURLFallback(){const t={};return window.location.search.substring(1).split("&").forEach(e=>{const[n,i]=e.split("="),s=decodeURIComponent(n),r=i?decodeURIComponent(i):"";Ht.includes(s)&&(t[s]=r)}),t}static readFromSessionStorage(){try{const t=sessionStorage.getItem(Ut);if(!t)return{};const e=JSON.parse(t);return e&&"object"==typeof e?e:{}}catch(t){return{}}}static saveToSessionStorage(t,e=!1){try{sessionStorage.setItem(Ut,JSON.stringify(t))}catch(n){e&&console.warn("[SensorsWave UTM] Failed to save to sessionStorage:",n)}}static captureAndStore(e=!1){const n=t.getUTMFromURL();return t.saveToSessionStorage(n,e),n}sendInitialUTM(t){const e={};Ht.forEach(n=>{e[`$initial_${n}`]=null!=t[n]?t[n]:""});try{this.sdk.profileSetOnce(e)}catch(n){this.config.debug&&console.warn("[SensorsWave UTM] Failed to send initial UTM:",n)}}destroy(){}};Xt.NAME="UTM";let jt=Xt;const qt=1e3,Wt=/^\s*(?:async\s+)?at\s+(?:(.+)\s+\()?(.+?):(\d+):(\d+)\)?$/,Gt=/^(?:(.*)@)?(.+?):(\d+):(\d+)$/;function zt(t){let e=t;try{const t=location.origin;t&&0===e.indexOf(t)&&(e=e.substring(t.length))}catch(s){}const n=e.indexOf("?");n>-1&&(e=e.substring(0,n));const i=e.indexOf("#");return i>-1&&(e=e.substring(0,i)),e}function Yt(t){return t.map(t=>({platform:"web:javascript",filename:zt(t.file),function:t.fn||"?",lineno:Number(t.line),colno:Number(t.col),abs_path:Kt(t.file,1e3)}))}function Kt(t,e){return t.length>e?t.substring(0,e):t}function Jt(t){let e;if("string"==typeof t)e=t;else if(null!==t&&"object"==typeof t){try{e=JSON.stringify(t)}catch(n){e=Object.prototype.toString.call(t)}e||(e=Object.prototype.toString.call(t))}else e=String(t);return Kt(e,qt)}function Zt(t){const{frames:e,headerType:n}=function(t){const e=[];let n="";if(!t||"string"!=typeof t)return{frames:e,headerType:n};const i=t.split(/\r?\n/);for(let s=0;s<i.length;s++){const t=i[s];if(!t||t.length>1024)continue;const r=t.match(Wt),o=r?null:t.match(Gt),a=r||o;if(a)e.push({fn:a[1]||"?",file:a[2],line:a[3],col:a[4]});else if(0===s){const e=t.indexOf(":");e>0&&(n=t.substring(0,e).trim())}if(e.length>=30)break}return{frames:e,headerType:n}}(t&&t.stack);let i=t&&t.name||n||"Error";return i=Kt(String(i),200),{$exception_level:"error",$exception_type:i,$exception_message:Kt(String(t&&t.message||""),qt),$exception_frames:Yt(e)}}function Qt(t,e,n,i){let s=[];return e&&(s=[{platform:"web:javascript",filename:zt(e),function:"?",lineno:n||0,colno:i||0,abs_path:Kt(e,1e3)}]),{$exception_level:"error",$exception_type:"Error",$exception_message:Kt(String(t||""),qt),$exception_frames:s}}class Vt{constructor(t=10,e=1,n=1e4){this.buckets=/* @__PURE__ */new Map,this.bucketSize=t,this.refillRate=e,this.refillInterval=n}allow(t){const e=Date.now();let n=this.buckets.get(t);if(n){if(e>n.lastRefill){const t=Math.floor((e-n.lastRefill)/this.refillInterval)*this.refillRate;t>0&&(n.tokens=Math.min(this.bucketSize,n.tokens+t),n.lastRefill+=t/this.refillRate*this.refillInterval)}}else n={tokens:this.bucketSize,lastRefill:e},this.buckets.set(t,n);return n.tokens>=1&&(n.tokens-=1,!0)}reset(){this.buckets.clear()}}const te=class{constructor({emitter:t,config:e}){this.isInitialized=!1,this.boundHandleError=null,this.boundHandleRejection=null,this.rateLimiter=new Vt,this.emitter=t,this.config=e}init(){this.isInitialized||(this.boundHandleError=this.handleError.bind(this),this.boundHandleRejection=this.handleRejection.bind(this),window.addEventListener("error",this.boundHandleError,!0),window.addEventListener("unhandledrejection",this.boundHandleRejection),this.isInitialized=!0)}handleError(t){try{const e=t.target;let n;if(e&&e!==window&&e.tagName)n=function(t){const e=t,n=(e.tagName||"").toLowerCase(),i=Kt(String(e.src||e.href||""),qt);return{$exception_level:"error",$exception_type:"ResourceLoadError",$exception_message:`Failed to load <${n}>${i?` from ${i}`:""}`,$exception_frames:[]}}(e);else{const e=t;n=e.error instanceof Error?Zt(e.error):Qt(String(e.message||""),e.filename,e.lineno,e.colno)}this.send(n)}catch(e){}}handleRejection(t){try{const e=t.reason;this.send(function(t){return t instanceof Error?Zt(t):{$exception_level:"error",$exception_type:"UnhandledRejection",$exception_message:Jt(t),$exception_frames:[]}}(e))}catch(e){}}send(t){t.$exception_message&&this.rateLimiter.allow(t.$exception_type)&&mt({event:T,properties:t},this.config)}destroy(){this.boundHandleError&&(window.removeEventListener("error",this.boundHandleError,!0),this.boundHandleError=null),this.boundHandleRejection&&(window.removeEventListener("unhandledrejection",this.boundHandleRejection),this.boundHandleRejection=null),this.rateLimiter.reset(),this.isInitialized=!1}};te.NAME="exception";let ee=te;const ne=[],ie={debug:!1,sourceToken:"",apiHost:"",autoCapture:!0,isSinglePageApp:!1,crossSubdomainCookie:!0,enableAB:!1,abRefreshInterval:6e5,enableClickTrack:!1,batchSend:!1,enableErrorTrack:!1,enableCrashTrack:!1,optOutCapturing:!1,persistOptOut:!1},se=new class{constructor(){this.__innerInited=!1,this.inited=!1,this.config={},this.eventEmitter=new t,this.pluginCore={},this.commonProps={},this.spaCleanup=null,this._optOutCapturing=!1,this.consentStorage=new vt(!1),this._setupAfterConsentDone=!1,this._postConsentInit=!1,O.instance=this}init(t,e={}){return this.inited?this:(O.instance=this,e.sourceToken=t,this.mergeConfig(e),this.consentStorage=new vt(!0===this.config.persistOptOut),this._optOutCapturing?this.consentStorage.write(!0):!0===this.config.optOutCapturing?(this._optOutCapturing=!0,this.consentStorage.write(!0)):!0===this.consentStorage.read()&&(this._optOutCapturing=!0),this.eventEmitter.emit("init-param",this.config),this.__innerInited=!0,this._optOutCapturing?(jt.captureAndStore(this.config.debug),this.eventEmitter.emit(b),this.inited=!0,this):(this.__setupAfterConsent(),this.eventEmitter.emit(b),this.inited=!0,this))}__setupAfterConsent(){if(this._setupAfterConsentDone)return;this._setupAfterConsentDone=!0;const t=this.config;ne.length=0,N.init(t.crossSubdomainCookie),t.anonId&&N.setAnonId(t.anonId),function(){if(window._swFailedRequestsInitialized)return;window._swFailedRequestsInitialized=!0;const t=O.instance;t&&"function"==typeof t.hasOptedOutCapturing&&t.hasOptedOutCapturing()||t&&!0===t._postConsentInit||function(){const t=et.getAll();if(0!==t.length)for(let e=0,n=t.length;e<n;e+=10){const n=t.slice(e,e+10),i=[],s=[];n.forEach(t=>{Array.isArray(t.data)?i.push(...t.data):i.push(t.data),s.push(t.id)});const r=n[n.length-1],o=r.url,a=r.headers;$({url:o,method:"POST",data:i,headers:a,callback:t=>{200!==t.statusCode?(console.error("Failed to send batch stored requests:",t),P(t.statusCode)||s.forEach(t=>{et.dequeue(t)})):s.forEach(t=>{et.dequeue(t)})}})}}()}(),ne.push(jt),t.autoCapture&&this.autoTrack(),t.enableAB&&ne.push(Dt),t.enableClickTrack&&ne.push(xt),t.enableCrashTrack&&t.debug&&console.warn("[SensorsWave] enableCrashTrack 仅在 app 宿主环境生效,当前 Web 环境不采集 crash"),t.enableErrorTrack&&ne.push(ee),this.pluginCore=new bt({plugins:ne,emitter:this.eventEmitter,config:t,sdk:this}),this.spaCleanup=function(t){let e=location.href;const n=window.history.pushState,i=window.history.replaceState,r=function(){t(e),e=location.href};return s(window.history.pushState)&&(window.history.pushState=function(...i){n.apply(window.history,i),t(e),e=location.href}),s(window.history.replaceState)&&(window.history.replaceState=function(...n){i.apply(window.history,n),t(e),e=location.href}),window.addEventListener("popstate",r),function(){s(window.history.pushState)&&(window.history.pushState=n),s(window.history.replaceState)&&(window.history.replaceState=i),window.removeEventListener("popstate",r)}}(t=>{this.eventEmitter.emit(y,t)})}mergeConfig(t){this.config={...ie,...t}}__canCapture(){return this.inited&&!this._optOutCapturing}track(t){this.__canCapture()&&function(t,e){if(!st())return;if(!rt())return;const n={...t};n.time||(n.time=Date.now()),n.login_id||(n.login_id=N.getLoginId()),n.anon_id||(n.anon_id=N.getAnonId()),n.trace_id||(n.trace_id=N.getTraceId()),n.properties={...tt(),...gt(N.getCommonProps()),...n.properties};const i=ut(e),s=ht(e),r=!1!==e.batchSend&&at();if(!r)return dt(i,{data:[n],headers:s});et.enqueue(i,[n],s),r.add()}(t,this.config)}trackEvent(t,e){this.__canCapture()&&mt({event:t,properties:e},this.config)}trackException(t,e){if(!this.__canCapture())return;const n={...e||{},...t instanceof Error?Zt(t):Qt(String(t))};mt({event:T,properties:n},this.config)}autoTrack(){ne.push(At,Nt,Tt)}profileSet(t){this.__canCapture()&&Et({userProps:{$set:t},opts:this.config})}profileSetOnce(t){this.__canCapture()&&Et({userProps:{$set_once:t},opts:this.config})}profileIncrement(t){this.__canCapture()&&Et({userProps:{$increment:t},opts:this.config})}profileAppend(t){this.__canCapture()&&Et({userProps:{$append:t},opts:this.config})}profileUnion(t){this.__canCapture()&&Et({userProps:{$union:t},opts:this.config})}profileUnset(t){if(!this.__canCapture())return;const e={};r(t)?t.forEach(function(t){e[t]=null}):e[t]=null,Et({userProps:{$unset:e},opts:this.config})}profileDelete(){this.__canCapture()&&Et({userProps:{$delete:!0},opts:this.config})}registerCommonProperties(t){if(!i(t))return console.warn("Commmon Properties must be an object!");this.commonProps=t,N.setCommonProps(this.commonProps)}clearCommonProperties(t){if(!r(t))return console.warn("Commmon Properties to be cleared must be an array!");t.forEach(t=>{delete this.commonProps[t]}),N.setCommonProps(this.commonProps)}identify(t){this.__canCapture()&&(N.setLoginId(t),function(t){if(!st())return;if(!rt())return;const e=N.getLoginId(),n=N.getAnonId();if(!e||!n)return;const i={time:Date.now(),trace_id:N.getTraceId(),event:"$Identify",login_id:e,anon_id:n,properties:ft()},s=ut(t),r=ht(t),o=at();if(!o)return dt(s,{data:[i],headers:r});et.enqueue(s,[i],r),o.add()}(this.config))}setLoginId(t){this.__canCapture()&&N.setLoginId(t)}getAnonId(){return this.__canCapture()?N.getAnonId():""}setAnonId(t){this.__canCapture()&&N.setAnonId(t)}getLoginId(){return this.__canCapture()?N.getLoginId():""}reset(t=!1){this.__canCapture()&&(N.clearLoginId(),t&&N.resetAnonId())}checkFeatureGate(t){if(!this.__canCapture())return Promise.resolve(!1);const e=this.pluginCore.getPlugin(Dt.NAME);return this.config.enableAB&&e?e.checkFeatureGate(t):Promise.reject("AB is disabled")}getExperiment(t){if(!this.__canCapture())return Promise.resolve({});const e=this.pluginCore.getPlugin(Dt.NAME);return this.config.enableAB&&e?e.getExperiment(t):Promise.reject("AB is disabled")}getFeatureConfig(t){if(!this.__canCapture())return Promise.resolve({});const e=this.pluginCore.getPlugin(Dt.NAME);return this.config.enableAB&&e?e.getFeatureConfig(t):Promise.reject("AB is disabled")}optOutCapturing(){this._optOutCapturing=!0,this.consentStorage.write(!0),ot&&ot.pause()}optInCapturing(){if(this._optOutCapturing=!1,this.consentStorage.write(!1),ot&&ot.resume(),this.inited&&!this._setupAfterConsentDone){this._postConsentInit=!0;try{this.__setupAfterConsent(),this.eventEmitter.emit(b)}finally{this._postConsentInit=!1}}}hasOptedOutCapturing(){return this._optOutCapturing}destroy(){ot&&(ot.destroy(),ot=null),"undefined"!=typeof window&&(window._swFailedRequestsInitialized=!1),this.inited=!1,this.__innerInited=!1,this.spaCleanup&&"function"==typeof this.spaCleanup&&(this.spaCleanup(),this.spaCleanup=null),this.pluginCore&&"function"==typeof this.pluginCore.destroy&&this.pluginCore.destroy(),this.pluginCore={},this.eventEmitter&&this.eventEmitter.removeAllListeners(),this.consentStorage=new vt(!0===this.config?.persistOptOut),this._optOutCapturing=!1,this._setupAfterConsentDone=!1,this._postConsentInit=!1,O.instance===this&&(O.instance=null)}};export{se as default};
|
|
1
|
+
class e{constructor(){this.listeners={}}on(e,t,i=!1){if(e&&t){if(!s(t))throw new Error("listener must be a function");this.listeners[e]=this.listeners[e]||[],this.listeners[e].push({listener:t,once:i})}}off(e,t){const i=this.listeners[e];if(!i?.length)return;"number"==typeof t&&i.splice(t,1);const n=i.findIndex(e=>e.listener===t);-1!==n&&i.splice(n,1)}emit(e,...t){this.listeners[e]&&this.listeners[e].forEach((i,n)=>{i.listener.call(this,...t),i.listener.once&&this.off(e,n)})}once(e,t){this.on(e,t,!0)}removeAllListeners(e){e?this.listeners[e]=[]:this.listeners={}}}const t={get:function(e){const t=e+"=",i=document.cookie.split(";");for(let n=0,s=i.length;n<s;n++){let e=i[n];for(;" "==e.charAt(0);)e=e.substring(1,e.length);if(0==e.indexOf(t))return h(e.substring(t.length,e.length))}return null},set:function({name:e,value:t,expires:i,samesite:n,secure:s,domain:r}){let o="",a="",c="",u="";if(0!==(i=null==i||void 0===i?365:i)){const e=/* @__PURE__ */new Date;"s"===String(i).slice(-1)?e.setTime(e.getTime()+1e3*Number(String(i).slice(0,-1))):e.setTime(e.getTime()+24*i*60*60*1e3),o="; expires="+e.toUTCString()}function l(e){return e?e.replace(/\r\n/g,""):""}n&&(c="; SameSite="+n),s&&(a="; secure");const h=l(e),d=l(t),p=l(r);p&&(u="; domain="+p),h&&d&&(document.cookie=h+"="+encodeURIComponent(d)+o+"; path=/"+u+c+a)},remove:function(e){this.set({name:e,value:"",expires:-1})},isSupport:function({samesite:e,secure:t}={}){if(!navigator.cookieEnabled)return!1;const i="sensorswave_cookie_support_test";return this.set({name:i,value:"1",samesite:e,secure:t}),"1"===this.get(i)&&(this.remove(i),!0)}},i=Object.prototype.toString;function n(e){return"[object Object]"===i.call(e)}function s(e){const t=i.call(e);return"[object Function]"==t||"[object AsyncFunction]"==t}function r(e){return"[object Array]"==i.call(e)}function o(e){return"[object String]"==i.call(e)}function a(e){return void 0===e}const c=Object.prototype.hasOwnProperty;function u(e){if(n(e)){for(let t in e)if(c.call(e,t))return!1;return!0}return!1}function l(e){return!(!e||1!==e.nodeType)}function h(e){let t=e;try{t=decodeURIComponent(e)}catch(i){t=e}return t}function d(e){try{return JSON.parse(e)}catch(t){return""}}const p=function(){let e=Date.now();return function(t){return Math.ceil((e=(9301*e+49297)%233280,e/233280*t))}}();function g(){if("function"==typeof Uint32Array){let e;if("undefined"!=typeof crypto&&(e=crypto),e&&n(e)&&e.getRandomValues)return e.getRandomValues(new Uint32Array(1))[0]/Math.pow(2,32)}return p(1e19)/1e19}const f=/* @__PURE__ */function(){function e(e){return("0".repeat(e)+Date.now().toString(16)).slice(-e)}return function(){let t=String(screen.height*screen.width);t=t&&/\d{4,}/.test(t)?t.slice(-4):String(31242*g()).replace(".","").slice(0,4);return e(8)+"-"+g().toString(16).replace(".","").slice(-4)+"-"+function(){const e=navigator.userAgent;let t,i=[],n=0;function s(e,t){let n=0;for(let s=0;s<t.length;s++)n|=i[s]<<8*s;return(e^n)>>>0}for(let r=0;r<e.length;r++)t=e.charCodeAt(r),i.unshift(255&t),i.length>=4&&(n=s(n,i),i=[]);return i.length>0&&(n=s(n,i)),("0000"+n.toString(16)).slice(-4)}()+"-"+t+"-"+e(12)||(String(g())+String(g())+String(g())).slice(2,15)}}();function m(e,t){t&&"string"==typeof t||(t="");let i=null;try{i=new URL(e).hostname}catch(n){}return i||t}function E(e){let t=[];try{t=atob(e).split("").map(function(e){return"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)})}catch(i){t=[]}try{return decodeURIComponent(t.join(""))}catch(i){return t.join("")}}function v(e){let t="";try{t=btoa(encodeURIComponent(e).replace(/%([0-9A-F]{2})/g,function(e,t){return String.fromCharCode(parseInt(t,16))}))}catch(i){t=e}return t}const b={get:function(e){return window.localStorage.getItem(e)},parse:function(e){let t;try{t=JSON.parse(b.get(e))||null}catch(i){console.warn(i)}return t},set:function(e,t){try{window.localStorage.setItem(e,t)}catch(i){console.warn(i)}},remove:function(e){window.localStorage.removeItem(e)},isSupport:function(){let e=!0;try{const t="__local_store_support__",i="testIsSupportStorage";b.set(t,i),b.get(t)!==i&&(e=!1),b.remove(t)}catch(t){e=!1}return e}};function _(e){return e.trim()}function I(e){if(!e||"string"!=typeof e)return"";try{return new URL(e,window.location.origin).pathname}catch(t){return""}}const S={},w="1.5.1",O="init-ready",y="spa-switch",A="ff-ready",R="$PageLeave",T="$Exception";var C=/* @__PURE__ */(e=>(e[e.FEATURE_GATE=1]="FEATURE_GATE",e[e.FEATURE_CONFIG=2]="FEATURE_CONFIG",e[e.EXPERIMENT=3]="EXPERIMENT",e))(C||{});const N={crossSubdomain:!1,requests:[],_sessionState:{},_abData:[],_trace_id:"",commonProps:{},_state:{anon_id:"",login_id:"",identities:{}},getIdentityCookieID(){return this._state.identities?.$identity_cookie_id||""},getCommonProps:function(){return this.commonProps||{}},setCommonProps:function(e){this.commonProps=e},getAnonId(){return this._state.anon_id||this.getIdentityCookieID()||f()},getLoginId(){return this._state.login_id},getTraceId(){return this._trace_id||f()},set:function(e,t){this._state[e]=t,this.save()},getCookieName:function(){return"sensorswave2025jssdkcross"},getABLSName:function(){return"sensorswave2025jssdkablatest"},save:function(){let e=JSON.parse(JSON.stringify(this._state));e.identities&&(e.identities=v(JSON.stringify(e.identities)));const i=JSON.stringify(e);t.set({name:this.getCookieName(),value:i,expires:365})},init:function(e){let i,s;this.crossSubdomain=e,t.isSupport()&&(i=t.get(this.getCookieName()),s=d(i)),N._state={...s||{}},N._state.identities&&(N._state.identities=d(E(N._state.identities))),N._state.identities&&n(N._state.identities)&&!u(N._state.identities)||(N._state.identities={$identity_cookie_id:f()}),N.save()},setLoginId(e){"number"==typeof e&&(e=String(e)),void 0!==e&&e&&(N.set("login_id",e),N.save())},clearLoginId(){this._state.login_id="",this.save()},resetAnonId(){this._state.anon_id="",this._state.identities={$identity_cookie_id:f()},this.save()},setAnonId(e){"number"==typeof e&&(e=String(e)),"string"==typeof e&&e?(N.set("anon_id",e),N.save()):console.warn("[SensorsWave store] Invalid anonId, ignored:",e)},saveABData(e){if(!e||u(e))return;this._abData=e;let t=JSON.parse(JSON.stringify(this._abData));t=v(JSON.stringify(t));try{localStorage.setItem(this.getABLSName(),JSON.stringify({time:Date.now(),data:t,anon_id:this.getAnonId(),login_id:this.getLoginId()}))}catch(i){console.warn("Failed to save abdata to localStorage",i)}},getABData(e=6e5){try{let t=localStorage.getItem(this.getABLSName());if(t){const{time:i,data:n,login_id:s,anon_id:r}=d(t)||{};if(i&&n&&Date.now()-i<e&&r===this.getAnonId()&&(!s||s===this.getLoginId())){const e=d(E(n));return this._abData=Array.isArray(e)?e:[],this._abData}localStorage.removeItem(this.getABLSName())}}catch(t){this._abData=[]}return this._abData||[]}};function P(e){return!(e>=400&&e<500)||408===e||429===e}function k(e){var t;if(e.data)return{contentType:"application/json",body:(t=e.data,JSON.stringify(t,(e,t)=>"bigint"==typeof t?t.toString():t,undefined))}}const x=[];function L(e){const t={...e};t.timeout=t.timeout||6e4;const i=t.transport??"fetch",n=x.find(e=>e.transport===i)?.method??x[0]?.method;if(!n)throw new Error("No available transport method for HTTP request");n(t)}function M(e){return o(e=e||document.referrer)&&(e=h(e=e.trim()))||""}function $(e){const t=m(e=e||M());if(!t)return"";const i={baidu:[/^.*\.baidu\.com$/],bing:[/^.*\.bing\.com$/],google:[/^www\.google\.com$/,/^www\.google\.com\.[a-z]{2}$/,/^www\.google\.[a-z]{2}$/],sm:[/^m\.sm\.cn$/],so:[/^.+\.so\.com$/],sogou:[/^.*\.sogou\.com$/],yahoo:[/^.*\.yahoo\.com$/],duckduckgo:[/^.*\.duckduckgo\.com$/]};for(let n of Object.keys(i)){let e=i[n];for(let i=0,s=e.length;i<s;i++)if(e[i].test(t))return n}return""}function D(e,t){return-1!==e.indexOf(t)}"function"==typeof fetch&&x.push({transport:"fetch",method:function(e){if("undefined"==typeof fetch)return void console.error("fetch API is not available");const t=k(e),i=new Headers;e.headers&&Object.keys(e.headers).forEach(t=>{i.append(t,e.headers[t])}),t?.contentType&&i.append("Content-Type",t.contentType),fetch(e.url,{method:e.method||"GET",headers:i,body:t?.body}).then(t=>t.text().then(i=>{const n={statusCode:t.status,text:i};if(200===t.status)try{n.json=JSON.parse(i)}catch(s){console.error("Failed to parse response:",s)}e.callback?.(n)})).catch(t=>{console.error("Request failed:",t),e.callback?.({statusCode:0,text:String(t)})})}}),"undefined"!=typeof XMLHttpRequest&&x.push({transport:"XHR",method:function(e){if("undefined"==typeof XMLHttpRequest)return void console.error("XMLHttpRequest is not available");const t=new XMLHttpRequest;t.open(e.method||"GET",e.url,!0);const i=k(e);e.headers&&Object.keys(e.headers).forEach(i=>{t.setRequestHeader(i,e.headers[i])}),i?.contentType&&t.setRequestHeader("Content-Type",i.contentType),t.timeout=e.timeout||6e4,t.withCredentials=!0,t.onreadystatechange=()=>{if(4===t.readyState){const n={statusCode:t.status,text:t.responseText};if(200===t.status)try{n.json=JSON.parse(t.responseText)}catch(i){console.error("Failed to parse JSON response:",i)}e.callback?.(n)}},t.send(i?.body)}});const F={FACEBOOK:"Facebook",MOBILE:"Mobile",IOS:"iOS",ANDROID:"Android",TABLET:"Tablet",ANDROID_TABLET:"Android Tablet",IPAD:"iPad",APPLE:"Apple",APPLE_WATCH:"Apple Watch",SAFARI:"Safari",BLACKBERRY:"BlackBerry",SAMSUNG_BROWSER:"SamsungBrowser",SAMSUNG_INTERNET:"Samsung Internet",CHROME:"Chrome",CHROME_OS:"Chrome OS",CHROME_IOS:"Chrome iOS",INTERNET_EXPLORER:"Internet Explorer",INTERNET_EXPLORER_MOBILE:"Internet Explorer Mobile",OPERA:"Opera",OPERA_MINI:"Opera Mini",EDGE:"Edge",MICROSOFT_EDGE:"Microsoft Edge",FIREFOX:"Firefox",FIREFOX_IOS:"Firefox iOS",NINTENDO:"Nintendo",PLAYSTATION:"PlayStation",XBOX:"Xbox",ANDROID_MOBILE:"Android Mobile",MOBILE_SAFARI:"Mobile Safari",WINDOWS:"Windows",WINDOWS_PHONE:"Windows Phone",NOKIA:"Nokia",OUYA:"Ouya",GENERIC_MOBILE:"Generic mobile",GENERIC_TABLET:"Generic tablet",KONQUEROR:"Konqueror",UC_BROWSER:"UC Browser",HUAWEI:"Huawei",XIAOMI:"Xiaomi",OPPO:"OPPO",VIVO:"vivo"},B="(\\d+(\\.\\d+)?)",H=new RegExp("Version/"+B),U=new RegExp(F.XBOX,"i"),W=new RegExp(F.PLAYSTATION+" \\w+","i"),X=new RegExp(F.NINTENDO+" \\w+","i"),j=new RegExp(F.BLACKBERRY+"|PlayBook|BB10","i"),q=new RegExp("(HUAWEI|honor|HONOR)","i"),G=new RegExp("(Xiaomi|Redmi)","i"),z=new RegExp("(OPPO|realme)","i"),V=new RegExp("(vivo|IQOO)","i"),Y={"NT3.51":"NT 3.11","NT4.0":"NT 4.0","5.0":"2000",5.1:"XP",5.2:"XP","6.0":"Vista",6.1:"7",6.2:"8",6.3:"8.1",6.4:"10","10.0":"10"};function K(e,t){return t=t||"",D(e," OPR/")&&D(e,"Mini")?F.OPERA_MINI:D(e," OPR/")?F.OPERA:j.test(e)?F.BLACKBERRY:D(e,"IE"+F.MOBILE)||D(e,"WPDesktop")?F.INTERNET_EXPLORER_MOBILE:D(e,F.SAMSUNG_BROWSER)?F.SAMSUNG_INTERNET:D(e,F.EDGE)||D(e,"Edg/")?F.MICROSOFT_EDGE:D(e,"FBIOS")?F.FACEBOOK+" "+F.MOBILE:D(e,"UCWEB")||D(e,"UCBrowser")?F.UC_BROWSER:D(e,"CriOS")?F.CHROME_IOS:D(e,"CrMo")||D(e,F.CHROME)?F.CHROME:D(e,F.ANDROID)&&D(e,F.SAFARI)?F.ANDROID_MOBILE:D(e,"FxiOS")?F.FIREFOX_IOS:D(e.toLowerCase(),F.KONQUEROR.toLowerCase())?F.KONQUEROR:function(e,t){return t&&D(t,F.APPLE)||D(i=e,F.SAFARI)&&!D(i,F.CHROME)&&!D(i,F.ANDROID);var i}(e,t)?D(e,F.MOBILE)?F.MOBILE_SAFARI:F.SAFARI:D(e,F.FIREFOX)?F.FIREFOX:D(e,"MSIE")||D(e,"Trident/")?F.INTERNET_EXPLORER:D(e,"Gecko")?F.FIREFOX:""}const J={[F.INTERNET_EXPLORER_MOBILE]:[new RegExp("rv:"+B)],[F.MICROSOFT_EDGE]:[new RegExp(F.EDGE+"?\\/"+B)],[F.CHROME]:[new RegExp("("+F.CHROME+"|CrMo)\\/"+B)],[F.CHROME_IOS]:[new RegExp("CriOS\\/"+B)],[F.UC_BROWSER]:[new RegExp("(UCBrowser|UCWEB)\\/"+B)],[F.SAFARI]:[H],[F.MOBILE_SAFARI]:[H],[F.OPERA]:[new RegExp("("+F.OPERA+"|OPR)\\/"+B)],[F.FIREFOX]:[new RegExp(F.FIREFOX+"\\/"+B)],[F.FIREFOX_IOS]:[new RegExp("FxiOS\\/"+B)],[F.KONQUEROR]:[new RegExp("Konqueror[:/]?"+B,"i")],[F.BLACKBERRY]:[new RegExp(F.BLACKBERRY+" "+B),H],[F.ANDROID_MOBILE]:[new RegExp("android\\s"+B,"i")],[F.SAMSUNG_INTERNET]:[new RegExp(F.SAMSUNG_BROWSER+"\\/"+B)],[F.INTERNET_EXPLORER]:[new RegExp("(rv:|MSIE )"+B)],Mozilla:[new RegExp("rv:"+B)]};function Z(e,t){const i=K(e,t),n=J[i];if(a(n))return null;for(let s=0;s<n.length;s++){const t=n[s],i=e.match(t);if(i)return parseFloat(i[i.length-2])}return null}const Q=[[new RegExp(F.XBOX+"; "+F.XBOX+" (.*?)[);]","i"),e=>[F.XBOX,e&&e[1]||""]],[new RegExp(F.NINTENDO,"i"),[F.NINTENDO,""]],[new RegExp(F.PLAYSTATION,"i"),[F.PLAYSTATION,""]],[j,[F.BLACKBERRY,""]],[new RegExp(F.WINDOWS,"i"),(e,t)=>{if(/Phone/.test(t)||/WPDesktop/.test(t))return[F.WINDOWS_PHONE,""];if(new RegExp(F.MOBILE).test(t)&&!/IEMobile\b/.test(t))return[F.WINDOWS+" "+F.MOBILE,""];const i=/Windows NT ([0-9.]+)/i.exec(t);if(i&&i[1]){const e=i[1];let n=Y[e]||"";return/arm/i.test(t)&&(n="RT"),[F.WINDOWS,n]}return[F.WINDOWS,""]}],[/((iPhone|iPad|iPod).*?OS (\d+)_(\d+)_?(\d+)?|iPhone)/,e=>{if(e&&e[3]){const t=[e[3],e[4],e[5]||"0"];return[F.IOS,t.join(".")]}return[F.IOS,""]}],[/(watch.*\/(\d+\.\d+\.\d+)|watch os,(\d+\.\d+),)/i,e=>{let t="";return e&&e.length>=3&&(t=a(e[2])?e[3]:e[2]),["watchOS",t]}],[new RegExp("("+F.ANDROID+" (\\d+)\\.(\\d+)\\.?(\\d+)?|"+F.ANDROID+")","i"),e=>{if(e&&e[2]){const t=[e[2],e[3],e[4]||"0"];return[F.ANDROID,t.join(".")]}return[F.ANDROID,""]}],[/Mac OS X (\d+)[_.](\d+)[_.]?(\d+)?/i,e=>{const t=["Mac OS X",""];if(e&&e[1]){const i=[e[1],e[2],e[3]||"0"];t[1]=i.join(".")}return t}],[/Mac/i,["Mac OS X",""]],[/CrOS/,[F.CHROME_OS,""]],[/Linux|debian/i,["Linux",""]]];function ee(){const e=window.innerHeight||document.documentElement.clientHeight||document.body&&document.body.clientHeight||0,t=window.innerWidth||document.documentElement.clientWidth||document.body&&document.body.clientWidth||0,i=navigator.userAgent,n=function(e){for(let t=0;t<Q.length;t++){const[i,n]=Q[t],s=i.exec(e),r=s&&("function"==typeof n?n(s,e):n);if(r)return r}return["",""]}(i)||["",""];return{$browser:K(i),$browser_version:Z(i),$url:location?.href.substring(0,1e3),$host:location?.host,$viewport_height:e,$viewport_width:t,$lib:"webjs",$lib_version:w,$search_engine:$(),$referrer:M(),$referrer_host:m(r=r||M()),$title:document.title,$language:navigator.language,$model:(s=i,(X.test(s)?F.NINTENDO:W.test(s)?F.PLAYSTATION:U.test(s)?F.XBOX:new RegExp(F.OUYA,"i").test(s)?F.OUYA:new RegExp("("+F.WINDOWS_PHONE+"|WPDesktop)","i").test(s)?F.WINDOWS_PHONE:/iPad/.test(s)?F.IPAD:/iPod/.test(s)?"iPod Touch":/iPhone/.test(s)?"iPhone":/(watch)(?: ?os[,/]|\d,\d\/)[\d.]+/i.test(s)?F.APPLE_WATCH:j.test(s)?F.BLACKBERRY:/(kobo)\s(ereader|touch)/i.test(s)?"Kobo":new RegExp(F.NOKIA,"i").test(s)?F.NOKIA:/(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i.test(s)||/(kf[a-z]+)( bui|\)).+silk\//i.test(s)?"Kindle Fire":q.test(s)?F.HUAWEI:G.test(s)?F.XIAOMI:z.test(s)?F.OPPO:V.test(s)?F.VIVO:/(Android|ZTE)/i.test(s)?!new RegExp(F.MOBILE).test(s)||/(9138B|TB782B|Nexus [97]|pixel c|HUAWEISHT|BTV|noble nook|smart ultra 6)/i.test(s)?/pixel[\daxl ]{1,6}/i.test(s)&&!/pixel c/i.test(s)||/(huaweimed-al00|tah-|APA|SM-G92|i980|zte|U304AA)/i.test(s)||/lmy47v/i.test(s)&&!/QTAQZ3/i.test(s)?F.ANDROID:F.ANDROID_TABLET:F.ANDROID:new RegExp("(pda|"+F.MOBILE+")","i").test(s)?F.GENERIC_MOBILE:new RegExp(F.TABLET,"i").test(s)&&!new RegExp(F.TABLET+" pc","i").test(s)?F.GENERIC_TABLET:"")||""),$os:n?.[0]||"",$os_version:n?.[1]||"",$pathname:location?.pathname,$screen_height:Number(screen.height)||0,$screen_width:Number(screen.width)||0,$timezone_offset:60*-/* @__PURE__ */(new Date).getTimezoneOffset()};var s,r}const te=new class{constructor(){this.STORAGE_KEY="sensorswave_unsent_events",this.MAX_QUEUE_SIZE=200,this.MAX_RETRY_COUNT=1,this.MAX_AGE_MS=6048e5,this.queue=[],this.loadFromStorage(),this.cleanupExpiredItems()}loadFromStorage(){try{const e=localStorage.getItem(this.STORAGE_KEY);e&&(this.queue=d(e)||[])}catch(e){console.warn("Failed to load queue from localStorage:",e),this.queue=[]}}cleanupExpiredItems(){const e=Date.now(),t=this.queue.filter(t=>e-t.timestamp<this.MAX_AGE_MS);t.length!==this.queue.length&&(this.queue=t,this.saveToStorage())}saveToStorage(){try{this.cleanupExpiredItems(),this.queue.length>this.MAX_QUEUE_SIZE&&(this.queue=this.queue.slice(-this.MAX_QUEUE_SIZE)),localStorage.setItem(this.STORAGE_KEY,JSON.stringify(this.queue))}catch(e){console.warn("Failed to save queue to localStorage:",e)}}enqueue(e,t,i,n=this.MAX_RETRY_COUNT){try{const s={id:f(),url:e,data:t,headers:i,timestamp:Date.now(),retryCount:0,maxRetries:n};return this.queue.push(s),this.saveToStorage(),s.id}catch(s){return console.warn("Failed to enqueue request:",s),""}}dequeue(e){try{this.queue=this.queue.filter(t=>t.id!==e),this.saveToStorage()}catch(t){console.warn("Failed to dequeue request:",t)}}getAll(){try{return this.cleanupExpiredItems(),[...this.queue]}catch(e){return console.warn("Failed to get queue items:",e),[]}}incrementRetryCount(e){const t=this.queue.find(t=>t.id===e);return!(!t||t.retryCount>=t.maxRetries||(t.retryCount++,this.saveToStorage(),0))}clear(){this.queue=[];try{localStorage.removeItem(this.STORAGE_KEY)}catch(e){console.warn("Failed to clear queue from localStorage:",e)}}getItemById(e){return this.queue.find(t=>t.id===e)}};class ie{constructor(e={}){this.flushTimer=null,this.isFlushing=!1,this.paused=!1,this.destroyed=!1,this.config={maxBatchSize:e.maxBatchSize||20,flushInterval:e.flushInterval||5e3},this.startFlushTimer()}pause(){this.paused=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null)}resume(){this.paused&&(this.paused=!1,this.startFlushTimer())}isPaused(){return this.paused}add(){te.getAll().length>=this.config.maxBatchSize&&this.triggerFlush()}triggerFlush(){this.paused||this.isFlushing||(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.isFlushing=!0,this.flush())}flush(){const e=te.getAll();if(0===e.length)return this.isFlushing=!1,void this.startFlushTimer();const t=e.slice(0,this.config.maxBatchSize),i=[],n=[];t.forEach(e=>{Array.isArray(e.data)?i.push(...e.data):i.push(e.data),n.push(e.id)});const s=t[t.length-1],r=s.url,o=s.headers;S.instance&&S.instance.config.debug&&console.log(JSON.stringify(i,null,2)),L({url:r,method:"POST",data:i,headers:o,callback:e=>{200===e.statusCode?n.forEach(e=>{te.dequeue(e)}):P(e.statusCode)?console.error("Failed to send batch events:",e):n.forEach(e=>{te.dequeue(e)}),this.isFlushing=!1,this.startFlushTimer()}})}startFlushTimer(){this.destroyed||(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.flushTimer=setInterval(()=>{te.getAll().length>0&&this.triggerFlush()},this.config.flushInterval))}destroy(){this.destroyed=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.paused||this.flush()}}let ne=null;function se(){const e=S.instance;return!(!e||!e.__innerInited)||(console.warn("[SensorsWave] SDK is not initialized. Please call init() first."),!1)}function re(){const e=S.instance;return!e||"function"!=typeof e.hasOptedOutCapturing||!e.hasOptedOutCapturing()}let oe=null;function ae(){return b.isSupport()?(oe||(ne||(ne=new ie({maxBatchSize:20,flushInterval:5e3})),oe=ne),oe):null}function ce(e,t,i){if(re())return L({url:e,method:"POST",data:t.data,headers:t.headers,callback:e=>{if(200!==e.statusCode){if(!P(e.statusCode))return void(i&&te.dequeue(i));if(i&&te.incrementRetryCount(i)){const e=te.getItemById(i);if(e){const t=Math.min(1e3*Math.pow(2,e.retryCount),3e4);setTimeout(()=>{ce(e.url,{data:e.data,headers:e.headers},e.id)},t)}}}else i&&te.dequeue(i),t.callback&&t.callback(e.json)}})}function ue(e){return`${e.apiHost}/in/track`}function le(e){return`${e.apiHost}/ab/evalall`}function he(e){return{"Content-Type":"application/json",SourceToken:e.sourceToken}}function de(e,t,i){S.instance&&S.instance.config.debug&&console.log(JSON.stringify(t.data,null,2));const n=te.enqueue(e,t.data,t.headers);return ce(e,{...t,callback:void 0},n)}function pe(){try{const e=sessionStorage.getItem("sensorswave_utm");if(!e)return{};const t=JSON.parse(e),i={};return Object.entries(t).forEach(([e,t])=>{null!=t&&""!==t&&(i[`$${e}`]=t)}),i}catch(e){return{}}}function ge(e){const t={};return Object.entries(e).forEach(([e,i])=>{if("function"==typeof i)try{const n=i();t[e]=n}catch(n){console.warn("[SensorsWave] Failed to resolve dynamic property:",e,n)}else t[e]=i}),t}function fe(e={},t=!0){const i={...t?ee():{},...ge(N.getCommonProps()),...e},n=pe();return Object.keys(n).length>0&&Object.assign(i,n),i}function me(e,t,i=!0){if(!se())return;if(!re())return;const n={time:Date.now(),trace_id:N.getTraceId(),event:e.event,properties:fe(e.properties,i)},s=pe();Object.keys(s).length>0&&(n.user_properties||(n.user_properties={}),n.user_properties.$set||(n.user_properties.$set={}),Object.assign(n.user_properties.$set,s)),e.user_properties&&(e.user_properties.$set&&(n.user_properties=n.user_properties||{},n.user_properties.$set={...n.user_properties.$set||{},...e.user_properties.$set},delete e.user_properties.$set),n.user_properties={...n.user_properties,...e.user_properties});const r=N.getLoginId(),o=N.getAnonId();r&&(n.login_id=r),o&&(n.anon_id=o);const a=ue(t),c=he(t),u=!1!==t.batchSend&&ae();u?(te.enqueue(a,[n],c),u.add()):de(a,{data:[n],headers:c})}function Ee({userProps:e,opts:t}){if(!se())return;if(!re())return;const i=N.getLoginId(),n=N.getAnonId();if(!i&&!n)return;const s={time:Date.now(),trace_id:N.getTraceId(),event:"$UserSet",login_id:i,anon_id:n,user_properties:e,properties:fe()},r=ue(t),o=he(t),a=ae();if(!a)return de(r,{data:[s],headers:o});te.enqueue(r,[s],o),a.add()}function ve(e){return e.typ===C.FEATURE_GATE||e.typ===C.FEATURE_CONFIG?`$feature_${e.id}`:e.typ===C.EXPERIMENT?`$exp_${e.id}`:""}function be(e){const t=e.typ;return[C.FEATURE_GATE,C.EXPERIMENT,C.FEATURE_CONFIG].includes(t)?{[ve(e)]:e.vid}:{}}function _e(e){const t=e.typ;return t===C.FEATURE_GATE||t===C.FEATURE_CONFIG?{$feature_key:e.key,$feature_variant:e.vid}:t===C.EXPERIMENT?{$exp_key:e.key,$exp_variant:e.vid}:{}}function Ie({isUnset:e=!1,data:t,opts:i}){if(!se())return;if(!re())return;if(!t||u(t)||t.disable_impress)return;const n=N.getLoginId(),s=N.getAnonId();if(!n&&!s)return;const r=t.typ===C.EXPERIMENT?"$ExpImpress":"$FeatureImpress";let o={};return o=e?{$unset:{[ve(t)]:null}}:{$set:{...be(t)}},me({event:r,properties:_e(t),user_properties:o},i)}const Se="sensorswave_opt_out";class we{constructor(e){this.persist=e}read(){if(this.persist)try{const e=b.get(Se);return"0"===e||"1"!==e&&void 0}catch{return}}write(e){if(this.persist)try{b.set(Se,e?"0":"1")}catch{}}}class Oe{constructor({plugins:e,emitter:t,config:i,sdk:n}){this.plugins=[],this.pluginInsMap={},this.emitter=t,this.config=i,this.sdk=n,this.registerBuiltInPlugins(e),this.created(),this.emitter.on(O,()=>{this.init()})}registerBuiltInPlugins(e){for(let t=0,i=e.length;t<i;t++)this.registerPlugin(e[t])}registerPlugin(e){this.plugins.push(e)}getPlugins(){return this.plugins}getPlugin(e){return this.pluginInsMap[e]}created(){for(let e=0,t=this.plugins.length;e<t;e++){const t=this.plugins[e];if(!t.NAME)throw new Error('Plugin should be defined with "NAME"');const i=new t({emitter:this.emitter,config:this.config,sdk:this.sdk});this.pluginInsMap[t.NAME]=i}}init(){for(const e of Object.keys(this.pluginInsMap)){const t=this.pluginInsMap[e];t.init&&t.init()}}destroy(){for(const e of Object.keys(this.pluginInsMap)){const t=this.pluginInsMap[e];t.destroy&&"function"==typeof t.destroy&&t.destroy()}this.pluginInsMap={},this.plugins=[]}}const ye=class{constructor({emitter:e,config:t,sdk:i}){this.boundSend=null,this.hashEvent=null,this.spaSwitchHandler=null,this.emitter=e,this.config=t,this.sdk=i}init(){const e=this.config;this.boundSend=()=>{me({event:"$PageView",properties:{}},e)},this.sdk&&!0===this.sdk._postConsentInit||setTimeout(()=>{this.boundSend()},0),e.isSinglePageApp&&this.addSinglePageListener()}addSinglePageListener(){this.spaSwitchHandler=e=>{e!==location.href&&this.boundSend()},this.emitter.on(y,this.spaSwitchHandler)}destroy(){this.spaSwitchHandler&&(this.emitter.off(y,this.spaSwitchHandler),this.spaSwitchHandler=null),this.hashEvent&&this.boundSend&&(window.removeEventListener(this.hashEvent,this.boundSend),this.hashEvent=null),this.boundSend=null}};ye.NAME="pageview";let Ae=ye;const Re=class{constructor({emitter:e,config:t,sdk:i}){this.startTime=Date.now(),this.pageShowStatus=!0,this.pageHiddenStatus=!1,this.timer=null,this.currentPageUrl=document.referrer,this.url=location.href,this.title=document.title||"",this.heartbeatIntervalTime=5e3,this.heartbeatIntervalTimer=null,this.pageId=null,this.storageName="sensorswavewebjssdkpageleave",this.maxDuration=432e3,this.eventListeners=[],this._skipFirstPageEnd=!1,this.emitter=e,this.config=t,this.sdk=i}__canCapture(){return!this.sdk||"function"!=typeof this.sdk.hasOptedOutCapturing||!this.sdk.hasOptedOutCapturing()}init(){this.pageId=Number(String(g()).slice(2,5)+String(g()).slice(2,4)+String(Date.now()).slice(-4)),this.addEventListener(),this.sdk&&!0===this.sdk._postConsentInit&&(this._skipFirstPageEnd=!0),!0===document.hidden?this.pageShowStatus=!1:this.addHeartBeatInterval()}log(e){console.log(e)}refreshPageEndTimer(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.timer=setTimeout(()=>{this.pageHiddenStatus=!1},5e3)}hiddenStatusHandler(){this.timer&&clearTimeout(this.timer),this.timer=null,this.pageHiddenStatus=!1}pageStartHandler(){this.startTime=Date.now(),1==!document.hidden?this.pageShowStatus=!0:this.pageShowStatus=!1,this.url=location.href,this.title=document.title,this._skipFirstPageEnd=!1}pageEndHandler(){if(!0===this.pageHiddenStatus)return;if(!this.__canCapture())return;const e=this.getPageLeaveProperties();!1===this.pageShowStatus&&delete e.$event_duration,this.pageShowStatus=!1,this.pageHiddenStatus=!0,me({event:R,properties:e},this.config),this.refreshPageEndTimer(),this.delHeartBeatData()}addEventListener(){this.addPageStartListener(),this.addPageSwitchListener(),this.addSinglePageListener(),this.addPageEndListener()}addPageStartListener(){if("onpageshow"in window){const e=()=>{this.pageStartHandler(),this.hiddenStatusHandler()};window.addEventListener("pageshow",e),this.eventListeners.push({target:window,event:"pageshow",handler:e})}}addSinglePageListener(){this.config.isSinglePageApp&&this.emitter.on(y,e=>{e!==location.href&&(this.url=e,this.pageEndHandler(),this.stopHeartBeatInterval(),this.currentPageUrl=this.url,this.pageStartHandler(),this.hiddenStatusHandler(),this.addHeartBeatInterval())})}addPageEndListener(){["pagehide","beforeunload"].forEach(e=>{if(`on${e}`in window){const t=()=>{if(this._skipFirstPageEnd)return this._skipFirstPageEnd=!1,void this.stopHeartBeatInterval();this.pageEndHandler(),this.stopHeartBeatInterval()};window.addEventListener(e,t),this.eventListeners.push({target:window,event:e,handler:t})}})}addPageSwitchListener(){const e=()=>{"visible"===document.visibilityState?(this.pageStartHandler(),this.hiddenStatusHandler(),this.addHeartBeatInterval()):(this.url=location.href,this.title=document.title,this.stopHeartBeatInterval(),this.delHeartBeatData())};document.addEventListener("visibilitychange",e),this.eventListeners.push({target:document,event:"visibilitychange",handler:e})}addHeartBeatInterval(){b.isSupport()&&this.startHeartBeatInterval()}startHeartBeatInterval(){this.heartbeatIntervalTimer&&this.stopHeartBeatInterval(),this.sdk&&!0===this.sdk._postConsentInit&&!0===this._skipFirstPageEnd||(this.heartbeatIntervalTimer=setInterval(()=>{this.saveHeartBeatData()},this.heartbeatIntervalTime),this.saveHeartBeatData("is_first_heartbeat"),this.reissueHeartBeatData())}stopHeartBeatInterval(){this.heartbeatIntervalTimer&&clearInterval(this.heartbeatIntervalTimer),this.heartbeatIntervalTimer=null}saveHeartBeatData(e){if(!this.__canCapture())return;const t=this.getPageLeaveProperties();t.$time=Date.now(),"is_first_heartbeat"===e&&(t.$event_duration=3);const i={type:"track",event:R,properties:t,time:t.$time};i.heartbeat_interval_time=this.heartbeatIntervalTime,b.isSupport()&&b.set(`${this.storageName}-${this.pageId}`,JSON.stringify(i))}delHeartBeatData(e){b.isSupport()&&b.remove(e||`${this.storageName}-${this.pageId}`)}reissueHeartBeatData(){if(this.__canCapture())for(let e=window.localStorage.length-1;e>=0;e--){const t=window.localStorage.key(e);if(t&&t!==`${this.storageName}-${this.pageId}`&&0===t.indexOf(`${this.storageName}-`)){const e=b.parse(t);n(e)&&Date.now()-e.time>e.heartbeat_interval_time+5e3&&(delete e.heartbeat_interval_time,e._flush_time=/* @__PURE__ */(new Date).getTime(),me({event:R,properties:e?.properties},this.config),this.delHeartBeatData(t))}}}getPageLeaveProperties(){let e=(Date.now()-this.startTime)/1e3;(isNaN(e)||e<0||e>this.maxDuration)&&(e=0),e=Number(e.toFixed(3));const t={$title:this.title,$url:this.url?.substring(0,1e3),$pathname:I(this.url)};return 0!==e&&(t.$event_duration=e),t}destroy(){this.eventListeners.forEach(({target:e,event:t,handler:i})=>{e.removeEventListener(t,i)}),this.eventListeners=[],this.timer&&(clearTimeout(this.timer),this.timer=null),this.heartbeatIntervalTimer&&(clearInterval(this.heartbeatIntervalTimer),this.heartbeatIntervalTimer=null)}};Re.NAME="pageleave";let Te=Re;const Ce=class{constructor({emitter:e,config:t,sdk:i}){this.eventSended=!1,this.emitter=e,this.config=t,this.sdk=i}init(){if(this.sdk&&!0===this.sdk._postConsentInit)return;const e=()=>{let t=0;const i={};if(window.performance){t=function(){let e=0;if("function"==typeof performance.getEntriesByType){const t=performance.getEntriesByType("navigation");t.length>0&&(e=t[0].domContentLoadedEventEnd||0)}return e}();const e=function(){if(performance.getEntries&&"function"==typeof performance.getEntries){const e=performance.getEntries();let t=0;for(const i of e)"transferSize"in i&&(t+=i.transferSize);if("number"==typeof t&&t>=0&&t<10737418240)return Number((t/1024).toFixed(3))}}();e&&(i.$page_resource_size=e)}else console.warn("Performance API is not supported.");t>0&&!Number.isFinite(t)&&(i.$event_duration=Number((t/1e3).toFixed(3))),this.eventSended||(this.eventSended=!0,me({event:"$PageLoad",properties:i},this.config)),window.removeEventListener("load",e)};"complete"===document.readyState?e():window.addEventListener&&window.addEventListener("load",e)}};Ce.NAME="pageload";let Ne=Ce;function Pe(e){if(!l(e))return!1;const t=o(e.tagName)?e.tagName.toLowerCase():"",i={};return i.$element_type=t,i.$element_name=e.getAttribute("name")||"",i.$element_id=e.getAttribute("id")||"",i.$element_class_name=o(e.className)?e.className:"",i.$element_target_url=e.getAttribute("href")||"",i.$element_content=function(e,t){return o(t)&&"input"===t.toLowerCase()?("button"===(i=e).type||"submit"===i.type)&&i.value||"":function(e,t){let i="",n="";return e.textContent?i=_(e.textContent):e.innerText&&(i=_(e.innerText)),i&&(i=i.replace(/[\r\n]/g," ").replace(/[ ]+/g," ").substring(0,255)),n=i||"","input"!==t&&"INPUT"!==t||(n=e.value||""),n}(e,t);var i}(e,t)||"",i.$element_selector=ke(e)||"",i.$element_path=function(e){let t=[];for(;e.parentNode&&l(e);){if(!o(e.tagName))return"";if(e.id&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.id)){t.unshift(e.tagName.toLowerCase()+"#"+e.id);break}if(e===document.body){t.unshift("body");break}t.unshift(e.tagName.toLowerCase()),e=e.parentNode}return t.join(" > ")}(e)||"",i}function ke(e,t=[]){if(!(e&&e.parentNode&&e.parentNode.children&&o(e.tagName)))return"";t=Array.isArray(t)?t:[];const i=e.nodeName.toLowerCase();return e&&"body"!==i&&1==e.nodeType?(t.unshift(function(e){if(!e||!l(e)||!o(e.tagName))return"";let t=e.parentNode&&9==e.parentNode.nodeType?-1:function(e){if(!e.parentNode)return-1;let t=0;const i=e.tagName,n=e.parentNode.children;for(let s=0,r=n.length;s<r;s++)if(n[s].tagName===i){if(e===n[s])return t;t++}return-1}(e);return e.getAttribute&&e.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.getAttribute("id"))?"#"+e.getAttribute("id"):e.tagName.toLowerCase()+(~t?":nth-of-type("+(t+1)+")":"")}(e)),e.getAttribute&&e.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.getAttribute("id"))?t.join(" > "):ke(e.parentNode,t)):(t.unshift("body"),t.join(" > "))}function xe(){return{scrollLeft:document.body.scrollLeft||document.documentElement.scrollLeft||0,scrollTop:document.body.scrollTop||document.documentElement.scrollTop||0}}function Le(e){if(document.documentElement.getBoundingClientRect){const t=e.getBoundingClientRect();return{targetEleX:t.left+xe().scrollLeft||0,targetEleY:t.top+xe().scrollTop||0}}return{targetEleX:0,targetEleY:0}}function Me(e){return Number(Number(e).toFixed(3))}const $e=class{constructor({emitter:e,config:t}){this.isInitialized=!1,this.boundHandleClick=null,this.emitter=e,this.config=t}init(){this.isInitialized||(this.boundHandleClick=this.handleClick.bind(this),document.addEventListener("click",this.boundHandleClick,!0),this.isInitialized=!0)}handleClick(e){const t=e.target;if(!t)return;if(!["A","INPUT","BUTTON","TEXTAREA"].includes(t.tagName))return;if("true"===t.getAttribute("sensorswave-disable"))return;const i=function(e,t){const i=Pe(e);if(!i)return!1;const n=function(e,t){const i=t.pageX||t.clientX+xe().scrollLeft||t.offsetX+Le(e).targetEleX,n=t.pageY||t.clientY+xe().scrollTop||t.offsetY+Le(e).targetEleY;return{$page_x:Me(i),$page_y:Me(n)}}(e,t);return i.$page_x=n.$page_x,i.$page_y=n.$page_y,i}(t,e);me({event:"$WebClick",properties:i||{}},this.config)}destroy(){this.boundHandleClick&&(document.removeEventListener("click",this.boundHandleClick,!0),this.boundHandleClick=null),this.isInitialized=!1}};$e.NAME="webclick";let De=$e;const Fe=class{constructor({emitter:e,config:t,sdk:i}){this.updateInterval=null,this.fetchingPromise=null,this.emitter=e,this.config=t,this.sdk=i}init(){const e=this.config;if(e.enableAB){if(this.sdk&&"function"==typeof this.sdk.hasOptedOutCapturing&&this.sdk.hasOptedOutCapturing())return;this.fastFetch().then(()=>{this.emitter.emit(A)}),e.abRefreshInterval<3e4&&(e.abRefreshInterval=3e4),this.updateInterval=setInterval(()=>{this.fetchNewData().catch(console.warn)},e.abRefreshInterval)}}async fastFetch(){const e=N.getABData(this.config.abRefreshInterval);return e&&e.length?(this.emitter.emit(A),Promise.resolve(e)):this.fetchNewData()}async fetchNewData(){return this.fetchingPromise||(this.fetchingPromise=new Promise(e=>{!function({opts:e,cb:t}){if(!se())return void(t&&t({}));if(!re())return void(t&&t({}));const i=N.getLoginId(),n=N.getAnonId();if(!i&&!n)return void(t&&t({}));const s={user:{login_id:i||"",anon_id:n||"",props:{...ee(),...ge(N.getCommonProps())}},sdk:"webjs",sdk_version:w};L({url:le(e),method:"POST",data:s,headers:he(e),callback:e=>{200!==e.statusCode?(console.error("Failed to fetch feature flags"),t&&t({})):t&&t(e.json)}})}({opts:this.config,cb:t=>{N.saveABData(t?.data?.results||[]),e(t),this.fetchingPromise=null}})})),this.fetchingPromise}async getFeatureGate(e){return await this.fastFetch().catch(console.warn),N.getABData(this.config.abRefreshInterval).find(t=>t.typ===C.FEATURE_GATE&&t.key==e)}async checkFeatureGate(e){const t=await this.getFeatureGate(e);return!!t&&(!t.hasOwnProperty("vid")&&t.key?(Ie({isUnset:!0,data:t,opts:this.config}),!1):(Ie({data:t,opts:this.config}),"fail"!==t.vid))}async getExperiment(e){await this.fastFetch().catch(console.warn);const t=N.getABData(this.config.abRefreshInterval).find(t=>t.typ===C.EXPERIMENT&&t.key===e);return t?!t.hasOwnProperty("vid")&&t.key?(Ie({isUnset:!0,data:t,opts:this.config}),{}):(Ie({data:t,opts:this.config}),t?.value||{}):{}}async getFeatureConfig(e){await this.fastFetch().catch(console.warn);const t=N.getABData(this.config.abRefreshInterval).find(t=>t.typ===C.FEATURE_CONFIG&&t.key===e);if(!t)return{};if(!t.hasOwnProperty("vid")&&t.key)return Ie({isUnset:!0,data:t,opts:this.config}),{};Ie({data:t,opts:this.config});const i=t?.value;if(i){if(n(i))return i;try{return JSON.parse(i)}catch{return i}}return{}}destroy(){this.updateInterval&&(clearInterval(this.updateInterval),this.updateInterval=null),this.fetchingPromise=null}};Fe.NAME="abtest";let Be=Fe;const He=["utm_source","utm_medium","utm_campaign","utm_content","utm_term"],Ue="sensorswave_utm",We=class e{constructor({sdk:e,emitter:t,config:i}){this.sdk=e,this.emitter=t,this.config=i}init(){if(this.sdk&&!0===this.sdk._postConsentInit){let t=e.readFromSessionStorage();return t&&0!==Object.keys(t).length||(t=e.captureAndStore(this.config?.debug)),void this.scheduleInitialUTM(t)}const t=e.getUTMFromURL();e.saveToSessionStorage(t,this.config?.debug),this.scheduleInitialUTM(t)}scheduleInitialUTM(e){setTimeout(()=>{this.sendInitialUTM(e)},0)}static getUTMFromURL(){try{const e=new URLSearchParams(window.location.search),t={};return He.forEach(i=>{const n=e.get(i);n&&(t[i]=n)}),t}catch(t){return e.getUTMFromURLFallback()}}static getUTMFromURLFallback(){const e={};return window.location.search.substring(1).split("&").forEach(t=>{const[i,n]=t.split("="),s=decodeURIComponent(i),r=n?decodeURIComponent(n):"";He.includes(s)&&(e[s]=r)}),e}static readFromSessionStorage(){try{const e=sessionStorage.getItem(Ue);if(!e)return{};const t=JSON.parse(e);return t&&"object"==typeof t?t:{}}catch(e){return{}}}static saveToSessionStorage(e,t=!1){try{sessionStorage.setItem(Ue,JSON.stringify(e))}catch(i){t&&console.warn("[SensorsWave UTM] Failed to save to sessionStorage:",i)}}static captureAndStore(t=!1){const i=e.getUTMFromURL();return e.saveToSessionStorage(i,t),i}sendInitialUTM(e){const t={};He.forEach(i=>{t[`$initial_${i}`]=null!=e[i]?e[i]:""});try{this.sdk.profileSetOnce(t)}catch(i){this.config.debug&&console.warn("[SensorsWave UTM] Failed to send initial UTM:",i)}}destroy(){}};We.NAME="UTM";let Xe=We;const je=1e3,qe=/^\s*(?:async\s+)?at\s+(?:(.+)\s+\()?(.+?):(\d+):(\d+)\)?$/,Ge=/^(?:(.*)@)?(.+?):(\d+):(\d+)$/;function ze(e){let t=e;try{const e=location.origin;e&&0===t.indexOf(e)&&(t=t.substring(e.length))}catch(s){}const i=t.indexOf("?");i>-1&&(t=t.substring(0,i));const n=t.indexOf("#");return n>-1&&(t=t.substring(0,n)),t}function Ve(e){return e.map(e=>({platform:"web:javascript",filename:ze(e.file),function:e.fn||"?",lineno:Number(e.line),colno:Number(e.col),abs_path:Ye(e.file,1e3)}))}function Ye(e,t){return e.length>t?e.substring(0,t):e}function Ke(e){let t;if("string"==typeof e)t=e;else if(null!==e&&"object"==typeof e){try{t=JSON.stringify(e)}catch(i){t=Object.prototype.toString.call(e)}t||(t=Object.prototype.toString.call(e))}else t=String(e);return Ye(t,je)}function Je(e){const{frames:t,headerType:i}=function(e){const t=[];let i="";if(!e||"string"!=typeof e)return{frames:t,headerType:i};const n=e.split(/\r?\n/);for(let s=0;s<n.length;s++){const e=n[s];if(!e||e.length>1024)continue;const r=e.match(qe),o=r?null:e.match(Ge),a=r||o;if(a)t.push({fn:a[1]||"?",file:a[2],line:a[3],col:a[4]});else if(0===s){const t=e.indexOf(":");t>0&&(i=e.substring(0,t).trim())}if(t.length>=30)break}return{frames:t,headerType:i}}(e&&e.stack);let n=e&&e.name||i||"Error";return n=Ye(String(n),200),{$exception_level:"error",$exception_type:n,$exception_message:Ye(String(e&&e.message||""),je),$exception_frames:Ve(t)}}function Ze(e,t,i,n){let s=[];return t&&(s=[{platform:"web:javascript",filename:ze(t),function:"?",lineno:i||0,colno:n||0,abs_path:Ye(t,1e3)}]),{$exception_level:"error",$exception_type:"Error",$exception_message:Ye(String(e||""),je),$exception_frames:s}}class Qe{constructor(e=10,t=1,i=1e4){this.buckets=/* @__PURE__ */new Map,this.bucketSize=e,this.refillRate=t,this.refillInterval=i}allow(e){const t=Date.now();let i=this.buckets.get(e);if(i){if(t>i.lastRefill){const e=Math.floor((t-i.lastRefill)/this.refillInterval)*this.refillRate;e>0&&(i.tokens=Math.min(this.bucketSize,i.tokens+e),i.lastRefill+=e/this.refillRate*this.refillInterval)}}else i={tokens:this.bucketSize,lastRefill:t},this.buckets.set(e,i);return i.tokens>=1&&(i.tokens-=1,!0)}reset(){this.buckets.clear()}}const et=class{constructor({emitter:e,config:t}){this.isInitialized=!1,this.boundHandleError=null,this.boundHandleRejection=null,this.rateLimiter=new Qe,this.emitter=e,this.config=t}init(){this.isInitialized||(this.boundHandleError=this.handleError.bind(this),this.boundHandleRejection=this.handleRejection.bind(this),window.addEventListener("error",this.boundHandleError,!0),window.addEventListener("unhandledrejection",this.boundHandleRejection),this.isInitialized=!0)}handleError(e){try{const t=e.target;let i;if(t&&t!==window&&t.tagName)i=function(e){const t=e,i=(t.tagName||"").toLowerCase(),n=Ye(String(t.src||t.href||""),je);return{$exception_level:"error",$exception_type:"ResourceLoadError",$exception_message:`Failed to load <${i}>${n?` from ${n}`:""}`,$exception_frames:[]}}(t);else{const t=e;i=t.error instanceof Error?Je(t.error):Ze(String(t.message||""),t.filename,t.lineno,t.colno)}this.send(i)}catch(t){}}handleRejection(e){try{const t=e.reason;this.send(function(e){return e instanceof Error?Je(e):{$exception_level:"error",$exception_type:"UnhandledRejection",$exception_message:Ke(e),$exception_frames:[]}}(t))}catch(t){}}send(e){e.$exception_message&&this.rateLimiter.allow(e.$exception_type)&&me({event:T,properties:e},this.config)}destroy(){this.boundHandleError&&(window.removeEventListener("error",this.boundHandleError,!0),this.boundHandleError=null),this.boundHandleRejection&&(window.removeEventListener("unhandledrejection",this.boundHandleRejection),this.boundHandleRejection=null),this.rateLimiter.reset(),this.isInitialized=!1}};et.NAME="exception";let tt=et;const it="data-sw-exposure-event-name",nt="data-sw-exposure-config-",st=`[${it}]`,rt={visibleRatio:0,stayDuration:0,repeated:!0};function ot(e,t){const i={};if(!n(e))return i;const s=e;if(void 0!==s.visibleRatio){const e=Number(s.visibleRatio);!isNaN(e)&&e>=0&&e<=1?i.visibleRatio=e:t&&t("[exposure] parameter config.visibleRatio 非法(值域 0~1),已忽略:",s.visibleRatio)}if(void 0!==s.stayDuration){const e=Number(s.stayDuration);!isNaN(e)&&e>=0?i.stayDuration=e:t&&t("[exposure] parameter config.stayDuration 非法(须 >= 0),已忽略:",s.stayDuration)}if(void 0!==s.repeated){const e=s.repeated;!0===e||"true"===e?i.repeated=!0:!1===e||"false"===e?i.repeated=!1:t&&t("[exposure] parameter config.repeated 非法(须为布尔),已忽略:",e)}return i}function at(...e){const t={...rt};for(let i=0;i<e.length;i++){const s=e[i];if(!n(s))continue;const r=s;void 0!==r.visibleRatio&&(t.visibleRatio=r.visibleRatio),void 0!==r.stayDuration&&(t.stayDuration=r.stayDuration),void 0!==r.repeated&&(t.repeated=r.repeated)}return t}function ct(e){const t=(e.getAttribute(it)||"").trim();let i={},s={};const r=e.getAttribute("data-sw-exposure-option");if(r){const e=d(r);n(e)&&(n(e.config)&&(i=e.config),n(e.properties)&&(s=e.properties))}const a=e.getAttribute(nt+"visible-ratio");null!==a&&(i.visibleRatio=a);const c=e.getAttribute(nt+"stay-duration");null!==c&&(i.stayDuration=c);const u=e.getAttribute(nt+"repeated");null!==u&&(i.repeated=u);const l=e.attributes;for(let n=0;n<l.length;n++){const e=l[n],t=e.name;if(o(t)&&0===t.indexOf("data-sw-exposure-property-")){const i=t.substring(26);i&&(s[i]=e.value)}}return{eventName:t,config:ot(i),properties:s}}const ut=class{constructor({emitter:e,config:t,sdk:i}){this.isInitialized=!1,this.observers=/* @__PURE__ */new Map,this.records=/* @__PURE__ */new Map,this.mutationObserver=null,this.boundHandleIntersection=null,this.boundHandleMutation=null,this.boundHandleVisibility=null,this.boundHandleReady=null,this.boundHandleSpa=null,this.eventListeners=[],this.globalConfig={...rt},this.log=function(){},this.emitter=e,this.config=t,this.sdk=i}init(){this.isInitialized||(function(){try{return"undefined"!=typeof window&&"IntersectionObserver"in window&&"MutationObserver"in window}catch(e){return!1}}()?(this.log=!0==(!0===this.config.debug)&&"undefined"!=typeof console&&console.log?function(...e){console.log("[SensorsWave][exposure]",...e)}:function(){},this.globalConfig=at(this.globalConfig,ot(this.config.exposureConfig,this.log)),this.boundHandleIntersection=this.handleIntersection.bind(this),this.boundHandleMutation=this.handleMutation.bind(this),this.boundHandleVisibility=this.handleVisibility.bind(this),"loading"===document.readyState?(this.boundHandleReady=()=>{this.scanDocument(),this.observeMutations()},document.addEventListener("DOMContentLoaded",this.boundHandleReady),this.eventListeners.push({target:document,event:"DOMContentLoaded",handler:this.boundHandleReady})):(this.scanDocument(),this.observeMutations()),!0===this.config.isSinglePageApp&&(this.boundHandleSpa=e=>{this.handleSpaSwitch(e)},this.emitter.on(y,this.boundHandleSpa)),document.addEventListener("visibilitychange",this.boundHandleVisibility),this.eventListeners.push({target:document,event:"visibilitychange",handler:this.boundHandleVisibility}),!0===document.hidden&&this.stop(),this.isInitialized=!0):console.warn("[SensorsWave][exposure] 当前浏览器不支持 IntersectionObserver / MutationObserver,曝光采集未初始化"))}addExposureView(e,t){this.isInitialized?l(e)?n(t)&&o(t.eventName)&&t.eventName.trim()?this.addOrUpdateWatchEle(e,{eventName:t.eventName.trim(),config:n(t.config)?ot(t.config,this.log):void 0,properties:n(t.properties)?{...t.properties}:{},listener:n(t.listener)?{...t.listener}:{}},"api"):this.log("addExposureView parameter option.eventName 缺失:",t):this.log("addExposureView parameter element 非法:",e):this.log("曝光插件未初始化(enableExposureTrack 未开启或浏览器不支持)")}removeExposureView(e){this.isInitialized?l(e)?this.removeWatchEle(e):this.log("removeExposureView parameter element 非法:",e):this.log("曝光插件未初始化")}scanDocument(e){try{const t=e||document;if(!t.querySelectorAll)return;const i=t.querySelectorAll(st);for(let e=0;e<i.length;e++){const t=i[e];this.addOrUpdateWatchEle(t,ct(t),"attr")}}catch(t){}}addOrUpdateWatchEle(e,t,i){if(!e||!l(e))return void this.log("parameter element error:",e);if(!o(t.eventName)||!t.eventName.trim())return void this.log("parameter option.eventName error:",t);const n=this.records.get(e);if(n&&"api"===n.source&&"attr"===i)return void this.log("声明式属性变更被忽略:元素已由 addExposureView 注册",e);const s=at(this.globalConfig,n&&n.config,t.config);if(n&&n.config.visibleRatio===s.visibleRatio)return n.eventName=t.eventName,n.source=i,n.config=s,n.properties={...t.properties||{}},n.listener=t.listener||{},void(n.hasSent=!1);n&&this.removeWatchEle(e);const r={ele:e,eventName:t.eventName,source:i,config:s,properties:{...t.properties||{}},listener:t.listener||{},timer:null,hasSent:!1};this.records.set(e,r),this.getIntersection(s.visibleRatio).observe(e)}getIntersection(e){let t=this.observers.get(e);return!t&&this.boundHandleIntersection&&(t=new IntersectionObserver(this.boundHandleIntersection,{threshold:e}),this.observers.set(e,t)),t}removeWatchEle(e){const t=this.records.get(e);if(!t)return;const i=this.observers.get(t.config.visibleRatio);i&&l(e)&&i.unobserve(e),t.timer&&(clearTimeout(t.timer),t.timer=null),this.records.delete(e)}handleIntersection(e){try{for(const t of e){const e=t.target,i=this.records.get(e);i&&(!0===t.isIntersecting&&t.intersectionRatio>=i.config.visibleRatio?!0!==document.hidden&&(i.timer&&clearTimeout(i.timer),i.timer=setTimeout(()=>{this.fireExposure(e)},1e3*i.config.stayDuration)):i.timer&&(clearTimeout(i.timer),i.timer=null))}}catch(t){}}fireExposure(e){try{const i=this.records.get(e);if(i&&(i.timer=null),!i||i.hasSent)return;let n={width:0,height:0};try{n=e.getBoundingClientRect()}catch(t){}if(!n.width||!n.height)return;if(!e.isConnected)return void this.removeWatchEle(e);if(this.sdk&&"function"==typeof this.sdk.hasOptedOutCapturing&&this.sdk.hasOptedOutCapturing())return;const r={...Pe(e),...i.properties},{shouldExpose:o,didExpose:a}=i.listener||{};if(o&&s(o))try{if(!1===o(e,r))return}catch(t){return}if(me({event:i.eventName,properties:r},this.config),i.hasSent=!0,i.config.repeated&&(i.hasSent=!1),a&&s(a))try{a(e,r)}catch(t){}}catch(t){}}observeMutations(){!this.mutationObserver&&this.boundHandleMutation&&(this.mutationObserver=new MutationObserver(this.boundHandleMutation),this.mutationObserver.observe(document.body,{attributes:!0,childList:!0,subtree:!0}))}handleMutation(e){try{for(const t of e)if("childList"===t.type){if(t.removedNodes.length>0)for(const e of Array.from(t.removedNodes)){if(1!==e.nodeType)continue;this.removeWatchEle(e);const t=e.querySelectorAll(st);for(let e=0;e<t.length;e++)this.removeWatchEle(t[e])}if(t.addedNodes.length>0)for(const e of Array.from(t.addedNodes))1===e.nodeType&&(e.hasAttribute(it)&&this.addOrUpdateWatchEle(e,ct(e),"attr"),this.scanDocument(e))}else"attributes"===t.type&&this.handleAttrChange(t)}catch(t){}}handleAttrChange(e){const t=e.attributeName;if(!t||0!==t.indexOf("data-sw-exposure"))return;const i=e.target;t!==it||(i.getAttribute(t)||"").trim()?(i.getAttribute(it)||"").trim()&&this.addOrUpdateWatchEle(i,ct(i),"attr"):this.removeWatchEle(i)}handleSpaSwitch(e){try{if(e===location.href)return;this.stop();for(const[e,t]of Array.from(this.records))"attr"===t.source&&this.records.delete(e);this.start(),this.scanDocument()}catch(t){}}stop(){for(const e of Array.from(this.records.values())){const t=this.observers.get(e.config.visibleRatio);t&&t.unobserve(e.ele),e.timer&&(clearTimeout(e.timer),e.timer=null)}}start(){for(const e of Array.from(this.records.values())){if(!e.ele.isConnected){this.records.delete(e.ele);continue}const t=this.observers.get(e.config.visibleRatio);t&&t.observe(e.ele)}}handleVisibility(){try{"visible"===document.visibilityState?this.start():this.stop()}catch(e){}}destroy(){this.observers.forEach(e=>{try{e.disconnect()}catch(t){}}),this.observers.clear(),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null);for(const e of Array.from(this.records.values()))e.timer&&(clearTimeout(e.timer),e.timer=null);this.records.clear(),this.eventListeners.forEach(({target:e,event:t,handler:i})=>{e.removeEventListener(t,i)}),this.eventListeners=[],this.boundHandleSpa&&(this.emitter.off(y,this.boundHandleSpa),this.boundHandleSpa=null),this.boundHandleIntersection=null,this.boundHandleMutation=null,this.boundHandleVisibility=null,this.boundHandleReady=null,this.globalConfig={...rt},this.log=function(){},this.isInitialized=!1}};ut.NAME="exposure";let lt=ut;const ht=[],dt={debug:!1,sourceToken:"",apiHost:"",autoCapture:!0,isSinglePageApp:!1,crossSubdomainCookie:!0,enableAB:!1,abRefreshInterval:6e5,enableClickTrack:!1,enableExposureTrack:!1,batchSend:!1,enableErrorTrack:!1,enableCrashTrack:!1,optOutCapturing:!1,persistOptOut:!1},pt=new class{constructor(){this.__innerInited=!1,this.inited=!1,this.config={},this.eventEmitter=new e,this.pluginCore={},this.commonProps={},this.spaCleanup=null,this._optOutCapturing=!1,this.consentStorage=new we(!1),this._setupAfterConsentDone=!1,this._postConsentInit=!1,S.instance=this}init(e,t={}){return this.inited?this:(S.instance=this,t.sourceToken=e,this.mergeConfig(t),this.consentStorage=new we(!0===this.config.persistOptOut),this._optOutCapturing?this.consentStorage.write(!0):!0===this.config.optOutCapturing?(this._optOutCapturing=!0,this.consentStorage.write(!0)):!0===this.consentStorage.read()&&(this._optOutCapturing=!0),this.eventEmitter.emit("init-param",this.config),this.__innerInited=!0,this._optOutCapturing?(Xe.captureAndStore(this.config.debug),this.eventEmitter.emit(O),this.inited=!0,this):(this.__setupAfterConsent(),this.eventEmitter.emit(O),this.inited=!0,this))}__setupAfterConsent(){if(this._setupAfterConsentDone)return;this._setupAfterConsentDone=!0;const e=this.config;ht.length=0,N.init(e.crossSubdomainCookie),e.anonId&&N.setAnonId(e.anonId),function(){if(window._swFailedRequestsInitialized)return;window._swFailedRequestsInitialized=!0;const e=S.instance;e&&"function"==typeof e.hasOptedOutCapturing&&e.hasOptedOutCapturing()||e&&!0===e._postConsentInit||function(){const e=te.getAll();if(0!==e.length)for(let t=0,i=e.length;t<i;t+=10){const i=e.slice(t,t+10),n=[],s=[];i.forEach(e=>{Array.isArray(e.data)?n.push(...e.data):n.push(e.data),s.push(e.id)});const r=i[i.length-1],o=r.url,a=r.headers;L({url:o,method:"POST",data:n,headers:a,callback:e=>{200!==e.statusCode?(console.error("Failed to send batch stored requests:",e),P(e.statusCode)||s.forEach(e=>{te.dequeue(e)})):s.forEach(e=>{te.dequeue(e)})}})}}()}(),ht.push(Xe),e.autoCapture&&this.autoTrack(),e.enableAB&&ht.push(Be),e.enableClickTrack&&ht.push(De),e.enableCrashTrack&&e.debug&&console.warn("[SensorsWave] enableCrashTrack 仅在 app 宿主环境生效,当前 Web 环境不采集 crash"),e.enableErrorTrack&&ht.push(tt),e.enableExposureTrack&&ht.push(lt),this.pluginCore=new Oe({plugins:ht,emitter:this.eventEmitter,config:e,sdk:this}),this.spaCleanup=function(e){let t=location.href;const i=window.history.pushState,n=window.history.replaceState,r=function(){e(t),t=location.href};return s(window.history.pushState)&&(window.history.pushState=function(...n){i.apply(window.history,n),e(t),t=location.href}),s(window.history.replaceState)&&(window.history.replaceState=function(...i){n.apply(window.history,i),e(t),t=location.href}),window.addEventListener("popstate",r),function(){s(window.history.pushState)&&(window.history.pushState=i),s(window.history.replaceState)&&(window.history.replaceState=n),window.removeEventListener("popstate",r)}}(e=>{this.eventEmitter.emit(y,e)})}mergeConfig(e){this.config={...dt,...e}}__canCapture(){return this.inited&&!this._optOutCapturing}track(e){this.__canCapture()&&function(e,t){if(!se())return;if(!re())return;const i={...e};i.time||(i.time=Date.now()),i.login_id||(i.login_id=N.getLoginId()),i.anon_id||(i.anon_id=N.getAnonId()),i.trace_id||(i.trace_id=N.getTraceId()),i.properties={...ee(),...ge(N.getCommonProps()),...i.properties};const n=ue(t),s=he(t),r=!1!==t.batchSend&&ae();if(!r)return de(n,{data:[i],headers:s});te.enqueue(n,[i],s),r.add()}(e,this.config)}trackEvent(e,t){this.__canCapture()&&me({event:e,properties:t},this.config)}trackException(e,t){if(!this.__canCapture())return;const i={...t||{},...e instanceof Error?Je(e):Ze(String(e))};me({event:T,properties:i},this.config)}addExposureView(e,t){if(!this.__canCapture())return;const i=this.pluginCore.getPlugin(lt.NAME);i?i.addExposureView(e,t):console.warn("[SensorsWave] addExposureView 需在 init 时配置 enableExposureTrack: true")}removeExposureView(e){if(!this.__canCapture())return;const t=this.pluginCore.getPlugin(lt.NAME);t&&t.removeExposureView(e)}autoTrack(){ht.push(Ae,Ne,Te)}profileSet(e){this.__canCapture()&&Ee({userProps:{$set:e},opts:this.config})}profileSetOnce(e){this.__canCapture()&&Ee({userProps:{$set_once:e},opts:this.config})}profileIncrement(e){this.__canCapture()&&Ee({userProps:{$increment:e},opts:this.config})}profileAppend(e){this.__canCapture()&&Ee({userProps:{$append:e},opts:this.config})}profileUnion(e){this.__canCapture()&&Ee({userProps:{$union:e},opts:this.config})}profileUnset(e){if(!this.__canCapture())return;const t={};r(e)?e.forEach(function(e){t[e]=null}):t[e]=null,Ee({userProps:{$unset:t},opts:this.config})}profileDelete(){this.__canCapture()&&Ee({userProps:{$delete:!0},opts:this.config})}registerCommonProperties(e){if(!n(e))return console.warn("Commmon Properties must be an object!");this.commonProps=e,N.setCommonProps(this.commonProps)}clearCommonProperties(e){if(!r(e))return console.warn("Commmon Properties to be cleared must be an array!");e.forEach(e=>{delete this.commonProps[e]}),N.setCommonProps(this.commonProps)}identify(e){this.__canCapture()&&(N.setLoginId(e),function(e){if(!se())return;if(!re())return;const t=N.getLoginId(),i=N.getAnonId();if(!t||!i)return;const n={time:Date.now(),trace_id:N.getTraceId(),event:"$Identify",login_id:t,anon_id:i,properties:fe()},s=ue(e),r=he(e),o=ae();if(!o)return de(s,{data:[n],headers:r});te.enqueue(s,[n],r),o.add()}(this.config))}setLoginId(e){this.__canCapture()&&N.setLoginId(e)}getAnonId(){return this.__canCapture()?N.getAnonId():""}setAnonId(e){this.__canCapture()&&N.setAnonId(e)}getLoginId(){return this.__canCapture()?N.getLoginId():""}reset(e=!1){this.__canCapture()&&(N.clearLoginId(),e&&N.resetAnonId())}checkFeatureGate(e){if(!this.__canCapture())return Promise.resolve(!1);const t=this.pluginCore.getPlugin(Be.NAME);return this.config.enableAB&&t?t.checkFeatureGate(e):Promise.reject("AB is disabled")}getExperiment(e){if(!this.__canCapture())return Promise.resolve({});const t=this.pluginCore.getPlugin(Be.NAME);return this.config.enableAB&&t?t.getExperiment(e):Promise.reject("AB is disabled")}getFeatureConfig(e){if(!this.__canCapture())return Promise.resolve({});const t=this.pluginCore.getPlugin(Be.NAME);return this.config.enableAB&&t?t.getFeatureConfig(e):Promise.reject("AB is disabled")}optOutCapturing(){this._optOutCapturing=!0,this.consentStorage.write(!0),oe&&oe.pause()}optInCapturing(){if(this._optOutCapturing=!1,this.consentStorage.write(!1),oe&&oe.resume(),this.inited&&!this._setupAfterConsentDone){this._postConsentInit=!0;try{this.__setupAfterConsent(),this.eventEmitter.emit(O)}finally{this._postConsentInit=!1}}}hasOptedOutCapturing(){return this._optOutCapturing}destroy(){oe&&(oe.destroy(),oe=null),"undefined"!=typeof window&&(window._swFailedRequestsInitialized=!1),this.inited=!1,this.__innerInited=!1,this.spaCleanup&&"function"==typeof this.spaCleanup&&(this.spaCleanup(),this.spaCleanup=null),this.pluginCore&&"function"==typeof this.pluginCore.destroy&&this.pluginCore.destroy(),this.pluginCore={},this.eventEmitter&&this.eventEmitter.removeAllListeners(),this.consentStorage=new we(!0===this.config?.persistOptOut),this._optOutCapturing=!1,this._setupAfterConsentDone=!1,this._postConsentInit=!1,S.instance===this&&(S.instance=null)}};export{pt as default};
|
package/dist/index.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).SensorsWave=e()}(this,function(){"use strict";class t{constructor(){this.listeners={}}on(t,e,n=!1){if(t&&e){if(!s(e))throw new Error("listener must be a function");this.listeners[t]=this.listeners[t]||[],this.listeners[t].push({listener:e,once:n})}}off(t,e){const n=this.listeners[t];if(!n?.length)return;"number"==typeof e&&n.splice(e,1);const i=n.findIndex(t=>t.listener===e);-1!==i&&n.splice(i,1)}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((n,i)=>{n.listener.call(this,...e),n.listener.once&&this.off(t,i)})}once(t,e){this.on(t,e,!0)}removeAllListeners(t){t?this.listeners[t]=[]:this.listeners={}}}const e={get:function(t){const e=t+"=",n=document.cookie.split(";");for(let i=0,s=n.length;i<s;i++){let t=n[i];for(;" "==t.charAt(0);)t=t.substring(1,t.length);if(0==t.indexOf(e))return h(t.substring(e.length,t.length))}return null},set:function({name:t,value:e,expires:n,samesite:i,secure:s,domain:r}){let o="",a="",c="",u="";if(0!==(n=null==n||void 0===n?365:n)){const t=new Date;"s"===String(n).slice(-1)?t.setTime(t.getTime()+1e3*Number(String(n).slice(0,-1))):t.setTime(t.getTime()+24*n*60*60*1e3),o="; expires="+t.toUTCString()}function l(t){return t?t.replace(/\r\n/g,""):""}i&&(c="; SameSite="+i),s&&(a="; secure");const h=l(t),d=l(e),p=l(r);p&&(u="; domain="+p),h&&d&&(document.cookie=h+"="+encodeURIComponent(d)+o+"; path=/"+u+c+a)},remove:function(t){this.set({name:t,value:"",expires:-1})},isSupport:function({samesite:t,secure:e}={}){if(!navigator.cookieEnabled)return!1;const n="sensorswave_cookie_support_test";return this.set({name:n,value:"1",samesite:t,secure:e}),"1"===this.get(n)&&(this.remove(n),!0)}},n=Object.prototype.toString;function i(t){return"[object Object]"===n.call(t)}function s(t){const e=n.call(t);return"[object Function]"==e||"[object AsyncFunction]"==e}function r(t){return"[object Array]"==n.call(t)}function o(t){return"[object String]"==n.call(t)}function a(t){return void 0===t}const c=Object.prototype.hasOwnProperty;function u(t){if(i(t)){for(let e in t)if(c.call(t,e))return!1;return!0}return!1}function l(t){return!(!t||1!==t.nodeType)}function h(t){let e=t;try{e=decodeURIComponent(t)}catch(n){e=t}return e}function d(t){try{return JSON.parse(t)}catch(e){return""}}const p=function(){let t=Date.now();return function(e){return Math.ceil((t=(9301*t+49297)%233280,t/233280*e))}}();function g(){if("function"==typeof Uint32Array){let t;if("undefined"!=typeof crypto&&(t=crypto),t&&i(t)&&t.getRandomValues)return t.getRandomValues(new Uint32Array(1))[0]/Math.pow(2,32)}return p(1e19)/1e19}const f=function(){function t(t){return("0".repeat(t)+Date.now().toString(16)).slice(-t)}return function(){let e=String(screen.height*screen.width);e=e&&/\d{4,}/.test(e)?e.slice(-4):String(31242*g()).replace(".","").slice(0,4);return t(8)+"-"+g().toString(16).replace(".","").slice(-4)+"-"+function(){const t=navigator.userAgent;let e,n=[],i=0;function s(t,e){let i=0;for(let s=0;s<e.length;s++)i|=n[s]<<8*s;return(t^i)>>>0}for(let r=0;r<t.length;r++)e=t.charCodeAt(r),n.unshift(255&e),n.length>=4&&(i=s(i,n),n=[]);return n.length>0&&(i=s(i,n)),("0000"+i.toString(16)).slice(-4)}()+"-"+e+"-"+t(12)||(String(g())+String(g())+String(g())).slice(2,15)}}();function m(t,e){e&&"string"==typeof e||(e="");let n=null;try{n=new URL(t).hostname}catch(i){}return n||e}function E(t){let e=[];try{e=atob(t).split("").map(function(t){return"%"+("00"+t.charCodeAt(0).toString(16)).slice(-2)})}catch(n){e=[]}try{return decodeURIComponent(e.join(""))}catch(n){return e.join("")}}function _(t){let e="";try{e=btoa(encodeURIComponent(t).replace(/%([0-9A-F]{2})/g,function(t,e){return String.fromCharCode(parseInt(e,16))}))}catch(n){e=t}return e}const I={get:function(t){return window.localStorage.getItem(t)},parse:function(t){let e;try{e=JSON.parse(I.get(t))||null}catch(n){console.warn(n)}return e},set:function(t,e){try{window.localStorage.setItem(t,e)}catch(n){console.warn(n)}},remove:function(t){window.localStorage.removeItem(t)},isSupport:function(){let t=!0;try{const e="__local_store_support__",n="testIsSupportStorage";I.set(e,n),I.get(e)!==n&&(t=!1),I.remove(e)}catch(e){t=!1}return t}};function S(t){return t.trim()}function w(t){if(!t||"string"!=typeof t)return"";try{return new URL(t,window.location.origin).pathname}catch(e){return""}}const O={},v="1.4.0",b="init-ready",y="spa-switch",A="ff-ready",R="$PageLeave",T="$Exception";var C=(t=>(t[t.FEATURE_GATE=1]="FEATURE_GATE",t[t.FEATURE_CONFIG=2]="FEATURE_CONFIG",t[t.EXPERIMENT=3]="EXPERIMENT",t))(C||{});const N={crossSubdomain:!1,requests:[],_sessionState:{},_abData:[],_trace_id:"",commonProps:{},_state:{anon_id:"",login_id:"",identities:{}},getIdentityCookieID(){return this._state.identities?.$identity_cookie_id||""},getCommonProps:function(){return this.commonProps||{}},setCommonProps:function(t){this.commonProps=t},getAnonId(){return this._state.anon_id||this.getIdentityCookieID()||f()},getLoginId(){return this._state.login_id},getTraceId(){return this._trace_id||f()},set:function(t,e){this._state[t]=e,this.save()},getCookieName:function(){return"sensorswave2025jssdkcross"},getABLSName:function(){return"sensorswave2025jssdkablatest"},save:function(){let t=JSON.parse(JSON.stringify(this._state));t.identities&&(t.identities=_(JSON.stringify(t.identities)));const n=JSON.stringify(t);e.set({name:this.getCookieName(),value:n,expires:365})},init:function(t){let n,s;this.crossSubdomain=t,e.isSupport()&&(n=e.get(this.getCookieName()),s=d(n)),N._state={...s||{}},N._state.identities&&(N._state.identities=d(E(N._state.identities))),N._state.identities&&i(N._state.identities)&&!u(N._state.identities)||(N._state.identities={$identity_cookie_id:f()}),N.save()},setLoginId(t){"number"==typeof t&&(t=String(t)),void 0!==t&&t&&(N.set("login_id",t),N.save())},clearLoginId(){this._state.login_id="",this.save()},resetAnonId(){this._state.anon_id="",this._state.identities={$identity_cookie_id:f()},this.save()},setAnonId(t){"number"==typeof t&&(t=String(t)),"string"==typeof t&&t?(N.set("anon_id",t),N.save()):console.warn("[SensorsWave store] Invalid anonId, ignored:",t)},saveABData(t){if(!t||u(t))return;this._abData=t;let e=JSON.parse(JSON.stringify(this._abData));e=_(JSON.stringify(e));try{localStorage.setItem(this.getABLSName(),JSON.stringify({time:Date.now(),data:e,anon_id:this.getAnonId(),login_id:this.getLoginId()}))}catch(n){console.warn("Failed to save abdata to localStorage",n)}},getABData(t=6e5){try{let e=localStorage.getItem(this.getABLSName());if(e){const{time:n,data:i,login_id:s,anon_id:r}=d(e)||{};if(n&&i&&Date.now()-n<t&&r===this.getAnonId()&&(!s||s===this.getLoginId())){const t=d(E(i));return this._abData=Array.isArray(t)?t:[],this._abData}localStorage.removeItem(this.getABLSName())}}catch(e){this._abData=[]}return this._abData||[]}};function P(t){return!(t>=400&&t<500)||408===t||429===t}function k(t){var e;if(t.data)return{contentType:"application/json",body:(e=t.data,JSON.stringify(e,(t,e)=>"bigint"==typeof e?e.toString():e,undefined))}}const L=[];function $(t){const e={...t};e.timeout=e.timeout||6e4;const n=e.transport??"fetch",i=L.find(t=>t.transport===n)?.method??L[0]?.method;if(!i)throw new Error("No available transport method for HTTP request");i(e)}function F(t){return o(t=t||document.referrer)&&(t=h(t=t.trim()))||""}function x(t){const e=m(t=t||F());if(!e)return"";const n={baidu:[/^.*\.baidu\.com$/],bing:[/^.*\.bing\.com$/],google:[/^www\.google\.com$/,/^www\.google\.com\.[a-z]{2}$/,/^www\.google\.[a-z]{2}$/],sm:[/^m\.sm\.cn$/],so:[/^.+\.so\.com$/],sogou:[/^.*\.sogou\.com$/],yahoo:[/^.*\.yahoo\.com$/],duckduckgo:[/^.*\.duckduckgo\.com$/]};for(let i of Object.keys(n)){let t=n[i];for(let n=0,s=t.length;n<s;n++)if(t[n].test(e))return i}return""}function B(t,e){return-1!==t.indexOf(e)}"function"==typeof fetch&&L.push({transport:"fetch",method:function(t){if("undefined"==typeof fetch)return void console.error("fetch API is not available");const e=k(t),n=new Headers;t.headers&&Object.keys(t.headers).forEach(e=>{n.append(e,t.headers[e])}),e?.contentType&&n.append("Content-Type",e.contentType),fetch(t.url,{method:t.method||"GET",headers:n,body:e?.body}).then(e=>e.text().then(n=>{const i={statusCode:e.status,text:n};if(200===e.status)try{i.json=JSON.parse(n)}catch(s){console.error("Failed to parse response:",s)}t.callback?.(i)})).catch(e=>{console.error("Request failed:",e),t.callback?.({statusCode:0,text:String(e)})})}}),"undefined"!=typeof XMLHttpRequest&&L.push({transport:"XHR",method:function(t){if("undefined"==typeof XMLHttpRequest)return void console.error("XMLHttpRequest is not available");const e=new XMLHttpRequest;e.open(t.method||"GET",t.url,!0);const n=k(t);t.headers&&Object.keys(t.headers).forEach(n=>{e.setRequestHeader(n,t.headers[n])}),n?.contentType&&e.setRequestHeader("Content-Type",n.contentType),e.timeout=t.timeout||6e4,e.withCredentials=!0,e.onreadystatechange=()=>{if(4===e.readyState){const i={statusCode:e.status,text:e.responseText};if(200===e.status)try{i.json=JSON.parse(e.responseText)}catch(n){console.error("Failed to parse JSON response:",n)}t.callback?.(i)}},e.send(n?.body)}});const M={FACEBOOK:"Facebook",MOBILE:"Mobile",IOS:"iOS",ANDROID:"Android",TABLET:"Tablet",ANDROID_TABLET:"Android Tablet",IPAD:"iPad",APPLE:"Apple",APPLE_WATCH:"Apple Watch",SAFARI:"Safari",BLACKBERRY:"BlackBerry",SAMSUNG_BROWSER:"SamsungBrowser",SAMSUNG_INTERNET:"Samsung Internet",CHROME:"Chrome",CHROME_OS:"Chrome OS",CHROME_IOS:"Chrome iOS",INTERNET_EXPLORER:"Internet Explorer",INTERNET_EXPLORER_MOBILE:"Internet Explorer Mobile",OPERA:"Opera",OPERA_MINI:"Opera Mini",EDGE:"Edge",MICROSOFT_EDGE:"Microsoft Edge",FIREFOX:"Firefox",FIREFOX_IOS:"Firefox iOS",NINTENDO:"Nintendo",PLAYSTATION:"PlayStation",XBOX:"Xbox",ANDROID_MOBILE:"Android Mobile",MOBILE_SAFARI:"Mobile Safari",WINDOWS:"Windows",WINDOWS_PHONE:"Windows Phone",NOKIA:"Nokia",OUYA:"Ouya",GENERIC_MOBILE:"Generic mobile",GENERIC_TABLET:"Generic tablet",KONQUEROR:"Konqueror",UC_BROWSER:"UC Browser",HUAWEI:"Huawei",XIAOMI:"Xiaomi",OPPO:"OPPO",VIVO:"vivo"},D="(\\d+(\\.\\d+)?)",H=new RegExp("Version/"+D),U=new RegExp(M.XBOX,"i"),X=new RegExp(M.PLAYSTATION+" \\w+","i"),j=new RegExp(M.NINTENDO+" \\w+","i"),q=new RegExp(M.BLACKBERRY+"|PlayBook|BB10","i"),W=new RegExp("(HUAWEI|honor|HONOR)","i"),G=new RegExp("(Xiaomi|Redmi)","i"),z=new RegExp("(OPPO|realme)","i"),Y=new RegExp("(vivo|IQOO)","i"),K={"NT3.51":"NT 3.11","NT4.0":"NT 4.0","5.0":"2000",5.1:"XP",5.2:"XP","6.0":"Vista",6.1:"7",6.2:"8",6.3:"8.1",6.4:"10","10.0":"10"};function J(t,e){return e=e||"",B(t," OPR/")&&B(t,"Mini")?M.OPERA_MINI:B(t," OPR/")?M.OPERA:q.test(t)?M.BLACKBERRY:B(t,"IE"+M.MOBILE)||B(t,"WPDesktop")?M.INTERNET_EXPLORER_MOBILE:B(t,M.SAMSUNG_BROWSER)?M.SAMSUNG_INTERNET:B(t,M.EDGE)||B(t,"Edg/")?M.MICROSOFT_EDGE:B(t,"FBIOS")?M.FACEBOOK+" "+M.MOBILE:B(t,"UCWEB")||B(t,"UCBrowser")?M.UC_BROWSER:B(t,"CriOS")?M.CHROME_IOS:B(t,"CrMo")||B(t,M.CHROME)?M.CHROME:B(t,M.ANDROID)&&B(t,M.SAFARI)?M.ANDROID_MOBILE:B(t,"FxiOS")?M.FIREFOX_IOS:B(t.toLowerCase(),M.KONQUEROR.toLowerCase())?M.KONQUEROR:function(t,e){return e&&B(e,M.APPLE)||B(n=t,M.SAFARI)&&!B(n,M.CHROME)&&!B(n,M.ANDROID);var n}(t,e)?B(t,M.MOBILE)?M.MOBILE_SAFARI:M.SAFARI:B(t,M.FIREFOX)?M.FIREFOX:B(t,"MSIE")||B(t,"Trident/")?M.INTERNET_EXPLORER:B(t,"Gecko")?M.FIREFOX:""}const Z={[M.INTERNET_EXPLORER_MOBILE]:[new RegExp("rv:"+D)],[M.MICROSOFT_EDGE]:[new RegExp(M.EDGE+"?\\/"+D)],[M.CHROME]:[new RegExp("("+M.CHROME+"|CrMo)\\/"+D)],[M.CHROME_IOS]:[new RegExp("CriOS\\/"+D)],[M.UC_BROWSER]:[new RegExp("(UCBrowser|UCWEB)\\/"+D)],[M.SAFARI]:[H],[M.MOBILE_SAFARI]:[H],[M.OPERA]:[new RegExp("("+M.OPERA+"|OPR)\\/"+D)],[M.FIREFOX]:[new RegExp(M.FIREFOX+"\\/"+D)],[M.FIREFOX_IOS]:[new RegExp("FxiOS\\/"+D)],[M.KONQUEROR]:[new RegExp("Konqueror[:/]?"+D,"i")],[M.BLACKBERRY]:[new RegExp(M.BLACKBERRY+" "+D),H],[M.ANDROID_MOBILE]:[new RegExp("android\\s"+D,"i")],[M.SAMSUNG_INTERNET]:[new RegExp(M.SAMSUNG_BROWSER+"\\/"+D)],[M.INTERNET_EXPLORER]:[new RegExp("(rv:|MSIE )"+D)],Mozilla:[new RegExp("rv:"+D)]};function Q(t,e){const n=J(t,e),i=Z[n];if(a(i))return null;for(let s=0;s<i.length;s++){const e=i[s],n=t.match(e);if(n)return parseFloat(n[n.length-2])}return null}const V=[[new RegExp(M.XBOX+"; "+M.XBOX+" (.*?)[);]","i"),t=>[M.XBOX,t&&t[1]||""]],[new RegExp(M.NINTENDO,"i"),[M.NINTENDO,""]],[new RegExp(M.PLAYSTATION,"i"),[M.PLAYSTATION,""]],[q,[M.BLACKBERRY,""]],[new RegExp(M.WINDOWS,"i"),(t,e)=>{if(/Phone/.test(e)||/WPDesktop/.test(e))return[M.WINDOWS_PHONE,""];if(new RegExp(M.MOBILE).test(e)&&!/IEMobile\b/.test(e))return[M.WINDOWS+" "+M.MOBILE,""];const n=/Windows NT ([0-9.]+)/i.exec(e);if(n&&n[1]){const t=n[1];let i=K[t]||"";return/arm/i.test(e)&&(i="RT"),[M.WINDOWS,i]}return[M.WINDOWS,""]}],[/((iPhone|iPad|iPod).*?OS (\d+)_(\d+)_?(\d+)?|iPhone)/,t=>{if(t&&t[3]){const e=[t[3],t[4],t[5]||"0"];return[M.IOS,e.join(".")]}return[M.IOS,""]}],[/(watch.*\/(\d+\.\d+\.\d+)|watch os,(\d+\.\d+),)/i,t=>{let e="";return t&&t.length>=3&&(e=a(t[2])?t[3]:t[2]),["watchOS",e]}],[new RegExp("("+M.ANDROID+" (\\d+)\\.(\\d+)\\.?(\\d+)?|"+M.ANDROID+")","i"),t=>{if(t&&t[2]){const e=[t[2],t[3],t[4]||"0"];return[M.ANDROID,e.join(".")]}return[M.ANDROID,""]}],[/Mac OS X (\d+)[_.](\d+)[_.]?(\d+)?/i,t=>{const e=["Mac OS X",""];if(t&&t[1]){const n=[t[1],t[2],t[3]||"0"];e[1]=n.join(".")}return e}],[/Mac/i,["Mac OS X",""]],[/CrOS/,[M.CHROME_OS,""]],[/Linux|debian/i,["Linux",""]]];function tt(){const t=window.innerHeight||document.documentElement.clientHeight||document.body&&document.body.clientHeight||0,e=window.innerWidth||document.documentElement.clientWidth||document.body&&document.body.clientWidth||0,n=navigator.userAgent,i=function(t){for(let e=0;e<V.length;e++){const[n,i]=V[e],s=n.exec(t),r=s&&("function"==typeof i?i(s,t):i);if(r)return r}return["",""]}(n)||["",""];return{$browser:J(n),$browser_version:Q(n),$url:location?.href.substring(0,1e3),$host:location?.host,$viewport_height:t,$viewport_width:e,$lib:"webjs",$lib_version:v,$search_engine:x(),$referrer:F(),$referrer_host:m(r=r||F()),$title:document.title,$language:navigator.language,$model:(s=n,(j.test(s)?M.NINTENDO:X.test(s)?M.PLAYSTATION:U.test(s)?M.XBOX:new RegExp(M.OUYA,"i").test(s)?M.OUYA:new RegExp("("+M.WINDOWS_PHONE+"|WPDesktop)","i").test(s)?M.WINDOWS_PHONE:/iPad/.test(s)?M.IPAD:/iPod/.test(s)?"iPod Touch":/iPhone/.test(s)?"iPhone":/(watch)(?: ?os[,/]|\d,\d\/)[\d.]+/i.test(s)?M.APPLE_WATCH:q.test(s)?M.BLACKBERRY:/(kobo)\s(ereader|touch)/i.test(s)?"Kobo":new RegExp(M.NOKIA,"i").test(s)?M.NOKIA:/(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i.test(s)||/(kf[a-z]+)( bui|\)).+silk\//i.test(s)?"Kindle Fire":W.test(s)?M.HUAWEI:G.test(s)?M.XIAOMI:z.test(s)?M.OPPO:Y.test(s)?M.VIVO:/(Android|ZTE)/i.test(s)?!new RegExp(M.MOBILE).test(s)||/(9138B|TB782B|Nexus [97]|pixel c|HUAWEISHT|BTV|noble nook|smart ultra 6)/i.test(s)?/pixel[\daxl ]{1,6}/i.test(s)&&!/pixel c/i.test(s)||/(huaweimed-al00|tah-|APA|SM-G92|i980|zte|U304AA)/i.test(s)||/lmy47v/i.test(s)&&!/QTAQZ3/i.test(s)?M.ANDROID:M.ANDROID_TABLET:M.ANDROID:new RegExp("(pda|"+M.MOBILE+")","i").test(s)?M.GENERIC_MOBILE:new RegExp(M.TABLET,"i").test(s)&&!new RegExp(M.TABLET+" pc","i").test(s)?M.GENERIC_TABLET:"")||""),$os:i?.[0]||"",$os_version:i?.[1]||"",$pathname:location?.pathname,$screen_height:Number(screen.height)||0,$screen_width:Number(screen.width)||0,$timezone_offset:60*-(new Date).getTimezoneOffset()};var s,r}const et=new class{constructor(){this.STORAGE_KEY="sensorswave_unsent_events",this.MAX_QUEUE_SIZE=200,this.MAX_RETRY_COUNT=1,this.MAX_AGE_MS=6048e5,this.queue=[],this.loadFromStorage(),this.cleanupExpiredItems()}loadFromStorage(){try{const t=localStorage.getItem(this.STORAGE_KEY);t&&(this.queue=d(t)||[])}catch(t){console.warn("Failed to load queue from localStorage:",t),this.queue=[]}}cleanupExpiredItems(){const t=Date.now(),e=this.queue.filter(e=>t-e.timestamp<this.MAX_AGE_MS);e.length!==this.queue.length&&(this.queue=e,this.saveToStorage())}saveToStorage(){try{this.cleanupExpiredItems(),this.queue.length>this.MAX_QUEUE_SIZE&&(this.queue=this.queue.slice(-this.MAX_QUEUE_SIZE)),localStorage.setItem(this.STORAGE_KEY,JSON.stringify(this.queue))}catch(t){console.warn("Failed to save queue to localStorage:",t)}}enqueue(t,e,n,i=this.MAX_RETRY_COUNT){try{const s={id:f(),url:t,data:e,headers:n,timestamp:Date.now(),retryCount:0,maxRetries:i};return this.queue.push(s),this.saveToStorage(),s.id}catch(s){return console.warn("Failed to enqueue request:",s),""}}dequeue(t){try{this.queue=this.queue.filter(e=>e.id!==t),this.saveToStorage()}catch(e){console.warn("Failed to dequeue request:",e)}}getAll(){try{return this.cleanupExpiredItems(),[...this.queue]}catch(t){return console.warn("Failed to get queue items:",t),[]}}incrementRetryCount(t){const e=this.queue.find(e=>e.id===t);return!(!e||e.retryCount>=e.maxRetries||(e.retryCount++,this.saveToStorage(),0))}clear(){this.queue=[];try{localStorage.removeItem(this.STORAGE_KEY)}catch(t){console.warn("Failed to clear queue from localStorage:",t)}}getItemById(t){return this.queue.find(e=>e.id===t)}};class nt{constructor(t={}){this.flushTimer=null,this.isFlushing=!1,this.paused=!1,this.destroyed=!1,this.config={maxBatchSize:t.maxBatchSize||20,flushInterval:t.flushInterval||5e3},this.startFlushTimer()}pause(){this.paused=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null)}resume(){this.paused&&(this.paused=!1,this.startFlushTimer())}isPaused(){return this.paused}add(){et.getAll().length>=this.config.maxBatchSize&&this.triggerFlush()}triggerFlush(){this.paused||this.isFlushing||(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.isFlushing=!0,this.flush())}flush(){const t=et.getAll();if(0===t.length)return this.isFlushing=!1,void this.startFlushTimer();const e=t.slice(0,this.config.maxBatchSize),n=[],i=[];e.forEach(t=>{Array.isArray(t.data)?n.push(...t.data):n.push(t.data),i.push(t.id)});const s=e[e.length-1],r=s.url,o=s.headers;O.instance&&O.instance.config.debug&&console.log(JSON.stringify(n,null,2)),$({url:r,method:"POST",data:n,headers:o,callback:t=>{200===t.statusCode?i.forEach(t=>{et.dequeue(t)}):P(t.statusCode)?console.error("Failed to send batch events:",t):i.forEach(t=>{et.dequeue(t)}),this.isFlushing=!1,this.startFlushTimer()}})}startFlushTimer(){this.destroyed||(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.flushTimer=setInterval(()=>{et.getAll().length>0&&this.triggerFlush()},this.config.flushInterval))}destroy(){this.destroyed=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.paused||this.flush()}}let it=null;function st(){const t=O.instance;return!(!t||!t.__innerInited)||(console.warn("[SensorsWave] SDK is not initialized. Please call init() first."),!1)}function rt(){const t=O.instance;return!t||"function"!=typeof t.hasOptedOutCapturing||!t.hasOptedOutCapturing()}let ot=null;function at(){return I.isSupport()?(ot||(it||(it=new nt({maxBatchSize:20,flushInterval:5e3})),ot=it),ot):null}function ct(t,e,n){if(rt())return $({url:t,method:"POST",data:e.data,headers:e.headers,callback:t=>{if(200!==t.statusCode){if(!P(t.statusCode))return void(n&&et.dequeue(n));if(n&&et.incrementRetryCount(n)){const t=et.getItemById(n);if(t){const e=Math.min(1e3*Math.pow(2,t.retryCount),3e4);setTimeout(()=>{ct(t.url,{data:t.data,headers:t.headers},t.id)},e)}}}else n&&et.dequeue(n),e.callback&&e.callback(t.json)}})}function ut(t){return`${t.apiHost}/in/track`}function lt(t){return`${t.apiHost}/ab/evalall`}function ht(t){return{"Content-Type":"application/json",SourceToken:t.sourceToken}}function dt(t,e,n){O.instance&&O.instance.config.debug&&console.log(JSON.stringify(e.data,null,2));const i=et.enqueue(t,e.data,e.headers);return ct(t,{...e,callback:void 0},i)}function pt(){try{const t=sessionStorage.getItem("sensorswave_utm");if(!t)return{};const e=JSON.parse(t),n={};return Object.entries(e).forEach(([t,e])=>{null!=e&&""!==e&&(n[`$${t}`]=e)}),n}catch(t){return{}}}function gt(t){const e={};return Object.entries(t).forEach(([t,n])=>{if("function"==typeof n)try{const i=n();e[t]=i}catch(i){console.warn("[SensorsWave] Failed to resolve dynamic property:",t,i)}else e[t]=n}),e}function ft(t={},e=!0){const n={...e?tt():{},...gt(N.getCommonProps()),...t},i=pt();return Object.keys(i).length>0&&Object.assign(n,i),n}function mt(t,e,n=!0){if(!st())return;if(!rt())return;const i={time:Date.now(),trace_id:N.getTraceId(),event:t.event,properties:ft(t.properties,n)},s=pt();Object.keys(s).length>0&&(i.user_properties||(i.user_properties={}),i.user_properties.$set||(i.user_properties.$set={}),Object.assign(i.user_properties.$set,s)),t.user_properties&&(t.user_properties.$set&&(i.user_properties=i.user_properties||{},i.user_properties.$set={...i.user_properties.$set||{},...t.user_properties.$set},delete t.user_properties.$set),i.user_properties={...i.user_properties,...t.user_properties});const r=N.getLoginId(),o=N.getAnonId();r&&(i.login_id=r),o&&(i.anon_id=o);const a=ut(e),c=ht(e),u=!1!==e.batchSend&&at();u?(et.enqueue(a,[i],c),u.add()):dt(a,{data:[i],headers:c})}function Et({userProps:t,opts:e}){if(!st())return;if(!rt())return;const n=N.getLoginId(),i=N.getAnonId();if(!n&&!i)return;const s={time:Date.now(),trace_id:N.getTraceId(),event:"$UserSet",login_id:n,anon_id:i,user_properties:t,properties:ft()},r=ut(e),o=ht(e),a=at();if(!a)return dt(r,{data:[s],headers:o});et.enqueue(r,[s],o),a.add()}function _t(t){return t.typ===C.FEATURE_GATE||t.typ===C.FEATURE_CONFIG?`$feature_${t.id}`:t.typ===C.EXPERIMENT?`$exp_${t.id}`:""}function It(t){const e=t.typ;return[C.FEATURE_GATE,C.EXPERIMENT,C.FEATURE_CONFIG].includes(e)?{[_t(t)]:t.vid}:{}}function St(t){const e=t.typ;return e===C.FEATURE_GATE||e===C.FEATURE_CONFIG?{$feature_key:t.key,$feature_variant:t.vid}:e===C.EXPERIMENT?{$exp_key:t.key,$exp_variant:t.vid}:{}}function wt({isUnset:t=!1,data:e,opts:n}){if(!st())return;if(!rt())return;if(!e||u(e)||e.disable_impress)return;const i=N.getLoginId(),s=N.getAnonId();if(!i&&!s)return;const r=e.typ===C.EXPERIMENT?"$ExpImpress":"$FeatureImpress";let o={};return o=t?{$unset:{[_t(e)]:null}}:{$set:{...It(e)}},mt({event:r,properties:St(e),user_properties:o},n)}const Ot="sensorswave_opt_out";class vt{constructor(t){this.persist=t}read(){if(this.persist)try{const t=I.get(Ot);return"0"===t||"1"!==t&&void 0}catch{return}}write(t){if(this.persist)try{I.set(Ot,t?"0":"1")}catch{}}}class bt{constructor({plugins:t,emitter:e,config:n,sdk:i}){this.plugins=[],this.pluginInsMap={},this.emitter=e,this.config=n,this.sdk=i,this.registerBuiltInPlugins(t),this.created(),this.emitter.on(b,()=>{this.init()})}registerBuiltInPlugins(t){for(let e=0,n=t.length;e<n;e++)this.registerPlugin(t[e])}registerPlugin(t){this.plugins.push(t)}getPlugins(){return this.plugins}getPlugin(t){return this.pluginInsMap[t]}created(){for(let t=0,e=this.plugins.length;t<e;t++){const e=this.plugins[t];if(!e.NAME)throw new Error('Plugin should be defined with "NAME"');const n=new e({emitter:this.emitter,config:this.config,sdk:this.sdk});this.pluginInsMap[e.NAME]=n}}init(){for(const t of Object.keys(this.pluginInsMap)){const e=this.pluginInsMap[t];e.init&&e.init()}}destroy(){for(const t of Object.keys(this.pluginInsMap)){const e=this.pluginInsMap[t];e.destroy&&"function"==typeof e.destroy&&e.destroy()}this.pluginInsMap={},this.plugins=[]}}const yt=class{constructor({emitter:t,config:e,sdk:n}){this.boundSend=null,this.hashEvent=null,this.spaSwitchHandler=null,this.emitter=t,this.config=e,this.sdk=n}init(){const t=this.config;this.boundSend=()=>{mt({event:"$PageView",properties:{}},t)},this.sdk&&!0===this.sdk._postConsentInit||setTimeout(()=>{this.boundSend()},0),t.isSinglePageApp&&this.addSinglePageListener()}addSinglePageListener(){this.spaSwitchHandler=t=>{t!==location.href&&this.boundSend()},this.emitter.on(y,this.spaSwitchHandler)}destroy(){this.spaSwitchHandler&&(this.emitter.off(y,this.spaSwitchHandler),this.spaSwitchHandler=null),this.hashEvent&&this.boundSend&&(window.removeEventListener(this.hashEvent,this.boundSend),this.hashEvent=null),this.boundSend=null}};yt.NAME="pageview";let At=yt;const Rt=class{constructor({emitter:t,config:e,sdk:n}){this.startTime=Date.now(),this.pageShowStatus=!0,this.pageHiddenStatus=!1,this.timer=null,this.currentPageUrl=document.referrer,this.url=location.href,this.title=document.title||"",this.heartbeatIntervalTime=5e3,this.heartbeatIntervalTimer=null,this.pageId=null,this.storageName="sensorswavewebjssdkpageleave",this.maxDuration=432e3,this.eventListeners=[],this._skipFirstPageEnd=!1,this.emitter=t,this.config=e,this.sdk=n}__canCapture(){return!this.sdk||"function"!=typeof this.sdk.hasOptedOutCapturing||!this.sdk.hasOptedOutCapturing()}init(){this.pageId=Number(String(g()).slice(2,5)+String(g()).slice(2,4)+String(Date.now()).slice(-4)),this.addEventListener(),this.sdk&&!0===this.sdk._postConsentInit&&(this._skipFirstPageEnd=!0),!0===document.hidden?this.pageShowStatus=!1:this.addHeartBeatInterval()}log(t){console.log(t)}refreshPageEndTimer(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.timer=setTimeout(()=>{this.pageHiddenStatus=!1},5e3)}hiddenStatusHandler(){this.timer&&clearTimeout(this.timer),this.timer=null,this.pageHiddenStatus=!1}pageStartHandler(){this.startTime=Date.now(),1==!document.hidden?this.pageShowStatus=!0:this.pageShowStatus=!1,this.url=location.href,this.title=document.title,this._skipFirstPageEnd=!1}pageEndHandler(){if(!0===this.pageHiddenStatus)return;if(!this.__canCapture())return;const t=this.getPageLeaveProperties();!1===this.pageShowStatus&&delete t.$event_duration,this.pageShowStatus=!1,this.pageHiddenStatus=!0,mt({event:R,properties:t},this.config),this.refreshPageEndTimer(),this.delHeartBeatData()}addEventListener(){this.addPageStartListener(),this.addPageSwitchListener(),this.addSinglePageListener(),this.addPageEndListener()}addPageStartListener(){if("onpageshow"in window){const t=()=>{this.pageStartHandler(),this.hiddenStatusHandler()};window.addEventListener("pageshow",t),this.eventListeners.push({target:window,event:"pageshow",handler:t})}}addSinglePageListener(){this.config.isSinglePageApp&&this.emitter.on(y,t=>{t!==location.href&&(this.url=t,this.pageEndHandler(),this.stopHeartBeatInterval(),this.currentPageUrl=this.url,this.pageStartHandler(),this.hiddenStatusHandler(),this.addHeartBeatInterval())})}addPageEndListener(){["pagehide","beforeunload"].forEach(t=>{if(`on${t}`in window){const e=()=>{if(this._skipFirstPageEnd)return this._skipFirstPageEnd=!1,void this.stopHeartBeatInterval();this.pageEndHandler(),this.stopHeartBeatInterval()};window.addEventListener(t,e),this.eventListeners.push({target:window,event:t,handler:e})}})}addPageSwitchListener(){const t=()=>{"visible"===document.visibilityState?(this.pageStartHandler(),this.hiddenStatusHandler(),this.addHeartBeatInterval()):(this.url=location.href,this.title=document.title,this.stopHeartBeatInterval())};document.addEventListener("visibilitychange",t),this.eventListeners.push({target:document,event:"visibilitychange",handler:t})}addHeartBeatInterval(){I.isSupport()&&this.startHeartBeatInterval()}startHeartBeatInterval(){this.heartbeatIntervalTimer&&this.stopHeartBeatInterval(),this.sdk&&!0===this.sdk._postConsentInit&&!0===this._skipFirstPageEnd||(this.heartbeatIntervalTimer=setInterval(()=>{this.saveHeartBeatData()},this.heartbeatIntervalTime),this.saveHeartBeatData("is_first_heartbeat"),this.reissueHeartBeatData())}stopHeartBeatInterval(){this.heartbeatIntervalTimer&&clearInterval(this.heartbeatIntervalTimer),this.heartbeatIntervalTimer=null}saveHeartBeatData(t){if(!this.__canCapture())return;const e=this.getPageLeaveProperties();e.$time=Date.now(),"is_first_heartbeat"===t&&(e.$event_duration=3);const n={type:"track",event:R,properties:e,time:e.$time};n.heartbeat_interval_time=this.heartbeatIntervalTime,I.isSupport()&&I.set(`${this.storageName}-${this.pageId}`,JSON.stringify(n))}delHeartBeatData(t){I.isSupport()&&I.remove(t||`${this.storageName}-${this.pageId}`)}reissueHeartBeatData(){if(this.__canCapture())for(let t=window.localStorage.length-1;t>=0;t--){const e=window.localStorage.key(t);if(e&&e!==`${this.storageName}-${this.pageId}`&&0===e.indexOf(`${this.storageName}-`)){const t=I.parse(e);i(t)&&Date.now()-t.time>t.heartbeat_interval_time+5e3&&(delete t.heartbeat_interval_time,t._flush_time=(new Date).getTime(),mt({event:R,properties:t?.properties},this.config),this.delHeartBeatData(e))}}}getPageLeaveProperties(){let t=(Date.now()-this.startTime)/1e3;(isNaN(t)||t<0||t>this.maxDuration)&&(t=0),t=Number(t.toFixed(3));const e={$title:this.title,$url:this.url?.substring(0,1e3),$pathname:w(this.url)};return 0!==t&&(e.$event_duration=t),e}destroy(){this.eventListeners.forEach(({target:t,event:e,handler:n})=>{t.removeEventListener(e,n)}),this.eventListeners=[],this.timer&&(clearTimeout(this.timer),this.timer=null),this.heartbeatIntervalTimer&&(clearInterval(this.heartbeatIntervalTimer),this.heartbeatIntervalTimer=null)}};Rt.NAME="pageleave";let Tt=Rt;const Ct=class{constructor({emitter:t,config:e,sdk:n}){this.eventSended=!1,this.emitter=t,this.config=e,this.sdk=n}init(){if(this.sdk&&!0===this.sdk._postConsentInit)return;const t=()=>{let e=0;const n={};if(window.performance){e=function(){let t=0;if("function"==typeof performance.getEntriesByType){const e=performance.getEntriesByType("navigation");e.length>0&&(t=e[0].domContentLoadedEventEnd||0)}return t}();const t=function(){if(performance.getEntries&&"function"==typeof performance.getEntries){const t=performance.getEntries();let e=0;for(const n of t)"transferSize"in n&&(e+=n.transferSize);if("number"==typeof e&&e>=0&&e<10737418240)return Number((e/1024).toFixed(3))}}();t&&(n.$page_resource_size=t)}else console.warn("Performance API is not supported.");e>0&&!Number.isFinite(e)&&(n.$event_duration=Number((e/1e3).toFixed(3))),this.eventSended||(this.eventSended=!0,mt({event:"$PageLoad",properties:n},this.config)),window.removeEventListener("load",t)};"complete"===document.readyState?t():window.addEventListener&&window.addEventListener("load",t)}};Ct.NAME="pageload";let Nt=Ct;function Pt(t,e){if(!l(t))return!1;const n=o(t.tagName)?t.tagName.toLowerCase():"",i={};i.$element_type=n,i.$element_name=t.getAttribute("name")||"",i.$element_id=t.getAttribute("id")||"",i.$element_class_name=o(t.className)?t.className:"",i.$element_target_url=t.getAttribute("href")||"",i.$element_content=function(t,e){return o(e)&&"input"===e.toLowerCase()?("button"===(n=t).type||"submit"===n.type)&&n.value||"":function(t,e){let n="",i="";return t.textContent?n=S(t.textContent):t.innerText&&(n=S(t.innerText)),n&&(n=n.replace(/[\r\n]/g," ").replace(/[ ]+/g," ").substring(0,255)),i=n||"","input"!==e&&"INPUT"!==e||(i=t.value||""),i}(t,e);var n}(t,n)||"",i.$element_selector=kt(t)||"",i.$element_path=function(t){let e=[];for(;t.parentNode&&l(t);){if(!o(t.tagName))return"";if(t.id&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(t.id)){e.unshift(t.tagName.toLowerCase()+"#"+t.id);break}if(t===document.body){e.unshift("body");break}e.unshift(t.tagName.toLowerCase()),t=t.parentNode}return e.join(" > ")}(t)||"";const s=function(t,e){const n=e.pageX||e.clientX+Lt().scrollLeft||e.offsetX+$t(t).targetEleX,i=e.pageY||e.clientY+Lt().scrollTop||e.offsetY+$t(t).targetEleY;return{$page_x:Ft(n),$page_y:Ft(i)}}(t,e);return i.$page_x=s.$page_x,i.$page_y=s.$page_y,i}function kt(t,e=[]){if(!(t&&t.parentNode&&t.parentNode.children&&o(t.tagName)))return"";e=Array.isArray(e)?e:[];const n=t.nodeName.toLowerCase();return t&&"body"!==n&&1==t.nodeType?(e.unshift(function(t){if(!t||!l(t)||!o(t.tagName))return"";let e=t.parentNode&&9==t.parentNode.nodeType?-1:function(t){if(!t.parentNode)return-1;let e=0;const n=t.tagName,i=t.parentNode.children;for(let s=0,r=i.length;s<r;s++)if(i[s].tagName===n){if(t===i[s])return e;e++}return-1}(t);return t.getAttribute&&t.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(t.getAttribute("id"))?"#"+t.getAttribute("id"):t.tagName.toLowerCase()+(~e?":nth-of-type("+(e+1)+")":"")}(t)),t.getAttribute&&t.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(t.getAttribute("id"))?e.join(" > "):kt(t.parentNode,e)):(e.unshift("body"),e.join(" > "))}function Lt(){return{scrollLeft:document.body.scrollLeft||document.documentElement.scrollLeft||0,scrollTop:document.body.scrollTop||document.documentElement.scrollTop||0}}function $t(t){if(document.documentElement.getBoundingClientRect){const e=t.getBoundingClientRect();return{targetEleX:e.left+Lt().scrollLeft||0,targetEleY:e.top+Lt().scrollTop||0}}return{targetEleX:0,targetEleY:0}}function Ft(t){return Number(Number(t).toFixed(3))}const xt=class{constructor({emitter:t,config:e}){this.isInitialized=!1,this.boundHandleClick=null,this.emitter=t,this.config=e}init(){this.isInitialized||(this.boundHandleClick=this.handleClick.bind(this),document.addEventListener("click",this.boundHandleClick,!0),this.isInitialized=!0)}handleClick(t){const e=t.target;if(!e)return;if(!["A","INPUT","BUTTON","TEXTAREA"].includes(e.tagName))return;if("true"===e.getAttribute("sensorswave-disable"))return;mt({event:"$WebClick",properties:Pt(e,t)||{}},this.config)}destroy(){this.boundHandleClick&&(document.removeEventListener("click",this.boundHandleClick,!0),this.boundHandleClick=null),this.isInitialized=!1}};xt.NAME="webclick";let Bt=xt;const Mt=class{constructor({emitter:t,config:e,sdk:n}){this.updateInterval=null,this.fetchingPromise=null,this.emitter=t,this.config=e,this.sdk=n}init(){const t=this.config;if(t.enableAB){if(this.sdk&&"function"==typeof this.sdk.hasOptedOutCapturing&&this.sdk.hasOptedOutCapturing())return;this.fastFetch().then(()=>{this.emitter.emit(A)}),t.abRefreshInterval<3e4&&(t.abRefreshInterval=3e4),this.updateInterval=setInterval(()=>{this.fetchNewData().catch(console.warn)},t.abRefreshInterval)}}async fastFetch(){const t=N.getABData(this.config.abRefreshInterval);return t&&t.length?(this.emitter.emit(A),Promise.resolve(t)):this.fetchNewData()}async fetchNewData(){return this.fetchingPromise||(this.fetchingPromise=new Promise(t=>{!function({opts:t,cb:e}){if(!st())return void(e&&e({}));if(!rt())return void(e&&e({}));const n=N.getLoginId(),i=N.getAnonId();if(!n&&!i)return void(e&&e({}));const s={user:{login_id:n||"",anon_id:i||"",props:{...tt(),...gt(N.getCommonProps())}},sdk:"webjs",sdk_version:v};$({url:lt(t),method:"POST",data:s,headers:ht(t),callback:t=>{200!==t.statusCode?(console.error("Failed to fetch feature flags"),e&&e({})):e&&e(t.json)}})}({opts:this.config,cb:e=>{N.saveABData(e?.data?.results||[]),t(e),this.fetchingPromise=null}})})),this.fetchingPromise}async getFeatureGate(t){return await this.fastFetch().catch(console.warn),N.getABData(this.config.abRefreshInterval).find(e=>e.typ===C.FEATURE_GATE&&e.key==t)}async checkFeatureGate(t){const e=await this.getFeatureGate(t);return!!e&&(!e.hasOwnProperty("vid")&&e.key?(wt({isUnset:!0,data:e,opts:this.config}),!1):(wt({data:e,opts:this.config}),"fail"!==e.vid))}async getExperiment(t){await this.fastFetch().catch(console.warn);const e=N.getABData(this.config.abRefreshInterval).find(e=>e.typ===C.EXPERIMENT&&e.key===t);return e?!e.hasOwnProperty("vid")&&e.key?(wt({isUnset:!0,data:e,opts:this.config}),{}):(wt({data:e,opts:this.config}),e?.value||{}):{}}async getFeatureConfig(t){await this.fastFetch().catch(console.warn);const e=N.getABData(this.config.abRefreshInterval).find(e=>e.typ===C.FEATURE_CONFIG&&e.key===t);if(!e)return{};if(!e.hasOwnProperty("vid")&&e.key)return wt({isUnset:!0,data:e,opts:this.config}),{};wt({data:e,opts:this.config});const n=e?.value;if(n){if(i(n))return n;try{return JSON.parse(n)}catch{return n}}return{}}destroy(){this.updateInterval&&(clearInterval(this.updateInterval),this.updateInterval=null),this.fetchingPromise=null}};Mt.NAME="abtest";let Dt=Mt;const Ht=["utm_source","utm_medium","utm_campaign","utm_content","utm_term"],Ut="sensorswave_utm",Xt=class t{constructor({sdk:t,emitter:e,config:n}){this.sdk=t,this.emitter=e,this.config=n}init(){if(this.sdk&&!0===this.sdk._postConsentInit){let e=t.readFromSessionStorage();return e&&0!==Object.keys(e).length||(e=t.captureAndStore(this.config?.debug)),void this.scheduleInitialUTM(e)}const e=t.getUTMFromURL();t.saveToSessionStorage(e,this.config?.debug),this.scheduleInitialUTM(e)}scheduleInitialUTM(t){setTimeout(()=>{this.sendInitialUTM(t)},0)}static getUTMFromURL(){try{const t=new URLSearchParams(window.location.search),e={};return Ht.forEach(n=>{const i=t.get(n);i&&(e[n]=i)}),e}catch(e){return t.getUTMFromURLFallback()}}static getUTMFromURLFallback(){const t={};return window.location.search.substring(1).split("&").forEach(e=>{const[n,i]=e.split("="),s=decodeURIComponent(n),r=i?decodeURIComponent(i):"";Ht.includes(s)&&(t[s]=r)}),t}static readFromSessionStorage(){try{const t=sessionStorage.getItem(Ut);if(!t)return{};const e=JSON.parse(t);return e&&"object"==typeof e?e:{}}catch(t){return{}}}static saveToSessionStorage(t,e=!1){try{sessionStorage.setItem(Ut,JSON.stringify(t))}catch(n){e&&console.warn("[SensorsWave UTM] Failed to save to sessionStorage:",n)}}static captureAndStore(e=!1){const n=t.getUTMFromURL();return t.saveToSessionStorage(n,e),n}sendInitialUTM(t){const e={};Ht.forEach(n=>{e[`$initial_${n}`]=null!=t[n]?t[n]:""});try{this.sdk.profileSetOnce(e)}catch(n){this.config.debug&&console.warn("[SensorsWave UTM] Failed to send initial UTM:",n)}}destroy(){}};Xt.NAME="UTM";let jt=Xt;const qt=1e3,Wt=/^\s*(?:async\s+)?at\s+(?:(.+)\s+\()?(.+?):(\d+):(\d+)\)?$/,Gt=/^(?:(.*)@)?(.+?):(\d+):(\d+)$/;function zt(t){let e=t;try{const t=location.origin;t&&0===e.indexOf(t)&&(e=e.substring(t.length))}catch(s){}const n=e.indexOf("?");n>-1&&(e=e.substring(0,n));const i=e.indexOf("#");return i>-1&&(e=e.substring(0,i)),e}function Yt(t){return t.map(t=>({platform:"web:javascript",filename:zt(t.file),function:t.fn||"?",lineno:Number(t.line),colno:Number(t.col),abs_path:Kt(t.file,1e3)}))}function Kt(t,e){return t.length>e?t.substring(0,e):t}function Jt(t){let e;if("string"==typeof t)e=t;else if(null!==t&&"object"==typeof t){try{e=JSON.stringify(t)}catch(n){e=Object.prototype.toString.call(t)}e||(e=Object.prototype.toString.call(t))}else e=String(t);return Kt(e,qt)}function Zt(t){const{frames:e,headerType:n}=function(t){const e=[];let n="";if(!t||"string"!=typeof t)return{frames:e,headerType:n};const i=t.split(/\r?\n/);for(let s=0;s<i.length;s++){const t=i[s];if(!t||t.length>1024)continue;const r=t.match(Wt),o=r?null:t.match(Gt),a=r||o;if(a)e.push({fn:a[1]||"?",file:a[2],line:a[3],col:a[4]});else if(0===s){const e=t.indexOf(":");e>0&&(n=t.substring(0,e).trim())}if(e.length>=30)break}return{frames:e,headerType:n}}(t&&t.stack);let i=t&&t.name||n||"Error";return i=Kt(String(i),200),{$exception_level:"error",$exception_type:i,$exception_message:Kt(String(t&&t.message||""),qt),$exception_frames:Yt(e)}}function Qt(t,e,n,i){let s=[];return e&&(s=[{platform:"web:javascript",filename:zt(e),function:"?",lineno:n||0,colno:i||0,abs_path:Kt(e,1e3)}]),{$exception_level:"error",$exception_type:"Error",$exception_message:Kt(String(t||""),qt),$exception_frames:s}}class Vt{constructor(t=10,e=1,n=1e4){this.buckets=new Map,this.bucketSize=t,this.refillRate=e,this.refillInterval=n}allow(t){const e=Date.now();let n=this.buckets.get(t);if(n){if(e>n.lastRefill){const t=Math.floor((e-n.lastRefill)/this.refillInterval)*this.refillRate;t>0&&(n.tokens=Math.min(this.bucketSize,n.tokens+t),n.lastRefill+=t/this.refillRate*this.refillInterval)}}else n={tokens:this.bucketSize,lastRefill:e},this.buckets.set(t,n);return n.tokens>=1&&(n.tokens-=1,!0)}reset(){this.buckets.clear()}}const te=class{constructor({emitter:t,config:e}){this.isInitialized=!1,this.boundHandleError=null,this.boundHandleRejection=null,this.rateLimiter=new Vt,this.emitter=t,this.config=e}init(){this.isInitialized||(this.boundHandleError=this.handleError.bind(this),this.boundHandleRejection=this.handleRejection.bind(this),window.addEventListener("error",this.boundHandleError,!0),window.addEventListener("unhandledrejection",this.boundHandleRejection),this.isInitialized=!0)}handleError(t){try{const e=t.target;let n;if(e&&e!==window&&e.tagName)n=function(t){const e=t,n=(e.tagName||"").toLowerCase(),i=Kt(String(e.src||e.href||""),qt);return{$exception_level:"error",$exception_type:"ResourceLoadError",$exception_message:`Failed to load <${n}>${i?` from ${i}`:""}`,$exception_frames:[]}}(e);else{const e=t;n=e.error instanceof Error?Zt(e.error):Qt(String(e.message||""),e.filename,e.lineno,e.colno)}this.send(n)}catch(e){}}handleRejection(t){try{const e=t.reason;this.send(function(t){return t instanceof Error?Zt(t):{$exception_level:"error",$exception_type:"UnhandledRejection",$exception_message:Jt(t),$exception_frames:[]}}(e))}catch(e){}}send(t){t.$exception_message&&this.rateLimiter.allow(t.$exception_type)&&mt({event:T,properties:t},this.config)}destroy(){this.boundHandleError&&(window.removeEventListener("error",this.boundHandleError,!0),this.boundHandleError=null),this.boundHandleRejection&&(window.removeEventListener("unhandledrejection",this.boundHandleRejection),this.boundHandleRejection=null),this.rateLimiter.reset(),this.isInitialized=!1}};te.NAME="exception";let ee=te;const ne=[],ie={debug:!1,sourceToken:"",apiHost:"",autoCapture:!0,isSinglePageApp:!1,crossSubdomainCookie:!0,enableAB:!1,abRefreshInterval:6e5,enableClickTrack:!1,batchSend:!1,enableErrorTrack:!1,enableCrashTrack:!1,optOutCapturing:!1,persistOptOut:!1};return new class{constructor(){this.__innerInited=!1,this.inited=!1,this.config={},this.eventEmitter=new t,this.pluginCore={},this.commonProps={},this.spaCleanup=null,this._optOutCapturing=!1,this.consentStorage=new vt(!1),this._setupAfterConsentDone=!1,this._postConsentInit=!1,O.instance=this}init(t,e={}){return this.inited?this:(O.instance=this,e.sourceToken=t,this.mergeConfig(e),this.consentStorage=new vt(!0===this.config.persistOptOut),this._optOutCapturing?this.consentStorage.write(!0):!0===this.config.optOutCapturing?(this._optOutCapturing=!0,this.consentStorage.write(!0)):!0===this.consentStorage.read()&&(this._optOutCapturing=!0),this.eventEmitter.emit("init-param",this.config),this.__innerInited=!0,this._optOutCapturing?(jt.captureAndStore(this.config.debug),this.eventEmitter.emit(b),this.inited=!0,this):(this.__setupAfterConsent(),this.eventEmitter.emit(b),this.inited=!0,this))}__setupAfterConsent(){if(this._setupAfterConsentDone)return;this._setupAfterConsentDone=!0;const t=this.config;ne.length=0,N.init(t.crossSubdomainCookie),t.anonId&&N.setAnonId(t.anonId),function(){if(window._swFailedRequestsInitialized)return;window._swFailedRequestsInitialized=!0;const t=O.instance;t&&"function"==typeof t.hasOptedOutCapturing&&t.hasOptedOutCapturing()||t&&!0===t._postConsentInit||function(){const t=et.getAll();if(0!==t.length)for(let e=0,n=t.length;e<n;e+=10){const n=t.slice(e,e+10),i=[],s=[];n.forEach(t=>{Array.isArray(t.data)?i.push(...t.data):i.push(t.data),s.push(t.id)});const r=n[n.length-1],o=r.url,a=r.headers;$({url:o,method:"POST",data:i,headers:a,callback:t=>{200!==t.statusCode?(console.error("Failed to send batch stored requests:",t),P(t.statusCode)||s.forEach(t=>{et.dequeue(t)})):s.forEach(t=>{et.dequeue(t)})}})}}()}(),ne.push(jt),t.autoCapture&&this.autoTrack(),t.enableAB&&ne.push(Dt),t.enableClickTrack&&ne.push(Bt),t.enableCrashTrack&&t.debug&&console.warn("[SensorsWave] enableCrashTrack 仅在 app 宿主环境生效,当前 Web 环境不采集 crash"),t.enableErrorTrack&&ne.push(ee),this.pluginCore=new bt({plugins:ne,emitter:this.eventEmitter,config:t,sdk:this}),this.spaCleanup=function(t){let e=location.href;const n=window.history.pushState,i=window.history.replaceState,r=function(){t(e),e=location.href};return s(window.history.pushState)&&(window.history.pushState=function(...i){n.apply(window.history,i),t(e),e=location.href}),s(window.history.replaceState)&&(window.history.replaceState=function(...n){i.apply(window.history,n),t(e),e=location.href}),window.addEventListener("popstate",r),function(){s(window.history.pushState)&&(window.history.pushState=n),s(window.history.replaceState)&&(window.history.replaceState=i),window.removeEventListener("popstate",r)}}(t=>{this.eventEmitter.emit(y,t)})}mergeConfig(t){this.config={...ie,...t}}__canCapture(){return this.inited&&!this._optOutCapturing}track(t){this.__canCapture()&&function(t,e){if(!st())return;if(!rt())return;const n={...t};n.time||(n.time=Date.now()),n.login_id||(n.login_id=N.getLoginId()),n.anon_id||(n.anon_id=N.getAnonId()),n.trace_id||(n.trace_id=N.getTraceId()),n.properties={...tt(),...gt(N.getCommonProps()),...n.properties};const i=ut(e),s=ht(e),r=!1!==e.batchSend&&at();if(!r)return dt(i,{data:[n],headers:s});et.enqueue(i,[n],s),r.add()}(t,this.config)}trackEvent(t,e){this.__canCapture()&&mt({event:t,properties:e},this.config)}trackException(t,e){if(!this.__canCapture())return;const n={...e||{},...t instanceof Error?Zt(t):Qt(String(t))};mt({event:T,properties:n},this.config)}autoTrack(){ne.push(At,Nt,Tt)}profileSet(t){this.__canCapture()&&Et({userProps:{$set:t},opts:this.config})}profileSetOnce(t){this.__canCapture()&&Et({userProps:{$set_once:t},opts:this.config})}profileIncrement(t){this.__canCapture()&&Et({userProps:{$increment:t},opts:this.config})}profileAppend(t){this.__canCapture()&&Et({userProps:{$append:t},opts:this.config})}profileUnion(t){this.__canCapture()&&Et({userProps:{$union:t},opts:this.config})}profileUnset(t){if(!this.__canCapture())return;const e={};r(t)?t.forEach(function(t){e[t]=null}):e[t]=null,Et({userProps:{$unset:e},opts:this.config})}profileDelete(){this.__canCapture()&&Et({userProps:{$delete:!0},opts:this.config})}registerCommonProperties(t){if(!i(t))return console.warn("Commmon Properties must be an object!");this.commonProps=t,N.setCommonProps(this.commonProps)}clearCommonProperties(t){if(!r(t))return console.warn("Commmon Properties to be cleared must be an array!");t.forEach(t=>{delete this.commonProps[t]}),N.setCommonProps(this.commonProps)}identify(t){this.__canCapture()&&(N.setLoginId(t),function(t){if(!st())return;if(!rt())return;const e=N.getLoginId(),n=N.getAnonId();if(!e||!n)return;const i={time:Date.now(),trace_id:N.getTraceId(),event:"$Identify",login_id:e,anon_id:n,properties:ft()},s=ut(t),r=ht(t),o=at();if(!o)return dt(s,{data:[i],headers:r});et.enqueue(s,[i],r),o.add()}(this.config))}setLoginId(t){this.__canCapture()&&N.setLoginId(t)}getAnonId(){return this.__canCapture()?N.getAnonId():""}setAnonId(t){this.__canCapture()&&N.setAnonId(t)}getLoginId(){return this.__canCapture()?N.getLoginId():""}reset(t=!1){this.__canCapture()&&(N.clearLoginId(),t&&N.resetAnonId())}checkFeatureGate(t){if(!this.__canCapture())return Promise.resolve(!1);const e=this.pluginCore.getPlugin(Dt.NAME);return this.config.enableAB&&e?e.checkFeatureGate(t):Promise.reject("AB is disabled")}getExperiment(t){if(!this.__canCapture())return Promise.resolve({});const e=this.pluginCore.getPlugin(Dt.NAME);return this.config.enableAB&&e?e.getExperiment(t):Promise.reject("AB is disabled")}getFeatureConfig(t){if(!this.__canCapture())return Promise.resolve({});const e=this.pluginCore.getPlugin(Dt.NAME);return this.config.enableAB&&e?e.getFeatureConfig(t):Promise.reject("AB is disabled")}optOutCapturing(){this._optOutCapturing=!0,this.consentStorage.write(!0),ot&&ot.pause()}optInCapturing(){if(this._optOutCapturing=!1,this.consentStorage.write(!1),ot&&ot.resume(),this.inited&&!this._setupAfterConsentDone){this._postConsentInit=!0;try{this.__setupAfterConsent(),this.eventEmitter.emit(b)}finally{this._postConsentInit=!1}}}hasOptedOutCapturing(){return this._optOutCapturing}destroy(){ot&&(ot.destroy(),ot=null),"undefined"!=typeof window&&(window._swFailedRequestsInitialized=!1),this.inited=!1,this.__innerInited=!1,this.spaCleanup&&"function"==typeof this.spaCleanup&&(this.spaCleanup(),this.spaCleanup=null),this.pluginCore&&"function"==typeof this.pluginCore.destroy&&this.pluginCore.destroy(),this.pluginCore={},this.eventEmitter&&this.eventEmitter.removeAllListeners(),this.consentStorage=new vt(!0===this.config?.persistOptOut),this._optOutCapturing=!1,this._setupAfterConsentDone=!1,this._postConsentInit=!1,O.instance===this&&(O.instance=null)}}});
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).SensorsWave=t()}(this,function(){"use strict";class e{constructor(){this.listeners={}}on(e,t,i=!1){if(e&&t){if(!s(t))throw new Error("listener must be a function");this.listeners[e]=this.listeners[e]||[],this.listeners[e].push({listener:t,once:i})}}off(e,t){const i=this.listeners[e];if(!i?.length)return;"number"==typeof t&&i.splice(t,1);const n=i.findIndex(e=>e.listener===t);-1!==n&&i.splice(n,1)}emit(e,...t){this.listeners[e]&&this.listeners[e].forEach((i,n)=>{i.listener.call(this,...t),i.listener.once&&this.off(e,n)})}once(e,t){this.on(e,t,!0)}removeAllListeners(e){e?this.listeners[e]=[]:this.listeners={}}}const t={get:function(e){const t=e+"=",i=document.cookie.split(";");for(let n=0,s=i.length;n<s;n++){let e=i[n];for(;" "==e.charAt(0);)e=e.substring(1,e.length);if(0==e.indexOf(t))return h(e.substring(t.length,e.length))}return null},set:function({name:e,value:t,expires:i,samesite:n,secure:s,domain:r}){let o="",a="",c="",u="";if(0!==(i=null==i||void 0===i?365:i)){const e=new Date;"s"===String(i).slice(-1)?e.setTime(e.getTime()+1e3*Number(String(i).slice(0,-1))):e.setTime(e.getTime()+24*i*60*60*1e3),o="; expires="+e.toUTCString()}function l(e){return e?e.replace(/\r\n/g,""):""}n&&(c="; SameSite="+n),s&&(a="; secure");const h=l(e),d=l(t),p=l(r);p&&(u="; domain="+p),h&&d&&(document.cookie=h+"="+encodeURIComponent(d)+o+"; path=/"+u+c+a)},remove:function(e){this.set({name:e,value:"",expires:-1})},isSupport:function({samesite:e,secure:t}={}){if(!navigator.cookieEnabled)return!1;const i="sensorswave_cookie_support_test";return this.set({name:i,value:"1",samesite:e,secure:t}),"1"===this.get(i)&&(this.remove(i),!0)}},i=Object.prototype.toString;function n(e){return"[object Object]"===i.call(e)}function s(e){const t=i.call(e);return"[object Function]"==t||"[object AsyncFunction]"==t}function r(e){return"[object Array]"==i.call(e)}function o(e){return"[object String]"==i.call(e)}function a(e){return void 0===e}const c=Object.prototype.hasOwnProperty;function u(e){if(n(e)){for(let t in e)if(c.call(e,t))return!1;return!0}return!1}function l(e){return!(!e||1!==e.nodeType)}function h(e){let t=e;try{t=decodeURIComponent(e)}catch(i){t=e}return t}function d(e){try{return JSON.parse(e)}catch(t){return""}}const p=function(){let e=Date.now();return function(t){return Math.ceil((e=(9301*e+49297)%233280,e/233280*t))}}();function g(){if("function"==typeof Uint32Array){let e;if("undefined"!=typeof crypto&&(e=crypto),e&&n(e)&&e.getRandomValues)return e.getRandomValues(new Uint32Array(1))[0]/Math.pow(2,32)}return p(1e19)/1e19}const f=function(){function e(e){return("0".repeat(e)+Date.now().toString(16)).slice(-e)}return function(){let t=String(screen.height*screen.width);t=t&&/\d{4,}/.test(t)?t.slice(-4):String(31242*g()).replace(".","").slice(0,4);return e(8)+"-"+g().toString(16).replace(".","").slice(-4)+"-"+function(){const e=navigator.userAgent;let t,i=[],n=0;function s(e,t){let n=0;for(let s=0;s<t.length;s++)n|=i[s]<<8*s;return(e^n)>>>0}for(let r=0;r<e.length;r++)t=e.charCodeAt(r),i.unshift(255&t),i.length>=4&&(n=s(n,i),i=[]);return i.length>0&&(n=s(n,i)),("0000"+n.toString(16)).slice(-4)}()+"-"+t+"-"+e(12)||(String(g())+String(g())+String(g())).slice(2,15)}}();function m(e,t){t&&"string"==typeof t||(t="");let i=null;try{i=new URL(e).hostname}catch(n){}return i||t}function E(e){let t=[];try{t=atob(e).split("").map(function(e){return"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)})}catch(i){t=[]}try{return decodeURIComponent(t.join(""))}catch(i){return t.join("")}}function b(e){let t="";try{t=btoa(encodeURIComponent(e).replace(/%([0-9A-F]{2})/g,function(e,t){return String.fromCharCode(parseInt(t,16))}))}catch(i){t=e}return t}const v={get:function(e){return window.localStorage.getItem(e)},parse:function(e){let t;try{t=JSON.parse(v.get(e))||null}catch(i){console.warn(i)}return t},set:function(e,t){try{window.localStorage.setItem(e,t)}catch(i){console.warn(i)}},remove:function(e){window.localStorage.removeItem(e)},isSupport:function(){let e=!0;try{const t="__local_store_support__",i="testIsSupportStorage";v.set(t,i),v.get(t)!==i&&(e=!1),v.remove(t)}catch(t){e=!1}return e}};function _(e){return e.trim()}function I(e){if(!e||"string"!=typeof e)return"";try{return new URL(e,window.location.origin).pathname}catch(t){return""}}const S={},w="1.5.1",y="init-ready",O="spa-switch",A="ff-ready",R="$PageLeave",T="$Exception";var C=(e=>(e[e.FEATURE_GATE=1]="FEATURE_GATE",e[e.FEATURE_CONFIG=2]="FEATURE_CONFIG",e[e.EXPERIMENT=3]="EXPERIMENT",e))(C||{});const N={crossSubdomain:!1,requests:[],_sessionState:{},_abData:[],_trace_id:"",commonProps:{},_state:{anon_id:"",login_id:"",identities:{}},getIdentityCookieID(){return this._state.identities?.$identity_cookie_id||""},getCommonProps:function(){return this.commonProps||{}},setCommonProps:function(e){this.commonProps=e},getAnonId(){return this._state.anon_id||this.getIdentityCookieID()||f()},getLoginId(){return this._state.login_id},getTraceId(){return this._trace_id||f()},set:function(e,t){this._state[e]=t,this.save()},getCookieName:function(){return"sensorswave2025jssdkcross"},getABLSName:function(){return"sensorswave2025jssdkablatest"},save:function(){let e=JSON.parse(JSON.stringify(this._state));e.identities&&(e.identities=b(JSON.stringify(e.identities)));const i=JSON.stringify(e);t.set({name:this.getCookieName(),value:i,expires:365})},init:function(e){let i,s;this.crossSubdomain=e,t.isSupport()&&(i=t.get(this.getCookieName()),s=d(i)),N._state={...s||{}},N._state.identities&&(N._state.identities=d(E(N._state.identities))),N._state.identities&&n(N._state.identities)&&!u(N._state.identities)||(N._state.identities={$identity_cookie_id:f()}),N.save()},setLoginId(e){"number"==typeof e&&(e=String(e)),void 0!==e&&e&&(N.set("login_id",e),N.save())},clearLoginId(){this._state.login_id="",this.save()},resetAnonId(){this._state.anon_id="",this._state.identities={$identity_cookie_id:f()},this.save()},setAnonId(e){"number"==typeof e&&(e=String(e)),"string"==typeof e&&e?(N.set("anon_id",e),N.save()):console.warn("[SensorsWave store] Invalid anonId, ignored:",e)},saveABData(e){if(!e||u(e))return;this._abData=e;let t=JSON.parse(JSON.stringify(this._abData));t=b(JSON.stringify(t));try{localStorage.setItem(this.getABLSName(),JSON.stringify({time:Date.now(),data:t,anon_id:this.getAnonId(),login_id:this.getLoginId()}))}catch(i){console.warn("Failed to save abdata to localStorage",i)}},getABData(e=6e5){try{let t=localStorage.getItem(this.getABLSName());if(t){const{time:i,data:n,login_id:s,anon_id:r}=d(t)||{};if(i&&n&&Date.now()-i<e&&r===this.getAnonId()&&(!s||s===this.getLoginId())){const e=d(E(n));return this._abData=Array.isArray(e)?e:[],this._abData}localStorage.removeItem(this.getABLSName())}}catch(t){this._abData=[]}return this._abData||[]}};function P(e){return!(e>=400&&e<500)||408===e||429===e}function k(e){var t;if(e.data)return{contentType:"application/json",body:(t=e.data,JSON.stringify(t,(e,t)=>"bigint"==typeof t?t.toString():t,undefined))}}const x=[];function L(e){const t={...e};t.timeout=t.timeout||6e4;const i=t.transport??"fetch",n=x.find(e=>e.transport===i)?.method??x[0]?.method;if(!n)throw new Error("No available transport method for HTTP request");n(t)}function M(e){return o(e=e||document.referrer)&&(e=h(e=e.trim()))||""}function $(e){const t=m(e=e||M());if(!t)return"";const i={baidu:[/^.*\.baidu\.com$/],bing:[/^.*\.bing\.com$/],google:[/^www\.google\.com$/,/^www\.google\.com\.[a-z]{2}$/,/^www\.google\.[a-z]{2}$/],sm:[/^m\.sm\.cn$/],so:[/^.+\.so\.com$/],sogou:[/^.*\.sogou\.com$/],yahoo:[/^.*\.yahoo\.com$/],duckduckgo:[/^.*\.duckduckgo\.com$/]};for(let n of Object.keys(i)){let e=i[n];for(let i=0,s=e.length;i<s;i++)if(e[i].test(t))return n}return""}function D(e,t){return-1!==e.indexOf(t)}"function"==typeof fetch&&x.push({transport:"fetch",method:function(e){if("undefined"==typeof fetch)return void console.error("fetch API is not available");const t=k(e),i=new Headers;e.headers&&Object.keys(e.headers).forEach(t=>{i.append(t,e.headers[t])}),t?.contentType&&i.append("Content-Type",t.contentType),fetch(e.url,{method:e.method||"GET",headers:i,body:t?.body}).then(t=>t.text().then(i=>{const n={statusCode:t.status,text:i};if(200===t.status)try{n.json=JSON.parse(i)}catch(s){console.error("Failed to parse response:",s)}e.callback?.(n)})).catch(t=>{console.error("Request failed:",t),e.callback?.({statusCode:0,text:String(t)})})}}),"undefined"!=typeof XMLHttpRequest&&x.push({transport:"XHR",method:function(e){if("undefined"==typeof XMLHttpRequest)return void console.error("XMLHttpRequest is not available");const t=new XMLHttpRequest;t.open(e.method||"GET",e.url,!0);const i=k(e);e.headers&&Object.keys(e.headers).forEach(i=>{t.setRequestHeader(i,e.headers[i])}),i?.contentType&&t.setRequestHeader("Content-Type",i.contentType),t.timeout=e.timeout||6e4,t.withCredentials=!0,t.onreadystatechange=()=>{if(4===t.readyState){const n={statusCode:t.status,text:t.responseText};if(200===t.status)try{n.json=JSON.parse(t.responseText)}catch(i){console.error("Failed to parse JSON response:",i)}e.callback?.(n)}},t.send(i?.body)}});const F={FACEBOOK:"Facebook",MOBILE:"Mobile",IOS:"iOS",ANDROID:"Android",TABLET:"Tablet",ANDROID_TABLET:"Android Tablet",IPAD:"iPad",APPLE:"Apple",APPLE_WATCH:"Apple Watch",SAFARI:"Safari",BLACKBERRY:"BlackBerry",SAMSUNG_BROWSER:"SamsungBrowser",SAMSUNG_INTERNET:"Samsung Internet",CHROME:"Chrome",CHROME_OS:"Chrome OS",CHROME_IOS:"Chrome iOS",INTERNET_EXPLORER:"Internet Explorer",INTERNET_EXPLORER_MOBILE:"Internet Explorer Mobile",OPERA:"Opera",OPERA_MINI:"Opera Mini",EDGE:"Edge",MICROSOFT_EDGE:"Microsoft Edge",FIREFOX:"Firefox",FIREFOX_IOS:"Firefox iOS",NINTENDO:"Nintendo",PLAYSTATION:"PlayStation",XBOX:"Xbox",ANDROID_MOBILE:"Android Mobile",MOBILE_SAFARI:"Mobile Safari",WINDOWS:"Windows",WINDOWS_PHONE:"Windows Phone",NOKIA:"Nokia",OUYA:"Ouya",GENERIC_MOBILE:"Generic mobile",GENERIC_TABLET:"Generic tablet",KONQUEROR:"Konqueror",UC_BROWSER:"UC Browser",HUAWEI:"Huawei",XIAOMI:"Xiaomi",OPPO:"OPPO",VIVO:"vivo"},B="(\\d+(\\.\\d+)?)",H=new RegExp("Version/"+B),U=new RegExp(F.XBOX,"i"),W=new RegExp(F.PLAYSTATION+" \\w+","i"),X=new RegExp(F.NINTENDO+" \\w+","i"),j=new RegExp(F.BLACKBERRY+"|PlayBook|BB10","i"),q=new RegExp("(HUAWEI|honor|HONOR)","i"),G=new RegExp("(Xiaomi|Redmi)","i"),z=new RegExp("(OPPO|realme)","i"),V=new RegExp("(vivo|IQOO)","i"),Y={"NT3.51":"NT 3.11","NT4.0":"NT 4.0","5.0":"2000",5.1:"XP",5.2:"XP","6.0":"Vista",6.1:"7",6.2:"8",6.3:"8.1",6.4:"10","10.0":"10"};function K(e,t){return t=t||"",D(e," OPR/")&&D(e,"Mini")?F.OPERA_MINI:D(e," OPR/")?F.OPERA:j.test(e)?F.BLACKBERRY:D(e,"IE"+F.MOBILE)||D(e,"WPDesktop")?F.INTERNET_EXPLORER_MOBILE:D(e,F.SAMSUNG_BROWSER)?F.SAMSUNG_INTERNET:D(e,F.EDGE)||D(e,"Edg/")?F.MICROSOFT_EDGE:D(e,"FBIOS")?F.FACEBOOK+" "+F.MOBILE:D(e,"UCWEB")||D(e,"UCBrowser")?F.UC_BROWSER:D(e,"CriOS")?F.CHROME_IOS:D(e,"CrMo")||D(e,F.CHROME)?F.CHROME:D(e,F.ANDROID)&&D(e,F.SAFARI)?F.ANDROID_MOBILE:D(e,"FxiOS")?F.FIREFOX_IOS:D(e.toLowerCase(),F.KONQUEROR.toLowerCase())?F.KONQUEROR:function(e,t){return t&&D(t,F.APPLE)||D(i=e,F.SAFARI)&&!D(i,F.CHROME)&&!D(i,F.ANDROID);var i}(e,t)?D(e,F.MOBILE)?F.MOBILE_SAFARI:F.SAFARI:D(e,F.FIREFOX)?F.FIREFOX:D(e,"MSIE")||D(e,"Trident/")?F.INTERNET_EXPLORER:D(e,"Gecko")?F.FIREFOX:""}const J={[F.INTERNET_EXPLORER_MOBILE]:[new RegExp("rv:"+B)],[F.MICROSOFT_EDGE]:[new RegExp(F.EDGE+"?\\/"+B)],[F.CHROME]:[new RegExp("("+F.CHROME+"|CrMo)\\/"+B)],[F.CHROME_IOS]:[new RegExp("CriOS\\/"+B)],[F.UC_BROWSER]:[new RegExp("(UCBrowser|UCWEB)\\/"+B)],[F.SAFARI]:[H],[F.MOBILE_SAFARI]:[H],[F.OPERA]:[new RegExp("("+F.OPERA+"|OPR)\\/"+B)],[F.FIREFOX]:[new RegExp(F.FIREFOX+"\\/"+B)],[F.FIREFOX_IOS]:[new RegExp("FxiOS\\/"+B)],[F.KONQUEROR]:[new RegExp("Konqueror[:/]?"+B,"i")],[F.BLACKBERRY]:[new RegExp(F.BLACKBERRY+" "+B),H],[F.ANDROID_MOBILE]:[new RegExp("android\\s"+B,"i")],[F.SAMSUNG_INTERNET]:[new RegExp(F.SAMSUNG_BROWSER+"\\/"+B)],[F.INTERNET_EXPLORER]:[new RegExp("(rv:|MSIE )"+B)],Mozilla:[new RegExp("rv:"+B)]};function Z(e,t){const i=K(e,t),n=J[i];if(a(n))return null;for(let s=0;s<n.length;s++){const t=n[s],i=e.match(t);if(i)return parseFloat(i[i.length-2])}return null}const Q=[[new RegExp(F.XBOX+"; "+F.XBOX+" (.*?)[);]","i"),e=>[F.XBOX,e&&e[1]||""]],[new RegExp(F.NINTENDO,"i"),[F.NINTENDO,""]],[new RegExp(F.PLAYSTATION,"i"),[F.PLAYSTATION,""]],[j,[F.BLACKBERRY,""]],[new RegExp(F.WINDOWS,"i"),(e,t)=>{if(/Phone/.test(t)||/WPDesktop/.test(t))return[F.WINDOWS_PHONE,""];if(new RegExp(F.MOBILE).test(t)&&!/IEMobile\b/.test(t))return[F.WINDOWS+" "+F.MOBILE,""];const i=/Windows NT ([0-9.]+)/i.exec(t);if(i&&i[1]){const e=i[1];let n=Y[e]||"";return/arm/i.test(t)&&(n="RT"),[F.WINDOWS,n]}return[F.WINDOWS,""]}],[/((iPhone|iPad|iPod).*?OS (\d+)_(\d+)_?(\d+)?|iPhone)/,e=>{if(e&&e[3]){const t=[e[3],e[4],e[5]||"0"];return[F.IOS,t.join(".")]}return[F.IOS,""]}],[/(watch.*\/(\d+\.\d+\.\d+)|watch os,(\d+\.\d+),)/i,e=>{let t="";return e&&e.length>=3&&(t=a(e[2])?e[3]:e[2]),["watchOS",t]}],[new RegExp("("+F.ANDROID+" (\\d+)\\.(\\d+)\\.?(\\d+)?|"+F.ANDROID+")","i"),e=>{if(e&&e[2]){const t=[e[2],e[3],e[4]||"0"];return[F.ANDROID,t.join(".")]}return[F.ANDROID,""]}],[/Mac OS X (\d+)[_.](\d+)[_.]?(\d+)?/i,e=>{const t=["Mac OS X",""];if(e&&e[1]){const i=[e[1],e[2],e[3]||"0"];t[1]=i.join(".")}return t}],[/Mac/i,["Mac OS X",""]],[/CrOS/,[F.CHROME_OS,""]],[/Linux|debian/i,["Linux",""]]];function ee(){const e=window.innerHeight||document.documentElement.clientHeight||document.body&&document.body.clientHeight||0,t=window.innerWidth||document.documentElement.clientWidth||document.body&&document.body.clientWidth||0,i=navigator.userAgent,n=function(e){for(let t=0;t<Q.length;t++){const[i,n]=Q[t],s=i.exec(e),r=s&&("function"==typeof n?n(s,e):n);if(r)return r}return["",""]}(i)||["",""];return{$browser:K(i),$browser_version:Z(i),$url:location?.href.substring(0,1e3),$host:location?.host,$viewport_height:e,$viewport_width:t,$lib:"webjs",$lib_version:w,$search_engine:$(),$referrer:M(),$referrer_host:m(r=r||M()),$title:document.title,$language:navigator.language,$model:(s=i,(X.test(s)?F.NINTENDO:W.test(s)?F.PLAYSTATION:U.test(s)?F.XBOX:new RegExp(F.OUYA,"i").test(s)?F.OUYA:new RegExp("("+F.WINDOWS_PHONE+"|WPDesktop)","i").test(s)?F.WINDOWS_PHONE:/iPad/.test(s)?F.IPAD:/iPod/.test(s)?"iPod Touch":/iPhone/.test(s)?"iPhone":/(watch)(?: ?os[,/]|\d,\d\/)[\d.]+/i.test(s)?F.APPLE_WATCH:j.test(s)?F.BLACKBERRY:/(kobo)\s(ereader|touch)/i.test(s)?"Kobo":new RegExp(F.NOKIA,"i").test(s)?F.NOKIA:/(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i.test(s)||/(kf[a-z]+)( bui|\)).+silk\//i.test(s)?"Kindle Fire":q.test(s)?F.HUAWEI:G.test(s)?F.XIAOMI:z.test(s)?F.OPPO:V.test(s)?F.VIVO:/(Android|ZTE)/i.test(s)?!new RegExp(F.MOBILE).test(s)||/(9138B|TB782B|Nexus [97]|pixel c|HUAWEISHT|BTV|noble nook|smart ultra 6)/i.test(s)?/pixel[\daxl ]{1,6}/i.test(s)&&!/pixel c/i.test(s)||/(huaweimed-al00|tah-|APA|SM-G92|i980|zte|U304AA)/i.test(s)||/lmy47v/i.test(s)&&!/QTAQZ3/i.test(s)?F.ANDROID:F.ANDROID_TABLET:F.ANDROID:new RegExp("(pda|"+F.MOBILE+")","i").test(s)?F.GENERIC_MOBILE:new RegExp(F.TABLET,"i").test(s)&&!new RegExp(F.TABLET+" pc","i").test(s)?F.GENERIC_TABLET:"")||""),$os:n?.[0]||"",$os_version:n?.[1]||"",$pathname:location?.pathname,$screen_height:Number(screen.height)||0,$screen_width:Number(screen.width)||0,$timezone_offset:60*-(new Date).getTimezoneOffset()};var s,r}const te=new class{constructor(){this.STORAGE_KEY="sensorswave_unsent_events",this.MAX_QUEUE_SIZE=200,this.MAX_RETRY_COUNT=1,this.MAX_AGE_MS=6048e5,this.queue=[],this.loadFromStorage(),this.cleanupExpiredItems()}loadFromStorage(){try{const e=localStorage.getItem(this.STORAGE_KEY);e&&(this.queue=d(e)||[])}catch(e){console.warn("Failed to load queue from localStorage:",e),this.queue=[]}}cleanupExpiredItems(){const e=Date.now(),t=this.queue.filter(t=>e-t.timestamp<this.MAX_AGE_MS);t.length!==this.queue.length&&(this.queue=t,this.saveToStorage())}saveToStorage(){try{this.cleanupExpiredItems(),this.queue.length>this.MAX_QUEUE_SIZE&&(this.queue=this.queue.slice(-this.MAX_QUEUE_SIZE)),localStorage.setItem(this.STORAGE_KEY,JSON.stringify(this.queue))}catch(e){console.warn("Failed to save queue to localStorage:",e)}}enqueue(e,t,i,n=this.MAX_RETRY_COUNT){try{const s={id:f(),url:e,data:t,headers:i,timestamp:Date.now(),retryCount:0,maxRetries:n};return this.queue.push(s),this.saveToStorage(),s.id}catch(s){return console.warn("Failed to enqueue request:",s),""}}dequeue(e){try{this.queue=this.queue.filter(t=>t.id!==e),this.saveToStorage()}catch(t){console.warn("Failed to dequeue request:",t)}}getAll(){try{return this.cleanupExpiredItems(),[...this.queue]}catch(e){return console.warn("Failed to get queue items:",e),[]}}incrementRetryCount(e){const t=this.queue.find(t=>t.id===e);return!(!t||t.retryCount>=t.maxRetries||(t.retryCount++,this.saveToStorage(),0))}clear(){this.queue=[];try{localStorage.removeItem(this.STORAGE_KEY)}catch(e){console.warn("Failed to clear queue from localStorage:",e)}}getItemById(e){return this.queue.find(t=>t.id===e)}};class ie{constructor(e={}){this.flushTimer=null,this.isFlushing=!1,this.paused=!1,this.destroyed=!1,this.config={maxBatchSize:e.maxBatchSize||20,flushInterval:e.flushInterval||5e3},this.startFlushTimer()}pause(){this.paused=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null)}resume(){this.paused&&(this.paused=!1,this.startFlushTimer())}isPaused(){return this.paused}add(){te.getAll().length>=this.config.maxBatchSize&&this.triggerFlush()}triggerFlush(){this.paused||this.isFlushing||(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.isFlushing=!0,this.flush())}flush(){const e=te.getAll();if(0===e.length)return this.isFlushing=!1,void this.startFlushTimer();const t=e.slice(0,this.config.maxBatchSize),i=[],n=[];t.forEach(e=>{Array.isArray(e.data)?i.push(...e.data):i.push(e.data),n.push(e.id)});const s=t[t.length-1],r=s.url,o=s.headers;S.instance&&S.instance.config.debug&&console.log(JSON.stringify(i,null,2)),L({url:r,method:"POST",data:i,headers:o,callback:e=>{200===e.statusCode?n.forEach(e=>{te.dequeue(e)}):P(e.statusCode)?console.error("Failed to send batch events:",e):n.forEach(e=>{te.dequeue(e)}),this.isFlushing=!1,this.startFlushTimer()}})}startFlushTimer(){this.destroyed||(this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.flushTimer=setInterval(()=>{te.getAll().length>0&&this.triggerFlush()},this.config.flushInterval))}destroy(){this.destroyed=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.paused||this.flush()}}let ne=null;function se(){const e=S.instance;return!(!e||!e.__innerInited)||(console.warn("[SensorsWave] SDK is not initialized. Please call init() first."),!1)}function re(){const e=S.instance;return!e||"function"!=typeof e.hasOptedOutCapturing||!e.hasOptedOutCapturing()}let oe=null;function ae(){return v.isSupport()?(oe||(ne||(ne=new ie({maxBatchSize:20,flushInterval:5e3})),oe=ne),oe):null}function ce(e,t,i){if(re())return L({url:e,method:"POST",data:t.data,headers:t.headers,callback:e=>{if(200!==e.statusCode){if(!P(e.statusCode))return void(i&&te.dequeue(i));if(i&&te.incrementRetryCount(i)){const e=te.getItemById(i);if(e){const t=Math.min(1e3*Math.pow(2,e.retryCount),3e4);setTimeout(()=>{ce(e.url,{data:e.data,headers:e.headers},e.id)},t)}}}else i&&te.dequeue(i),t.callback&&t.callback(e.json)}})}function ue(e){return`${e.apiHost}/in/track`}function le(e){return`${e.apiHost}/ab/evalall`}function he(e){return{"Content-Type":"application/json",SourceToken:e.sourceToken}}function de(e,t,i){S.instance&&S.instance.config.debug&&console.log(JSON.stringify(t.data,null,2));const n=te.enqueue(e,t.data,t.headers);return ce(e,{...t,callback:void 0},n)}function pe(){try{const e=sessionStorage.getItem("sensorswave_utm");if(!e)return{};const t=JSON.parse(e),i={};return Object.entries(t).forEach(([e,t])=>{null!=t&&""!==t&&(i[`$${e}`]=t)}),i}catch(e){return{}}}function ge(e){const t={};return Object.entries(e).forEach(([e,i])=>{if("function"==typeof i)try{const n=i();t[e]=n}catch(n){console.warn("[SensorsWave] Failed to resolve dynamic property:",e,n)}else t[e]=i}),t}function fe(e={},t=!0){const i={...t?ee():{},...ge(N.getCommonProps()),...e},n=pe();return Object.keys(n).length>0&&Object.assign(i,n),i}function me(e,t,i=!0){if(!se())return;if(!re())return;const n={time:Date.now(),trace_id:N.getTraceId(),event:e.event,properties:fe(e.properties,i)},s=pe();Object.keys(s).length>0&&(n.user_properties||(n.user_properties={}),n.user_properties.$set||(n.user_properties.$set={}),Object.assign(n.user_properties.$set,s)),e.user_properties&&(e.user_properties.$set&&(n.user_properties=n.user_properties||{},n.user_properties.$set={...n.user_properties.$set||{},...e.user_properties.$set},delete e.user_properties.$set),n.user_properties={...n.user_properties,...e.user_properties});const r=N.getLoginId(),o=N.getAnonId();r&&(n.login_id=r),o&&(n.anon_id=o);const a=ue(t),c=he(t),u=!1!==t.batchSend&&ae();u?(te.enqueue(a,[n],c),u.add()):de(a,{data:[n],headers:c})}function Ee({userProps:e,opts:t}){if(!se())return;if(!re())return;const i=N.getLoginId(),n=N.getAnonId();if(!i&&!n)return;const s={time:Date.now(),trace_id:N.getTraceId(),event:"$UserSet",login_id:i,anon_id:n,user_properties:e,properties:fe()},r=ue(t),o=he(t),a=ae();if(!a)return de(r,{data:[s],headers:o});te.enqueue(r,[s],o),a.add()}function be(e){return e.typ===C.FEATURE_GATE||e.typ===C.FEATURE_CONFIG?`$feature_${e.id}`:e.typ===C.EXPERIMENT?`$exp_${e.id}`:""}function ve(e){const t=e.typ;return[C.FEATURE_GATE,C.EXPERIMENT,C.FEATURE_CONFIG].includes(t)?{[be(e)]:e.vid}:{}}function _e(e){const t=e.typ;return t===C.FEATURE_GATE||t===C.FEATURE_CONFIG?{$feature_key:e.key,$feature_variant:e.vid}:t===C.EXPERIMENT?{$exp_key:e.key,$exp_variant:e.vid}:{}}function Ie({isUnset:e=!1,data:t,opts:i}){if(!se())return;if(!re())return;if(!t||u(t)||t.disable_impress)return;const n=N.getLoginId(),s=N.getAnonId();if(!n&&!s)return;const r=t.typ===C.EXPERIMENT?"$ExpImpress":"$FeatureImpress";let o={};return o=e?{$unset:{[be(t)]:null}}:{$set:{...ve(t)}},me({event:r,properties:_e(t),user_properties:o},i)}const Se="sensorswave_opt_out";class we{constructor(e){this.persist=e}read(){if(this.persist)try{const e=v.get(Se);return"0"===e||"1"!==e&&void 0}catch{return}}write(e){if(this.persist)try{v.set(Se,e?"0":"1")}catch{}}}class ye{constructor({plugins:e,emitter:t,config:i,sdk:n}){this.plugins=[],this.pluginInsMap={},this.emitter=t,this.config=i,this.sdk=n,this.registerBuiltInPlugins(e),this.created(),this.emitter.on(y,()=>{this.init()})}registerBuiltInPlugins(e){for(let t=0,i=e.length;t<i;t++)this.registerPlugin(e[t])}registerPlugin(e){this.plugins.push(e)}getPlugins(){return this.plugins}getPlugin(e){return this.pluginInsMap[e]}created(){for(let e=0,t=this.plugins.length;e<t;e++){const t=this.plugins[e];if(!t.NAME)throw new Error('Plugin should be defined with "NAME"');const i=new t({emitter:this.emitter,config:this.config,sdk:this.sdk});this.pluginInsMap[t.NAME]=i}}init(){for(const e of Object.keys(this.pluginInsMap)){const t=this.pluginInsMap[e];t.init&&t.init()}}destroy(){for(const e of Object.keys(this.pluginInsMap)){const t=this.pluginInsMap[e];t.destroy&&"function"==typeof t.destroy&&t.destroy()}this.pluginInsMap={},this.plugins=[]}}const Oe=class{constructor({emitter:e,config:t,sdk:i}){this.boundSend=null,this.hashEvent=null,this.spaSwitchHandler=null,this.emitter=e,this.config=t,this.sdk=i}init(){const e=this.config;this.boundSend=()=>{me({event:"$PageView",properties:{}},e)},this.sdk&&!0===this.sdk._postConsentInit||setTimeout(()=>{this.boundSend()},0),e.isSinglePageApp&&this.addSinglePageListener()}addSinglePageListener(){this.spaSwitchHandler=e=>{e!==location.href&&this.boundSend()},this.emitter.on(O,this.spaSwitchHandler)}destroy(){this.spaSwitchHandler&&(this.emitter.off(O,this.spaSwitchHandler),this.spaSwitchHandler=null),this.hashEvent&&this.boundSend&&(window.removeEventListener(this.hashEvent,this.boundSend),this.hashEvent=null),this.boundSend=null}};Oe.NAME="pageview";let Ae=Oe;const Re=class{constructor({emitter:e,config:t,sdk:i}){this.startTime=Date.now(),this.pageShowStatus=!0,this.pageHiddenStatus=!1,this.timer=null,this.currentPageUrl=document.referrer,this.url=location.href,this.title=document.title||"",this.heartbeatIntervalTime=5e3,this.heartbeatIntervalTimer=null,this.pageId=null,this.storageName="sensorswavewebjssdkpageleave",this.maxDuration=432e3,this.eventListeners=[],this._skipFirstPageEnd=!1,this.emitter=e,this.config=t,this.sdk=i}__canCapture(){return!this.sdk||"function"!=typeof this.sdk.hasOptedOutCapturing||!this.sdk.hasOptedOutCapturing()}init(){this.pageId=Number(String(g()).slice(2,5)+String(g()).slice(2,4)+String(Date.now()).slice(-4)),this.addEventListener(),this.sdk&&!0===this.sdk._postConsentInit&&(this._skipFirstPageEnd=!0),!0===document.hidden?this.pageShowStatus=!1:this.addHeartBeatInterval()}log(e){console.log(e)}refreshPageEndTimer(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.timer=setTimeout(()=>{this.pageHiddenStatus=!1},5e3)}hiddenStatusHandler(){this.timer&&clearTimeout(this.timer),this.timer=null,this.pageHiddenStatus=!1}pageStartHandler(){this.startTime=Date.now(),1==!document.hidden?this.pageShowStatus=!0:this.pageShowStatus=!1,this.url=location.href,this.title=document.title,this._skipFirstPageEnd=!1}pageEndHandler(){if(!0===this.pageHiddenStatus)return;if(!this.__canCapture())return;const e=this.getPageLeaveProperties();!1===this.pageShowStatus&&delete e.$event_duration,this.pageShowStatus=!1,this.pageHiddenStatus=!0,me({event:R,properties:e},this.config),this.refreshPageEndTimer(),this.delHeartBeatData()}addEventListener(){this.addPageStartListener(),this.addPageSwitchListener(),this.addSinglePageListener(),this.addPageEndListener()}addPageStartListener(){if("onpageshow"in window){const e=()=>{this.pageStartHandler(),this.hiddenStatusHandler()};window.addEventListener("pageshow",e),this.eventListeners.push({target:window,event:"pageshow",handler:e})}}addSinglePageListener(){this.config.isSinglePageApp&&this.emitter.on(O,e=>{e!==location.href&&(this.url=e,this.pageEndHandler(),this.stopHeartBeatInterval(),this.currentPageUrl=this.url,this.pageStartHandler(),this.hiddenStatusHandler(),this.addHeartBeatInterval())})}addPageEndListener(){["pagehide","beforeunload"].forEach(e=>{if(`on${e}`in window){const t=()=>{if(this._skipFirstPageEnd)return this._skipFirstPageEnd=!1,void this.stopHeartBeatInterval();this.pageEndHandler(),this.stopHeartBeatInterval()};window.addEventListener(e,t),this.eventListeners.push({target:window,event:e,handler:t})}})}addPageSwitchListener(){const e=()=>{"visible"===document.visibilityState?(this.pageStartHandler(),this.hiddenStatusHandler(),this.addHeartBeatInterval()):(this.url=location.href,this.title=document.title,this.stopHeartBeatInterval(),this.delHeartBeatData())};document.addEventListener("visibilitychange",e),this.eventListeners.push({target:document,event:"visibilitychange",handler:e})}addHeartBeatInterval(){v.isSupport()&&this.startHeartBeatInterval()}startHeartBeatInterval(){this.heartbeatIntervalTimer&&this.stopHeartBeatInterval(),this.sdk&&!0===this.sdk._postConsentInit&&!0===this._skipFirstPageEnd||(this.heartbeatIntervalTimer=setInterval(()=>{this.saveHeartBeatData()},this.heartbeatIntervalTime),this.saveHeartBeatData("is_first_heartbeat"),this.reissueHeartBeatData())}stopHeartBeatInterval(){this.heartbeatIntervalTimer&&clearInterval(this.heartbeatIntervalTimer),this.heartbeatIntervalTimer=null}saveHeartBeatData(e){if(!this.__canCapture())return;const t=this.getPageLeaveProperties();t.$time=Date.now(),"is_first_heartbeat"===e&&(t.$event_duration=3);const i={type:"track",event:R,properties:t,time:t.$time};i.heartbeat_interval_time=this.heartbeatIntervalTime,v.isSupport()&&v.set(`${this.storageName}-${this.pageId}`,JSON.stringify(i))}delHeartBeatData(e){v.isSupport()&&v.remove(e||`${this.storageName}-${this.pageId}`)}reissueHeartBeatData(){if(this.__canCapture())for(let e=window.localStorage.length-1;e>=0;e--){const t=window.localStorage.key(e);if(t&&t!==`${this.storageName}-${this.pageId}`&&0===t.indexOf(`${this.storageName}-`)){const e=v.parse(t);n(e)&&Date.now()-e.time>e.heartbeat_interval_time+5e3&&(delete e.heartbeat_interval_time,e._flush_time=(new Date).getTime(),me({event:R,properties:e?.properties},this.config),this.delHeartBeatData(t))}}}getPageLeaveProperties(){let e=(Date.now()-this.startTime)/1e3;(isNaN(e)||e<0||e>this.maxDuration)&&(e=0),e=Number(e.toFixed(3));const t={$title:this.title,$url:this.url?.substring(0,1e3),$pathname:I(this.url)};return 0!==e&&(t.$event_duration=e),t}destroy(){this.eventListeners.forEach(({target:e,event:t,handler:i})=>{e.removeEventListener(t,i)}),this.eventListeners=[],this.timer&&(clearTimeout(this.timer),this.timer=null),this.heartbeatIntervalTimer&&(clearInterval(this.heartbeatIntervalTimer),this.heartbeatIntervalTimer=null)}};Re.NAME="pageleave";let Te=Re;const Ce=class{constructor({emitter:e,config:t,sdk:i}){this.eventSended=!1,this.emitter=e,this.config=t,this.sdk=i}init(){if(this.sdk&&!0===this.sdk._postConsentInit)return;const e=()=>{let t=0;const i={};if(window.performance){t=function(){let e=0;if("function"==typeof performance.getEntriesByType){const t=performance.getEntriesByType("navigation");t.length>0&&(e=t[0].domContentLoadedEventEnd||0)}return e}();const e=function(){if(performance.getEntries&&"function"==typeof performance.getEntries){const e=performance.getEntries();let t=0;for(const i of e)"transferSize"in i&&(t+=i.transferSize);if("number"==typeof t&&t>=0&&t<10737418240)return Number((t/1024).toFixed(3))}}();e&&(i.$page_resource_size=e)}else console.warn("Performance API is not supported.");t>0&&!Number.isFinite(t)&&(i.$event_duration=Number((t/1e3).toFixed(3))),this.eventSended||(this.eventSended=!0,me({event:"$PageLoad",properties:i},this.config)),window.removeEventListener("load",e)};"complete"===document.readyState?e():window.addEventListener&&window.addEventListener("load",e)}};Ce.NAME="pageload";let Ne=Ce;function Pe(e){if(!l(e))return!1;const t=o(e.tagName)?e.tagName.toLowerCase():"",i={};return i.$element_type=t,i.$element_name=e.getAttribute("name")||"",i.$element_id=e.getAttribute("id")||"",i.$element_class_name=o(e.className)?e.className:"",i.$element_target_url=e.getAttribute("href")||"",i.$element_content=function(e,t){return o(t)&&"input"===t.toLowerCase()?("button"===(i=e).type||"submit"===i.type)&&i.value||"":function(e,t){let i="",n="";return e.textContent?i=_(e.textContent):e.innerText&&(i=_(e.innerText)),i&&(i=i.replace(/[\r\n]/g," ").replace(/[ ]+/g," ").substring(0,255)),n=i||"","input"!==t&&"INPUT"!==t||(n=e.value||""),n}(e,t);var i}(e,t)||"",i.$element_selector=ke(e)||"",i.$element_path=function(e){let t=[];for(;e.parentNode&&l(e);){if(!o(e.tagName))return"";if(e.id&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.id)){t.unshift(e.tagName.toLowerCase()+"#"+e.id);break}if(e===document.body){t.unshift("body");break}t.unshift(e.tagName.toLowerCase()),e=e.parentNode}return t.join(" > ")}(e)||"",i}function ke(e,t=[]){if(!(e&&e.parentNode&&e.parentNode.children&&o(e.tagName)))return"";t=Array.isArray(t)?t:[];const i=e.nodeName.toLowerCase();return e&&"body"!==i&&1==e.nodeType?(t.unshift(function(e){if(!e||!l(e)||!o(e.tagName))return"";let t=e.parentNode&&9==e.parentNode.nodeType?-1:function(e){if(!e.parentNode)return-1;let t=0;const i=e.tagName,n=e.parentNode.children;for(let s=0,r=n.length;s<r;s++)if(n[s].tagName===i){if(e===n[s])return t;t++}return-1}(e);return e.getAttribute&&e.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.getAttribute("id"))?"#"+e.getAttribute("id"):e.tagName.toLowerCase()+(~t?":nth-of-type("+(t+1)+")":"")}(e)),e.getAttribute&&e.getAttribute("id")&&/^[A-Za-z][-A-Za-z0-9_:.]*$/.test(e.getAttribute("id"))?t.join(" > "):ke(e.parentNode,t)):(t.unshift("body"),t.join(" > "))}function xe(){return{scrollLeft:document.body.scrollLeft||document.documentElement.scrollLeft||0,scrollTop:document.body.scrollTop||document.documentElement.scrollTop||0}}function Le(e){if(document.documentElement.getBoundingClientRect){const t=e.getBoundingClientRect();return{targetEleX:t.left+xe().scrollLeft||0,targetEleY:t.top+xe().scrollTop||0}}return{targetEleX:0,targetEleY:0}}function Me(e){return Number(Number(e).toFixed(3))}const $e=class{constructor({emitter:e,config:t}){this.isInitialized=!1,this.boundHandleClick=null,this.emitter=e,this.config=t}init(){this.isInitialized||(this.boundHandleClick=this.handleClick.bind(this),document.addEventListener("click",this.boundHandleClick,!0),this.isInitialized=!0)}handleClick(e){const t=e.target;if(!t)return;if(!["A","INPUT","BUTTON","TEXTAREA"].includes(t.tagName))return;if("true"===t.getAttribute("sensorswave-disable"))return;const i=function(e,t){const i=Pe(e);if(!i)return!1;const n=function(e,t){const i=t.pageX||t.clientX+xe().scrollLeft||t.offsetX+Le(e).targetEleX,n=t.pageY||t.clientY+xe().scrollTop||t.offsetY+Le(e).targetEleY;return{$page_x:Me(i),$page_y:Me(n)}}(e,t);return i.$page_x=n.$page_x,i.$page_y=n.$page_y,i}(t,e);me({event:"$WebClick",properties:i||{}},this.config)}destroy(){this.boundHandleClick&&(document.removeEventListener("click",this.boundHandleClick,!0),this.boundHandleClick=null),this.isInitialized=!1}};$e.NAME="webclick";let De=$e;const Fe=class{constructor({emitter:e,config:t,sdk:i}){this.updateInterval=null,this.fetchingPromise=null,this.emitter=e,this.config=t,this.sdk=i}init(){const e=this.config;if(e.enableAB){if(this.sdk&&"function"==typeof this.sdk.hasOptedOutCapturing&&this.sdk.hasOptedOutCapturing())return;this.fastFetch().then(()=>{this.emitter.emit(A)}),e.abRefreshInterval<3e4&&(e.abRefreshInterval=3e4),this.updateInterval=setInterval(()=>{this.fetchNewData().catch(console.warn)},e.abRefreshInterval)}}async fastFetch(){const e=N.getABData(this.config.abRefreshInterval);return e&&e.length?(this.emitter.emit(A),Promise.resolve(e)):this.fetchNewData()}async fetchNewData(){return this.fetchingPromise||(this.fetchingPromise=new Promise(e=>{!function({opts:e,cb:t}){if(!se())return void(t&&t({}));if(!re())return void(t&&t({}));const i=N.getLoginId(),n=N.getAnonId();if(!i&&!n)return void(t&&t({}));const s={user:{login_id:i||"",anon_id:n||"",props:{...ee(),...ge(N.getCommonProps())}},sdk:"webjs",sdk_version:w};L({url:le(e),method:"POST",data:s,headers:he(e),callback:e=>{200!==e.statusCode?(console.error("Failed to fetch feature flags"),t&&t({})):t&&t(e.json)}})}({opts:this.config,cb:t=>{N.saveABData(t?.data?.results||[]),e(t),this.fetchingPromise=null}})})),this.fetchingPromise}async getFeatureGate(e){return await this.fastFetch().catch(console.warn),N.getABData(this.config.abRefreshInterval).find(t=>t.typ===C.FEATURE_GATE&&t.key==e)}async checkFeatureGate(e){const t=await this.getFeatureGate(e);return!!t&&(!t.hasOwnProperty("vid")&&t.key?(Ie({isUnset:!0,data:t,opts:this.config}),!1):(Ie({data:t,opts:this.config}),"fail"!==t.vid))}async getExperiment(e){await this.fastFetch().catch(console.warn);const t=N.getABData(this.config.abRefreshInterval).find(t=>t.typ===C.EXPERIMENT&&t.key===e);return t?!t.hasOwnProperty("vid")&&t.key?(Ie({isUnset:!0,data:t,opts:this.config}),{}):(Ie({data:t,opts:this.config}),t?.value||{}):{}}async getFeatureConfig(e){await this.fastFetch().catch(console.warn);const t=N.getABData(this.config.abRefreshInterval).find(t=>t.typ===C.FEATURE_CONFIG&&t.key===e);if(!t)return{};if(!t.hasOwnProperty("vid")&&t.key)return Ie({isUnset:!0,data:t,opts:this.config}),{};Ie({data:t,opts:this.config});const i=t?.value;if(i){if(n(i))return i;try{return JSON.parse(i)}catch{return i}}return{}}destroy(){this.updateInterval&&(clearInterval(this.updateInterval),this.updateInterval=null),this.fetchingPromise=null}};Fe.NAME="abtest";let Be=Fe;const He=["utm_source","utm_medium","utm_campaign","utm_content","utm_term"],Ue="sensorswave_utm",We=class e{constructor({sdk:e,emitter:t,config:i}){this.sdk=e,this.emitter=t,this.config=i}init(){if(this.sdk&&!0===this.sdk._postConsentInit){let t=e.readFromSessionStorage();return t&&0!==Object.keys(t).length||(t=e.captureAndStore(this.config?.debug)),void this.scheduleInitialUTM(t)}const t=e.getUTMFromURL();e.saveToSessionStorage(t,this.config?.debug),this.scheduleInitialUTM(t)}scheduleInitialUTM(e){setTimeout(()=>{this.sendInitialUTM(e)},0)}static getUTMFromURL(){try{const e=new URLSearchParams(window.location.search),t={};return He.forEach(i=>{const n=e.get(i);n&&(t[i]=n)}),t}catch(t){return e.getUTMFromURLFallback()}}static getUTMFromURLFallback(){const e={};return window.location.search.substring(1).split("&").forEach(t=>{const[i,n]=t.split("="),s=decodeURIComponent(i),r=n?decodeURIComponent(n):"";He.includes(s)&&(e[s]=r)}),e}static readFromSessionStorage(){try{const e=sessionStorage.getItem(Ue);if(!e)return{};const t=JSON.parse(e);return t&&"object"==typeof t?t:{}}catch(e){return{}}}static saveToSessionStorage(e,t=!1){try{sessionStorage.setItem(Ue,JSON.stringify(e))}catch(i){t&&console.warn("[SensorsWave UTM] Failed to save to sessionStorage:",i)}}static captureAndStore(t=!1){const i=e.getUTMFromURL();return e.saveToSessionStorage(i,t),i}sendInitialUTM(e){const t={};He.forEach(i=>{t[`$initial_${i}`]=null!=e[i]?e[i]:""});try{this.sdk.profileSetOnce(t)}catch(i){this.config.debug&&console.warn("[SensorsWave UTM] Failed to send initial UTM:",i)}}destroy(){}};We.NAME="UTM";let Xe=We;const je=1e3,qe=/^\s*(?:async\s+)?at\s+(?:(.+)\s+\()?(.+?):(\d+):(\d+)\)?$/,Ge=/^(?:(.*)@)?(.+?):(\d+):(\d+)$/;function ze(e){let t=e;try{const e=location.origin;e&&0===t.indexOf(e)&&(t=t.substring(e.length))}catch(s){}const i=t.indexOf("?");i>-1&&(t=t.substring(0,i));const n=t.indexOf("#");return n>-1&&(t=t.substring(0,n)),t}function Ve(e){return e.map(e=>({platform:"web:javascript",filename:ze(e.file),function:e.fn||"?",lineno:Number(e.line),colno:Number(e.col),abs_path:Ye(e.file,1e3)}))}function Ye(e,t){return e.length>t?e.substring(0,t):e}function Ke(e){let t;if("string"==typeof e)t=e;else if(null!==e&&"object"==typeof e){try{t=JSON.stringify(e)}catch(i){t=Object.prototype.toString.call(e)}t||(t=Object.prototype.toString.call(e))}else t=String(e);return Ye(t,je)}function Je(e){const{frames:t,headerType:i}=function(e){const t=[];let i="";if(!e||"string"!=typeof e)return{frames:t,headerType:i};const n=e.split(/\r?\n/);for(let s=0;s<n.length;s++){const e=n[s];if(!e||e.length>1024)continue;const r=e.match(qe),o=r?null:e.match(Ge),a=r||o;if(a)t.push({fn:a[1]||"?",file:a[2],line:a[3],col:a[4]});else if(0===s){const t=e.indexOf(":");t>0&&(i=e.substring(0,t).trim())}if(t.length>=30)break}return{frames:t,headerType:i}}(e&&e.stack);let n=e&&e.name||i||"Error";return n=Ye(String(n),200),{$exception_level:"error",$exception_type:n,$exception_message:Ye(String(e&&e.message||""),je),$exception_frames:Ve(t)}}function Ze(e,t,i,n){let s=[];return t&&(s=[{platform:"web:javascript",filename:ze(t),function:"?",lineno:i||0,colno:n||0,abs_path:Ye(t,1e3)}]),{$exception_level:"error",$exception_type:"Error",$exception_message:Ye(String(e||""),je),$exception_frames:s}}class Qe{constructor(e=10,t=1,i=1e4){this.buckets=new Map,this.bucketSize=e,this.refillRate=t,this.refillInterval=i}allow(e){const t=Date.now();let i=this.buckets.get(e);if(i){if(t>i.lastRefill){const e=Math.floor((t-i.lastRefill)/this.refillInterval)*this.refillRate;e>0&&(i.tokens=Math.min(this.bucketSize,i.tokens+e),i.lastRefill+=e/this.refillRate*this.refillInterval)}}else i={tokens:this.bucketSize,lastRefill:t},this.buckets.set(e,i);return i.tokens>=1&&(i.tokens-=1,!0)}reset(){this.buckets.clear()}}const et=class{constructor({emitter:e,config:t}){this.isInitialized=!1,this.boundHandleError=null,this.boundHandleRejection=null,this.rateLimiter=new Qe,this.emitter=e,this.config=t}init(){this.isInitialized||(this.boundHandleError=this.handleError.bind(this),this.boundHandleRejection=this.handleRejection.bind(this),window.addEventListener("error",this.boundHandleError,!0),window.addEventListener("unhandledrejection",this.boundHandleRejection),this.isInitialized=!0)}handleError(e){try{const t=e.target;let i;if(t&&t!==window&&t.tagName)i=function(e){const t=e,i=(t.tagName||"").toLowerCase(),n=Ye(String(t.src||t.href||""),je);return{$exception_level:"error",$exception_type:"ResourceLoadError",$exception_message:`Failed to load <${i}>${n?` from ${n}`:""}`,$exception_frames:[]}}(t);else{const t=e;i=t.error instanceof Error?Je(t.error):Ze(String(t.message||""),t.filename,t.lineno,t.colno)}this.send(i)}catch(t){}}handleRejection(e){try{const t=e.reason;this.send(function(e){return e instanceof Error?Je(e):{$exception_level:"error",$exception_type:"UnhandledRejection",$exception_message:Ke(e),$exception_frames:[]}}(t))}catch(t){}}send(e){e.$exception_message&&this.rateLimiter.allow(e.$exception_type)&&me({event:T,properties:e},this.config)}destroy(){this.boundHandleError&&(window.removeEventListener("error",this.boundHandleError,!0),this.boundHandleError=null),this.boundHandleRejection&&(window.removeEventListener("unhandledrejection",this.boundHandleRejection),this.boundHandleRejection=null),this.rateLimiter.reset(),this.isInitialized=!1}};et.NAME="exception";let tt=et;const it="data-sw-exposure-event-name",nt="data-sw-exposure-config-",st=`[${it}]`,rt={visibleRatio:0,stayDuration:0,repeated:!0};function ot(e,t){const i={};if(!n(e))return i;const s=e;if(void 0!==s.visibleRatio){const e=Number(s.visibleRatio);!isNaN(e)&&e>=0&&e<=1?i.visibleRatio=e:t&&t("[exposure] parameter config.visibleRatio 非法(值域 0~1),已忽略:",s.visibleRatio)}if(void 0!==s.stayDuration){const e=Number(s.stayDuration);!isNaN(e)&&e>=0?i.stayDuration=e:t&&t("[exposure] parameter config.stayDuration 非法(须 >= 0),已忽略:",s.stayDuration)}if(void 0!==s.repeated){const e=s.repeated;!0===e||"true"===e?i.repeated=!0:!1===e||"false"===e?i.repeated=!1:t&&t("[exposure] parameter config.repeated 非法(须为布尔),已忽略:",e)}return i}function at(...e){const t={...rt};for(let i=0;i<e.length;i++){const s=e[i];if(!n(s))continue;const r=s;void 0!==r.visibleRatio&&(t.visibleRatio=r.visibleRatio),void 0!==r.stayDuration&&(t.stayDuration=r.stayDuration),void 0!==r.repeated&&(t.repeated=r.repeated)}return t}function ct(e){const t=(e.getAttribute(it)||"").trim();let i={},s={};const r=e.getAttribute("data-sw-exposure-option");if(r){const e=d(r);n(e)&&(n(e.config)&&(i=e.config),n(e.properties)&&(s=e.properties))}const a=e.getAttribute(nt+"visible-ratio");null!==a&&(i.visibleRatio=a);const c=e.getAttribute(nt+"stay-duration");null!==c&&(i.stayDuration=c);const u=e.getAttribute(nt+"repeated");null!==u&&(i.repeated=u);const l=e.attributes;for(let n=0;n<l.length;n++){const e=l[n],t=e.name;if(o(t)&&0===t.indexOf("data-sw-exposure-property-")){const i=t.substring(26);i&&(s[i]=e.value)}}return{eventName:t,config:ot(i),properties:s}}const ut=class{constructor({emitter:e,config:t,sdk:i}){this.isInitialized=!1,this.observers=new Map,this.records=new Map,this.mutationObserver=null,this.boundHandleIntersection=null,this.boundHandleMutation=null,this.boundHandleVisibility=null,this.boundHandleReady=null,this.boundHandleSpa=null,this.eventListeners=[],this.globalConfig={...rt},this.log=function(){},this.emitter=e,this.config=t,this.sdk=i}init(){this.isInitialized||(function(){try{return"undefined"!=typeof window&&"IntersectionObserver"in window&&"MutationObserver"in window}catch(e){return!1}}()?(this.log=!0==(!0===this.config.debug)&&"undefined"!=typeof console&&console.log?function(...e){console.log("[SensorsWave][exposure]",...e)}:function(){},this.globalConfig=at(this.globalConfig,ot(this.config.exposureConfig,this.log)),this.boundHandleIntersection=this.handleIntersection.bind(this),this.boundHandleMutation=this.handleMutation.bind(this),this.boundHandleVisibility=this.handleVisibility.bind(this),"loading"===document.readyState?(this.boundHandleReady=()=>{this.scanDocument(),this.observeMutations()},document.addEventListener("DOMContentLoaded",this.boundHandleReady),this.eventListeners.push({target:document,event:"DOMContentLoaded",handler:this.boundHandleReady})):(this.scanDocument(),this.observeMutations()),!0===this.config.isSinglePageApp&&(this.boundHandleSpa=e=>{this.handleSpaSwitch(e)},this.emitter.on(O,this.boundHandleSpa)),document.addEventListener("visibilitychange",this.boundHandleVisibility),this.eventListeners.push({target:document,event:"visibilitychange",handler:this.boundHandleVisibility}),!0===document.hidden&&this.stop(),this.isInitialized=!0):console.warn("[SensorsWave][exposure] 当前浏览器不支持 IntersectionObserver / MutationObserver,曝光采集未初始化"))}addExposureView(e,t){this.isInitialized?l(e)?n(t)&&o(t.eventName)&&t.eventName.trim()?this.addOrUpdateWatchEle(e,{eventName:t.eventName.trim(),config:n(t.config)?ot(t.config,this.log):void 0,properties:n(t.properties)?{...t.properties}:{},listener:n(t.listener)?{...t.listener}:{}},"api"):this.log("addExposureView parameter option.eventName 缺失:",t):this.log("addExposureView parameter element 非法:",e):this.log("曝光插件未初始化(enableExposureTrack 未开启或浏览器不支持)")}removeExposureView(e){this.isInitialized?l(e)?this.removeWatchEle(e):this.log("removeExposureView parameter element 非法:",e):this.log("曝光插件未初始化")}scanDocument(e){try{const t=e||document;if(!t.querySelectorAll)return;const i=t.querySelectorAll(st);for(let e=0;e<i.length;e++){const t=i[e];this.addOrUpdateWatchEle(t,ct(t),"attr")}}catch(t){}}addOrUpdateWatchEle(e,t,i){if(!e||!l(e))return void this.log("parameter element error:",e);if(!o(t.eventName)||!t.eventName.trim())return void this.log("parameter option.eventName error:",t);const n=this.records.get(e);if(n&&"api"===n.source&&"attr"===i)return void this.log("声明式属性变更被忽略:元素已由 addExposureView 注册",e);const s=at(this.globalConfig,n&&n.config,t.config);if(n&&n.config.visibleRatio===s.visibleRatio)return n.eventName=t.eventName,n.source=i,n.config=s,n.properties={...t.properties||{}},n.listener=t.listener||{},void(n.hasSent=!1);n&&this.removeWatchEle(e);const r={ele:e,eventName:t.eventName,source:i,config:s,properties:{...t.properties||{}},listener:t.listener||{},timer:null,hasSent:!1};this.records.set(e,r),this.getIntersection(s.visibleRatio).observe(e)}getIntersection(e){let t=this.observers.get(e);return!t&&this.boundHandleIntersection&&(t=new IntersectionObserver(this.boundHandleIntersection,{threshold:e}),this.observers.set(e,t)),t}removeWatchEle(e){const t=this.records.get(e);if(!t)return;const i=this.observers.get(t.config.visibleRatio);i&&l(e)&&i.unobserve(e),t.timer&&(clearTimeout(t.timer),t.timer=null),this.records.delete(e)}handleIntersection(e){try{for(const t of e){const e=t.target,i=this.records.get(e);i&&(!0===t.isIntersecting&&t.intersectionRatio>=i.config.visibleRatio?!0!==document.hidden&&(i.timer&&clearTimeout(i.timer),i.timer=setTimeout(()=>{this.fireExposure(e)},1e3*i.config.stayDuration)):i.timer&&(clearTimeout(i.timer),i.timer=null))}}catch(t){}}fireExposure(e){try{const i=this.records.get(e);if(i&&(i.timer=null),!i||i.hasSent)return;let n={width:0,height:0};try{n=e.getBoundingClientRect()}catch(t){}if(!n.width||!n.height)return;if(!e.isConnected)return void this.removeWatchEle(e);if(this.sdk&&"function"==typeof this.sdk.hasOptedOutCapturing&&this.sdk.hasOptedOutCapturing())return;const r={...Pe(e),...i.properties},{shouldExpose:o,didExpose:a}=i.listener||{};if(o&&s(o))try{if(!1===o(e,r))return}catch(t){return}if(me({event:i.eventName,properties:r},this.config),i.hasSent=!0,i.config.repeated&&(i.hasSent=!1),a&&s(a))try{a(e,r)}catch(t){}}catch(t){}}observeMutations(){!this.mutationObserver&&this.boundHandleMutation&&(this.mutationObserver=new MutationObserver(this.boundHandleMutation),this.mutationObserver.observe(document.body,{attributes:!0,childList:!0,subtree:!0}))}handleMutation(e){try{for(const t of e)if("childList"===t.type){if(t.removedNodes.length>0)for(const e of Array.from(t.removedNodes)){if(1!==e.nodeType)continue;this.removeWatchEle(e);const t=e.querySelectorAll(st);for(let e=0;e<t.length;e++)this.removeWatchEle(t[e])}if(t.addedNodes.length>0)for(const e of Array.from(t.addedNodes))1===e.nodeType&&(e.hasAttribute(it)&&this.addOrUpdateWatchEle(e,ct(e),"attr"),this.scanDocument(e))}else"attributes"===t.type&&this.handleAttrChange(t)}catch(t){}}handleAttrChange(e){const t=e.attributeName;if(!t||0!==t.indexOf("data-sw-exposure"))return;const i=e.target;t!==it||(i.getAttribute(t)||"").trim()?(i.getAttribute(it)||"").trim()&&this.addOrUpdateWatchEle(i,ct(i),"attr"):this.removeWatchEle(i)}handleSpaSwitch(e){try{if(e===location.href)return;this.stop();for(const[e,t]of Array.from(this.records))"attr"===t.source&&this.records.delete(e);this.start(),this.scanDocument()}catch(t){}}stop(){for(const e of Array.from(this.records.values())){const t=this.observers.get(e.config.visibleRatio);t&&t.unobserve(e.ele),e.timer&&(clearTimeout(e.timer),e.timer=null)}}start(){for(const e of Array.from(this.records.values())){if(!e.ele.isConnected){this.records.delete(e.ele);continue}const t=this.observers.get(e.config.visibleRatio);t&&t.observe(e.ele)}}handleVisibility(){try{"visible"===document.visibilityState?this.start():this.stop()}catch(e){}}destroy(){this.observers.forEach(e=>{try{e.disconnect()}catch(t){}}),this.observers.clear(),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null);for(const e of Array.from(this.records.values()))e.timer&&(clearTimeout(e.timer),e.timer=null);this.records.clear(),this.eventListeners.forEach(({target:e,event:t,handler:i})=>{e.removeEventListener(t,i)}),this.eventListeners=[],this.boundHandleSpa&&(this.emitter.off(O,this.boundHandleSpa),this.boundHandleSpa=null),this.boundHandleIntersection=null,this.boundHandleMutation=null,this.boundHandleVisibility=null,this.boundHandleReady=null,this.globalConfig={...rt},this.log=function(){},this.isInitialized=!1}};ut.NAME="exposure";let lt=ut;const ht=[],dt={debug:!1,sourceToken:"",apiHost:"",autoCapture:!0,isSinglePageApp:!1,crossSubdomainCookie:!0,enableAB:!1,abRefreshInterval:6e5,enableClickTrack:!1,enableExposureTrack:!1,batchSend:!1,enableErrorTrack:!1,enableCrashTrack:!1,optOutCapturing:!1,persistOptOut:!1};return new class{constructor(){this.__innerInited=!1,this.inited=!1,this.config={},this.eventEmitter=new e,this.pluginCore={},this.commonProps={},this.spaCleanup=null,this._optOutCapturing=!1,this.consentStorage=new we(!1),this._setupAfterConsentDone=!1,this._postConsentInit=!1,S.instance=this}init(e,t={}){return this.inited?this:(S.instance=this,t.sourceToken=e,this.mergeConfig(t),this.consentStorage=new we(!0===this.config.persistOptOut),this._optOutCapturing?this.consentStorage.write(!0):!0===this.config.optOutCapturing?(this._optOutCapturing=!0,this.consentStorage.write(!0)):!0===this.consentStorage.read()&&(this._optOutCapturing=!0),this.eventEmitter.emit("init-param",this.config),this.__innerInited=!0,this._optOutCapturing?(Xe.captureAndStore(this.config.debug),this.eventEmitter.emit(y),this.inited=!0,this):(this.__setupAfterConsent(),this.eventEmitter.emit(y),this.inited=!0,this))}__setupAfterConsent(){if(this._setupAfterConsentDone)return;this._setupAfterConsentDone=!0;const e=this.config;ht.length=0,N.init(e.crossSubdomainCookie),e.anonId&&N.setAnonId(e.anonId),function(){if(window._swFailedRequestsInitialized)return;window._swFailedRequestsInitialized=!0;const e=S.instance;e&&"function"==typeof e.hasOptedOutCapturing&&e.hasOptedOutCapturing()||e&&!0===e._postConsentInit||function(){const e=te.getAll();if(0!==e.length)for(let t=0,i=e.length;t<i;t+=10){const i=e.slice(t,t+10),n=[],s=[];i.forEach(e=>{Array.isArray(e.data)?n.push(...e.data):n.push(e.data),s.push(e.id)});const r=i[i.length-1],o=r.url,a=r.headers;L({url:o,method:"POST",data:n,headers:a,callback:e=>{200!==e.statusCode?(console.error("Failed to send batch stored requests:",e),P(e.statusCode)||s.forEach(e=>{te.dequeue(e)})):s.forEach(e=>{te.dequeue(e)})}})}}()}(),ht.push(Xe),e.autoCapture&&this.autoTrack(),e.enableAB&&ht.push(Be),e.enableClickTrack&&ht.push(De),e.enableCrashTrack&&e.debug&&console.warn("[SensorsWave] enableCrashTrack 仅在 app 宿主环境生效,当前 Web 环境不采集 crash"),e.enableErrorTrack&&ht.push(tt),e.enableExposureTrack&&ht.push(lt),this.pluginCore=new ye({plugins:ht,emitter:this.eventEmitter,config:e,sdk:this}),this.spaCleanup=function(e){let t=location.href;const i=window.history.pushState,n=window.history.replaceState,r=function(){e(t),t=location.href};return s(window.history.pushState)&&(window.history.pushState=function(...n){i.apply(window.history,n),e(t),t=location.href}),s(window.history.replaceState)&&(window.history.replaceState=function(...i){n.apply(window.history,i),e(t),t=location.href}),window.addEventListener("popstate",r),function(){s(window.history.pushState)&&(window.history.pushState=i),s(window.history.replaceState)&&(window.history.replaceState=n),window.removeEventListener("popstate",r)}}(e=>{this.eventEmitter.emit(O,e)})}mergeConfig(e){this.config={...dt,...e}}__canCapture(){return this.inited&&!this._optOutCapturing}track(e){this.__canCapture()&&function(e,t){if(!se())return;if(!re())return;const i={...e};i.time||(i.time=Date.now()),i.login_id||(i.login_id=N.getLoginId()),i.anon_id||(i.anon_id=N.getAnonId()),i.trace_id||(i.trace_id=N.getTraceId()),i.properties={...ee(),...ge(N.getCommonProps()),...i.properties};const n=ue(t),s=he(t),r=!1!==t.batchSend&&ae();if(!r)return de(n,{data:[i],headers:s});te.enqueue(n,[i],s),r.add()}(e,this.config)}trackEvent(e,t){this.__canCapture()&&me({event:e,properties:t},this.config)}trackException(e,t){if(!this.__canCapture())return;const i={...t||{},...e instanceof Error?Je(e):Ze(String(e))};me({event:T,properties:i},this.config)}addExposureView(e,t){if(!this.__canCapture())return;const i=this.pluginCore.getPlugin(lt.NAME);i?i.addExposureView(e,t):console.warn("[SensorsWave] addExposureView 需在 init 时配置 enableExposureTrack: true")}removeExposureView(e){if(!this.__canCapture())return;const t=this.pluginCore.getPlugin(lt.NAME);t&&t.removeExposureView(e)}autoTrack(){ht.push(Ae,Ne,Te)}profileSet(e){this.__canCapture()&&Ee({userProps:{$set:e},opts:this.config})}profileSetOnce(e){this.__canCapture()&&Ee({userProps:{$set_once:e},opts:this.config})}profileIncrement(e){this.__canCapture()&&Ee({userProps:{$increment:e},opts:this.config})}profileAppend(e){this.__canCapture()&&Ee({userProps:{$append:e},opts:this.config})}profileUnion(e){this.__canCapture()&&Ee({userProps:{$union:e},opts:this.config})}profileUnset(e){if(!this.__canCapture())return;const t={};r(e)?e.forEach(function(e){t[e]=null}):t[e]=null,Ee({userProps:{$unset:t},opts:this.config})}profileDelete(){this.__canCapture()&&Ee({userProps:{$delete:!0},opts:this.config})}registerCommonProperties(e){if(!n(e))return console.warn("Commmon Properties must be an object!");this.commonProps=e,N.setCommonProps(this.commonProps)}clearCommonProperties(e){if(!r(e))return console.warn("Commmon Properties to be cleared must be an array!");e.forEach(e=>{delete this.commonProps[e]}),N.setCommonProps(this.commonProps)}identify(e){this.__canCapture()&&(N.setLoginId(e),function(e){if(!se())return;if(!re())return;const t=N.getLoginId(),i=N.getAnonId();if(!t||!i)return;const n={time:Date.now(),trace_id:N.getTraceId(),event:"$Identify",login_id:t,anon_id:i,properties:fe()},s=ue(e),r=he(e),o=ae();if(!o)return de(s,{data:[n],headers:r});te.enqueue(s,[n],r),o.add()}(this.config))}setLoginId(e){this.__canCapture()&&N.setLoginId(e)}getAnonId(){return this.__canCapture()?N.getAnonId():""}setAnonId(e){this.__canCapture()&&N.setAnonId(e)}getLoginId(){return this.__canCapture()?N.getLoginId():""}reset(e=!1){this.__canCapture()&&(N.clearLoginId(),e&&N.resetAnonId())}checkFeatureGate(e){if(!this.__canCapture())return Promise.resolve(!1);const t=this.pluginCore.getPlugin(Be.NAME);return this.config.enableAB&&t?t.checkFeatureGate(e):Promise.reject("AB is disabled")}getExperiment(e){if(!this.__canCapture())return Promise.resolve({});const t=this.pluginCore.getPlugin(Be.NAME);return this.config.enableAB&&t?t.getExperiment(e):Promise.reject("AB is disabled")}getFeatureConfig(e){if(!this.__canCapture())return Promise.resolve({});const t=this.pluginCore.getPlugin(Be.NAME);return this.config.enableAB&&t?t.getFeatureConfig(e):Promise.reject("AB is disabled")}optOutCapturing(){this._optOutCapturing=!0,this.consentStorage.write(!0),oe&&oe.pause()}optInCapturing(){if(this._optOutCapturing=!1,this.consentStorage.write(!1),oe&&oe.resume(),this.inited&&!this._setupAfterConsentDone){this._postConsentInit=!0;try{this.__setupAfterConsent(),this.eventEmitter.emit(y)}finally{this._postConsentInit=!1}}}hasOptedOutCapturing(){return this._optOutCapturing}destroy(){oe&&(oe.destroy(),oe=null),"undefined"!=typeof window&&(window._swFailedRequestsInitialized=!1),this.inited=!1,this.__innerInited=!1,this.spaCleanup&&"function"==typeof this.spaCleanup&&(this.spaCleanup(),this.spaCleanup=null),this.pluginCore&&"function"==typeof this.pluginCore.destroy&&this.pluginCore.destroy(),this.pluginCore={},this.eventEmitter&&this.eventEmitter.removeAllListeners(),this.consentStorage=new we(!0===this.config?.persistOptOut),this._optOutCapturing=!1,this._setupAfterConsentDone=!1,this._postConsentInit=!1,S.instance===this&&(S.instance=null)}}});
|
package/dist/types/Api.d.ts
CHANGED
|
@@ -36,6 +36,21 @@ export type SensorsWaveABRequestData = {
|
|
|
36
36
|
sdk: string;
|
|
37
37
|
sdk_version: string;
|
|
38
38
|
};
|
|
39
|
+
export type ExposureConfig = {
|
|
40
|
+
visibleRatio?: number;
|
|
41
|
+
stayDuration?: number;
|
|
42
|
+
repeated?: boolean;
|
|
43
|
+
};
|
|
44
|
+
export type ExposureListener = {
|
|
45
|
+
shouldExpose?: (ele: HTMLElement, props: Record<string, any>) => boolean | void;
|
|
46
|
+
didExpose?: (ele: HTMLElement, props: Record<string, any>) => void;
|
|
47
|
+
};
|
|
48
|
+
export type ExposureOption = {
|
|
49
|
+
eventName: string;
|
|
50
|
+
config?: ExposureConfig;
|
|
51
|
+
properties?: Record<string, any>;
|
|
52
|
+
listener?: ExposureListener;
|
|
53
|
+
};
|
|
39
54
|
export interface SensorsWaveConfig {
|
|
40
55
|
debug?: boolean;
|
|
41
56
|
apiHost?: string;
|
|
@@ -46,6 +61,8 @@ export interface SensorsWaveConfig {
|
|
|
46
61
|
abRefreshInterval?: number;
|
|
47
62
|
enableClickTrack?: boolean;
|
|
48
63
|
batchSend?: boolean;
|
|
64
|
+
enableExposureTrack?: boolean;
|
|
65
|
+
exposureConfig?: ExposureConfig;
|
|
49
66
|
enableErrorTrack?: boolean;
|
|
50
67
|
enableCrashTrack?: boolean;
|
|
51
68
|
anonId?: string;
|
|
@@ -57,6 +74,8 @@ interface SensorsWaveInterface {
|
|
|
57
74
|
trackEvent(e: string, p?: Object): void;
|
|
58
75
|
track(e: AdvanceEvent): void;
|
|
59
76
|
trackException(error: Error | string, properties?: Record<string, any>): void;
|
|
77
|
+
addExposureView(ele: HTMLElement, option: ExposureOption): void;
|
|
78
|
+
removeExposureView(ele: HTMLElement): void;
|
|
60
79
|
profileSet(p: Object): void;
|
|
61
80
|
profileSetOnce(p: Object): void;
|
|
62
81
|
profileIncrement(p: Object): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SensorsWaveConfig, SensorsWaveSendEvent } from '../types/Api';
|
|
1
|
+
import { SensorsWaveConfig, SensorsWaveSendEvent, ExposureOption } from '../types/Api';
|
|
2
2
|
type CommmonProps = {
|
|
3
3
|
[key: string]: string | Function;
|
|
4
4
|
};
|
|
@@ -22,6 +22,8 @@ declare class SensorsWave {
|
|
|
22
22
|
track(e: SensorsWaveSendEvent): void;
|
|
23
23
|
trackEvent(event: string, properties: Record<string, any>): void;
|
|
24
24
|
trackException(error: Error | string, properties?: Record<string, any>): void;
|
|
25
|
+
addExposureView(ele: HTMLElement, option: ExposureOption): void;
|
|
26
|
+
removeExposureView(ele: HTMLElement): void;
|
|
25
27
|
private autoTrack;
|
|
26
28
|
profileSet(p: Object): void;
|
|
27
29
|
profileSetOnce(p: Object): void;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { EventEmitter } from '../../../core';
|
|
2
|
+
import { ExposureOption } from '../../types/Api';
|
|
3
|
+
export declare class Exposure {
|
|
4
|
+
static NAME: string;
|
|
5
|
+
private emitter;
|
|
6
|
+
private config;
|
|
7
|
+
private sdk;
|
|
8
|
+
private isInitialized;
|
|
9
|
+
private observers;
|
|
10
|
+
private records;
|
|
11
|
+
private mutationObserver;
|
|
12
|
+
private boundHandleIntersection;
|
|
13
|
+
private boundHandleMutation;
|
|
14
|
+
private boundHandleVisibility;
|
|
15
|
+
private boundHandleReady;
|
|
16
|
+
private boundHandleSpa;
|
|
17
|
+
private eventListeners;
|
|
18
|
+
private globalConfig;
|
|
19
|
+
private log;
|
|
20
|
+
constructor({ emitter, config, sdk }: {
|
|
21
|
+
emitter: EventEmitter;
|
|
22
|
+
config: any;
|
|
23
|
+
sdk: any;
|
|
24
|
+
});
|
|
25
|
+
init(): void;
|
|
26
|
+
addExposureView(ele: HTMLElement, option: ExposureOption): void;
|
|
27
|
+
removeExposureView(ele: HTMLElement): void;
|
|
28
|
+
private scanDocument;
|
|
29
|
+
private addOrUpdateWatchEle;
|
|
30
|
+
private getIntersection;
|
|
31
|
+
private removeWatchEle;
|
|
32
|
+
private handleIntersection;
|
|
33
|
+
private fireExposure;
|
|
34
|
+
private observeMutations;
|
|
35
|
+
private handleMutation;
|
|
36
|
+
private handleAttrChange;
|
|
37
|
+
private handleSpaSwitch;
|
|
38
|
+
private stop;
|
|
39
|
+
private start;
|
|
40
|
+
private handleVisibility;
|
|
41
|
+
destroy(): void;
|
|
42
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const EXPOSURE_ATTR_PREFIX = "data-sw-exposure";
|
|
2
|
+
export declare const EXPOSURE_ATTR_EVENT_NAME = "data-sw-exposure-event-name";
|
|
3
|
+
export declare const EXPOSURE_ATTR_OPTION = "data-sw-exposure-option";
|
|
4
|
+
export declare const EXPOSURE_ATTR_CONFIG_PREFIX = "data-sw-exposure-config-";
|
|
5
|
+
export declare const EXPOSURE_ATTR_PROPERTY_PREFIX = "data-sw-exposure-property-";
|
|
6
|
+
export declare const EXPOSURE_SCAN_SELECTOR = "[data-sw-exposure-event-name]";
|
|
7
|
+
export declare const DEFAULT_EXPOSURE_CONFIG: ExposureResolvedConfig;
|
|
8
|
+
export type ExposureResolvedConfig = {
|
|
9
|
+
visibleRatio: number;
|
|
10
|
+
stayDuration: number;
|
|
11
|
+
repeated: boolean;
|
|
12
|
+
};
|
|
13
|
+
export type ExposureEleAttrs = {
|
|
14
|
+
eventName: string;
|
|
15
|
+
config: Partial<ExposureResolvedConfig>;
|
|
16
|
+
properties: Record<string, any>;
|
|
17
|
+
};
|
|
18
|
+
export declare function isExposureSupported(): boolean;
|
|
19
|
+
export declare function formatExposureConfig(input: unknown, log?: (...args: any[]) => void): Partial<ExposureResolvedConfig>;
|
|
20
|
+
export declare function resolveExposureConfig(...sources: Array<Partial<ExposureResolvedConfig> | undefined>): ExposureResolvedConfig;
|
|
21
|
+
export declare function parseExposureEleAttrs(ele: Element): ExposureEleAttrs;
|
|
22
|
+
export declare function createExposureLogger(debug: boolean): (...args: any[]) => void;
|