@bitpalm/ai-agents 0.4.0 → 0.6.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/README.md +57 -193
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -2
- package/dist/index.d.ts +50 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +47 -2
- package/dist/react.d.ts +47 -2
- package/dist/react.js +1 -1
- package/dist/react.js.map +1 -1
- package/dist/widget.global.js +1 -1
- package/dist/widget.global.js.map +1 -1
- package/package.json +10 -18
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var ze="https://agents.bitpalm.ai",h="_bp_",qe=new Set(["password","file","checkbox","radio","submit","button","reset","image"]),Ye=8e3,Oe=4096,He=`${h}identify_signature`,Ne=`${h}identify_fingerprint`,Re=`${h}identify_sent_at`;function Je(o){return[o.external_user_id||"",o.email||"",o.phone||"",o.name||"",o.company||"",o.signature||"",o.signed_at!=null?String(o.signed_at):"",o.signature_version||"",o.identify_source||""].join("|").toLowerCase()}function d(o,s=180){return o?o.replace(/\s+/g," ").trim().slice(0,s):""}function Ge(o){return o?` ${o.toLowerCase().replace(/[_-]+/g," ").replace(/[^a-z0-9\s@.]/g," ").replace(/\s+/g," ").trim()} `:""}function W(o,s){for(let f of s)if(o.includes(f))return!0;return!1}function A(o){return/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i.test(o)}function _(o){let s=d(o,50);if(!s)return"";let f=s.startsWith("+"),a=s.replace(/\D/g,"");return a.length<6?"":`${f?"+":""}${a.slice(0,20)}`}function Fe(o){let s=d(o,140).toLowerCase();return!s||!A(s)?"":s}function U(o,s){for(let f of s){let a=o.querySelector(f),g=d(a?.value);if(g)return g}return""}function Ve(o){return d(o.getAttribute("data-bp-field")||o.getAttribute("data-bitpalm-field"),64).toLowerCase().replace(/[_\s]+/g,"-")}function Ke(o){return o.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Xe(o,s){let f=[],a=(n,x=140)=>{let l=d(n,x);l&&f.push(l)};a(s.name),a(s.id),a(s.getAttribute("autocomplete")),a(s.getAttribute("placeholder")),a(s.getAttribute("aria-label")),a(s.getAttribute("data-field")),a(s.getAttribute("data-name")),a(s.getAttribute("data-label")),a(s.getAttribute("data-bp-field")),a(s.getAttribute("data-bitpalm-field"));let g=new Set,w=n=>{let x=d(n,200);!x||g.has(x)||(g.add(x),f.push(x))};for(let n of Array.from(s.labels||[]))w(n.textContent);if(s.id){let n=o.querySelector(`label[for="${Ke(s.id)}"]`);w(n?.textContent)}let y=s.closest("label");w(y?.textContent);let r=s.getAttribute("aria-labelledby");if(r)for(let n of r.split(/\s+/)){if(!n)continue;let x=o.ownerDocument.getElementById(n);w(x?.textContent)}return f}function Ze(o){let s=d(U(o,["[data-bp-email]","[data-bitpalm-email]"]),140).toLowerCase(),f=_(U(o,["[data-bp-phone]","[data-bitpalm-phone]"])),a=d(U(o,["[data-bp-name]","[data-bitpalm-name]","[data-bp-full-name]","[data-bitpalm-full-name]"])),g=d(U(o,["[data-bp-first-name]","[data-bitpalm-first-name]"])),w=d(U(o,["[data-bp-last-name]","[data-bitpalm-last-name]"])),y=d(U(o,["[data-bp-company]","[data-bitpalm-company]"]));for(let l of Array.from(o.elements)){if(!(l instanceof HTMLInputElement||l instanceof HTMLTextAreaElement||l instanceof HTMLSelectElement)||l.disabled||l instanceof HTMLInputElement&&qe.has(l.type.toLowerCase()))continue;let p=Ve(l),m=l.hasAttribute("data-bp-email")||l.hasAttribute("data-bitpalm-email")||l.hasAttribute("data-bp-phone")||l.hasAttribute("data-bitpalm-phone")||l.hasAttribute("data-bp-name")||l.hasAttribute("data-bitpalm-name")||l.hasAttribute("data-bp-full-name")||l.hasAttribute("data-bitpalm-full-name")||l.hasAttribute("data-bp-first-name")||l.hasAttribute("data-bitpalm-first-name")||l.hasAttribute("data-bp-last-name")||l.hasAttribute("data-bitpalm-last-name")||l.hasAttribute("data-bp-company")||l.hasAttribute("data-bitpalm-company")||!!p;if(l instanceof HTMLInputElement&&l.type.toLowerCase()==="hidden"&&!m)continue;let c=d(l.value);if(!c)continue;let $=l instanceof HTMLInputElement?l.type.toLowerCase():"",S=Ge(Xe(o,l).join(" "));if(!s&&p==="email"&&A(c)){s=c.toLowerCase();continue}if(!f&&(p==="phone"||p==="tel"||p==="mobile"||p==="whatsapp")){let I=_(c);if(I){f=I;continue}}if(!y&&p==="company"){y=d(c,160);continue}if(!g&&(p==="first-name"||p==="firstname")){g=d(c,100);continue}if(!w&&(p==="last-name"||p==="lastname"||p==="surname")){w=d(c,100);continue}if(!a&&(p==="name"||p==="full-name"||p==="fullname")){!A(c)&&!_(c)&&(a=d(c,140));continue}let j=$==="email"||W(S,[" email "," e mail "," mail "," email adresse "," mailadresse "," correo "]),O=$==="tel"||W(S,[" phone "," phone number "," mobile "," tel "," telefon "," telefonnummer "," whatsapp "," handy "," kontakt "," nummer "]),H=W(S,[" company "," company name "," firma "," firmenname "," organization "," organisation "," business "," unternehmen "," agency "," brokerage "]),N=W(S,[" first name "," firstname "," given name "," givenname "," vorname "," fname "]),R=W(S,[" last name "," lastname "," family name "," familyname "," surname "," nachname "," lname "]),z=W(S,[" full name "," fullname "," contact name "," name "])&&!j&&!O;if(!s&&j&&A(c)){s=c.toLowerCase();continue}if(!f&&O){let I=_(c);if(I){f=I;continue}}if(!y&&H){y=d(c,160);continue}if(!g&&N){g=d(c,100);continue}if(!w&&R){w=d(c,100);continue}if(!a&&z&&!A(c)&&!_(c)){a=d(c,140);continue}!s&&A(c)&&(s=c.toLowerCase())}if(a&&(A(a)||_(a))&&(a=""),y&&(A(y)||_(y))&&(y=""),a||(a=d([g,w].filter(Boolean).join(" "),140)),a&&s&&a.toLowerCase()===s.toLowerCase()&&(a=""),!!!(s||f)&&!!!(a&&y))return null;let x={...a?{name:a}:{},...s?{email:s}:{},...f?{phone:f}:{},...y?{company:y}:{}};return Object.keys(x).length>0?x:null}function Qe(){if(typeof document<"u"){let o=document.documentElement.lang;if(o)return o.slice(0,2).toLowerCase()}return"en"}function de(o,s=1200){if(typeof window<"u"&&"requestIdleCallback"in window){window.requestIdleCallback(o,{timeout:s});return}setTimeout(o,Math.min(s,300))}function me(){if(typeof window>"u")return!1;let o=typeof navigator<"u"?navigator.userAgent:"";if(/Android|iPhone|iPad|iPod|IEMobile|Windows Phone|Mobile/i.test(o))return!0;let f=window.matchMedia("(pointer: coarse)").matches,a=window.matchMedia("(hover: none)").matches,g=Math.min(window.screen?.width||window.innerWidth,window.screen?.height||window.innerHeight);return f&&a&&g<=900}function ue(o){let{slug:s,locale:f=Qe(),baseUrl:a=ze,token:g,zIndex:w=9999,autoIdentify:y=!0}=o,r=document,n=r.createElement("iframe"),x=`${a}/t/${s}/widget`,l=new URLSearchParams({locale:f});g&&l.set("token",g),n.src=`${x}?${l.toString()}`,n.allow="clipboard-write; microphone",n.setAttribute("allowtransparency","true"),n.loading="lazy",n.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${w};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`;let p=new URL(n.src).origin,m=r.createElement("div");if(m.setAttribute("role","button"),m.setAttribute("aria-label","Chat"),m.style.cssText=`position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;display:none;align-items:center;justify-content:center;cursor:pointer;z-index:${w-1};background:#00ff41;box-shadow:0 0 15px rgba(0,255,65,0.31);transition:transform .2s,opacity .3s;opacity:0;`,m.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',m.onmouseenter=()=>{m.style.transform="scale(1.1)"},m.onmouseleave=()=>{m.style.transform="scale(1)"},m.onclick=()=>X(),r.body.appendChild(m),!r.getElementById("_bp_fade")){let e=r.createElement("style");e.id="_bp_fade",e.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",r.head.appendChild(e)}let c=null,$=!1,S=!1,j=!1,O=!1,H=!1,N=()=>{j||(j=!0,r.body.appendChild(n))},R=!1,z=0,I={overflow:"",overscrollBehavior:""},v={overflow:"",overscrollBehavior:"",position:"",top:"",left:"",right:"",width:""},fe=()=>{if(R||!me())return;let i=r.documentElement,t=r.body;z=window.scrollY||window.pageYOffset||0,I.overflow=i.style.overflow,I.overscrollBehavior=i.style.overscrollBehavior,v.overflow=t.style.overflow,v.overscrollBehavior=t.style.overscrollBehavior,v.position=t.style.position,v.top=t.style.top,v.left=t.style.left,v.right=t.style.right,v.width=t.style.width,i.style.overflow="hidden",i.style.overscrollBehavior="none",t.style.overflow="hidden",t.style.overscrollBehavior="none",t.style.position="fixed",t.style.top=`-${z}px`,t.style.left="0",t.style.right="0",t.style.width="100%",R=!0},F=()=>{if(!R)return;let e=r.documentElement,i=r.body;e.style.overflow=I.overflow,e.style.overscrollBehavior=I.overscrollBehavior,i.style.overflow=v.overflow,i.style.overscrollBehavior=v.overscrollBehavior,i.style.position=v.position,i.style.top=v.top,i.style.left=v.left,i.style.right=v.right,i.style.width=v.width,window.scrollTo(0,z),R=!1},pe=()=>{let e=me();n.style.display==="none"&&(n.style.display=""),e?(n.style.width="100vw",n.style.height="100dvh",n.style.left="0",n.style.top="0",n.style.bottom="0",n.style.right="0",fe()):(n.style.width="420px",n.style.height="620px",n.style.bottom="24px",n.style.right="24px",n.style.left="",n.style.top="",F()),n.style.opacity="1",n.style.pointerEvents="auto"},C=()=>{c&&(c.remove(),c=null)},J=()=>{},Q=()=>{},D=!1,P=new Map;function ee(e,i){let t=P.get(e);if(t)for(let u of t)try{u(i)}catch{}}let ge=e=>{if(e.origin===p){if(e.data?.type==="bitpalm-widget-config"){S=!1,$=!0,n.style.display==="none"&&(n.style.display=""),e.data.primaryColor&&(m.style.background=e.data.primaryColor,m.style.boxShadow=e.data.chatShadow==="none"?"none":`0 0 15px ${e.data.primaryColor}50`);let i=e.data.chatButtonIconColor||"black";if(e.data.chatButtonIconSvg){m.innerHTML="";let t=r.createElement("span");t.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${i}`;let b=new DOMParser().parseFromString(e.data.chatButtonIconSvg,"image/svg+xml").querySelector("svg");b?(b.querySelectorAll("script,foreignObject").forEach(B=>B.remove()),b.querySelectorAll("*").forEach(B=>{for(let k of[...B.attributes])(k.name.startsWith("on")||k.value&&k.value.includes("javascript:"))&&B.removeAttribute(k.name)}),b.setAttribute("width","24"),b.setAttribute("height","24"),b.style.display="block",t.appendChild(b)):t.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',m.appendChild(t)}else{let t=m.querySelector("svg");t&&(t.style.stroke=i)}m.style.display="flex",requestAnimationFrame(()=>{m.style.opacity="1"})}if(e.data?.type==="bitpalm-widget-resize"){let i=e.data.width>0,t=D;D=i,i&&!t&&ee("widget_opened"),!i&&t&&ee("widget_closed");let u=me();i?(n.style.width=u?"100vw":`${e.data.width}px`,n.style.height=u?"100dvh":`${e.data.height}px`,u?(n.style.left="0",n.style.top="0",n.style.bottom="0",n.style.right="0",fe()):F(),n.style.opacity="1",n.style.pointerEvents="auto"):(F(),n.style.width="1px",n.style.height="1px",n.style.left="",n.style.top="",n.style.opacity="0",n.style.pointerEvents="none"),m.style.display=i?"none":"flex"}if(e.data?.type==="bitpalm-trigger-show"){if(S||!$)return;C(),c=r.createElement("div"),c.style.cssText=`position:fixed;bottom:90px;right:24px;max-width:240px;background:#fff;border-radius:16px;padding:12px 32px 12px 12px;box-shadow:0 2px 20px rgba(0,0,0,0.08);cursor:pointer;z-index:${w-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;let i=(e.data.message||"").replace(/</g,"<");c.innerHTML=`<p style="font-size:14px;color:#1f2937;margin:0;">${i}</p><div style="position:absolute;bottom:-8px;right:20px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #fff;"></div>`;let t=r.createElement("button");t.style.cssText="position:absolute;top:-8px;right:-8px;width:28px;height:28px;border-radius:50%;background:#fff;border:none;box-shadow:0 1px 4px rgba(0,0,0,0.1);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;color:#9ca3af;",t.innerHTML="✕",t.onclick=u=>{u.stopPropagation(),C(),n.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},c.onclick=()=>{if(C(),m.style.display="none",pe(),N(),!O){H=!0;return}n.contentWindow?.postMessage({type:"bitpalm-trigger-engaged",message:i},"*")},c.appendChild(t),r.body.appendChild(c)}e.data?.type==="bitpalm-trigger-hide"&&C(),e.data?.type==="bitpalm-request-context"&&J(),e.data?.type==="bitpalm-chat-event"&&e.data.event&&ee(e.data.event,e.data.data),e.data?.type==="bitpalm-widget-blocked"&&(S=!0,$=!1,m.style.display="none",C(),F(),n.style.display="none")}};window.addEventListener("message",ge);let L=!1;try{L=localStorage.getItem(`${h}optout`)==="1"}catch{}let G=`${h}vid`,E="";if(!L){try{E=localStorage.getItem(G)||""}catch{}if(!E){let e=r.cookie.match(new RegExp(`(?:^|; )${G}=([^;]+)`));E=e?decodeURIComponent(e[1]):""}E||(E=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(G,E)}catch{}try{r.cookie=`${G}=${encodeURIComponent(E)};path=/;max-age=31536000;SameSite=Lax`}catch{}}L||de(()=>{try{let e=new URLSearchParams(location.search),i={};for(let T of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let b=e.get(T);b&&(i[T]=b)}let t=JSON.stringify({tenant_slug:s,visitor_id:E,url:location.href,referrer:r.referrer||void 0,...Object.keys(i).length>0?{utm:i}:{}}),u=`${a}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(u,new Blob([t],{type:"application/json"})):fetch(u,{method:"POST",body:t,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}},2e3);let te="",ne="",oe=0;try{te=sessionStorage.getItem(He)||"",ne=sessionStorage.getItem(Ne)||"";let e=parseInt(sessionStorage.getItem(Re)||"0",10);Number.isFinite(e)&&e>0&&(oe=e)}catch{}let ye=(e,i="")=>{if(L||!E)return;let t={},u=d(e.name,140),T=Fe(e.email),b=_(e.phone),B=d(e.company,160),k=d(e.external_user_id,140),Be=d(e.signature,260),re=Number(e.signed_at);if(u&&(t.name=u),T&&(t.email=T),b&&(t.phone=b),B&&(t.company=B),k&&(t.external_user_id=k),Be&&(t.signature=Be),Number.isFinite(re)&&re>0&&(t.signed_at=Math.floor(re)),(e.signature_version==="v1"||t.signature)&&(t.signature_version="v1"),(e.identify_source==="manual"||e.identify_source==="form")&&(t.identify_source=e.identify_source),!t.name&&!t.email&&!t.phone&&!t.company&&!t.external_user_id)return;let Z=Je(t),le=[i.toLowerCase(),Z].filter(Boolean).join("|"),ce=Date.now();if(!(ce-oe<Ye&&(le===te||Z===ne))){te=le,ne=Z,oe=ce;try{sessionStorage.setItem(He,le),sessionStorage.setItem(Ne,Z),sessionStorage.setItem(Re,String(ce))}catch{}try{let ke=JSON.stringify({tenant_slug:s,visitor_id:E,url:location.href,referrer:r.referrer||void 0,...t}),$e=`${a}/api/widget/identify`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon($e,new Blob([ke],{type:"application/json"})):fetch($e,{method:"POST",body:ke,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}}},he=e=>{if(L||!y||!E)return;let i=e.target instanceof HTMLFormElement?e.target:e.target instanceof Element?e.target.closest("form"):null;if(!(i instanceof HTMLFormElement))return;let t=(i.getAttribute("data-bp-identify")||i.getAttribute("data-bitpalm-identify")||"").toLowerCase();if(t==="off"||t==="false"||t==="0")return;let u=Ze(i);if(!u)return;let T=[i.getAttribute("id")||"",i.getAttribute("name")||"",i.getAttribute("action")||""].join("|");ye({...u,identify_source:"form"},T)};!L&&y&&r.addEventListener("submit",he,!0);let q=parseInt(sessionStorage.getItem(`${h}pages`)||"0")+1;sessionStorage.setItem(`${h}pages`,String(q));let M=JSON.parse(sessionStorage.getItem(`${h}hist`)||"[]");M.push(location.href),M.length>20&&(M=M.slice(-20)),sessionStorage.setItem(`${h}hist`,JSON.stringify(M));let be=Date.now(),V=parseInt(sessionStorage.getItem(`${h}site_start`)||"0");V||(V=be,sessionStorage.setItem(`${h}site_start`,String(V)));let we=[];J=()=>{let e=!1;try{e=!!localStorage.getItem(`${h}visited`)}catch{e=!1}if(n.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:r.title,returning:e,pageCount:q,pageHistory:M,loadedAt:be,siteStart:V,locale:f,visitorId:L?"":E},"*"),!e&&!L)try{localStorage.setItem(`${h}visited`,"1")}catch{}},n.addEventListener("load",()=>{O=!0,J(),[120,450,1100].forEach(e=>{let i=setTimeout(()=>J(),e);we.push(i)}),H&&(H=!1,Q())}),r.readyState==="loading"?r.addEventListener("DOMContentLoaded",()=>de(N,1600),{once:!0}):de(N,1600);let ve=history.pushState.bind(history),xe=history.replaceState.bind(history),K=()=>{q++,sessionStorage.setItem(`${h}pages`,String(q));let e=JSON.parse(sessionStorage.getItem(`${h}hist`)||"[]");if(e.push(location.href),e.length>20&&e.splice(0,e.length-20),M=e,sessionStorage.setItem(`${h}hist`,JSON.stringify(e)),n.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:r.title,pageCount:q,pageHistory:e,loadedAt:Date.now()},"*"),!L)try{let i=JSON.stringify({tenant_slug:s,visitor_id:E,url:location.href}),t=`${a}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(t,new Blob([i],{type:"application/json"})):fetch(t,{method:"POST",body:i,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...e){ve(...e),K()},history.replaceState=function(...e){xe(...e),K()},window.addEventListener("popstate",K);let Ee=-1,ie,Se=()=>{clearTimeout(ie),ie=setTimeout(()=>{let e=Math.max(r.documentElement.scrollHeight,r.body.scrollHeight)-window.innerHeight,i=e>0?Math.round(window.scrollY/e*100):100;i!==Ee&&(Ee=i,n.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:i},"*"))},500)};window.addEventListener("scroll",Se,{passive:!0});let Ie=e=>{e.clientY<=0&&n.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};r.addEventListener("mouseout",Ie);let se,Le=!1,ae=()=>{clearTimeout(se),!Le&&(se=setTimeout(()=>{Le=!0,n.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},Te=["mousemove","keydown","scroll","touchstart"];Te.forEach(e=>r.addEventListener(e,ae,{passive:!0})),ae(),Q=()=>{n.contentWindow?.postMessage({type:"bitpalm-open"},"*");let e=n.src.split("#")[0];n.src=`${e}#bp-open-${Date.now()}`};let X=()=>{if(m.style.display="none",C(),pe(),N(),!O){H=!0;return}Q()},_e=()=>{F(),n.contentWindow?.postMessage({type:"bitpalm-close"},"*")},Ae=e=>{!e||typeof e!="object"||ye({external_user_id:d(e.externalUserId,140)||void 0,name:d(e.name,140)||void 0,email:Fe(e.email)||void 0,phone:_(e.phone)||void 0,company:d(e.company,160)||void 0,signature:d(e.signature,260)||void 0,signed_at:Number.isFinite(Number(e.signedAt))?Math.floor(Number(e.signedAt)):void 0,signature_version:e.signatureVersion==="v1"?"v1":void 0,identify_source:"manual"},"manual")},De=()=>{D?_e():X()},We=()=>D,Ue=e=>{if(!e||typeof e!="string")return;let i=e.trim().slice(0,1e4);i&&(D||X(),setTimeout(()=>{n.contentWindow?.postMessage({type:"bitpalm-send-message",message:i},"*")},D?50:500))},Y={},Ce=e=>{if(!e||typeof e!="object"||Array.isArray(e))return;Y={...Y,...e};let i=JSON.stringify(Y);i.length>Oe&&console.warn(`[BitPalm] Custom context exceeds ${Oe} bytes (${i.length}). It may be truncated.`),n.contentWindow?.postMessage({type:"bitpalm-custom-context",data:Y},"*")},je=()=>{Y={},n.contentWindow?.postMessage({type:"bitpalm-custom-context",data:{}},"*")},Pe=e=>{let t=e.detail;if(!t||typeof t!="object")return;let u=d(t.slug,120);if(u&&u!==s)return;let{slug:T,...b}=t;Ce(b)};window.addEventListener("bitpalm-context",Pe);let Me=e=>{let t=e.detail;if(!t||typeof t!="object")return;let u=d(t.slug,120);u&&u!==s||Ae(t)};return window.addEventListener("bitpalm-identify",Me),{open:X,close:_e,toggle:De,isOpen:We,identify:Ae,context:Ce,resetContext:je,send:Ue,on:(e,i)=>(P.has(e)||P.set(e,new Set),P.get(e).add(i),()=>P.get(e)?.delete(i)),off:(e,i)=>{P.get(e)?.delete(i)},destroy:()=>{window.removeEventListener("message",ge),window.removeEventListener("scroll",Se),window.removeEventListener("popstate",K),r.removeEventListener("mouseout",Ie),r.removeEventListener("submit",he,!0),Te.forEach(e=>r.removeEventListener(e,ae)),clearTimeout(ie),clearTimeout(se),we.forEach(e=>clearTimeout(e)),history.pushState=ve,history.replaceState=xe,window.removeEventListener("bitpalm-identify",Me),window.removeEventListener("bitpalm-context",Pe),P.clear(),F(),C(),m.remove(),n.remove()}}}function et(o){if(o==null)return;let s=o.trim().toLowerCase();if(["1","true","yes","on"].includes(s))return!0;if(["0","false","no","off"].includes(s))return!1}if(typeof document<"u"){let o=document.currentScript;if(o?.dataset.slug){let s=()=>{ue({slug:o.dataset.slug,locale:o.dataset.locale,baseUrl:o.dataset.baseUrl,token:o.dataset.token,zIndex:o.dataset.zIndex?Number(o.dataset.zIndex):void 0,autoIdentify:et(o.dataset.autoIdentify)})};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",s):s()}}export{ue as createWidget};
|
|
1
|
+
function ae(t){if(t===!1)return"off";if(typeof t=="string"){let n=t.trim().toLowerCase();if(["false","off","0","no","none"].includes(n))return"off";if(n==="events")return"events"}return"bubble"}function st(t){return t==="off"?!1:t==="events"?"events":!0}function rt(t,n){let l=t.createElement("div");l.setAttribute("data-bitpalm-trigger",""),l.style.cssText=`max-width:240px;background:#fff;border-radius:16px;padding:12px 32px 12px 12px;box-shadow:0 2px 20px rgba(0,0,0,0.08);cursor:pointer;z-index:${n.zIndex-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`,l.style.position="fixed",l.style.right="24px",l.style.bottom=`${n.bottom}px`;let r=t.createElement("p");r.style.cssText="font-size:14px;color:#1f2937;margin:0;",r.textContent=n.message;let m=t.createElement("div");m.style.cssText="position:absolute;bottom:-8px;right:20px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #fff;";let u=t.createElement("button");return u.type="button",u.setAttribute("aria-label","Close"),u.style.cssText="position:absolute;top:-8px;right:-8px;width:28px;height:28px;border-radius:50%;background:#fff;border:none;box-shadow:0 1px 4px rgba(0,0,0,0.1);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;color:#9ca3af;",u.textContent="\u2715",u.onclick=g=>{g.stopPropagation(),n.onDismiss()},l.onclick=()=>n.onEngage(),l.append(r,m,u),l}var xt=["dark","dark-mode","dark-theme","theme-dark"],St=["light","light-mode","light-theme","theme-light"],ct=["data-theme","data-color-scheme","data-color-mode","data-mode","data-bs-theme"],dt="(prefers-color-scheme: dark)";function R(t){return t==="light"||t==="dark"?t:"auto"}function at(t){if(!t)return null;if(xt.some(n=>t.classList.contains(n)))return"dark";if(St.some(n=>t.classList.contains(n)))return"light";for(let n of ct){let l=(t.getAttribute(n)||"").toLowerCase();if(l.includes("dark"))return"dark";if(l.includes("light"))return"light"}return null}function xe(t){let n=t/255;return n<=.03928?n/12.92:((n+.055)/1.055)**2.4}function lt(t,n){if(!t)return null;let l=n.getComputedStyle(t).backgroundColor.match(/rgba?\(([^)]+)\)/);if(!l)return null;let[r,m,u,g=1]=l[1].split(/[\s,/]+/).filter(Boolean).map(Number);return[r,m,u,g].some(a=>Number.isNaN(a))||g<.5?null:.2126*xe(r)+.7152*xe(m)+.0722*xe(u)<.2?"dark":"light"}function Lt(t,n){let l=n.getComputedStyle(t.documentElement).colorScheme||"",r=t.querySelector('meta[name="color-scheme"]')?.getAttribute("content")||"",m=`${l} ${r}`.toLowerCase();return m.includes("dark")?m.includes("light")?n.matchMedia?.(dt).matches?"dark":"light":"dark":null}function W(t=document,n=window){return at(t.documentElement)??at(t.body)??lt(t.body,n)??lt(t.documentElement,n)??Lt(t,n)??"light"}function Se(t,n=document,l=window){let r=W(n,l),m=!1,u=()=>{m=!1;let c=W(n,l);c!==r&&(r=c,t(c))},g=()=>{m||(m=!0,typeof l.requestAnimationFrame=="function"?l.requestAnimationFrame(u):setTimeout(u,16))},T=typeof MutationObserver<"u"?new MutationObserver(g):null,a={attributes:!0,attributeFilter:["class","style",...ct]};T?.observe(n.documentElement,a),n.body&&T?.observe(n.body,a);let h=typeof l.matchMedia=="function"?l.matchMedia(dt):null;return h?.addEventListener?.("change",g),()=>{T?.disconnect(),h?.removeEventListener?.("change",g)}}var It="https://agents.bitpalm.ai",v="_bp_",_t=new Set(["password","file","checkbox","radio","submit","button","reset","image"]),At=8e3,mt=4096,ut=`${v}identify_signature`,ft=`${v}identify_fingerprint`,gt=`${v}identify_sent_at`,pt="0 4px 14px rgba(0,0,0,0.18)";function Ct(t){return[t.external_user_id||"",t.email||"",t.phone||"",t.name||"",t.company||"",t.signature||"",t.signed_at!=null?String(t.signed_at):"",t.signature_version||"",t.identify_source||""].join("|").toLowerCase()}function d(t,n=180){return t?t.replace(/\s+/g," ").trim().slice(0,n):""}function Mt(t){return t?` ${t.toLowerCase().replace(/[_-]+/g," ").replace(/[^a-z0-9\s@.]/g," ").replace(/\s+/g," ").trim()} `:""}function F(t,n){for(let l of n)if(t.includes(l))return!0;return!1}function M(t){return/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i.test(t)}function _(t){let n=d(t,50);if(!n)return"";let l=n.startsWith("+"),r=n.replace(/\D/g,"");return r.length<6?"":`${l?"+":""}${r.slice(0,20)}`}function ht(t){let n=d(t,140).toLowerCase();return!n||!M(n)?"":n}function U(t,n){for(let l of n){let r=t.querySelector(l),m=d(r?.value);if(m)return m}return""}function kt(t){return d(t.getAttribute("data-bp-field")||t.getAttribute("data-bitpalm-field"),64).toLowerCase().replace(/[_\s]+/g,"-")}function Bt(t){return t.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Pt(t,n){let l=[],r=(a,h=140)=>{let c=d(a,h);c&&l.push(c)};r(n.name),r(n.id),r(n.getAttribute("autocomplete")),r(n.getAttribute("placeholder")),r(n.getAttribute("aria-label")),r(n.getAttribute("data-field")),r(n.getAttribute("data-name")),r(n.getAttribute("data-label")),r(n.getAttribute("data-bp-field")),r(n.getAttribute("data-bitpalm-field"));let m=new Set,u=a=>{let h=d(a,200);!h||m.has(h)||(m.add(h),l.push(h))};for(let a of Array.from(n.labels||[]))u(a.textContent);if(n.id){let a=t.querySelector(`label[for="${Bt(n.id)}"]`);u(a?.textContent)}let g=n.closest("label");u(g?.textContent);let T=n.getAttribute("aria-labelledby");if(T)for(let a of T.split(/\s+/)){if(!a)continue;let h=t.ownerDocument.getElementById(a);u(h?.textContent)}return l}function Ht(t){let n=d(U(t,["[data-bp-email]","[data-bitpalm-email]"]),140).toLowerCase(),l=_(U(t,["[data-bp-phone]","[data-bitpalm-phone]"])),r=d(U(t,["[data-bp-name]","[data-bitpalm-name]","[data-bp-full-name]","[data-bitpalm-full-name]"])),m=d(U(t,["[data-bp-first-name]","[data-bitpalm-first-name]"])),u=d(U(t,["[data-bp-last-name]","[data-bitpalm-last-name]"])),g=d(U(t,["[data-bp-company]","[data-bitpalm-company]"]));for(let c of Array.from(t.elements)){if(!(c instanceof HTMLInputElement||c instanceof HTMLTextAreaElement||c instanceof HTMLSelectElement)||c.disabled||c instanceof HTMLInputElement&&_t.has(c.type.toLowerCase()))continue;let y=kt(c),z=c.hasAttribute("data-bp-email")||c.hasAttribute("data-bitpalm-email")||c.hasAttribute("data-bp-phone")||c.hasAttribute("data-bitpalm-phone")||c.hasAttribute("data-bp-name")||c.hasAttribute("data-bitpalm-name")||c.hasAttribute("data-bp-full-name")||c.hasAttribute("data-bitpalm-full-name")||c.hasAttribute("data-bp-first-name")||c.hasAttribute("data-bitpalm-first-name")||c.hasAttribute("data-bp-last-name")||c.hasAttribute("data-bitpalm-last-name")||c.hasAttribute("data-bp-company")||c.hasAttribute("data-bitpalm-company")||!!y;if(c instanceof HTMLInputElement&&c.type.toLowerCase()==="hidden"&&!z)continue;let f=d(c.value);if(!f)continue;let A=c instanceof HTMLInputElement?c.type.toLowerCase():"",s=Mt(Pt(t,c).join(" "));if(!n&&y==="email"&&M(f)){n=f.toLowerCase();continue}if(!l&&(y==="phone"||y==="tel"||y==="mobile"||y==="whatsapp")){let S=_(f);if(S){l=S;continue}}if(!g&&y==="company"){g=d(f,160);continue}if(!m&&(y==="first-name"||y==="firstname")){m=d(f,100);continue}if(!u&&(y==="last-name"||y==="lastname"||y==="surname")){u=d(f,100);continue}if(!r&&(y==="name"||y==="full-name"||y==="fullname")){!M(f)&&!_(f)&&(r=d(f,140));continue}let K=A==="email"||F(s,[" email "," e mail "," mail "," email adresse "," mailadresse "," correo "]),O=A==="tel"||F(s,[" phone "," phone number "," mobile "," tel "," telefon "," telefonnummer "," whatsapp "," handy "," kontakt "," nummer "]),le=F(s,[" company "," company name "," firma "," firmenname "," organization "," organisation "," business "," unternehmen "," agency "," brokerage "]),p=F(s,[" first name "," firstname "," given name "," givenname "," vorname "," fname "]),k=F(s,[" last name "," lastname "," family name "," familyname "," surname "," nachname "," lname "]),j=F(s,[" full name "," fullname "," contact name "," name "])&&!K&&!O;if(!n&&K&&M(f)){n=f.toLowerCase();continue}if(!l&&O){let S=_(f);if(S){l=S;continue}}if(!g&&le){g=d(f,160);continue}if(!m&&p){m=d(f,100);continue}if(!u&&k){u=d(f,100);continue}if(!r&&j&&!M(f)&&!_(f)){r=d(f,140);continue}!n&&M(f)&&(n=f.toLowerCase())}if(r&&(M(r)||_(r))&&(r=""),g&&(M(g)||_(g))&&(g=""),r||(r=d([m,u].filter(Boolean).join(" "),140)),r&&n&&r.toLowerCase()===n.toLowerCase()&&(r=""),!!!(n||l)&&!!!(r&&g))return null;let h={...r?{name:r}:{},...n?{email:n}:{},...l?{phone:l}:{},...g?{company:g}:{}};return Object.keys(h).length>0?h:null}function $t(){if(typeof document<"u"){let t=document.documentElement.lang;if(t)return t.slice(0,2).toLowerCase()}return"en"}function Le(t,n=1200){if(typeof window<"u"&&"requestIdleCallback"in window){window.requestIdleCallback(t,{timeout:n});return}setTimeout(t,Math.min(n,300))}function Ie(){if(typeof window>"u")return!1;let t=typeof navigator<"u"?navigator.userAgent:"";if(/Android|iPhone|iPad|iPod|IEMobile|Windows Phone|Mobile/i.test(t))return!0;let l=window.matchMedia("(pointer: coarse)").matches,r=window.matchMedia("(hover: none)").matches,m=Math.min(window.screen?.width||window.innerWidth,window.screen?.height||window.innerHeight);return l&&r&&m<=900}function _e(t){let{slug:n,locale:l=$t(),baseUrl:r=It,token:m,zIndex:u=9999,autoIdentify:g=!0,launcher:T=!0}=t,a=document,h=R(t.theme),c=h==="auto"?W():h,y=null,z=ae(t.triggers),f=z,A=null,s=a.createElement("iframe");s.setAttribute("data-bitpalm-chat","");let K=`${r}/t/${n}/widget`,O=new URLSearchParams({locale:l,theme:c});m&&O.set("token",m),f==="off"&&O.set("triggers","off"),s.src=`${K}?${O.toString()}`,s.allow="clipboard-write; microphone",s.setAttribute("allowtransparency","true"),s.loading="lazy",s.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${u};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`;let le=new URL(s.src).origin,p=a.createElement("div");if(p.setAttribute("role","button"),p.setAttribute("aria-label","Chat"),p.setAttribute("data-bitpalm-launcher",""),p.style.cssText=`position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;display:none;align-items:center;justify-content:center;cursor:pointer;z-index:${u-1};background:#171717;box-shadow:${pt};transition:transform .2s,opacity .3s;opacity:0;`,p.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',p.onmouseenter=()=>{p.style.transform="scale(1.05)"},p.onmouseleave=()=>{p.style.transform="scale(1)"},p.onclick=()=>J(),T&&a.body.appendChild(p),!a.getElementById("_bp_fade")){let e=a.createElement("style");e.id="_bp_fade",e.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",a.head.appendChild(e)}let k=null,j=!1,S=!1,Ae=!1,ce=!1,V=!1,X=()=>{Ae||(Ae=!0,a.body.appendChild(s))},Z=!1,de=0,Q={overflow:"",overscrollBehavior:""},E={overflow:"",overscrollBehavior:"",position:"",top:"",left:"",right:"",width:""},Ce=()=>{if(Z||!Ie())return;let o=a.documentElement,i=a.body;de=window.scrollY||window.pageYOffset||0,Q.overflow=o.style.overflow,Q.overscrollBehavior=o.style.overscrollBehavior,E.overflow=i.style.overflow,E.overscrollBehavior=i.style.overscrollBehavior,E.position=i.style.position,E.top=i.style.top,E.left=i.style.left,E.right=i.style.right,E.width=i.style.width,o.style.overflow="hidden",o.style.overscrollBehavior="none",i.style.overflow="hidden",i.style.overscrollBehavior="none",i.style.position="fixed",i.style.top=`-${de}px`,i.style.left="0",i.style.right="0",i.style.width="100%",Z=!0},D=()=>{if(!Z)return;let e=a.documentElement,o=a.body;e.style.overflow=Q.overflow,e.style.overscrollBehavior=Q.overscrollBehavior,o.style.overflow=E.overflow,o.style.overscrollBehavior=E.overscrollBehavior,o.style.position=E.position,o.style.top=E.top,o.style.left=E.left,o.style.right=E.right,o.style.width=E.width,window.scrollTo(0,de),Z=!1},Me=()=>{let e=Ie();s.style.display==="none"&&(s.style.display=""),e?(s.style.width="100vw",s.style.height="100dvh",s.style.left="0",s.style.top="0",s.style.bottom="0",s.style.right="0",Ce()):(s.style.width="420px",s.style.height="620px",s.style.bottom="24px",s.style.right="24px",s.style.left="",s.style.top="",D()),s.style.opacity="1",s.style.pointerEvents="auto"},C=()=>{k&&(k.remove(),k=null)},ee=()=>{A!==null&&(A=null,q("trigger_hidden"))},ke=()=>{s.contentWindow?.postMessage({type:"bitpalm-triggers",enabled:f!=="off"},"*")},te=()=>{},me=()=>{},N=!1,B=new Map;function q(e,o){let i=B.get(e);if(i)for(let b of i)try{b(o)}catch{}}let Be=e=>{if(e.origin===le){if(e.data?.type==="bitpalm-widget-config"){S=!1,j=!0,s.style.display==="none"&&(s.style.display=""),e.data.primaryColor&&(p.style.background=e.data.primaryColor,p.style.boxShadow=e.data.chatShadow==="none"?"none":pt);let o=e.data.chatButtonIconColor||"black";if(e.data.chatButtonIconSvg){p.innerHTML="";let i=a.createElement("span");i.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${o}`;let w=new DOMParser().parseFromString(e.data.chatButtonIconSvg,"image/svg+xml").querySelector("svg");w?(w.querySelectorAll("script,foreignObject").forEach(H=>H.remove()),w.querySelectorAll("*").forEach(H=>{for(let $ of[...H.attributes])($.name.startsWith("on")||$.value&&$.value.includes("javascript:"))&&H.removeAttribute($.name)}),w.setAttribute("width","24"),w.setAttribute("height","24"),w.style.display="block",i.appendChild(w)):i.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',p.appendChild(i)}else{let i=p.querySelector("svg");i&&(i.style.stroke=o)}T&&(p.style.display="flex",requestAnimationFrame(()=>{p.style.opacity="1"})),ke()}if(e.data?.type==="bitpalm-widget-resize"){let o=e.data.width>0,i=N;N=o,o&&!i&&q("widget_opened"),!o&&i&&q("widget_closed");let b=Ie();o?(s.style.width=b?"100vw":`${e.data.width}px`,s.style.height=b?"100dvh":`${e.data.height}px`,b?(s.style.left="0",s.style.top="0",s.style.bottom="0",s.style.right="0",Ce()):D(),s.style.opacity="1",s.style.pointerEvents="auto"):(D(),s.style.width="1px",s.style.height="1px",s.style.left="",s.style.top="",s.style.opacity="0",s.style.pointerEvents="none"),p.style.display=o||!T?"none":"flex"}if(e.data?.type==="bitpalm-trigger-show"){if(S||!j||f==="off")return;let o=typeof e.data.message=="string"?e.data.message:"";if(!o)return;if(f==="events"){A=o,q("trigger_shown",{message:o,triggerId:e.data.triggerId,triggerType:e.data.triggerType});return}C(),k=rt(a,{message:o,zIndex:u,bottom:T?90:24,onDismiss:()=>{C(),s.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},onEngage:()=>{if(C(),p.style.display="none",Me(),X(),!ce){V=!0;return}s.contentWindow?.postMessage({type:"bitpalm-trigger-engaged",message:o},"*")}}),a.body.appendChild(k)}e.data?.type==="bitpalm-trigger-hide"&&(C(),ee()),e.data?.type==="bitpalm-request-context"&&te(),e.data?.type==="bitpalm-chat-event"&&e.data.event&&q(e.data.event,e.data.data),e.data?.type==="bitpalm-widget-blocked"&&(S=!0,j=!1,p.style.display="none",C(),ee(),D(),s.style.display="none")}};window.addEventListener("message",Be);let L=!1;try{L=localStorage.getItem(`${v}optout`)==="1"}catch{}let ne=`${v}vid`,x="";if(!L){try{x=localStorage.getItem(ne)||""}catch{}if(!x){let e=a.cookie.match(new RegExp(`(?:^|; )${ne}=([^;]+)`));x=e?decodeURIComponent(e[1]):""}x||(x=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(ne,x)}catch{}try{a.cookie=`${ne}=${encodeURIComponent(x)};path=/;max-age=31536000;SameSite=Lax`}catch{}}L||Le(()=>{try{let e=new URLSearchParams(location.search),o={};for(let I of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let w=e.get(I);w&&(o[I]=w)}let i=JSON.stringify({tenant_slug:n,visitor_id:x,url:location.href,referrer:a.referrer||void 0,...Object.keys(o).length>0?{utm:o}:{}}),b=`${r}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(b,new Blob([i],{type:"application/json"})):fetch(b,{method:"POST",body:i,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}},2e3);let ue="",fe="",ge=0;try{ue=sessionStorage.getItem(ut)||"",fe=sessionStorage.getItem(ft)||"";let e=parseInt(sessionStorage.getItem(gt)||"0",10);Number.isFinite(e)&&e>0&&(ge=e)}catch{}let Pe=(e,o="")=>{if(L||!x)return;let i={},b=d(e.name,140),I=ht(e.email),w=_(e.phone),H=d(e.company,160),$=d(e.external_user_id,140),nt=d(e.signature,260),we=Number(e.signed_at);if(b&&(i.name=b),I&&(i.email=I),w&&(i.phone=w),H&&(i.company=H),$&&(i.external_user_id=$),nt&&(i.signature=nt),Number.isFinite(we)&&we>0&&(i.signed_at=Math.floor(we)),(e.signature_version==="v1"||i.signature)&&(i.signature_version="v1"),(e.identify_source==="manual"||e.identify_source==="form")&&(i.identify_source=e.identify_source),!i.name&&!i.email&&!i.phone&&!i.company&&!i.external_user_id)return;let re=Ct(i),Ee=[o.toLowerCase(),re].filter(Boolean).join("|"),Te=Date.now();if(!(Te-ge<At&&(Ee===ue||re===fe))){ue=Ee,fe=re,ge=Te;try{sessionStorage.setItem(ut,Ee),sessionStorage.setItem(ft,re),sessionStorage.setItem(gt,String(Te))}catch{}try{let ot=JSON.stringify({tenant_slug:n,visitor_id:x,url:location.href,referrer:a.referrer||void 0,...i}),it=`${r}/api/widget/identify`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(it,new Blob([ot],{type:"application/json"})):fetch(it,{method:"POST",body:ot,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}}},He=e=>{if(L||!g||!x)return;let o=e.target instanceof HTMLFormElement?e.target:e.target instanceof Element?e.target.closest("form"):null;if(!(o instanceof HTMLFormElement))return;let i=(o.getAttribute("data-bp-identify")||o.getAttribute("data-bitpalm-identify")||"").toLowerCase();if(i==="off"||i==="false"||i==="0")return;let b=Ht(o);if(!b)return;let I=[o.getAttribute("id")||"",o.getAttribute("name")||"",o.getAttribute("action")||""].join("|");Pe({...b,identify_source:"form"},I)};!L&&g&&a.addEventListener("submit",He,!0);let Y=parseInt(sessionStorage.getItem(`${v}pages`)||"0")+1;sessionStorage.setItem(`${v}pages`,String(Y));let P=JSON.parse(sessionStorage.getItem(`${v}hist`)||"[]");P.push(location.href),P.length>20&&(P=P.slice(-20)),sessionStorage.setItem(`${v}hist`,JSON.stringify(P));let $e=Date.now(),oe=parseInt(sessionStorage.getItem(`${v}site_start`)||"0");oe||(oe=$e,sessionStorage.setItem(`${v}site_start`,String(oe)));let Oe=[];te=()=>{let e=!1;try{e=!!localStorage.getItem(`${v}visited`)}catch{e=!1}if(s.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:a.title,returning:e,pageCount:Y,pageHistory:P,loadedAt:$e,siteStart:oe,locale:l,visitorId:L?"":x},"*"),Je(),!e&&!L)try{localStorage.setItem(`${v}visited`,"1")}catch{}},s.addEventListener("load",()=>{ce=!0,te(),[120,450,1100].forEach(e=>{let o=setTimeout(()=>te(),e);Oe.push(o)}),V&&(V=!1,me())}),a.readyState==="loading"?a.addEventListener("DOMContentLoaded",()=>Le(X,1600),{once:!0}):Le(X,1600);let De=history.pushState.bind(history),Ne=history.replaceState.bind(history),ie=()=>{Y++,sessionStorage.setItem(`${v}pages`,String(Y));let e=JSON.parse(sessionStorage.getItem(`${v}hist`)||"[]");if(e.push(location.href),e.length>20&&e.splice(0,e.length-20),P=e,sessionStorage.setItem(`${v}hist`,JSON.stringify(e)),s.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:a.title,pageCount:Y,pageHistory:e,loadedAt:Date.now()},"*"),!L)try{let o=JSON.stringify({tenant_slug:n,visitor_id:x,url:location.href}),i=`${r}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(i,new Blob([o],{type:"application/json"})):fetch(i,{method:"POST",body:o,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...e){De(...e),ie()},history.replaceState=function(...e){Ne(...e),ie()},window.addEventListener("popstate",ie);let We=-1,pe,Re=()=>{clearTimeout(pe),pe=setTimeout(()=>{let e=Math.max(a.documentElement.scrollHeight,a.body.scrollHeight)-window.innerHeight,o=e>0?Math.round(window.scrollY/e*100):100;o!==We&&(We=o,s.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:o},"*"))},500)};window.addEventListener("scroll",Re,{passive:!0});let Fe=e=>{e.clientY<=0&&s.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};a.addEventListener("mouseout",Fe);let he,Ue=!1,ye=()=>{clearTimeout(he),!Ue&&(he=setTimeout(()=>{Ue=!0,s.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},ze=["mousemove","keydown","scroll","touchstart"];ze.forEach(e=>a.addEventListener(e,ye,{passive:!0})),ye(),me=()=>{s.contentWindow?.postMessage({type:"bitpalm-open"},"*");let e=s.src.split("#")[0];s.src=`${e}#bp-open-${Date.now()}`};let J=()=>{if(p.style.display="none",C(),Me(),X(),!ce){V=!0;return}if(A!==null){let e=A;ee(),s.contentWindow?.postMessage({type:"bitpalm-trigger-engaged",message:e},"*");return}me()},je=e=>{f=e,e==="off"&&(C(),ee()),ke()},bt=()=>je("off"),vt=()=>je(z==="off"?"bubble":z),be=()=>{D(),s.contentWindow?.postMessage({type:"bitpalm-close"},"*")},qe=e=>{!e||typeof e!="object"||Pe({external_user_id:d(e.externalUserId,140)||void 0,name:d(e.name,140)||void 0,email:ht(e.email)||void 0,phone:_(e.phone)||void 0,company:d(e.company,160)||void 0,signature:d(e.signature,260)||void 0,signed_at:Number.isFinite(Number(e.signedAt))?Math.floor(Number(e.signedAt)):void 0,signature_version:e.signatureVersion==="v1"?"v1":void 0,identify_source:"manual"},"manual")},wt=()=>{N?be():J()},Et=()=>N,Ye=e=>{if(!e||typeof e!="string")return;let o=e.trim().slice(0,1e4);o&&(N||J(),setTimeout(()=>{s.contentWindow?.postMessage({type:"bitpalm-send-message",message:o},"*")},N?50:500))};function Je(){s.contentWindow?.postMessage({type:"bitpalm-theme",theme:c},"*")}let se=e=>{e!==c&&(c=e,Je())},Ge=e=>{h=R(e),y?.(),y=null,h==="auto"?(y=Se(se),se(W())):se(h)};h==="auto"&&(y=Se(se));let Ke=e=>{let o=e.detail;if(!o||typeof o!="object")return;let i=d(o.slug,120);i&&i!==n||Ge(R(o.theme))};window.addEventListener("bitpalm-theme",Ke);let G={},Ve=e=>{if(!e||typeof e!="object"||Array.isArray(e))return;G={...G,...e};let o=JSON.stringify(G);o.length>mt&&console.warn(`[BitPalm] Custom context exceeds ${mt} bytes (${o.length}). It may be truncated.`),s.contentWindow?.postMessage({type:"bitpalm-custom-context",data:G},"*")},Tt=()=>{G={},s.contentWindow?.postMessage({type:"bitpalm-custom-context",data:{}},"*")},Xe=e=>{let i=e.detail;if(!i||typeof i!="object")return;let b=d(i.slug,120);if(b&&b!==n)return;let{slug:I,...w}=i;Ve(w)};window.addEventListener("bitpalm-context",Xe);let Ze=e=>{let i=e.detail;if(!i||typeof i!="object")return;let b=d(i.slug,120);b&&b!==n||qe(i)};window.addEventListener("bitpalm-identify",Ze);let ve=e=>{let o=e.detail,i=d(o?.slug,120);return!i||i===n},Qe=e=>{ve(e)&&J()},et=e=>{ve(e)&&be()},tt=e=>{if(!ve(e))return;let o=e.detail?.message;typeof o=="string"&&Ye(o)};return window.addEventListener("bitpalm-open",Qe),window.addEventListener("bitpalm-close",et),window.addEventListener("bitpalm-send",tt),{open:J,close:be,toggle:wt,isOpen:Et,identify:qe,context:Ve,resetContext:Tt,send:Ye,on:(e,o)=>(B.has(e)||B.set(e,new Set),B.get(e).add(o),()=>B.get(e)?.delete(o)),off:(e,o)=>{B.get(e)?.delete(o)},setTheme:Ge,disableTriggers:bt,enableTriggers:vt,destroy:()=>{window.removeEventListener("message",Be),window.removeEventListener("scroll",Re),window.removeEventListener("popstate",ie),a.removeEventListener("mouseout",Fe),a.removeEventListener("submit",He,!0),ze.forEach(e=>a.removeEventListener(e,ye)),clearTimeout(pe),clearTimeout(he),Oe.forEach(e=>clearTimeout(e)),history.pushState=De,history.replaceState=Ne,window.removeEventListener("bitpalm-identify",Ze),window.removeEventListener("bitpalm-context",Xe),window.removeEventListener("bitpalm-theme",Ke),window.removeEventListener("bitpalm-open",Qe),window.removeEventListener("bitpalm-close",et),window.removeEventListener("bitpalm-send",tt),y?.(),B.clear(),D(),C(),p.remove(),s.remove()}}}function yt(t){if(t==null)return;let n=t.trim().toLowerCase();if(["1","true","yes","on"].includes(n))return!0;if(["0","false","no","off"].includes(n))return!1}if(typeof document<"u"){let t=document.currentScript;if(t?.dataset.slug){let n=()=>{_e({slug:t.dataset.slug,locale:t.dataset.locale,baseUrl:t.dataset.baseUrl,token:t.dataset.token,zIndex:t.dataset.zIndex?Number(t.dataset.zIndex):void 0,autoIdentify:yt(t.dataset.autoIdentify),theme:R(t.dataset.theme),launcher:yt(t.dataset.launcher),triggers:t.dataset.triggers===void 0?void 0:st(ae(t.dataset.triggers))})};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",n):n()}}export{_e as createWidget,W as detectHostTheme};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/widget.ts","../src/index.ts"],"sourcesContent":["import type { BitPalmAgentOptions, BitPalmAgentInstance, BitPalmIdentifyPayload, BitPalmCustomContext, BitPalmEventType, BitPalmEventCallback } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ai\";\nconst STORAGE_PREFIX = \"_bp_\";\nconst IGNORED_INPUT_TYPES = new Set([\"password\", \"file\", \"checkbox\", \"radio\", \"submit\", \"button\", \"reset\", \"image\"]);\nconst IDENTITY_DEDUPE_WINDOW_MS = 8_000;\nconst CUSTOM_CONTEXT_MAX_BYTES = 4096;\nconst IDENTITY_SIGNATURE_KEY = `${STORAGE_PREFIX}identify_signature`;\nconst IDENTITY_FINGERPRINT_KEY = `${STORAGE_PREFIX}identify_fingerprint`;\nconst IDENTITY_SENT_AT_KEY = `${STORAGE_PREFIX}identify_sent_at`;\n\ntype FormFieldElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n\ntype IdentityPayload = {\n name?: string;\n email?: string;\n phone?: string;\n company?: string;\n};\n\ntype IdentifyRequestPayload = IdentityPayload & {\n external_user_id?: string;\n signature?: string;\n signed_at?: number;\n signature_version?: \"v1\";\n identify_source?: \"manual\" | \"form\";\n};\n\nfunction buildIdentityFingerprint(payload: IdentifyRequestPayload): string {\n return [\n payload.external_user_id || \"\",\n payload.email || \"\",\n payload.phone || \"\",\n payload.name || \"\",\n payload.company || \"\",\n payload.signature || \"\",\n payload.signed_at != null ? String(payload.signed_at) : \"\",\n payload.signature_version || \"\",\n payload.identify_source || \"\",\n ]\n .join(\"|\")\n .toLowerCase();\n}\n\nfunction normalizeText(value: string | null | undefined, maxLen = 180): string {\n if (!value) return \"\";\n return value.replace(/\\s+/g, \" \").trim().slice(0, maxLen);\n}\n\nfunction normalizeTokens(value: string | null | undefined): string {\n if (!value) return \"\";\n return ` ${value.toLowerCase().replace(/[_-]+/g, \" \").replace(/[^a-z0-9\\s@.]/g, \" \").replace(/\\s+/g, \" \").trim()} `;\n}\n\nfunction includesAny(haystack: string, needles: string[]): boolean {\n for (const needle of needles) {\n if (haystack.includes(needle)) return true;\n }\n return false;\n}\n\nfunction isEmail(value: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$/i.test(value);\n}\n\nfunction normalizePhone(value: string | null | undefined): string {\n const trimmed = normalizeText(value, 50);\n if (!trimmed) return \"\";\n const hasPlus = trimmed.startsWith(\"+\");\n const digits = trimmed.replace(/\\D/g, \"\");\n if (digits.length < 6) return \"\";\n return `${hasPlus ? \"+\" : \"\"}${digits.slice(0, 20)}`;\n}\n\nfunction normalizeEmail(value: string | null | undefined): string {\n const normalized = normalizeText(value, 140).toLowerCase();\n if (!normalized) return \"\";\n if (!isEmail(normalized)) return \"\";\n return normalized;\n}\n\nfunction getExplicitValue(form: HTMLFormElement, selectors: string[]): string {\n for (const selector of selectors) {\n const el = form.querySelector<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>(selector);\n const value = normalizeText(el?.value);\n if (value) return value;\n }\n return \"\";\n}\n\nfunction getFieldHint(el: FormFieldElement): string {\n return normalizeText(el.getAttribute(\"data-bp-field\") || el.getAttribute(\"data-bitpalm-field\"), 64)\n .toLowerCase()\n .replace(/[_\\s]+/g, \"-\");\n}\n\nfunction escapeAttrSelectorValue(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction collectElementTokenParts(form: HTMLFormElement, el: FormFieldElement): string[] {\n const parts: string[] = [];\n const pushText = (value: string | null | undefined, maxLen = 140) => {\n const clean = normalizeText(value, maxLen);\n if (clean) parts.push(clean);\n };\n\n pushText(el.name);\n pushText(el.id);\n pushText(el.getAttribute(\"autocomplete\"));\n pushText(el.getAttribute(\"placeholder\"));\n pushText(el.getAttribute(\"aria-label\"));\n pushText(el.getAttribute(\"data-field\"));\n pushText(el.getAttribute(\"data-name\"));\n pushText(el.getAttribute(\"data-label\"));\n pushText(el.getAttribute(\"data-bp-field\"));\n pushText(el.getAttribute(\"data-bitpalm-field\"));\n\n const seenLabels = new Set<string>();\n const pushLabel = (value: string | null | undefined) => {\n const label = normalizeText(value, 200);\n if (!label || seenLabels.has(label)) return;\n seenLabels.add(label);\n parts.push(label);\n };\n\n for (const label of Array.from(el.labels || [])) {\n pushLabel(label.textContent);\n }\n\n if (el.id) {\n const forLabel = form.querySelector(`label[for=\"${escapeAttrSelectorValue(el.id)}\"]`);\n pushLabel(forLabel?.textContent);\n }\n\n const nearestLabel = el.closest(\"label\");\n pushLabel(nearestLabel?.textContent);\n\n const ariaLabelledBy = el.getAttribute(\"aria-labelledby\");\n if (ariaLabelledBy) {\n for (const id of ariaLabelledBy.split(/\\s+/)) {\n if (!id) continue;\n const ref = form.ownerDocument.getElementById(id);\n pushLabel(ref?.textContent);\n }\n }\n\n return parts;\n}\n\nfunction extractIdentityFromForm(form: HTMLFormElement): IdentityPayload | null {\n let email = normalizeText(getExplicitValue(form, [\n \"[data-bp-email]\",\n \"[data-bitpalm-email]\",\n ]), 140).toLowerCase();\n\n let phone = normalizePhone(getExplicitValue(form, [\n \"[data-bp-phone]\",\n \"[data-bitpalm-phone]\",\n ]));\n\n let name = normalizeText(getExplicitValue(form, [\n \"[data-bp-name]\",\n \"[data-bitpalm-name]\",\n \"[data-bp-full-name]\",\n \"[data-bitpalm-full-name]\",\n ]));\n\n let firstName = normalizeText(getExplicitValue(form, [\n \"[data-bp-first-name]\",\n \"[data-bitpalm-first-name]\",\n ]));\n\n let lastName = normalizeText(getExplicitValue(form, [\n \"[data-bp-last-name]\",\n \"[data-bitpalm-last-name]\",\n ]));\n\n let company = normalizeText(getExplicitValue(form, [\n \"[data-bp-company]\",\n \"[data-bitpalm-company]\",\n ]));\n\n for (const rawEl of Array.from(form.elements)) {\n if (!(rawEl instanceof HTMLInputElement || rawEl instanceof HTMLTextAreaElement || rawEl instanceof HTMLSelectElement)) continue;\n if (rawEl.disabled) continue;\n if (rawEl instanceof HTMLInputElement && IGNORED_INPUT_TYPES.has(rawEl.type.toLowerCase())) continue;\n const fieldHint = getFieldHint(rawEl);\n\n const explicitField =\n rawEl.hasAttribute(\"data-bp-email\") ||\n rawEl.hasAttribute(\"data-bitpalm-email\") ||\n rawEl.hasAttribute(\"data-bp-phone\") ||\n rawEl.hasAttribute(\"data-bitpalm-phone\") ||\n rawEl.hasAttribute(\"data-bp-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-name\") ||\n rawEl.hasAttribute(\"data-bp-full-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-full-name\") ||\n rawEl.hasAttribute(\"data-bp-first-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-first-name\") ||\n rawEl.hasAttribute(\"data-bp-last-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-last-name\") ||\n rawEl.hasAttribute(\"data-bp-company\") ||\n rawEl.hasAttribute(\"data-bitpalm-company\") ||\n !!fieldHint;\n\n if (rawEl instanceof HTMLInputElement && rawEl.type.toLowerCase() === \"hidden\" && !explicitField) continue;\n\n const value = normalizeText(rawEl.value);\n if (!value) continue;\n\n const type = rawEl instanceof HTMLInputElement ? rawEl.type.toLowerCase() : \"\";\n const tokens = normalizeTokens(collectElementTokenParts(form, rawEl).join(\" \"));\n\n if (!email && fieldHint === \"email\" && isEmail(value)) {\n email = value.toLowerCase();\n continue;\n }\n if (!phone && (fieldHint === \"phone\" || fieldHint === \"tel\" || fieldHint === \"mobile\" || fieldHint === \"whatsapp\")) {\n const normalized = normalizePhone(value);\n if (normalized) {\n phone = normalized;\n continue;\n }\n }\n if (!company && fieldHint === \"company\") {\n company = normalizeText(value, 160);\n continue;\n }\n if (!firstName && (fieldHint === \"first-name\" || fieldHint === \"firstname\")) {\n firstName = normalizeText(value, 100);\n continue;\n }\n if (!lastName && (fieldHint === \"last-name\" || fieldHint === \"lastname\" || fieldHint === \"surname\")) {\n lastName = normalizeText(value, 100);\n continue;\n }\n if (!name && (fieldHint === \"name\" || fieldHint === \"full-name\" || fieldHint === \"fullname\")) {\n if (!isEmail(value) && !normalizePhone(value)) name = normalizeText(value, 140);\n continue;\n }\n\n const emailLike = type === \"email\" || includesAny(tokens, [\" email \", \" e mail \", \" mail \", \" email adresse \", \" mailadresse \", \" correo \"]);\n const phoneLike = type === \"tel\" || includesAny(tokens, [\" phone \", \" phone number \", \" mobile \", \" tel \", \" telefon \", \" telefonnummer \", \" whatsapp \", \" handy \", \" kontakt \", \" nummer \"]);\n const companyLike = includesAny(tokens, [\" company \", \" company name \", \" firma \", \" firmenname \", \" organization \", \" organisation \", \" business \", \" unternehmen \", \" agency \", \" brokerage \"]);\n const firstNameLike = includesAny(tokens, [\" first name \", \" firstname \", \" given name \", \" givenname \", \" vorname \", \" fname \"]);\n const lastNameLike = includesAny(tokens, [\" last name \", \" lastname \", \" family name \", \" familyname \", \" surname \", \" nachname \", \" lname \"]);\n const fullNameLike = includesAny(tokens, [\" full name \", \" fullname \", \" contact name \", \" name \"]) && !emailLike && !phoneLike;\n\n if (!email && emailLike && isEmail(value)) {\n email = value.toLowerCase();\n continue;\n }\n if (!phone && phoneLike) {\n const normalized = normalizePhone(value);\n if (normalized) {\n phone = normalized;\n continue;\n }\n }\n if (!company && companyLike) {\n company = normalizeText(value, 160);\n continue;\n }\n if (!firstName && firstNameLike) {\n firstName = normalizeText(value, 100);\n continue;\n }\n if (!lastName && lastNameLike) {\n lastName = normalizeText(value, 100);\n continue;\n }\n if (!name && fullNameLike && !isEmail(value) && !normalizePhone(value)) {\n name = normalizeText(value, 140);\n continue;\n }\n\n if (!email && isEmail(value)) {\n email = value.toLowerCase();\n }\n }\n\n if (name && (isEmail(name) || normalizePhone(name))) {\n name = \"\";\n }\n if (company && (isEmail(company) || normalizePhone(company))) {\n company = \"\";\n }\n\n if (!name) {\n name = normalizeText([firstName, lastName].filter(Boolean).join(\" \"), 140);\n }\n\n if (name && email && name.toLowerCase() === email.toLowerCase()) {\n name = \"\";\n }\n\n const hasContactSignal = !!(email || phone);\n const hasStrongProfileSignal = !!(name && company);\n if (!hasContactSignal && !hasStrongProfileSignal) {\n return null;\n }\n\n const identity: IdentityPayload = {\n ...(name ? { name } : {}),\n ...(email ? { email } : {}),\n ...(phone ? { phone } : {}),\n ...(company ? { company } : {}),\n };\n\n return Object.keys(identity).length > 0 ? identity : null;\n}\n\nfunction detectLocale(): string {\n if (typeof document !== \"undefined\") {\n const lang = document.documentElement.lang;\n if (lang) return lang.slice(0, 2).toLowerCase();\n }\n return \"en\";\n}\n\nfunction runWhenIdle(task: () => void, timeout = 1200) {\n if (typeof window !== \"undefined\" && \"requestIdleCallback\" in window) {\n (\n window as unknown as {\n requestIdleCallback: (cb: () => void, opts?: { timeout?: number }) => number;\n }\n ).requestIdleCallback(task, { timeout });\n return;\n }\n setTimeout(task, Math.min(timeout, 300));\n}\n\nfunction isMobileWidgetDevice(): boolean {\n if (typeof window === \"undefined\") return false;\n const userAgent = typeof navigator !== \"undefined\" ? navigator.userAgent : \"\";\n const isMobileUa = /Android|iPhone|iPad|iPod|IEMobile|Windows Phone|Mobile/i.test(userAgent);\n if (isMobileUa) return true;\n\n const coarsePointer = window.matchMedia(\"(pointer: coarse)\").matches;\n const noHover = window.matchMedia(\"(hover: none)\").matches;\n const minScreenSide = Math.min(\n window.screen?.width || window.innerWidth,\n window.screen?.height || window.innerHeight,\n );\n return coarsePointer && noHover && minScreenSide <= 900;\n}\n\nexport function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance {\n const {\n slug,\n locale = detectLocale(),\n baseUrl = DEFAULT_BASE_URL,\n token,\n zIndex = 9999,\n autoIdentify = true,\n } = options;\n\n const d = document;\n\n // --- Iframe ---\n const iframe = d.createElement(\"iframe\");\n const widgetUrl = `${baseUrl}/t/${slug}/widget`;\n const qs = new URLSearchParams({ locale });\n if (token) qs.set(\"token\", token);\n iframe.src = `${widgetUrl}?${qs.toString()}`;\n // Explicitly grant the iframe permission to use the visitor's\n // microphone — required for the voice-input feature on cross-origin\n // iframes. Without this, Chrome silently denies getUserMedia /\n // SpeechRecognition without ever prompting the user.\n iframe.allow = \"clipboard-write; microphone\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\n iframe.loading = \"lazy\";\n iframe.style.cssText = `position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${zIndex};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`;\n\n const origin = new URL(iframe.src).origin;\n\n // --- Native launcher button ---\n const btn = d.createElement(\"div\");\n btn.setAttribute(\"role\", \"button\");\n btn.setAttribute(\"aria-label\", \"Chat\");\n btn.style.cssText = `position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;display:none;align-items:center;justify-content:center;cursor:pointer;z-index:${zIndex - 1};background:#00ff41;box-shadow:0 0 15px rgba(0,255,65,0.31);transition:transform .2s,opacity .3s;opacity:0;`;\n btn.innerHTML = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"black\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\"/></svg>';\n btn.onmouseenter = () => { btn.style.transform = \"scale(1.1)\"; };\n btn.onmouseleave = () => { btn.style.transform = \"scale(1)\"; };\n btn.onclick = () => openWidget();\n d.body.appendChild(btn);\n\n // --- Fade animation for trigger bubbles ---\n if (!d.getElementById(\"_bp_fade\")) {\n const s = d.createElement(\"style\");\n s.id = \"_bp_fade\";\n s.textContent = \"@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}\";\n d.head.appendChild(s);\n }\n\n // --- Trigger bubble ---\n let bubble: HTMLDivElement | null = null;\n let launcherReady = false;\n let widgetBlocked = false;\n let iframeMounted = false;\n let iframeReady = false;\n let pendingOpen = false;\n const mountIframe = () => {\n if (iframeMounted) return;\n iframeMounted = true;\n d.body.appendChild(iframe);\n };\n let mobileScrollLocked = false;\n let scrollLockY = 0;\n const prevHtmlStyle = {\n overflow: \"\",\n overscrollBehavior: \"\",\n };\n const prevBodyStyle = {\n overflow: \"\",\n overscrollBehavior: \"\",\n position: \"\",\n top: \"\",\n left: \"\",\n right: \"\",\n width: \"\",\n };\n const lockMobilePageScroll = () => {\n if (mobileScrollLocked) return;\n const mobile = isMobileWidgetDevice();\n if (!mobile) return;\n const html = d.documentElement;\n const body = d.body;\n scrollLockY = window.scrollY || window.pageYOffset || 0;\n prevHtmlStyle.overflow = html.style.overflow;\n prevHtmlStyle.overscrollBehavior = html.style.overscrollBehavior;\n prevBodyStyle.overflow = body.style.overflow;\n prevBodyStyle.overscrollBehavior = body.style.overscrollBehavior;\n prevBodyStyle.position = body.style.position;\n prevBodyStyle.top = body.style.top;\n prevBodyStyle.left = body.style.left;\n prevBodyStyle.right = body.style.right;\n prevBodyStyle.width = body.style.width;\n html.style.overflow = \"hidden\";\n html.style.overscrollBehavior = \"none\";\n body.style.overflow = \"hidden\";\n body.style.overscrollBehavior = \"none\";\n body.style.position = \"fixed\";\n body.style.top = `-${scrollLockY}px`;\n body.style.left = \"0\";\n body.style.right = \"0\";\n body.style.width = \"100%\";\n mobileScrollLocked = true;\n };\n const unlockMobilePageScroll = () => {\n if (!mobileScrollLocked) return;\n const html = d.documentElement;\n const body = d.body;\n html.style.overflow = prevHtmlStyle.overflow;\n html.style.overscrollBehavior = prevHtmlStyle.overscrollBehavior;\n body.style.overflow = prevBodyStyle.overflow;\n body.style.overscrollBehavior = prevBodyStyle.overscrollBehavior;\n body.style.position = prevBodyStyle.position;\n body.style.top = prevBodyStyle.top;\n body.style.left = prevBodyStyle.left;\n body.style.right = prevBodyStyle.right;\n body.style.width = prevBodyStyle.width;\n window.scrollTo(0, scrollLockY);\n mobileScrollLocked = false;\n };\n const prepareIframeForOpen = () => {\n const mobile = isMobileWidgetDevice();\n if (iframe.style.display === \"none\") iframe.style.display = \"\";\n if (mobile) {\n iframe.style.width = \"100vw\";\n iframe.style.height = \"100dvh\";\n iframe.style.left = \"0\";\n iframe.style.top = \"0\";\n iframe.style.bottom = \"0\";\n iframe.style.right = \"0\";\n lockMobilePageScroll();\n } else {\n // Match desktop widget target size so the opening animation is visible from frame 1.\n iframe.style.width = \"420px\";\n iframe.style.height = \"620px\";\n iframe.style.bottom = \"24px\";\n iframe.style.right = \"24px\";\n iframe.style.left = \"\";\n iframe.style.top = \"\";\n unlockMobilePageScroll();\n }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n };\n const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\n };\n let sendParentContext = () => {};\n let sendOpenSignal = () => {};\n\n // --- Widget state & event bus ---\n let widgetIsOpen = false;\n const eventListeners = new Map<BitPalmEventType, Set<BitPalmEventCallback>>();\n\n function emit(event: BitPalmEventType, data?: Record<string, unknown>) {\n const listeners = eventListeners.get(event);\n if (!listeners) return;\n for (const cb of listeners) {\n try { cb(data); } catch { /* don't let listener errors break the widget */ }\n }\n }\n\n // --- postMessage handler ---\n const handleMessage = (e: MessageEvent) => {\n if (e.origin !== origin) return;\n\n // Widget config (colors, icon)\n if (e.data?.type === \"bitpalm-widget-config\") {\n widgetBlocked = false;\n launcherReady = true;\n if (iframe.style.display === \"none\") iframe.style.display = \"\";\n if (e.data.primaryColor) {\n btn.style.background = e.data.primaryColor;\n btn.style.boxShadow = e.data.chatShadow === \"none\" ? \"none\" : `0 0 15px ${e.data.primaryColor}50`;\n }\n const ic = e.data.chatButtonIconColor || \"black\";\n if (e.data.chatButtonIconSvg) {\n btn.innerHTML = \"\";\n const sp = d.createElement(\"span\");\n sp.style.cssText = `display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${ic}`;\n const parser = new DOMParser();\n const doc = parser.parseFromString(e.data.chatButtonIconSvg, \"image/svg+xml\");\n const svg = doc.querySelector(\"svg\");\n if (svg) {\n // Remove dangerous elements and attributes\n svg.querySelectorAll(\"script,foreignObject\").forEach(el => el.remove());\n svg.querySelectorAll(\"*\").forEach(el => {\n for (const attr of [...el.attributes]) {\n if (attr.name.startsWith(\"on\") || (attr.value && attr.value.includes(\"javascript:\"))) {\n el.removeAttribute(attr.name);\n }\n }\n });\n svg.setAttribute(\"width\", \"24\");\n svg.setAttribute(\"height\", \"24\");\n svg.style.display = \"block\";\n sp.appendChild(svg);\n } else {\n // Fallback: use default icon\n sp.innerHTML = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\"/></svg>';\n }\n btn.appendChild(sp);\n } else {\n const sv = btn.querySelector(\"svg\");\n if (sv) (sv as SVGElement).style.stroke = ic;\n }\n btn.style.display = \"flex\";\n // Fade in after styles are applied\n requestAnimationFrame(() => { btn.style.opacity = \"1\"; });\n }\n\n // Resize — use full viewport on mobile\n if (e.data?.type === \"bitpalm-widget-resize\") {\n const isOpen = e.data.width > 0;\n const wasOpen = widgetIsOpen;\n widgetIsOpen = isOpen;\n if (isOpen && !wasOpen) emit(\"widget_opened\");\n if (!isOpen && wasOpen) emit(\"widget_closed\");\n const mobile = isMobileWidgetDevice();\n if (isOpen) {\n iframe.style.width = mobile ? \"100vw\" : `${e.data.width}px`;\n iframe.style.height = mobile ? \"100dvh\" : `${e.data.height}px`;\n if (mobile) {\n iframe.style.left = \"0\";\n iframe.style.top = \"0\";\n iframe.style.bottom = \"0\";\n iframe.style.right = \"0\";\n lockMobilePageScroll();\n } else {\n unlockMobilePageScroll();\n }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\n unlockMobilePageScroll();\n iframe.style.width = \"1px\";\n iframe.style.height = \"1px\";\n iframe.style.left = \"\";\n iframe.style.top = \"\";\n iframe.style.opacity = \"0\";\n iframe.style.pointerEvents = \"none\";\n }\n btn.style.display = isOpen ? \"none\" : \"flex\";\n }\n\n // Trigger bubble show\n if (e.data?.type === \"bitpalm-trigger-show\") {\n if (widgetBlocked || !launcherReady) return;\n removeBubble();\n bubble = d.createElement(\"div\");\n bubble.style.cssText = `position:fixed;bottom:90px;right:24px;max-width:240px;background:#fff;border-radius:16px;padding:12px 32px 12px 12px;box-shadow:0 2px 20px rgba(0,0,0,0.08);cursor:pointer;z-index:${zIndex - 1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;\n const msg = (e.data.message || \"\").replace(/</g, \"<\");\n bubble.innerHTML = `<p style=\"font-size:14px;color:#1f2937;margin:0;\">${msg}</p><div style=\"position:absolute;bottom:-8px;right:20px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #fff;\"></div>`;\n const close = d.createElement(\"button\");\n close.style.cssText = \"position:absolute;top:-8px;right:-8px;width:28px;height:28px;border-radius:50%;background:#fff;border:none;box-shadow:0 1px 4px rgba(0,0,0,0.1);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;color:#9ca3af;\";\n close.innerHTML = \"✕\";\n close.onclick = (ev) => { ev.stopPropagation(); removeBubble(); iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-dismiss\" }, \"*\"); };\n bubble.onclick = () => {\n removeBubble();\n btn.style.display = \"none\";\n prepareIframeForOpen();\n mountIframe();\n if (!iframeReady) {\n pendingOpen = true;\n return;\n }\n iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\", message: msg }, \"*\");\n };\n bubble.appendChild(close);\n d.body.appendChild(bubble);\n }\n\n // Trigger bubble hide\n if (e.data?.type === \"bitpalm-trigger-hide\") { removeBubble(); }\n\n // Iframe requests latest parent context (avoids first-load race conditions)\n if (e.data?.type === \"bitpalm-request-context\") {\n sendParentContext();\n }\n\n // Chat events from iframe → emit to SDK listeners\n if (e.data?.type === \"bitpalm-chat-event\" && e.data.event) {\n emit(e.data.event as BitPalmEventType, e.data.data);\n }\n\n // Widget blocked (excluded path or access denied) — hide button & iframe\n if (e.data?.type === \"bitpalm-widget-blocked\") {\n widgetBlocked = true;\n launcherReady = false;\n btn.style.display = \"none\";\n removeBubble();\n unlockMobilePageScroll();\n iframe.style.display = \"none\";\n }\n };\n window.addEventListener(\"message\", handleMessage);\n\n // --- Privacy opt-out check ---\n let optedOut = false;\n try { optedOut = localStorage.getItem(`${STORAGE_PREFIX}optout`) === \"1\"; } catch { /* ignore */ }\n\n // --- Persistent Visitor ID (skip if opted out) ---\n const VID_KEY = `${STORAGE_PREFIX}vid`;\n let visitorId = \"\";\n if (!optedOut) {\n try { visitorId = localStorage.getItem(VID_KEY) || \"\"; } catch { /* ignore */ }\n if (!visitorId) {\n // Fallback: try reading from cookie\n const match = d.cookie.match(new RegExp(`(?:^|; )${VID_KEY}=([^;]+)`));\n visitorId = match ? decodeURIComponent(match[1]) : \"\";\n }\n if (!visitorId) {\n visitorId = crypto.randomUUID ? crypto.randomUUID() : (`${Date.now()}-${Math.random().toString(36).slice(2, 11)}`);\n }\n // Persist in both localStorage and cookie (cookie survives Safari ITP clearing localStorage)\n try { localStorage.setItem(VID_KEY, visitorId); } catch { /* ignore */ }\n try {\n const maxAge = 365 * 24 * 60 * 60; // 1 year\n d.cookie = `${VID_KEY}=${encodeURIComponent(visitorId)};path=/;max-age=${maxAge};SameSite=Lax`;\n } catch { /* ignore */ }\n }\n\n // --- Visitor beacon: track page view even without chat (skip if opted out) ---\n if (!optedOut) {\n runWhenIdle(() => {\n try {\n const utmParams = new URLSearchParams(location.search);\n const utm: Record<string, string> = {};\n for (const key of [\"utm_source\", \"utm_medium\", \"utm_campaign\", \"utm_term\", \"utm_content\"]) {\n const val = utmParams.get(key);\n if (val) utm[key] = val;\n }\n const beaconPayload = JSON.stringify({\n tenant_slug: slug,\n visitor_id: visitorId,\n url: location.href,\n referrer: d.referrer || undefined,\n ...(Object.keys(utm).length > 0 ? { utm } : {}),\n });\n const beaconUrl = `${baseUrl}/api/widget/impression`;\n if (typeof navigator.sendBeacon === \"function\") {\n navigator.sendBeacon(beaconUrl, new Blob([beaconPayload], { type: \"application/json\" }));\n } else {\n fetch(beaconUrl, { method: \"POST\", body: beaconPayload, headers: { \"Content-Type\": \"application/json\" }, keepalive: true }).catch(() => {});\n }\n } catch { /* ignore */ }\n }, 2000);\n }\n\n // --- Auto-identify visitor from form submissions on host page ---\n let lastIdentitySignature = \"\";\n let lastIdentityFingerprint = \"\";\n let lastIdentitySentAt = 0;\n try {\n lastIdentitySignature = sessionStorage.getItem(IDENTITY_SIGNATURE_KEY) || \"\";\n lastIdentityFingerprint = sessionStorage.getItem(IDENTITY_FINGERPRINT_KEY) || \"\";\n const storedAt = parseInt(sessionStorage.getItem(IDENTITY_SENT_AT_KEY) || \"0\", 10);\n if (Number.isFinite(storedAt) && storedAt > 0) {\n lastIdentitySentAt = storedAt;\n }\n } catch {\n // ignore\n }\n\n const dispatchIdentify = (payloadInput: IdentifyRequestPayload, scopeSignature = \"\") => {\n if (optedOut || !visitorId) return;\n\n const payload: IdentifyRequestPayload = {};\n const name = normalizeText(payloadInput.name, 140);\n const email = normalizeEmail(payloadInput.email);\n const phone = normalizePhone(payloadInput.phone);\n const company = normalizeText(payloadInput.company, 160);\n const externalUserId = normalizeText(payloadInput.external_user_id, 140);\n const requestSignature = normalizeText(payloadInput.signature, 260);\n const signedAtRaw = Number(payloadInput.signed_at);\n\n if (name) payload.name = name;\n if (email) payload.email = email;\n if (phone) payload.phone = phone;\n if (company) payload.company = company;\n if (externalUserId) payload.external_user_id = externalUserId;\n if (requestSignature) payload.signature = requestSignature;\n if (Number.isFinite(signedAtRaw) && signedAtRaw > 0) {\n payload.signed_at = Math.floor(signedAtRaw);\n }\n if (payloadInput.signature_version === \"v1\" || payload.signature) {\n payload.signature_version = \"v1\";\n }\n if (payloadInput.identify_source === \"manual\" || payloadInput.identify_source === \"form\") {\n payload.identify_source = payloadInput.identify_source;\n }\n\n if (!payload.name && !payload.email && !payload.phone && !payload.company && !payload.external_user_id) {\n return;\n }\n\n const identityFingerprint = buildIdentityFingerprint(payload);\n const dedupeSignature = [scopeSignature.toLowerCase(), identityFingerprint].filter(Boolean).join(\"|\");\n\n const now = Date.now();\n const insideDedupWindow = now - lastIdentitySentAt < IDENTITY_DEDUPE_WINDOW_MS;\n if (insideDedupWindow && (dedupeSignature === lastIdentitySignature || identityFingerprint === lastIdentityFingerprint)) {\n return;\n }\n\n lastIdentitySignature = dedupeSignature;\n lastIdentityFingerprint = identityFingerprint;\n lastIdentitySentAt = now;\n try {\n sessionStorage.setItem(IDENTITY_SIGNATURE_KEY, dedupeSignature);\n sessionStorage.setItem(IDENTITY_FINGERPRINT_KEY, identityFingerprint);\n sessionStorage.setItem(IDENTITY_SENT_AT_KEY, String(now));\n } catch {\n // ignore\n }\n\n try {\n const requestBody = JSON.stringify({\n tenant_slug: slug,\n visitor_id: visitorId,\n url: location.href,\n referrer: d.referrer || undefined,\n ...payload,\n });\n const identifyUrl = `${baseUrl}/api/widget/identify`;\n if (typeof navigator.sendBeacon === \"function\") {\n navigator.sendBeacon(identifyUrl, new Blob([requestBody], { type: \"application/json\" }));\n } else {\n fetch(identifyUrl, { method: \"POST\", body: requestBody, headers: { \"Content-Type\": \"application/json\" }, keepalive: true }).catch(() => {});\n }\n } catch {\n // ignore\n }\n };\n\n const handleFormSubmit = (event: Event) => {\n if (optedOut || !autoIdentify || !visitorId) return;\n\n const form = event.target instanceof HTMLFormElement\n ? event.target\n : event.target instanceof Element\n ? event.target.closest(\"form\")\n : null;\n if (!(form instanceof HTMLFormElement)) return;\n\n const formIdentifySetting = (form.getAttribute(\"data-bp-identify\") || form.getAttribute(\"data-bitpalm-identify\") || \"\").toLowerCase();\n if (formIdentifySetting === \"off\" || formIdentifySetting === \"false\" || formIdentifySetting === \"0\") return;\n\n const identity = extractIdentityFromForm(form);\n if (!identity) return;\n\n const formSignature = [\n form.getAttribute(\"id\") || \"\",\n form.getAttribute(\"name\") || \"\",\n form.getAttribute(\"action\") || \"\",\n ].join(\"|\");\n\n dispatchIdentify({ ...identity, identify_source: \"form\" }, formSignature);\n };\n\n if (!optedOut && autoIdentify) {\n d.addEventListener(\"submit\", handleFormSubmit, true);\n }\n\n // --- Visitor Intelligence: page counter + history ---\n let pageCount = parseInt(sessionStorage.getItem(`${STORAGE_PREFIX}pages`) || \"0\") + 1;\n sessionStorage.setItem(`${STORAGE_PREFIX}pages`, String(pageCount));\n\n let hist: string[] = JSON.parse(sessionStorage.getItem(`${STORAGE_PREFIX}hist`) || \"[]\");\n hist.push(location.href);\n if (hist.length > 20) hist = hist.slice(-20);\n sessionStorage.setItem(`${STORAGE_PREFIX}hist`, JSON.stringify(hist));\n\n const loadedAt = Date.now();\n let siteStart = parseInt(sessionStorage.getItem(`${STORAGE_PREFIX}site_start`) || \"0\");\n if (!siteStart) {\n siteStart = loadedAt;\n sessionStorage.setItem(`${STORAGE_PREFIX}site_start`, String(siteStart));\n }\n\n const contextRetryTimers: ReturnType<typeof setTimeout>[] = [];\n sendParentContext = () => {\n let returning = false;\n try {\n returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\n } catch {\n returning = false;\n }\n iframe.contentWindow?.postMessage({\n type: \"bitpalm-parent-context\",\n url: location.href,\n title: d.title,\n returning,\n pageCount,\n pageHistory: hist,\n loadedAt,\n siteStart,\n locale,\n visitorId: optedOut ? \"\" : visitorId,\n }, \"*\");\n if (!returning && !optedOut) {\n try { localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\"); } catch { /* ignore */ }\n }\n };\n\n // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n iframeReady = true;\n sendParentContext();\n [120, 450, 1100].forEach((delay) => {\n const timer = setTimeout(() => sendParentContext(), delay);\n contextRetryTimers.push(timer);\n });\n if (pendingOpen) {\n pendingOpen = false;\n sendOpenSignal();\n }\n });\n\n // Lazy-mount iframe after initial paint/idle to reduce impact on host load.\n if (d.readyState === \"loading\") {\n d.addEventListener(\"DOMContentLoaded\", () => runWhenIdle(mountIframe, 1600), { once: true });\n } else {\n runWhenIdle(mountIframe, 1600);\n }\n\n // --- SPA navigation detection ---\n const origPush = history.pushState.bind(history);\n const origReplace = history.replaceState.bind(history);\n\n const onNav = () => {\n pageCount++;\n sessionStorage.setItem(`${STORAGE_PREFIX}pages`, String(pageCount));\n const h: string[] = JSON.parse(sessionStorage.getItem(`${STORAGE_PREFIX}hist`) || \"[]\");\n h.push(location.href);\n if (h.length > 20) h.splice(0, h.length - 20);\n hist = h;\n sessionStorage.setItem(`${STORAGE_PREFIX}hist`, JSON.stringify(h));\n iframe.contentWindow?.postMessage({\n type: \"bitpalm-page-change\",\n url: location.href,\n title: d.title,\n pageCount,\n pageHistory: h,\n loadedAt: Date.now(),\n }, \"*\");\n // Track page view for visitor (skip if opted out)\n if (!optedOut) {\n try {\n const navPayload = JSON.stringify({ tenant_slug: slug, visitor_id: visitorId, url: location.href });\n const navUrl = `${baseUrl}/api/widget/impression`;\n if (typeof navigator.sendBeacon === \"function\") {\n navigator.sendBeacon(navUrl, new Blob([navPayload], { type: \"application/json\" }));\n } else {\n fetch(navUrl, { method: \"POST\", body: navPayload, headers: { \"Content-Type\": \"application/json\" }, keepalive: true }).catch(() => {});\n }\n } catch { /* ignore */ }\n }\n };\n\n history.pushState = function (...args: Parameters<typeof history.pushState>) {\n origPush(...args);\n onNav();\n };\n history.replaceState = function (...args: Parameters<typeof history.replaceState>) {\n origReplace(...args);\n onNav();\n };\n window.addEventListener(\"popstate\", onNav);\n\n // --- Scroll depth tracking ---\n let lastScrollDepth = -1;\n let scrollTimeout: ReturnType<typeof setTimeout>;\n const handleScroll = () => {\n clearTimeout(scrollTimeout);\n scrollTimeout = setTimeout(() => {\n const total = Math.max(d.documentElement.scrollHeight, d.body.scrollHeight) - window.innerHeight;\n const pct = total > 0 ? Math.round(window.scrollY / total * 100) : 100;\n if (pct !== lastScrollDepth) {\n lastScrollDepth = pct;\n iframe.contentWindow?.postMessage({ type: \"bitpalm-scroll-depth\", percent: pct }, \"*\");\n }\n }, 500);\n };\n window.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n // --- Exit intent ---\n const handleMouseOut = (e: MouseEvent) => {\n if (e.clientY <= 0) {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-exit-intent\" }, \"*\");\n }\n };\n d.addEventListener(\"mouseout\", handleMouseOut);\n\n // --- Inactivity detection (15s) ---\n let idleTimer: ReturnType<typeof setTimeout>;\n let idleFired = false;\n const resetIdle = () => {\n clearTimeout(idleTimer);\n if (idleFired) return;\n idleTimer = setTimeout(() => {\n idleFired = true;\n iframe.contentWindow?.postMessage({ type: \"bitpalm-inactivity\" }, \"*\");\n }, 15_000);\n };\n const idleEvents = [\"mousemove\", \"keydown\", \"scroll\", \"touchstart\"] as const;\n idleEvents.forEach((ev) => d.addEventListener(ev, resetIdle, { passive: true }));\n resetIdle();\n\n sendOpenSignal = () => {\n // Primary: postMessage\n iframe.contentWindow?.postMessage({ type: \"bitpalm-open\" }, \"*\");\n // Fallback for mobile: trigger hashchange inside iframe (no reload)\n const base = iframe.src.split(\"#\")[0];\n iframe.src = `${base}#bp-open-${Date.now()}`;\n };\n\n // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\n prepareIframeForOpen();\n mountIframe();\n if (!iframeReady) {\n pendingOpen = true;\n return;\n }\n sendOpenSignal();\n };\n\n const closeWidget = () => {\n unlockMobilePageScroll();\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\n };\n\n const identify = (input: BitPalmIdentifyPayload) => {\n if (!input || typeof input !== \"object\") return;\n dispatchIdentify({\n external_user_id: normalizeText(input.externalUserId, 140) || undefined,\n name: normalizeText(input.name, 140) || undefined,\n email: normalizeEmail(input.email) || undefined,\n phone: normalizePhone(input.phone) || undefined,\n company: normalizeText(input.company, 160) || undefined,\n signature: normalizeText(input.signature, 260) || undefined,\n signed_at: Number.isFinite(Number(input.signedAt)) ? Math.floor(Number(input.signedAt)) : undefined,\n signature_version: input.signatureVersion === \"v1\" ? \"v1\" : undefined,\n identify_source: \"manual\",\n }, \"manual\");\n };\n\n const toggleWidget = () => {\n if (widgetIsOpen) closeWidget();\n else openWidget();\n };\n\n const getIsOpen = () => widgetIsOpen;\n\n const sendMessage = (message: string) => {\n if (!message || typeof message !== \"string\") return;\n const text = message.trim().slice(0, 10_000);\n if (!text) return;\n if (!widgetIsOpen) openWidget();\n // Small delay to ensure widget is open before sending\n setTimeout(() => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-send-message\", message: text }, \"*\");\n }, widgetIsOpen ? 50 : 500);\n };\n\n // --- Custom context for AI ---\n let customContext: Record<string, unknown> = {};\n\n const setCustomContext = (data: BitPalmCustomContext) => {\n if (!data || typeof data !== \"object\" || Array.isArray(data)) return;\n customContext = { ...customContext, ...data };\n const json = JSON.stringify(customContext);\n if (json.length > CUSTOM_CONTEXT_MAX_BYTES) {\n console.warn(\n `[BitPalm] Custom context exceeds ${CUSTOM_CONTEXT_MAX_BYTES} bytes (${json.length}). It may be truncated.`\n );\n }\n iframe.contentWindow?.postMessage({ type: \"bitpalm-custom-context\", data: customContext }, \"*\");\n };\n\n const clearCustomContext = () => {\n customContext = {};\n iframe.contentWindow?.postMessage({ type: \"bitpalm-custom-context\", data: {} }, \"*\");\n };\n\n const handleContextEvent = (event: Event) => {\n const customEvent = event as CustomEvent<BitPalmCustomContext & { slug?: string }>;\n const detail = customEvent.detail;\n if (!detail || typeof detail !== \"object\") return;\n const targetSlug = normalizeText((detail as Record<string, unknown>).slug as string, 120);\n if (targetSlug && targetSlug !== slug) return;\n const { slug: _s, ...contextData } = detail as Record<string, unknown>;\n setCustomContext(contextData);\n };\n\n window.addEventListener(\"bitpalm-context\", handleContextEvent as EventListener);\n\n const handleIdentifyEvent = (event: Event) => {\n const customEvent = event as CustomEvent<BitPalmIdentifyPayload & { slug?: string }>;\n const detail = customEvent.detail;\n if (!detail || typeof detail !== \"object\") return;\n const targetSlug = normalizeText(detail.slug, 120);\n if (targetSlug && targetSlug !== slug) return;\n identify(detail);\n };\n\n window.addEventListener(\"bitpalm-identify\", handleIdentifyEvent as EventListener);\n\n const onEvent = (event: BitPalmEventType, callback: BitPalmEventCallback): (() => void) => {\n if (!eventListeners.has(event)) eventListeners.set(event, new Set());\n eventListeners.get(event)!.add(callback);\n return () => eventListeners.get(event)?.delete(callback);\n };\n\n const offEvent = (event: BitPalmEventType, callback: BitPalmEventCallback) => {\n eventListeners.get(event)?.delete(callback);\n };\n\n const destroy = () => {\n window.removeEventListener(\"message\", handleMessage);\n window.removeEventListener(\"scroll\", handleScroll);\n window.removeEventListener(\"popstate\", onNav);\n d.removeEventListener(\"mouseout\", handleMouseOut);\n d.removeEventListener(\"submit\", handleFormSubmit, true);\n idleEvents.forEach((ev) => d.removeEventListener(ev, resetIdle));\n clearTimeout(scrollTimeout);\n clearTimeout(idleTimer);\n contextRetryTimers.forEach((t) => clearTimeout(t));\n history.pushState = origPush;\n history.replaceState = origReplace;\n window.removeEventListener(\"bitpalm-identify\", handleIdentifyEvent as EventListener);\n window.removeEventListener(\"bitpalm-context\", handleContextEvent as EventListener);\n eventListeners.clear();\n unlockMobilePageScroll();\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return {\n open: openWidget,\n close: closeWidget,\n toggle: toggleWidget,\n isOpen: getIsOpen,\n identify,\n context: setCustomContext,\n resetContext: clearCustomContext,\n send: sendMessage,\n on: onEvent,\n off: offEvent,\n destroy,\n };\n}\n","export { createWidget } from \"./widget\";\nexport type { BitPalmAgentOptions, BitPalmAgentInstance, BitPalmIdentifyPayload, BitPalmCustomContext, BitPalmEventType, BitPalmEventCallback } from \"./types\";\n\nimport { createWidget } from \"./widget\";\n\nfunction parseBoolean(value: string | undefined): boolean | undefined {\n if (value == null) return undefined;\n const normalized = value.trim().toLowerCase();\n if ([\"1\", \"true\", \"yes\", \"on\"].includes(normalized)) return true;\n if ([\"0\", \"false\", \"no\", \"off\"].includes(normalized)) return false;\n return undefined;\n}\n\n/**\n * Auto-init from script tag:\n * <script src=\"https://cdn.bitpalm.ai/widget.js\" data-slug=\"my-agent\"></script>\n */\nif (typeof document !== \"undefined\") {\n const script = document.currentScript as HTMLScriptElement | null;\n if (script?.dataset.slug) {\n const init = () => {\n createWidget({\n slug: script!.dataset.slug!,\n locale: script!.dataset.locale,\n baseUrl: script!.dataset.baseUrl,\n token: script!.dataset.token,\n zIndex: script!.dataset.zIndex ? Number(script!.dataset.zIndex) : undefined,\n autoIdentify: parseBoolean(script!.dataset.autoIdentify),\n });\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init);\n } else {\n init();\n }\n }\n}\n"],"mappings":"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","names":["DEFAULT_BASE_URL","STORAGE_PREFIX","IGNORED_INPUT_TYPES","IDENTITY_DEDUPE_WINDOW_MS","CUSTOM_CONTEXT_MAX_BYTES","IDENTITY_SIGNATURE_KEY","IDENTITY_FINGERPRINT_KEY","IDENTITY_SENT_AT_KEY","buildIdentityFingerprint","payload","normalizeText","value","maxLen","normalizeTokens","includesAny","haystack","needles","needle","isEmail","normalizePhone","trimmed","hasPlus","digits","normalizeEmail","normalized","getExplicitValue","form","selectors","selector","el","getFieldHint","escapeAttrSelectorValue","collectElementTokenParts","parts","pushText","clean","seenLabels","pushLabel","label","forLabel","nearestLabel","ariaLabelledBy","id","ref","extractIdentityFromForm","email","phone","name","firstName","lastName","company","rawEl","fieldHint","explicitField","type","tokens","emailLike","phoneLike","companyLike","firstNameLike","lastNameLike","fullNameLike","identity","detectLocale","lang","runWhenIdle","task","timeout","isMobileWidgetDevice","userAgent","coarsePointer","noHover","minScreenSide","createWidget","options","slug","locale","baseUrl","token","zIndex","autoIdentify","d","iframe","widgetUrl","qs","origin","btn","openWidget","s","bubble","launcherReady","widgetBlocked","iframeMounted","iframeReady","pendingOpen","mountIframe","mobileScrollLocked","scrollLockY","prevHtmlStyle","prevBodyStyle","lockMobilePageScroll","html","body","unlockMobilePageScroll","prepareIframeForOpen","mobile","removeBubble","sendParentContext","sendOpenSignal","widgetIsOpen","eventListeners","emit","event","data","listeners","cb","handleMessage","ic","sp","svg","attr","sv","isOpen","wasOpen","msg","close","ev","optedOut","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","lastIdentitySignature","lastIdentityFingerprint","lastIdentitySentAt","storedAt","dispatchIdentify","payloadInput","scopeSignature","externalUserId","requestSignature","signedAtRaw","identityFingerprint","dedupeSignature","now","requestBody","identifyUrl","handleFormSubmit","formIdentifySetting","formSignature","pageCount","hist","loadedAt","siteStart","contextRetryTimers","returning","delay","timer","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","base","closeWidget","identify","input","toggleWidget","getIsOpen","sendMessage","message","text","customContext","setCustomContext","json","clearCustomContext","handleContextEvent","detail","targetSlug","_s","contextData","handleIdentifyEvent","callback","t","parseBoolean","value","normalized","script","init","createWidget"]}
|
|
1
|
+
{"version":3,"sources":["../src/triggers.ts","../src/theme.ts","../src/widget.ts","../src/index.ts"],"sourcesContent":["/*\n * Trigger messages: the bubble that shows up by itself on the website.\n * Sites with a chat button of their own can take the message as an event\n * instead and show it their way, or switch triggers off.\n */\n\n/** \"bubble\" shows our bubble, \"events\" only fires trigger_shown, \"off\" stops triggers. */\nexport type TriggerMode = \"bubble\" | \"events\" | \"off\";\n\n/** Reads the triggers option, from the SDK or from the script tag's data-triggers. */\nexport function parseTriggerMode(value: unknown): TriggerMode {\n if (value === false) return \"off\";\n if (typeof value === \"string\") {\n const normalized = value.trim().toLowerCase();\n if ([\"false\", \"off\", \"0\", \"no\", \"none\"].includes(normalized)) return \"off\";\n if (normalized === \"events\") return \"events\";\n }\n return \"bubble\";\n}\n\n/** The option value for a mode, the way BitPalmAgentOptions takes it. */\nexport function triggersOption(mode: TriggerMode): boolean | \"events\" {\n return mode === \"off\" ? false : mode === \"events\" ? \"events\" : true;\n}\n\nexport interface TriggerBubbleOptions {\n message: string;\n zIndex: number;\n /** Distance from the bottom edge: above the launcher, or lower without one. */\n bottom: number;\n onEngage: () => void;\n onDismiss: () => void;\n}\n\n/** The bubble on the website. The message goes in as text, never as HTML. */\nexport function createTriggerBubble(d: Document, options: TriggerBubbleOptions): HTMLDivElement {\n const bubble = d.createElement(\"div\");\n bubble.setAttribute(\"data-bitpalm-trigger\", \"\");\n bubble.style.cssText = `max-width:240px;background:#fff;border-radius:16px;padding:12px 32px 12px 12px;box-shadow:0 2px 20px rgba(0,0,0,0.08);cursor:pointer;z-index:${options.zIndex - 1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;\n bubble.style.position = \"fixed\";\n bubble.style.right = \"24px\";\n bubble.style.bottom = `${options.bottom}px`;\n\n const text = d.createElement(\"p\");\n text.style.cssText = \"font-size:14px;color:#1f2937;margin:0;\";\n text.textContent = options.message;\n\n const arrow = d.createElement(\"div\");\n arrow.style.cssText = \"position:absolute;bottom:-8px;right:20px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #fff;\";\n\n const close = d.createElement(\"button\");\n close.type = \"button\";\n close.setAttribute(\"aria-label\", \"Close\");\n close.style.cssText = \"position:absolute;top:-8px;right:-8px;width:28px;height:28px;border-radius:50%;background:#fff;border:none;box-shadow:0 1px 4px rgba(0,0,0,0.1);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;color:#9ca3af;\";\n close.textContent = \"✕\";\n close.onclick = (event) => {\n event.stopPropagation();\n options.onDismiss();\n };\n\n bubble.onclick = () => options.onEngage();\n bubble.append(text, arrow, close);\n return bubble;\n}\n","import type { BitPalmTheme } from \"./types\";\n\nexport type HostTheme = \"light\" | \"dark\";\n\nconst DARK_CLASSES = [\"dark\", \"dark-mode\", \"dark-theme\", \"theme-dark\"];\nconst LIGHT_CLASSES = [\"light\", \"light-mode\", \"light-theme\", \"theme-light\"];\nconst THEME_ATTRIBUTES = [\"data-theme\", \"data-color-scheme\", \"data-color-mode\", \"data-mode\", \"data-bs-theme\"];\nconst DARK_QUERY = \"(prefers-color-scheme: dark)\";\n\nexport function normalizeThemeSetting(value: unknown): BitPalmTheme {\n return value === \"light\" || value === \"dark\" ? value : \"auto\";\n}\n\n/** Theme set explicitly on an element: a class like \"dark\" or an attribute like data-theme=\"dark\". */\nfunction explicitTheme(el: Element | null): HostTheme | null {\n if (!el) return null;\n if (DARK_CLASSES.some((name) => el.classList.contains(name))) return \"dark\";\n if (LIGHT_CLASSES.some((name) => el.classList.contains(name))) return \"light\";\n for (const attr of THEME_ATTRIBUTES) {\n const value = (el.getAttribute(attr) || \"\").toLowerCase();\n if (value.includes(\"dark\")) return \"dark\";\n if (value.includes(\"light\")) return \"light\";\n }\n return null;\n}\n\nfunction channel(value: number): number {\n const s = value / 255;\n return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n}\n\n/** Dark or light from an element's own opaque background color. */\nfunction backgroundTheme(el: Element | null, win: Window): HostTheme | null {\n if (!el) return null;\n const match = win.getComputedStyle(el).backgroundColor.match(/rgba?\\(([^)]+)\\)/);\n if (!match) return null;\n const [r, g, b, a = 1] = match[1].split(/[\\s,/]+/).filter(Boolean).map(Number);\n if ([r, g, b, a].some((n) => Number.isNaN(n)) || a < 0.5) return null;\n const luminance = 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b);\n return luminance < 0.2 ? \"dark\" : \"light\";\n}\n\n/** The site declares color-scheme: only dark, or both and the visitor's system decides. */\nfunction colorSchemeTheme(doc: Document, win: Window): HostTheme | null {\n const computed = win.getComputedStyle(doc.documentElement).colorScheme || \"\";\n const meta = doc.querySelector('meta[name=\"color-scheme\"]')?.getAttribute(\"content\") || \"\";\n const scheme = `${computed} ${meta}`.toLowerCase();\n if (!scheme.includes(\"dark\")) return null;\n if (!scheme.includes(\"light\")) return \"dark\";\n return win.matchMedia?.(DARK_QUERY).matches ? \"dark\" : \"light\";\n}\n\n/**\n * Best guess of the host page's current theme, most explicit signal first:\n * theme classes and attributes on <html> or <body>, then the page background,\n * then a declared color-scheme. Pages without any of these count as light, so\n * a light-only site never gets a dark widget just because the visitor's\n * system is dark.\n */\nexport function detectHostTheme(doc: Document = document, win: Window = window): HostTheme {\n return (\n explicitTheme(doc.documentElement) ??\n explicitTheme(doc.body) ??\n backgroundTheme(doc.body, win) ??\n backgroundTheme(doc.documentElement, win) ??\n colorSchemeTheme(doc, win) ??\n \"light\"\n );\n}\n\n/**\n * Calls onChange when the detected theme changes: class or attribute changes\n * on <html> and <body>, and system theme changes. Returns a stop function.\n */\nexport function watchHostTheme(\n onChange: (theme: HostTheme) => void,\n doc: Document = document,\n win: Window = window,\n): () => void {\n let last = detectHostTheme(doc, win);\n let scheduled = false;\n\n const check = () => {\n scheduled = false;\n const next = detectHostTheme(doc, win);\n if (next === last) return;\n last = next;\n onChange(next);\n };\n // Theme switches often touch several attributes at once, check once per frame.\n const schedule = () => {\n if (scheduled) return;\n scheduled = true;\n if (typeof win.requestAnimationFrame === \"function\") win.requestAnimationFrame(check);\n else setTimeout(check, 16);\n };\n\n const observer = typeof MutationObserver !== \"undefined\" ? new MutationObserver(schedule) : null;\n const observed = { attributes: true, attributeFilter: [\"class\", \"style\", ...THEME_ATTRIBUTES] };\n observer?.observe(doc.documentElement, observed);\n if (doc.body) observer?.observe(doc.body, observed);\n\n const media = typeof win.matchMedia === \"function\" ? win.matchMedia(DARK_QUERY) : null;\n media?.addEventListener?.(\"change\", schedule);\n\n return () => {\n observer?.disconnect();\n media?.removeEventListener?.(\"change\", schedule);\n };\n}\n","import type { BitPalmAgentOptions, BitPalmAgentInstance, BitPalmIdentifyPayload, BitPalmCustomContext, BitPalmEventType, BitPalmEventCallback, BitPalmTheme } from \"./types\";\nimport { createTriggerBubble, parseTriggerMode, type TriggerMode } from \"./triggers\";\nimport { detectHostTheme, normalizeThemeSetting, watchHostTheme, type HostTheme } from \"./theme\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ai\";\nconst STORAGE_PREFIX = \"_bp_\";\nconst IGNORED_INPUT_TYPES = new Set([\"password\", \"file\", \"checkbox\", \"radio\", \"submit\", \"button\", \"reset\", \"image\"]);\nconst IDENTITY_DEDUPE_WINDOW_MS = 8_000;\nconst CUSTOM_CONTEXT_MAX_BYTES = 4096;\nconst IDENTITY_SIGNATURE_KEY = `${STORAGE_PREFIX}identify_signature`;\nconst IDENTITY_FINGERPRINT_KEY = `${STORAGE_PREFIX}identify_fingerprint`;\nconst IDENTITY_SENT_AT_KEY = `${STORAGE_PREFIX}identify_sent_at`;\nconst LAUNCHER_SHADOW = \"0 4px 14px rgba(0,0,0,0.18)\";\n\ntype FormFieldElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n\ntype IdentityPayload = {\n name?: string;\n email?: string;\n phone?: string;\n company?: string;\n};\n\ntype IdentifyRequestPayload = IdentityPayload & {\n external_user_id?: string;\n signature?: string;\n signed_at?: number;\n signature_version?: \"v1\";\n identify_source?: \"manual\" | \"form\";\n};\n\nfunction buildIdentityFingerprint(payload: IdentifyRequestPayload): string {\n return [\n payload.external_user_id || \"\",\n payload.email || \"\",\n payload.phone || \"\",\n payload.name || \"\",\n payload.company || \"\",\n payload.signature || \"\",\n payload.signed_at != null ? String(payload.signed_at) : \"\",\n payload.signature_version || \"\",\n payload.identify_source || \"\",\n ]\n .join(\"|\")\n .toLowerCase();\n}\n\nfunction normalizeText(value: string | null | undefined, maxLen = 180): string {\n if (!value) return \"\";\n return value.replace(/\\s+/g, \" \").trim().slice(0, maxLen);\n}\n\nfunction normalizeTokens(value: string | null | undefined): string {\n if (!value) return \"\";\n return ` ${value.toLowerCase().replace(/[_-]+/g, \" \").replace(/[^a-z0-9\\s@.]/g, \" \").replace(/\\s+/g, \" \").trim()} `;\n}\n\nfunction includesAny(haystack: string, needles: string[]): boolean {\n for (const needle of needles) {\n if (haystack.includes(needle)) return true;\n }\n return false;\n}\n\nfunction isEmail(value: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$/i.test(value);\n}\n\nfunction normalizePhone(value: string | null | undefined): string {\n const trimmed = normalizeText(value, 50);\n if (!trimmed) return \"\";\n const hasPlus = trimmed.startsWith(\"+\");\n const digits = trimmed.replace(/\\D/g, \"\");\n if (digits.length < 6) return \"\";\n return `${hasPlus ? \"+\" : \"\"}${digits.slice(0, 20)}`;\n}\n\nfunction normalizeEmail(value: string | null | undefined): string {\n const normalized = normalizeText(value, 140).toLowerCase();\n if (!normalized) return \"\";\n if (!isEmail(normalized)) return \"\";\n return normalized;\n}\n\nfunction getExplicitValue(form: HTMLFormElement, selectors: string[]): string {\n for (const selector of selectors) {\n const el = form.querySelector<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>(selector);\n const value = normalizeText(el?.value);\n if (value) return value;\n }\n return \"\";\n}\n\nfunction getFieldHint(el: FormFieldElement): string {\n return normalizeText(el.getAttribute(\"data-bp-field\") || el.getAttribute(\"data-bitpalm-field\"), 64)\n .toLowerCase()\n .replace(/[_\\s]+/g, \"-\");\n}\n\nfunction escapeAttrSelectorValue(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction collectElementTokenParts(form: HTMLFormElement, el: FormFieldElement): string[] {\n const parts: string[] = [];\n const pushText = (value: string | null | undefined, maxLen = 140) => {\n const clean = normalizeText(value, maxLen);\n if (clean) parts.push(clean);\n };\n\n pushText(el.name);\n pushText(el.id);\n pushText(el.getAttribute(\"autocomplete\"));\n pushText(el.getAttribute(\"placeholder\"));\n pushText(el.getAttribute(\"aria-label\"));\n pushText(el.getAttribute(\"data-field\"));\n pushText(el.getAttribute(\"data-name\"));\n pushText(el.getAttribute(\"data-label\"));\n pushText(el.getAttribute(\"data-bp-field\"));\n pushText(el.getAttribute(\"data-bitpalm-field\"));\n\n const seenLabels = new Set<string>();\n const pushLabel = (value: string | null | undefined) => {\n const label = normalizeText(value, 200);\n if (!label || seenLabels.has(label)) return;\n seenLabels.add(label);\n parts.push(label);\n };\n\n for (const label of Array.from(el.labels || [])) {\n pushLabel(label.textContent);\n }\n\n if (el.id) {\n const forLabel = form.querySelector(`label[for=\"${escapeAttrSelectorValue(el.id)}\"]`);\n pushLabel(forLabel?.textContent);\n }\n\n const nearestLabel = el.closest(\"label\");\n pushLabel(nearestLabel?.textContent);\n\n const ariaLabelledBy = el.getAttribute(\"aria-labelledby\");\n if (ariaLabelledBy) {\n for (const id of ariaLabelledBy.split(/\\s+/)) {\n if (!id) continue;\n const ref = form.ownerDocument.getElementById(id);\n pushLabel(ref?.textContent);\n }\n }\n\n return parts;\n}\n\nfunction extractIdentityFromForm(form: HTMLFormElement): IdentityPayload | null {\n let email = normalizeText(getExplicitValue(form, [\n \"[data-bp-email]\",\n \"[data-bitpalm-email]\",\n ]), 140).toLowerCase();\n\n let phone = normalizePhone(getExplicitValue(form, [\n \"[data-bp-phone]\",\n \"[data-bitpalm-phone]\",\n ]));\n\n let name = normalizeText(getExplicitValue(form, [\n \"[data-bp-name]\",\n \"[data-bitpalm-name]\",\n \"[data-bp-full-name]\",\n \"[data-bitpalm-full-name]\",\n ]));\n\n let firstName = normalizeText(getExplicitValue(form, [\n \"[data-bp-first-name]\",\n \"[data-bitpalm-first-name]\",\n ]));\n\n let lastName = normalizeText(getExplicitValue(form, [\n \"[data-bp-last-name]\",\n \"[data-bitpalm-last-name]\",\n ]));\n\n let company = normalizeText(getExplicitValue(form, [\n \"[data-bp-company]\",\n \"[data-bitpalm-company]\",\n ]));\n\n for (const rawEl of Array.from(form.elements)) {\n if (!(rawEl instanceof HTMLInputElement || rawEl instanceof HTMLTextAreaElement || rawEl instanceof HTMLSelectElement)) continue;\n if (rawEl.disabled) continue;\n if (rawEl instanceof HTMLInputElement && IGNORED_INPUT_TYPES.has(rawEl.type.toLowerCase())) continue;\n const fieldHint = getFieldHint(rawEl);\n\n const explicitField =\n rawEl.hasAttribute(\"data-bp-email\") ||\n rawEl.hasAttribute(\"data-bitpalm-email\") ||\n rawEl.hasAttribute(\"data-bp-phone\") ||\n rawEl.hasAttribute(\"data-bitpalm-phone\") ||\n rawEl.hasAttribute(\"data-bp-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-name\") ||\n rawEl.hasAttribute(\"data-bp-full-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-full-name\") ||\n rawEl.hasAttribute(\"data-bp-first-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-first-name\") ||\n rawEl.hasAttribute(\"data-bp-last-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-last-name\") ||\n rawEl.hasAttribute(\"data-bp-company\") ||\n rawEl.hasAttribute(\"data-bitpalm-company\") ||\n !!fieldHint;\n\n if (rawEl instanceof HTMLInputElement && rawEl.type.toLowerCase() === \"hidden\" && !explicitField) continue;\n\n const value = normalizeText(rawEl.value);\n if (!value) continue;\n\n const type = rawEl instanceof HTMLInputElement ? rawEl.type.toLowerCase() : \"\";\n const tokens = normalizeTokens(collectElementTokenParts(form, rawEl).join(\" \"));\n\n if (!email && fieldHint === \"email\" && isEmail(value)) {\n email = value.toLowerCase();\n continue;\n }\n if (!phone && (fieldHint === \"phone\" || fieldHint === \"tel\" || fieldHint === \"mobile\" || fieldHint === \"whatsapp\")) {\n const normalized = normalizePhone(value);\n if (normalized) {\n phone = normalized;\n continue;\n }\n }\n if (!company && fieldHint === \"company\") {\n company = normalizeText(value, 160);\n continue;\n }\n if (!firstName && (fieldHint === \"first-name\" || fieldHint === \"firstname\")) {\n firstName = normalizeText(value, 100);\n continue;\n }\n if (!lastName && (fieldHint === \"last-name\" || fieldHint === \"lastname\" || fieldHint === \"surname\")) {\n lastName = normalizeText(value, 100);\n continue;\n }\n if (!name && (fieldHint === \"name\" || fieldHint === \"full-name\" || fieldHint === \"fullname\")) {\n if (!isEmail(value) && !normalizePhone(value)) name = normalizeText(value, 140);\n continue;\n }\n\n const emailLike = type === \"email\" || includesAny(tokens, [\" email \", \" e mail \", \" mail \", \" email adresse \", \" mailadresse \", \" correo \"]);\n const phoneLike = type === \"tel\" || includesAny(tokens, [\" phone \", \" phone number \", \" mobile \", \" tel \", \" telefon \", \" telefonnummer \", \" whatsapp \", \" handy \", \" kontakt \", \" nummer \"]);\n const companyLike = includesAny(tokens, [\" company \", \" company name \", \" firma \", \" firmenname \", \" organization \", \" organisation \", \" business \", \" unternehmen \", \" agency \", \" brokerage \"]);\n const firstNameLike = includesAny(tokens, [\" first name \", \" firstname \", \" given name \", \" givenname \", \" vorname \", \" fname \"]);\n const lastNameLike = includesAny(tokens, [\" last name \", \" lastname \", \" family name \", \" familyname \", \" surname \", \" nachname \", \" lname \"]);\n const fullNameLike = includesAny(tokens, [\" full name \", \" fullname \", \" contact name \", \" name \"]) && !emailLike && !phoneLike;\n\n if (!email && emailLike && isEmail(value)) {\n email = value.toLowerCase();\n continue;\n }\n if (!phone && phoneLike) {\n const normalized = normalizePhone(value);\n if (normalized) {\n phone = normalized;\n continue;\n }\n }\n if (!company && companyLike) {\n company = normalizeText(value, 160);\n continue;\n }\n if (!firstName && firstNameLike) {\n firstName = normalizeText(value, 100);\n continue;\n }\n if (!lastName && lastNameLike) {\n lastName = normalizeText(value, 100);\n continue;\n }\n if (!name && fullNameLike && !isEmail(value) && !normalizePhone(value)) {\n name = normalizeText(value, 140);\n continue;\n }\n\n if (!email && isEmail(value)) {\n email = value.toLowerCase();\n }\n }\n\n if (name && (isEmail(name) || normalizePhone(name))) {\n name = \"\";\n }\n if (company && (isEmail(company) || normalizePhone(company))) {\n company = \"\";\n }\n\n if (!name) {\n name = normalizeText([firstName, lastName].filter(Boolean).join(\" \"), 140);\n }\n\n if (name && email && name.toLowerCase() === email.toLowerCase()) {\n name = \"\";\n }\n\n const hasContactSignal = !!(email || phone);\n const hasStrongProfileSignal = !!(name && company);\n if (!hasContactSignal && !hasStrongProfileSignal) {\n return null;\n }\n\n const identity: IdentityPayload = {\n ...(name ? { name } : {}),\n ...(email ? { email } : {}),\n ...(phone ? { phone } : {}),\n ...(company ? { company } : {}),\n };\n\n return Object.keys(identity).length > 0 ? identity : null;\n}\n\nfunction detectLocale(): string {\n if (typeof document !== \"undefined\") {\n const lang = document.documentElement.lang;\n if (lang) return lang.slice(0, 2).toLowerCase();\n }\n return \"en\";\n}\n\nfunction runWhenIdle(task: () => void, timeout = 1200) {\n if (typeof window !== \"undefined\" && \"requestIdleCallback\" in window) {\n (\n window as unknown as {\n requestIdleCallback: (cb: () => void, opts?: { timeout?: number }) => number;\n }\n ).requestIdleCallback(task, { timeout });\n return;\n }\n setTimeout(task, Math.min(timeout, 300));\n}\n\nfunction isMobileWidgetDevice(): boolean {\n if (typeof window === \"undefined\") return false;\n const userAgent = typeof navigator !== \"undefined\" ? navigator.userAgent : \"\";\n const isMobileUa = /Android|iPhone|iPad|iPod|IEMobile|Windows Phone|Mobile/i.test(userAgent);\n if (isMobileUa) return true;\n\n const coarsePointer = window.matchMedia(\"(pointer: coarse)\").matches;\n const noHover = window.matchMedia(\"(hover: none)\").matches;\n const minScreenSide = Math.min(\n window.screen?.width || window.innerWidth,\n window.screen?.height || window.innerHeight,\n );\n return coarsePointer && noHover && minScreenSide <= 900;\n}\n\nexport function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance {\n const {\n slug,\n locale = detectLocale(),\n baseUrl = DEFAULT_BASE_URL,\n token,\n zIndex = 9999,\n autoIdentify = true,\n launcher = true,\n } = options;\n\n const d = document;\n\n // --- Theme ---\n let themeSetting: BitPalmTheme = normalizeThemeSetting(options.theme);\n let currentTheme: HostTheme = themeSetting === \"auto\" ? detectHostTheme() : themeSetting;\n let stopThemeWatch: (() => void) | null = null;\n\n // --- Triggers ---\n const configuredTriggerMode = parseTriggerMode(options.triggers);\n let triggerMode: TriggerMode = configuredTriggerMode;\n /** With triggers: \"events\", the message waiting for the next open(). */\n let pendingTrigger: string | null = null;\n\n // --- Iframe ---\n const iframe = d.createElement(\"iframe\");\n iframe.setAttribute(\"data-bitpalm-chat\", \"\");\n const widgetUrl = `${baseUrl}/t/${slug}/widget`;\n const qs = new URLSearchParams({ locale, theme: currentTheme });\n if (token) qs.set(\"token\", token);\n if (triggerMode === \"off\") qs.set(\"triggers\", \"off\");\n iframe.src = `${widgetUrl}?${qs.toString()}`;\n // Explicitly grant the iframe permission to use the visitor's\n // microphone — required for the voice-input feature on cross-origin\n // iframes. Without this, Chrome silently denies getUserMedia /\n // SpeechRecognition without ever prompting the user.\n iframe.allow = \"clipboard-write; microphone\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\n iframe.loading = \"lazy\";\n iframe.style.cssText = `position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${zIndex};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`;\n\n const origin = new URL(iframe.src).origin;\n\n // --- Native launcher button ---\n const btn = d.createElement(\"div\");\n btn.setAttribute(\"role\", \"button\");\n btn.setAttribute(\"aria-label\", \"Chat\");\n btn.setAttribute(\"data-bitpalm-launcher\", \"\");\n btn.style.cssText = `position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;display:none;align-items:center;justify-content:center;cursor:pointer;z-index:${zIndex - 1};background:#171717;box-shadow:${LAUNCHER_SHADOW};transition:transform .2s,opacity .3s;opacity:0;`;\n btn.innerHTML = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\"/></svg>';\n btn.onmouseenter = () => { btn.style.transform = \"scale(1.05)\"; };\n btn.onmouseleave = () => { btn.style.transform = \"scale(1)\"; };\n btn.onclick = () => openWidget();\n // Sites with a chat button of their own call open() instead.\n if (launcher) d.body.appendChild(btn);\n\n // --- Fade animation for trigger bubbles ---\n if (!d.getElementById(\"_bp_fade\")) {\n const s = d.createElement(\"style\");\n s.id = \"_bp_fade\";\n s.textContent = \"@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}\";\n d.head.appendChild(s);\n }\n\n // --- Trigger bubble ---\n let bubble: HTMLDivElement | null = null;\n let launcherReady = false;\n let widgetBlocked = false;\n let iframeMounted = false;\n let iframeReady = false;\n let pendingOpen = false;\n const mountIframe = () => {\n if (iframeMounted) return;\n iframeMounted = true;\n d.body.appendChild(iframe);\n };\n let mobileScrollLocked = false;\n let scrollLockY = 0;\n const prevHtmlStyle = {\n overflow: \"\",\n overscrollBehavior: \"\",\n };\n const prevBodyStyle = {\n overflow: \"\",\n overscrollBehavior: \"\",\n position: \"\",\n top: \"\",\n left: \"\",\n right: \"\",\n width: \"\",\n };\n const lockMobilePageScroll = () => {\n if (mobileScrollLocked) return;\n const mobile = isMobileWidgetDevice();\n if (!mobile) return;\n const html = d.documentElement;\n const body = d.body;\n scrollLockY = window.scrollY || window.pageYOffset || 0;\n prevHtmlStyle.overflow = html.style.overflow;\n prevHtmlStyle.overscrollBehavior = html.style.overscrollBehavior;\n prevBodyStyle.overflow = body.style.overflow;\n prevBodyStyle.overscrollBehavior = body.style.overscrollBehavior;\n prevBodyStyle.position = body.style.position;\n prevBodyStyle.top = body.style.top;\n prevBodyStyle.left = body.style.left;\n prevBodyStyle.right = body.style.right;\n prevBodyStyle.width = body.style.width;\n html.style.overflow = \"hidden\";\n html.style.overscrollBehavior = \"none\";\n body.style.overflow = \"hidden\";\n body.style.overscrollBehavior = \"none\";\n body.style.position = \"fixed\";\n body.style.top = `-${scrollLockY}px`;\n body.style.left = \"0\";\n body.style.right = \"0\";\n body.style.width = \"100%\";\n mobileScrollLocked = true;\n };\n const unlockMobilePageScroll = () => {\n if (!mobileScrollLocked) return;\n const html = d.documentElement;\n const body = d.body;\n html.style.overflow = prevHtmlStyle.overflow;\n html.style.overscrollBehavior = prevHtmlStyle.overscrollBehavior;\n body.style.overflow = prevBodyStyle.overflow;\n body.style.overscrollBehavior = prevBodyStyle.overscrollBehavior;\n body.style.position = prevBodyStyle.position;\n body.style.top = prevBodyStyle.top;\n body.style.left = prevBodyStyle.left;\n body.style.right = prevBodyStyle.right;\n body.style.width = prevBodyStyle.width;\n window.scrollTo(0, scrollLockY);\n mobileScrollLocked = false;\n };\n const prepareIframeForOpen = () => {\n const mobile = isMobileWidgetDevice();\n if (iframe.style.display === \"none\") iframe.style.display = \"\";\n if (mobile) {\n iframe.style.width = \"100vw\";\n iframe.style.height = \"100dvh\";\n iframe.style.left = \"0\";\n iframe.style.top = \"0\";\n iframe.style.bottom = \"0\";\n iframe.style.right = \"0\";\n lockMobilePageScroll();\n } else {\n // Match desktop widget target size so the opening animation is visible from frame 1.\n iframe.style.width = \"420px\";\n iframe.style.height = \"620px\";\n iframe.style.bottom = \"24px\";\n iframe.style.right = \"24px\";\n iframe.style.left = \"\";\n iframe.style.top = \"\";\n unlockMobilePageScroll();\n }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n };\n const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\n };\n const clearPendingTrigger = () => {\n if (pendingTrigger === null) return;\n pendingTrigger = null;\n emit(\"trigger_hidden\");\n };\n /** Tells the iframe whether to run triggers at all. \"events\" still needs them to run. */\n const sendTriggerState = () => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-triggers\", enabled: triggerMode !== \"off\" }, \"*\");\n };\n let sendParentContext = () => {};\n let sendOpenSignal = () => {};\n\n // --- Widget state & event bus ---\n let widgetIsOpen = false;\n const eventListeners = new Map<BitPalmEventType, Set<BitPalmEventCallback>>();\n\n function emit(event: BitPalmEventType, data?: Record<string, unknown>) {\n const listeners = eventListeners.get(event);\n if (!listeners) return;\n for (const cb of listeners) {\n try { cb(data); } catch { /* don't let listener errors break the widget */ }\n }\n }\n\n // --- postMessage handler ---\n const handleMessage = (e: MessageEvent) => {\n if (e.origin !== origin) return;\n\n // Widget config (colors, icon)\n if (e.data?.type === \"bitpalm-widget-config\") {\n widgetBlocked = false;\n launcherReady = true;\n if (iframe.style.display === \"none\") iframe.style.display = \"\";\n if (e.data.primaryColor) {\n btn.style.background = e.data.primaryColor;\n btn.style.boxShadow = e.data.chatShadow === \"none\" ? \"none\" : LAUNCHER_SHADOW;\n }\n const ic = e.data.chatButtonIconColor || \"black\";\n if (e.data.chatButtonIconSvg) {\n btn.innerHTML = \"\";\n const sp = d.createElement(\"span\");\n sp.style.cssText = `display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${ic}`;\n const parser = new DOMParser();\n const doc = parser.parseFromString(e.data.chatButtonIconSvg, \"image/svg+xml\");\n const svg = doc.querySelector(\"svg\");\n if (svg) {\n // Remove dangerous elements and attributes\n svg.querySelectorAll(\"script,foreignObject\").forEach(el => el.remove());\n svg.querySelectorAll(\"*\").forEach(el => {\n for (const attr of [...el.attributes]) {\n if (attr.name.startsWith(\"on\") || (attr.value && attr.value.includes(\"javascript:\"))) {\n el.removeAttribute(attr.name);\n }\n }\n });\n svg.setAttribute(\"width\", \"24\");\n svg.setAttribute(\"height\", \"24\");\n svg.style.display = \"block\";\n sp.appendChild(svg);\n } else {\n // Fallback: use default icon\n sp.innerHTML = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\"/></svg>';\n }\n btn.appendChild(sp);\n } else {\n const sv = btn.querySelector(\"svg\");\n if (sv) (sv as SVGElement).style.stroke = ic;\n }\n if (launcher) {\n btn.style.display = \"flex\";\n // Fade in after styles are applied\n requestAnimationFrame(() => { btn.style.opacity = \"1\"; });\n }\n // The iframe may have loaded after disableTriggers() or enableTriggers().\n sendTriggerState();\n }\n\n // Resize — use full viewport on mobile\n if (e.data?.type === \"bitpalm-widget-resize\") {\n const isOpen = e.data.width > 0;\n const wasOpen = widgetIsOpen;\n widgetIsOpen = isOpen;\n if (isOpen && !wasOpen) emit(\"widget_opened\");\n if (!isOpen && wasOpen) emit(\"widget_closed\");\n const mobile = isMobileWidgetDevice();\n if (isOpen) {\n iframe.style.width = mobile ? \"100vw\" : `${e.data.width}px`;\n iframe.style.height = mobile ? \"100dvh\" : `${e.data.height}px`;\n if (mobile) {\n iframe.style.left = \"0\";\n iframe.style.top = \"0\";\n iframe.style.bottom = \"0\";\n iframe.style.right = \"0\";\n lockMobilePageScroll();\n } else {\n unlockMobilePageScroll();\n }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\n unlockMobilePageScroll();\n iframe.style.width = \"1px\";\n iframe.style.height = \"1px\";\n iframe.style.left = \"\";\n iframe.style.top = \"\";\n iframe.style.opacity = \"0\";\n iframe.style.pointerEvents = \"none\";\n }\n btn.style.display = isOpen || !launcher ? \"none\" : \"flex\";\n }\n\n // A trigger fired inside the iframe: our bubble, or an event for the site's own UI\n if (e.data?.type === \"bitpalm-trigger-show\") {\n if (widgetBlocked || !launcherReady || triggerMode === \"off\") return;\n const message = typeof e.data.message === \"string\" ? e.data.message : \"\";\n if (!message) return;\n if (triggerMode === \"events\") {\n pendingTrigger = message;\n emit(\"trigger_shown\", { message, triggerId: e.data.triggerId, triggerType: e.data.triggerType });\n return;\n }\n removeBubble();\n bubble = createTriggerBubble(d, {\n message,\n zIndex,\n bottom: launcher ? 90 : 24,\n onDismiss: () => {\n removeBubble();\n iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-dismiss\" }, \"*\");\n },\n onEngage: () => {\n removeBubble();\n btn.style.display = \"none\";\n prepareIframeForOpen();\n mountIframe();\n if (!iframeReady) {\n pendingOpen = true;\n return;\n }\n iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\", message }, \"*\");\n },\n });\n d.body.appendChild(bubble);\n }\n\n // Trigger gone (chat opened, dismissed, switched off)\n if (e.data?.type === \"bitpalm-trigger-hide\") {\n removeBubble();\n clearPendingTrigger();\n }\n\n // Iframe requests latest parent context (avoids first-load race conditions)\n if (e.data?.type === \"bitpalm-request-context\") {\n sendParentContext();\n }\n\n // Chat events from iframe → emit to SDK listeners\n if (e.data?.type === \"bitpalm-chat-event\" && e.data.event) {\n emit(e.data.event as BitPalmEventType, e.data.data);\n }\n\n // Widget blocked (excluded path or access denied) — hide button & iframe\n if (e.data?.type === \"bitpalm-widget-blocked\") {\n widgetBlocked = true;\n launcherReady = false;\n btn.style.display = \"none\";\n removeBubble();\n clearPendingTrigger();\n unlockMobilePageScroll();\n iframe.style.display = \"none\";\n }\n };\n window.addEventListener(\"message\", handleMessage);\n\n // --- Privacy opt-out check ---\n let optedOut = false;\n try { optedOut = localStorage.getItem(`${STORAGE_PREFIX}optout`) === \"1\"; } catch { /* ignore */ }\n\n // --- Persistent Visitor ID (skip if opted out) ---\n const VID_KEY = `${STORAGE_PREFIX}vid`;\n let visitorId = \"\";\n if (!optedOut) {\n try { visitorId = localStorage.getItem(VID_KEY) || \"\"; } catch { /* ignore */ }\n if (!visitorId) {\n // Fallback: try reading from cookie\n const match = d.cookie.match(new RegExp(`(?:^|; )${VID_KEY}=([^;]+)`));\n visitorId = match ? decodeURIComponent(match[1]) : \"\";\n }\n if (!visitorId) {\n visitorId = crypto.randomUUID ? crypto.randomUUID() : (`${Date.now()}-${Math.random().toString(36).slice(2, 11)}`);\n }\n // Persist in both localStorage and cookie (cookie survives Safari ITP clearing localStorage)\n try { localStorage.setItem(VID_KEY, visitorId); } catch { /* ignore */ }\n try {\n const maxAge = 365 * 24 * 60 * 60; // 1 year\n d.cookie = `${VID_KEY}=${encodeURIComponent(visitorId)};path=/;max-age=${maxAge};SameSite=Lax`;\n } catch { /* ignore */ }\n }\n\n // --- Visitor beacon: track page view even without chat (skip if opted out) ---\n if (!optedOut) {\n runWhenIdle(() => {\n try {\n const utmParams = new URLSearchParams(location.search);\n const utm: Record<string, string> = {};\n for (const key of [\"utm_source\", \"utm_medium\", \"utm_campaign\", \"utm_term\", \"utm_content\"]) {\n const val = utmParams.get(key);\n if (val) utm[key] = val;\n }\n const beaconPayload = JSON.stringify({\n tenant_slug: slug,\n visitor_id: visitorId,\n url: location.href,\n referrer: d.referrer || undefined,\n ...(Object.keys(utm).length > 0 ? { utm } : {}),\n });\n const beaconUrl = `${baseUrl}/api/widget/impression`;\n if (typeof navigator.sendBeacon === \"function\") {\n navigator.sendBeacon(beaconUrl, new Blob([beaconPayload], { type: \"application/json\" }));\n } else {\n fetch(beaconUrl, { method: \"POST\", body: beaconPayload, headers: { \"Content-Type\": \"application/json\" }, keepalive: true }).catch(() => {});\n }\n } catch { /* ignore */ }\n }, 2000);\n }\n\n // --- Auto-identify visitor from form submissions on host page ---\n let lastIdentitySignature = \"\";\n let lastIdentityFingerprint = \"\";\n let lastIdentitySentAt = 0;\n try {\n lastIdentitySignature = sessionStorage.getItem(IDENTITY_SIGNATURE_KEY) || \"\";\n lastIdentityFingerprint = sessionStorage.getItem(IDENTITY_FINGERPRINT_KEY) || \"\";\n const storedAt = parseInt(sessionStorage.getItem(IDENTITY_SENT_AT_KEY) || \"0\", 10);\n if (Number.isFinite(storedAt) && storedAt > 0) {\n lastIdentitySentAt = storedAt;\n }\n } catch {\n // ignore\n }\n\n const dispatchIdentify = (payloadInput: IdentifyRequestPayload, scopeSignature = \"\") => {\n if (optedOut || !visitorId) return;\n\n const payload: IdentifyRequestPayload = {};\n const name = normalizeText(payloadInput.name, 140);\n const email = normalizeEmail(payloadInput.email);\n const phone = normalizePhone(payloadInput.phone);\n const company = normalizeText(payloadInput.company, 160);\n const externalUserId = normalizeText(payloadInput.external_user_id, 140);\n const requestSignature = normalizeText(payloadInput.signature, 260);\n const signedAtRaw = Number(payloadInput.signed_at);\n\n if (name) payload.name = name;\n if (email) payload.email = email;\n if (phone) payload.phone = phone;\n if (company) payload.company = company;\n if (externalUserId) payload.external_user_id = externalUserId;\n if (requestSignature) payload.signature = requestSignature;\n if (Number.isFinite(signedAtRaw) && signedAtRaw > 0) {\n payload.signed_at = Math.floor(signedAtRaw);\n }\n if (payloadInput.signature_version === \"v1\" || payload.signature) {\n payload.signature_version = \"v1\";\n }\n if (payloadInput.identify_source === \"manual\" || payloadInput.identify_source === \"form\") {\n payload.identify_source = payloadInput.identify_source;\n }\n\n if (!payload.name && !payload.email && !payload.phone && !payload.company && !payload.external_user_id) {\n return;\n }\n\n const identityFingerprint = buildIdentityFingerprint(payload);\n const dedupeSignature = [scopeSignature.toLowerCase(), identityFingerprint].filter(Boolean).join(\"|\");\n\n const now = Date.now();\n const insideDedupWindow = now - lastIdentitySentAt < IDENTITY_DEDUPE_WINDOW_MS;\n if (insideDedupWindow && (dedupeSignature === lastIdentitySignature || identityFingerprint === lastIdentityFingerprint)) {\n return;\n }\n\n lastIdentitySignature = dedupeSignature;\n lastIdentityFingerprint = identityFingerprint;\n lastIdentitySentAt = now;\n try {\n sessionStorage.setItem(IDENTITY_SIGNATURE_KEY, dedupeSignature);\n sessionStorage.setItem(IDENTITY_FINGERPRINT_KEY, identityFingerprint);\n sessionStorage.setItem(IDENTITY_SENT_AT_KEY, String(now));\n } catch {\n // ignore\n }\n\n try {\n const requestBody = JSON.stringify({\n tenant_slug: slug,\n visitor_id: visitorId,\n url: location.href,\n referrer: d.referrer || undefined,\n ...payload,\n });\n const identifyUrl = `${baseUrl}/api/widget/identify`;\n if (typeof navigator.sendBeacon === \"function\") {\n navigator.sendBeacon(identifyUrl, new Blob([requestBody], { type: \"application/json\" }));\n } else {\n fetch(identifyUrl, { method: \"POST\", body: requestBody, headers: { \"Content-Type\": \"application/json\" }, keepalive: true }).catch(() => {});\n }\n } catch {\n // ignore\n }\n };\n\n const handleFormSubmit = (event: Event) => {\n if (optedOut || !autoIdentify || !visitorId) return;\n\n const form = event.target instanceof HTMLFormElement\n ? event.target\n : event.target instanceof Element\n ? event.target.closest(\"form\")\n : null;\n if (!(form instanceof HTMLFormElement)) return;\n\n const formIdentifySetting = (form.getAttribute(\"data-bp-identify\") || form.getAttribute(\"data-bitpalm-identify\") || \"\").toLowerCase();\n if (formIdentifySetting === \"off\" || formIdentifySetting === \"false\" || formIdentifySetting === \"0\") return;\n\n const identity = extractIdentityFromForm(form);\n if (!identity) return;\n\n const formSignature = [\n form.getAttribute(\"id\") || \"\",\n form.getAttribute(\"name\") || \"\",\n form.getAttribute(\"action\") || \"\",\n ].join(\"|\");\n\n dispatchIdentify({ ...identity, identify_source: \"form\" }, formSignature);\n };\n\n if (!optedOut && autoIdentify) {\n d.addEventListener(\"submit\", handleFormSubmit, true);\n }\n\n // --- Visitor Intelligence: page counter + history ---\n let pageCount = parseInt(sessionStorage.getItem(`${STORAGE_PREFIX}pages`) || \"0\") + 1;\n sessionStorage.setItem(`${STORAGE_PREFIX}pages`, String(pageCount));\n\n let hist: string[] = JSON.parse(sessionStorage.getItem(`${STORAGE_PREFIX}hist`) || \"[]\");\n hist.push(location.href);\n if (hist.length > 20) hist = hist.slice(-20);\n sessionStorage.setItem(`${STORAGE_PREFIX}hist`, JSON.stringify(hist));\n\n const loadedAt = Date.now();\n let siteStart = parseInt(sessionStorage.getItem(`${STORAGE_PREFIX}site_start`) || \"0\");\n if (!siteStart) {\n siteStart = loadedAt;\n sessionStorage.setItem(`${STORAGE_PREFIX}site_start`, String(siteStart));\n }\n\n const contextRetryTimers: ReturnType<typeof setTimeout>[] = [];\n sendParentContext = () => {\n let returning = false;\n try {\n returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\n } catch {\n returning = false;\n }\n iframe.contentWindow?.postMessage({\n type: \"bitpalm-parent-context\",\n url: location.href,\n title: d.title,\n returning,\n pageCount,\n pageHistory: hist,\n loadedAt,\n siteStart,\n locale,\n visitorId: optedOut ? \"\" : visitorId,\n }, \"*\");\n sendTheme();\n if (!returning && !optedOut) {\n try { localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\"); } catch { /* ignore */ }\n }\n };\n\n // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n iframeReady = true;\n sendParentContext();\n [120, 450, 1100].forEach((delay) => {\n const timer = setTimeout(() => sendParentContext(), delay);\n contextRetryTimers.push(timer);\n });\n if (pendingOpen) {\n pendingOpen = false;\n sendOpenSignal();\n }\n });\n\n // Lazy-mount iframe after initial paint/idle to reduce impact on host load.\n if (d.readyState === \"loading\") {\n d.addEventListener(\"DOMContentLoaded\", () => runWhenIdle(mountIframe, 1600), { once: true });\n } else {\n runWhenIdle(mountIframe, 1600);\n }\n\n // --- SPA navigation detection ---\n const origPush = history.pushState.bind(history);\n const origReplace = history.replaceState.bind(history);\n\n const onNav = () => {\n pageCount++;\n sessionStorage.setItem(`${STORAGE_PREFIX}pages`, String(pageCount));\n const h: string[] = JSON.parse(sessionStorage.getItem(`${STORAGE_PREFIX}hist`) || \"[]\");\n h.push(location.href);\n if (h.length > 20) h.splice(0, h.length - 20);\n hist = h;\n sessionStorage.setItem(`${STORAGE_PREFIX}hist`, JSON.stringify(h));\n iframe.contentWindow?.postMessage({\n type: \"bitpalm-page-change\",\n url: location.href,\n title: d.title,\n pageCount,\n pageHistory: h,\n loadedAt: Date.now(),\n }, \"*\");\n // Track page view for visitor (skip if opted out)\n if (!optedOut) {\n try {\n const navPayload = JSON.stringify({ tenant_slug: slug, visitor_id: visitorId, url: location.href });\n const navUrl = `${baseUrl}/api/widget/impression`;\n if (typeof navigator.sendBeacon === \"function\") {\n navigator.sendBeacon(navUrl, new Blob([navPayload], { type: \"application/json\" }));\n } else {\n fetch(navUrl, { method: \"POST\", body: navPayload, headers: { \"Content-Type\": \"application/json\" }, keepalive: true }).catch(() => {});\n }\n } catch { /* ignore */ }\n }\n };\n\n history.pushState = function (...args: Parameters<typeof history.pushState>) {\n origPush(...args);\n onNav();\n };\n history.replaceState = function (...args: Parameters<typeof history.replaceState>) {\n origReplace(...args);\n onNav();\n };\n window.addEventListener(\"popstate\", onNav);\n\n // --- Scroll depth tracking ---\n let lastScrollDepth = -1;\n let scrollTimeout: ReturnType<typeof setTimeout>;\n const handleScroll = () => {\n clearTimeout(scrollTimeout);\n scrollTimeout = setTimeout(() => {\n const total = Math.max(d.documentElement.scrollHeight, d.body.scrollHeight) - window.innerHeight;\n const pct = total > 0 ? Math.round(window.scrollY / total * 100) : 100;\n if (pct !== lastScrollDepth) {\n lastScrollDepth = pct;\n iframe.contentWindow?.postMessage({ type: \"bitpalm-scroll-depth\", percent: pct }, \"*\");\n }\n }, 500);\n };\n window.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n // --- Exit intent ---\n const handleMouseOut = (e: MouseEvent) => {\n if (e.clientY <= 0) {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-exit-intent\" }, \"*\");\n }\n };\n d.addEventListener(\"mouseout\", handleMouseOut);\n\n // --- Inactivity detection (15s) ---\n let idleTimer: ReturnType<typeof setTimeout>;\n let idleFired = false;\n const resetIdle = () => {\n clearTimeout(idleTimer);\n if (idleFired) return;\n idleTimer = setTimeout(() => {\n idleFired = true;\n iframe.contentWindow?.postMessage({ type: \"bitpalm-inactivity\" }, \"*\");\n }, 15_000);\n };\n const idleEvents = [\"mousemove\", \"keydown\", \"scroll\", \"touchstart\"] as const;\n idleEvents.forEach((ev) => d.addEventListener(ev, resetIdle, { passive: true }));\n resetIdle();\n\n sendOpenSignal = () => {\n // Primary: postMessage\n iframe.contentWindow?.postMessage({ type: \"bitpalm-open\" }, \"*\");\n // Fallback for mobile: trigger hashchange inside iframe (no reload)\n const base = iframe.src.split(\"#\")[0];\n iframe.src = `${base}#bp-open-${Date.now()}`;\n };\n\n // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\n prepareIframeForOpen();\n mountIframe();\n if (!iframeReady) {\n pendingOpen = true;\n return;\n }\n // A waiting trigger message opens with the chat and counts as clicked, like the bubble.\n if (pendingTrigger !== null) {\n const message = pendingTrigger;\n clearPendingTrigger();\n iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\", message }, \"*\");\n return;\n }\n sendOpenSignal();\n };\n\n const setTriggerMode = (mode: TriggerMode) => {\n triggerMode = mode;\n if (mode === \"off\") {\n removeBubble();\n clearPendingTrigger();\n }\n sendTriggerState();\n };\n const disableTriggers = () => setTriggerMode(\"off\");\n const enableTriggers = () => setTriggerMode(configuredTriggerMode === \"off\" ? \"bubble\" : configuredTriggerMode);\n\n const closeWidget = () => {\n unlockMobilePageScroll();\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\n };\n\n const identify = (input: BitPalmIdentifyPayload) => {\n if (!input || typeof input !== \"object\") return;\n dispatchIdentify({\n external_user_id: normalizeText(input.externalUserId, 140) || undefined,\n name: normalizeText(input.name, 140) || undefined,\n email: normalizeEmail(input.email) || undefined,\n phone: normalizePhone(input.phone) || undefined,\n company: normalizeText(input.company, 160) || undefined,\n signature: normalizeText(input.signature, 260) || undefined,\n signed_at: Number.isFinite(Number(input.signedAt)) ? Math.floor(Number(input.signedAt)) : undefined,\n signature_version: input.signatureVersion === \"v1\" ? \"v1\" : undefined,\n identify_source: \"manual\",\n }, \"manual\");\n };\n\n const toggleWidget = () => {\n if (widgetIsOpen) closeWidget();\n else openWidget();\n };\n\n const getIsOpen = () => widgetIsOpen;\n\n const sendMessage = (message: string) => {\n if (!message || typeof message !== \"string\") return;\n const text = message.trim().slice(0, 10_000);\n if (!text) return;\n if (!widgetIsOpen) openWidget();\n // Small delay to ensure widget is open before sending\n setTimeout(() => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-send-message\", message: text }, \"*\");\n }, widgetIsOpen ? 50 : 500);\n };\n\n // --- Theme switching ---\n function sendTheme() {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-theme\", theme: currentTheme }, \"*\");\n }\n\n const applyTheme = (theme: HostTheme) => {\n if (theme === currentTheme) return;\n currentTheme = theme;\n sendTheme();\n };\n\n const setTheme = (theme: BitPalmTheme) => {\n themeSetting = normalizeThemeSetting(theme);\n stopThemeWatch?.();\n stopThemeWatch = null;\n if (themeSetting === \"auto\") {\n stopThemeWatch = watchHostTheme(applyTheme);\n applyTheme(detectHostTheme());\n } else {\n applyTheme(themeSetting);\n }\n };\n\n if (themeSetting === \"auto\") stopThemeWatch = watchHostTheme(applyTheme);\n\n const handleThemeEvent = (event: Event) => {\n const detail = (event as CustomEvent<{ slug?: string; theme?: BitPalmTheme }>).detail;\n if (!detail || typeof detail !== \"object\") return;\n const targetSlug = normalizeText(detail.slug, 120);\n if (targetSlug && targetSlug !== slug) return;\n setTheme(normalizeThemeSetting(detail.theme));\n };\n window.addEventListener(\"bitpalm-theme\", handleThemeEvent as EventListener);\n\n // --- Custom context for AI ---\n let customContext: Record<string, unknown> = {};\n\n const setCustomContext = (data: BitPalmCustomContext) => {\n if (!data || typeof data !== \"object\" || Array.isArray(data)) return;\n customContext = { ...customContext, ...data };\n const json = JSON.stringify(customContext);\n if (json.length > CUSTOM_CONTEXT_MAX_BYTES) {\n console.warn(\n `[BitPalm] Custom context exceeds ${CUSTOM_CONTEXT_MAX_BYTES} bytes (${json.length}). It may be truncated.`\n );\n }\n iframe.contentWindow?.postMessage({ type: \"bitpalm-custom-context\", data: customContext }, \"*\");\n };\n\n const clearCustomContext = () => {\n customContext = {};\n iframe.contentWindow?.postMessage({ type: \"bitpalm-custom-context\", data: {} }, \"*\");\n };\n\n const handleContextEvent = (event: Event) => {\n const customEvent = event as CustomEvent<BitPalmCustomContext & { slug?: string }>;\n const detail = customEvent.detail;\n if (!detail || typeof detail !== \"object\") return;\n const targetSlug = normalizeText((detail as Record<string, unknown>).slug as string, 120);\n if (targetSlug && targetSlug !== slug) return;\n const { slug: _s, ...contextData } = detail as Record<string, unknown>;\n setCustomContext(contextData);\n };\n\n window.addEventListener(\"bitpalm-context\", handleContextEvent as EventListener);\n\n const handleIdentifyEvent = (event: Event) => {\n const customEvent = event as CustomEvent<BitPalmIdentifyPayload & { slug?: string }>;\n const detail = customEvent.detail;\n if (!detail || typeof detail !== \"object\") return;\n const targetSlug = normalizeText(detail.slug, 120);\n if (targetSlug && targetSlug !== slug) return;\n identify(detail);\n };\n\n window.addEventListener(\"bitpalm-identify\", handleIdentifyEvent as EventListener);\n\n // open, close and send for setups without an instance (script tag)\n const targetsThisWidget = (event: Event) => {\n const detail = (event as CustomEvent<{ slug?: string }>).detail;\n const targetSlug = normalizeText(detail?.slug, 120);\n return !targetSlug || targetSlug === slug;\n };\n const handleOpenEvent = (event: Event) => { if (targetsThisWidget(event)) openWidget(); };\n const handleCloseEvent = (event: Event) => { if (targetsThisWidget(event)) closeWidget(); };\n const handleSendEvent = (event: Event) => {\n if (!targetsThisWidget(event)) return;\n const message = (event as CustomEvent<{ message?: string }>).detail?.message;\n if (typeof message === \"string\") sendMessage(message);\n };\n window.addEventListener(\"bitpalm-open\", handleOpenEvent);\n window.addEventListener(\"bitpalm-close\", handleCloseEvent);\n window.addEventListener(\"bitpalm-send\", handleSendEvent);\n\n const onEvent = (event: BitPalmEventType, callback: BitPalmEventCallback): (() => void) => {\n if (!eventListeners.has(event)) eventListeners.set(event, new Set());\n eventListeners.get(event)!.add(callback);\n return () => eventListeners.get(event)?.delete(callback);\n };\n\n const offEvent = (event: BitPalmEventType, callback: BitPalmEventCallback) => {\n eventListeners.get(event)?.delete(callback);\n };\n\n const destroy = () => {\n window.removeEventListener(\"message\", handleMessage);\n window.removeEventListener(\"scroll\", handleScroll);\n window.removeEventListener(\"popstate\", onNav);\n d.removeEventListener(\"mouseout\", handleMouseOut);\n d.removeEventListener(\"submit\", handleFormSubmit, true);\n idleEvents.forEach((ev) => d.removeEventListener(ev, resetIdle));\n clearTimeout(scrollTimeout);\n clearTimeout(idleTimer);\n contextRetryTimers.forEach((t) => clearTimeout(t));\n history.pushState = origPush;\n history.replaceState = origReplace;\n window.removeEventListener(\"bitpalm-identify\", handleIdentifyEvent as EventListener);\n window.removeEventListener(\"bitpalm-context\", handleContextEvent as EventListener);\n window.removeEventListener(\"bitpalm-theme\", handleThemeEvent as EventListener);\n window.removeEventListener(\"bitpalm-open\", handleOpenEvent);\n window.removeEventListener(\"bitpalm-close\", handleCloseEvent);\n window.removeEventListener(\"bitpalm-send\", handleSendEvent);\n stopThemeWatch?.();\n eventListeners.clear();\n unlockMobilePageScroll();\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return {\n open: openWidget,\n close: closeWidget,\n toggle: toggleWidget,\n isOpen: getIsOpen,\n identify,\n context: setCustomContext,\n resetContext: clearCustomContext,\n send: sendMessage,\n on: onEvent,\n off: offEvent,\n setTheme,\n disableTriggers,\n enableTriggers,\n destroy,\n };\n}\n","export { createWidget } from \"./widget\";\nexport { detectHostTheme } from \"./theme\";\nexport type { BitPalmAgentOptions, BitPalmAgentInstance, BitPalmIdentifyPayload, BitPalmCustomContext, BitPalmEventType, BitPalmEventCallback, BitPalmTheme } from \"./types\";\n\nimport { createWidget } from \"./widget\";\nimport { normalizeThemeSetting } from \"./theme\";\nimport { parseTriggerMode, triggersOption } from \"./triggers\";\n\nfunction parseBoolean(value: string | undefined): boolean | undefined {\n if (value == null) return undefined;\n const normalized = value.trim().toLowerCase();\n if ([\"1\", \"true\", \"yes\", \"on\"].includes(normalized)) return true;\n if ([\"0\", \"false\", \"no\", \"off\"].includes(normalized)) return false;\n return undefined;\n}\n\n/**\n * Auto-init from script tag:\n * <script src=\"https://cdn.bitpalm.ai/widget.js\" data-slug=\"my-agent\"></script>\n * Optional: data-launcher=\"false\" and data-triggers=\"events\" or \"false\".\n */\nif (typeof document !== \"undefined\") {\n const script = document.currentScript as HTMLScriptElement | null;\n if (script?.dataset.slug) {\n const init = () => {\n createWidget({\n slug: script!.dataset.slug!,\n locale: script!.dataset.locale,\n baseUrl: script!.dataset.baseUrl,\n token: script!.dataset.token,\n zIndex: script!.dataset.zIndex ? Number(script!.dataset.zIndex) : undefined,\n autoIdentify: parseBoolean(script!.dataset.autoIdentify),\n theme: normalizeThemeSetting(script!.dataset.theme),\n launcher: parseBoolean(script!.dataset.launcher),\n triggers: script!.dataset.triggers === undefined ? undefined : triggersOption(parseTriggerMode(script!.dataset.triggers)),\n });\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init);\n } else {\n init();\n }\n }\n}\n"],"mappings":"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","names":["parseTriggerMode","value","normalized","triggersOption","mode","createTriggerBubble","d","options","bubble","text","arrow","close","event","DARK_CLASSES","LIGHT_CLASSES","THEME_ATTRIBUTES","DARK_QUERY","normalizeThemeSetting","value","explicitTheme","el","name","attr","channel","s","backgroundTheme","win","match","g","b","a","n","colorSchemeTheme","doc","computed","meta","scheme","detectHostTheme","watchHostTheme","onChange","last","scheduled","check","next","schedule","observer","observed","media","DEFAULT_BASE_URL","STORAGE_PREFIX","IGNORED_INPUT_TYPES","IDENTITY_DEDUPE_WINDOW_MS","CUSTOM_CONTEXT_MAX_BYTES","IDENTITY_SIGNATURE_KEY","IDENTITY_FINGERPRINT_KEY","IDENTITY_SENT_AT_KEY","LAUNCHER_SHADOW","buildIdentityFingerprint","payload","normalizeText","value","maxLen","normalizeTokens","includesAny","haystack","needles","needle","isEmail","normalizePhone","trimmed","hasPlus","digits","normalizeEmail","normalized","getExplicitValue","form","selectors","selector","el","getFieldHint","escapeAttrSelectorValue","collectElementTokenParts","parts","pushText","clean","seenLabels","pushLabel","label","forLabel","nearestLabel","ariaLabelledBy","id","ref","extractIdentityFromForm","email","phone","name","firstName","lastName","company","rawEl","fieldHint","explicitField","type","tokens","emailLike","phoneLike","companyLike","firstNameLike","lastNameLike","fullNameLike","identity","detectLocale","lang","runWhenIdle","task","timeout","isMobileWidgetDevice","userAgent","coarsePointer","noHover","minScreenSide","createWidget","options","slug","locale","baseUrl","token","zIndex","autoIdentify","launcher","d","themeSetting","normalizeThemeSetting","currentTheme","detectHostTheme","stopThemeWatch","configuredTriggerMode","parseTriggerMode","triggerMode","pendingTrigger","iframe","widgetUrl","qs","origin","btn","openWidget","s","bubble","launcherReady","widgetBlocked","iframeMounted","iframeReady","pendingOpen","mountIframe","mobileScrollLocked","scrollLockY","prevHtmlStyle","prevBodyStyle","lockMobilePageScroll","html","body","unlockMobilePageScroll","prepareIframeForOpen","mobile","removeBubble","clearPendingTrigger","emit","sendTriggerState","sendParentContext","sendOpenSignal","widgetIsOpen","eventListeners","event","data","listeners","cb","handleMessage","ic","sp","svg","attr","sv","isOpen","wasOpen","message","createTriggerBubble","optedOut","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","lastIdentitySignature","lastIdentityFingerprint","lastIdentitySentAt","storedAt","dispatchIdentify","payloadInput","scopeSignature","externalUserId","requestSignature","signedAtRaw","identityFingerprint","dedupeSignature","now","requestBody","identifyUrl","handleFormSubmit","formIdentifySetting","formSignature","pageCount","hist","loadedAt","siteStart","contextRetryTimers","returning","sendTheme","delay","timer","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","ev","base","setTriggerMode","mode","disableTriggers","enableTriggers","closeWidget","identify","input","toggleWidget","getIsOpen","sendMessage","text","applyTheme","theme","setTheme","watchHostTheme","handleThemeEvent","detail","targetSlug","customContext","setCustomContext","json","clearCustomContext","handleContextEvent","_s","contextData","handleIdentifyEvent","targetsThisWidget","handleOpenEvent","handleCloseEvent","handleSendEvent","callback","t","parseBoolean","value","normalized","script","init","createWidget","normalizeThemeSetting","triggersOption","parseTriggerMode"]}
|