@bitpalm/ai-agents 0.1.13 → 0.1.15

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/widget.ts"],"sourcesContent":["export { createWidget } from \"./widget\";\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nimport { createWidget } from \"./widget\";\n\nfunction parseBoolean(value: string | undefined): boolean | undefined {\n if (value == null) return undefined;\n const normalized = value.trim().toLowerCase();\n if ([\"1\", \"true\", \"yes\", \"on\"].includes(normalized)) return true;\n if ([\"0\", \"false\", \"no\", \"off\"].includes(normalized)) return false;\n return undefined;\n}\n\n/**\n * Auto-init from script tag:\n * <script src=\"https://cdn.bitpalm.ae/widget.js\" data-slug=\"my-agent\"></script>\n */\nif (typeof document !== \"undefined\") {\n const script = document.currentScript as HTMLScriptElement | null;\n if (script?.dataset.slug) {\n const init = () => {\n createWidget({\n slug: script!.dataset.slug!,\n locale: script!.dataset.locale,\n baseUrl: script!.dataset.baseUrl,\n token: script!.dataset.token,\n zIndex: script!.dataset.zIndex ? Number(script!.dataset.zIndex) : undefined,\n autoIdentify: parseBoolean(script!.dataset.autoIdentify),\n });\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init);\n } else {\n init();\n }\n }\n}\n","import type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ae\";\nconst STORAGE_PREFIX = \"_bp_\";\nconst IGNORED_INPUT_TYPES = new Set([\"password\", \"file\", \"checkbox\", \"radio\", \"submit\", \"button\", \"reset\", \"image\"]);\n\ntype IdentityPayload = {\n name?: string;\n email?: string;\n phone?: string;\n company?: string;\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): 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 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 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\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\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([\n rawEl.name,\n rawEl.id,\n rawEl.getAttribute(\"autocomplete\"),\n rawEl.getAttribute(\"placeholder\"),\n rawEl.getAttribute(\"aria-label\"),\n rawEl.getAttribute(\"data-field\"),\n rawEl.getAttribute(\"data-name\"),\n ].filter(Boolean).join(\" \"));\n\n const emailLike = type === \"email\" || includesAny(tokens, [\" email \", \" e mail \", \" mail \", \" correo \"]);\n const phoneLike = type === \"tel\" || includesAny(tokens, [\" phone \", \" mobile \", \" tel \", \" whatsapp \", \" handy \", \" telefon \", \" kontakt \"]);\n const companyLike = includesAny(tokens, [\" company \", \" firma \", \" organization \", \" organisation \", \" business \", \" unternehmen \", \" agency \", \" brokerage \"]);\n const firstNameLike = includesAny(tokens, [\" first name \", \" firstname \", \" given name \", \" given name \", \" givenname \", \" vorname \"]);\n const lastNameLike = includesAny(tokens, [\" last name \", \" lastname \", \" family name \", \" familyname \", \" surname \", \" nachname \"]);\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) && includesAny(tokens, [\" mail \", \" email \", \" e mail \"])) {\n email = value.toLowerCase();\n }\n }\n\n if (!name) {\n name = normalizeText([firstName, lastName].filter(Boolean).join(\" \"), 140);\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\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 iframe.allow = \"clipboard-write\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\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 d.body.appendChild(iframe);\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 const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\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 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 mobile = window.innerWidth <= 640;\n if (isOpen) {\n iframe.style.width = mobile ? `${window.innerWidth}px` : `${e.data.width}px`;\n iframe.style.height = mobile ? `${window.innerHeight}px` : `${e.data.height}px`;\n if (mobile) { iframe.style.left = \"0\"; iframe.style.top = \"0\"; }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\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 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, \"&lt;\");\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 = \"&#10005;\";\n close.onclick = (ev) => { ev.stopPropagation(); removeBubble(); iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-dismiss\" }, \"*\"); };\n bubble.onclick = () => { removeBubble(); btn.style.display = \"none\"; iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\" }, \"*\"); };\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 // Widget blocked (excluded path or access denied) — hide button & iframe\n if (e.data?.type === \"bitpalm-widget-blocked\") {\n btn.style.display = \"none\";\n removeBubble();\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 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 }\n\n // --- Auto-identify visitor from form submissions on host page ---\n let lastIdentitySignature = \"\";\n let lastIdentitySentAt = 0;\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 signature = [\n form.getAttribute(\"id\") || \"\",\n form.getAttribute(\"name\") || \"\",\n form.getAttribute(\"action\") || \"\",\n identity.email || \"\",\n identity.phone || \"\",\n identity.name || \"\",\n identity.company || \"\",\n ].join(\"|\").toLowerCase();\n\n const now = Date.now();\n if (signature === lastIdentitySignature && now - lastIdentitySentAt < 8000) return;\n lastIdentitySignature = signature;\n lastIdentitySentAt = now;\n\n try {\n const payload = JSON.stringify({\n tenant_slug: slug,\n visitor_id: visitorId,\n url: location.href,\n referrer: d.referrer || undefined,\n ...identity,\n });\n const identifyUrl = `${baseUrl}/api/widget/identify`;\n if (typeof navigator.sendBeacon === \"function\") {\n navigator.sendBeacon(identifyUrl, new Blob([payload], { type: \"application/json\" }));\n } else {\n fetch(identifyUrl, { method: \"POST\", body: payload, headers: { \"Content-Type\": \"application/json\" }, keepalive: true }).catch(() => {});\n }\n } catch {\n // ignore\n }\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 // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n const returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\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) localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\");\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 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 // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\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 const closeWidget = () => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\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 history.pushState = origPush;\n history.replaceState = origReplace;\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return { open: openWidget, close: closeWidget, destroy };\n}\n"],"mappings":"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","names":["src_exports","__export","createWidget","DEFAULT_BASE_URL","STORAGE_PREFIX","IGNORED_INPUT_TYPES","normalizeText","value","maxLen","normalizeTokens","includesAny","haystack","needles","needle","isEmail","normalizePhone","trimmed","hasPlus","digits","getExplicitValue","form","selectors","selector","el","extractIdentityFromForm","email","phone","name","firstName","lastName","company","rawEl","explicitField","type","tokens","emailLike","phoneLike","companyLike","firstNameLike","lastNameLike","fullNameLike","normalized","identity","detectLocale","lang","createWidget","options","slug","locale","baseUrl","token","zIndex","autoIdentify","d","iframe","widgetUrl","qs","origin","btn","openWidget","s","bubble","removeBubble","handleMessage","ic","sp","svg","attr","sv","isOpen","mobile","msg","close","ev","optedOut","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","lastIdentitySignature","lastIdentitySentAt","handleFormSubmit","event","formIdentifySetting","signature","now","payload","identifyUrl","pageCount","hist","loadedAt","siteStart","returning","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","base","parseBoolean","value","normalized","script","init","createWidget"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/widget.ts"],"sourcesContent":["export { createWidget } from \"./widget\";\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nimport { createWidget } from \"./widget\";\n\nfunction parseBoolean(value: string | undefined): boolean | undefined {\n if (value == null) return undefined;\n const normalized = value.trim().toLowerCase();\n if ([\"1\", \"true\", \"yes\", \"on\"].includes(normalized)) return true;\n if ([\"0\", \"false\", \"no\", \"off\"].includes(normalized)) return false;\n return undefined;\n}\n\n/**\n * Auto-init from script tag:\n * <script src=\"https://cdn.bitpalm.ae/widget.js\" data-slug=\"my-agent\"></script>\n */\nif (typeof document !== \"undefined\") {\n const script = document.currentScript as HTMLScriptElement | null;\n if (script?.dataset.slug) {\n const init = () => {\n createWidget({\n slug: script!.dataset.slug!,\n locale: script!.dataset.locale,\n baseUrl: script!.dataset.baseUrl,\n token: script!.dataset.token,\n zIndex: script!.dataset.zIndex ? Number(script!.dataset.zIndex) : undefined,\n autoIdentify: parseBoolean(script!.dataset.autoIdentify),\n });\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init);\n } else {\n init();\n }\n }\n}\n","import type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ae\";\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 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\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): 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 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\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 iframe.allow = \"clipboard-write\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\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 d.body.appendChild(iframe);\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 const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\n };\n let sendParentContext = () => {};\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 mobile = window.innerWidth <= 640;\n if (isOpen) {\n iframe.style.width = mobile ? `${window.innerWidth}px` : `${e.data.width}px`;\n iframe.style.height = mobile ? `${window.innerHeight}px` : `${e.data.height}px`;\n if (mobile) { iframe.style.left = \"0\"; iframe.style.top = \"0\"; }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\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, \"&lt;\");\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 = \"&#10005;\";\n close.onclick = (ev) => { ev.stopPropagation(); removeBubble(); iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-dismiss\" }, \"*\"); };\n bubble.onclick = () => { removeBubble(); btn.style.display = \"none\"; iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\" }, \"*\"); };\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 // 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 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 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 }\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 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 identityFingerprint = [\n identity.email || \"\",\n identity.phone || \"\",\n identity.name || \"\",\n identity.company || \"\",\n ].join(\"|\").toLowerCase();\n\n const signature = [\n form.getAttribute(\"id\") || \"\",\n form.getAttribute(\"name\") || \"\",\n form.getAttribute(\"action\") || \"\",\n identityFingerprint,\n ].join(\"|\").toLowerCase();\n\n const now = Date.now();\n const insideDedupWindow = now - lastIdentitySentAt < IDENTITY_DEDUPE_WINDOW_MS;\n if (insideDedupWindow && (signature === lastIdentitySignature || identityFingerprint === lastIdentityFingerprint)) {\n return;\n }\n\n lastIdentitySignature = signature;\n lastIdentityFingerprint = identityFingerprint;\n lastIdentitySentAt = now;\n try {\n sessionStorage.setItem(IDENTITY_SIGNATURE_KEY, signature);\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 payload = JSON.stringify({\n tenant_slug: slug,\n visitor_id: visitorId,\n url: location.href,\n referrer: d.referrer || undefined,\n ...identity,\n });\n const identifyUrl = `${baseUrl}/api/widget/identify`;\n if (typeof navigator.sendBeacon === \"function\") {\n navigator.sendBeacon(identifyUrl, new Blob([payload], { type: \"application/json\" }));\n } else {\n fetch(identifyUrl, { method: \"POST\", body: payload, headers: { \"Content-Type\": \"application/json\" }, keepalive: true }).catch(() => {});\n }\n } catch {\n // ignore\n }\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 sendParentContext();\n [120, 450, 1100].forEach((delay) => {\n const timer = setTimeout(() => sendParentContext(), delay);\n contextRetryTimers.push(timer);\n });\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 // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\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 const closeWidget = () => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\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 removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return { open: openWidget, close: closeWidget, destroy };\n}\n"],"mappings":"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","names":["src_exports","__export","createWidget","DEFAULT_BASE_URL","STORAGE_PREFIX","IGNORED_INPUT_TYPES","IDENTITY_DEDUPE_WINDOW_MS","IDENTITY_SIGNATURE_KEY","IDENTITY_FINGERPRINT_KEY","IDENTITY_SENT_AT_KEY","normalizeText","value","maxLen","normalizeTokens","includesAny","haystack","needles","needle","isEmail","normalizePhone","trimmed","hasPlus","digits","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","normalized","emailLike","phoneLike","companyLike","firstNameLike","lastNameLike","fullNameLike","identity","detectLocale","lang","createWidget","options","slug","locale","baseUrl","token","zIndex","autoIdentify","d","iframe","widgetUrl","qs","origin","btn","openWidget","s","bubble","launcherReady","widgetBlocked","removeBubble","sendParentContext","handleMessage","e","ic","sp","svg","attr","sv","isOpen","mobile","msg","close","ev","optedOut","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","lastIdentitySignature","lastIdentityFingerprint","lastIdentitySentAt","storedAt","handleFormSubmit","event","formIdentifySetting","identityFingerprint","signature","now","payload","identifyUrl","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","parseBoolean","value","normalized","script","init","createWidget"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitpalm/ai-agents",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Drop-in AI chat agent widget for any website. Includes visitor intelligence, SPA navigation tracking, trigger bubbles, and more.",
5
5
  "license": "MIT",
6
6
  "author": "BitPalm <agents@bitpalm.ae>",