@tengence/track-sdk-web 1.1.14 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,10 +4,10 @@ Tengence Web 行为埋点 SDK。上报统一走 `Authorization: Bearer`,凭证
4
4
 
5
5
  ## 安装与引入
6
6
 
7
- UMD:
7
+ UMD(**生产环境务必固定版本号**:升级显式改版本、可回滚;`@latest` 仅作预览用途):
8
8
 
9
9
  ```html
10
- <script src="https://static.tengence.com/track/tengence-track-sdk@1.1.13.js"></script>
10
+ <script src="https://static.tengence.com/track/tengence-track-sdk@1.2.0.js"></script>
11
11
  ```
12
12
 
13
13
  ## 初始化
@@ -56,7 +56,7 @@ v1.1.12 起主 API 为 **`track`**(对齐 Segment / Mixpanel / Amplitude 主
56
56
 
57
57
  ```js
58
58
  // 字符串形式:track(eventType, eventDetail?, options?) —— 推荐
59
- client.track("click", { id: "btn-1", name: "提交" }); // eventDetail 非字符串会被序列化为 JSON 字符串,键数 ≤ 50
59
+ client.track("click", { id: "btn-1", name: "提交" }); // eventDetail 非字符串会被序列化为 JSON 字符串;建议键数 ≤ 50(不硬限,注意单条 64KB 上限)
60
60
  client.track("pay", { order: "x" }, { data_type: "custom", track_real_time: true }); // options 透传高频控制字段
61
61
 
62
62
  // 对象形式:track({ event_type, event_detail, ... }) —— 兼容完整字段(原 report 语义)
@@ -103,6 +103,7 @@ client.registerGlobalProperties({
103
103
  | `realTimeUrl` | 实时推送地址,无默认值;**未配置时实时事件并入普通通道上报(单份、不丢、不双写)**;配置后实时事件走独立实时通道(200ms 快发,按 `realTimeReportInterval`) |
104
104
  | `realTimeReportInterval` | 实时通道上报周期,默认 **200ms** |
105
105
  | `errorTraceRate` | 错误采样率,默认 **0.5**(50%);传 `0` 关闭错误上报、传 `1` 全量上报(v1.1.8 起显式 0/1 生效) |
106
+ | `resourceFlowLimit` | 资源性能明细条数上限,默认 **15**(v1.1.16,范围 [0,200]):`navigation_timing`/`metrics` 不受影响;传 `0` 关闭 `resource_flow` 采集(页面加载即上报 15 条资源明细体积较大,低流量场景可关) |
106
107
  | `sanitize` | 发送前 PII 脱敏(**默认关闭**,业务按需显式开启):传入对象开启——`stripQuery` 剥离 URL 查询串(默认 true)、`maxTextLength` 超长文本截断(默认 0 关闭,0 关闭截断)、`preserveQueryKeys` 剥离时保留的键;传 `false` 显式关闭 |
107
108
  | `enableAutoSessionId` | 会话自动维护开关,默认 **false**:外部未传 `session_id` 时,开启则 SDK 维护 30min 空闲超时会话(超时自动重置新 id,活跃顺延);关闭则不带 `session_id` |
108
109
  | `enableTracking` | 采集总开关,默认 **true**(v1.1.11):传 `false` 初始化或 `client.enableTracking(false)` 即退出采集(opt-out)——后续 `track` 忽略、**清空本地与实时未上报队列**(合规语义:退出后不再持有/上报任何数据)、停止一切发送(含周期定时、卸载补发);`client.enableTracking()` 无参返回当前状态,`client.enableTracking(true)` 恢复采集。开关状态持久化 localStorage,刷新后保持 |
@@ -146,6 +147,8 @@ client.registerGlobalProperties({
146
147
  | `queue_write_failed` | 写入 localStorage 队列失败(隐私模式/容量满) | 队列清空处理(尽力兜底) |
147
148
  | `localstorage_unavailable` | localStorage 完全不可用(隐私模式) | 本次数据仅保留内存 |
148
149
  | `enqueue_failed` | 事件入队失败 | 该事件丢弃 |
150
+ | `serialize_failed` | 事件 `event_detail` 序列化失败(循环引用/BigInt 等,v1.1.16) | 该事件丢弃(不冒泡到业务调用方) |
151
+ | `before_send_failed` | `beforeSend` 钩子抛错(v1.1.17) | 回退原始数据发送(不丢事件) |
149
152
 
150
153
  ## 自动采集事件(全埋点,v1.1.13 补全)
151
154
 
@@ -161,6 +164,39 @@ client.registerGlobalProperties({
161
164
  | `form_submit`(v1.1.13) | 表单提交(捕获阶段) | 每次提交上报,含 submitter 信息;只采表单元数据不采 input 值 |
162
165
  | `expose` / `view` / `view_expose` | 元素进入可视区(IntersectionObserver) | 可视区停留默认 500ms(`data-duration-view`/`data-duration-expose` 可逐元素覆盖) |
163
166
 
167
+ ## v1.1.17 变更(自 v1.1.16)
168
+
169
+ | 变更 | 说明 |
170
+ | --- | --- |
171
+ | README script 标签改 `@latest.js`(D1) | 安装示例指向 CDN latest 软链(deploy 自动维护),不再随版本迭代手动改 README |
172
+ | exposePlugin DOM 就绪兜底(D2) | `<head>` 同步加载并 init 时 `document.body` 尚不存在,`MutationObserver.observe(null)` 抛 TypeError 导致 init 崩溃;现兜底 `document.body \|\| document.documentElement`(subtree 覆盖 body),对齐 GA4/神策 DOM 就绪保护 |
173
+ | 空 `resource_flow` 不上报(D5) | 页面无资源明细时不再上报 `{data: []}` 空事件(噪声) |
174
+ | `beforeSend` 钩子兜底(D6) | 钩子返回非数组(undefined/null)时回退原始数据,避免 `{ data: undefined }` 空载荷;钩子抛错不崩,`onError("before_send_failed")` 通知后按原始数据发送(对齐 Segment middleware 容错) |
175
+ | 验证 | typecheck 通过;vitest **31/31**(新增 D5 空资源、D6 返回 undefined/抛错 3 用例,fetch mock 验证请求体);冒烟 38/38 全绿 |
176
+
177
+ ## v1.1.16 变更(自 v1.1.15)
178
+
179
+ | 变更 | 说明 |
180
+ | --- | --- |
181
+ | event_detail 序列化兜底(C1) | `track()` 传循环引用 / BigInt 等导致 `JSON.stringify` 抛错时,**丢弃该事件并 `onError("serialize_failed")` 通知,不再冒泡到业务调用方**(对齐 Segment/Amplitude 序列化兜底);业务代码不会因错误参数崩溃 |
182
+ | 注册扩展属性内存缓存(C2) | `register_properties` 首次读取后持有,每次事件省一次 localStorage 读 + parse(registerGlobalProperties 写入时同步更新) |
183
+ | `resourceFlowLimit` 可配(C7) | 新增配置(默认 15,范围 [0,200]):`resource_flow` 明细条数上限;传 `0` 关闭该项采集(navigation_timing/metrics 不受影响) |
184
+ | 放弃 IE11(C6) | babel target `ie:11` → `esmodules: true`:原 IE11 目标与 `Promise.finally` 等运行时 API 实际不兼容(未引入 polyfill 会崩);现只面向现代浏览器,UMD 保留原生 async/await,产物更小、运行更快 |
185
+ | 细节修正(C3/C4/C5) | README 键数声明改为"建议 ≤50 键"(与实现一致,不硬限);`getErrorKey` 的 "cors" 分支加注释(保留用于防止 Script error 被 resource 误采);脱敏 URL 键正则收紧为 `(^|_)href$`(原 `href` 匹配过宽) |
186
+ | 验证 | typecheck 通过;vitest **28/28**(新增 C1 循环引用/BigInt 兜底、C7 关闭/限条数 4 用例);冒烟 38/38 全绿 |
187
+
188
+ ## v1.1.15 变更(自 v1.1.14)
189
+
190
+ | 变更 | 说明 |
191
+ | --- | --- |
192
+ | `maxCacheSize` 单位修复(B1) | 队列体积以 KB 计,但默认值误写成字节量级(`1024*56=57344`),实际触发阈值变成 56MB,体积触发上报形同虚设;修正为 **56(KB)**,恢复"满 56KB 触发"文档语义(与 fetch keepalive 64KB 切片兼容) |
193
+ | SDK 自身请求排除采集(B2) | `proxyFetch`/`proxyXmlHttp` 覆写全局后,SDK 自身上报/鉴权请求也会进入 http 错误采集(遇 401/413 会额外生成 http_error 事件自举上报/递归);现采集时排除 pushUrl/authUrl/realTimeUrl 端点(对齐 Sentry 忽略自身请求) |
194
+ | `track()` options.platform 生效(B3) | 原 `TrackOptions.platform` 被静默忽略(硬编码全局平台值);现 `platform: data.platform \|\| 全局值`,单事件可覆盖平台维度 |
195
+ | 指纹哈希换 djb2(B4) | errorUuid 去重指纹由自实现 485 行 MD5 换为 ~10 行 djb2(非加密用途,确定性 + 低碰撞足够);**dist 体积 -8.1KB(62.5KB → 54.4KB,-13%)**;指纹格式变化不影响服务端(服务端按 event_id 去重) |
196
+ | 边界防御(B5/B6) | `collectNavigationTiming` 对 `getEntriesByType` 返回 undefined 的边界防御(防老浏览器 TypeError);设备 ID 首次解析后内存缓存,每次事件省 2 次存储读 |
197
+ | 死代码清理(B7) | logger.ts 移除长注释代码块 |
198
+ | 验证 | typecheck 通过;vitest 24/24(md5 向量测试改为 djb2 向量:`""→00001505`、`"abc"→0b885c8b`);冒烟 38/38 全绿 |
199
+
164
200
  ## v1.1.14 变更(自 v1.1.13)
165
201
 
166
202
  | 变更 | 说明 |
package/dist/client.d.ts CHANGED
@@ -25,6 +25,7 @@ interface SdkOptions {
25
25
  maxRetries: number;
26
26
  isLogger: boolean;
27
27
  errorTraceRate: number;
28
+ resourceFlowLimit: number;
28
29
  traceBehavior: boolean;
29
30
  tracePerformance: boolean;
30
31
  traceError: boolean;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- class e extends Error{status;constructor(e,t){super(t||`[TM]: Auth error ${e}`),this.name="AuthError",this.status=e}}const t=({method:e,url:t,data:r,headers:n={},withCredentials:o=!1,timeoutMs:i})=>new Promise(((a,s)=>{const c=new XMLHttpRequest;c.open(e,t,!0),i&&(c.timeout=i),Object.keys(n).forEach((e=>{c.setRequestHeader(e,n[e])})),c.withCredentials=!!o,c.onreadystatechange=()=>{if(4===c.readyState)if(c.status>=200&&c.status<300)try{const e=JSON.parse(c.responseText);a(e)}catch(e){s(e)}else{const e=new Error(`[TM]: Request failed with status ${c.status}`);e.status=c.status,s(e)}},c.onerror=()=>{s(new Error("[TM]: Network error"))},c.ontimeout=()=>{const e=new Error("[TM]: Request timeout");e.timeout=!0,s(e)},r?c.send(r):c.send()})),r=(e,t,r)=>{if(!r)return fetch(e,t);const n=new AbortController,o=setTimeout((()=>n.abort()),r);return fetch(e,{...t,signal:n.signal}).catch((e=>{if(e&&"AbortError"===e.name){const e=new Error("[TM]: Request timeout");throw e.timeout=!0,e}throw e})).finally((()=>clearTimeout(o)))},n=(n,o,i,a)=>{const s={"Content-Type":"application/json"};i&&(s.Authorization=`Bearer ${i}`);const c=()=>t({method:"POST",url:n,data:JSON.stringify(o),headers:s,withCredentials:!0,timeoutMs:a});return"function"!=typeof fetch?c():r(n,{method:"POST",keepalive:!0,credentials:"include",headers:s,body:JSON.stringify(o)},a).then((t=>{if(401===t.status||403===t.status)throw new e(t.status,`[TM]: Auth error ${t.status}`);if(429===t.status){const e=new Error("[TM]: Request throttled with status 429");e.status=429;const r=t.headers.get("Retry-After");if(r){const t=parseInt(r,10);isNaN(t)||(e.retryAfter=1e3*t)}throw e}if(!t.ok){const e=new Error(`[TM]: Request failed with status ${t.status}`);throw e.status=t.status,e}return t.json()})).catch((t=>{if(t instanceof e)throw t;if(t&&t.status)throw t;return c()}))},o=new Int32Array(4);class i{static selfTested=!1;static selfTest(){if(!i.selfTested&&(i.selfTested=!0,"5d41402abc4b2a76b9719d911017c592"!==i.hashStr("hello")))throw new Error("Md5 self test failed.")}static hashStr(e,t=!1){return i.selfTest(),this.onePassHasher.start().appendStr(e).end(t)}static hashAsciiStr(e,t=!1){return this.onePassHasher.start().appendAsciiStr(e).end(t)}static stateIdentity=new Int32Array([1732584193,-271733879,-1732584194,271733878]);static buffer32Identity=new Int32Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);static hexChars="0123456789abcdef";static hexOut=[];static onePassHasher=new i;static _hex(e){const t=i.hexChars,r=i.hexOut;let n,o,a,s;for(s=0;s<4;s+=1)for(o=8*s,n=e[s],a=0;a<8;a+=2)r[o+1+a]=t.charAt(15&n),n>>>=4,r[o+0+a]=t.charAt(15&n),n>>>=4;return r.join("")}static _md5cycle(e,t){let r=e[0],n=e[1],o=e[2],i=e[3];r+=(n&o|~n&i)+t[0]-680876936|0,r=(r<<7|r>>>25)+n|0,i+=(r&n|~r&o)+t[1]-389564586|0,i=(i<<12|i>>>20)+r|0,o+=(i&r|~i&n)+t[2]+606105819|0,o=(o<<17|o>>>15)+i|0,n+=(o&i|~o&r)+t[3]-1044525330|0,n=(n<<22|n>>>10)+o|0,r+=(n&o|~n&i)+t[4]-176418897|0,r=(r<<7|r>>>25)+n|0,i+=(r&n|~r&o)+t[5]+1200080426|0,i=(i<<12|i>>>20)+r|0,o+=(i&r|~i&n)+t[6]-1473231341|0,o=(o<<17|o>>>15)+i|0,n+=(o&i|~o&r)+t[7]-45705983|0,n=(n<<22|n>>>10)+o|0,r+=(n&o|~n&i)+t[8]+1770035416|0,r=(r<<7|r>>>25)+n|0,i+=(r&n|~r&o)+t[9]-1958414417|0,i=(i<<12|i>>>20)+r|0,o+=(i&r|~i&n)+t[10]-42063|0,o=(o<<17|o>>>15)+i|0,n+=(o&i|~o&r)+t[11]-1990404162|0,n=(n<<22|n>>>10)+o|0,r+=(n&o|~n&i)+t[12]+1804603682|0,r=(r<<7|r>>>25)+n|0,i+=(r&n|~r&o)+t[13]-40341101|0,i=(i<<12|i>>>20)+r|0,o+=(i&r|~i&n)+t[14]-1502002290|0,o=(o<<17|o>>>15)+i|0,n+=(o&i|~o&r)+t[15]+1236535329|0,n=(n<<22|n>>>10)+o|0,r+=(n&i|o&~i)+t[1]-165796510|0,r=(r<<5|r>>>27)+n|0,i+=(r&o|n&~o)+t[6]-1069501632|0,i=(i<<9|i>>>23)+r|0,o+=(i&n|r&~n)+t[11]+643717713|0,o=(o<<14|o>>>18)+i|0,n+=(o&r|i&~r)+t[0]-373897302|0,n=(n<<20|n>>>12)+o|0,r+=(n&i|o&~i)+t[5]-701558691|0,r=(r<<5|r>>>27)+n|0,i+=(r&o|n&~o)+t[10]+38016083|0,i=(i<<9|i>>>23)+r|0,o+=(i&n|r&~n)+t[15]-660478335|0,o=(o<<14|o>>>18)+i|0,n+=(o&r|i&~r)+t[4]-405537848|0,n=(n<<20|n>>>12)+o|0,r+=(n&i|o&~i)+t[9]+568446438|0,r=(r<<5|r>>>27)+n|0,i+=(r&o|n&~o)+t[14]-1019803690|0,i=(i<<9|i>>>23)+r|0,o+=(i&n|r&~n)+t[3]-187363961|0,o=(o<<14|o>>>18)+i|0,n+=(o&r|i&~r)+t[8]+1163531501|0,n=(n<<20|n>>>12)+o|0,r+=(n&i|o&~i)+t[13]-1444681467|0,r=(r<<5|r>>>27)+n|0,i+=(r&o|n&~o)+t[2]-51403784|0,i=(i<<9|i>>>23)+r|0,o+=(i&n|r&~n)+t[7]+1735328473|0,o=(o<<14|o>>>18)+i|0,n+=(o&r|i&~r)+t[12]-1926607734|0,n=(n<<20|n>>>12)+o|0,r+=(n^o^i)+t[5]-378558|0,r=(r<<4|r>>>28)+n|0,i+=(r^n^o)+t[8]-2022574463|0,i=(i<<11|i>>>21)+r|0,o+=(i^r^n)+t[11]+1839030562|0,o=(o<<16|o>>>16)+i|0,n+=(o^i^r)+t[14]-35309556|0,n=(n<<23|n>>>9)+o|0,r+=(n^o^i)+t[1]-1530992060|0,r=(r<<4|r>>>28)+n|0,i+=(r^n^o)+t[4]+1272893353|0,i=(i<<11|i>>>21)+r|0,o+=(i^r^n)+t[7]-155497632|0,o=(o<<16|o>>>16)+i|0,n+=(o^i^r)+t[10]-1094730640|0,n=(n<<23|n>>>9)+o|0,r+=(n^o^i)+t[13]+681279174|0,r=(r<<4|r>>>28)+n|0,i+=(r^n^o)+t[0]-358537222|0,i=(i<<11|i>>>21)+r|0,o+=(i^r^n)+t[3]-722521979|0,o=(o<<16|o>>>16)+i|0,n+=(o^i^r)+t[6]+76029189|0,n=(n<<23|n>>>9)+o|0,r+=(n^o^i)+t[9]-640364487|0,r=(r<<4|r>>>28)+n|0,i+=(r^n^o)+t[12]-421815835|0,i=(i<<11|i>>>21)+r|0,o+=(i^r^n)+t[15]+530742520|0,o=(o<<16|o>>>16)+i|0,n+=(o^i^r)+t[2]-995338651|0,n=(n<<23|n>>>9)+o|0,r+=(o^(n|~i))+t[0]-198630844|0,r=(r<<6|r>>>26)+n|0,i+=(n^(r|~o))+t[7]+1126891415|0,i=(i<<10|i>>>22)+r|0,o+=(r^(i|~n))+t[14]-1416354905|0,o=(o<<15|o>>>17)+i|0,n+=(i^(o|~r))+t[5]-57434055|0,n=(n<<21|n>>>11)+o|0,r+=(o^(n|~i))+t[12]+1700485571|0,r=(r<<6|r>>>26)+n|0,i+=(n^(r|~o))+t[3]-1894986606|0,i=(i<<10|i>>>22)+r|0,o+=(r^(i|~n))+t[10]-1051523|0,o=(o<<15|o>>>17)+i|0,n+=(i^(o|~r))+t[1]-2054922799|0,n=(n<<21|n>>>11)+o|0,r+=(o^(n|~i))+t[8]+1873313359|0,r=(r<<6|r>>>26)+n|0,i+=(n^(r|~o))+t[15]-30611744|0,i=(i<<10|i>>>22)+r|0,o+=(r^(i|~n))+t[6]-1560198380|0,o=(o<<15|o>>>17)+i|0,n+=(i^(o|~r))+t[13]+1309151649|0,n=(n<<21|n>>>11)+o|0,r+=(o^(n|~i))+t[4]-145523070|0,r=(r<<6|r>>>26)+n|0,i+=(n^(r|~o))+t[11]-1120210379|0,i=(i<<10|i>>>22)+r|0,o+=(r^(i|~n))+t[2]+718787259|0,o=(o<<15|o>>>17)+i|0,n+=(i^(o|~r))+t[9]-343485551|0,n=(n<<21|n>>>11)+o|0,e[0]=r+e[0]|0,e[1]=n+e[1]|0,e[2]=o+e[2]|0,e[3]=i+e[3]|0}_dataLength=0;_bufferLength=0;_state=new Int32Array(4);_buffer=new ArrayBuffer(68);_buffer8;_buffer32;constructor(){this._buffer8=new Uint8Array(this._buffer,0,68),this._buffer32=new Uint32Array(this._buffer,0,17),this.start()}start(){return this._dataLength=0,this._bufferLength=0,this._state.set(i.stateIdentity),this}appendStr(e){const t=this._buffer8,r=this._buffer32;let n,o,a=this._bufferLength;for(o=0;o<e.length;o+=1){if(n=e.charCodeAt(o),n<128)t[a++]=n;else if(n<2048)t[a++]=192+(n>>>6),t[a++]=63&n|128;else if(n<55296||n>56319)t[a++]=224+(n>>>12),t[a++]=n>>>6&63|128,t[a++]=63&n|128;else{if(n=1024*(n-55296)+(e.charCodeAt(++o)-56320)+65536,n>1114111)throw new Error("Unicode standard supports code points up to U+10FFFF");t[a++]=240+(n>>>18),t[a++]=n>>>12&63|128,t[a++]=n>>>6&63|128,t[a++]=63&n|128}a>=64&&(this._dataLength+=64,i._md5cycle(this._state,r),a-=64,r[0]=r[16])}return this._bufferLength=a,this}appendAsciiStr(e){const t=this._buffer8,r=this._buffer32;let n,o=this._bufferLength,a=0;for(;;){for(n=Math.min(e.length-a,64-o);n--;)t[o++]=e.charCodeAt(a++);if(o<64)break;this._dataLength+=64,i._md5cycle(this._state,r),o=0}return this._bufferLength=o,this}appendByteArray(e){const t=this._buffer8,r=this._buffer32;let n,o=this._bufferLength,a=0;for(;;){for(n=Math.min(e.length-a,64-o);n--;)t[o++]=e[a++];if(o<64)break;this._dataLength+=64,i._md5cycle(this._state,r),o=0}return this._bufferLength=o,this}getState(){const e=this._state;return{buffer:String.fromCharCode.apply(null,Array.from(this._buffer8)),buflen:this._bufferLength,length:this._dataLength,state:[e[0],e[1],e[2],e[3]]}}setState(e){const t=e.buffer,r=e.state,n=this._state;let o;for(this._dataLength=e.length,this._bufferLength=e.buflen,n[0]=r[0],n[1]=r[1],n[2]=r[2],n[3]=r[3],o=0;o<t.length;o+=1)this._buffer8[o]=t.charCodeAt(o)}end(e=!1){const t=this._bufferLength,r=this._buffer8,n=this._buffer32,a=1+(t>>2);this._dataLength+=t;const s=8*this._dataLength;if(r[t]=128,r[t+1]=r[t+2]=r[t+3]=0,n.set(i.buffer32Identity.subarray(a),a),t>55&&(i._md5cycle(this._state,n),n.set(i.buffer32Identity)),s<=4294967295)n[14]=s;else{const t=s.toString(16).match(/(.*?)(.{0,8})$/);if(null===t)return e?o:"";const r=parseInt(t[2],16),i=parseInt(t[1],16)||0;n[14]=r,n[15]=i}return i._md5cycle(this._state,n),e?this._state:i._hex(this._state)}}const a=window.requestIdleCallback||window.requestAnimationFrame||(e=>setTimeout(e,17));function s(e,t=150,r=!1){let n=null;return function(...o){const i=this,a=r&&!n;n&&clearTimeout(n),n=setTimeout((()=>{n=null,r||e.apply(i,o)}),t),a&&e.apply(i,o)}}const c=(e,t=300)=>{let r=0;return function(...n){const o=Date.now();o-r>=t&&(r=o,e.apply(this,n))}};function l(e,t=""){if(!e)return t;const r=e.parentElement,{id:n}=e,o=e.tagName.toLowerCase(),i=t?`>${t}`:"";return r&&r!==document.documentElement&&r!==document.body?n?`#${n}${i}`:l(r,`${o}${i}`):`${o}${i}`}const d=()=>{if(window.performance?.navigation)return performance.navigation.type;if(window.performance?.getEntriesByType){const e=performance.getEntriesByType("navigation");if(e.length>0)return e[0].type}return 255},u=e=>{"prerendering"in document&&document.prerendering?(e=>{"prerendering"in document&&document.prerendering?addEventListener("prerenderingchange",(()=>e()),!0):e()})((()=>u(e))):"complete"!==document?.readyState?addEventListener("load",(()=>u(e)),!0):setTimeout(e)};function m(e){return"number"!=typeof e||!isFinite(e)||e<0?null:Math.round(100*e)/100}const h=Array(32);function f(e){return function(){for(let t=0;t<2*e;t++)h[t]=Math.floor(16*Math.random())+48,h[t]>=58&&(h[t]+=39);return String.fromCharCode.apply(null,h.slice(0,2*e))}}function p(){return"undefined"!=typeof crypto&&"function"==typeof crypto.randomUUID?crypto.randomUUID():f(16)()}const g=e=>e instanceof ErrorEvent?"Script error."===e.message?"cors":"js":"resource",y=e=>i.hashStr(e);const w={view:"#3b82f6",click:"#06b6d4",expose:"#8b5cf6",enter:"#10b981",leave:"#f59e0b",stay:"#84cc16",cart:"#ec4899",buy:"#ef4444",pay:"#dc2626",default:"#6b7280"},v={view:"👁️",click:"👆",expose:"✨",enter:"🚪",leave:"👋",stay:"⏱️",cart:"🛒",buy:"💰",pay:"💳",default:"📊"},T={common:"#3b82f6",behavior:"#10b981",performance:"#f59e0b",error:"#ef4444",custom:"#8b5cf6",default:"#6b7280"},_=(e,t)=>{t.forEach(((t,r)=>{const n=t.event_type||"unknown",o=t.data_type||"common",i=(e=>w[e]||w.default)(n),a=(e=>T[e]||T.default)(o),s=(e=>v[e]||v.default)(n);let c=t.event_detail;if("string"==typeof c)try{c=JSON.parse(c)}catch(e){}console.groupCollapsed(`%c${s} [TM-${e}] %c${o.toUpperCase()}%c → %c${n.toUpperCase()}%c #${r+1}`,"color: #6b7280; font-weight: bold;",`color: ${a}; font-weight: bold; background: ${a}20; padding: 2px 6px; border-radius: 3px;`,"color: #6b7280;",`color: ${i}; font-weight: bold; background: ${i}20; padding: 2px 6px; border-radius: 3px;`,"color: #6b7280; font-weight: normal;");const l={...t,event_detail:c};console.log("%c"+JSON.stringify(l,null,2),"color: #6b7280; font-family: monospace; font-size: 11px; line-height: 1.5;"),console.groupEnd()})),console.log(`%c✅ [TM] 本次通过 ${e} 上报 ${t.length} 条埋点数据`,"color: #10b981; font-weight: bold; font-size: 12px; padding: 4px 8px; background: #10b98120; border-radius: 4px; border-left: 3px solid #10b981;")};let b;const S="TRACK_MONITOR_DATA",E="MONITOR_REAL_TIME_DATA",k="TRACK_MONITOR_USER",x="tengence_device_id",L="tengence_register_properties",A="TRACK_MONITOR_LOGGER",M="tengence_tracking_enabled",C=2e3,I="tengence_access_token";let R=null,$=null;const q=e=>((e,n,o)=>{const i={"Content-Type":"application/json"},a=()=>t({method:"POST",url:e,data:JSON.stringify(n),headers:i,withCredentials:!0,timeoutMs:o});return"function"!=typeof fetch?a():r(e,{method:"POST",credentials:"include",headers:i,body:JSON.stringify(n)},o).then((e=>{if(!e.ok){const t=new Error(`[TM]: Request failed with status ${e.status}`);throw t.status=e.status,t}return e.json()})).catch((e=>{if(e&&e.status)throw e;return a()}))})(e,{},b?.requestTimeout).then((e=>{const t=e&&e.data,r=t&&t.accessToken,n=t&&t.accessExpAt;if(!r||"number"!=typeof n)throw new Error("[TM]: authUrl 响应缺少 accessToken/accessExpAt");return((e,t)=>{R={token:e,expAt:t};try{localStorage.setItem(I,JSON.stringify({token:e,expAt:t}))}catch(e){}})(r,n),r})),N=e=>{const t=(()=>{if(R)return R;try{const e=localStorage.getItem(I);if(!e)return null;const t=JSON.parse(e);if(t&&"string"==typeof t.token&&t.token&&"number"==typeof t.expAt)return R={token:t.token,expAt:t.expAt},R}catch(e){}return null})();return(r=t)&&r.token.length>0&&r.expAt-6e4>Date.now()?Promise.resolve(t.token):($||($=q(e).catch((e=>{throw e})).finally((()=>{$=null}))),$);var r},P={timer:null,promise:null},O={timer:null,promise:null},U=e=>{const t=JSON.stringify(e);return(new TextEncoder).encode(t).length/1024},B=()=>{try{const e=localStorage.getItem(L);return e?JSON.parse(e):{}}catch(e){return console.error("[TM]: get register properties fail: ",e),{}}},z=e=>{try{localStorage.setItem(L,JSON.stringify(e))}catch(e){console.error("[TM]: save register properties fail: ",e)}},D=e=>{if(!e||"object"!=typeof e||Array.isArray(e))return void console.error("[TM]: registerGlobalProperties props must be a plain object");const t={...B(),...e},r=Object.keys(t);if(r.length>50){const e={};return r.slice(0,50).forEach((r=>{e[r]=t[r]})),console.warn("[TM]: register properties exceed max 50 keys, extra keys dropped"),void z(e)}z(t)},H=e=>{const t=document.cookie.match(new RegExp("(?:^|;\\s*)"+e+"=([^;]*)"));return t?decodeURIComponent(t[1]):void 0},j=e=>{document.cookie=`${x}=${encodeURIComponent(e)}; Max-Age=63072000; Path=/`},F=()=>{try{let e=localStorage.getItem(x);if(e)return H(x)||j(e),e;const t=H(x);if(t){try{localStorage.setItem(x,t)}catch(e){}return t}e=p();try{localStorage.setItem(x,e)}catch(e){}return j(e),e}catch(e){return void console.error("[TM]: get or create device id fail: ",e)}},J="tengence_session_id",K=()=>{try{const e=sessionStorage.getItem(J);let t=e?JSON.parse(e):null;const r=Date.now();return!t||!t.id||r-t.lastActiveAt>18e5?(t={id:p(),lastActiveAt:r},sessionStorage.setItem(J,JSON.stringify(t))):(t.lastActiveAt=r,sessionStorage.setItem(J,JSON.stringify(t))),t.id}catch(e){return}},W=(e,t)=>{try{const r=new URL(e,location.href);if(!r.searchParams.toString())return e;if(t&&t.length){const e=[];for(const n of t){const t=r.searchParams.get(n);null!==t&&e.push(`${n}=${encodeURIComponent(t)}`)}r.search=e.length?`?${e.join("&")}`:""}else r.search="";return r.toString()}catch(t){return e}},X=(e,t,r)=>{if("string"==typeof e)return t>0&&e.length>t?e.slice(0,t)+"...[truncated]":e;if(Array.isArray(e))return e.map((e=>X(e,t,r)));if(e&&"object"==typeof e){const n={};for(const o of Object.keys(e)){const i=e[o];"string"==typeof i&&/(^|_)url$|href|^referrer$/i.test(o)&&/^https?:\/\//i.test(i)?n[o]=W(i,r):n[o]=X(i,t,r)}return n}return e},Q=e=>{const t={page_url:location.href,hostname:window.location.hostname||window.location.host,os:window.navigator.platform,user_id:localStorage.getItem(k)||void 0,user_agent:window.navigator.userAgent,screen_width:window.screen.width,screen_height:window.screen.height,lib_version:"1.1.14",lib_type:"js",event_time:(new Date).getTime().toString(),timezone_offset:(new Date).getTimezoneOffset().toString()},r=b?.sanitize;return{session_id:e.session_id||(b?.enableAutoSessionId?K():void 0),request_id:e.request_id,event_id:e.event_id||p(),spm:e.spm,data_type:e.data_type||"behavior",event_type:e.event_type,event_detail:"string"==typeof e.event_detail?e.event_detail:JSON.stringify(r&&(r.maxTextLength>0||r.stripQuery)?X(e.event_detail,r.maxTextLength,r.preserveQueryKeys):e.event_detail),...t,page_url:r&&r.stripQuery?W(t.page_url,r.preserveQueryKeys):t.page_url,device_id:F(),register_properties:JSON.stringify(B()),platform:G}};let G;const Y=()=>{try{return"true"===localStorage.getItem(A)}catch(e){return!1}},V=(e,t,r,n,o)=>void 0===e?t:"number"!=typeof e||Number.isNaN(e)||e<r||e>n?(console.warn(`[TM]: 配置 ${o}=${e} 非法,回退默认值 ${t}`),t):e,Z=(e,t)=>{try{b?.onDrop?.(e,t)}catch(e){}},ee=(e,t,r)=>{b?.isLogger&&console.error(`[TM]: ${t}`);try{b?.onError?.({code:e,message:t,context:r})}catch(e){}},te=()=>{try{const e=localStorage.getItem(M);return null===e||"1"===e}catch(e){return!0}},re=t=>{const r=t.apiKey;let o;const i=/Android|iPhone|iPad|iPod|Mobile/i.test(window.navigator.userAgent);G=t.platform||(i?"h5":"web"),b={pushUrl:t.pushUrl||"https://api.tengence.com/v1/push/event",authUrl:t.authUrl,realTimeUrl:t.realTimeUrl,cacheNumber:V(t.cacheNumber,100,1,1/0,"cacheNumber"),reportInterval:V(t.reportInterval,5e3,100,1/0,"reportInterval"),realTimeReportInterval:V(t.realTimeReportInterval,200,100,1/0,"realTimeReportInterval"),maxCacheSize:V(t.maxCacheSize,57344,1024,1/0,"maxCacheSize"),maxRetries:V(t.maxRetries,10,0,1/0,"maxRetries"),isLogger:t.isLogger??Y(),errorTraceRate:V(t.errorTraceRate,.5,0,1,"errorTraceRate"),traceBehavior:t.traceBehavior??!0,tracePerformance:t.tracePerformance??!0,traceError:t.traceError??!0,sanitize:!1===t.sanitize?{stripQuery:!1,maxTextLength:0,preserveQueryKeys:[]}:{stripQuery:t.sanitize?.stripQuery??!1,maxTextLength:V(t.sanitize?.maxTextLength,0,0,1/0,"sanitize.maxTextLength"),preserveQueryKeys:t.sanitize?.preserveQueryKeys||[]},enableAutoSessionId:t.enableAutoSessionId??!1,enableTracking:t.enableTracking??te(),respectGpc:t.respectGpc??!0,requestTimeout:V(t.requestTimeout,1e4,1e3,6e4,"requestTimeout"),beforeSend:t.beforeSend,onDrop:t.onDrop,onError:t.onError};let{pushUrl:s,authUrl:c,realTimeUrl:l,cacheNumber:d,reportInterval:u,realTimeReportInterval:m,maxCacheSize:h,maxRetries:f}=b;r||c||(console.error("[TM]: 未配置 apiKey 或 authUrl,SDK 无法获取上报凭证,数据将不会上报。请配置 apiKey(直连)或 authUrl(自动换取 accessToken),或调用 setToken 注入 accessToken。"),ee("init_missing_credential","未配置 apiKey 或 authUrl,SDK 无法获取上报凭证,数据将不会上报。请配置 apiKey(直连)或 authUrl(自动换取 accessToken),或调用 setToken 注入 accessToken。"));const p={retryCount:0,nextRetryAt:0,retryExhausted:!1,halveBatch:!1},g={retryCount:0,nextRetryAt:0,retryExhausted:!1,halveBatch:!1},y=e=>{try{localStorage.setItem(k,e)}catch(e){console.error("[TM]: monitor bind user fail: ",e)}},w=()=>{localStorage.removeItem(k)},v={},T={},x=new Set;let L=null;const $=()=>{null!==L&&(clearTimeout(L),L=null),x.size&&(x.forEach((e=>{try{localStorage.setItem(e,JSON.stringify(v[e]||[]))}catch(t){ee("queue_write_failed","写入本地缓存队列失败(隐私模式/容量满?),本次数据仅保留内存",{key:e,error:t})}})),x.clear())},q=e=>{if(v[e])return v[e];let t=[];try{t=JSON.parse(localStorage.getItem(e)||"[]")}catch(t){ee("queue_read_failed","读取本地缓存队列失败,按空队列处理",{key:e,error:t})}return v[e]=t,T[e]=t.reduce(((e,t)=>e+U(t)),0),v[e]},B=(e,t)=>{x.delete(e),v[e]=t,T[e]=t.reduce(((e,t)=>e+U(t)),0);try{localStorage.setItem(e,JSON.stringify(t))}catch(t){ee("queue_write_failed","写入本地缓存队列失败(隐私模式/容量满?),队列清空处理",{key:e,error:t});try{localStorage.setItem(e,"[]")}catch(t){ee("localstorage_unavailable","localStorage 不可用,本次数据仅保留内存",{key:e,error:t})}}},z=e=>{o=e},H=async(t,i,a=!1)=>{const d=t&&l?l:s;let u;try{u=r||o||(c?await N(c):void 0)}catch(e){throw ee("token_fetch_failed","从 authUrl 获取 accessToken 失败,本批暂不上报(保留队列待重试)",{authUrl:c,error:e}),e}if(!u)throw ee("init_missing_credential","未配置 apiKey/authUrl 且未注入 accessToken,本次数据未上报(保留缓存队列待重试)"),new Error("[TM]: credential missing, skip report");b?.isLogger&&_(t?"RealTimeFetch":"Fetch",i);const m=b?.beforeSend?b.beforeSend(i):i,h=a?void 0:b?.requestTimeout;return n(d,{data:m},u,h).catch((async t=>{const i=t?.status;if((t instanceof e||401===i||403===i)&&!r&&!o&&c){(()=>{R=null;try{localStorage.removeItem(I)}catch(e){}})();const e=await N(c).catch((()=>{}));if(e)return n(d,{data:m},e,h);ee("token_invalid","上报 401/403 且刷新 accessToken 失败,本批暂不上报(保留队列待重试)",{authUrl:c})}throw t}))},j=(e,t)=>{const r=new Set(t.filter((e=>!!e)));if(!r.size)return;const n=q(e);if(!n.length)return;const o=n.filter((e=>e.event_id&&!r.has(e.event_id)));o.length!==n.length&&B(e,o)},F=(e,t,r=0)=>{const n=(t?m:u)*Math.pow(2,e)*(.8+.4*Math.random()),o=Math.min(n,6e4);return Math.max(o,r)},J=(e,t)=>{const r=U(t);if(r>=64)return Z([t],"item_too_large"),void console.warn("[TM]: 单条事件超过体积上限(64KB),丢弃该条");const n=q(e);if(n.unshift(t),T[e]+=r,n.length>C){const t=n.length-C,r=n.splice(n.length-t,n.length);T[e]=n.reduce(((e,t)=>e+U(t)),0),Z(r,"queue_overflow"),console.warn(`[TM]: 队列超过上限(2000条),丢弃最旧 ${t} 条`)}(e=>{x.add(e),null===L&&(L=setTimeout((()=>{L=null,$()}),200))})(e),K(e,T[e]>=h)},K=(e,t=!1,r=!1)=>{if(!b?.enableTracking)return;let n=q(e);if(!n.length)return;const o=(e=>e===E)(e),i=o?O:P,a=(e=>e?g:p)(o);if(a.halveBatch&&n.length>1&&(n=n.slice(0,Math.ceil(n.length/2))),a.retryExhausted)return;if(Date.now()<a.nextRetryAt)return void(null===i.timer&&(i.timer=setTimeout((()=>{i.timer=null,K(e)}),a.nextRetryAt-Date.now())));if(0!==a.retryCount||(n.length>=d||t)){if(null!==i.timer&&(clearTimeout(i.timer),i.timer=null),i.promise)return;i.promise=(async(e,t,r,n,o=!1)=>{const i=[];let a=[],s=0;for(const e of t){const t=1024*U(e);a.length&&s+t>65536&&(i.push(a),a=[],s=0),a.push(e),s+=t}a.length&&i.push(a);for(const t of i){const n=await H(r,t,o),i=n?.data?.accepted_ids,a=n?.data?.rejected_ids;if(Array.isArray(i)){if(j(e,i),Array.isArray(a)&&a.length){const r=new Set(a);j(e,a);const n=t.filter((e=>e.event_id&&r.has(e.event_id)));n.length&&Z(n,"server_rejected"),console.warn(`[TM]: 服务端校验拒绝 ${a.length} 条(永久性拒绝),已从队列移除并通知 onDrop`)}}else j(e,t.map((e=>e.event_id))),b?.isLogger&&console.warn("[TM]: 响应缺少 accepted_ids,按整批成功清理")}n.retryCount=0,n.nextRetryAt=0,n.halveBatch=!1})(e,n,o,a,r).catch((e=>{((e,t,r,n,o)=>{t?.timeout&&ee("request_timeout","上报请求超时,数据保留队列按退避重试",{url:r&&l?l:s,timeoutMs:b?.requestTimeout});const i=t?.status;if(413===i)return void(o.length>1?(n.halveBatch=!0,n.retryCount++,n.nextRetryAt=Date.now()+F(n.retryCount,r,0),console.warn(`[TM]: 批次过大(HTTP 413),降容半批重发(本批 ${o.length} 条)`)):(n.retryExhausted=!0,Z(o,"rejected_4xx"),console.warn("[TM]: 单条事件仍超限(HTTP 413),数据保留在队列")));if(i&&i>=400&&i<500&&401!==i&&403!==i&&408!==i&&410!==i&&429!==i)return n.retryExhausted=!0,Z(o,"rejected_4xx"),void console.warn(`[TM]: 批次提交被服务端拒绝(HTTP ${i}),数据保留在队列并暂停自动重试`);if(n.retryCount++,n.retryCount>f)return n.retryExhausted=!0,Z(o,"retries_exhausted"),void console.warn(`[TM]: 重试次数已达上限(${f}),数据保留在队列(不丢弃),待下次会话或手动触发重试`);const a=429===i&&t?.retryAfter||0;n.nextRetryAt=Date.now()+F(n.retryCount,r,a),console.error(`[TM]: send report fail, retryCount: ${n.retryCount}, next retry after ${Math.round((n.nextRetryAt-Date.now())/1e3)}s`)})(0,e,o,a,n)})).finally((()=>{i.timer=null,i.promise=null,K(e)}))}else if(null===i.timer){const t=o?m:u;i.timer=setTimeout((()=>{i.timer=null,K(e,!0)}),t)}},W=e=>{if(!b?.enableTracking||b?.respectGpc&&function(){const e="undefined"!=typeof navigator?navigator:void 0;return!0===e?.globalPrivacyControl}())return void(b?.isLogger&&console.warn("[TM]: 用户已选择退出采集(enableTracking=false 或 GPC 信号开启),本事件忽略"));if(!e||"object"!=typeof e)return void console.error("[TM]: track data must be an object");const t=!0===e.track_real_time,r=Q(e);try{J(t&&l?E:S,r)}catch(e){ee("enqueue_failed","事件入队失败",{error:e})}},X=(e,t,r)=>{W("string"==typeof e?{event_type:e,event_detail:t,...r}:e)},re=()=>{K(S,!0),K(E,!0);const e=[P.promise,O.promise].filter((e=>!!e));return Promise.all(e).then((()=>{}))},ne=()=>{b.isLogger=!0;try{localStorage.setItem(A,"true")}catch(e){console.error("[TM]: enable logger fail:",e)}},oe=()=>{b.isLogger=!1;try{localStorage.setItem(A,"false")}catch(e){console.error("[TM]: disable logger fail:",e)}};a((()=>{K(S,!0),K(E,!0)}));const ie=e=>("boolean"==typeof e&&(b.enableTracking=e,(e=>{try{localStorage.setItem(M,e?"1":"0")}catch(e){}})(e),e?b?.isLogger&&console.warn("[TM]: 恢复采集"):(B(S,[]),B(E,[]),b?.isLogger&&console.warn("[TM]: 用户已选择退出采集,已清空未上报队列"))),!0===b?.enableTracking);return window.trackMonitor={track:X,flush:re,bindUser:y,unBindUser:w,enableLogger:ne,disableLogger:oe,setToken:z,registerGlobalProperties:D,enableTracking:ie},{client:{track:X,flush:re,bindUser:y,unBindUser:w,enableLogger:ne,disableLogger:oe,setToken:z,registerGlobalProperties:D,enableTracking:ie},beforeClose:()=>{const e=()=>{$(),K(S,!0,!0),K(E,!0,!0)};window.addEventListener("beforeunload",e),window.addEventListener("pagehide",e),document.addEventListener("visibilitychange",(()=>{"hidden"===document.visibilityState&&e()})),window.addEventListener("online",e)}}},ne=f(16)(),oe=e=>{const t=history[e];return function(){const r=t.apply(this,arguments),n=new Event(e);return window.dispatchEvent(n),r}},ie=e=>{window.addEventListener("replaceState",(t=>e(t)),!0),window.addEventListener("pushState",(t=>e(t)),!0)},ae=e=>{window.addEventListener("popstate",(t=>e(t)),!0)},se=[25,50,75,90],ce=e=>{history.pushState=oe("pushState"),history.replaceState=oe("replaceState"),(()=>{let e="";const t=()=>{const t=window.location.href;if(t===e)return;const{host:r,hostname:n,href:o,protocol:i,origin:a,port:s,pathname:c,search:l,hash:u}=window.location,m={host:r,hostname:n,href:o,protocol:i,origin:a,port:s,pathname:c,search:l,hash:u,title:document.title,language:navigator.language.substring(0,2),user_agent:navigator.userAgent,win_screen:`${window.screen.width}x${window.screen.height}`,doc_screen:`${document.documentElement.clientWidth}x${document.documentElement.clientHeight}`,referrer:document.referrer,type:d()};window.trackMonitor.track({data_type:"common",event_type:"page_view",event_detail:m}),e=t},r=s(t,200);t(),ae((()=>{r()})),ie((()=>{r()})),window.addEventListener("popstate",(()=>{r()}))})(),(()=>{let e=document.referrer,t=window.location.href,r=Date.now(),n=!0;const o=(n=!1)=>{if(window.location.href!==t||n){const n=Date.now()-r;n>200&&window.trackMonitor.track({data_type:"common",event_type:"page_leave",event_detail:{url:t,referrer:e,duration:n}}),r=Date.now(),e=t,t=window.location.href}},i=s(o);o(),ae((()=>{i()})),ie((()=>{i()})),document.addEventListener("visibilitychange",(()=>{"hidden"===document.visibilityState?n&&(n=!1,o(!0)):(n=!0,r=Date.now())})),window.addEventListener("beforeunload",(()=>{n&&(n=!1,o(!0))}),!0)})(),(()=>{const e=c((e=>{const t=function(e){if(!e)return;if(["A","INPUT","TEXTAREA","BUTTON"].includes(e.tagName))return e;if(e.hasAttribute("track-click"))return e;return e.closest("a, button, [track-click]")||void 0}(e.target);if(!t)return;const r={element_id:t.id,element_content:t.textContent?.trim()||null,element_class_name:t.className||null,element_name:t.getAttribute("name")||null,element_type:t.tagName.toLowerCase(),element_path:l(t),scroll_width:document.documentElement.scrollWidth,scroll_height:document.documentElement.scrollHeight,pageX:e.pageX,pageY:e.pageY,ratio:window.devicePixelRatio||1};window.trackMonitor.track({data_type:"common",event_type:"click",event_detail:r})}));window.addEventListener("click",e,!0)})(),!1!==e?.enableScroll&&(()=>{const e=new Set,t=c((()=>{const r=document.documentElement,n=r.scrollHeight-r.clientHeight;if(n<=0)return;const o=Math.round((window.scrollY||r.scrollTop)/n*100),i=se.filter((t=>o>=t&&!e.has(t)));i.length&&(i.forEach((t=>{e.add(t),window.trackMonitor.track({data_type:"common",event_type:"scroll",event_detail:{scroll_depth:t}})})),e.has(90)&&window.removeEventListener("scroll",t))}),300);window.addEventListener("scroll",t,{passive:!0})})()};let le=null,de=null;const ue="track-expose",me="track-view",he=e=>{try{de=new WeakMap}catch(e){console.error("[TM]: create WeakMap fail: ",e)}const t=(e,t=!1)=>{const n=de?.get(e);if(n&&!t)return;n&&(n.viewTimer&&clearTimeout(n.viewTimer),n.exposeTimer&&clearTimeout(n.exposeTimer));const o=e.dataset.durationView||500,i=e.dataset.durationExpose||500;de?.set(e,{duration_view:o,duration_expose:i,viewTimer:null,exposeTimer:null}),le?.observe(e),t&&function(e){if(!(e instanceof Element))return!1;if(!function e(t){if(!t)return!0;const r=window.getComputedStyle(t);return"none"!==r.display&&"hidden"!==r.visibility&&0!==parseFloat(r.opacity)&&e(t.parentElement)}(e))return!1;const t=e.getBoundingClientRect();return t.top>=0&&t.left>=0&&t.bottom<=(window.innerHeight||document.documentElement.clientHeight)&&t.right<=(window.innerWidth||document.documentElement.clientWidth)}(e)&&r(e)},r=t=>{const r=de?.get(t);if(!r)return;const o=t.dataset.eventDetail,i=t.dataset.traceid??void 0,a=t.dataset.spm,s=t.hasAttribute("track-real-time"),c=t.hasAttribute(me),l=t.hasAttribute(ue);c&&l?r.exposeTimer=window.setTimeout((()=>{e({spm:a,request_id:i,data_type:"common",event_type:"view_expose",event_detail:o,track_real_time:s}),t.removeAttribute(me),r.exposeTimer=null}),parseInt(r.duration_expose,10)):(c&&(r.viewTimer=window.setTimeout((()=>{e({spm:a,request_id:i,data_type:"common",event_type:"view",event_detail:o,track_real_time:s}),t.removeAttribute(me),l&&r.exposeTimer||n(t),r.viewTimer=null}),parseInt(r.duration_view,10))),l&&(r.exposeTimer=window.setTimeout((()=>{e({spm:a,request_id:i,data_type:"common",event_type:"expose",event_detail:o,track_real_time:s}),r.exposeTimer=null}),parseInt(r.duration_expose,10))))},n=e=>{const t=de?.get(e);t&&(le?.unobserve(e),t.viewTimer&&clearTimeout(t.viewTimer),t.exposeTimer&&clearTimeout(t.exposeTimer),de?.delete(e))},o=e=>{e.forEach((e=>{const t=e.target,o=de?.get(t);o&&(o.viewTimer&&(clearTimeout(o.viewTimer),o.viewTimer=null),o.exposeTimer&&(clearTimeout(o.exposeTimer),o.exposeTimer=null),e.isIntersecting&&(r(t),t.hasAttribute(me)||t.hasAttribute(ue)||n(t)))}))};le=(()=>{let e=null;try{e=new IntersectionObserver(o,{root:null,threshold:.5})}catch(e){console.error("[TM]: create IntersectionObserver fail: ",e)}return e})();new Set([...document.querySelectorAll(`[${ue}]`),...document.querySelectorAll(`[${me}]`)]).forEach((e=>t(e))),new MutationObserver((e=>{e.forEach((e=>{if("attributes"===e.type&&e.target instanceof HTMLElement){const r=e.target,o=e.attributeName,i=["data-event-detail","data-traceid","data-spm","data-duration-view","data-duration-expose"];r.hasAttribute(ue)||r.hasAttribute(me)?i.includes(o)?t(r,!0):o!==ue&&o!==me||t(r,!1):n(r)}else"childList"===e.type&&(e.addedNodes.forEach((e=>{if(e instanceof HTMLElement)if(e.hasAttribute(ue)||e.hasAttribute(me))t(e);else{new Set([...e.querySelectorAll(`[${ue}]`),...e.querySelectorAll(`[${me}]`)]).forEach((e=>t(e)))}})),e.removedNodes.forEach((e=>{if(e instanceof HTMLElement){const t=de?.get(e);if(t)n(e);else{new Set([...e.querySelectorAll(`[${ue}]`),...e.querySelectorAll(`[${me}]`)]).forEach((e=>n(e)))}}})))}))})).observe(document.body,{attributes:!0,childList:!0,subtree:!0})},fe=/^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|address|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;function pe(e){const t=e.match(fe);if(!t)return{};return{filename:t[2],functionName:t[1]||"",lineno:parseInt(t[3],10)||void 0,colno:parseInt(t[4],10)||void 0}}function ge(e){try{const{stack:t}=e;if(!t)return[];const r=[];for(const e of t.split("\n").slice(1)){const t=pe(e);!t||t.filename?.includes("chrome-extension://")||t.filename?.includes("node_modules")||t.filename?.includes("<anonymous>")||r.push(t)}return r.slice(0,10)}catch(e){return[]}}const ye=new Set,we=(e,t)=>{if((r=b?.errorTraceRate??.5)<0||r>1?(console.warn("[TM]: probability should be between 0 and 1"),0):Math.random()<r){if(window.trackMonitor.track(t),ye.size>=1e3){const e=ye.values().next().value;void 0!==e&&ye.delete(e)}ye.add(e)}var r},ve=()=>{window.addEventListener("error",(e=>{(e=>{if(e instanceof ErrorEvent&&"Script error."===e.message){const t=y("js-Script error.");if(ye.has(t))return;return void we(t,{data_type:"error",event_type:"js",event_detail:{traceId:ne,msg:'Script error.(跨域脚本未加载 crossorigin 属性,无法获取堆栈;建议脚本加 crossorigin="anonymous")',target:"",stack:[],errorUuid:t,meta:{filename:e.filename,colno:e.colno,lineno:e.lineno,crossorigin_missing:!0}}})}if("js"!==g(e))return;if((e=>{const t=e.error?.stack||"";return/chrome-extension:\/\//.test(t)})(e))return;const t=y(`js-${e.message}-${e.filename}`);if(ye.has(t))return;const r=ge(e.error),n={traceId:ne,msg:e.message,target:r[0]?`${r[0].filename?.split("?")[0]}:${r[0].lineno}:${r[0].colno}`:"",stack:r,errorUuid:t,meta:{filename:e.filename,colno:e.colno,lineno:e.lineno}};we(t,{data_type:"error",event_type:"js",event_detail:n})})(e)}),!0)},Te=()=>{window.addEventListener("error",(e=>{(e=>{if("resource"!==g(e))return;const t=e.target,r=y(`resource-${t.src}-${t.tagName}`);if(ye.has(r))return;const n={traceId:ne,msg:`加载${t.tagName}失败`,target:t.src?.split("?")[0],errorUuid:r,meta:{url:t.src,html:t.outerHTML,tagName:t.tagName}};we(r,{data_type:"error",event_type:"resource",event_detail:n})})(e)}),!0)},_e=()=>{window.addEventListener("unhandledrejection",(e=>(e=>{const t=e.reason?.message||e.reason,r=y(`unhandledrejection-${t}`);if(ye.has(r))return;const n={traceId:ne,msg:t,stack:ge(e.reason),errorUuid:r};we(r,{data_type:"error",event_type:"unhandledrejection",event_detail:n})})(e)),!0)},be=()=>{const e=(e,t,r)=>{if(t){const n=y(`http-${t}-${e.url}-${r}`);if(ye.has(n))return;const o={traceId:ne,errorType:t,msg:r,target:e.url.split("?")[0],errorUuid:n,request:e};we(n,{data_type:"error",event_type:"http",event_detail:o})}else if(e.status>=400){let r=e.statusText;const n=y(`http-${t="http_error"}-${e.url}-${r}`);if(ye.has(n))return;const o={traceId:ne,errorUuid:n,errorType:t,target:e.url.split("?")[0],msg:r,request:e};we(n,{data_type:"error",event_type:"http",event_detail:o})}};((e,t)=>{if("XMLHttpRequest"in window&&"function"==typeof window.XMLHttpRequest){const e=window.XMLHttpRequest;window.oXMLHttpRequest||(window.oXMLHttpRequest=e),window.XMLHttpRequest=function(){const r=new e,{open:n,send:o}=r;let i={};r.open=(e,t,o,a,s)=>{void 0===o&&(o=!0),i.method=e,i.url=t,n.call(r,e,t,o,a,s)},r.send=e=>{i.requestTime=(new Date).getTime(),o.call(r,e)};const a=(e,n)=>{const{status:o,statusText:a}=r,s=(new Date).getTime();i={...i,status:o,statusText:a,responseTime:s,duration:s-i.requestTime},"function"==typeof t&&t(i,e,n)};return r.addEventListener("loadend",(()=>a())),r.addEventListener("error",(()=>a("net_error","ERR_NETWORK"))),r.addEventListener("abort",(()=>a("cannel_request","ERR_CANCELED"))),r.addEventListener("timeout",(()=>a("timeout","ERR_NETWORK"))),r}}})(0,e),((e,t)=>{if("fetch"in window&&"function"==typeof window.fetch){const e=window.fetch;window.oFetch||(window.oFetch=e),window.fetch=async(r,n)=>{let o={};return o.method=n?.method||"",o.url=(r&&"string"!=typeof r?r?.url:r)||"",o.requestTime=(new Date).getTime(),e.call(window,r,n).then((async e=>{if("function"==typeof t){const r=e.clone(),n=(new Date).getTime();o={...o,status:r.status,statusText:r.statusText,responseTime:n,duration:n-o.requestTime},t(o)}return e})).catch((e=>{if("function"==typeof t){const r=(new Date).getTime();o={...o,responseTime:r,duration:r-o.requestTime},"AbortError"===e.name?t(o,"cannel_request","ERR_CANCELED"):t(o,"net_error","ERR_NETWORK")}return Promise.reject(e)}))}}})(0,e)};const Se=new WeakSet,Ee=e=>({form_id:e.id||null,form_class:"string"==typeof e.className?e.className:null,form_name:e.getAttribute("name")||null,form_action:e.getAttribute("action")||null,form_text:(e.textContent||"").trim().slice(0,200)||null});let ke=-1;const xe=e=>{addEventListener("pageshow",(t=>{t.persisted&&(ke=t.timeStamp,e(t))}),!0)},Le=(e,t,r,n)=>{let o,i;return a=>{t.value>=0&&(a||n)&&(i=t.value-(o??0),(i||void 0===o)&&(o=t.value,t.delta=i,t.rating=((e,t)=>e>t[1]?"poor":e>t[0]?"needs-improvement":"good")(t.value,r),e(t)))}},Ae=e=>{requestAnimationFrame((()=>requestAnimationFrame((()=>e()))))},Me=()=>{const e=performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},Ce=()=>{const e=Me();return e?.activationStart??0},Ie=(e,t=-1)=>{const r=Me();let n="navigate";return ke>=0?n="back-forward-cache":r&&(document.prerendering||Ce()>0?n="prerender":document.wasDiscarded?n="restore":r.type&&(n=r.type.replace(/_/g,"-"))),{name:e,value:t,rating:"good",delta:0,entries:[],id:`v5-${Date.now()}-${Math.floor(8999999999999*Math.random())+1e12}`,navigationType:n}},Re=new WeakMap;function $e(e,t){return Re.get(e)||Re.set(e,new t),Re.get(e)}class qe{t;i=0;o=[];h(e){if(e.hadRecentInput)return;const t=this.o[0],r=this.o.at(-1);this.i&&t&&r&&e.startTime-r.startTime<1e3&&e.startTime-t.startTime<5e3?(this.i+=e.value,this.o.push(e)):(this.i=e.value,this.o=[e]),this.t?.(e)}}const Ne=(e,t,r={})=>{try{if(PerformanceObserver.supportedEntryTypes.includes(e)){const n=new PerformanceObserver((e=>{Promise.resolve().then((()=>{t(e.getEntries())}))}));return n.observe({type:e,buffered:!0,...r}),n}}catch{}},Pe=e=>{let t=!1;return()=>{t||(e(),t=!0)}};let Oe=-1;const Ue=new Set,Be=()=>"hidden"!==document.visibilityState||document.prerendering?1/0:0,ze=e=>{if("hidden"===document.visibilityState){if("visibilitychange"===e.type)for(const e of Ue)e();isFinite(Oe)||(Oe="visibilitychange"===e.type?e.timeStamp:0,removeEventListener("prerenderingchange",ze,!0))}},De=()=>{if(Oe<0){const e=Ce(),t=document.prerendering?void 0:globalThis.performance.getEntriesByType("visibility-state").filter((t=>"hidden"===t.name&&t.startTime>e))[0]?.startTime;Oe=t??Be(),addEventListener("visibilitychange",ze,!0),addEventListener("prerenderingchange",ze,!0),xe((()=>{setTimeout((()=>{Oe=Be()}))}))}return{get firstHiddenTime(){return Oe},onHidden(e){Ue.add(e)}}},He=e=>{document.prerendering?addEventListener("prerenderingchange",(()=>e()),!0):e()},je=[1800,3e3],Fe=(e,t={})=>{He((()=>{const r=De();let n,o=Ie("FCP");const i=Ne("paint",(e=>{for(const t of e)"first-contentful-paint"===t.name&&(i.disconnect(),t.startTime<r.firstHiddenTime&&(o.value=Math.max(t.startTime-Ce(),0),o.entries.push(t),n(!0)))}));i&&(n=Le(e,o,je,t.reportAllChanges),xe((r=>{o=Ie("FCP"),n=Le(e,o,je,t.reportAllChanges),Ae((()=>{o.value=performance.now()-r.timeStamp,n(!0)}))})))}))},Je=[.1,.25];let Ke=0,We=1/0,Xe=0;const Qe=e=>{for(const t of e)t.interactionId&&(We=Math.min(We,t.interactionId),Xe=Math.max(Xe,t.interactionId),Ke=Xe?(Xe-We)/7+1:0)};let Ge;const Ye=()=>Ge?Ke:performance.interactionCount??0;let Ve=0;class Ze{u=[];l=new Map;m;p;v(){Ve=Ye(),this.u.length=0,this.l.clear()}L(){const e=Math.min(this.u.length-1,Math.floor((Ye()-Ve)/50));return this.u[e]}h(e){if(this.m?.(e),!e.interactionId&&"first-input"!==e.entryType)return;const t=this.u.at(-1);let r=this.l.get(e.interactionId);if(r||this.u.length<10||e.duration>t.P){if(r?e.duration>r.P?(r.entries=[e],r.P=e.duration):e.duration===r.P&&e.startTime===r.entries[0].startTime&&r.entries.push(e):(r={id:e.interactionId,entries:[e],P:e.duration},this.l.set(r.id,r),this.u.push(r)),this.u.sort(((e,t)=>t.P-e.P)),this.u.length>10){const e=this.u.splice(10);for(const t of e)this.l.delete(t.id)}this.p?.(r)}}}const et=e=>{const t=globalThis.requestIdleCallback||setTimeout;"hidden"===document.visibilityState?e():(e=Pe(e),addEventListener("visibilitychange",e,{once:!0,capture:!0}),t((()=>{e(),removeEventListener("visibilitychange",e,{capture:!0})})))},tt=[200,500],rt=(e,t={})=>{if(!globalThis.PerformanceEventTiming||!("interactionId"in PerformanceEventTiming.prototype))return;const r=De();He((()=>{"interactionCount"in performance||Ge||(Ge=Ne("event",Qe,{type:"event",buffered:!0,durationThreshold:0}));let n,o=Ie("INP");const i=$e(t,Ze),a=e=>{et((()=>{for(const t of e)i.h(t);const t=i.L();t&&t.P!==o.value&&(o.value=t.P,o.entries=t.entries,n())}))},s=Ne("event",a,{durationThreshold:t.durationThreshold??40});n=Le(e,o,tt,t.reportAllChanges),s&&(s.observe({type:"first-input",buffered:!0}),r.onHidden((()=>{a(s.takeRecords()),n(!0)})),xe((()=>{i.v(),o=Ie("INP"),n=Le(e,o,tt,t.reportAllChanges)})))}))};class nt{m;h(e){this.m?.(e)}}const ot=[2500,4e3],it=[800,1800],at=e=>{document.prerendering?He((()=>at(e))):"complete"!==document.readyState?addEventListener("load",(()=>at(e)),!0):setTimeout(e)};function st(){const e={ttfb:null,lcp:null,fp:null,fcp:null,connectionRtt:null,ttfbRequestTime:null,inp:null,cls:null,dcl:null,loadTime:null};((e,t={})=>{He((()=>{const r=De();let n,o=Ie("LCP");const i=$e(t,nt),a=e=>{t.reportAllChanges||(e=e.slice(-1));for(const t of e)i.h(t),t.startTime<r.firstHiddenTime&&(o.value=Math.max(t.startTime-Ce(),0),o.entries=[t],n())},s=Ne("largest-contentful-paint",a);if(s){n=Le(e,o,ot,t.reportAllChanges);const r=Pe((()=>{a(s.takeRecords()),s.disconnect(),n(!0)})),i=e=>{e.isTrusted&&(et(r),removeEventListener(e.type,i,{capture:!0}))};for(const e of["keydown","click","visibilitychange"])addEventListener(e,i,{capture:!0});xe((r=>{o=Ie("LCP"),n=Le(e,o,ot,t.reportAllChanges),Ae((()=>{o.value=performance.now()-r.timeStamp,n(!0)}))}))}}))})((t=>{e.lcp=m(t.value)}),{reportAllChanges:!0}),((e,t={})=>{const r=De();Fe(Pe((()=>{let n,o=Ie("CLS",0);const i=$e(t,qe),a=e=>{for(const t of e)i.h(t);i.i>o.value&&(o.value=i.i,o.entries=i.o,n())},s=Ne("layout-shift",a);s&&(n=Le(e,o,Je,t.reportAllChanges),r.onHidden((()=>{a(s.takeRecords()),n(!0)})),xe((()=>{i.i=0,o=Ie("CLS",0),n=Le(e,o,Je,t.reportAllChanges),Ae((()=>n()))})),setTimeout(n))})))})((t=>{e.cls=Math.round(1e4*t.value)/1e4}),{reportAllChanges:!0}),rt((t=>{e.inp=m(t.value)}),{reportAllChanges:!0}),((e,t={})=>{let r=Ie("TTFB"),n=Le(e,r,it,t.reportAllChanges);at((()=>{const o=Me();o&&(r.value=Math.max(o.responseStart-Ce(),0),r.entries=[o],n(!0),xe((()=>{r=Ie("TTFB",0),n=Le(e,r,it,t.reportAllChanges),n(!0)})))}))})((t=>{e.ttfb=m(t.value)})),Fe((t=>{e.fcp=m(t.value)}));const t=()=>{(()=>{try{performance.getEntriesByType("paint").forEach((t=>{"first-paint"===t.name&&(e.fp=m(t.startTime))}))}catch(e){console.warn("[TM]: Failed to collect FP:",e)}try{const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection;t&&void 0!==t.rtt&&(e.connectionRtt=t.rtt)}catch(e){console.warn("[TM]: Failed to collect Connection RTT:",e)}try{const t=performance.getEntriesByType("navigation")[0];if(t){const{responseStart:r,requestStart:n}=t;r>0&&n>0&&n<=r&&(e.ttfbRequestTime=m(r-n))}}catch(e){console.warn("[TM]: Failed to collect TTFB Request Time:",e)}try{const t=performance.getEntriesByType("navigation")[0];if(t){const{domContentLoadedEventEnd:r,loadEventEnd:n,fetchStart:o}=t;r>0&&o>0&&(e.dcl=m(r-o)),n>0&&o>0&&(e.loadTime=m(n-o))}}catch(e){console.warn("[TM]: Failed to collect DCL and Load Time:",e)}})(),window.trackMonitor.track({data_type:"performance",event_type:"metrics",event_detail:{traceId:ne,data:e}})};let r=0;const n=()=>{const e=Date.now();e-r<3e4||(r=e,t())};window.addEventListener("beforeunload",t),window.addEventListener("pagehide",n),document.addEventListener("visibilitychange",(()=>{"hidden"===document.visibilityState&&n()}))}const ct="__tengence_sdk",lt=e=>{if("undefined"!=typeof window&&window.trackMonitor&&window.trackMonitor[ct])return console.warn("[TM]: init 已调用过,复用现有实例(如需重建请刷新页面)"),window.trackMonitor;const{client:t,beforeClose:r}=re(e);var n;return he(t.track),!1!==e.traceBehavior&&ce({enableScroll:e.enableScroll}),!1!==e.enableFormTrack&&(n=t.track,document.addEventListener("focusin",(e=>{const t=e.target;if(!(r=t)||"INPUT"!==r.tagName&&"SELECT"!==r.tagName&&"TEXTAREA"!==r.tagName)return;var r;const o=t.closest("form");o&&!Se.has(o)&&(Se.add(o),n({data_type:"common",event_type:"form_start",event_detail:Ee(o)}))}),!0),document.addEventListener("submit",(e=>{const t=e.target;if(!t||"FORM"!==t.tagName)return;const r=e.submitter;n({data_type:"common",event_type:"form_submit",event_detail:{...Ee(t),submitter_id:r?.id||null,submitter_text:(r?.textContent||"").trim().slice(0,200)||null}})}),!0)),!1!==e.traceError&&(ve(),Te(),_e(),be()),!1!==e.tracePerformance&&u((()=>{!function(){const e=window.performance||window.msPerformance;if(!e)return{dnsLookupTime:null,tcpConnectTime:null,ttfb:null,transferTime:null,domParseTime:null,domCompleteTime:null,loadEventTime:null,totalPageLoad:null};const t=e.getEntriesByType&&e.getEntriesByType("navigation")&&e.getEntriesByType("navigation")[0];let r=null;if(t)r=t;else{const t=e.timing;t&&(r={startTime:0,domainLookupStart:t.domainLookupStart,domainLookupEnd:t.domainLookupEnd,connectStart:t.connectStart,connectEnd:t.connectEnd,requestStart:t.requestStart,responseStart:t.responseStart,responseEnd:t.responseEnd,domInteractive:t.domInteractive,domComplete:t.domComplete,loadEventEnd:t.loadEventEnd,fetchStart:t.fetchStart},!r.requestStart&&t.fetchStart&&(r.requestStart=t.fetchStart))}const n={dnsLookupTime:r?m(r.domainLookupEnd-r.domainLookupStart):null,tcpConnectTime:r?m(r.connectEnd-r.connectStart):null,ttfb:r?m(r.responseStart-(r.requestStart??r.fetchStart??0)):null,transferTime:r?m(r.responseEnd-r.responseStart):null,domParseTime:r?m(r.domInteractive-r.responseEnd):null,domCompleteTime:r?m(r.domComplete-r.domInteractive):null,loadEventTime:r?m(r.loadEventEnd-(r.domComplete??0)):null,totalPageLoad:r?m((r.loadEventEnd??performance.now())-(r.startTime??0)):null};window.trackMonitor.track({data_type:"performance",event_type:"navigation_timing",event_detail:{traceId:ne,data:n}})}(),function(){const e=window.performance||window.msPerformance;if(!e)return[];const t=[];if(e.getEntriesByType){const r=(e.getEntriesByType("resource")||[]).map((e=>{const t="number"==typeof e.redirectEnd&&"number"==typeof e.redirectStart?m(e.redirectEnd-e.redirectStart):null,r="number"==typeof e.domainLookupEnd&&"number"==typeof e.domainLookupStart?m(e.domainLookupEnd-e.domainLookupStart):null,n="number"==typeof e.connectEnd&&"number"==typeof e.connectStart?m(e.connectEnd-e.connectStart):null,o="number"==typeof e.requestStart&&"number"==typeof e.fetchStart?m(e.requestStart-e.fetchStart):null,i="number"==typeof e.responseStart&&"number"==typeof e.requestStart?m(e.responseStart-e.requestStart):null,a="number"==typeof e.responseEnd&&"number"==typeof e.responseStart?m(e.responseEnd-e.responseStart):null,s="number"==typeof e.duration?m(e.duration):null,c="number"==typeof e.startTime?m(e.startTime):null,l="number"==typeof e.transferSize&&isFinite(e.transferSize)&&e.transferSize>=0?Math.round(e.transferSize):null,d="number"==typeof e.encodedBodySize&&isFinite(e.encodedBodySize)&&e.encodedBodySize>=0?Math.round(e.encodedBodySize):null,u="number"==typeof e.decodedBodySize&&isFinite(e.decodedBodySize)&&e.decodedBodySize>=0?Math.round(e.decodedBodySize):null;return{name:e.name,initiatorType:e.initiatorType||"",startTime:c,duration:s,redirectTime:t,cacheTime:o,dnsTime:r,connectTime:n,requestTime:i,responseTime:a,transferSize:l,encodedBodySize:d,decodedBodySize:u}}));r.sort(((e,t)=>(t.duration??0)-(e.duration??0)));for(let e=0;e<Math.min(15,r.length);e++)t.push(r[e])}window.trackMonitor.track({data_type:"performance",event_type:"resource_flow",event_detail:{traceId:ne,data:t}})}(),st()})),u((()=>{r()})),window.trackMonitor[ct]=!0,window.trackMonitor};export{lt as default};
1
+ class e extends Error{status;constructor(e,t){super(t||`[TM]: Auth error ${e}`),this.name="AuthError",this.status=e}}const t=({method:e,url:t,data:r,headers:n={},withCredentials:o=!1,timeoutMs:i})=>new Promise(((a,s)=>{const c=new XMLHttpRequest;c.open(e,t,!0),i&&(c.timeout=i),Object.keys(n).forEach((e=>{c.setRequestHeader(e,n[e])})),c.withCredentials=!!o,c.onreadystatechange=()=>{if(4===c.readyState)if(c.status>=200&&c.status<300)try{const e=JSON.parse(c.responseText);a(e)}catch(e){s(e)}else{const e=new Error(`[TM]: Request failed with status ${c.status}`);e.status=c.status,s(e)}},c.onerror=()=>{s(new Error("[TM]: Network error"))},c.ontimeout=()=>{const e=new Error("[TM]: Request timeout");e.timeout=!0,s(e)},r?c.send(r):c.send()})),r=(e,t,r)=>{if(!r)return fetch(e,t);const n=new AbortController,o=setTimeout((()=>n.abort()),r);return fetch(e,{...t,signal:n.signal}).catch((e=>{if(e&&"AbortError"===e.name){const e=new Error("[TM]: Request timeout");throw e.timeout=!0,e}throw e})).finally((()=>clearTimeout(o)))},n=(n,o,i,a)=>{const s={"Content-Type":"application/json"};i&&(s.Authorization=`Bearer ${i}`);const c=()=>t({method:"POST",url:n,data:JSON.stringify(o),headers:s,withCredentials:!0,timeoutMs:a});return"function"!=typeof fetch?c():r(n,{method:"POST",keepalive:!0,credentials:"include",headers:s,body:JSON.stringify(o)},a).then((t=>{if(401===t.status||403===t.status)throw new e(t.status,`[TM]: Auth error ${t.status}`);if(429===t.status){const e=new Error("[TM]: Request throttled with status 429");e.status=429;const r=t.headers.get("Retry-After");if(r){const t=parseInt(r,10);isNaN(t)||(e.retryAfter=1e3*t)}throw e}if(!t.ok){const e=new Error(`[TM]: Request failed with status ${t.status}`);throw e.status=t.status,e}return t.json()})).catch((t=>{if(t instanceof e)throw t;if(t&&t.status)throw t;return c()}))},o=window.requestIdleCallback||window.requestAnimationFrame||(e=>setTimeout(e,17));function i(e,t=150,r=!1){let n=null;return function(...o){const i=this,a=r&&!n;n&&clearTimeout(n),n=setTimeout((()=>{n=null,r||e.apply(i,o)}),t),a&&e.apply(i,o)}}const a=(e,t=300)=>{let r=0;return function(...n){const o=Date.now();o-r>=t&&(r=o,e.apply(this,n))}};function s(e,t=""){if(!e)return t;const r=e.parentElement,{id:n}=e,o=e.tagName.toLowerCase(),i=t?`>${t}`:"";return r&&r!==document.documentElement&&r!==document.body?n?`#${n}${i}`:s(r,`${o}${i}`):`${o}${i}`}const c=()=>{if(window.performance?.navigation)return performance.navigation.type;if(window.performance?.getEntriesByType){const e=performance.getEntriesByType("navigation");if(e.length>0)return e[0].type}return 255},l=e=>{"prerendering"in document&&document.prerendering?(e=>{"prerendering"in document&&document.prerendering?addEventListener("prerenderingchange",(()=>e()),!0):e()})((()=>l(e))):"complete"!==document?.readyState?addEventListener("load",(()=>l(e)),!0):setTimeout(e)};function d(e){return"number"!=typeof e||!isFinite(e)||e<0?null:Math.round(100*e)/100}function u(){const e=new Uint8Array(16);if("undefined"!=typeof crypto&&"function"==typeof crypto.getRandomValues)crypto.getRandomValues(e);else for(let t=0;t<16;t++)e[t]=Math.floor(256*Math.random());e[6]=15&e[6]|64,e[8]=63&e[8]|128;let t="";for(let r=0;r<16;r++)t+=(e[r]<16?"0":"")+e[r].toString(16);return t}const m=e=>e instanceof ErrorEvent?"Script error."===e.message?"cors":"js":"resource",p=e=>(e=>{let t=5381;for(let r=0;r<e.length;r++)t=(t<<5)+t+e.charCodeAt(r)>>>0;return t.toString(16).padStart(8,"0")})(e)+(e=>{let t=5381;for(let r=e.length-1;r>=0;r--)t=((t<<5)+t^e.charCodeAt(r))>>>0;return t.toString(16).padStart(8,"0")})(e);const f={view:"#3b82f6",click:"#06b6d4",expose:"#8b5cf6",enter:"#10b981",leave:"#f59e0b",stay:"#84cc16",cart:"#ec4899",buy:"#ef4444",pay:"#dc2626",default:"#6b7280"},h={view:"👁️",click:"👆",expose:"✨",enter:"🚪",leave:"👋",stay:"⏱️",cart:"🛒",buy:"💰",pay:"💳",default:"📊"},g={common:"#3b82f6",behavior:"#10b981",performance:"#f59e0b",error:"#ef4444",custom:"#8b5cf6",default:"#6b7280"},y=(e,t)=>{t.forEach(((t,r)=>{const n=t.event_type||"unknown",o=t.data_type||"auto",i=(e=>f[e]||f.default)(n),a=(e=>g[e]||g.default)(o),s=(e=>h[e]||h.default)(n);let c=t.event_detail;if("string"==typeof c)try{c=JSON.parse(c)}catch(e){}console.groupCollapsed(`%c${s} [TM-${e}] %c${o.toUpperCase()}%c → %c${n.toUpperCase()}%c #${r+1}`,"color: #6b7280; font-weight: bold;",`color: ${a}; font-weight: bold; background: ${a}20; padding: 2px 6px; border-radius: 3px;`,"color: #6b7280;",`color: ${i}; font-weight: bold; background: ${i}20; padding: 2px 6px; border-radius: 3px;`,"color: #6b7280; font-weight: normal;");const l={...t,event_detail:c};console.log("%c"+JSON.stringify(l,null,2),"color: #6b7280; font-family: monospace; font-size: 11px; line-height: 1.5;"),console.groupEnd()})),console.log(`%c✅ [TM] 本次通过 ${e} 上报 ${t.length} 条埋点数据`,"color: #10b981; font-weight: bold; font-size: 12px; padding: 4px 8px; background: #10b98120; border-radius: 4px; border-left: 3px solid #10b981;")};let w;const v="TRACK_MONITOR_DATA",T="MONITOR_REAL_TIME_DATA",_="TRACK_MONITOR_USER",b="tengence_device_id",S="tengence_register_properties",E="TRACK_MONITOR_LOGGER",k="tengence_tracking_enabled",x=2e3,M="tengence_access_token";let A=null,L=null;const C=e=>((e,n,o)=>{const i={"Content-Type":"application/json"},a=()=>t({method:"POST",url:e,data:JSON.stringify(n),headers:i,withCredentials:!0,timeoutMs:o});return"function"!=typeof fetch?a():r(e,{method:"POST",credentials:"include",headers:i,body:JSON.stringify(n)},o).then((e=>{if(!e.ok){const t=new Error(`[TM]: Request failed with status ${e.status}`);throw t.status=e.status,t}return e.json()})).catch((e=>{if(e&&e.status)throw e;return a()}))})(e,{},w?.requestTimeout).then((e=>{const t=e&&e.data,r=t&&t.accessToken,n=t&&t.accessExpAt;if(!r||"number"!=typeof n)throw new Error("[TM]: authUrl 响应缺少 accessToken/accessExpAt");return((e,t)=>{A={token:e,expAt:t};try{localStorage.setItem(M,JSON.stringify({token:e,expAt:t}))}catch(e){}})(r,n),r})),R=e=>{const t=(()=>{if(A)return A;try{const e=localStorage.getItem(M);if(!e)return null;const t=JSON.parse(e);if(t&&"string"==typeof t.token&&t.token&&"number"==typeof t.expAt)return A={token:t.token,expAt:t.expAt},A}catch(e){}return null})();return(r=t)&&r.token.length>0&&r.expAt-6e4>Date.now()?Promise.resolve(t.token):(L||(L=C(e).catch((e=>{throw e})).finally((()=>{L=null}))),L);var r},I={timer:null,promise:null},$={timer:null,promise:null},q=e=>{const t=JSON.stringify(e);return(new TextEncoder).encode(t).length/1024};let N=null;const P=()=>{if(N)return N;try{const e=localStorage.getItem(S),t=e?JSON.parse(e):{};return N=t,t}catch(e){return console.error("[TM]: get register properties fail: ",e),{}}},O=e=>{N=e;try{localStorage.setItem(S,JSON.stringify(e))}catch(e){console.error("[TM]: save register properties fail: ",e)}},U=e=>{if(!e||"object"!=typeof e||Array.isArray(e))return void console.error("[TM]: registerGlobalProperties props must be a plain object");const t={...P(),...e},r=Object.keys(t);if(r.length>50){const e={};return r.slice(0,50).forEach((r=>{e[r]=t[r]})),console.warn("[TM]: register properties exceed max 50 keys, extra keys dropped"),void O(e)}O(t)},B=e=>{const t=document.cookie.match(new RegExp("(?:^|;\\s*)"+e+"=([^;]*)"));return t?decodeURIComponent(t[1]):void 0},z=e=>{document.cookie=`${b}=${encodeURIComponent(e)}; Max-Age=63072000; Path=/; Secure; SameSite=Lax`};let D;const F=()=>{if(D)return D;try{let e=localStorage.getItem(b);if(e)return B(b)||z(e),D=e;const t=B(b);if(t){try{localStorage.setItem(b,t)}catch(e){}return D=t}e=u();try{localStorage.setItem(b,e)}catch(e){}return z(e),D=e}catch(e){return void console.error("[TM]: get or create device id fail: ",e)}},j="tengence_session_id",H=()=>{try{const e=sessionStorage.getItem(j);let t=e?JSON.parse(e):null;const r=Date.now();return!t||!t.id||r-t.lastActiveAt>18e5?(t={id:u(),lastActiveAt:r},sessionStorage.setItem(j,JSON.stringify(t))):(t.lastActiveAt=r,sessionStorage.setItem(j,JSON.stringify(t))),t.id}catch(e){return}},J=(e,t)=>{try{const r=new URL(e,location.href);if(!r.searchParams.toString())return e;if(t&&t.length){const e=[];for(const n of t){const t=r.searchParams.get(n);null!==t&&e.push(`${n}=${encodeURIComponent(t)}`)}r.search=e.length?`?${e.join("&")}`:""}else r.search="";return r.toString()}catch(t){return e}},K=(e,t,r)=>{if("string"==typeof e)return t>0&&e.length>t?e.slice(0,t)+"...[truncated]":e;if(Array.isArray(e))return e.map((e=>K(e,t,r)));if(e&&"object"==typeof e){const n={};for(const o of Object.keys(e)){const i=e[o];"string"==typeof i&&/(^|_)url$|(^|_)href$|^referrer$/i.test(o)&&/^https?:\/\//i.test(i)?n[o]=J(i,r):n[o]=K(i,t,r)}return n}return e},W=e=>{const t={page_url:location.href,hostname:window.location.hostname||window.location.host,os:window.navigator.platform,user_id:localStorage.getItem(_)||void 0,user_agent:window.navigator.userAgent,screen_width:window.screen.width,screen_height:window.screen.height,lib_version:"1.2.1",lib_type:"js",event_time:Date.now(),timezone_offset:(new Date).getTimezoneOffset().toString()},r=w?.sanitize;let n;try{n="string"==typeof e.event_detail?e.event_detail:JSON.stringify(r&&(r.maxTextLength>0||r.stripQuery)?K(e.event_detail,r.maxTextLength,r.preserveQueryKeys):e.event_detail)}catch(e){return Y("serialize_failed","事件 event_detail 序列化失败(循环引用/BigInt?),该事件丢弃",{error:e}),void console.warn("[TM]: event_detail 序列化失败,该事件丢弃",e)}return{session_id:e.session_id||(w?.enableAutoSessionId?H():void 0),request_id:e.request_id,event_id:e.event_id||u(),spm:e.spm,data_type:e.data_type||"behavior",event_type:e.event_type,event_detail:n,...t,page_url:r&&r.stripQuery?J(t.page_url,r.preserveQueryKeys):t.page_url,device_id:F(),register_properties:JSON.stringify(P()),platform:e.platform||X}};let X;const Q=()=>{try{return"true"===localStorage.getItem(E)}catch(e){return!1}},G=(e,t,r,n,o)=>void 0===e?t:"number"!=typeof e||Number.isNaN(e)||e<r||e>n?(console.warn(`[TM]: 配置 ${o}=${e} 非法,回退默认值 ${t}`),t):e,V=(e,t)=>{try{w?.onDrop?.(e,t)}catch(e){}},Y=(e,t,r)=>{w?.isLogger&&console.error(`[TM]: ${t}`);try{w?.onError?.({code:e,message:t,context:r})}catch(e){}},Z=()=>{try{const e=localStorage.getItem(k);return null===e||"1"===e}catch(e){return!0}},ee=t=>{const r=t.apiKey;let i;const a=/Android|iPhone|iPad|iPod|Mobile/i.test(window.navigator.userAgent);X=t.platform||(a?"h5":"web"),w={pushUrl:t.pushUrl||"https://api.tengence.com/v1/push/event",authUrl:t.authUrl,realTimeUrl:t.realTimeUrl,cacheNumber:G(t.cacheNumber,100,1,1/0,"cacheNumber"),reportInterval:G(t.reportInterval,5e3,100,1/0,"reportInterval"),realTimeReportInterval:G(t.realTimeReportInterval,200,100,1/0,"realTimeReportInterval"),maxCacheSize:G(t.maxCacheSize,56,1,1/0,"maxCacheSize"),maxRetries:G(t.maxRetries,10,0,1/0,"maxRetries"),isLogger:t.isLogger??Q(),errorTraceRate:G(t.errorTraceRate,.5,0,1,"errorTraceRate"),resourceFlowLimit:G(t.resourceFlowLimit,15,0,200,"resourceFlowLimit"),traceBehavior:t.traceBehavior??!0,tracePerformance:t.tracePerformance??!0,traceError:t.traceError??!0,sanitize:!1===t.sanitize?{stripQuery:!1,maxTextLength:0,preserveQueryKeys:[]}:{stripQuery:t.sanitize?.stripQuery??!1,maxTextLength:G(t.sanitize?.maxTextLength,0,0,1/0,"sanitize.maxTextLength"),preserveQueryKeys:t.sanitize?.preserveQueryKeys||[]},enableAutoSessionId:t.enableAutoSessionId??!1,enableTracking:t.enableTracking??Z(),respectGpc:t.respectGpc??!0,requestTimeout:G(t.requestTimeout,1e4,1e3,6e4,"requestTimeout"),beforeSend:t.beforeSend,onDrop:t.onDrop,onError:t.onError};let{pushUrl:s,authUrl:c,realTimeUrl:l,cacheNumber:d,reportInterval:u,realTimeReportInterval:m,maxCacheSize:p,maxRetries:f}=w;r||c||(console.error("[TM]: 未配置 apiKey 或 authUrl,SDK 无法获取上报凭证,数据将不会上报。请配置 apiKey(直连)或 authUrl(自动换取 accessToken),或调用 setToken 注入 accessToken。"),Y("init_missing_credential","未配置 apiKey 或 authUrl,SDK 无法获取上报凭证,数据将不会上报。请配置 apiKey(直连)或 authUrl(自动换取 accessToken),或调用 setToken 注入 accessToken。"));const h={retryCount:0,nextRetryAt:0,retryExhausted:!1,halveBatch:!1},g={retryCount:0,nextRetryAt:0,retryExhausted:!1,halveBatch:!1},b=e=>{try{localStorage.setItem(_,e)}catch(e){console.error("[TM]: monitor bind user fail: ",e)}},S=()=>{localStorage.removeItem(_)},L={},C={},N=new Set;let P=null;const O=()=>{null!==P&&(clearTimeout(P),P=null),N.size&&(N.forEach((e=>{try{localStorage.setItem(e,JSON.stringify(L[e]||[]))}catch(t){Y("queue_write_failed","写入本地缓存队列失败(隐私模式/容量满?),本次数据仅保留内存",{key:e,error:t})}})),N.clear())},B=e=>{if(L[e])return L[e];let t=[];try{t=JSON.parse(localStorage.getItem(e)||"[]")}catch(t){Y("queue_read_failed","读取本地缓存队列失败,按空队列处理",{key:e,error:t})}return L[e]=t,C[e]=t.reduce(((e,t)=>e+q(t)),0),L[e]},z=(e,t)=>{N.delete(e),L[e]=t,C[e]=t.reduce(((e,t)=>e+q(t)),0);try{localStorage.setItem(e,JSON.stringify(t))}catch(t){Y("queue_write_failed","写入本地缓存队列失败(隐私模式/容量满?),队列清空处理",{key:e,error:t});try{localStorage.setItem(e,"[]")}catch(t){Y("localstorage_unavailable","localStorage 不可用,本次数据仅保留内存",{key:e,error:t})}}},D=e=>{i=e},F=async(t,o,a=!1)=>{const d=t&&l?l:s;let u;try{u=r||i||(c?await R(c):void 0)}catch(e){throw Y("token_fetch_failed","从 authUrl 获取 accessToken 失败,本批暂不上报(保留队列待重试)",{authUrl:c,error:e}),e}if(!u)throw Y("init_missing_credential","未配置 apiKey/authUrl 且未注入 accessToken,本次数据未上报(保留缓存队列待重试)"),new Error("[TM]: credential missing, skip report");w?.isLogger&&y(t?"RealTimeFetch":"Fetch",o);const m=w?.beforeSend?(()=>{let e;try{e=w.beforeSend(o)}catch(e){Y("before_send_failed","beforeSend 钩子抛错,本次按原始数据发送",{error:e})}return Array.isArray(e)?e:o})():o,p=a?void 0:w?.requestTimeout;return n(d,{data:m},u,p).catch((async t=>{const o=t?.status;if((t instanceof e||401===o||403===o)&&!r&&!i&&c){(()=>{A=null;try{localStorage.removeItem(M)}catch(e){}})();const e=await R(c).catch((()=>{}));if(e)return n(d,{data:m},e,p);Y("token_invalid","上报 401/403 且刷新 accessToken 失败,本批暂不上报(保留队列待重试)",{authUrl:c})}throw t}))},j=(e,t)=>{const r=new Set(t.filter((e=>!!e)));if(!r.size)return;const n=B(e);if(!n.length)return;const o=n.filter((e=>e.event_id&&!r.has(e.event_id)));o.length!==n.length&&z(e,o)},H=(e,t,r=0)=>{const n=(t?m:u)*Math.pow(2,e)*(.8+.4*Math.random()),o=Math.min(n,6e4);return Math.max(o,r)},J=(e,t)=>{const r=q(t);if(r>=64)return V([t],"item_too_large"),void console.warn("[TM]: 单条事件超过体积上限(64KB),丢弃该条");const n=B(e);if(n.unshift(t),C[e]+=r,n.length>x){const t=n.length-x,r=n.splice(n.length-t,n.length);C[e]=n.reduce(((e,t)=>e+q(t)),0),V(r,"queue_overflow"),console.warn(`[TM]: 队列超过上限(2000条),丢弃最旧 ${t} 条`)}(e=>{N.add(e),null===P&&(P=setTimeout((()=>{P=null,O()}),200))})(e),K(e,C[e]>=p)},K=(e,t=!1,r=!1)=>{if(!w?.enableTracking)return;let n=B(e);if(!n.length)return;const o=(e=>e===T)(e),i=o?$:I,a=(e=>e?g:h)(o);if(a.halveBatch&&n.length>1&&(n=n.slice(0,Math.ceil(n.length/2))),a.retryExhausted)return;if(Date.now()<a.nextRetryAt)return void(null===i.timer&&(i.timer=setTimeout((()=>{i.timer=null,K(e)}),a.nextRetryAt-Date.now())));if(0!==a.retryCount||(n.length>=d||t)){if(null!==i.timer&&(clearTimeout(i.timer),i.timer=null),i.promise)return;i.promise=(async(e,t,r,n,o=!1)=>{const i=[];let a=[],s=0;for(const e of t){const t=1024*q(e);a.length&&s+t>65536&&(i.push(a),a=[],s=0),a.push(e),s+=t}a.length&&i.push(a);for(const t of i){const n=await F(r,t,o),i=n?.data?.accepted_ids,a=n?.data?.rejected_ids;if(Array.isArray(i)){if(j(e,i),Array.isArray(a)&&a.length){const r=new Set(a);j(e,a);const n=t.filter((e=>e.event_id&&r.has(e.event_id)));n.length&&V(n,"server_rejected"),console.warn(`[TM]: 服务端校验拒绝 ${a.length} 条(永久性拒绝),已从队列移除并通知 onDrop`)}}else j(e,t.map((e=>e.event_id))),w?.isLogger&&console.warn("[TM]: 响应缺少 accepted_ids,按整批成功清理")}n.retryCount=0,n.nextRetryAt=0,n.halveBatch=!1})(e,n,o,a,r).catch((e=>{((e,t,r,n,o)=>{t?.timeout&&Y("request_timeout","上报请求超时,数据保留队列按退避重试",{url:r&&l?l:s,timeoutMs:w?.requestTimeout});const i=t?.status;if(413===i)return void(o.length>1?(n.halveBatch=!0,n.retryCount++,n.nextRetryAt=Date.now()+H(n.retryCount,r,0),console.warn(`[TM]: 批次过大(HTTP 413),降容半批重发(本批 ${o.length} 条)`)):(n.retryExhausted=!0,V(o,"rejected_4xx"),console.warn("[TM]: 单条事件仍超限(HTTP 413),数据保留在队列")));if(i&&i>=400&&i<500&&401!==i&&403!==i&&408!==i&&410!==i&&429!==i)return n.retryExhausted=!0,V(o,"rejected_4xx"),void console.warn(`[TM]: 批次提交被服务端拒绝(HTTP ${i}),数据保留在队列并暂停自动重试`);if(n.retryCount++,n.retryCount>f)return n.retryExhausted=!0,V(o,"retries_exhausted"),void console.warn(`[TM]: 重试次数已达上限(${f}),数据保留在队列(不丢弃),待下次会话或手动触发重试`);const a=429===i&&t?.retryAfter||0;n.nextRetryAt=Date.now()+H(n.retryCount,r,a),console.error(`[TM]: send report fail, retryCount: ${n.retryCount}, next retry after ${Math.round((n.nextRetryAt-Date.now())/1e3)}s`)})(0,e,o,a,n)})).finally((()=>{i.timer=null,i.promise=null,K(e)}))}else if(null===i.timer){const t=o?m:u;i.timer=setTimeout((()=>{i.timer=null,K(e,!0)}),t)}},ee=e=>{if(!w?.enableTracking||w?.respectGpc&&function(){const e="undefined"!=typeof navigator?navigator:void 0;return!0===e?.globalPrivacyControl}())return void(w?.isLogger&&console.warn("[TM]: 用户已选择退出采集(enableTracking=false 或 GPC 信号开启),本事件忽略"));if(!e||"object"!=typeof e)return void console.error("[TM]: track data must be an object");const t=!0===e.track_real_time,r=W(e);if(r)try{J(t&&l?T:v,r)}catch(e){Y("enqueue_failed","事件入队失败",{error:e})}},te=(e,t,r)=>{ee("string"==typeof e?{event_type:e,event_detail:t,...r}:e)},re=()=>{K(v,!0),K(T,!0);const e=[I.promise,$.promise].filter((e=>!!e));return Promise.all(e).then((()=>{}))},ne=()=>{w.isLogger=!0;try{localStorage.setItem(E,"true")}catch(e){console.error("[TM]: enable logger fail:",e)}},oe=()=>{w.isLogger=!1;try{localStorage.setItem(E,"false")}catch(e){console.error("[TM]: disable logger fail:",e)}};o((()=>{K(v,!0),K(T,!0)}));const ie=e=>("boolean"==typeof e&&(w.enableTracking=e,(e=>{try{localStorage.setItem(k,e?"1":"0")}catch(e){}})(e),e?w?.isLogger&&console.warn("[TM]: 恢复采集"):(z(v,[]),z(T,[]),w?.isLogger&&console.warn("[TM]: 用户已选择退出采集,已清空未上报队列"))),!0===w?.enableTracking);return window.trackMonitor={track:te,flush:re,bindUser:b,unBindUser:S,enableLogger:ne,disableLogger:oe,setToken:D,registerGlobalProperties:U,enableTracking:ie},{client:{track:te,flush:re,bindUser:b,unBindUser:S,enableLogger:ne,disableLogger:oe,setToken:D,registerGlobalProperties:U,enableTracking:ie},beforeClose:()=>{const e=()=>{O(),K(v,!0,!0),K(T,!0,!0)};window.addEventListener("beforeunload",e),window.addEventListener("pagehide",e),document.addEventListener("visibilitychange",(()=>{"hidden"===document.visibilityState&&e()})),window.addEventListener("online",e)}}},te=(re=16,function(){const e=new Uint8Array(re);if("undefined"!=typeof crypto&&"function"==typeof crypto.getRandomValues)crypto.getRandomValues(e);else for(let t=0;t<re;t++)e[t]=Math.floor(256*Math.random());let t="";for(let r=0;r<re;r++)t+=(e[r]<16?"0":"")+e[r].toString(16);return t})();var re;const ne=e=>{const t=history[e];return function(){const r=t.apply(this,arguments),n=new Event(e);return window.dispatchEvent(n),r}},oe=e=>{window.addEventListener("replaceState",(t=>e(t)),!0),window.addEventListener("pushState",(t=>e(t)),!0)},ie=e=>{window.addEventListener("popstate",(t=>e(t)),!0)},ae=[25,50,75,90],se=e=>{history.pushState=ne("pushState"),history.replaceState=ne("replaceState"),(()=>{let e="";const t=()=>{const t=window.location.href;if(t===e)return;const{host:r,hostname:n,href:o,protocol:i,origin:a,port:s,pathname:l,search:d,hash:u}=window.location,m={host:r,hostname:n,href:o,protocol:i,origin:a,port:s,pathname:l,search:d,hash:u,title:document.title,language:navigator.language.substring(0,2),user_agent:navigator.userAgent,win_screen:`${window.screen.width}x${window.screen.height}`,doc_screen:`${document.documentElement.clientWidth}x${document.documentElement.clientHeight}`,referrer:document.referrer,type:c()};window.trackMonitor.track({data_type:"auto",event_type:"page_view",event_detail:m}),e=t},r=i(t,200);t(),ie((()=>{r()})),oe((()=>{r()})),window.addEventListener("popstate",(()=>{r()}))})(),(()=>{let e=document.referrer,t=window.location.href,r=Date.now(),n=!0;const o=(n=!1)=>{if(window.location.href!==t||n){const n=Date.now()-r;n>200&&window.trackMonitor.track({data_type:"auto",event_type:"page_leave",event_detail:{url:t,referrer:e,duration:n}}),r=Date.now(),e=t,t=window.location.href}},a=i(o);o(),ie((()=>{a()})),oe((()=>{a()})),document.addEventListener("visibilitychange",(()=>{"hidden"===document.visibilityState?n&&(n=!1,o(!0)):(n=!0,r=Date.now())})),window.addEventListener("beforeunload",(()=>{n&&(n=!1,o(!0))}),!0)})(),(()=>{const e=a((e=>{const t=function(e){if(!e)return;if(["A","INPUT","TEXTAREA","BUTTON"].includes(e.tagName))return e;if(e.hasAttribute("track-click"))return e;return e.closest("a, button, [track-click]")||void 0}(e.target);if(!t)return;const r={element_id:t.id,element_content:t.textContent?.trim().slice(0,200)||null,element_class_name:t.className||null,element_name:t.getAttribute("name")||null,element_type:t.tagName.toLowerCase(),element_path:s(t),scroll_width:document.documentElement.scrollWidth,scroll_height:document.documentElement.scrollHeight,pageX:e.pageX,pageY:e.pageY,ratio:window.devicePixelRatio||1};window.trackMonitor.track({data_type:"auto",event_type:"click",event_detail:r})}));window.addEventListener("click",e,!0)})(),!1!==e?.enableScroll&&(()=>{const e=new Set,t=a((()=>{const r=document.documentElement,n=r.scrollHeight-r.clientHeight;if(n<=0)return;const o=Math.round((window.scrollY||r.scrollTop)/n*100),i=ae.filter((t=>o>=t&&!e.has(t)));i.length&&(i.forEach((t=>{e.add(t),window.trackMonitor.track({data_type:"auto",event_type:"scroll",event_detail:{scroll_depth:t}})})),e.has(90)&&window.removeEventListener("scroll",t))}),300);window.addEventListener("scroll",t,{passive:!0})})()};let ce=null,le=null;const de="track-expose",ue="track-view",me=e=>{try{le=new WeakMap}catch(e){console.error("[TM]: create WeakMap fail: ",e)}const t=(e,t=!1)=>{const n=le?.get(e);if(n&&!t)return;n&&(n.viewTimer&&clearTimeout(n.viewTimer),n.exposeTimer&&clearTimeout(n.exposeTimer));const o=e.dataset.durationView||500,i=e.dataset.durationExpose||500;le?.set(e,{duration_view:o,duration_expose:i,viewTimer:null,exposeTimer:null}),ce?.observe(e),t&&function(e){if(!(e instanceof Element))return!1;if(!function e(t){if(!t)return!0;const r=window.getComputedStyle(t);return"none"!==r.display&&"hidden"!==r.visibility&&0!==parseFloat(r.opacity)&&e(t.parentElement)}(e))return!1;const t=e.getBoundingClientRect();return t.top>=0&&t.left>=0&&t.bottom<=(window.innerHeight||document.documentElement.clientHeight)&&t.right<=(window.innerWidth||document.documentElement.clientWidth)}(e)&&r(e)},r=t=>{const r=le?.get(t);if(!r)return;const o=t.dataset.eventDetail,i=t.dataset.traceid??void 0,a=t.dataset.spm,s=t.hasAttribute("track-real-time"),c=t.hasAttribute(ue),l=t.hasAttribute(de);c&&l?r.exposeTimer=window.setTimeout((()=>{e({spm:a,request_id:i,data_type:"auto",event_type:"view_expose",event_detail:o,track_real_time:s}),t.removeAttribute(ue),r.exposeTimer=null}),parseInt(r.duration_expose,10)):(c&&(r.viewTimer=window.setTimeout((()=>{e({spm:a,request_id:i,data_type:"auto",event_type:"view",event_detail:o,track_real_time:s}),t.removeAttribute(ue),l&&r.exposeTimer||n(t),r.viewTimer=null}),parseInt(r.duration_view,10))),l&&(r.exposeTimer=window.setTimeout((()=>{e({spm:a,request_id:i,data_type:"auto",event_type:"expose",event_detail:o,track_real_time:s}),r.exposeTimer=null}),parseInt(r.duration_expose,10))))},n=e=>{const t=le?.get(e);t&&(ce?.unobserve(e),t.viewTimer&&clearTimeout(t.viewTimer),t.exposeTimer&&clearTimeout(t.exposeTimer),le?.delete(e))},o=e=>{e.forEach((e=>{const t=e.target,o=le?.get(t);o&&(o.viewTimer&&(clearTimeout(o.viewTimer),o.viewTimer=null),o.exposeTimer&&(clearTimeout(o.exposeTimer),o.exposeTimer=null),e.isIntersecting&&(r(t),t.hasAttribute(ue)||t.hasAttribute(de)||n(t)))}))};ce=(()=>{let e=null;try{e=new IntersectionObserver(o,{root:null,threshold:.5})}catch(e){console.error("[TM]: create IntersectionObserver fail: ",e)}return e})();new Set([...document.querySelectorAll(`[${de}]`),...document.querySelectorAll(`[${ue}]`)]).forEach((e=>t(e))),new MutationObserver((e=>{e.forEach((e=>{if("attributes"===e.type&&e.target instanceof HTMLElement){const r=e.target,o=e.attributeName,i=["data-event-detail","data-traceid","data-spm","data-duration-view","data-duration-expose"];r.hasAttribute(de)||r.hasAttribute(ue)?i.includes(o)?t(r,!0):o!==de&&o!==ue||t(r,!1):n(r)}else"childList"===e.type&&(e.addedNodes.forEach((e=>{if(e instanceof HTMLElement)if(e.hasAttribute(de)||e.hasAttribute(ue))t(e);else{new Set([...e.querySelectorAll(`[${de}]`),...e.querySelectorAll(`[${ue}]`)]).forEach((e=>t(e)))}})),e.removedNodes.forEach((e=>{if(e instanceof HTMLElement){const t=le?.get(e);if(t)n(e);else{new Set([...e.querySelectorAll(`[${de}]`),...e.querySelectorAll(`[${ue}]`)]).forEach((e=>n(e)))}}})))}))})).observe(document.body||document.documentElement,{attributes:!0,childList:!0,subtree:!0})},pe=/^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|address|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;function fe(e){const t=e.match(pe);if(!t)return{};return{filename:t[2],functionName:t[1]||"",lineno:parseInt(t[3],10)||void 0,colno:parseInt(t[4],10)||void 0}}function he(e){try{const{stack:t}=e;if(!t)return[];const r=[];for(const e of t.split("\n").slice(1)){const t=fe(e);!t||t.filename?.includes("chrome-extension://")||t.filename?.includes("node_modules")||t.filename?.includes("<anonymous>")||r.push(t)}return r.slice(0,10)}catch(e){return[]}}const ge=new Set,ye=(e,t)=>{if((r=w?.errorTraceRate??.5)<0||r>1?(console.warn("[TM]: probability should be between 0 and 1"),0):Math.random()<r){if(window.trackMonitor.track(t),ge.size>=1e3){const e=ge.values().next().value;void 0!==e&&ge.delete(e)}ge.add(e)}var r},we=()=>{window.addEventListener("error",(e=>{(e=>{if(e instanceof ErrorEvent&&"Script error."===e.message){const t=p("js-Script error.");if(ge.has(t))return;return void ye(t,{data_type:"error",event_type:"js",event_detail:{traceId:te,msg:'Script error.(跨域脚本未加载 crossorigin 属性,无法获取堆栈;建议脚本加 crossorigin="anonymous")',target:"",stack:[],errorUuid:t,meta:{filename:e.filename,colno:e.colno,lineno:e.lineno,crossorigin_missing:!0}}})}if("js"!==m(e))return;if((e=>{const t=e.error?.stack||"";return/chrome-extension:\/\//.test(t)})(e))return;const t=p(`js-${e.message}-${e.filename}`);if(ge.has(t))return;const r=he(e.error),n={traceId:te,msg:e.message,target:r[0]?`${r[0].filename?.split("?")[0]}:${r[0].lineno}:${r[0].colno}`:"",stack:r,errorUuid:t,meta:{filename:e.filename,colno:e.colno,lineno:e.lineno}};ye(t,{data_type:"error",event_type:"js",event_detail:n})})(e)}),!0)},ve=()=>{window.addEventListener("error",(e=>{(e=>{if("resource"!==m(e))return;const t=e.target,r=p(`resource-${t.src}-${t.tagName}`);if(ge.has(r))return;const n={traceId:te,msg:`加载${t.tagName}失败`,target:t.src?.split("?")[0],errorUuid:r,meta:{url:t.src,html:t.outerHTML,tagName:t.tagName}};ye(r,{data_type:"error",event_type:"resource",event_detail:n})})(e)}),!0)},Te=()=>{window.addEventListener("unhandledrejection",(e=>(e=>{const t=e.reason?.message||e.reason,r=p(`unhandledrejection-${t}`);if(ge.has(r))return;const n={traceId:te,msg:t,stack:he(e.reason),errorUuid:r};ye(r,{data_type:"error",event_type:"unhandledrejection",event_detail:n})})(e)),!0)},_e=()=>{const e=(e,t,r)=>{var n;if("string"!=typeof(n=e.url)||![w?.pushUrl,w?.authUrl,w?.realTimeUrl].filter((e=>!!e)).some((e=>0===n.indexOf(e))))if(t){const n=p(`http-${t}-${e.url}-${r}`);if(ge.has(n))return;const o={traceId:te,errorType:t,msg:r,target:e.url.split("?")[0],errorUuid:n,request:e};ye(n,{data_type:"error",event_type:"http",event_detail:o})}else if(e.status>=400){let r=e.statusText;const n=p(`http-${t="http_error"}-${e.url}-${r}`);if(ge.has(n))return;const o={traceId:te,errorUuid:n,errorType:t,target:e.url.split("?")[0],msg:r,request:e};ye(n,{data_type:"error",event_type:"http",event_detail:o})}};((e,t)=>{if("XMLHttpRequest"in window&&"function"==typeof window.XMLHttpRequest){const e=window.XMLHttpRequest;window.oXMLHttpRequest||(window.oXMLHttpRequest=e),window.XMLHttpRequest=function(){const r=new e,{open:n,send:o}=r;let i={};r.open=(e,t,o,a,s)=>{void 0===o&&(o=!0),i.method=e,i.url=t,n.call(r,e,t,o,a,s)},r.send=e=>{i.requestTime=(new Date).getTime(),o.call(r,e)};const a=(e,n)=>{const{status:o,statusText:a}=r,s=(new Date).getTime();i={...i,status:o,statusText:a,responseTime:s,duration:s-i.requestTime},"function"==typeof t&&t(i,e,n)};return r.addEventListener("loadend",(()=>a())),r.addEventListener("error",(()=>a("net_error","ERR_NETWORK"))),r.addEventListener("abort",(()=>a("cannel_request","ERR_CANCELED"))),r.addEventListener("timeout",(()=>a("timeout","ERR_NETWORK"))),r}}})(0,e),((e,t)=>{if("fetch"in window&&"function"==typeof window.fetch){const e=window.fetch;window.oFetch||(window.oFetch=e),window.fetch=async(r,n)=>{let o={};return o.method=n?.method||"",o.url=(r&&"string"!=typeof r?r?.url:r)||"",o.requestTime=(new Date).getTime(),e.call(window,r,n).then((async e=>{if("function"==typeof t){const r=e.clone(),n=(new Date).getTime();o={...o,status:r.status,statusText:r.statusText,responseTime:n,duration:n-o.requestTime},t(o)}return e})).catch((e=>{if("function"==typeof t){const r=(new Date).getTime();o={...o,responseTime:r,duration:r-o.requestTime},"AbortError"===e.name?t(o,"cannel_request","ERR_CANCELED"):t(o,"net_error","ERR_NETWORK")}return Promise.reject(e)}))}}})(0,e)};const be=new WeakSet,Se=e=>({form_id:e.id||null,form_class:"string"==typeof e.className?e.className:null,form_name:e.getAttribute("name")||null,form_action:e.getAttribute("action")||null,form_text:(e.textContent||"").trim().slice(0,200)||null});let Ee=-1;const ke=e=>{addEventListener("pageshow",(t=>{t.persisted&&(Ee=t.timeStamp,e(t))}),!0)},xe=(e,t,r,n)=>{let o,i;return a=>{t.value>=0&&(a||n)&&(i=t.value-(o??0),(i||void 0===o)&&(o=t.value,t.delta=i,t.rating=((e,t)=>e>t[1]?"poor":e>t[0]?"needs-improvement":"good")(t.value,r),e(t)))}},Me=e=>{requestAnimationFrame((()=>requestAnimationFrame((()=>e()))))},Ae=()=>{const e=performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},Le=()=>{const e=Ae();return e?.activationStart??0},Ce=(e,t=-1)=>{const r=Ae();let n="navigate";return Ee>=0?n="back-forward-cache":r&&(document.prerendering||Le()>0?n="prerender":document.wasDiscarded?n="restore":r.type&&(n=r.type.replace(/_/g,"-"))),{name:e,value:t,rating:"good",delta:0,entries:[],id:`v5-${Date.now()}-${Math.floor(8999999999999*Math.random())+1e12}`,navigationType:n}},Re=new WeakMap;function Ie(e,t){return Re.get(e)||Re.set(e,new t),Re.get(e)}class $e{t;i=0;o=[];h(e){if(e.hadRecentInput)return;const t=this.o[0],r=this.o.at(-1);this.i&&t&&r&&e.startTime-r.startTime<1e3&&e.startTime-t.startTime<5e3?(this.i+=e.value,this.o.push(e)):(this.i=e.value,this.o=[e]),this.t?.(e)}}const qe=(e,t,r={})=>{try{if(PerformanceObserver.supportedEntryTypes.includes(e)){const n=new PerformanceObserver((e=>{Promise.resolve().then((()=>{t(e.getEntries())}))}));return n.observe({type:e,buffered:!0,...r}),n}}catch{}},Ne=e=>{let t=!1;return()=>{t||(e(),t=!0)}};let Pe=-1;const Oe=new Set,Ue=()=>"hidden"!==document.visibilityState||document.prerendering?1/0:0,Be=e=>{if("hidden"===document.visibilityState){if("visibilitychange"===e.type)for(const e of Oe)e();isFinite(Pe)||(Pe="visibilitychange"===e.type?e.timeStamp:0,removeEventListener("prerenderingchange",Be,!0))}},ze=()=>{if(Pe<0){const e=Le(),t=document.prerendering?void 0:globalThis.performance.getEntriesByType("visibility-state").filter((t=>"hidden"===t.name&&t.startTime>e))[0]?.startTime;Pe=t??Ue(),addEventListener("visibilitychange",Be,!0),addEventListener("prerenderingchange",Be,!0),ke((()=>{setTimeout((()=>{Pe=Ue()}))}))}return{get firstHiddenTime(){return Pe},onHidden(e){Oe.add(e)}}},De=e=>{document.prerendering?addEventListener("prerenderingchange",(()=>e()),!0):e()},Fe=[1800,3e3],je=(e,t={})=>{De((()=>{const r=ze();let n,o=Ce("FCP");const i=qe("paint",(e=>{for(const t of e)"first-contentful-paint"===t.name&&(i.disconnect(),t.startTime<r.firstHiddenTime&&(o.value=Math.max(t.startTime-Le(),0),o.entries.push(t),n(!0)))}));i&&(n=xe(e,o,Fe,t.reportAllChanges),ke((r=>{o=Ce("FCP"),n=xe(e,o,Fe,t.reportAllChanges),Me((()=>{o.value=performance.now()-r.timeStamp,n(!0)}))})))}))},He=[.1,.25];let Je=0,Ke=1/0,We=0;const Xe=e=>{for(const t of e)t.interactionId&&(Ke=Math.min(Ke,t.interactionId),We=Math.max(We,t.interactionId),Je=We?(We-Ke)/7+1:0)};let Qe;const Ge=()=>Qe?Je:performance.interactionCount??0;let Ve=0;class Ye{u=[];l=new Map;m;p;v(){Ve=Ge(),this.u.length=0,this.l.clear()}L(){const e=Math.min(this.u.length-1,Math.floor((Ge()-Ve)/50));return this.u[e]}h(e){if(this.m?.(e),!e.interactionId&&"first-input"!==e.entryType)return;const t=this.u.at(-1);let r=this.l.get(e.interactionId);if(r||this.u.length<10||e.duration>t.P){if(r?e.duration>r.P?(r.entries=[e],r.P=e.duration):e.duration===r.P&&e.startTime===r.entries[0].startTime&&r.entries.push(e):(r={id:e.interactionId,entries:[e],P:e.duration},this.l.set(r.id,r),this.u.push(r)),this.u.sort(((e,t)=>t.P-e.P)),this.u.length>10){const e=this.u.splice(10);for(const t of e)this.l.delete(t.id)}this.p?.(r)}}}const Ze=e=>{const t=globalThis.requestIdleCallback||setTimeout;"hidden"===document.visibilityState?e():(e=Ne(e),addEventListener("visibilitychange",e,{once:!0,capture:!0}),t((()=>{e(),removeEventListener("visibilitychange",e,{capture:!0})})))},et=[200,500],tt=(e,t={})=>{if(!globalThis.PerformanceEventTiming||!("interactionId"in PerformanceEventTiming.prototype))return;const r=ze();De((()=>{"interactionCount"in performance||Qe||(Qe=qe("event",Xe,{type:"event",buffered:!0,durationThreshold:0}));let n,o=Ce("INP");const i=Ie(t,Ye),a=e=>{Ze((()=>{for(const t of e)i.h(t);const t=i.L();t&&t.P!==o.value&&(o.value=t.P,o.entries=t.entries,n())}))},s=qe("event",a,{durationThreshold:t.durationThreshold??40});n=xe(e,o,et,t.reportAllChanges),s&&(s.observe({type:"first-input",buffered:!0}),r.onHidden((()=>{a(s.takeRecords()),n(!0)})),ke((()=>{i.v(),o=Ce("INP"),n=xe(e,o,et,t.reportAllChanges)})))}))};class rt{m;h(e){this.m?.(e)}}const nt=[2500,4e3],ot=[800,1800],it=e=>{document.prerendering?De((()=>it(e))):"complete"!==document.readyState?addEventListener("load",(()=>it(e)),!0):setTimeout(e)};function at(){const e={ttfb:null,lcp:null,fp:null,fcp:null,connectionRtt:null,ttfbRequestTime:null,inp:null,cls:null,dcl:null,loadTime:null};((e,t={})=>{De((()=>{const r=ze();let n,o=Ce("LCP");const i=Ie(t,rt),a=e=>{t.reportAllChanges||(e=e.slice(-1));for(const t of e)i.h(t),t.startTime<r.firstHiddenTime&&(o.value=Math.max(t.startTime-Le(),0),o.entries=[t],n())},s=qe("largest-contentful-paint",a);if(s){n=xe(e,o,nt,t.reportAllChanges);const r=Ne((()=>{a(s.takeRecords()),s.disconnect(),n(!0)})),i=e=>{e.isTrusted&&(Ze(r),removeEventListener(e.type,i,{capture:!0}))};for(const e of["keydown","click","visibilitychange"])addEventListener(e,i,{capture:!0});ke((r=>{o=Ce("LCP"),n=xe(e,o,nt,t.reportAllChanges),Me((()=>{o.value=performance.now()-r.timeStamp,n(!0)}))}))}}))})((t=>{e.lcp=d(t.value)}),{reportAllChanges:!0}),((e,t={})=>{const r=ze();je(Ne((()=>{let n,o=Ce("CLS",0);const i=Ie(t,$e),a=e=>{for(const t of e)i.h(t);i.i>o.value&&(o.value=i.i,o.entries=i.o,n())},s=qe("layout-shift",a);s&&(n=xe(e,o,He,t.reportAllChanges),r.onHidden((()=>{a(s.takeRecords()),n(!0)})),ke((()=>{i.i=0,o=Ce("CLS",0),n=xe(e,o,He,t.reportAllChanges),Me((()=>n()))})),setTimeout(n))})))})((t=>{e.cls=Math.round(1e4*t.value)/1e4}),{reportAllChanges:!0}),tt((t=>{e.inp=d(t.value)}),{reportAllChanges:!0}),((e,t={})=>{let r=Ce("TTFB"),n=xe(e,r,ot,t.reportAllChanges);it((()=>{const o=Ae();o&&(r.value=Math.max(o.responseStart-Le(),0),r.entries=[o],n(!0),ke((()=>{r=Ce("TTFB",0),n=xe(e,r,ot,t.reportAllChanges),n(!0)})))}))})((t=>{e.ttfb=d(t.value)})),je((t=>{e.fcp=d(t.value)}));const t=()=>{(()=>{try{performance.getEntriesByType("paint").forEach((t=>{"first-paint"===t.name&&(e.fp=d(t.startTime))}))}catch(e){console.warn("[TM]: Failed to collect FP:",e)}try{const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection;t&&void 0!==t.rtt&&(e.connectionRtt=t.rtt)}catch(e){console.warn("[TM]: Failed to collect Connection RTT:",e)}try{const t=performance.getEntriesByType("navigation")[0];if(t){const{responseStart:r,requestStart:n}=t;r>0&&n>0&&n<=r&&(e.ttfbRequestTime=d(r-n))}}catch(e){console.warn("[TM]: Failed to collect TTFB Request Time:",e)}try{const t=performance.getEntriesByType("navigation")[0];if(t){const{domContentLoadedEventEnd:r,loadEventEnd:n,fetchStart:o}=t;r>0&&o>0&&(e.dcl=d(r-o)),n>0&&o>0&&(e.loadTime=d(n-o))}}catch(e){console.warn("[TM]: Failed to collect DCL and Load Time:",e)}})(),window.trackMonitor.track({data_type:"performance",event_type:"metrics",event_detail:{traceId:te,data:e}})};let r=0;const n=()=>{const e=Date.now();e-r<3e4||(r=e,t())};window.addEventListener("beforeunload",t),window.addEventListener("pagehide",n),document.addEventListener("visibilitychange",(()=>{"hidden"===document.visibilityState&&n()}))}const st="__tengence_sdk",ct=e=>{if("undefined"!=typeof window&&window.trackMonitor&&window.trackMonitor[st])return console.warn("[TM]: init 已调用过,复用现有实例(如需重建请刷新页面)"),window.trackMonitor;const{client:t,beforeClose:r}=ee(e);var n;return me(t.track),!1!==e.traceBehavior&&se({enableScroll:e.enableScroll}),!1!==e.enableFormTrack&&(n=t.track,document.addEventListener("focusin",(e=>{const t=e.target;if(!(r=t)||"INPUT"!==r.tagName&&"SELECT"!==r.tagName&&"TEXTAREA"!==r.tagName)return;var r;const o=t.closest("form");o&&!be.has(o)&&(be.add(o),n({data_type:"auto",event_type:"form_start",event_detail:Se(o)}))}),!0),document.addEventListener("submit",(e=>{const t=e.target;if(!t||"FORM"!==t.tagName)return;const r=e.submitter;n({data_type:"auto",event_type:"form_submit",event_detail:{...Se(t),submitter_id:r?.id||null,submitter_text:(r?.textContent||"").trim().slice(0,200)||null}})}),!0)),!1!==e.traceError&&(we(),ve(),Te(),_e()),!1!==e.tracePerformance&&l((()=>{!function(){const e=window.performance||window.msPerformance;if(!e)return{dnsLookupTime:null,tcpConnectTime:null,ttfb:null,transferTime:null,domParseTime:null,domCompleteTime:null,loadEventTime:null,totalPageLoad:null};const t=e.getEntriesByType&&"function"==typeof e.getEntriesByType?e.getEntriesByType("navigation"):void 0,r=Array.isArray(t)?t[0]:void 0;let n=null;if(r)n=r;else{const t=e.timing;t&&(n={startTime:0,domainLookupStart:t.domainLookupStart,domainLookupEnd:t.domainLookupEnd,connectStart:t.connectStart,connectEnd:t.connectEnd,requestStart:t.requestStart,responseStart:t.responseStart,responseEnd:t.responseEnd,domInteractive:t.domInteractive,domComplete:t.domComplete,loadEventEnd:t.loadEventEnd,fetchStart:t.fetchStart},!n.requestStart&&t.fetchStart&&(n.requestStart=t.fetchStart))}const o={dnsLookupTime:n?d(n.domainLookupEnd-n.domainLookupStart):null,tcpConnectTime:n?d(n.connectEnd-n.connectStart):null,ttfb:n?d(n.responseStart-(n.requestStart??n.fetchStart??0)):null,transferTime:n?d(n.responseEnd-n.responseStart):null,domParseTime:n?d(n.domInteractive-n.responseEnd):null,domCompleteTime:n?d(n.domComplete-n.domInteractive):null,loadEventTime:n?d(n.loadEventEnd-(n.domComplete??0)):null,totalPageLoad:n?d((n.loadEventEnd??performance.now())-(n.startTime??0)):null};window.trackMonitor.track({data_type:"performance",event_type:"navigation_timing",event_detail:{traceId:te,data:o}})}(),function(){const e=window.performance||window.msPerformance;if(!e)return[];const t=[];if(e.getEntriesByType){const r=(e.getEntriesByType("resource")||[]).map((e=>{const t="number"==typeof e.redirectEnd&&"number"==typeof e.redirectStart?d(e.redirectEnd-e.redirectStart):null,r="number"==typeof e.domainLookupEnd&&"number"==typeof e.domainLookupStart?d(e.domainLookupEnd-e.domainLookupStart):null,n="number"==typeof e.connectEnd&&"number"==typeof e.connectStart?d(e.connectEnd-e.connectStart):null,o="number"==typeof e.requestStart&&"number"==typeof e.fetchStart?d(e.requestStart-e.fetchStart):null,i="number"==typeof e.responseStart&&"number"==typeof e.requestStart?d(e.responseStart-e.requestStart):null,a="number"==typeof e.responseEnd&&"number"==typeof e.responseStart?d(e.responseEnd-e.responseStart):null,s="number"==typeof e.duration?d(e.duration):null,c="number"==typeof e.startTime?d(e.startTime):null,l="number"==typeof e.transferSize&&isFinite(e.transferSize)&&e.transferSize>=0?Math.round(e.transferSize):null,u="number"==typeof e.encodedBodySize&&isFinite(e.encodedBodySize)&&e.encodedBodySize>=0?Math.round(e.encodedBodySize):null,m="number"==typeof e.decodedBodySize&&isFinite(e.decodedBodySize)&&e.decodedBodySize>=0?Math.round(e.decodedBodySize):null;return{name:e.name,initiatorType:e.initiatorType||"",startTime:c,duration:s,redirectTime:t,cacheTime:o,dnsTime:r,connectTime:n,requestTime:i,responseTime:a,transferSize:l,encodedBodySize:u,decodedBodySize:m}}));r.sort(((e,t)=>(t.duration??0)-(e.duration??0)));const n=w?.resourceFlowLimit??15;if(0===n)return;for(let e=0;e<Math.min(n,r.length);e++)t.push(r[e]);if(!t.length)return}window.trackMonitor.track({data_type:"performance",event_type:"resource_flow",event_detail:{traceId:te,data:t}})}(),at()})),l((()=>{r()})),window.trackMonitor[st]=!0,window.trackMonitor};export{ct as default};
@@ -1,4 +1,4 @@
1
- export type DataType = "common" | "behavior" | "performance" | "error" | "custom";
1
+ export type DataType = "auto" | "behavior" | "performance" | "error" | "custom";
2
2
  export type EventType = "click" | "expose" | "view" | "cart" | "buy" | "pay" | "leave";
3
3
  export interface SanitizeOptions {
4
4
  stripQuery?: boolean;
@@ -29,6 +29,7 @@ export interface BaseOptions {
29
29
  enableScroll?: boolean;
30
30
  enableFormTrack?: boolean;
31
31
  errorTraceRate?: number;
32
+ resourceFlowLimit?: number;
32
33
  enableAutoSessionId?: boolean;
33
34
  enableTracking?: boolean;
34
35
  respectGpc?: boolean;
@@ -49,7 +50,7 @@ export interface SdkReportData {
49
50
  screen_height: number;
50
51
  lib_version: string;
51
52
  lib_type: string;
52
- event_time: string;
53
+ event_time: number;
53
54
  timezone_offset: string;
54
55
  }
55
56
  export interface ClientReportData {