flusterduck 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core.d.ts +14 -0
- package/dist/d.global.js +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.mjs +1 -0
- package/dist/queue.d.ts +6 -0
- package/dist/router.d.ts +5 -0
- package/dist/safe.d.ts +3 -0
- package/dist/script.d.ts +1 -0
- package/dist/selector.d.ts +2 -0
- package/dist/session.d.ts +2 -0
- package/dist/signals/dead-click.d.ts +2 -0
- package/dist/signals/error-encounter.d.ts +2 -0
- package/dist/signals/form-signals.d.ts +5 -0
- package/dist/signals/index.d.ts +12 -0
- package/dist/signals/keyboard-signals.d.ts +2 -0
- package/dist/signals/loop-nav.d.ts +5 -0
- package/dist/signals/mobile-signals.d.ts +2 -0
- package/dist/signals/rage-click.d.ts +5 -0
- package/dist/signals/scroll-bounce.d.ts +6 -0
- package/dist/signals/scroll-depth-abandon.d.ts +3 -0
- package/dist/signals/scroll-hijack.d.ts +2 -0
- package/dist/signals/speed-frustration.d.ts +4 -0
- package/dist/signals/thrash-cursor.d.ts +5 -0
- package/dist/snapshot.d.ts +3 -0
- package/dist/types.d.ts +120 -0
- package/package.json +42 -0
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Config, SDKEvent } from './types';
|
|
2
|
+
import { enqueue, flush } from './queue';
|
|
3
|
+
export declare function init(cfg: Config): void;
|
|
4
|
+
export declare function signal(name: string, data?: {
|
|
5
|
+
element?: string;
|
|
6
|
+
metadata?: Record<string, unknown>;
|
|
7
|
+
weight?: number;
|
|
8
|
+
}): void;
|
|
9
|
+
export declare function identify(segment: Record<string, string>): void;
|
|
10
|
+
export declare function setConsent(consented: boolean): void;
|
|
11
|
+
export declare function optOut(): void;
|
|
12
|
+
export declare function destroy(): void;
|
|
13
|
+
export { enqueue, flush };
|
|
14
|
+
export type { Config, SDKEvent };
|
package/dist/d.global.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(()=>{function t(t){return(...e)=>{try{return t(...e)}catch{}}}function e(t){return e=>{try{t(e)}catch{}}}var n="_fd_s",o=/^[0-9a-f]{32}$/;function r(){s(n,"",-1)}function i(){const t=new Uint8Array(16);crypto.getRandomValues(t);let e="";for(const n of t)e+=n.toString(16).padStart(2,"0");return e}function s(t,e,n){const o=new Date;o.setTime(o.getTime()+864e5*n);const r="https:"===location.protocol?";Secure":"";document.cookie=`${t}=${encodeURIComponent(e)};path=/;expires=${o.toUTCString()};SameSite=Lax${r}`}var a=/^[:\d]|--|^(ember|react|ng-|__)/;function c(t){if(!t||t===document.documentElement)return"html";const e=t.getAttribute("data-fd");if(e)return`[data-fd="${u(e)}"]`;if(t.id&&!a.test(t.id)&&t.id.length<64)return"#"+u(t.id);const n=[];let o=t,r=0;for(;o&&o!==document.body&&r<5;){let t=o.tagName.toLowerCase();const e=o.getAttribute("name"),i=o.getAttribute("role"),s=o.getAttribute("type");e&&e.length<64?t+=`[name="${u(e)}"]`:i?t+=`[role="${u(i)}"]`:!s||"input"!==t&&"button"!==t||(t+=`[type="${u(s)}"]`);const a=o.parentElement;if(a){const e=a.children;let n=0,r=0;for(let t=0;t<e.length;t++){const i=e[t];i&&i.tagName===o.tagName&&(n++,i===o&&(r=n))}n>1&&(t+=`:nth-of-type(${r})`)}n.unshift(t);const c=n.join(" > ");try{if(1===document.querySelectorAll(c).length)return c}catch(t){}o=a,r++}return n.join(" > ")}function u(t){return"undefined"!=typeof CSS&&CSS.escape?CSS.escape(t):t.replace(/([^\w-])/g,"\\$1")}function l(t,e){if(t.hasAttribute("data-fd-ignore"))return!0;if(t.closest("[data-fd-ignore]"))return!0;for(const n of e)try{if(t.matches(n)||t.closest(n))return!0}catch(t){}return!1}function d(t,e){return t&&e.includes(t)?t:null}function f(t){const e=t.tagName.toLowerCase();if("input"!==e&&"button"!==e)return null;const n=t.getAttribute("type");return n&&/^[a-z0-9_-]{1,32}$/i.test(n)?n.toLowerCase():null}function h(t){return t.top<window.innerHeight&&t.bottom>0&&t.left<window.innerWidth&&t.right>0}function p(t){if(/^(A|BUTTON|INPUT|SELECT|TEXTAREA)$/.test(t.tagName))return!0;const e=t.getAttribute("role");return!(!e||!/^(button|link|tab|menuitem|checkbox|radio)$/.test(e))}var m=[],w=null,b="",g=3e3,y=50,v=null,M={domMode:"off"},_=!1,k=new Set(["sid","key","url","page","ua","vw","vh","segment","environment"]),D=new Set(["click","move","scroll","keyboard","form_focus","form_blur","form_submit","touch","navigation","error","signal","pageview","custom_signal","performance","visibility","sdk_error"]),T=/(?:value|text|label|email|e-mail|name|phone|address|password|token|secret|cookie|session|jwt|auth|credential|card|cc|cvv|ssn)/i,A=/(?:[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}|\b(?:\d[ -]*?){13,19}\b)/i,x=e(()=>{"hidden"===document.visibilityState&&S()}),E=t(()=>S());function j(t){m.length>=50||(m.push(t),m.length>=y?S():w||(w=setTimeout(S,g)))}function S(){if(_)return;if(!m.length||!v)return;_=!0,w&&(clearTimeout(w),w=null);const t=m;m=[];const e={v:1,sid:v.sid,key:v.key,url:v.url,page:v.page,ts:Date.now(),ua:v.ua,vw:v.vw,vh:v.vh,environment:v.environment,dom_mode:M.domMode,events:t.map(t=>((t,e,n)=>{const o=t.d??{},r=(t=>"pv"===t?"pageview":"sig"===t?"signal":D.has(t)?t:"custom_signal")(t.t),i={type:r,ts:t.ts,page:"string"==typeof o.page?o.page.slice(0,2048):e},s=R(o.el,o.element,o.target);if("signal"===r){i.signal_type=R(o.s,o.signal_type,o.name)?.slice(0,128),s&&(i.element=s.slice(0,2048));const t=s?((t,e)=>{if("off"===e)return null;try{const n=document.querySelector(t);return n?((t,e)=>{if("off"===e)return null;if("metadata"===e)return(t=>({mode:"metadata",selector:c(t),tag:t.tagName.toLowerCase(),role:t.getAttribute("role"),attributes:{disabled:!0===t.disabled,required:!0===t.required,ariaDisabled:"true"===t.getAttribute("aria-disabled"),ariaExpanded:d(t.getAttribute("aria-expanded"),["true","false"]),ariaInvalid:d(t.getAttribute("aria-invalid"),["true","false","grammar","spelling"]),type:f(t)}}))(t);const n=(t=>{try{const e=t.getBoundingClientRect(),n=getComputedStyle(t),o=t.parentElement,r=[];if(o)for(let e=0;e<o.children.length&&r.length<6;e++){const n=o.children[e];if(!n||n===t)continue;const i=n.getBoundingClientRect();r.push({selector:c(n),tag:n.tagName.toLowerCase(),box:{x:Math.round(i.x),y:Math.round(i.y),w:Math.round(i.width),h:Math.round(i.height)},interactive:p(n)})}const i=[];try{const e=t.getAnimations();for(const t of e)"animationName"in t&&i.push(t.animationName)}catch{}return{selector:c(t),tag:t.tagName.toLowerCase(),role:t.getAttribute("role"),parent:o?c(o):"",box:{x:Math.round(e.x),y:Math.round(e.y),w:Math.round(e.width),h:Math.round(e.height)},styles:{opacity:n.opacity,cursor:n.cursor,pointerEvents:n.pointerEvents,display:n.display,visibility:n.visibility,disabled:!0===t.disabled},inView:h(e),animations:i,siblings:r}}catch{return null}})(t);return n?{mode:"snapshot",...n}:null})(n,e):null}catch{return null}})(s,n):null;t&&(i.dom=t)}const a=(t=>{const e=Object.create(null);for(const n of Object.keys(t)){if(["s","signal_type","name","el","element","target","dom","page","meta"].includes(n))continue;const o=U(t[n],n);void 0!==o&&(e[n.slice(0,64)]=o)}if(t.meta&&"object"==typeof t.meta&&!Array.isArray(t.meta)){const n=U(t.meta,"meta");n&&"object"==typeof n&&!Array.isArray(n)&&Object.assign(e,n)}return e})(o);return Object.keys(a).length&&(i.metadata=a),i})(t,v.page,M.domMode))};try{const t=JSON.stringify(e);t.length<=65536&&O(t,0)}catch{}_=!1}function $(t){if(v)for(const e of Object.keys(t))k.has(e)&&(v[e]=t[e])}function O(t,e){if(b){if(navigator.sendBeacon){const e=new Blob([t],{type:"application/json"});if(navigator.sendBeacon(b,e))return}try{fetch(b,{method:"POST",body:t,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{e<3&&setTimeout(()=>O(t,e+1),1e3*(e+1))})}catch{}}}function U(t,e="",n=0){if(!(n>4||T.test(e))){if(null===t||"boolean"==typeof t)return t;if("number"==typeof t)return Number.isFinite(t)?t:void 0;if("string"==typeof t){if(A.test(t))return;return t.slice(0,500)}if(Array.isArray(t))return t.slice(0,20).map(t=>U(t,e,n+1)).filter(t=>void 0!==t);if("object"==typeof t){const e=Object.create(null);for(const o of Object.keys(t).slice(0,40)){if("__proto__"===o||"constructor"===o||"prototype"===o)continue;const r=U(t[o],o,n+1);void 0!==r&&(e[o.slice(0,64)]=r)}return e}}}function R(...t){for(const e of t)if("string"==typeof e&&e)return e}function L(t,e){for(const n of e){const e=C(n.pattern);if(e&&e.test(t))return n.label}return(t=>t.replace(/\/\d+/g,"/:id").replace(/\/[a-f0-9-]{36}/g,"/:id"))(t)}var N=/^[a-zA-Z0-9/:._*\-]+$/;function C(t){if(t.length>200)return null;if(!N.test(t))return null;const e=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/:\w+/g,"[^/]+");try{return new RegExp("^"+e+"$")}catch{return null}}var I=[".carousel-arrow",".slick-arrow",".swiper-button-next",".swiper-button-prev","[data-carousel]",'button[aria-label*="next"]','button[aria-label*="prev"]','button[aria-label*="slide"]',".quantity-btn",".qty-btn",'input[type="number"]'],z=[],B=3,F=2e3,q=[],P=e(t=>{const e=t.target;if(!e)return;if(l(e,q))return;if((t=>{const e=t.tagName;return"VIDEO"===e||"AUDIO"===e||!!t.hasAttribute("ondblclick")})(e))return;const n=Date.now(),o=t.clientX,r=t.clientY;for(;z.length&&n-z[0].t>F;)z.shift();if(z.push({t:n,x:o,y:r,el:e}),z.length<B)return;const i=z.slice(-B),s=i[0];for(let t=1;t<i.length;t++){const e=i[t],n=e.x-s.x,o=e.y-s.y;if(n*n+o*o>64)return}const a=(i[i.length-1].t-s.t)/1e3,u=a>0?i.length/a:i.length;j({t:"sig",ts:n,d:{s:"rage_click",el:c(e),cnt:i.length,vel:Math.round(10*u)/10}}),z=[]}),X=/^(A|BUTTON|INPUT|SELECT|TEXTAREA|DETAILS|SUMMARY)$/,J=/^(button|link|tab|menuitem|checkbox|radio|switch|option|combobox|slider|spinbutton|textbox)$/,Z=/^(A|BUTTON|LABEL)$/,H=[],V=null,Y=e(t=>{V={x:t.clientX,y:t.clientY}}),G=e(t=>{if(0!==t.button)return;if(0===t.detail)return;const e=t.target;if(!e)return;if(l(e,H))return;if((()=>{const t=window.getSelection();return null!==t&&t.toString().length>0})())return;if((t=>{if(!V)return!1;const e=t.clientX-V.x,n=t.clientY-V.y;return Math.sqrt(e*e+n*n)>5})(t))return;if((t=>{if(X.test(t.tagName))return!0;const e=t.getAttribute("role");if(e&&J.test(e))return!0;if(t.hasAttribute("contenteditable"))return!0;if(t.hasAttribute("tabindex")&&"-1"!==t.getAttribute("tabindex"))return!0;if(t.hasAttribute("onclick")||t.hasAttribute("onmousedown")||t.hasAttribute("onmouseup"))return!0;const n=t.parentElement;if(n&&Z.test(n.tagName))return!0;if(t.closest('a, button, [role="button"], label, [onclick]'))return!0;try{if("pointer"===getComputedStyle(t).cursor)return!0}catch{return!1}return!1})(e))return;const n=((t,e,n)=>{const o=t.parentElement;if(!o)return null;const r=o.querySelectorAll('a, button, input, select, textarea, [role="button"], [tabindex]');let i=null,s=1/0;for(let t=0;t<r.length;t++){const o=r[t];if(!o)continue;const a=K(e,n,o);a<s&&(s=a,i=o)}return i})(e,t.clientX,t.clientY),o=n?K(t.clientX,t.clientY,n):-1;j({t:"sig",ts:Date.now(),d:{s:"dead_click",el:c(e),near:n?c(n):"",dist:Math.round(o)}})});function K(t,e,n){const o=n.getBoundingClientRect(),r=t-Math.max(o.left,Math.min(t,o.right)),i=e-Math.max(o.top,Math.min(e,o.bottom));return Math.sqrt(r*r+i*i)}var Q=null,W=3e3,tt=[],et=/^(A|BUTTON|INPUT|SELECT|TEXTAREA)$/,nt=/^(button|link|tab|menuitem|checkbox|radio|switch|option|combobox|slider|spinbutton)$/,ot=e(t=>{const e=t.target;if(!e)return;if(l(e,tt))return;const n=e.getAttribute("role");if(!(et.test(e.tagName)||n&&nt.test(n)))return;if(Q){if(Q.el===e||Q.el.contains(e)){const t=Date.now()-Q.ts;return t>=W&&j({t:"sig",ts:Date.now(),d:{s:"speed_frustration",el:Q.selector,delay:t}}),void rt()}rt()}const o=c(e);let r=!1;const i=new MutationObserver(t=>{for(const n of t){if("childList"===n.type&&(n.addedNodes.length>0||n.removedNodes.length>0))return r=!0,void rt();if("attributes"===n.type&&n.target instanceof Element&&(n.target===e||e.contains(n.target)||n.target.contains(e)))return r=!0,void rt()}}),s=e.parentElement||document.body;i.observe(s,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class","style","hidden","aria-hidden","disabled"]});const a=setTimeout(()=>{!r&&Q&&(Q={...Q,timeout:null})},W+500);Q={el:e,selector:o,ts:Date.now(),observer:i,timeout:a}});function rt(){Q&&(Q.observer.disconnect(),Q.timeout&&clearTimeout(Q.timeout),Q=null)}var it=800,st=2e3,at=0,ct=0,ut=0,lt=0,dt=0,ft=0,ht=0,pt=0,mt=[],wt=e(t=>{const e=Date.now();e-at<50||(at=e,((t,e,n)=>{if(0===lt)return ct=t,ut=e,lt=n,void(pt=n);const o=(n-lt)/1e3;if(0===o)return;const r=t-ct,i=e-ut,s=Math.sqrt(r*r+i*i)/o;mt.length>=100&&(mt=mt.slice(-50)),mt.push(s);const a=Math.sign(r),c=Math.sign(i);if((0!==dt&&0!==a&&a!==dt||0!==ft&&0!==c&&c!==ft)&&ht++,dt=a||dt,ft=c||ft,ct=t,ut=e,lt=n,n-pt>st){if(ht>=3){const t=mt.reduce((t,e)=>t+e,0)/mt.length;t>=it&&j({t:"sig",ts:n,d:{s:"thrash_cursor",vel:Math.round(t),rev:ht}})}bt(),pt=n}})(t.clientX,t.clientY,e))});function bt(){ht=0,mt=[],dt=0,ft=0,lt=0,ct=0,ut=0}var gt=[],yt=3e4,vt=1e4,Mt=.5,_t=[],kt=0,Dt=0,Tt=!1,At=0,xt=e(()=>{Tt||(Tt=!0,requestAnimationFrame(()=>{Tt=!1,(()=>{const t=Date.now(),e=window.scrollY;if((At=document.documentElement.scrollHeight-window.innerHeight)<=0)return;const n=e/At,o=e>kt?"down":"up";if(t-Dt<100)return void(kt=e);for(;_t.length&&t-_t[0].ts>vt;)_t.shift();_t.length>=100&&(_t=_t.slice(-50)),_t.push({depth:n,ts:t,direction:o}),kt=e,Dt=t;let r=0,i=1,s=0,a=!1;for(let t=0;t<_t.length;t++){const e=_t[t].depth;e>r&&(r=e),e>=Mt&&(a=!0),a&&e<i&&(i=e),a&&i<.25&&e>=Mt&&(s++,a=!1,i=1)}s>=1&&(j({t:"sig",ts:t,d:{s:"scroll_bounce",depth:Math.round(100*r)/100,rev:s+1}}),_t=[])})()}))}),Et=["textarea",'[role="textbox"]',"[contenteditable]"],jt=new Map,St=new Set,$t=null,Ot=0,Ut=5e3,Rt=[],Lt=e(t=>{const e=t.target;if(!e||!Ft(e))return;if(l(e,Rt))return;if((t=>{if("TEXTAREA"===t.tagName)return!0;for(const e of Et)try{if(t.matches(e))return!0}catch{return!1}return!1})(e))return;jt.set(e,Date.now());const n=e.closest("form");n&&n!==$t&&($t=n,Ot=n.querySelectorAll("input, select, textarea").length)}),Nt=e(t=>{const e=t.target;if(!e||!Ft(e))return;const n=jt.get(e);if(jt.delete(e),n){const t=Date.now()-n;t>=Ut&&j({t:"sig",ts:Date.now(),d:{s:"form_hesitation",el:c(e),pause:t}})}const o=e.getAttribute("name")||e.getAttribute("id")||c(e);(t=>"value"in t&&t.value.length>0)(e)&&St.add(o)}),Ct=e(()=>{St.clear(),$t=null}),It=t(Bt),zt=null;function Bt(){St.size>0&&$t&&(j({t:"sig",ts:Date.now(),d:{s:"form_abandon",filled:St.size,total:Ot||St.size}}),St.clear(),$t=null)}function Ft(t){const e=t.tagName;return"INPUT"===e||"SELECT"===e||"TEXTAREA"===e}var qt=null,Pt=null,Xt=/flusterduck\.com|\/v1\/ingest/,Jt=e(t=>{j({t:"sig",ts:Date.now(),d:{s:"error_encounter",type:"js_error",msg:Vt(t.message||"Unknown error",200),ep:"",status:0}})}),Zt=e(t=>{const e=t.reason instanceof Error?t.reason.message:String(t.reason??"");j({t:"sig",ts:Date.now(),d:{s:"error_encounter",type:"unhandled_rejection",msg:Vt(e,200),ep:"",status:0}})});function Ht(t){try{return new URL(t,location.origin).pathname}catch{const e=t.indexOf("?"),n=t.indexOf("#"),o=Math.min(e>=0?e:t.length,n>=0?n:t.length);return t.slice(0,o)||"/"}}function Vt(t,e){let n=t.length>e?t.slice(0,e):t;return n=n.replace(/(?:token|key|secret|password|auth|bearer|jwt|session|cookie|credential)[=:]\s*\S+/gi,"[REDACTED]"),n=n.replace(/https?:\/\/[^\s]*[?&][^\s]*/g,t=>{try{return new URL(t).origin+new URL(t).pathname}catch{return"[URL]"}}),n}var Yt=[".carousel",".slider",".swiper","[data-swipeable]",".drawer"],Gt=['[class*="map"]',"canvas",".gallery","[data-zoom]"],Kt=null,Qt=0,Wt=0,te=0,ee=0,ne=null,oe=[],re=e(t=>{const e=t.touches[0];1===t.touches.length&&e&&(Kt={x:e.clientX,y:e.clientY,ts:Date.now()})}),ie=e(t=>{if(!Kt)return;if(1!==t.changedTouches.length)return;const e=t.changedTouches[0];if(!e)return;const n=e.clientX-Kt.x,o=e.clientY-Kt.y,r=Date.now()-Kt.ts,i=document.elementFromPoint(e.clientX,e.clientY);Math.abs(n)<10&&Math.abs(o)<10&&r<300&&i&&((t,e,n)=>{if(l(t,oe))return;const o=((t,e,n)=>{const o=(t.parentElement||document.body).querySelectorAll('a, button, input, select, textarea, [role="button"], [tabindex]:not([tabindex="-1"])');let r=null,i=21;for(let t=0;t<o.length;t++){const s=o[t];if(!s)continue;const a=s.getBoundingClientRect(),c=Math.max(a.left,Math.min(e,a.right)),u=Math.max(a.top,Math.min(n,a.bottom)),l=Math.sqrt((e-c)**2+(n-u)**2);l<i&&l>0&&(i=l,r=s)}return r})(t,e,n);if(!o)return;const r=o.getBoundingClientRect(),i=Math.max(r.left,Math.min(e,r.right)),s=Math.max(r.top,Math.min(n,r.bottom)),a=Math.sqrt((e-i)**2+(n-s)**2);if(a>0&&a<=20){const t=`${Math.round(r.width)}x${Math.round(r.height)}`;j({t:"sig",ts:Date.now(),d:{s:"tap_miss",el:c(o),dist:Math.round(a),size:t}})}})(i,e.clientX,e.clientY),r<500&&(Math.abs(n)>50||Math.abs(o)>50)&&((t,e,n)=>{if(Math.abs(n)>Math.abs(e))return;if(!t)return;if(Yt.some(e=>{try{return t.matches(e)||t.closest(e)}catch{return!1}}))return;if(!Yt.some(t=>{try{return null!==document.querySelector(t)}catch{return!1}}))return;const o=e>0?"right":"left";j({t:"sig",ts:Date.now(),d:{s:"swipe_miss",dir:o}})})(i,n,o),Kt=null}),se=e(()=>{const t=Date.now();if(t-Wt>3e4&&(Qt=0,Wt=t),++Qt>=2){const e=document.activeElement||document.body;Gt.some(t=>{try{return e.matches(t)||e.closest(t)}catch{return!1}})||j({t:"sig",ts:t,d:{s:"pinch_zoom",cnt:Qt}}),Qt=0}}),ae=e(()=>{const t=Date.now(),e=screen.orientation?.type||"unknown";t-ee>3e4&&(te=0,ee=t),e!==ne&&(te++,ne=e),te>=3&&(j({t:"sig",ts:t,d:{s:"orientation_thrash",cnt:te}}),te=0)}),ce=e(()=>{const t=window.visualViewport;if(t&&t.scale>1.1){const t=Date.now();t-Wt>3e4&&(Qt=0,Wt=t),++Qt>=2&&(j({t:"sig",ts:t,d:{s:"pinch_zoom",cnt:Qt}}),Qt=0)}}),ue=[],le=null,de=0,fe=0,he=[],pe=e(t=>{const e=Date.now(),n=t.target;n&&l(n,[])||("Tab"===t.key?((t,e)=>{for(;ue.length&&t-ue[0].ts>5e3;)ue.shift();ue.length>=50&&(ue=ue.slice(-25));const n=e?c(e):"";if(ue.push({ts:t,el:n}),ue.length>=10){const e=ue.map(t=>t.el).filter(Boolean);j({t:"sig",ts:t,d:{s:"tab_thrash",cnt:ue.length,els:e}}),ue=[]}if(!e)return;const o=e.closest('[role="dialog"]')||e.closest('[role="menu"]')||e.closest(".modal")||e.closest('[aria-modal="true"]');o&&(o===le?t-fe<=3e3?++de>=5&&(j({t:"sig",ts:t,d:{s:"focus_trap",container:c(o),attempts:de}}),de=0,le=null):(fe=t,de=1):(le=o,fe=t,de=1))})(e,n):"Escape"===t.key?((t,e)=>{if(!e)return;const n=e.closest('[role="dialog"]')||e.closest('[role="menu"]')||e.closest(".modal")||e.closest('[aria-modal="true"]');n&&n===le&&++de>=5&&(j({t:"sig",ts:t,d:{s:"focus_trap",container:c(n),attempts:de}}),de=0,le=null)})(e,t.target):"ArrowDown"!==t.key&&"ArrowUp"!==t.key&&"ArrowLeft"!==t.key&&"ArrowRight"!==t.key||((t,e)=>{if(!e)return;const n=e.closest('[role="listbox"]')||e.closest('[role="menu"]')||e.closest('[role="tree"]')||e.closest("select");if(!n)return;for(;he.length&&t-he[0].ts>5e3;)he.shift();he.length>=50&&(he=he.slice(-25)),he.push({ts:t,container:n});const o=he.filter(t=>t.container===n);o.length>=15&&(j({t:"sig",ts:t,d:{s:"keyboard_nav_frustration",container:c(n),keys:o.length}}),he=[])})(e,t.target))}),me=0,we=0,be=null,ge=0,ye=!1,ve=e(()=>{ye||(ye=!0,requestAnimationFrame(()=>{ye=!1,(()=>{const t=Date.now(),e=window.scrollY,n=e-we;if(Math.abs(n)<2)return void(we=e);const o=n>0?"down":"up";be&&o!==be&&(t-ge>3e3&&(me=0,ge=t),++me>=4)&&Math.abs(n)>100&&(j({t:"sig",ts:t,d:{s:"scroll_hijack",rev:me}}),me=0),be=o,we=e})()}))}),Me=0,_e=!1,ke=e(()=>{_e||(_e=!0,requestAnimationFrame(()=>{_e=!1;const t=document.documentElement.scrollHeight-window.innerHeight;if(t>0){const e=window.scrollY/t;e>Me&&(Me=e)}}))}),De=t(Ae),Te=null;function Ae(){Me>.05&&j({t:"sig",ts:Date.now(),d:{s:"scroll_depth_abandon",depth:Math.round(100*Me)/100}})}var xe=!1,Ee=null,je=null;function Se(e){if(xe)return;if(!e.key)return;if(e.key.startsWith("fd_sec_"))return;if(!e.key.startsWith("fd_pub_"))return;if(!1!==e.respectDoNotTrack&&("1"===navigator.doNotTrack||navigator.globalPrivacyControl))return;if(void 0!==e.sampleRate&&e.sampleRate<1&&Math.random()>e.sampleRate)return;je=e,xe=!0;const r=(t=>{if(t)return i();const e=(()=>{const t=document.cookie.match(new RegExp("(?:^|; )_fd_s=([^;]*)"));return t?.[1]?decodeURIComponent(t[1]):null})();if(e&&o.test(e))return e;const r=i();return s(n,r,30),r})(e.cookieless??!1),a=(t=>{if(t)try{const e=new URL(t),n="http:"===e.protocol&&/^(localhost|127\.0\.0\.1|\[::1\])$/.test(e.hostname);if("https:"!==e.protocol&&!n)return;return e.origin+e.pathname}catch{return}})(e.endpoint)??"https://api.flusterduck.com/v1/ingest",c=L(location.pathname,e.pageRules??[]),u="metadata"===(l=e.domMode)||"snapshot"===l?l:"off";var l;((t,e,n,o,r)=>{var i;b=t,v=Object.assign(Object.create(null),e),M={domMode:(i=r?.domMode,"metadata"===i||"snapshot"===i?i:"off")},g=Math.max(1e3,Math.min(n??3e3,3e4)),y=Math.max(5,Math.min(o??50,50)),document.addEventListener("visibilitychange",x),window.addEventListener("pagehide",E)})(a,{sid:r,key:e.key,url:location.origin+location.pathname,page:c,ua:navigator.userAgent.slice(0,200),vw:window.innerWidth,vh:window.innerHeight,segment:e.segment,environment:e.environment},e.batchInterval,e.batchMaxSize,{domMode:u});const d=document.referrer;let f="";if(d)try{f=new URL(d).origin+new URL(d).pathname}catch{f=""}j({t:"pv",ts:Date.now(),d:{ref:f}});const h=e.ignoreElements??[],p=t=>{const n=e.signals?.[t];return!1!==n?.enabled};if(p("rageClick")&&((t,e)=>{B=t?.threshold??3,F=t?.windowMs??2e3,q=[...I,...e??[]],document.addEventListener("click",P,{capture:!0,passive:!0})})(e.signals?.rageClick,h),p("deadClick")&&(t=>{H=t??[],document.addEventListener("mousedown",Y,{capture:!0,passive:!0}),document.addEventListener("click",G,{capture:!0,passive:!0})})(h),p("speedFrustration")){const t=e.signals?.speedFrustration;((t,e)=>{W=t?.delayMs??3e3,tt=e??[],document.addEventListener("click",ot,{capture:!0,passive:!0})})(t?{delayMs:t.windowMs}:void 0,h)}var m;if(!1!==e.trackMouse&&p("thrashCursor")&&(m=e.signals?.thrashCursor,it=m?.velocityThreshold??800,st=m?.windowMs??2e3,document.addEventListener("mousemove",wt,{passive:!0})),p("loopNav")&&(t=>{yt=t?.windowMs??3e4})(e.signals?.loopNav),p("scrollBounce")&&(vt=1e4,Mt=.5,window.addEventListener("scroll",xt,{passive:!0})),!1!==e.trackForms&&(p("formHesitation")||p("formAbandon"))){const n=e.signals?.formHesitation;((e,n)=>{Ut=e?.pauseMs??5e3,Rt=n??[],document.addEventListener("focusin",Lt,{capture:!0,passive:!0}),document.addEventListener("focusout",Nt,{capture:!0,passive:!0}),document.addEventListener("submit",Ct,{capture:!0,passive:!0}),window.addEventListener("pagehide",It),zt=t(()=>{"hidden"===document.visibilityState&&Bt()}),document.addEventListener("visibilitychange",zt)})(n?{pauseMs:n.threshold}:void 0,h)}p("errorEncounter")&&(window.addEventListener("error",Jt),window.addEventListener("unhandledrejection",Zt),qt||(qt=window.fetch,Pt=function(t,e){let n;try{n=qt.call(this,t,e)}catch(t){throw t}return n.then(e=>{try{if(e.status>=400){const n="string"==typeof t?t:t instanceof URL?t.pathname:t.url;Xt.test(n)||j({t:"sig",ts:Date.now(),d:{s:"error_encounter",type:"network_error",msg:`${e.status} ${e.statusText}`,ep:Ht(n),status:e.status}})}}catch{}return e},e=>{try{const n="string"==typeof t?t:t instanceof URL?t.href:t.url;Xt.test(n)||j({t:"sig",ts:Date.now(),d:{s:"error_encounter",type:"network_error",msg:Vt(e instanceof Error?e.message:"Fetch failed",200),ep:"string"==typeof t?Ht(t):"",status:0}})}catch{}throw e})},window.fetch=Pt)),("ontouchstart"in window||navigator.maxTouchPoints>0)&&(t=>{oe=t??[],document.addEventListener("touchstart",re,{passive:!0}),document.addEventListener("touchend",ie,{passive:!0}),"ontouchstart"in window&&(document.addEventListener("gesturechange",se,{passive:!0}),window.addEventListener("orientationchange",ae,{passive:!0})),window.visualViewport?.addEventListener("resize",ce)})(h),(p("tabThrash")||p("focusTrap")||p("keyboardNavFrustration"))&&document.addEventListener("keydown",pe,{capture:!0,passive:!0}),p("scrollHijack")&&window.addEventListener("scroll",ve,{passive:!0}),p("scrollDepthAbandon")&&(window.addEventListener("scroll",ke,{passive:!0}),window.addEventListener("pagehide",De),Te=t(()=>{"hidden"===document.visibilityState&&Ae()}),document.addEventListener("visibilitychange",Te)),Ee=function(t){let e=location.href;function n(){const n=location.href;n!==e&&(e=n,t(n,location.pathname))}const o=history.pushState,r=history.replaceState,i=function(...t){o.apply(this,t),n()},s=function(...t){r.apply(this,t),n()};return history.pushState=i,history.replaceState=s,window.addEventListener("popstate",n),window.addEventListener("hashchange",n),()=>{history.pushState===i&&(history.pushState=o),history.replaceState===s&&(history.replaceState=r),window.removeEventListener("popstate",n),window.removeEventListener("hashchange",n)}}(t((t,n)=>{S(),_t=[],kt=0,Dt=0,jt.clear(),St.clear(),$t=null,Ot=0,Me=0,$({page:L(n,e.pageRules??[]),url:t}),(t=>{const e=Date.now();for(;gt.length&&e-gt[0].ts>yt;)gt.shift();if(gt.length>=100&&(gt=gt.slice(-50)),gt.push({path:t,ts:e}),gt.length<4)return;const n=t;let o=!1;const r=[];for(let t=gt.length-2;t>=1;t--)if(gt[t-1].path===n){const e=gt.slice(t-1,gt.length);for(const t of e)r.includes(t.path)||r.push(t.path);o=!0;break}o&&r.length>=2&&(j({t:"sig",ts:e,d:{s:"loop_nav",pages:r}}),gt=[{path:t,ts:e}])})(n),j({t:"pv",ts:Date.now(),d:{ref:""}})}))}function $e(t,e){if(!xe)return;if("string"!=typeof t||!t||t.length>128)return;let n;try{n=JSON.stringify(e?.metadata??{})}catch{return}if(n.length>2048)return;const o=JSON.parse(n);j({t:"sig",ts:Date.now(),d:{s:"custom",name:t.slice(0,128),el:"string"==typeof e?.element?e.element.slice(0,256):"",meta:o,w:Math.max(0,Math.min(e?.weight??15,100))}})}function Oe(t){if(!xe)return;if(!t||"object"!=typeof t)return;const e=Object.create(null);let n=0;for(const o of Object.keys(t)){if(n>=20)break;"__proto__"!==o&&"constructor"!==o&&"prototype"!==o&&(e[o.slice(0,64)]=String(t[o]).slice(0,256),n++)}$({segment:e})}function Ue(t){t&&je&&!xe?Se(je):t||(Le(),r())}function Re(){Le(),r()}function Le(){xe&&(document.removeEventListener("click",P,{capture:!0}),z=[],document.removeEventListener("mousedown",Y,{capture:!0}),document.removeEventListener("click",G,{capture:!0}),V=null,document.removeEventListener("click",ot,{capture:!0}),rt(),document.removeEventListener("mousemove",wt),bt(),gt=[],window.removeEventListener("scroll",xt),_t=[],document.removeEventListener("focusin",Lt,{capture:!0}),document.removeEventListener("focusout",Nt,{capture:!0}),document.removeEventListener("submit",Ct,{capture:!0}),window.removeEventListener("pagehide",It),zt&&(document.removeEventListener("visibilitychange",zt),zt=null),jt.clear(),St.clear(),$t=null,window.removeEventListener("error",Jt),window.removeEventListener("unhandledrejection",Zt),qt&&Pt&&window.fetch===Pt&&(window.fetch=qt),qt=null,Pt=null,document.removeEventListener("touchstart",re),document.removeEventListener("touchend",ie),document.removeEventListener("gesturechange",se),window.removeEventListener("orientationchange",ae),window.visualViewport?.removeEventListener("resize",ce),document.removeEventListener("keydown",pe,{capture:!0}),ue=[],he=[],le=null,window.removeEventListener("scroll",ve),me=0,we=0,be=null,ge=0,ye=!1,window.removeEventListener("scroll",ke),window.removeEventListener("pagehide",De),Te&&(document.removeEventListener("visibilitychange",Te),Te=null),Me=0,_e=!1,S(),document.removeEventListener("visibilitychange",x),window.removeEventListener("pagehide",E),w&&(clearTimeout(w),w=null),Ee&&(Ee(),Ee=null),xe=!1)}function Ne(t){if(t)try{const e=new URL(t),n="http:"===e.protocol&&/^(localhost|127\.0\.0\.1|\[::1\])$/.test(e.hostname);if("https:"!==e.protocol&&!n)return;return e.origin+e.pathname}catch{return}}(()=>{try{const t=window;if(t.flusterduck)return;const e=document.currentScript;if(!e)return;const n=e.getAttribute("data-key");if(!n)return;const o={key:n,environment:e.getAttribute("data-env")||void 0,endpoint:Ne(e.getAttribute("data-endpoint")),debug:"true"===e.getAttribute("data-debug"),cookieless:"true"===e.getAttribute("data-cookieless"),respectDoNotTrack:"false"!==e.getAttribute("data-dnt")},r=e.getAttribute("data-dom-mode");"metadata"!==r&&"snapshot"!==r||(o.domMode=r);const i=e.getAttribute("data-sample");if(i){const t=parseFloat(i);isNaN(t)||(o.sampleRate=Math.max(0,Math.min(t,1)))}const s=e.getAttribute("data-segment");if(s&&s.length<2048)try{const t=JSON.parse(s);if(t&&"object"==typeof t&&!Array.isArray(t)){const e=Object.create(null);for(const n of Object.keys(t))"__proto__"!==n&&"constructor"!==n&&"prototype"!==n&&(e[n]=String(t[n]));o.segment=e}}catch{}Se(o),t.flusterduck=Object.freeze({init:Se,signal:$e,identify:Oe,setConsent:Ue,optOut:Re,destroy:Le})}catch{}})()})();
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var fe=Object.defineProperty;var wn=Object.getOwnPropertyDescriptor;var En=Object.getOwnPropertyNames;var yn=Object.prototype.hasOwnProperty;var Sn=(e,t)=>{for(var n in t)fe(e,n,{get:t[n],enumerable:!0})},Mn=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of En(t))!yn.call(e,r)&&r!==n&&fe(e,r,{get:()=>t[r],enumerable:!(o=wn(t,r))||o.enumerable});return e};var Tn=e=>Mn(fe({},"__esModule",{value:!0}),e);var or={};Sn(or,{destroy:()=>ue,identify:()=>gn,init:()=>it,optOut:()=>bn,setConsent:()=>vn,signal:()=>hn});module.exports=Tn(or);function S(e){return(...t)=>{try{return e(...t)}catch{}}}function d(e){return t=>{try{e(t)}catch{}}}var me="_fd_s";var xn=/^[0-9a-f]{32}$/;function at(e){if(e)return st();let t=An(me);if(t&&xn.test(t))return t;let n=st();return ct(me,n,30),n}function pe(){ct(me,"",-1)}function st(){let e=new Uint8Array(16);crypto.getRandomValues(e);let t="";for(let n of e)t+=n.toString(16).padStart(2,"0");return t}function An(e){let t=document.cookie.match(new RegExp("(?:^|; )"+e+"=([^;]*)"));return t?.[1]?decodeURIComponent(t[1]):null}function ct(e,t,n){let o=new Date;o.setTime(o.getTime()+n*864e5);let r=location.protocol==="https:"?";Secure":"";document.cookie=`${e}=${encodeURIComponent(t)};path=/;expires=${o.toUTCString()};SameSite=Lax${r}`}var kn=/^[:\d]|--|^(ember|react|ng-|__)/;function f(e){if(!e||e===document.documentElement)return"html";let t=e.getAttribute("data-fd");if(t)return`[data-fd="${q(t)}"]`;if(e.id&&!kn.test(e.id)&&e.id.length<64)return"#"+q(e.id);let n=[],o=e,r=0;for(;o&&o!==document.body&&r<5;){let i=o.tagName.toLowerCase(),a=o.getAttribute("name"),s=o.getAttribute("role"),c=o.getAttribute("type");a&&a.length<64?i+=`[name="${q(a)}"]`:s?i+=`[role="${q(s)}"]`:c&&(i==="input"||i==="button")&&(i+=`[type="${q(c)}"]`);let l=o.parentElement;if(l){let g=l.children,b=0,j=0;for(let O=0;O<g.length;O++){let de=g[O];de&&de.tagName===o.tagName&&(b++,de===o&&(j=b))}b>1&&(i+=`:nth-of-type(${j})`)}n.unshift(i);let h=n.join(" > ");try{if(document.querySelectorAll(h).length===1)return h}catch{}o=l,r++}return n.join(" > ")}function q(e){return typeof CSS<"u"&&CSS.escape?CSS.escape(e):e.replace(/([^\w-])/g,"\\$1")}function w(e,t){if(e.hasAttribute("data-fd-ignore")||e.closest("[data-fd-ignore]"))return!0;for(let n of t)try{if(e.matches(n)||e.closest(n))return!0}catch{}return!1}function ut(e,t){if(t==="off")return null;if(t==="metadata")return Ln(e);let n=Dn(e);return n?{mode:"snapshot",...n}:null}function Ln(e){return{mode:"metadata",selector:f(e),tag:e.tagName.toLowerCase(),role:e.getAttribute("role"),attributes:{disabled:e.disabled===!0,required:e.required===!0,ariaDisabled:e.getAttribute("aria-disabled")==="true",ariaExpanded:lt(e.getAttribute("aria-expanded"),["true","false"]),ariaInvalid:lt(e.getAttribute("aria-invalid"),["true","false","grammar","spelling"]),type:Rn(e)}}}function Dn(e){try{let t=e.getBoundingClientRect(),n=getComputedStyle(e),o=e.parentElement,r=[];if(o)for(let a=0;a<o.children.length&&r.length<6;a++){let s=o.children[a];if(!s||s===e)continue;let c=s.getBoundingClientRect();r.push({selector:f(s),tag:s.tagName.toLowerCase(),box:{x:Math.round(c.x),y:Math.round(c.y),w:Math.round(c.width),h:Math.round(c.height)},interactive:Cn(s)})}let i=[];try{let a=e.getAnimations();for(let s of a)"animationName"in s&&i.push(s.animationName)}catch{}return{selector:f(e),tag:e.tagName.toLowerCase(),role:e.getAttribute("role"),parent:o?f(o):"",box:{x:Math.round(t.x),y:Math.round(t.y),w:Math.round(t.width),h:Math.round(t.height)},styles:{opacity:n.opacity,cursor:n.cursor,pointerEvents:n.pointerEvents,display:n.display,visibility:n.visibility,disabled:e.disabled===!0},inView:_n(t),animations:i,siblings:r}}catch{return null}}function lt(e,t){return e&&t.includes(e)?e:null}function Rn(e){let t=e.tagName.toLowerCase();if(t!=="input"&&t!=="button")return null;let n=e.getAttribute("type");return n&&/^[a-z0-9_-]{1,32}$/i.test(n)?n.toLowerCase():null}function _n(e){return e.top<window.innerHeight&&e.bottom>0&&e.left<window.innerWidth&&e.right>0}function Cn(e){let t=e.tagName;if(/^(A|BUTTON|INPUT|SELECT|TEXTAREA)$/.test(t))return!0;let n=e.getAttribute("role");return!!(n&&/^(button|link|tab|menuitem|checkbox|radio)$/.test(n))}var ft=3e3,mt=50,pt=50,On=3,Nn=65536,N=[],A=null,Z="",ht=ft,gt=mt,v=null,ge={domMode:"off"},he=!1,In=new Set(["sid","key","url","page","ua","vw","vh","segment","environment"]),Fn=new Set(["click","move","scroll","keyboard","form_focus","form_blur","form_submit","touch","navigation","error","signal","pageview","custom_signal","performance","visibility","sdk_error"]),Pn=/(?:value|text|label|email|e-mail|name|phone|address|password|token|secret|cookie|session|jwt|auth|credential|card|cc|cvv|ssn)/i,Un=/(?:[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}|\b(?:\d[ -]*?){13,19}\b)/i,vt=d(Hn),bt=S(()=>D());function wt(e,t,n,o,r){Z=e,v=Object.assign(Object.create(null),t),ge={domMode:Xn(r?.domMode)},ht=Math.max(1e3,Math.min(n??ft,3e4)),gt=Math.max(5,Math.min(o??mt,pt)),document.addEventListener("visibilitychange",vt),window.addEventListener("pagehide",bt)}function u(e){N.length>=pt||(N.push(e),N.length>=gt?D():A||(A=setTimeout(D,ht)))}function D(){if(he||!N.length||!v)return;he=!0,A&&(clearTimeout(A),A=null);let e=N;N=[];let t={v:1,sid:v.sid,key:v.key,url:v.url,page:v.page,ts:Date.now(),ua:v.ua,vw:v.vw,vh:v.vh,environment:v.environment,dom_mode:ge.domMode,events:e.map(n=>jn(n,v.page,ge.domMode))};try{let n=JSON.stringify(t);n.length<=Nn&&yt(n,0)}catch{}he=!1}function ve(e){if(v)for(let t of Object.keys(e))In.has(t)&&(v[t]=e[t])}function Et(){D(),document.removeEventListener("visibilitychange",vt),window.removeEventListener("pagehide",bt),A&&(clearTimeout(A),A=null)}function Hn(){document.visibilityState==="hidden"&&D()}function yt(e,t){if(Z){if(navigator.sendBeacon){let n=new Blob([e],{type:"application/json"});if(navigator.sendBeacon(Z,n))return}try{fetch(Z,{method:"POST",body:e,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{t<On&&setTimeout(()=>yt(e,t+1),1e3*(t+1))})}catch{}}}function jn(e,t,n){let o=e.d??{},r=qn(e.t),i={type:r,ts:e.ts,page:typeof o.page=="string"?o.page.slice(0,2048):t},a=dt(o.el,o.element,o.target);if(r==="signal"){i.signal_type=dt(o.s,o.signal_type,o.name)?.slice(0,128),a&&(i.element=a.slice(0,2048));let c=a?Vn(a,n):null;c&&(i.dom=c)}let s=Bn(o);return Object.keys(s).length&&(i.metadata=s),i}function qn(e){return e==="pv"?"pageview":e==="sig"?"signal":Fn.has(e)?e:"custom_signal"}function Bn(e){let t=Object.create(null);for(let n of Object.keys(e)){if(["s","signal_type","name","el","element","target","dom","page","meta"].includes(n))continue;let o=J(e[n],n);o!==void 0&&(t[n.slice(0,64)]=o)}if(e.meta&&typeof e.meta=="object"&&!Array.isArray(e.meta)){let n=J(e.meta,"meta");n&&typeof n=="object"&&!Array.isArray(n)&&Object.assign(t,n)}return t}function J(e,t="",n=0){if(!(n>4)&&!Pn.test(t)){if(e===null||typeof e=="boolean")return e;if(typeof e=="number")return Number.isFinite(e)?e:void 0;if(typeof e=="string")return Un.test(e)?void 0:e.slice(0,500);if(Array.isArray(e))return e.slice(0,20).map(r=>J(r,t,n+1)).filter(r=>r!==void 0);if(typeof e=="object"){let o=Object.create(null);for(let r of Object.keys(e).slice(0,40)){if(r==="__proto__"||r==="constructor"||r==="prototype")continue;let i=J(e[r],r,n+1);i!==void 0&&(o[r.slice(0,64)]=i)}return o}}}function Vn(e,t){if(t==="off")return null;try{let n=document.querySelector(e);return n?ut(n,t):null}catch{return null}}function dt(...e){for(let t of e)if(typeof t=="string"&&t)return t}function Xn(e){return e==="metadata"||e==="snapshot"?e:"off"}function St(e){let t=location.href;function n(){let s=location.href;s!==t&&(t=s,e(s,location.pathname))}let o=history.pushState,r=history.replaceState,i=function(...s){o.apply(this,s),n()},a=function(...s){r.apply(this,s),n()};return history.pushState=i,history.replaceState=a,window.addEventListener("popstate",n),window.addEventListener("hashchange",n),function(){history.pushState===i&&(history.pushState=o),history.replaceState===a&&(history.replaceState=r),window.removeEventListener("popstate",n),window.removeEventListener("hashchange",n)}}function be(e,t){for(let n of t){let o=$n(n.pattern);if(o&&o.test(e))return n.label}return zn(e)}var Yn=/^[a-zA-Z0-9/:._*\-]+$/;function $n(e){if(e.length>200||!Yn.test(e))return null;let t=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/:\w+/g,"[^/]+");try{return new RegExp("^"+t+"$")}catch{return null}}function zn(e){return e.replace(/\/\d+/g,"/:id").replace(/\/[a-f0-9-]{36}/g,"/:id")}var Kn=[".carousel-arrow",".slick-arrow",".swiper-button-next",".swiper-button-prev","[data-carousel]",'button[aria-label*="next"]','button[aria-label*="prev"]','button[aria-label*="slide"]',".quantity-btn",".qty-btn",'input[type="number"]'],k=[],we=3,Tt=2e3,Mt=8,xt=[],At=d(Wn);function Ee(e,t){we=e?.threshold??3,Tt=e?.windowMs??2e3,xt=[...Kn,...t??[]],document.addEventListener("click",At,{capture:!0,passive:!0})}function ye(){document.removeEventListener("click",At,{capture:!0}),k=[]}function Wn(e){let t=e.target;if(!t||w(t,xt)||Qn(t))return;let n=Date.now(),o=e.clientX,r=e.clientY;for(;k.length&&n-k[0].t>Tt;)k.shift();if(k.push({t:n,x:o,y:r,el:t}),k.length<we)return;let i=k.slice(-we),a=i[0];for(let g=1;g<i.length;g++){let b=i[g],j=b.x-a.x,O=b.y-a.y;if(j*j+O*O>Mt*Mt)return}let s=a.t,l=(i[i.length-1].t-s)/1e3,h=l>0?i.length/l:i.length;u({t:"sig",ts:n,d:{s:"rage_click",el:f(t),cnt:i.length,vel:Math.round(h*10)/10}}),k=[]}function Qn(e){let t=e.tagName;return!!(t==="VIDEO"||t==="AUDIO"||e.hasAttribute("ondblclick"))}var Gn=/^(A|BUTTON|INPUT|SELECT|TEXTAREA|DETAILS|SUMMARY)$/,Zn=/^(button|link|tab|menuitem|checkbox|radio|switch|option|combobox|slider|spinbutton|textbox)$/,Jn=/^(A|BUTTON|LABEL)$/,kt=[],B=null,eo=5,Lt=d(to),Dt=d(no);function to(e){B={x:e.clientX,y:e.clientY}}function Se(e){kt=e??[],document.addEventListener("mousedown",Lt,{capture:!0,passive:!0}),document.addEventListener("click",Dt,{capture:!0,passive:!0})}function Me(){document.removeEventListener("mousedown",Lt,{capture:!0}),document.removeEventListener("click",Dt,{capture:!0}),B=null}function no(e){if(e.button!==0||e.detail===0)return;let t=e.target;if(!t||w(t,kt)||io()||so(e)||oo(t))return;let n=ro(t,e.clientX,e.clientY),o=n?Rt(e.clientX,e.clientY,n):-1;u({t:"sig",ts:Date.now(),d:{s:"dead_click",el:f(t),near:n?f(n):"",dist:Math.round(o)}})}function oo(e){if(Gn.test(e.tagName))return!0;let t=e.getAttribute("role");if(t&&Zn.test(t)||e.hasAttribute("contenteditable")||e.hasAttribute("tabindex")&&e.getAttribute("tabindex")!=="-1"||e.hasAttribute("onclick")||e.hasAttribute("onmousedown")||e.hasAttribute("onmouseup"))return!0;let n=e.parentElement;if(n&&Jn.test(n.tagName)||e.closest('a, button, [role="button"], label, [onclick]'))return!0;try{if(getComputedStyle(e).cursor==="pointer")return!0}catch{return!1}return!1}function ro(e,t,n){let o=e.parentElement;if(!o)return null;let r=o.querySelectorAll('a, button, input, select, textarea, [role="button"], [tabindex]'),i=null,a=1/0;for(let s=0;s<r.length;s++){let c=r[s];if(!c)continue;let l=Rt(t,n,c);l<a&&(a=l,i=c)}return i}function Rt(e,t,n){let o=n.getBoundingClientRect(),r=Math.max(o.left,Math.min(e,o.right)),i=Math.max(o.top,Math.min(t,o.bottom)),a=e-r,s=t-i;return Math.sqrt(a*a+s*s)}function io(){let e=window.getSelection();return e!==null&&e.toString().length>0}function so(e){if(!B)return!1;let t=e.clientX-B.x,n=e.clientY-B.y;return Math.sqrt(t*t+n*n)>eo}var m=null,Te=3e3,_t=[],ao=/^(A|BUTTON|INPUT|SELECT|TEXTAREA)$/,co=/^(button|link|tab|menuitem|checkbox|radio|switch|option|combobox|slider|spinbutton)$/,Ct=d(lo);function xe(e,t){Te=e?.delayMs??3e3,_t=t??[],document.addEventListener("click",Ct,{capture:!0,passive:!0})}function Ae(){document.removeEventListener("click",Ct,{capture:!0}),V()}function lo(e){let t=e.target;if(!t||w(t,_t))return;let n=t.getAttribute("role");if(!ao.test(t.tagName)&&!(n&&co.test(n)))return;if(m){if(m.el===t||m.el.contains(t)){let c=Date.now()-m.ts;c>=Te&&u({t:"sig",ts:Date.now(),d:{s:"speed_frustration",el:m.selector,delay:c}}),V();return}V()}let o=f(t),r=!1,i=new MutationObserver(c=>{for(let l of c){if(l.type==="childList"&&(l.addedNodes.length>0||l.removedNodes.length>0)){r=!0,V();return}if(l.type==="attributes"&&l.target instanceof Element&&(l.target===t||t.contains(l.target)||l.target.contains(t))){r=!0,V();return}}}),a=t.parentElement||document.body;i.observe(a,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class","style","hidden","aria-hidden","disabled"]});let s=setTimeout(()=>{!r&&m&&(m={...m,timeout:null})},Te+500);m={el:t,selector:o,ts:Date.now(),observer:i,timeout:s}}function V(){m&&(m.observer.disconnect(),m.timeout&&clearTimeout(m.timeout),m=null)}var uo=100,Nt=800,It=2e3,fo=3,Ot=0,mo=50,ee=0,te=0,X=0,Y=0,$=0,ne=0,ke=0,R=[],Ft=d(po);function Le(e){Nt=e?.velocityThreshold??800,It=e?.windowMs??2e3,document.addEventListener("mousemove",Ft,{passive:!0})}function De(){document.removeEventListener("mousemove",Ft),Pt()}function po(e){let t=Date.now();t-Ot<mo||(Ot=t,ho(e.clientX,e.clientY,t))}function ho(e,t,n){if(X===0){ee=e,te=t,X=n,ke=n;return}let o=(n-X)/1e3;if(o===0)return;let r=e-ee,i=t-te,s=Math.sqrt(r*r+i*i)/o;R.length>=uo&&(R=R.slice(-50)),R.push(s);let c=Math.sign(r),l=Math.sign(i);if((Y!==0&&c!==0&&c!==Y||$!==0&&l!==0&&l!==$)&&ne++,Y=c||Y,$=l||$,ee=e,te=t,X=n,n-ke>It){if(ne>=fo){let h=R.reduce((g,b)=>g+b,0)/R.length;h>=Nt&&u({t:"sig",ts:n,d:{s:"thrash_cursor",vel:Math.round(h),rev:ne}})}Pt(),ke=n}}function Pt(){ne=0,R=[],Y=0,$=0,X=0,ee=0,te=0}var go=100,p=[],Ut=3e4;function Re(e){Ut=e?.windowMs??3e4}function _e(){p=[]}function Ce(e){let t=Date.now();for(;p.length&&t-p[0].ts>Ut;)p.shift();if(p.length>=go&&(p=p.slice(-50)),p.push({path:e,ts:t}),p.length<4)return;let n=e,o=!1,r=[];for(let i=p.length-2;i>=1;i--)if(p[i-1].path===n){let a=p.slice(i-1,p.length);for(let s of a)r.includes(s.path)||r.push(s.path);o=!0;break}o&&r.length>=2&&(u({t:"sig",ts:t,d:{s:"loop_nav",pages:r}}),p=[{path:e,ts:t}])}var vo=100,Ht=1e4,Ie=.5,E=[],oe=0,Fe=0,Oe=!1,Ne=0,jt=d(bo);function Pe(e){Ht=e?.windowMs??1e4,Ie=e?.depthThreshold??.5,window.addEventListener("scroll",jt,{passive:!0})}function Ue(){window.removeEventListener("scroll",jt),E=[]}function He(){E=[],oe=0,Fe=0}function bo(){Oe||(Oe=!0,requestAnimationFrame(()=>{Oe=!1,wo()}))}function wo(){let e=Date.now(),t=window.scrollY;if(Ne=document.documentElement.scrollHeight-window.innerHeight,Ne<=0)return;let n=t/Ne,o=t>oe?"down":"up";if(e-Fe<100){oe=t;return}for(;E.length&&e-E[0].ts>Ht;)E.shift();E.length>=vo&&(E=E.slice(-50)),E.push({depth:n,ts:e,direction:o}),oe=t,Fe=e;let r=0,i=1,a=0,s=!1;for(let c=0;c<E.length;c++){let l=E[c].depth;l>r&&(r=l),l>=Ie&&(s=!0),s&&l<i&&(i=l),s&&i<.25&&l>=Ie&&(a++,s=!1,i=1)}a>=1&&(u({t:"sig",ts:e,d:{s:"scroll_bounce",depth:Math.round(r*100)/100,rev:a+1}}),E=[])}var Eo=["textarea",'[role="textbox"]',"[contenteditable]"],K=new Map,L=new Set,_=null,je=0,qt=5e3,Bt=[],Vt=d(yo),Xt=d(So),Yt=d(Mo),$t=S(zt),z=null;function qe(e,t){qt=e?.pauseMs??5e3,Bt=t??[],document.addEventListener("focusin",Vt,{capture:!0,passive:!0}),document.addEventListener("focusout",Xt,{capture:!0,passive:!0}),document.addEventListener("submit",Yt,{capture:!0,passive:!0}),window.addEventListener("pagehide",$t),z=S(()=>{document.visibilityState==="hidden"&&zt()}),document.addEventListener("visibilitychange",z)}function Be(){document.removeEventListener("focusin",Vt,{capture:!0}),document.removeEventListener("focusout",Xt,{capture:!0}),document.removeEventListener("submit",Yt,{capture:!0}),window.removeEventListener("pagehide",$t),z&&(document.removeEventListener("visibilitychange",z),z=null),K.clear(),L.clear(),_=null}function Ve(){K.clear(),L.clear(),_=null,je=0}function yo(e){let t=e.target;if(!t||!Kt(t)||w(t,Bt)||To(t))return;K.set(t,Date.now());let n=t.closest("form");n&&n!==_&&(_=n,je=n.querySelectorAll("input, select, textarea").length)}function So(e){let t=e.target;if(!t||!Kt(t))return;let n=K.get(t);if(K.delete(t),n){let r=Date.now()-n;r>=qt&&u({t:"sig",ts:Date.now(),d:{s:"form_hesitation",el:f(t),pause:r}})}let o=t.getAttribute("name")||t.getAttribute("id")||f(t);xo(t)&&L.add(o)}function Mo(){L.clear(),_=null}function zt(){L.size>0&&_&&(u({t:"sig",ts:Date.now(),d:{s:"form_abandon",filled:L.size,total:je||L.size}}),L.clear(),_=null)}function Kt(e){let t=e.tagName;return t==="INPUT"||t==="SELECT"||t==="TEXTAREA"}function To(e){if(e.tagName==="TEXTAREA")return!0;for(let t of Eo)try{if(e.matches(t))return!0}catch{return!1}return!1}function xo(e){return"value"in e?e.value.length>0:!1}var I=null,W=null,Wt=/flusterduck\.com|\/v1\/ingest/,Gt=d(Ao),Zt=d(ko);function Xe(){window.addEventListener("error",Gt),window.addEventListener("unhandledrejection",Zt),Lo()}function Ye(){window.removeEventListener("error",Gt),window.removeEventListener("unhandledrejection",Zt),Do()}function Ao(e){u({t:"sig",ts:Date.now(),d:{s:"error_encounter",type:"js_error",msg:$e(e.message||"Unknown error",200),ep:"",status:0}})}function ko(e){let t=e.reason instanceof Error?e.reason.message:String(e.reason??"");u({t:"sig",ts:Date.now(),d:{s:"error_encounter",type:"unhandled_rejection",msg:$e(t,200),ep:"",status:0}})}function Lo(){I||(I=window.fetch,W=function(t,n){let o;try{o=I.call(this,t,n)}catch(r){throw r}return o.then(r=>{try{if(r.status>=400){let i=typeof t=="string"?t:t instanceof URL?t.pathname:t.url;Wt.test(i)||u({t:"sig",ts:Date.now(),d:{s:"error_encounter",type:"network_error",msg:`${r.status} ${r.statusText}`,ep:Qt(i),status:r.status}})}}catch{}return r},r=>{try{let i=typeof t=="string"?t:t instanceof URL?t.href:t.url;Wt.test(i)||u({t:"sig",ts:Date.now(),d:{s:"error_encounter",type:"network_error",msg:$e(r instanceof Error?r.message:"Fetch failed",200),ep:typeof t=="string"?Qt(t):"",status:0}})}catch{}throw r})},window.fetch=W)}function Do(){I&&W&&window.fetch===W&&(window.fetch=I),I=null,W=null}function Qt(e){try{return new URL(e,location.origin).pathname}catch{let t=e.indexOf("?"),n=e.indexOf("#"),o=Math.min(t>=0?t:e.length,n>=0?n:e.length);return e.slice(0,o)||"/"}}function $e(e,t){let n=e.length>t?e.slice(0,t):e;return n=n.replace(/(?:token|key|secret|password|auth|bearer|jwt|session|cookie|credential)[=:]\s*\S+/gi,"[REDACTED]"),n=n.replace(/https?:\/\/[^\s]*[?&][^\s]*/g,o=>{try{return new URL(o).origin+new URL(o).pathname}catch{return"[URL]"}}),n}var Jt=[".carousel",".slider",".swiper","[data-swipeable]",".drawer"],Ro=['[class*="map"]',"canvas",".gallery","[data-zoom]"],F=null,M=0,re=0,Q=0,en=0,tn=null,nn=[],on=d(_o),rn=d(Co),sn=d(Io),an=d(Po),cn=d(Fo);function ze(e){nn=e??[],document.addEventListener("touchstart",on,{passive:!0}),document.addEventListener("touchend",rn,{passive:!0}),"ontouchstart"in window&&(document.addEventListener("gesturechange",sn,{passive:!0}),window.addEventListener("orientationchange",an,{passive:!0})),window.visualViewport?.addEventListener("resize",cn)}function Ke(){document.removeEventListener("touchstart",on),document.removeEventListener("touchend",rn),document.removeEventListener("gesturechange",sn),window.removeEventListener("orientationchange",an),window.visualViewport?.removeEventListener("resize",cn)}function _o(e){let t=e.touches[0];e.touches.length===1&&t&&(F={x:t.clientX,y:t.clientY,ts:Date.now()})}function Co(e){if(!F||e.changedTouches.length!==1)return;let t=e.changedTouches[0];if(!t)return;let n=t.clientX-F.x,o=t.clientY-F.y,r=Date.now()-F.ts,i=document.elementFromPoint(t.clientX,t.clientY);Math.abs(n)<10&&Math.abs(o)<10&&r<300&&i&&Oo(i,t.clientX,t.clientY),r<500&&(Math.abs(n)>50||Math.abs(o)>50)&&No(i,n,o),F=null}function Oo(e,t,n){if(w(e,nn))return;let o=Uo(e,t,n);if(!o)return;let r=o.getBoundingClientRect(),i=Math.max(r.left,Math.min(t,r.right)),a=Math.max(r.top,Math.min(n,r.bottom)),s=Math.sqrt((t-i)**2+(n-a)**2);if(s>0&&s<=20){let c=`${Math.round(r.width)}x${Math.round(r.height)}`;u({t:"sig",ts:Date.now(),d:{s:"tap_miss",el:f(o),dist:Math.round(s),size:c}})}}function No(e,t,n){if(Math.abs(n)>Math.abs(t)||!e||Jt.some(a=>{try{return e.matches(a)||e.closest(a)}catch{return!1}})||!Jt.some(a=>{try{return document.querySelector(a)!==null}catch{return!1}}))return;let i=t>0?"right":"left";u({t:"sig",ts:Date.now(),d:{s:"swipe_miss",dir:i}})}function Io(){let e=Date.now();if(e-re>3e4&&(M=0,re=e),M++,M>=2){let t=document.activeElement||document.body;Ro.some(o=>{try{return t.matches(o)||t.closest(o)}catch{return!1}})||u({t:"sig",ts:e,d:{s:"pinch_zoom",cnt:M}}),M=0}}function Fo(){let e=window.visualViewport;if(e&&e.scale>1.1){let t=Date.now();t-re>3e4&&(M=0,re=t),M++,M>=2&&(u({t:"sig",ts:t,d:{s:"pinch_zoom",cnt:M}}),M=0)}}function Po(){let e=Date.now(),t=screen.orientation?.type||"unknown";e-en>3e4&&(Q=0,en=e),t!==tn&&(Q++,tn=t),Q>=3&&(u({t:"sig",ts:e,d:{s:"orientation_thrash",cnt:Q}}),Q=0)}function Uo(e,t,n){let r=(e.parentElement||document.body).querySelectorAll('a, button, input, select, textarea, [role="button"], [tabindex]:not([tabindex="-1"])'),i=null,a=21;for(let s=0;s<r.length;s++){let c=r[s];if(!c)continue;let l=c.getBoundingClientRect(),h=Math.max(l.left,Math.min(t,l.right)),g=Math.max(l.top,Math.min(n,l.bottom)),b=Math.sqrt((t-h)**2+(n-g)**2);b<a&&b>0&&(a=b,i=c)}return i}var y=[],P=null,x=0,We=0,T=[],Ho=10,jo=5e3,ln=5,qo=3e3,Bo=15,Vo=5e3,un=d(Xo);function Qe(){document.addEventListener("keydown",un,{capture:!0,passive:!0})}function Ge(){document.removeEventListener("keydown",un,{capture:!0}),y=[],T=[],P=null}function Xo(e){let t=Date.now(),n=e.target;n&&w(n,[])||(e.key==="Tab"?Yo(t,n):e.key==="Escape"?$o(t,e.target):(e.key==="ArrowDown"||e.key==="ArrowUp"||e.key==="ArrowLeft"||e.key==="ArrowRight")&&zo(t,e.target))}function Yo(e,t){for(;y.length&&e-y[0].ts>jo;)y.shift();y.length>=50&&(y=y.slice(-25));let n=t?f(t):"";if(y.push({ts:e,el:n}),y.length>=Ho){let r=y.map(i=>i.el).filter(Boolean);u({t:"sig",ts:e,d:{s:"tab_thrash",cnt:y.length,els:r}}),y=[]}if(!t)return;let o=t.closest('[role="dialog"]')||t.closest('[role="menu"]')||t.closest(".modal")||t.closest('[aria-modal="true"]');o&&(o===P?e-We<=qo?(x++,x>=ln&&(u({t:"sig",ts:e,d:{s:"focus_trap",container:f(o),attempts:x}}),x=0,P=null)):(We=e,x=1):(P=o,We=e,x=1))}function $o(e,t){if(!t)return;let n=t.closest('[role="dialog"]')||t.closest('[role="menu"]')||t.closest(".modal")||t.closest('[aria-modal="true"]');n&&n===P&&(x++,x>=ln&&(u({t:"sig",ts:e,d:{s:"focus_trap",container:f(n),attempts:x}}),x=0,P=null))}function zo(e,t){if(!t)return;let n=t.closest('[role="listbox"]')||t.closest('[role="menu"]')||t.closest('[role="tree"]')||t.closest("select");if(!n)return;for(;T.length&&e-T[0].ts>Vo;)T.shift();T.length>=50&&(T=T.slice(-25)),T.push({ts:e,container:n});let o=T.filter(r=>r.container===n);o.length>=Bo&&(u({t:"sig",ts:e,d:{s:"keyboard_nav_frustration",container:f(n),keys:o.length}}),T=[])}var U=0,ie=0,se=null,Ze=0,ae=!1,Ko=4,Wo=3e3,dn=d(Qo);function Je(){window.addEventListener("scroll",dn,{passive:!0})}function et(){window.removeEventListener("scroll",dn),U=0,ie=0,se=null,Ze=0,ae=!1}function Qo(){ae||(ae=!0,requestAnimationFrame(()=>{ae=!1,Go()}))}function Go(){let e=Date.now(),t=window.scrollY,n=t-ie;if(Math.abs(n)<2){ie=t;return}let o=n>0?"down":"up";se&&o!==se&&(e-Ze>Wo&&(U=0,Ze=e),U++,U>=Ko&&Math.abs(n)>100&&(u({t:"sig",ts:e,d:{s:"scroll_hijack",rev:U}}),U=0)),se=o,ie=t}var H=0,ce=!1,fn=d(Zo),mn=S(pn),G=null;function tt(){window.addEventListener("scroll",fn,{passive:!0}),window.addEventListener("pagehide",mn),G=S(()=>{document.visibilityState==="hidden"&&pn()}),document.addEventListener("visibilitychange",G)}function nt(){window.removeEventListener("scroll",fn),window.removeEventListener("pagehide",mn),G&&(document.removeEventListener("visibilitychange",G),G=null),H=0,ce=!1}function ot(){H=0}function Zo(){ce||(ce=!0,requestAnimationFrame(()=>{ce=!1;let e=document.documentElement.scrollHeight-window.innerHeight;if(e>0){let t=window.scrollY/e;t>H&&(H=t)}}))}function pn(){H>.05&&u({t:"sig",ts:Date.now(),d:{s:"scroll_depth_abandon",depth:Math.round(H*100)/100}})}var Jo="https://api.flusterduck.com/v1/ingest",C=!1,le=null,rt=null;function er(e){if(e)try{let t=new URL(e),n=t.protocol==="http:"&&/^(localhost|127\.0\.0\.1|\[::1\])$/.test(t.hostname);return t.protocol!=="https:"&&!n?void 0:t.origin+t.pathname}catch{return}}function it(e){if(C||!e.key)return;if(e.key.startsWith("fd_sec_")){console.error("[flusterduck] Secret key detected in browser. Use a publishable key (fd_pub_) instead. Aborting.");return}if(!e.key.startsWith("fd_pub_")||e.respectDoNotTrack!==!1&&tr()||e.sampleRate!==void 0&&e.sampleRate<1&&Math.random()>e.sampleRate)return;rt=e,C=!0;let t=at(e.cookieless??!1),n=er(e.endpoint)??Jo,o=be(location.pathname,e.pageRules??[]),r=nr(e.domMode);wt(n,{sid:t,key:e.key,url:location.origin+location.pathname,page:o,ua:navigator.userAgent.slice(0,200),vw:window.innerWidth,vh:window.innerHeight,segment:e.segment,environment:e.environment},e.batchInterval,e.batchMaxSize,{domMode:r});let i=document.referrer,a="";if(i)try{a=new URL(i).origin+new URL(i).pathname}catch{a=""}u({t:"pv",ts:Date.now(),d:{ref:a}});let s=e.ignoreElements??[],c=l=>e.signals?.[l]?.enabled!==!1;if(c("rageClick")&&Ee(e.signals?.rageClick,s),c("deadClick")&&Se(s),c("speedFrustration")){let l=e.signals?.speedFrustration;xe(l?{delayMs:l.windowMs}:void 0,s)}if(e.trackMouse!==!1&&c("thrashCursor")&&Le(e.signals?.thrashCursor),c("loopNav")&&Re(e.signals?.loopNav),c("scrollBounce")&&Pe(),e.trackForms!==!1&&(c("formHesitation")||c("formAbandon"))){let l=e.signals?.formHesitation;qe(l?{pauseMs:l.threshold}:void 0,s)}c("errorEncounter")&&Xe(),("ontouchstart"in window||navigator.maxTouchPoints>0)&&ze(s),(c("tabThrash")||c("focusTrap")||c("keyboardNavFrustration"))&&Qe(),c("scrollHijack")&&Je(),c("scrollDepthAbandon")&&tt(),le=St(S((l,h)=>{D(),He(),Ve(),ot();let g=be(h,e.pageRules??[]);ve({page:g,url:l}),Ce(h),u({t:"pv",ts:Date.now(),d:{ref:""}})})),e.debug&&console.warn("[flusterduck] initialized",{sid:t.slice(0,6)+"...",endpoint:n,page:o})}function hn(e,t){if(!C||typeof e!="string"||!e||e.length>128)return;let n;try{let r=t?.metadata??{};n=JSON.stringify(r)}catch{return}if(n.length>2048)return;let o=JSON.parse(n);u({t:"sig",ts:Date.now(),d:{s:"custom",name:e.slice(0,128),el:typeof t?.element=="string"?t.element.slice(0,256):"",meta:o,w:Math.max(0,Math.min(t?.weight??15,100))}})}function gn(e){if(!C||!e||typeof e!="object")return;let t=Object.create(null),n=0;for(let o of Object.keys(e)){if(n>=20)break;o==="__proto__"||o==="constructor"||o==="prototype"||(t[o.slice(0,64)]=String(e[o]).slice(0,256),n++)}ve({segment:t})}function vn(e){e&&rt&&!C?it(rt):e||(ue(),pe())}function bn(){ue(),pe()}function ue(){C&&(ye(),Me(),Ae(),De(),_e(),Ue(),Be(),Ye(),Ke(),Ge(),et(),nt(),Et(),le&&(le(),le=null),C=!1)}function tr(){return!!(navigator.doNotTrack==="1"||navigator.globalPrivacyControl)}function nr(e){return e==="metadata"||e==="snapshot"?e:"off"}
|
package/dist/index.d.ts
ADDED
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function S(e){return(...t)=>{try{return e(...t)}catch{}}}function d(e){return t=>{try{e(t)}catch{}}}var de="_fd_s";var pn=/^[0-9a-f]{32}$/;function it(e){if(e)return rt();let t=hn(de);if(t&&pn.test(t))return t;let n=rt();return st(de,n,30),n}function fe(){st(de,"",-1)}function rt(){let e=new Uint8Array(16);crypto.getRandomValues(e);let t="";for(let n of e)t+=n.toString(16).padStart(2,"0");return t}function hn(e){let t=document.cookie.match(new RegExp("(?:^|; )"+e+"=([^;]*)"));return t?.[1]?decodeURIComponent(t[1]):null}function st(e,t,n){let o=new Date;o.setTime(o.getTime()+n*864e5);let r=location.protocol==="https:"?";Secure":"";document.cookie=`${e}=${encodeURIComponent(t)};path=/;expires=${o.toUTCString()};SameSite=Lax${r}`}var gn=/^[:\d]|--|^(ember|react|ng-|__)/;function f(e){if(!e||e===document.documentElement)return"html";let t=e.getAttribute("data-fd");if(t)return`[data-fd="${q(t)}"]`;if(e.id&&!gn.test(e.id)&&e.id.length<64)return"#"+q(e.id);let n=[],o=e,r=0;for(;o&&o!==document.body&&r<5;){let i=o.tagName.toLowerCase(),a=o.getAttribute("name"),s=o.getAttribute("role"),c=o.getAttribute("type");a&&a.length<64?i+=`[name="${q(a)}"]`:s?i+=`[role="${q(s)}"]`:c&&(i==="input"||i==="button")&&(i+=`[type="${q(c)}"]`);let l=o.parentElement;if(l){let g=l.children,b=0,j=0;for(let O=0;O<g.length;O++){let ue=g[O];ue&&ue.tagName===o.tagName&&(b++,ue===o&&(j=b))}b>1&&(i+=`:nth-of-type(${j})`)}n.unshift(i);let h=n.join(" > ");try{if(document.querySelectorAll(h).length===1)return h}catch{}o=l,r++}return n.join(" > ")}function q(e){return typeof CSS<"u"&&CSS.escape?CSS.escape(e):e.replace(/([^\w-])/g,"\\$1")}function w(e,t){if(e.hasAttribute("data-fd-ignore")||e.closest("[data-fd-ignore]"))return!0;for(let n of t)try{if(e.matches(n)||e.closest(n))return!0}catch{}return!1}function ct(e,t){if(t==="off")return null;if(t==="metadata")return vn(e);let n=bn(e);return n?{mode:"snapshot",...n}:null}function vn(e){return{mode:"metadata",selector:f(e),tag:e.tagName.toLowerCase(),role:e.getAttribute("role"),attributes:{disabled:e.disabled===!0,required:e.required===!0,ariaDisabled:e.getAttribute("aria-disabled")==="true",ariaExpanded:at(e.getAttribute("aria-expanded"),["true","false"]),ariaInvalid:at(e.getAttribute("aria-invalid"),["true","false","grammar","spelling"]),type:wn(e)}}}function bn(e){try{let t=e.getBoundingClientRect(),n=getComputedStyle(e),o=e.parentElement,r=[];if(o)for(let a=0;a<o.children.length&&r.length<6;a++){let s=o.children[a];if(!s||s===e)continue;let c=s.getBoundingClientRect();r.push({selector:f(s),tag:s.tagName.toLowerCase(),box:{x:Math.round(c.x),y:Math.round(c.y),w:Math.round(c.width),h:Math.round(c.height)},interactive:yn(s)})}let i=[];try{let a=e.getAnimations();for(let s of a)"animationName"in s&&i.push(s.animationName)}catch{}return{selector:f(e),tag:e.tagName.toLowerCase(),role:e.getAttribute("role"),parent:o?f(o):"",box:{x:Math.round(t.x),y:Math.round(t.y),w:Math.round(t.width),h:Math.round(t.height)},styles:{opacity:n.opacity,cursor:n.cursor,pointerEvents:n.pointerEvents,display:n.display,visibility:n.visibility,disabled:e.disabled===!0},inView:En(t),animations:i,siblings:r}}catch{return null}}function at(e,t){return e&&t.includes(e)?e:null}function wn(e){let t=e.tagName.toLowerCase();if(t!=="input"&&t!=="button")return null;let n=e.getAttribute("type");return n&&/^[a-z0-9_-]{1,32}$/i.test(n)?n.toLowerCase():null}function En(e){return e.top<window.innerHeight&&e.bottom>0&&e.left<window.innerWidth&&e.right>0}function yn(e){let t=e.tagName;if(/^(A|BUTTON|INPUT|SELECT|TEXTAREA)$/.test(t))return!0;let n=e.getAttribute("role");return!!(n&&/^(button|link|tab|menuitem|checkbox|radio)$/.test(n))}var ut=3e3,dt=50,ft=50,Sn=3,Mn=65536,N=[],A=null,Z="",mt=ut,pt=dt,v=null,pe={domMode:"off"},me=!1,Tn=new Set(["sid","key","url","page","ua","vw","vh","segment","environment"]),xn=new Set(["click","move","scroll","keyboard","form_focus","form_blur","form_submit","touch","navigation","error","signal","pageview","custom_signal","performance","visibility","sdk_error"]),An=/(?:value|text|label|email|e-mail|name|phone|address|password|token|secret|cookie|session|jwt|auth|credential|card|cc|cvv|ssn)/i,kn=/(?:[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}|\b(?:\d[ -]*?){13,19}\b)/i,ht=d(Ln),gt=S(()=>D());function vt(e,t,n,o,r){Z=e,v=Object.assign(Object.create(null),t),pe={domMode:On(r?.domMode)},mt=Math.max(1e3,Math.min(n??ut,3e4)),pt=Math.max(5,Math.min(o??dt,ft)),document.addEventListener("visibilitychange",ht),window.addEventListener("pagehide",gt)}function u(e){N.length>=ft||(N.push(e),N.length>=pt?D():A||(A=setTimeout(D,mt)))}function D(){if(me||!N.length||!v)return;me=!0,A&&(clearTimeout(A),A=null);let e=N;N=[];let t={v:1,sid:v.sid,key:v.key,url:v.url,page:v.page,ts:Date.now(),ua:v.ua,vw:v.vw,vh:v.vh,environment:v.environment,dom_mode:pe.domMode,events:e.map(n=>Dn(n,v.page,pe.domMode))};try{let n=JSON.stringify(t);n.length<=Mn&&wt(n,0)}catch{}me=!1}function he(e){if(v)for(let t of Object.keys(e))Tn.has(t)&&(v[t]=e[t])}function bt(){D(),document.removeEventListener("visibilitychange",ht),window.removeEventListener("pagehide",gt),A&&(clearTimeout(A),A=null)}function Ln(){document.visibilityState==="hidden"&&D()}function wt(e,t){if(Z){if(navigator.sendBeacon){let n=new Blob([e],{type:"application/json"});if(navigator.sendBeacon(Z,n))return}try{fetch(Z,{method:"POST",body:e,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{t<Sn&&setTimeout(()=>wt(e,t+1),1e3*(t+1))})}catch{}}}function Dn(e,t,n){let o=e.d??{},r=Rn(e.t),i={type:r,ts:e.ts,page:typeof o.page=="string"?o.page.slice(0,2048):t},a=lt(o.el,o.element,o.target);if(r==="signal"){i.signal_type=lt(o.s,o.signal_type,o.name)?.slice(0,128),a&&(i.element=a.slice(0,2048));let c=a?Cn(a,n):null;c&&(i.dom=c)}let s=_n(o);return Object.keys(s).length&&(i.metadata=s),i}function Rn(e){return e==="pv"?"pageview":e==="sig"?"signal":xn.has(e)?e:"custom_signal"}function _n(e){let t=Object.create(null);for(let n of Object.keys(e)){if(["s","signal_type","name","el","element","target","dom","page","meta"].includes(n))continue;let o=J(e[n],n);o!==void 0&&(t[n.slice(0,64)]=o)}if(e.meta&&typeof e.meta=="object"&&!Array.isArray(e.meta)){let n=J(e.meta,"meta");n&&typeof n=="object"&&!Array.isArray(n)&&Object.assign(t,n)}return t}function J(e,t="",n=0){if(!(n>4)&&!An.test(t)){if(e===null||typeof e=="boolean")return e;if(typeof e=="number")return Number.isFinite(e)?e:void 0;if(typeof e=="string")return kn.test(e)?void 0:e.slice(0,500);if(Array.isArray(e))return e.slice(0,20).map(r=>J(r,t,n+1)).filter(r=>r!==void 0);if(typeof e=="object"){let o=Object.create(null);for(let r of Object.keys(e).slice(0,40)){if(r==="__proto__"||r==="constructor"||r==="prototype")continue;let i=J(e[r],r,n+1);i!==void 0&&(o[r.slice(0,64)]=i)}return o}}}function Cn(e,t){if(t==="off")return null;try{let n=document.querySelector(e);return n?ct(n,t):null}catch{return null}}function lt(...e){for(let t of e)if(typeof t=="string"&&t)return t}function On(e){return e==="metadata"||e==="snapshot"?e:"off"}function Et(e){let t=location.href;function n(){let s=location.href;s!==t&&(t=s,e(s,location.pathname))}let o=history.pushState,r=history.replaceState,i=function(...s){o.apply(this,s),n()},a=function(...s){r.apply(this,s),n()};return history.pushState=i,history.replaceState=a,window.addEventListener("popstate",n),window.addEventListener("hashchange",n),function(){history.pushState===i&&(history.pushState=o),history.replaceState===a&&(history.replaceState=r),window.removeEventListener("popstate",n),window.removeEventListener("hashchange",n)}}function ge(e,t){for(let n of t){let o=In(n.pattern);if(o&&o.test(e))return n.label}return Fn(e)}var Nn=/^[a-zA-Z0-9/:._*\-]+$/;function In(e){if(e.length>200||!Nn.test(e))return null;let t=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/:\w+/g,"[^/]+");try{return new RegExp("^"+t+"$")}catch{return null}}function Fn(e){return e.replace(/\/\d+/g,"/:id").replace(/\/[a-f0-9-]{36}/g,"/:id")}var Pn=[".carousel-arrow",".slick-arrow",".swiper-button-next",".swiper-button-prev","[data-carousel]",'button[aria-label*="next"]','button[aria-label*="prev"]','button[aria-label*="slide"]',".quantity-btn",".qty-btn",'input[type="number"]'],k=[],ve=3,St=2e3,yt=8,Mt=[],Tt=d(Un);function be(e,t){ve=e?.threshold??3,St=e?.windowMs??2e3,Mt=[...Pn,...t??[]],document.addEventListener("click",Tt,{capture:!0,passive:!0})}function we(){document.removeEventListener("click",Tt,{capture:!0}),k=[]}function Un(e){let t=e.target;if(!t||w(t,Mt)||Hn(t))return;let n=Date.now(),o=e.clientX,r=e.clientY;for(;k.length&&n-k[0].t>St;)k.shift();if(k.push({t:n,x:o,y:r,el:t}),k.length<ve)return;let i=k.slice(-ve),a=i[0];for(let g=1;g<i.length;g++){let b=i[g],j=b.x-a.x,O=b.y-a.y;if(j*j+O*O>yt*yt)return}let s=a.t,l=(i[i.length-1].t-s)/1e3,h=l>0?i.length/l:i.length;u({t:"sig",ts:n,d:{s:"rage_click",el:f(t),cnt:i.length,vel:Math.round(h*10)/10}}),k=[]}function Hn(e){let t=e.tagName;return!!(t==="VIDEO"||t==="AUDIO"||e.hasAttribute("ondblclick"))}var jn=/^(A|BUTTON|INPUT|SELECT|TEXTAREA|DETAILS|SUMMARY)$/,qn=/^(button|link|tab|menuitem|checkbox|radio|switch|option|combobox|slider|spinbutton|textbox)$/,Bn=/^(A|BUTTON|LABEL)$/,xt=[],B=null,Vn=5,At=d(Xn),kt=d(Yn);function Xn(e){B={x:e.clientX,y:e.clientY}}function Ee(e){xt=e??[],document.addEventListener("mousedown",At,{capture:!0,passive:!0}),document.addEventListener("click",kt,{capture:!0,passive:!0})}function ye(){document.removeEventListener("mousedown",At,{capture:!0}),document.removeEventListener("click",kt,{capture:!0}),B=null}function Yn(e){if(e.button!==0||e.detail===0)return;let t=e.target;if(!t||w(t,xt)||Kn()||Wn(e)||$n(t))return;let n=zn(t,e.clientX,e.clientY),o=n?Lt(e.clientX,e.clientY,n):-1;u({t:"sig",ts:Date.now(),d:{s:"dead_click",el:f(t),near:n?f(n):"",dist:Math.round(o)}})}function $n(e){if(jn.test(e.tagName))return!0;let t=e.getAttribute("role");if(t&&qn.test(t)||e.hasAttribute("contenteditable")||e.hasAttribute("tabindex")&&e.getAttribute("tabindex")!=="-1"||e.hasAttribute("onclick")||e.hasAttribute("onmousedown")||e.hasAttribute("onmouseup"))return!0;let n=e.parentElement;if(n&&Bn.test(n.tagName)||e.closest('a, button, [role="button"], label, [onclick]'))return!0;try{if(getComputedStyle(e).cursor==="pointer")return!0}catch{return!1}return!1}function zn(e,t,n){let o=e.parentElement;if(!o)return null;let r=o.querySelectorAll('a, button, input, select, textarea, [role="button"], [tabindex]'),i=null,a=1/0;for(let s=0;s<r.length;s++){let c=r[s];if(!c)continue;let l=Lt(t,n,c);l<a&&(a=l,i=c)}return i}function Lt(e,t,n){let o=n.getBoundingClientRect(),r=Math.max(o.left,Math.min(e,o.right)),i=Math.max(o.top,Math.min(t,o.bottom)),a=e-r,s=t-i;return Math.sqrt(a*a+s*s)}function Kn(){let e=window.getSelection();return e!==null&&e.toString().length>0}function Wn(e){if(!B)return!1;let t=e.clientX-B.x,n=e.clientY-B.y;return Math.sqrt(t*t+n*n)>Vn}var m=null,Se=3e3,Dt=[],Qn=/^(A|BUTTON|INPUT|SELECT|TEXTAREA)$/,Gn=/^(button|link|tab|menuitem|checkbox|radio|switch|option|combobox|slider|spinbutton)$/,Rt=d(Zn);function Me(e,t){Se=e?.delayMs??3e3,Dt=t??[],document.addEventListener("click",Rt,{capture:!0,passive:!0})}function Te(){document.removeEventListener("click",Rt,{capture:!0}),V()}function Zn(e){let t=e.target;if(!t||w(t,Dt))return;let n=t.getAttribute("role");if(!Qn.test(t.tagName)&&!(n&&Gn.test(n)))return;if(m){if(m.el===t||m.el.contains(t)){let c=Date.now()-m.ts;c>=Se&&u({t:"sig",ts:Date.now(),d:{s:"speed_frustration",el:m.selector,delay:c}}),V();return}V()}let o=f(t),r=!1,i=new MutationObserver(c=>{for(let l of c){if(l.type==="childList"&&(l.addedNodes.length>0||l.removedNodes.length>0)){r=!0,V();return}if(l.type==="attributes"&&l.target instanceof Element&&(l.target===t||t.contains(l.target)||l.target.contains(t))){r=!0,V();return}}}),a=t.parentElement||document.body;i.observe(a,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class","style","hidden","aria-hidden","disabled"]});let s=setTimeout(()=>{!r&&m&&(m={...m,timeout:null})},Se+500);m={el:t,selector:o,ts:Date.now(),observer:i,timeout:s}}function V(){m&&(m.observer.disconnect(),m.timeout&&clearTimeout(m.timeout),m=null)}var Jn=100,Ct=800,Ot=2e3,eo=3,_t=0,to=50,ee=0,te=0,X=0,Y=0,$=0,ne=0,xe=0,R=[],Nt=d(no);function Ae(e){Ct=e?.velocityThreshold??800,Ot=e?.windowMs??2e3,document.addEventListener("mousemove",Nt,{passive:!0})}function ke(){document.removeEventListener("mousemove",Nt),It()}function no(e){let t=Date.now();t-_t<to||(_t=t,oo(e.clientX,e.clientY,t))}function oo(e,t,n){if(X===0){ee=e,te=t,X=n,xe=n;return}let o=(n-X)/1e3;if(o===0)return;let r=e-ee,i=t-te,s=Math.sqrt(r*r+i*i)/o;R.length>=Jn&&(R=R.slice(-50)),R.push(s);let c=Math.sign(r),l=Math.sign(i);if((Y!==0&&c!==0&&c!==Y||$!==0&&l!==0&&l!==$)&&ne++,Y=c||Y,$=l||$,ee=e,te=t,X=n,n-xe>Ot){if(ne>=eo){let h=R.reduce((g,b)=>g+b,0)/R.length;h>=Ct&&u({t:"sig",ts:n,d:{s:"thrash_cursor",vel:Math.round(h),rev:ne}})}It(),xe=n}}function It(){ne=0,R=[],Y=0,$=0,X=0,ee=0,te=0}var ro=100,p=[],Ft=3e4;function Le(e){Ft=e?.windowMs??3e4}function De(){p=[]}function Re(e){let t=Date.now();for(;p.length&&t-p[0].ts>Ft;)p.shift();if(p.length>=ro&&(p=p.slice(-50)),p.push({path:e,ts:t}),p.length<4)return;let n=e,o=!1,r=[];for(let i=p.length-2;i>=1;i--)if(p[i-1].path===n){let a=p.slice(i-1,p.length);for(let s of a)r.includes(s.path)||r.push(s.path);o=!0;break}o&&r.length>=2&&(u({t:"sig",ts:t,d:{s:"loop_nav",pages:r}}),p=[{path:e,ts:t}])}var io=100,Pt=1e4,Oe=.5,E=[],oe=0,Ne=0,_e=!1,Ce=0,Ut=d(so);function Ie(e){Pt=e?.windowMs??1e4,Oe=e?.depthThreshold??.5,window.addEventListener("scroll",Ut,{passive:!0})}function Fe(){window.removeEventListener("scroll",Ut),E=[]}function Pe(){E=[],oe=0,Ne=0}function so(){_e||(_e=!0,requestAnimationFrame(()=>{_e=!1,ao()}))}function ao(){let e=Date.now(),t=window.scrollY;if(Ce=document.documentElement.scrollHeight-window.innerHeight,Ce<=0)return;let n=t/Ce,o=t>oe?"down":"up";if(e-Ne<100){oe=t;return}for(;E.length&&e-E[0].ts>Pt;)E.shift();E.length>=io&&(E=E.slice(-50)),E.push({depth:n,ts:e,direction:o}),oe=t,Ne=e;let r=0,i=1,a=0,s=!1;for(let c=0;c<E.length;c++){let l=E[c].depth;l>r&&(r=l),l>=Oe&&(s=!0),s&&l<i&&(i=l),s&&i<.25&&l>=Oe&&(a++,s=!1,i=1)}a>=1&&(u({t:"sig",ts:e,d:{s:"scroll_bounce",depth:Math.round(r*100)/100,rev:a+1}}),E=[])}var co=["textarea",'[role="textbox"]',"[contenteditable]"],K=new Map,L=new Set,_=null,Ue=0,Ht=5e3,jt=[],qt=d(lo),Bt=d(uo),Vt=d(fo),Xt=S(Yt),z=null;function He(e,t){Ht=e?.pauseMs??5e3,jt=t??[],document.addEventListener("focusin",qt,{capture:!0,passive:!0}),document.addEventListener("focusout",Bt,{capture:!0,passive:!0}),document.addEventListener("submit",Vt,{capture:!0,passive:!0}),window.addEventListener("pagehide",Xt),z=S(()=>{document.visibilityState==="hidden"&&Yt()}),document.addEventListener("visibilitychange",z)}function je(){document.removeEventListener("focusin",qt,{capture:!0}),document.removeEventListener("focusout",Bt,{capture:!0}),document.removeEventListener("submit",Vt,{capture:!0}),window.removeEventListener("pagehide",Xt),z&&(document.removeEventListener("visibilitychange",z),z=null),K.clear(),L.clear(),_=null}function qe(){K.clear(),L.clear(),_=null,Ue=0}function lo(e){let t=e.target;if(!t||!$t(t)||w(t,jt)||mo(t))return;K.set(t,Date.now());let n=t.closest("form");n&&n!==_&&(_=n,Ue=n.querySelectorAll("input, select, textarea").length)}function uo(e){let t=e.target;if(!t||!$t(t))return;let n=K.get(t);if(K.delete(t),n){let r=Date.now()-n;r>=Ht&&u({t:"sig",ts:Date.now(),d:{s:"form_hesitation",el:f(t),pause:r}})}let o=t.getAttribute("name")||t.getAttribute("id")||f(t);po(t)&&L.add(o)}function fo(){L.clear(),_=null}function Yt(){L.size>0&&_&&(u({t:"sig",ts:Date.now(),d:{s:"form_abandon",filled:L.size,total:Ue||L.size}}),L.clear(),_=null)}function $t(e){let t=e.tagName;return t==="INPUT"||t==="SELECT"||t==="TEXTAREA"}function mo(e){if(e.tagName==="TEXTAREA")return!0;for(let t of co)try{if(e.matches(t))return!0}catch{return!1}return!1}function po(e){return"value"in e?e.value.length>0:!1}var I=null,W=null,zt=/flusterduck\.com|\/v1\/ingest/,Wt=d(ho),Qt=d(go);function Be(){window.addEventListener("error",Wt),window.addEventListener("unhandledrejection",Qt),vo()}function Ve(){window.removeEventListener("error",Wt),window.removeEventListener("unhandledrejection",Qt),bo()}function ho(e){u({t:"sig",ts:Date.now(),d:{s:"error_encounter",type:"js_error",msg:Xe(e.message||"Unknown error",200),ep:"",status:0}})}function go(e){let t=e.reason instanceof Error?e.reason.message:String(e.reason??"");u({t:"sig",ts:Date.now(),d:{s:"error_encounter",type:"unhandled_rejection",msg:Xe(t,200),ep:"",status:0}})}function vo(){I||(I=window.fetch,W=function(t,n){let o;try{o=I.call(this,t,n)}catch(r){throw r}return o.then(r=>{try{if(r.status>=400){let i=typeof t=="string"?t:t instanceof URL?t.pathname:t.url;zt.test(i)||u({t:"sig",ts:Date.now(),d:{s:"error_encounter",type:"network_error",msg:`${r.status} ${r.statusText}`,ep:Kt(i),status:r.status}})}}catch{}return r},r=>{try{let i=typeof t=="string"?t:t instanceof URL?t.href:t.url;zt.test(i)||u({t:"sig",ts:Date.now(),d:{s:"error_encounter",type:"network_error",msg:Xe(r instanceof Error?r.message:"Fetch failed",200),ep:typeof t=="string"?Kt(t):"",status:0}})}catch{}throw r})},window.fetch=W)}function bo(){I&&W&&window.fetch===W&&(window.fetch=I),I=null,W=null}function Kt(e){try{return new URL(e,location.origin).pathname}catch{let t=e.indexOf("?"),n=e.indexOf("#"),o=Math.min(t>=0?t:e.length,n>=0?n:e.length);return e.slice(0,o)||"/"}}function Xe(e,t){let n=e.length>t?e.slice(0,t):e;return n=n.replace(/(?:token|key|secret|password|auth|bearer|jwt|session|cookie|credential)[=:]\s*\S+/gi,"[REDACTED]"),n=n.replace(/https?:\/\/[^\s]*[?&][^\s]*/g,o=>{try{return new URL(o).origin+new URL(o).pathname}catch{return"[URL]"}}),n}var Gt=[".carousel",".slider",".swiper","[data-swipeable]",".drawer"],wo=['[class*="map"]',"canvas",".gallery","[data-zoom]"],F=null,M=0,re=0,Q=0,Zt=0,Jt=null,en=[],tn=d(Eo),nn=d(yo),on=d(To),rn=d(Ao),sn=d(xo);function Ye(e){en=e??[],document.addEventListener("touchstart",tn,{passive:!0}),document.addEventListener("touchend",nn,{passive:!0}),"ontouchstart"in window&&(document.addEventListener("gesturechange",on,{passive:!0}),window.addEventListener("orientationchange",rn,{passive:!0})),window.visualViewport?.addEventListener("resize",sn)}function $e(){document.removeEventListener("touchstart",tn),document.removeEventListener("touchend",nn),document.removeEventListener("gesturechange",on),window.removeEventListener("orientationchange",rn),window.visualViewport?.removeEventListener("resize",sn)}function Eo(e){let t=e.touches[0];e.touches.length===1&&t&&(F={x:t.clientX,y:t.clientY,ts:Date.now()})}function yo(e){if(!F||e.changedTouches.length!==1)return;let t=e.changedTouches[0];if(!t)return;let n=t.clientX-F.x,o=t.clientY-F.y,r=Date.now()-F.ts,i=document.elementFromPoint(t.clientX,t.clientY);Math.abs(n)<10&&Math.abs(o)<10&&r<300&&i&&So(i,t.clientX,t.clientY),r<500&&(Math.abs(n)>50||Math.abs(o)>50)&&Mo(i,n,o),F=null}function So(e,t,n){if(w(e,en))return;let o=ko(e,t,n);if(!o)return;let r=o.getBoundingClientRect(),i=Math.max(r.left,Math.min(t,r.right)),a=Math.max(r.top,Math.min(n,r.bottom)),s=Math.sqrt((t-i)**2+(n-a)**2);if(s>0&&s<=20){let c=`${Math.round(r.width)}x${Math.round(r.height)}`;u({t:"sig",ts:Date.now(),d:{s:"tap_miss",el:f(o),dist:Math.round(s),size:c}})}}function Mo(e,t,n){if(Math.abs(n)>Math.abs(t)||!e||Gt.some(a=>{try{return e.matches(a)||e.closest(a)}catch{return!1}})||!Gt.some(a=>{try{return document.querySelector(a)!==null}catch{return!1}}))return;let i=t>0?"right":"left";u({t:"sig",ts:Date.now(),d:{s:"swipe_miss",dir:i}})}function To(){let e=Date.now();if(e-re>3e4&&(M=0,re=e),M++,M>=2){let t=document.activeElement||document.body;wo.some(o=>{try{return t.matches(o)||t.closest(o)}catch{return!1}})||u({t:"sig",ts:e,d:{s:"pinch_zoom",cnt:M}}),M=0}}function xo(){let e=window.visualViewport;if(e&&e.scale>1.1){let t=Date.now();t-re>3e4&&(M=0,re=t),M++,M>=2&&(u({t:"sig",ts:t,d:{s:"pinch_zoom",cnt:M}}),M=0)}}function Ao(){let e=Date.now(),t=screen.orientation?.type||"unknown";e-Zt>3e4&&(Q=0,Zt=e),t!==Jt&&(Q++,Jt=t),Q>=3&&(u({t:"sig",ts:e,d:{s:"orientation_thrash",cnt:Q}}),Q=0)}function ko(e,t,n){let r=(e.parentElement||document.body).querySelectorAll('a, button, input, select, textarea, [role="button"], [tabindex]:not([tabindex="-1"])'),i=null,a=21;for(let s=0;s<r.length;s++){let c=r[s];if(!c)continue;let l=c.getBoundingClientRect(),h=Math.max(l.left,Math.min(t,l.right)),g=Math.max(l.top,Math.min(n,l.bottom)),b=Math.sqrt((t-h)**2+(n-g)**2);b<a&&b>0&&(a=b,i=c)}return i}var y=[],P=null,x=0,ze=0,T=[],Lo=10,Do=5e3,an=5,Ro=3e3,_o=15,Co=5e3,cn=d(Oo);function Ke(){document.addEventListener("keydown",cn,{capture:!0,passive:!0})}function We(){document.removeEventListener("keydown",cn,{capture:!0}),y=[],T=[],P=null}function Oo(e){let t=Date.now(),n=e.target;n&&w(n,[])||(e.key==="Tab"?No(t,n):e.key==="Escape"?Io(t,e.target):(e.key==="ArrowDown"||e.key==="ArrowUp"||e.key==="ArrowLeft"||e.key==="ArrowRight")&&Fo(t,e.target))}function No(e,t){for(;y.length&&e-y[0].ts>Do;)y.shift();y.length>=50&&(y=y.slice(-25));let n=t?f(t):"";if(y.push({ts:e,el:n}),y.length>=Lo){let r=y.map(i=>i.el).filter(Boolean);u({t:"sig",ts:e,d:{s:"tab_thrash",cnt:y.length,els:r}}),y=[]}if(!t)return;let o=t.closest('[role="dialog"]')||t.closest('[role="menu"]')||t.closest(".modal")||t.closest('[aria-modal="true"]');o&&(o===P?e-ze<=Ro?(x++,x>=an&&(u({t:"sig",ts:e,d:{s:"focus_trap",container:f(o),attempts:x}}),x=0,P=null)):(ze=e,x=1):(P=o,ze=e,x=1))}function Io(e,t){if(!t)return;let n=t.closest('[role="dialog"]')||t.closest('[role="menu"]')||t.closest(".modal")||t.closest('[aria-modal="true"]');n&&n===P&&(x++,x>=an&&(u({t:"sig",ts:e,d:{s:"focus_trap",container:f(n),attempts:x}}),x=0,P=null))}function Fo(e,t){if(!t)return;let n=t.closest('[role="listbox"]')||t.closest('[role="menu"]')||t.closest('[role="tree"]')||t.closest("select");if(!n)return;for(;T.length&&e-T[0].ts>Co;)T.shift();T.length>=50&&(T=T.slice(-25)),T.push({ts:e,container:n});let o=T.filter(r=>r.container===n);o.length>=_o&&(u({t:"sig",ts:e,d:{s:"keyboard_nav_frustration",container:f(n),keys:o.length}}),T=[])}var U=0,ie=0,se=null,Qe=0,ae=!1,Po=4,Uo=3e3,ln=d(Ho);function Ge(){window.addEventListener("scroll",ln,{passive:!0})}function Ze(){window.removeEventListener("scroll",ln),U=0,ie=0,se=null,Qe=0,ae=!1}function Ho(){ae||(ae=!0,requestAnimationFrame(()=>{ae=!1,jo()}))}function jo(){let e=Date.now(),t=window.scrollY,n=t-ie;if(Math.abs(n)<2){ie=t;return}let o=n>0?"down":"up";se&&o!==se&&(e-Qe>Uo&&(U=0,Qe=e),U++,U>=Po&&Math.abs(n)>100&&(u({t:"sig",ts:e,d:{s:"scroll_hijack",rev:U}}),U=0)),se=o,ie=t}var H=0,ce=!1,un=d(qo),dn=S(fn),G=null;function Je(){window.addEventListener("scroll",un,{passive:!0}),window.addEventListener("pagehide",dn),G=S(()=>{document.visibilityState==="hidden"&&fn()}),document.addEventListener("visibilitychange",G)}function et(){window.removeEventListener("scroll",un),window.removeEventListener("pagehide",dn),G&&(document.removeEventListener("visibilitychange",G),G=null),H=0,ce=!1}function tt(){H=0}function qo(){ce||(ce=!0,requestAnimationFrame(()=>{ce=!1;let e=document.documentElement.scrollHeight-window.innerHeight;if(e>0){let t=window.scrollY/e;t>H&&(H=t)}}))}function fn(){H>.05&&u({t:"sig",ts:Date.now(),d:{s:"scroll_depth_abandon",depth:Math.round(H*100)/100}})}var Bo="https://api.flusterduck.com/v1/ingest",C=!1,le=null,nt=null;function Vo(e){if(e)try{let t=new URL(e),n=t.protocol==="http:"&&/^(localhost|127\.0\.0\.1|\[::1\])$/.test(t.hostname);return t.protocol!=="https:"&&!n?void 0:t.origin+t.pathname}catch{return}}function mn(e){if(C||!e.key)return;if(e.key.startsWith("fd_sec_")){console.error("[flusterduck] Secret key detected in browser. Use a publishable key (fd_pub_) instead. Aborting.");return}if(!e.key.startsWith("fd_pub_")||e.respectDoNotTrack!==!1&&Ko()||e.sampleRate!==void 0&&e.sampleRate<1&&Math.random()>e.sampleRate)return;nt=e,C=!0;let t=it(e.cookieless??!1),n=Vo(e.endpoint)??Bo,o=ge(location.pathname,e.pageRules??[]),r=Wo(e.domMode);vt(n,{sid:t,key:e.key,url:location.origin+location.pathname,page:o,ua:navigator.userAgent.slice(0,200),vw:window.innerWidth,vh:window.innerHeight,segment:e.segment,environment:e.environment},e.batchInterval,e.batchMaxSize,{domMode:r});let i=document.referrer,a="";if(i)try{a=new URL(i).origin+new URL(i).pathname}catch{a=""}u({t:"pv",ts:Date.now(),d:{ref:a}});let s=e.ignoreElements??[],c=l=>e.signals?.[l]?.enabled!==!1;if(c("rageClick")&&be(e.signals?.rageClick,s),c("deadClick")&&Ee(s),c("speedFrustration")){let l=e.signals?.speedFrustration;Me(l?{delayMs:l.windowMs}:void 0,s)}if(e.trackMouse!==!1&&c("thrashCursor")&&Ae(e.signals?.thrashCursor),c("loopNav")&&Le(e.signals?.loopNav),c("scrollBounce")&&Ie(),e.trackForms!==!1&&(c("formHesitation")||c("formAbandon"))){let l=e.signals?.formHesitation;He(l?{pauseMs:l.threshold}:void 0,s)}c("errorEncounter")&&Be(),("ontouchstart"in window||navigator.maxTouchPoints>0)&&Ye(s),(c("tabThrash")||c("focusTrap")||c("keyboardNavFrustration"))&&Ke(),c("scrollHijack")&&Ge(),c("scrollDepthAbandon")&&Je(),le=Et(S((l,h)=>{D(),Pe(),qe(),tt();let g=ge(h,e.pageRules??[]);he({page:g,url:l}),Re(h),u({t:"pv",ts:Date.now(),d:{ref:""}})})),e.debug&&console.warn("[flusterduck] initialized",{sid:t.slice(0,6)+"...",endpoint:n,page:o})}function Xo(e,t){if(!C||typeof e!="string"||!e||e.length>128)return;let n;try{let r=t?.metadata??{};n=JSON.stringify(r)}catch{return}if(n.length>2048)return;let o=JSON.parse(n);u({t:"sig",ts:Date.now(),d:{s:"custom",name:e.slice(0,128),el:typeof t?.element=="string"?t.element.slice(0,256):"",meta:o,w:Math.max(0,Math.min(t?.weight??15,100))}})}function Yo(e){if(!C||!e||typeof e!="object")return;let t=Object.create(null),n=0;for(let o of Object.keys(e)){if(n>=20)break;o==="__proto__"||o==="constructor"||o==="prototype"||(t[o.slice(0,64)]=String(e[o]).slice(0,256),n++)}he({segment:t})}function $o(e){e&&nt&&!C?mn(nt):e||(ot(),fe())}function zo(){ot(),fe()}function ot(){C&&(we(),ye(),Te(),ke(),De(),Fe(),je(),Ve(),$e(),We(),Ze(),et(),bt(),le&&(le(),le=null),C=!1)}function Ko(){return!!(navigator.doNotTrack==="1"||navigator.globalPrivacyControl)}function Wo(e){return e==="metadata"||e==="snapshot"?e:"off"}export{ot as destroy,Yo as identify,mn as init,zo as optOut,$o as setConsent,Xo as signal};
|
package/dist/queue.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SDKEvent, QueueMeta, QueueOptions } from './types';
|
|
2
|
+
export declare function initQueue(ep: string, meta: QueueMeta, interval?: number, maxSize?: number, options?: QueueOptions): void;
|
|
3
|
+
export declare function enqueue(event: SDKEvent): void;
|
|
4
|
+
export declare function flush(): void;
|
|
5
|
+
export declare function updateMeta(updates: Partial<QueueMeta>): void;
|
|
6
|
+
export declare function destroyQueue(): void;
|
package/dist/router.d.ts
ADDED
package/dist/safe.d.ts
ADDED
package/dist/script.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { initRageClick, destroyRageClick } from './rage-click';
|
|
2
|
+
export { initDeadClick, destroyDeadClick } from './dead-click';
|
|
3
|
+
export { initSpeedFrustration, destroySpeedFrustration } from './speed-frustration';
|
|
4
|
+
export { initThrashCursor, destroyThrashCursor } from './thrash-cursor';
|
|
5
|
+
export { initLoopNav, destroyLoopNav, recordNavigation } from './loop-nav';
|
|
6
|
+
export { initScrollBounce, destroyScrollBounce, resetScrollBounce, } from './scroll-bounce';
|
|
7
|
+
export { initFormSignals, destroyFormSignals, resetFormSignals, } from './form-signals';
|
|
8
|
+
export { initErrorEncounter, destroyErrorEncounter } from './error-encounter';
|
|
9
|
+
export { initMobileSignals, destroyMobileSignals } from './mobile-signals';
|
|
10
|
+
export { initKeyboardSignals, destroyKeyboardSignals, } from './keyboard-signals';
|
|
11
|
+
export { initScrollHijack, destroyScrollHijack } from './scroll-hijack';
|
|
12
|
+
export { initScrollDepthAbandon, destroyScrollDepthAbandon, resetScrollDepthAbandon, } from './scroll-depth-abandon';
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
export interface Config {
|
|
2
|
+
key: string;
|
|
3
|
+
environment?: string;
|
|
4
|
+
endpoint?: string;
|
|
5
|
+
domMode?: DOMMode;
|
|
6
|
+
sampleRate?: number;
|
|
7
|
+
signals?: Partial<Record<string, SignalOpts>>;
|
|
8
|
+
trackForms?: boolean;
|
|
9
|
+
trackMouse?: boolean;
|
|
10
|
+
respectDoNotTrack?: boolean;
|
|
11
|
+
cookieless?: boolean;
|
|
12
|
+
pageRules?: Array<{
|
|
13
|
+
pattern: string;
|
|
14
|
+
label: string;
|
|
15
|
+
}>;
|
|
16
|
+
segment?: Record<string, string>;
|
|
17
|
+
debug?: boolean;
|
|
18
|
+
batchInterval?: number;
|
|
19
|
+
batchMaxSize?: number;
|
|
20
|
+
ignoreElements?: string[];
|
|
21
|
+
ignorePages?: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface SignalOpts {
|
|
24
|
+
enabled?: boolean;
|
|
25
|
+
threshold?: number;
|
|
26
|
+
windowMs?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface SDKEvent {
|
|
29
|
+
t: string;
|
|
30
|
+
ts: number;
|
|
31
|
+
d?: Record<string, unknown>;
|
|
32
|
+
}
|
|
33
|
+
export type DOMMode = 'off' | 'metadata' | 'snapshot';
|
|
34
|
+
export interface Batch {
|
|
35
|
+
v: 1;
|
|
36
|
+
sid: string;
|
|
37
|
+
key: string;
|
|
38
|
+
url: string;
|
|
39
|
+
page: string;
|
|
40
|
+
ts: number;
|
|
41
|
+
ua: string;
|
|
42
|
+
vw: number;
|
|
43
|
+
vh: number;
|
|
44
|
+
environment?: string;
|
|
45
|
+
dom_mode: DOMMode;
|
|
46
|
+
events: IngestEvent[];
|
|
47
|
+
}
|
|
48
|
+
export interface QueueMeta {
|
|
49
|
+
sid: string;
|
|
50
|
+
key: string;
|
|
51
|
+
url: string;
|
|
52
|
+
page: string;
|
|
53
|
+
ua: string;
|
|
54
|
+
vw: number;
|
|
55
|
+
vh: number;
|
|
56
|
+
segment?: Record<string, string>;
|
|
57
|
+
environment?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface QueueOptions {
|
|
60
|
+
domMode?: DOMMode;
|
|
61
|
+
}
|
|
62
|
+
export interface IngestEvent {
|
|
63
|
+
type: string;
|
|
64
|
+
ts: number;
|
|
65
|
+
page: string;
|
|
66
|
+
signal_type?: string;
|
|
67
|
+
element?: string;
|
|
68
|
+
metadata?: Record<string, unknown>;
|
|
69
|
+
dom?: DOMEvidence;
|
|
70
|
+
}
|
|
71
|
+
export interface DOMEvidenceMetadata {
|
|
72
|
+
mode: 'metadata';
|
|
73
|
+
selector: string;
|
|
74
|
+
tag: string;
|
|
75
|
+
role: string | null;
|
|
76
|
+
attributes: {
|
|
77
|
+
disabled: boolean;
|
|
78
|
+
required: boolean;
|
|
79
|
+
ariaDisabled: boolean;
|
|
80
|
+
ariaExpanded: string | null;
|
|
81
|
+
ariaInvalid: string | null;
|
|
82
|
+
type: string | null;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export type DOMEvidence = DOMEvidenceMetadata | (SnapshotData & {
|
|
86
|
+
mode: 'snapshot';
|
|
87
|
+
});
|
|
88
|
+
export interface SnapshotData {
|
|
89
|
+
selector: string;
|
|
90
|
+
tag: string;
|
|
91
|
+
role: string | null;
|
|
92
|
+
parent: string;
|
|
93
|
+
box: {
|
|
94
|
+
x: number;
|
|
95
|
+
y: number;
|
|
96
|
+
w: number;
|
|
97
|
+
h: number;
|
|
98
|
+
};
|
|
99
|
+
styles: {
|
|
100
|
+
opacity: string;
|
|
101
|
+
cursor: string;
|
|
102
|
+
pointerEvents: string;
|
|
103
|
+
display: string;
|
|
104
|
+
visibility: string;
|
|
105
|
+
disabled: boolean;
|
|
106
|
+
};
|
|
107
|
+
inView: boolean;
|
|
108
|
+
animations: string[];
|
|
109
|
+
siblings: Array<{
|
|
110
|
+
selector: string;
|
|
111
|
+
tag: string;
|
|
112
|
+
box: {
|
|
113
|
+
x: number;
|
|
114
|
+
y: number;
|
|
115
|
+
w: number;
|
|
116
|
+
h: number;
|
|
117
|
+
};
|
|
118
|
+
interactive: boolean;
|
|
119
|
+
}>;
|
|
120
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "flusterduck",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Lightweight UX confusion monitoring SDK",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.mjs",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.mjs",
|
|
14
|
+
"require": "./dist/index.cjs"
|
|
15
|
+
},
|
|
16
|
+
"./script": "./dist/d.global.js"
|
|
17
|
+
},
|
|
18
|
+
"unpkg": "dist/d.global.js",
|
|
19
|
+
"jsdelivr": "dist/d.global.js",
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"esbuild": "0.24.2",
|
|
29
|
+
"terser": "5.46.1",
|
|
30
|
+
"typescript": "5.9.3",
|
|
31
|
+
"vitest": "2.1.9",
|
|
32
|
+
"jsdom": "25.0.1",
|
|
33
|
+
"@flusterduck/tsconfig": "0.0.0"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "node build.mjs",
|
|
37
|
+
"dev": "node build.mjs --watch",
|
|
38
|
+
"typecheck": "tsc --noEmit",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"clean": "rm -rf dist"
|
|
41
|
+
}
|
|
42
|
+
}
|