@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/react.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var me=Object.defineProperty;var Ye=Object.getOwnPropertyDescriptor;var Je=Object.getOwnPropertyNames;var Ge=Object.prototype.hasOwnProperty;var Ve=(i,o)=>{for(var c in o)me(i,c,{get:o[c],enumerable:!0})},Ke=(i,o,c,a)=>{if(o&&typeof o=="object"||typeof o=="function")for(let p of Je(o))!Ge.call(i,p)&&p!==c&&me(i,p,{get:()=>o[p],enumerable:!(a=Ye(o,p))||a.enumerable});return i};var Xe=i=>Ke(me({},"__esModule",{value:!0}),i);var ct={};Ve(ct,{BitPalmAgent:()=>lt});module.exports=Xe(ct);var J=require("react");var Ze="https://agents.bitpalm.ai",h="_bp_",Qe=new Set(["password","file","checkbox","radio","submit","button","reset","image"]),et=8e3,He=4096,Re=`${h}identify_signature`,Ne=`${h}identify_fingerprint`,Fe=`${h}identify_sent_at`;function tt(i){return[i.external_user_id||"",i.email||"",i.phone||"",i.name||"",i.company||"",i.signature||"",i.signed_at!=null?String(i.signed_at):"",i.signature_version||"",i.identify_source||""].join("|").toLowerCase()}function m(i,o=180){return i?i.replace(/\s+/g," ").trim().slice(0,o):""}function nt(i){return i?` ${i.toLowerCase().replace(/[_-]+/g," ").replace(/[^a-z0-9\s@.]/g," ").replace(/\s+/g," ").trim()} `:""}function W(i,o){for(let c of o)if(i.includes(c))return!0;return!1}function A(i){return/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i.test(i)}function _(i){let o=m(i,50);if(!o)return"";let c=o.startsWith("+"),a=o.replace(/\D/g,"");return a.length<6?"":`${c?"+":""}${a.slice(0,20)}`}function De(i){let o=m(i,140).toLowerCase();return!o||!A(o)?"":o}function j(i,o){for(let c of o){let a=i.querySelector(c),p=m(a?.value);if(p)return p}return""}function ot(i){return m(i.getAttribute("data-bp-field")||i.getAttribute("data-bitpalm-field"),64).toLowerCase().replace(/[_\s]+/g,"-")}function it(i){return i.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function st(i,o){let c=[],a=(n,x=140)=>{let l=m(n,x);l&&c.push(l)};a(o.name),a(o.id),a(o.getAttribute("autocomplete")),a(o.getAttribute("placeholder")),a(o.getAttribute("aria-label")),a(o.getAttribute("data-field")),a(o.getAttribute("data-name")),a(o.getAttribute("data-label")),a(o.getAttribute("data-bp-field")),a(o.getAttribute("data-bitpalm-field"));let p=new Set,w=n=>{let x=m(n,200);!x||p.has(x)||(p.add(x),c.push(x))};for(let n of Array.from(o.labels||[]))w(n.textContent);if(o.id){let n=i.querySelector(`label[for="${it(o.id)}"]`);w(n?.textContent)}let y=o.closest("label");w(y?.textContent);let r=o.getAttribute("aria-labelledby");if(r)for(let n of r.split(/\s+/)){if(!n)continue;let x=i.ownerDocument.getElementById(n);w(x?.textContent)}return c}function at(i){let o=m(j(i,["[data-bp-email]","[data-bitpalm-email]"]),140).toLowerCase(),c=_(j(i,["[data-bp-phone]","[data-bitpalm-phone]"])),a=m(j(i,["[data-bp-name]","[data-bitpalm-name]","[data-bp-full-name]","[data-bitpalm-full-name]"])),p=m(j(i,["[data-bp-first-name]","[data-bitpalm-first-name]"])),w=m(j(i,["[data-bp-last-name]","[data-bitpalm-last-name]"])),y=m(j(i,["[data-bp-company]","[data-bitpalm-company]"]));for(let l of Array.from(i.elements)){if(!(l instanceof HTMLInputElement||l instanceof HTMLTextAreaElement||l instanceof HTMLSelectElement)||l.disabled||l instanceof HTMLInputElement&&Qe.has(l.type.toLowerCase()))continue;let g=ot(l),u=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")||!!g;if(l instanceof HTMLInputElement&&l.type.toLowerCase()==="hidden"&&!u)continue;let d=m(l.value);if(!d)continue;let $=l instanceof HTMLInputElement?l.type.toLowerCase():"",S=nt(st(i,l).join(" "));if(!o&&g==="email"&&A(d)){o=d.toLowerCase();continue}if(!c&&(g==="phone"||g==="tel"||g==="mobile"||g==="whatsapp")){let T=_(d);if(T){c=T;continue}}if(!y&&g==="company"){y=m(d,160);continue}if(!p&&(g==="first-name"||g==="firstname")){p=m(d,100);continue}if(!w&&(g==="last-name"||g==="lastname"||g==="surname")){w=m(d,100);continue}if(!a&&(g==="name"||g==="full-name"||g==="fullname")){!A(d)&&!_(d)&&(a=m(d,140));continue}let U=$==="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 "]),R=W(S,[" first name "," firstname "," given name "," givenname "," vorname "," fname "]),N=W(S,[" last name "," lastname "," family name "," familyname "," surname "," nachname "," lname "]),q=W(S,[" full name "," fullname "," contact name "," name "])&&!U&&!O;if(!o&&U&&A(d)){o=d.toLowerCase();continue}if(!c&&O){let T=_(d);if(T){c=T;continue}}if(!y&&H){y=m(d,160);continue}if(!p&&R){p=m(d,100);continue}if(!w&&N){w=m(d,100);continue}if(!a&&q&&!A(d)&&!_(d)){a=m(d,140);continue}!o&&A(d)&&(o=d.toLowerCase())}if(a&&(A(a)||_(a))&&(a=""),y&&(A(y)||_(y))&&(y=""),a||(a=m([p,w].filter(Boolean).join(" "),140)),a&&o&&a.toLowerCase()===o.toLowerCase()&&(a=""),!!!(o||c)&&!!!(a&&y))return null;let x={...a?{name:a}:{},...o?{email:o}:{},...c?{phone:c}:{},...y?{company:y}:{}};return Object.keys(x).length>0?x:null}function rt(){if(typeof document<"u"){let i=document.documentElement.lang;if(i)return i.slice(0,2).toLowerCase()}return"en"}function ue(i,o=1200){if(typeof window<"u"&&"requestIdleCallback"in window){window.requestIdleCallback(i,{timeout:o});return}setTimeout(i,Math.min(o,300))}function fe(){if(typeof window>"u")return!1;let i=typeof navigator<"u"?navigator.userAgent:"";if(/Android|iPhone|iPad|iPod|IEMobile|Windows Phone|Mobile/i.test(i))return!0;let c=window.matchMedia("(pointer: coarse)").matches,a=window.matchMedia("(hover: none)").matches,p=Math.min(window.screen?.width||window.innerWidth,window.screen?.height||window.innerHeight);return c&&a&&p<=900}function We(i){let{slug:o,locale:c=rt(),baseUrl:a=Ze,token:p,zIndex:w=9999,autoIdentify:y=!0}=i,r=document,n=r.createElement("iframe"),x=`${a}/t/${o}/widget`,l=new URLSearchParams({locale:c});p&&l.set("token",p),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 g=new URL(n.src).origin,u=r.createElement("div");if(u.setAttribute("role","button"),u.setAttribute("aria-label","Chat"),u.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;`,u.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>',u.onmouseenter=()=>{u.style.transform="scale(1.1)"},u.onmouseleave=()=>{u.style.transform="scale(1)"},u.onclick=()=>Z(),r.body.appendChild(u),!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 d=null,$=!1,S=!1,U=!1,O=!1,H=!1,R=()=>{U||(U=!0,r.body.appendChild(n))},N=!1,q=0,T={overflow:"",overscrollBehavior:""},v={overflow:"",overscrollBehavior:"",position:"",top:"",left:"",right:"",width:""},pe=()=>{if(N||!fe())return;let s=r.documentElement,t=r.body;q=window.scrollY||window.pageYOffset||0,T.overflow=s.style.overflow,T.overscrollBehavior=s.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,s.style.overflow="hidden",s.style.overscrollBehavior="none",t.style.overflow="hidden",t.style.overscrollBehavior="none",t.style.position="fixed",t.style.top=`-${q}px`,t.style.left="0",t.style.right="0",t.style.width="100%",N=!0},F=()=>{if(!N)return;let e=r.documentElement,s=r.body;e.style.overflow=T.overflow,e.style.overscrollBehavior=T.overscrollBehavior,s.style.overflow=v.overflow,s.style.overscrollBehavior=v.overscrollBehavior,s.style.position=v.position,s.style.top=v.top,s.style.left=v.left,s.style.right=v.right,s.style.width=v.width,window.scrollTo(0,q),N=!1},ge=()=>{let e=fe();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",pe()):(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"},P=()=>{d&&(d.remove(),d=null)},G=()=>{},ee=()=>{},D=!1,C=new Map;function te(e,s){let t=C.get(e);if(t)for(let f of t)try{f(s)}catch{}}let ye=e=>{if(e.origin===g){if(e.data?.type==="bitpalm-widget-config"){S=!1,$=!0,n.style.display==="none"&&(n.style.display=""),e.data.primaryColor&&(u.style.background=e.data.primaryColor,u.style.boxShadow=e.data.chatShadow==="none"?"none":`0 0 15px ${e.data.primaryColor}50`);let s=e.data.chatButtonIconColor||"black";if(e.data.chatButtonIconSvg){u.innerHTML="";let t=r.createElement("span");t.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${s}`;let b=new DOMParser().parseFromString(e.data.chatButtonIconSvg,"image/svg+xml").querySelector("svg");b?(b.querySelectorAll("script,foreignObject").forEach(M=>M.remove()),b.querySelectorAll("*").forEach(M=>{for(let k of[...M.attributes])(k.name.startsWith("on")||k.value&&k.value.includes("javascript:"))&&M.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>',u.appendChild(t)}else{let t=u.querySelector("svg");t&&(t.style.stroke=s)}u.style.display="flex",requestAnimationFrame(()=>{u.style.opacity="1"})}if(e.data?.type==="bitpalm-widget-resize"){let s=e.data.width>0,t=D;D=s,s&&!t&&te("widget_opened"),!s&&t&&te("widget_closed");let f=fe();s?(n.style.width=f?"100vw":`${e.data.width}px`,n.style.height=f?"100dvh":`${e.data.height}px`,f?(n.style.left="0",n.style.top="0",n.style.bottom="0",n.style.right="0",pe()):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"),u.style.display=s?"none":"flex"}if(e.data?.type==="bitpalm-trigger-show"){if(S||!$)return;P(),d=r.createElement("div"),d.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 s=(e.data.message||"").replace(/</g,"<");d.innerHTML=`<p style="font-size:14px;color:#1f2937;margin:0;">${s}</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=f=>{f.stopPropagation(),P(),n.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},d.onclick=()=>{if(P(),u.style.display="none",ge(),R(),!O){H=!0;return}n.contentWindow?.postMessage({type:"bitpalm-trigger-engaged",message:s},"*")},d.appendChild(t),r.body.appendChild(d)}e.data?.type==="bitpalm-trigger-hide"&&P(),e.data?.type==="bitpalm-request-context"&&G(),e.data?.type==="bitpalm-chat-event"&&e.data.event&&te(e.data.event,e.data.data),e.data?.type==="bitpalm-widget-blocked"&&(S=!0,$=!1,u.style.display="none",P(),F(),n.style.display="none")}};window.addEventListener("message",ye);let I=!1;try{I=localStorage.getItem(`${h}optout`)==="1"}catch{}let V=`${h}vid`,E="";if(!I){try{E=localStorage.getItem(V)||""}catch{}if(!E){let e=r.cookie.match(new RegExp(`(?:^|; )${V}=([^;]+)`));E=e?decodeURIComponent(e[1]):""}E||(E=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(V,E)}catch{}try{r.cookie=`${V}=${encodeURIComponent(E)};path=/;max-age=31536000;SameSite=Lax`}catch{}}I||ue(()=>{try{let e=new URLSearchParams(location.search),s={};for(let L of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let b=e.get(L);b&&(s[L]=b)}let t=JSON.stringify({tenant_slug:o,visitor_id:E,url:location.href,referrer:r.referrer||void 0,...Object.keys(s).length>0?{utm:s}:{}}),f=`${a}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(f,new Blob([t],{type:"application/json"})):fetch(f,{method:"POST",body:t,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}},2e3);let ne="",oe="",ie=0;try{ne=sessionStorage.getItem(Re)||"",oe=sessionStorage.getItem(Ne)||"";let e=parseInt(sessionStorage.getItem(Fe)||"0",10);Number.isFinite(e)&&e>0&&(ie=e)}catch{}let he=(e,s="")=>{if(I||!E)return;let t={},f=m(e.name,140),L=De(e.email),b=_(e.phone),M=m(e.company,160),k=m(e.external_user_id,140),ke=m(e.signature,260),le=Number(e.signed_at);if(f&&(t.name=f),L&&(t.email=L),b&&(t.phone=b),M&&(t.company=M),k&&(t.external_user_id=k),ke&&(t.signature=ke),Number.isFinite(le)&&le>0&&(t.signed_at=Math.floor(le)),(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 Q=tt(t),ce=[s.toLowerCase(),Q].filter(Boolean).join("|"),de=Date.now();if(!(de-ie<et&&(ce===ne||Q===oe))){ne=ce,oe=Q,ie=de;try{sessionStorage.setItem(Re,ce),sessionStorage.setItem(Ne,Q),sessionStorage.setItem(Fe,String(de))}catch{}try{let $e=JSON.stringify({tenant_slug:o,visitor_id:E,url:location.href,referrer:r.referrer||void 0,...t}),Oe=`${a}/api/widget/identify`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(Oe,new Blob([$e],{type:"application/json"})):fetch(Oe,{method:"POST",body:$e,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}}},be=e=>{if(I||!y||!E)return;let s=e.target instanceof HTMLFormElement?e.target:e.target instanceof Element?e.target.closest("form"):null;if(!(s instanceof HTMLFormElement))return;let t=(s.getAttribute("data-bp-identify")||s.getAttribute("data-bitpalm-identify")||"").toLowerCase();if(t==="off"||t==="false"||t==="0")return;let f=at(s);if(!f)return;let L=[s.getAttribute("id")||"",s.getAttribute("name")||"",s.getAttribute("action")||""].join("|");he({...f,identify_source:"form"},L)};!I&&y&&r.addEventListener("submit",be,!0);let z=parseInt(sessionStorage.getItem(`${h}pages`)||"0")+1;sessionStorage.setItem(`${h}pages`,String(z));let B=JSON.parse(sessionStorage.getItem(`${h}hist`)||"[]");B.push(location.href),B.length>20&&(B=B.slice(-20)),sessionStorage.setItem(`${h}hist`,JSON.stringify(B));let we=Date.now(),K=parseInt(sessionStorage.getItem(`${h}site_start`)||"0");K||(K=we,sessionStorage.setItem(`${h}site_start`,String(K)));let ve=[];G=()=>{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:z,pageHistory:B,loadedAt:we,siteStart:K,locale:c,visitorId:I?"":E},"*"),!e&&!I)try{localStorage.setItem(`${h}visited`,"1")}catch{}},n.addEventListener("load",()=>{O=!0,G(),[120,450,1100].forEach(e=>{let s=setTimeout(()=>G(),e);ve.push(s)}),H&&(H=!1,ee())}),r.readyState==="loading"?r.addEventListener("DOMContentLoaded",()=>ue(R,1600),{once:!0}):ue(R,1600);let xe=history.pushState.bind(history),Ee=history.replaceState.bind(history),X=()=>{z++,sessionStorage.setItem(`${h}pages`,String(z));let e=JSON.parse(sessionStorage.getItem(`${h}hist`)||"[]");if(e.push(location.href),e.length>20&&e.splice(0,e.length-20),B=e,sessionStorage.setItem(`${h}hist`,JSON.stringify(e)),n.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:r.title,pageCount:z,pageHistory:e,loadedAt:Date.now()},"*"),!I)try{let s=JSON.stringify({tenant_slug:o,visitor_id:E,url:location.href}),t=`${a}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(t,new Blob([s],{type:"application/json"})):fetch(t,{method:"POST",body:s,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...e){xe(...e),X()},history.replaceState=function(...e){Ee(...e),X()},window.addEventListener("popstate",X);let Se=-1,se,Te=()=>{clearTimeout(se),se=setTimeout(()=>{let e=Math.max(r.documentElement.scrollHeight,r.body.scrollHeight)-window.innerHeight,s=e>0?Math.round(window.scrollY/e*100):100;s!==Se&&(Se=s,n.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:s},"*"))},500)};window.addEventListener("scroll",Te,{passive:!0});let Ie=e=>{e.clientY<=0&&n.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};r.addEventListener("mouseout",Ie);let ae,Le=!1,re=()=>{clearTimeout(ae),!Le&&(ae=setTimeout(()=>{Le=!0,n.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},_e=["mousemove","keydown","scroll","touchstart"];_e.forEach(e=>r.addEventListener(e,re,{passive:!0})),re(),ee=()=>{n.contentWindow?.postMessage({type:"bitpalm-open"},"*");let e=n.src.split("#")[0];n.src=`${e}#bp-open-${Date.now()}`};let Z=()=>{if(u.style.display="none",P(),ge(),R(),!O){H=!0;return}ee()},Ae=()=>{F(),n.contentWindow?.postMessage({type:"bitpalm-close"},"*")},Pe=e=>{!e||typeof e!="object"||he({external_user_id:m(e.externalUserId,140)||void 0,name:m(e.name,140)||void 0,email:De(e.email)||void 0,phone:_(e.phone)||void 0,company:m(e.company,160)||void 0,signature:m(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")},je=()=>{D?Ae():Z()},Ue=()=>D,qe=e=>{if(!e||typeof e!="string")return;let s=e.trim().slice(0,1e4);s&&(D||Z(),setTimeout(()=>{n.contentWindow?.postMessage({type:"bitpalm-send-message",message:s},"*")},D?50:500))},Y={},Ce=e=>{if(!e||typeof e!="object"||Array.isArray(e))return;Y={...Y,...e};let s=JSON.stringify(Y);s.length>He&&console.warn(`[BitPalm] Custom context exceeds ${He} bytes (${s.length}). It may be truncated.`),n.contentWindow?.postMessage({type:"bitpalm-custom-context",data:Y},"*")},ze=()=>{Y={},n.contentWindow?.postMessage({type:"bitpalm-custom-context",data:{}},"*")},Be=e=>{let t=e.detail;if(!t||typeof t!="object")return;let f=m(t.slug,120);if(f&&f!==o)return;let{slug:L,...b}=t;Ce(b)};window.addEventListener("bitpalm-context",Be);let Me=e=>{let t=e.detail;if(!t||typeof t!="object")return;let f=m(t.slug,120);f&&f!==o||Pe(t)};return window.addEventListener("bitpalm-identify",Me),{open:Z,close:Ae,toggle:je,isOpen:Ue,identify:Pe,context:Ce,resetContext:ze,send:qe,on:(e,s)=>(C.has(e)||C.set(e,new Set),C.get(e).add(s),()=>C.get(e)?.delete(s)),off:(e,s)=>{C.get(e)?.delete(s)},destroy:()=>{window.removeEventListener("message",ye),window.removeEventListener("scroll",Te),window.removeEventListener("popstate",X),r.removeEventListener("mouseout",Ie),r.removeEventListener("submit",be,!0),_e.forEach(e=>r.removeEventListener(e,re)),clearTimeout(se),clearTimeout(ae),ve.forEach(e=>clearTimeout(e)),history.pushState=xe,history.replaceState=Ee,window.removeEventListener("bitpalm-identify",Me),window.removeEventListener("bitpalm-context",Be),C.clear(),F(),P(),u.remove(),n.remove()}}}function lt(i){let o=(0,J.useRef)(null),c=(0,J.useRef)(!1);return(0,J.useEffect)(()=>{if(!c.current)return c.current=!0,o.current=We(i),()=>{o.current?.destroy(),o.current=null,c.current=!1}},[]),null}0&&(module.exports={BitPalmAgent});
|
|
1
|
+
"use strict";var xe=Object.defineProperty;var xt=Object.getOwnPropertyDescriptor;var St=Object.getOwnPropertyNames;var Lt=Object.prototype.hasOwnProperty;var At=(n,t)=>{for(var a in t)xe(n,a,{get:t[a],enumerable:!0})},It=(n,t,a,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let d of St(t))!Lt.call(n,d)&&d!==a&&xe(n,d,{get:()=>t[d],enumerable:!(r=xt(t,d))||r.enumerable});return n};var _t=n=>It(xe({},"__esModule",{value:!0}),n);var jt={};At(jt,{BitPalmAgent:()=>Ut});module.exports=_t(jt);var F=require("react");function st(n){if(n===!1)return"off";if(typeof n=="string"){let t=n.trim().toLowerCase();if(["false","off","0","no","none"].includes(t))return"off";if(t==="events")return"events"}return"bubble"}function rt(n,t){let a=n.createElement("div");a.setAttribute("data-bitpalm-trigger",""),a.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:${t.zIndex-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`,a.style.position="fixed",a.style.right="24px",a.style.bottom=`${t.bottom}px`;let r=n.createElement("p");r.style.cssText="font-size:14px;color:#1f2937;margin:0;",r.textContent=t.message;let d=n.createElement("div");d.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=n.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(),t.onDismiss()},a.onclick=()=>t.onEngage(),a.append(r,d,u),a}var Mt=["dark","dark-mode","dark-theme","theme-dark"],Ct=["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 ae(n){return n==="light"||n==="dark"?n:"auto"}function at(n){if(!n)return null;if(Mt.some(t=>n.classList.contains(t)))return"dark";if(Ct.some(t=>n.classList.contains(t)))return"light";for(let t of ct){let a=(n.getAttribute(t)||"").toLowerCase();if(a.includes("dark"))return"dark";if(a.includes("light"))return"light"}return null}function Se(n){let t=n/255;return t<=.03928?t/12.92:((t+.055)/1.055)**2.4}function lt(n,t){if(!n)return null;let a=t.getComputedStyle(n).backgroundColor.match(/rgba?\(([^)]+)\)/);if(!a)return null;let[r,d,u,g=1]=a[1].split(/[\s,/]+/).filter(Boolean).map(Number);return[r,d,u,g].some(l=>Number.isNaN(l))||g<.5?null:.2126*Se(r)+.7152*Se(d)+.0722*Se(u)<.2?"dark":"light"}function Pt(n,t){let a=t.getComputedStyle(n.documentElement).colorScheme||"",r=n.querySelector('meta[name="color-scheme"]')?.getAttribute("content")||"",d=`${a} ${r}`.toLowerCase();return d.includes("dark")?d.includes("light")?t.matchMedia?.(dt).matches?"dark":"light":"dark":null}function G(n=document,t=window){return at(n.documentElement)??at(n.body)??lt(n.body,t)??lt(n.documentElement,t)??Pt(n,t)??"light"}function Le(n,t=document,a=window){let r=G(t,a),d=!1,u=()=>{d=!1;let c=G(t,a);c!==r&&(r=c,n(c))},g=()=>{d||(d=!0,typeof a.requestAnimationFrame=="function"?a.requestAnimationFrame(u):setTimeout(u,16))},T=typeof MutationObserver<"u"?new MutationObserver(g):null,l={attributes:!0,attributeFilter:["class","style",...ct]};T?.observe(t.documentElement,l),t.body&&T?.observe(t.body,l);let h=typeof a.matchMedia=="function"?a.matchMedia(dt):null;return h?.addEventListener?.("change",g),()=>{T?.disconnect(),h?.removeEventListener?.("change",g)}}var Bt="https://agents.bitpalm.ai",v="_bp_",kt=new Set(["password","file","checkbox","radio","submit","button","reset","image"]),Ht=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 $t(n){return[n.external_user_id||"",n.email||"",n.phone||"",n.name||"",n.company||"",n.signature||"",n.signed_at!=null?String(n.signed_at):"",n.signature_version||"",n.identify_source||""].join("|").toLowerCase()}function m(n,t=180){return n?n.replace(/\s+/g," ").trim().slice(0,t):""}function Ot(n){return n?` ${n.toLowerCase().replace(/[_-]+/g," ").replace(/[^a-z0-9\s@.]/g," ").replace(/\s+/g," ").trim()} `:""}function N(n,t){for(let a of t)if(n.includes(a))return!0;return!1}function C(n){return/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i.test(n)}function I(n){let t=m(n,50);if(!t)return"";let a=t.startsWith("+"),r=t.replace(/\D/g,"");return r.length<6?"":`${a?"+":""}${r.slice(0,20)}`}function ht(n){let t=m(n,140).toLowerCase();return!t||!C(t)?"":t}function W(n,t){for(let a of t){let r=n.querySelector(a),d=m(r?.value);if(d)return d}return""}function Rt(n){return m(n.getAttribute("data-bp-field")||n.getAttribute("data-bitpalm-field"),64).toLowerCase().replace(/[_\s]+/g,"-")}function Dt(n){return n.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Nt(n,t){let a=[],r=(l,h=140)=>{let c=m(l,h);c&&a.push(c)};r(t.name),r(t.id),r(t.getAttribute("autocomplete")),r(t.getAttribute("placeholder")),r(t.getAttribute("aria-label")),r(t.getAttribute("data-field")),r(t.getAttribute("data-name")),r(t.getAttribute("data-label")),r(t.getAttribute("data-bp-field")),r(t.getAttribute("data-bitpalm-field"));let d=new Set,u=l=>{let h=m(l,200);!h||d.has(h)||(d.add(h),a.push(h))};for(let l of Array.from(t.labels||[]))u(l.textContent);if(t.id){let l=n.querySelector(`label[for="${Dt(t.id)}"]`);u(l?.textContent)}let g=t.closest("label");u(g?.textContent);let T=t.getAttribute("aria-labelledby");if(T)for(let l of T.split(/\s+/)){if(!l)continue;let h=n.ownerDocument.getElementById(l);u(h?.textContent)}return a}function Wt(n){let t=m(W(n,["[data-bp-email]","[data-bitpalm-email]"]),140).toLowerCase(),a=I(W(n,["[data-bp-phone]","[data-bitpalm-phone]"])),r=m(W(n,["[data-bp-name]","[data-bitpalm-name]","[data-bp-full-name]","[data-bitpalm-full-name]"])),d=m(W(n,["[data-bp-first-name]","[data-bitpalm-first-name]"])),u=m(W(n,["[data-bp-last-name]","[data-bitpalm-last-name]"])),g=m(W(n,["[data-bp-company]","[data-bitpalm-company]"]));for(let c of Array.from(n.elements)){if(!(c instanceof HTMLInputElement||c instanceof HTMLTextAreaElement||c instanceof HTMLSelectElement)||c.disabled||c instanceof HTMLInputElement&&kt.has(c.type.toLowerCase()))continue;let y=Rt(c),U=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"&&!U)continue;let f=m(c.value);if(!f)continue;let _=c instanceof HTMLInputElement?c.type.toLowerCase():"",s=Ot(Nt(n,c).join(" "));if(!t&&y==="email"&&C(f)){t=f.toLowerCase();continue}if(!a&&(y==="phone"||y==="tel"||y==="mobile"||y==="whatsapp")){let S=I(f);if(S){a=S;continue}}if(!g&&y==="company"){g=m(f,160);continue}if(!d&&(y==="first-name"||y==="firstname")){d=m(f,100);continue}if(!u&&(y==="last-name"||y==="lastname"||y==="surname")){u=m(f,100);continue}if(!r&&(y==="name"||y==="full-name"||y==="fullname")){!C(f)&&!I(f)&&(r=m(f,140));continue}let K=_==="email"||N(s,[" email "," e mail "," mail "," email adresse "," mailadresse "," correo "]),O=_==="tel"||N(s,[" phone "," phone number "," mobile "," tel "," telefon "," telefonnummer "," whatsapp "," handy "," kontakt "," nummer "]),le=N(s,[" company "," company name "," firma "," firmenname "," organization "," organisation "," business "," unternehmen "," agency "," brokerage "]),p=N(s,[" first name "," firstname "," given name "," givenname "," vorname "," fname "]),P=N(s,[" last name "," lastname "," family name "," familyname "," surname "," nachname "," lname "]),j=N(s,[" full name "," fullname "," contact name "," name "])&&!K&&!O;if(!t&&K&&C(f)){t=f.toLowerCase();continue}if(!a&&O){let S=I(f);if(S){a=S;continue}}if(!g&&le){g=m(f,160);continue}if(!d&&p){d=m(f,100);continue}if(!u&&P){u=m(f,100);continue}if(!r&&j&&!C(f)&&!I(f)){r=m(f,140);continue}!t&&C(f)&&(t=f.toLowerCase())}if(r&&(C(r)||I(r))&&(r=""),g&&(C(g)||I(g))&&(g=""),r||(r=m([d,u].filter(Boolean).join(" "),140)),r&&t&&r.toLowerCase()===t.toLowerCase()&&(r=""),!!!(t||a)&&!!!(r&&g))return null;let h={...r?{name:r}:{},...t?{email:t}:{},...a?{phone:a}:{},...g?{company:g}:{}};return Object.keys(h).length>0?h:null}function Ft(){if(typeof document<"u"){let n=document.documentElement.lang;if(n)return n.slice(0,2).toLowerCase()}return"en"}function Ae(n,t=1200){if(typeof window<"u"&&"requestIdleCallback"in window){window.requestIdleCallback(n,{timeout:t});return}setTimeout(n,Math.min(t,300))}function Ie(){if(typeof window>"u")return!1;let n=typeof navigator<"u"?navigator.userAgent:"";if(/Android|iPhone|iPad|iPod|IEMobile|Windows Phone|Mobile/i.test(n))return!0;let a=window.matchMedia("(pointer: coarse)").matches,r=window.matchMedia("(hover: none)").matches,d=Math.min(window.screen?.width||window.innerWidth,window.screen?.height||window.innerHeight);return a&&r&&d<=900}function yt(n){let{slug:t,locale:a=Ft(),baseUrl:r=Bt,token:d,zIndex:u=9999,autoIdentify:g=!0,launcher:T=!0}=n,l=document,h=ae(n.theme),c=h==="auto"?G():h,y=null,U=st(n.triggers),f=U,_=null,s=l.createElement("iframe");s.setAttribute("data-bitpalm-chat","");let K=`${r}/t/${t}/widget`,O=new URLSearchParams({locale:a,theme:c});d&&O.set("token",d),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=l.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=()=>Y(),T&&l.body.appendChild(p),!l.getElementById("_bp_fade")){let e=l.createElement("style");e.id="_bp_fade",e.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",l.head.appendChild(e)}let P=null,j=!1,S=!1,_e=!1,ce=!1,V=!1,X=()=>{_e||(_e=!0,l.body.appendChild(s))},Z=!1,de=0,Q={overflow:"",overscrollBehavior:""},E={overflow:"",overscrollBehavior:"",position:"",top:"",left:"",right:"",width:""},Me=()=>{if(Z||!Ie())return;let o=l.documentElement,i=l.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},R=()=>{if(!Z)return;let e=l.documentElement,o=l.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},Ce=()=>{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",Me()):(s.style.width="420px",s.style.height="620px",s.style.bottom="24px",s.style.right="24px",s.style.left="",s.style.top="",R()),s.style.opacity="1",s.style.pointerEvents="auto"},M=()=>{P&&(P.remove(),P=null)},ee=()=>{_!==null&&(_=null,z("trigger_hidden"))},Pe=()=>{s.contentWindow?.postMessage({type:"bitpalm-triggers",enabled:f!=="off"},"*")},te=()=>{},me=()=>{},D=!1,B=new Map;function z(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=l.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"})),Pe()}if(e.data?.type==="bitpalm-widget-resize"){let o=e.data.width>0,i=D;D=o,o&&!i&&z("widget_opened"),!o&&i&&z("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",Me()):R(),s.style.opacity="1",s.style.pointerEvents="auto"):(R(),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"){_=o,z("trigger_shown",{message:o,triggerId:e.data.triggerId,triggerType:e.data.triggerType});return}M(),P=rt(l,{message:o,zIndex:u,bottom:T?90:24,onDismiss:()=>{M(),s.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},onEngage:()=>{if(M(),p.style.display="none",Ce(),X(),!ce){V=!0;return}s.contentWindow?.postMessage({type:"bitpalm-trigger-engaged",message:o},"*")}}),l.body.appendChild(P)}e.data?.type==="bitpalm-trigger-hide"&&(M(),ee()),e.data?.type==="bitpalm-request-context"&&te(),e.data?.type==="bitpalm-chat-event"&&e.data.event&&z(e.data.event,e.data.data),e.data?.type==="bitpalm-widget-blocked"&&(S=!0,j=!1,p.style.display="none",M(),ee(),R(),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=l.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{l.cookie=`${ne}=${encodeURIComponent(x)};path=/;max-age=31536000;SameSite=Lax`}catch{}}L||Ae(()=>{try{let e=new URLSearchParams(location.search),o={};for(let A of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let w=e.get(A);w&&(o[A]=w)}let i=JSON.stringify({tenant_slug:t,visitor_id:x,url:location.href,referrer:l.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 ke=(e,o="")=>{if(L||!x)return;let i={},b=m(e.name,140),A=ht(e.email),w=I(e.phone),H=m(e.company,160),$=m(e.external_user_id,140),nt=m(e.signature,260),we=Number(e.signed_at);if(b&&(i.name=b),A&&(i.email=A),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=$t(i),Ee=[o.toLowerCase(),re].filter(Boolean).join("|"),Te=Date.now();if(!(Te-ge<Ht&&(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:t,visitor_id:x,url:location.href,referrer:l.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=Wt(o);if(!b)return;let A=[o.getAttribute("id")||"",o.getAttribute("name")||"",o.getAttribute("action")||""].join("|");ke({...b,identify_source:"form"},A)};!L&&g&&l.addEventListener("submit",He,!0);let q=parseInt(sessionStorage.getItem(`${v}pages`)||"0")+1;sessionStorage.setItem(`${v}pages`,String(q));let k=JSON.parse(sessionStorage.getItem(`${v}hist`)||"[]");k.push(location.href),k.length>20&&(k=k.slice(-20)),sessionStorage.setItem(`${v}hist`,JSON.stringify(k));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:l.title,returning:e,pageCount:q,pageHistory:k,loadedAt:$e,siteStart:oe,locale:a,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())}),l.readyState==="loading"?l.addEventListener("DOMContentLoaded",()=>Ae(X,1600),{once:!0}):Ae(X,1600);let Re=history.pushState.bind(history),De=history.replaceState.bind(history),ie=()=>{q++,sessionStorage.setItem(`${v}pages`,String(q));let e=JSON.parse(sessionStorage.getItem(`${v}hist`)||"[]");if(e.push(location.href),e.length>20&&e.splice(0,e.length-20),k=e,sessionStorage.setItem(`${v}hist`,JSON.stringify(e)),s.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:l.title,pageCount:q,pageHistory:e,loadedAt:Date.now()},"*"),!L)try{let o=JSON.stringify({tenant_slug:t,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){Re(...e),ie()},history.replaceState=function(...e){De(...e),ie()},window.addEventListener("popstate",ie);let Ne=-1,pe,We=()=>{clearTimeout(pe),pe=setTimeout(()=>{let e=Math.max(l.documentElement.scrollHeight,l.body.scrollHeight)-window.innerHeight,o=e>0?Math.round(window.scrollY/e*100):100;o!==Ne&&(Ne=o,s.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:o},"*"))},500)};window.addEventListener("scroll",We,{passive:!0});let Fe=e=>{e.clientY<=0&&s.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};l.addEventListener("mouseout",Fe);let he,Ue=!1,ye=()=>{clearTimeout(he),!Ue&&(he=setTimeout(()=>{Ue=!0,s.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},je=["mousemove","keydown","scroll","touchstart"];je.forEach(e=>l.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 Y=()=>{if(p.style.display="none",M(),Ce(),X(),!ce){V=!0;return}if(_!==null){let e=_;ee(),s.contentWindow?.postMessage({type:"bitpalm-trigger-engaged",message:e},"*");return}me()},ze=e=>{f=e,e==="off"&&(M(),ee()),Pe()},bt=()=>ze("off"),vt=()=>ze(U==="off"?"bubble":U),be=()=>{R(),s.contentWindow?.postMessage({type:"bitpalm-close"},"*")},qe=e=>{!e||typeof e!="object"||ke({external_user_id:m(e.externalUserId,140)||void 0,name:m(e.name,140)||void 0,email:ht(e.email)||void 0,phone:I(e.phone)||void 0,company:m(e.company,160)||void 0,signature:m(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=()=>{D?be():Y()},Et=()=>D,Ye=e=>{if(!e||typeof e!="string")return;let o=e.trim().slice(0,1e4);o&&(D||Y(),setTimeout(()=>{s.contentWindow?.postMessage({type:"bitpalm-send-message",message:o},"*")},D?50:500))};function Je(){s.contentWindow?.postMessage({type:"bitpalm-theme",theme:c},"*")}let se=e=>{e!==c&&(c=e,Je())},Ge=e=>{h=ae(e),y?.(),y=null,h==="auto"?(y=Le(se),se(G())):se(h)};h==="auto"&&(y=Le(se));let Ke=e=>{let o=e.detail;if(!o||typeof o!="object")return;let i=m(o.slug,120);i&&i!==t||Ge(ae(o.theme))};window.addEventListener("bitpalm-theme",Ke);let J={},Ve=e=>{if(!e||typeof e!="object"||Array.isArray(e))return;J={...J,...e};let o=JSON.stringify(J);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:J},"*")},Tt=()=>{J={},s.contentWindow?.postMessage({type:"bitpalm-custom-context",data:{}},"*")},Xe=e=>{let i=e.detail;if(!i||typeof i!="object")return;let b=m(i.slug,120);if(b&&b!==t)return;let{slug:A,...w}=i;Ve(w)};window.addEventListener("bitpalm-context",Xe);let Ze=e=>{let i=e.detail;if(!i||typeof i!="object")return;let b=m(i.slug,120);b&&b!==t||qe(i)};window.addEventListener("bitpalm-identify",Ze);let ve=e=>{let o=e.detail,i=m(o?.slug,120);return!i||i===t},Qe=e=>{ve(e)&&Y()},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:Y,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",We),window.removeEventListener("popstate",ie),l.removeEventListener("mouseout",Fe),l.removeEventListener("submit",He,!0),je.forEach(e=>l.removeEventListener(e,ye)),clearTimeout(pe),clearTimeout(he),Oe.forEach(e=>clearTimeout(e)),history.pushState=Re,history.replaceState=De,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(),R(),M(),p.remove(),s.remove()}}}function Ut(n){let t=(0,F.useRef)(null),a=(0,F.useRef)(!1);return(0,F.useEffect)(()=>{t.current?.setTheme(n.theme??"auto")},[n.theme]),(0,F.useEffect)(()=>{if(a.current)return;a.current=!0;let{onReady:r,...d}=n;return t.current=yt(d),r?.(t.current),()=>{t.current?.destroy(),t.current=null,a.current=!1}},[]),null}0&&(module.exports={BitPalmAgent});
|
|
2
2
|
//# sourceMappingURL=react.cjs.map
|
package/dist/react.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react.ts","../src/widget.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { createWidget } from \"./widget\";\nimport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type BitPalmAgentProps = BitPalmAgentOptions;\n\n/**\n * React component that mounts the BitPalm AI agent widget.\n *\n * @example\n * ```tsx\n * import { BitPalmAgent } from '@bitpalm/ai-agents/react';\n *\n * export default function App() {\n * return <BitPalmAgent slug=\"my-agent\" />;\n * }\n * ```\n */\nexport function BitPalmAgent(props: BitPalmAgentProps): null {\n const instanceRef = useRef<BitPalmAgentInstance | null>(null);\n const mountedRef = useRef(false);\n\n useEffect(() => {\n if (mountedRef.current) return;\n mountedRef.current = true;\n\n instanceRef.current = createWidget(props);\n\n return () => {\n instanceRef.current?.destroy();\n instanceRef.current = null;\n mountedRef.current = false;\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n return null;\n}\n","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"],"mappings":"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","names":["react_exports","__export","BitPalmAgent","__toCommonJS","import_react","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","BitPalmAgent","props","instanceRef","mountedRef","createWidget"]}
|
|
1
|
+
{"version":3,"sources":["../src/react.ts","../src/triggers.ts","../src/theme.ts","../src/widget.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { createWidget } from \"./widget\";\nimport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport interface BitPalmAgentProps extends BitPalmAgentOptions {\n /**\n * Called once with the widget, for open(), on('trigger_shown', …) and\n * the rest of the API. Needed with launcher={false} and a button of\n * your own.\n */\n onReady?: (widget: BitPalmAgentInstance) => void;\n}\n\n/**\n * React component that mounts the BitPalm AI agent widget.\n *\n * @example\n * ```tsx\n * import { BitPalmAgent } from '@bitpalm/ai-agents/react';\n *\n * export default function App() {\n * return <BitPalmAgent slug=\"my-agent\" />;\n * }\n * ```\n */\nexport function BitPalmAgent(props: BitPalmAgentProps): null {\n const instanceRef = useRef<BitPalmAgentInstance | null>(null);\n const mountedRef = useRef(false);\n\n // The widget mounts once, later theme prop changes go through setTheme.\n useEffect(() => {\n instanceRef.current?.setTheme(props.theme ?? \"auto\");\n }, [props.theme]);\n\n useEffect(() => {\n if (mountedRef.current) return;\n mountedRef.current = true;\n\n const { onReady, ...options } = props;\n instanceRef.current = createWidget(options);\n onReady?.(instanceRef.current);\n\n return () => {\n instanceRef.current?.destroy();\n instanceRef.current = null;\n mountedRef.current = false;\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n return null;\n}\n","/*\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"],"mappings":"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","names":["react_exports","__export","BitPalmAgent","__toCommonJS","import_react","parseTriggerMode","value","normalized","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","BitPalmAgent","props","instanceRef","mountedRef","onReady","options","createWidget"]}
|