@sentientui/core 0.21.3 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-2RH7I6AP.mjs +2 -0
- package/dist/chunk-2RH7I6AP.mjs.map +1 -0
- package/dist/{index-BcRtGYVH.d.ts → index-BbrtAtrY.d.ts} +11 -4
- package/dist/{index-D3_vlZ3z.d.cts → index-CXxvWxCB.d.cts} +11 -4
- package/dist/index-engagement.js +1 -1
- package/dist/index-engagement.js.map +1 -1
- package/dist/index-engagement.mjs +1 -1
- package/dist/index-engagement.mjs.map +1 -1
- package/dist/index-graph.d.cts +4 -4
- package/dist/index-graph.d.ts +4 -4
- package/dist/index-graph.js +1 -1
- package/dist/index-graph.js.map +1 -1
- package/dist/index-graph.mjs +1 -1
- package/dist/index-graph.mjs.map +1 -1
- package/dist/index-local.d.cts +1 -1
- package/dist/index-local.d.ts +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +2 -2
- package/dist/chunk-Q252FDO2.mjs +0 -2
- package/dist/chunk-Q252FDO2.mjs.map +0 -1
package/dist/index-graph.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as b,d as v}from"./chunk-CD2A55US.mjs";import{A as _,y as x}from"./chunk-Q252FDO2.mjs";import{a as T,b as N,c as A,j as L,k as U,l as j,m as K,n as z}from"./chunk-QNEYUJJJ.mjs";import{a as y,b as I}from"./chunk-TMCGHANO.mjs";var O="_snt_graph_edges",F={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function q(e){var t;return(t=F[e])!=null?t:[]}function B(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function H(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var J=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function V(e){return J.has(e)?e:"generic"}function M(e){try{let t=new URL(e);return`${t.origin}${t.pathname}`}catch(t){return"/"}}function Y(e,t,n){let i=`${e}:${t}:${n.join(",")}`,p=5381;for(let l=0;l<i.length;l++)p=(p<<5)+p+i.charCodeAt(l)&4294967295;return(p>>>0).toString(16).padStart(8,"0")}function R(e){let t=new Map,n=new Map,i=`_snt_graph_nodes${T(e==null?void 0:e.apiKey)}`,p=()=>{typeof window!="undefined"&&H(i,[...t.values()])},l=o=>{var a;try{let d=JSON.parse(o);t.clear();for(let c of(a=d.pageNodes)!=null?a:[])t.set(c.componentId,c)}catch(d){}};if(typeof window!="undefined"){let o=B(i,[]);for(let a of o)t.set(a.componentId,a);try{localStorage.removeItem(O)}catch(a){}}return{addPageNode(o){t.set(o.componentId,o),p()},addStructuralEdge(o){let a=`${o.fromComponentId}->${o.toComponentId}`;n.set(a,o)},syncOnce(){var a,d;if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let o=[...t.values()];if(o.length!==0)try{let c=new Map;for(let s of o){let f=(a=c.get(s.semanticType))!=null?a:[];f.push(s),c.set(s.semanticType,f)}let u=[],m=new Set;for(let s of o)for(let f of q(s.semanticType)){let S=(d=c.get(f))!=null?d:[];for(let h of S){if(h.componentId===s.componentId)continue;let w=`semantic:${s.componentId}->${h.componentId}`;m.has(w)||(m.add(w),u.push({fromComponentId:s.componentId,toComponentId:h.componentId,type:"semantic",weight:.4,confidence:.9}))}}let g=new Set(o.map(s=>s.componentId));for(let s of n.values()){if(!g.has(s.fromComponentId)||!g.has(s.toComponentId))continue;let f=`structural:${s.fromComponentId}->${s.toComponentId}`;m.has(f)||(m.add(f),u.push({fromComponentId:s.fromComponentId,toComponentId:s.toComponentId,type:"structural",weight:s.weight,confidence:1}))}let r=I(y(y({pageUrl:M(window.location.href)},e.sessionId?{sessionId:e.sessionId}:{}),e.projectId?{projectId:e.projectId}:{}),{nodes:o.map(s=>{let f=V(s.semanticType);return{componentId:s.componentId,semanticType:f,answers:s.answers,contentHash:Y(s.componentId,f,s.answers),prominenceScore:s.prominenceScore,depthInPage:s.depth}}),edges:u});fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:y({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(r)}).catch(()=>{})}catch(c){}},snapshot(){return{pageNodes:[...t.values()],capturedAt:Date.now()}},serialize(){return JSON.stringify({pageNodes:[...t.values()]})},restore:l,destroy(){if(typeof window!="undefined")try{localStorage.removeItem(i),localStorage.removeItem(O)}catch(o){}}}}var W=new Set(["SECTION","ARTICLE","MAIN","DIV"]),Q="h1, h2, h3",P=30,X=1500,Z={scan:async()=>({nodes:[],edges:[],scannedAt:0}),observe:()=>{},getProminenceScore:()=>0,destroy:()=>{}};function D(e,t,n){return n<=t?0:Math.max(0,Math.min(1,(e-t)/(n-t)))}function ee(e){var t,n,i;try{let p=e;for(let l of Object.keys(p)){if(!l.startsWith("__reactFiber")&&!l.startsWith("__reactInternalInstance"))continue;let o=p[l],a=(i=(t=o==null?void 0:o.type)==null?void 0:t.displayName)!=null?i:(n=o==null?void 0:o.type)==null?void 0:n.name;if(a&&a.length>1)return a}}catch(p){}}function te(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}var G=new Set(b);function ne(e){let t=e.getAttribute("data-sentient-type");if(t&&G.has(t))return t;let n=e.getAttribute("role");return n&&G.has(n)?n:v(e)}function oe(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n)&4294967295;return(t>>>0).toString(16).padStart(8,"0")}function re(e){let t=[],n=e;for(;n;){let i=n.parentElement;if(!i){t.push(n.tagName.toLowerCase());break}let p=Array.prototype.indexOf.call(i.children,n);t.push(`${n.tagName.toLowerCase()}[${p}]`),n=i}return t.reverse().join("/")}function se(e){var n;let t=(n=e.getAttribute("data-sentient-id"))!=null?n:e.getAttribute("id");return t||`${e.tagName.toLowerCase()}-${oe(re(e))}`}function ae(e){let t=0,n=e.parentElement;for(;n;)t++,n=n.parentElement;return t}function C(e,t){var i,p,l;let n=e.querySelector(Q);return{componentId:se(e),semanticType:ne(e),ariaLabel:(i=e.getAttribute("aria-label"))!=null?i:void 0,headingText:(l=(p=n==null?void 0:n.textContent)==null?void 0:p.trim())!=null?l:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:ae(e),reactComponentName:ee(e),dataAttributes:te(e)}}function $(e){var l;let t=[],n=new Set,i="__root__",p=new Map;for(let[o,a]of e){let d=o.parentElement,c=i;for(;d;){if(e.has(d)){c=e.get(d);let m=e.get(o),g=`${c}->${m}`;!n.has(g)&&c!==m&&(n.add(g),t.push({fromComponentId:c,toComponentId:m,weight:.6}));break}d=d.parentElement}let u=(l=p.get(c))!=null?l:[];u.push(o),p.set(c,u)}for(let o of p.values()){if(o.length<2)continue;let a=o.length>P?o.slice(0,P):o;for(let d=0;d<a.length;d++)for(let c=d+1;c<a.length;c++){if(t.length>=X)return t;let u=e.get(a[d]),m=e.get(a[c]);if(u===m)continue;let g=`${u}->${m}::sib`,r=`${m}->${u}::sib`;n.has(g)||(n.add(g),t.push({fromComponentId:u,toComponentId:m,weight:.3})),n.has(r)||(n.add(r),t.push({fromComponentId:m,toComponentId:u,weight:.3}))}}return t}function ie(e){let t=[],n=new Set,i=new Map;return document.querySelectorAll("[data-sentient-id]").forEach(o=>{if(o instanceof Element&&!n.has(o)){n.add(o);let a=C(o,e);t.push(a),i.set(o,a.componentId)}}),document.querySelectorAll("section, article, main, aside").forEach(o=>{if(!(o instanceof Element)||n.has(o))return;let a=o.hasAttribute("aria-label"),d=o.hasAttribute("data-sentient-id");if(!a&&!d)return;n.add(o);let c=C(o,e);t.push(c),i.set(o,c.componentId)}),{nodes:t,edges:$(i),elementToId:i}}function k(){if(typeof window=="undefined")return Z;let e=null,t=0,n=null,i=new Map,p=d=>{try{let c=window.getComputedStyle(d),u=parseFloat(c.fontSize)||12,m=parseFloat(c.zIndex)||0,g=d.getBoundingClientRect(),r=Math.max(g.top,0),s=window.innerHeight||1,f=1/(r/s+1),S=D(u,12,48)*.4+f*.4+D(m,0,100)*.2;return Math.max(0,Math.min(1,S))}catch(c){return .5}};return{scan:()=>new Promise(d=>{let c=()=>{let{nodes:u,edges:m,elementToId:g}=ie(p);i.clear();for(let[r,s]of g)i.set(r,s);d({nodes:u,edges:m,scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(c,{timeout:100}):c()}catch(u){c()}}),observe:d=>{n=d;try{e=new MutationObserver(c=>{let u=[],m=new Set;for(let r of c)r.type==="childList"&&r.addedNodes.forEach(s=>{if(!(s instanceof Element)||!W.has(s.tagName))return;let f=s.hasAttribute("data-sentient-id"),S=s.hasAttribute("aria-label");if(!f&&!S)return;let h=C(s,p);u.push(h),m.add(h.componentId),i.set(s,h.componentId)});if(u.length===0||!n)return;for(let r of[...i.keys()])r.isConnected||i.delete(r);let g=$(i).filter(r=>m.has(r.fromComponentId)||m.has(r.toComponentId));n({nodes:u,edges:g,addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(c){}},getProminenceScore:p,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(d){}t=0,n=null,i.clear()}}}var de="https://api.sentient-ui.com/v1/events";function ce(e){var n;let t=i=>{try{let p=document.cookie.match(new RegExp(`(?:^|; )${i}=([^;]*)`));return p?decodeURIComponent(p[1]):void 0}catch(p){return}};return(n=e?t(A(e)):void 0)!=null?n:t(N)}var E=new Map;function Ie(e){var m;let t=_(e),n=e.respectDoNotTrack!==!1&&x(),i=e.consent===!1||n;if(!e.graph||!e.apiKey||i||typeof window=="undefined")return t;let p=E.get(e.apiKey);if(p)try{p()}catch(g){}let l=k(),o=(m=e.ingestUrl)!=null?m:de,a=R({syncUrl:o.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:ce(e.apiKey)});l.scan().then(g=>{for(let r of g.nodes)a.addPageNode({id:r.componentId,componentId:r.componentId,semanticType:r.semanticType,answers:e.captureDomText&&r.headingText?[r.headingText]:[],prominenceScore:r.prominenceScore,depth:r.depth});for(let r of g.edges)a.addStructuralEdge(r);a.syncOnce()});let d=null,c=()=>{d!==null&&clearTimeout(d),d=setTimeout(()=>{d=null,a.syncOnce()},500)};l.observe(g=>{for(let r of g.nodes)a.addPageNode({id:r.componentId,componentId:r.componentId,semanticType:r.semanticType,answers:e.captureDomText&&r.headingText?[r.headingText]:[],prominenceScore:r.prominenceScore,depth:r.depth});for(let r of g.edges)a.addStructuralEdge(r);c()});let u=()=>{d!==null&&(clearTimeout(d),d=null),l.destroy(),a.destroy(),E.get(e.apiKey)===u&&E.delete(e.apiKey)};return E.set(e.apiKey,u),I(y({},t),{getGraph:()=>a.snapshot(),dispose:()=>{u(),t.dispose()},destroy:()=>{u(),t.destroy()}})}export{z as deriveSessionSegment,L as detectDeviceClass,K as detectTimeOfDay,U as detectTrafficSource,Ie as init,j as referrerDomainFromReferer,M as sanitizePageUrl};
|
|
1
|
+
import{a as T,d as v}from"./chunk-CD2A55US.mjs";import{A as Q,B as _,a as Y,b as V,c as W,d as J,g as be,h as we,i as Te,j as ve,k as Ae,l as Ne,m as xe,n as _e,o as Oe,p as Re,q as Me,r as De,s as Pe,t as ke,u as Ge,v as $e,w as Le,x as X,y as N,z as x}from"./chunk-2RH7I6AP.mjs";import{a as A,b as C,c as b,j as L,k as K,l as U,m as j,n as F,p as q,q as z,r as B,s as H}from"./chunk-QNEYUJJJ.mjs";import{a as y,b as E}from"./chunk-TMCGHANO.mjs";var O="_snt_graph_edges",Z={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function ee(e){var t;return(t=Z[e])!=null?t:[]}function te(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function ne(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var oe=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function re(e){return oe.has(e)?e:"generic"}function R(e){try{let t=new URL(e);return`${t.origin}${t.pathname}`}catch(t){return"/"}}function se(e,t,n){let a=`${e}:${t}:${n.join(",")}`,c=5381;for(let i=0;i<a.length;i++)c=(c<<5)+c+a.charCodeAt(i)&4294967295;return(c>>>0).toString(16).padStart(8,"0")}function M(e){let t=new Map,n=new Map,a=`_snt_graph_nodes${A(e==null?void 0:e.apiKey)}`,c=()=>{typeof window!="undefined"&&ne(a,[...t.values()])};if(typeof window!="undefined"){let i=te(a,[]);for(let r of i)t.set(r.componentId,r);try{localStorage.removeItem(O)}catch(r){}}return{addPageNode(i){t.set(i.componentId,i),c()},addStructuralEdge(i){let r=`${i.fromComponentId}->${i.toComponentId}`;n.set(r,i)},syncOnce(){var r,m;if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let i=[...t.values()];if(i.length!==0)try{let u=new Map;for(let o of i){let p=(r=u.get(o.semanticType))!=null?r:[];p.push(o),u.set(o.semanticType,p)}let s=[],d=new Set;for(let o of i)for(let p of ee(o.semanticType)){let l=(m=u.get(p))!=null?m:[];for(let h of l){if(h.componentId===o.componentId)continue;let S=`semantic:${o.componentId}->${h.componentId}`;d.has(S)||(d.add(S),s.push({fromComponentId:o.componentId,toComponentId:h.componentId,type:"semantic",weight:.4,confidence:.9}))}}let f=new Set(i.map(o=>o.componentId));for(let o of n.values()){if(!f.has(o.fromComponentId)||!f.has(o.toComponentId))continue;let p=`structural:${o.fromComponentId}->${o.toComponentId}`;d.has(p)||(d.add(p),s.push({fromComponentId:o.fromComponentId,toComponentId:o.toComponentId,type:"structural",weight:o.weight,confidence:1}))}let g=E(y(y({pageUrl:R(window.location.href)},e.sessionId?{sessionId:e.sessionId}:{}),e.projectId?{projectId:e.projectId}:{}),{nodes:i.map(o=>{let p=re(o.semanticType);return{componentId:o.componentId,semanticType:p,answers:o.answers,contentHash:se(o.componentId,p,o.answers),prominenceScore:o.prominenceScore,depthInPage:o.depth}}),edges:s});fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:y({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(g)}).catch(()=>{})}catch(u){}},snapshot(){return{pageNodes:[...t.values()],capturedAt:Date.now()}},destroy(){if(typeof window!="undefined")try{localStorage.removeItem(a),localStorage.removeItem(O)}catch(i){}}}}var ae=new Set(["SECTION","ARTICLE","MAIN","DIV","ASIDE"]),ie="h1, h2, h3",ce="[data-sentient-id], section[aria-label], article[aria-label], main[aria-label], aside[aria-label]",D=30,de=1500,pe={scan:async()=>({nodes:[],edges:[],scannedAt:0}),observe:()=>{},getProminenceScore:()=>0,destroy:()=>{}};function P(e,t,n){return n<=t?0:Math.max(0,Math.min(1,(e-t)/(n-t)))}function ue(e){var t,n,a;try{let c=e;for(let i of Object.keys(c)){if(!i.startsWith("__reactFiber")&&!i.startsWith("__reactInternalInstance"))continue;let r=c[i],m=(a=(t=r==null?void 0:r.type)==null?void 0:t.displayName)!=null?a:(n=r==null?void 0:r.type)==null?void 0:n.name;if(m&&m.length>1)return m}}catch(c){}}function le(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}var k=new Set(T);function me(e){let t=e.getAttribute("data-sentient-type");if(t&&k.has(t))return t;let n=e.getAttribute("role");return n&&k.has(n)?n:v(e)}function fe(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n)&4294967295;return(t>>>0).toString(16).padStart(8,"0")}function ge(e){let t=[],n=e;for(;n;){let a=n.parentElement;if(!a){t.push(n.tagName.toLowerCase());break}let c=Array.prototype.indexOf.call(a.children,n);t.push(`${n.tagName.toLowerCase()}[${c}]`),n=a}return t.reverse().join("/")}function he(e){var n;let t=(n=e.getAttribute("data-sentient-id"))!=null?n:e.getAttribute("id");return t||`${e.tagName.toLowerCase()}-${fe(ge(e))}`}function Se(e){let t=0,n=e.parentElement;for(;n;)t++,n=n.parentElement;return t}function w(e,t){var a,c,i;let n=e.querySelector(ie);return{componentId:he(e),semanticType:me(e),ariaLabel:(a=e.getAttribute("aria-label"))!=null?a:void 0,headingText:(i=(c=n==null?void 0:n.textContent)==null?void 0:c.trim())!=null?i:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:Se(e),reactComponentName:ue(e),dataAttributes:le(e)}}function G(e){var i;let t=[],n=new Set,a="__root__",c=new Map;for(let[r,m]of e){let u=r.parentElement,s=a;for(;u;){if(e.has(u)){s=e.get(u);let f=e.get(r),g=`${s}->${f}`;!n.has(g)&&s!==f&&(n.add(g),t.push({fromComponentId:s,toComponentId:f,weight:.6}));break}u=u.parentElement}let d=(i=c.get(s))!=null?i:[];d.push(r),c.set(s,d)}for(let r of c.values()){if(r.length<2)continue;let m=r.length>D?r.slice(0,D):r;for(let u=0;u<m.length;u++)for(let s=u+1;s<m.length;s++){if(t.length>=de)return t;let d=e.get(m[u]),f=e.get(m[s]);if(d===f)continue;let g=`${d}->${f}::sib`,o=`${f}->${d}::sib`;n.has(g)||(n.add(g),t.push({fromComponentId:d,toComponentId:f,weight:.3})),n.has(o)||(n.add(o),t.push({fromComponentId:f,toComponentId:d,weight:.3}))}}return t}function ye(e){let t=[],n=new Set,a=new Map;return document.querySelectorAll("[data-sentient-id]").forEach(r=>{if(r instanceof Element&&!n.has(r)){n.add(r);let m=w(r,e);t.push(m),a.set(r,m.componentId)}}),document.querySelectorAll("section, article, main, aside").forEach(r=>{if(!(r instanceof Element)||n.has(r))return;let m=r.hasAttribute("aria-label"),u=r.hasAttribute("data-sentient-id");if(!m&&!u)return;n.add(r);let s=w(r,e);t.push(s),a.set(r,s.componentId)}),{nodes:t,edges:G(a),elementToId:a}}function $(){if(typeof window=="undefined")return pe;let e=null,t=0,n=null,a=new Map,c=u=>{try{let s=window.getComputedStyle(u),d=parseFloat(s.fontSize)||12,f=parseFloat(s.zIndex)||0,g=u.getBoundingClientRect(),o=Math.max(g.top,0),p=window.innerHeight||1,l=1/(o/p+1),h=P(d,12,48)*.4+l*.4+P(f,0,100)*.2;return Math.max(0,Math.min(1,h))}catch(s){return .5}};return{scan:()=>new Promise(u=>{let s=()=>{let{nodes:d,edges:f,elementToId:g}=ye(c);a.clear();for(let[o,p]of g)a.set(o,p);u({nodes:d,edges:f,scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(s,{timeout:100}):s()}catch(d){s()}}),observe:u=>{n=u;try{e=new MutationObserver(s=>{let d=[],f=new Set;for(let o of s)o.type==="childList"&&o.addedNodes.forEach(p=>{if(!(p instanceof Element))return;let l=[];ae.has(p.tagName)&&(p.hasAttribute("data-sentient-id")||p.hasAttribute("aria-label"))&&l.push(p);try{p.querySelectorAll(ce).forEach(h=>l.push(h))}catch(h){}for(let h of l){if(a.has(h))continue;let S=w(h,c);d.push(S),f.add(S.componentId),a.set(h,S.componentId)}});if(d.length===0||!n)return;for(let o of[...a.keys()])o.isConnected||a.delete(o);let g=G(a).filter(o=>f.has(o.fromComponentId)||f.has(o.toComponentId));n({nodes:d,edges:g,addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(s){}},getProminenceScore:c,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(u){}t=0,n=null,a.clear()}}}var Ee="https://api.sentient-ui.com/v1/events";function Ie(e){var n;let t=a=>{try{let c=document.cookie.match(new RegExp(`(?:^|; )${a}=([^;]*)`));return c?decodeURIComponent(c[1]):void 0}catch(c){return}};return(n=e?t(b(e)):void 0)!=null?n:t(C)}var I=new Map;function Ce(e){var o;let t=_(e),n=e.respectDoNotTrack!==!1&&x(),a=e.consent===!1||n,c=typeof e.apiKey=="string"&&e.apiKey.startsWith("pk_"),i=e.localMode===!0||!c;if(!e.graph||i||typeof window=="undefined")return t;if(a)return n||N(e.apiKey,p=>Ce(p)),t;let r=I.get(e.apiKey);if(r)try{r()}catch(p){}let m=$(),u=(o=e.ingestUrl)!=null?o:Ee,s=M({syncUrl:u.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:Ie(e.apiKey)});m.scan().then(p=>{for(let l of p.nodes)s.addPageNode({id:l.componentId,componentId:l.componentId,semanticType:l.semanticType,answers:e.captureDomText&&l.headingText?[l.headingText]:[],prominenceScore:l.prominenceScore,depth:l.depth});for(let l of p.edges)s.addStructuralEdge(l);s.syncOnce()});let d=null,f=()=>{d!==null&&clearTimeout(d),d=setTimeout(()=>{d=null,s.syncOnce()},500)};m.observe(p=>{for(let l of p.nodes)s.addPageNode({id:l.componentId,componentId:l.componentId,semanticType:l.semanticType,answers:e.captureDomText&&l.headingText?[l.headingText]:[],prominenceScore:l.prominenceScore,depth:l.depth});for(let l of p.edges)s.addStructuralEdge(l);f()});let g=()=>{d!==null&&(clearTimeout(d),d=null),m.destroy(),s.destroy(),I.get(e.apiKey)===g&&I.delete(e.apiKey)};return I.set(e.apiKey,g),E(y({},t),{getGraph:()=>s.snapshot(),dispose:()=>{g(),t.dispose()},destroy:()=>{g(),t.destroy()}})}export{we as BLOCK_ALIGNS,xe as BLOCK_EMPHASES,Re as BLOCK_FITS,be as BLOCK_GAPS,Me as BLOCK_GRID_COLUMNS,De as BLOCK_HEADING_LEVELS,Te as BLOCK_JUSTIFIES,Oe as BLOCK_RATIOS,ve as BLOCK_SIZES,_e as BLOCK_TEXT_ALIGNS,Ne as BLOCK_TONES,Ae as BLOCK_WEIGHTS,C as LEGACY_SESSION_COOKIE_NAME,$e as MAX_BLOCK_ARMS,Ge as MAX_BLOCK_CHILDREN,ke as MAX_BLOCK_DEPTH,Pe as MAX_BLOCK_NODES,Le as MAX_BLOCK_TEXT_LEN,Y as SNAPSHOT_STORAGE_KEY_PREFIX,H as armOfResult,X as attachMicroSignalDetectors,z as baselineResultFor,B as baselineSlots,F as deriveSessionSegment,L as detectDeviceClass,j as detectTimeOfDay,K as detectTrafficSource,Q as grantConsent,Ce as init,x as isDoNotTrackEnabled,V as readSnapshot,U as referrerDomainFromReferer,J as renderPrePaintScript,R as sanitizePageUrl,b as sessionCookieName,q as toWireSlot,W as writeSnapshot};
|
|
2
2
|
//# sourceMappingURL=index-graph.mjs.map
|
package/dist/index-graph.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graph.ts","../src/scanner.ts","../src/index-graph.ts"],"sourcesContent":["/** In-memory context graph with persistence and backend sync. */\n\nimport { storageSuffix } from './storage-key.js';\n\nexport type PageNode = {\n id: string;\n componentId: string;\n semanticType: string;\n answers: string[];\n prominenceScore: number;\n depth: number;\n};\n\nexport type GraphSnapshot = {\n pageNodes: PageNode[];\n capturedAt: number;\n};\n\nexport type GraphConfig = {\n syncUrl?: string;\n apiKey?: string;\n projectId?: string;\n sessionId?: string;\n};\n\nexport type StructuralEdge = {\n fromComponentId: string;\n toComponentId: string;\n weight: number;\n};\n\nexport type GraphClient = {\n addPageNode(node: PageNode): void;\n /** Record a DOM-derived parent/child or sibling relationship between two components. */\n addStructuralEdge(edge: StructuralEdge): void;\n /** One-shot batch sync of all current page nodes to the backend. */\n syncOnce(): void;\n snapshot(): GraphSnapshot;\n serialize(): string;\n restore(data: string): void;\n destroy(): void;\n};\n\n// _snt_graph_edges was written by earlier builds but never synced to the backend.\n// We still read and clear any leftover key on init/destroy so old clients don't\n// accumulate stale data, but we no longer write it.\nconst STALE_EDGES_KEY = '_snt_graph_edges';\n\nconst SEMANTIC_NEIGHBOURS: Record<string, string[]> = {\n pricing: ['features', 'faq'],\n features: ['pricing'],\n faq: ['pricing'],\n social_proof: ['cta'],\n cta: ['social_proof', 'hero', 'trust'],\n hero: ['cta'],\n comparison: ['pricing'],\n trust: ['cta'],\n};\n\nfunction neighboursFor(semanticType: string): string[] {\n return SEMANTIC_NEIGHBOURS[semanticType] ?? [];\n}\n\nfunction readStorage<T>(key: string, fallback: T): T {\n try {\n const raw = localStorage.getItem(key);\n if (!raw) return fallback;\n return JSON.parse(raw) as T;\n } catch {\n return fallback;\n }\n}\n\nfunction writeStorage(key: string, value: unknown): void {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n /* ignore */\n }\n}\n\nconst VALID_SEMANTIC_TYPES = new Set([\n 'pricing', 'hero', 'social_proof', 'cta', 'features',\n 'faq', 'comparison', 'trust', 'navigation', 'generic',\n]);\n\nfunction toValidSemanticType(type: string): string {\n return VALID_SEMANTIC_TYPES.has(type) ? type : 'generic';\n}\n\n/**\n * Path-only page URL for graph sync — strips query + fragment so tokens,\n * emails, and other sensitive URL params never leave the browser by default.\n */\nexport function sanitizePageUrl(href: string): string {\n try {\n const u = new URL(href);\n return `${u.origin}${u.pathname}`;\n } catch {\n return '/';\n }\n}\n\nfunction contentHashOf(componentId: string, semanticType: string, answers: string[]): string {\n const input = `${componentId}:${semanticType}:${answers.join(',')}`;\n let h = 5381;\n for (let i = 0; i < input.length; i++) {\n h = ((h << 5) + h + input.charCodeAt(i)) & 0xffffffff;\n }\n return (h >>> 0).toString(16).padStart(8, '0');\n}\n\n/**\n * Creates an in-memory graph client with optional persistence and sync.\n */\nexport function createGraphClient(config?: GraphConfig): GraphClient {\n const pageNodes = new Map<string, PageNode>();\n const structuralEdges = new Map<string, StructuralEdge>();\n\n // Per-project localStorage key so two projects on one origin don't share a\n // graph-node cache (see storage-key.ts). Legacy `_snt_graph_nodes` with no key.\n const nodesKey = `_snt_graph_nodes${storageSuffix(config?.apiKey)}`;\n\n const persist = (): void => {\n if (typeof window === 'undefined') return;\n writeStorage(nodesKey, [...pageNodes.values()]);\n };\n\n const restore = (data: string): void => {\n try {\n const parsed = JSON.parse(data) as { pageNodes?: PageNode[] };\n pageNodes.clear();\n for (const node of parsed.pageNodes ?? []) {\n pageNodes.set(node.componentId, node);\n }\n } catch {\n /* ignore corrupt state */\n }\n };\n\n if (typeof window !== 'undefined') {\n const storedNodes = readStorage<PageNode[]>(nodesKey, []);\n for (const node of storedNodes) {\n pageNodes.set(node.componentId, node);\n }\n // Clear any stale edge data written by older SDK versions.\n try { localStorage.removeItem(STALE_EDGES_KEY); } catch { /* ignore */ }\n }\n\n return {\n addPageNode(node: PageNode): void {\n pageNodes.set(node.componentId, node);\n persist();\n },\n\n addStructuralEdge(edge: StructuralEdge): void {\n const key = `${edge.fromComponentId}->${edge.toComponentId}`;\n structuralEdges.set(key, edge);\n },\n\n syncOnce(): void {\n if (!config?.syncUrl || typeof window === 'undefined') return;\n const nodes = [...pageNodes.values()];\n if (nodes.length === 0) return;\n try {\n // Build semantic edges from the SEMANTIC_NEIGHBOURS map. Each node emits\n // an edge to every present sibling that matches one of its neighbour types.\n // Weight matches propagate()'s 0.4 attention factor; confidence is high\n // because the mapping is curated, not inferred.\n const nodesByType = new Map<string, PageNode[]>();\n for (const n of nodes) {\n const list = nodesByType.get(n.semanticType) ?? [];\n list.push(n);\n nodesByType.set(n.semanticType, list);\n }\n const edges: Array<{\n fromComponentId: string;\n toComponentId: string;\n type: 'semantic' | 'structural';\n weight: number;\n confidence: number;\n }> = [];\n const seen = new Set<string>();\n for (const source of nodes) {\n for (const neighbourType of neighboursFor(source.semanticType)) {\n const targets = nodesByType.get(neighbourType) ?? [];\n for (const target of targets) {\n if (target.componentId === source.componentId) continue;\n const key = `semantic:${source.componentId}->${target.componentId}`;\n if (seen.has(key)) continue;\n seen.add(key);\n edges.push({\n fromComponentId: source.componentId,\n toComponentId: target.componentId,\n type: 'semantic',\n weight: 0.4,\n confidence: 0.9,\n });\n }\n }\n }\n\n // Structural edges from DOM relationships, recorded during scan.\n // Only emit when both endpoints are present in this page's node set —\n // a structural edge to/from a node that no longer exists would dangle.\n const componentIds = new Set(nodes.map((n) => n.componentId));\n for (const edge of structuralEdges.values()) {\n if (!componentIds.has(edge.fromComponentId) || !componentIds.has(edge.toComponentId)) continue;\n const key = `structural:${edge.fromComponentId}->${edge.toComponentId}`;\n if (seen.has(key)) continue;\n seen.add(key);\n edges.push({\n fromComponentId: edge.fromComponentId,\n toComponentId: edge.toComponentId,\n type: 'structural',\n weight: edge.weight,\n confidence: 1.0,\n });\n }\n\n const payload = {\n pageUrl: sanitizePageUrl(window.location.href),\n // Visitor/project attribution. The /graph/sync handler ignores unknown\n // top-level fields (Fastify additionalProperties + Zod strips extras),\n // so these ride along harmlessly and let beacons carry attribution.\n ...(config.sessionId ? { sessionId: config.sessionId } : {}),\n ...(config.projectId ? { projectId: config.projectId } : {}),\n nodes: nodes.map((n) => {\n const semanticType = toValidSemanticType(n.semanticType);\n return {\n componentId: n.componentId,\n semanticType,\n answers: n.answers,\n contentHash: contentHashOf(n.componentId, semanticType, n.answers),\n prominenceScore: n.prominenceScore,\n depthInPage: n.depth,\n };\n }),\n edges,\n };\n fetch(config.syncUrl, {\n method: 'POST',\n keepalive: true,\n headers: {\n 'Content-Type': 'application/json',\n ...(config.apiKey ? { Authorization: `Bearer ${config.apiKey}` } : {}),\n },\n body: JSON.stringify(payload),\n }).catch(() => undefined);\n } catch {\n /* ignore */\n }\n },\n\n snapshot(): GraphSnapshot {\n return {\n pageNodes: [...pageNodes.values()],\n capturedAt: Date.now(),\n };\n },\n\n serialize(): string {\n return JSON.stringify({ pageNodes: [...pageNodes.values()] });\n },\n\n restore,\n\n destroy(): void {\n if (typeof window === 'undefined') return;\n try {\n localStorage.removeItem(nodesKey);\n localStorage.removeItem(STALE_EDGES_KEY);\n } catch {\n /* ignore */\n }\n },\n };\n}\n","/** Reads the rendered DOM to build the page-side context graph. */\n\nimport { classifySection, SEMANTIC_TYPES, type SemanticType } from './engagement/classify';\n\nexport type ScannedNode = {\n componentId: string;\n semanticType: string;\n ariaLabel?: string;\n headingText?: string;\n isAboveFold: boolean;\n prominenceScore: number;\n depth: number;\n reactComponentName?: string;\n dataAttributes: Record<string, string>;\n};\n\nexport type StructuralEdge = {\n fromComponentId: string;\n toComponentId: string;\n /** 0.6 for direct parent → child, 0.3 for sibling (both directions emitted). */\n weight: number;\n};\n\nexport type ScanResult = {\n nodes: ScannedNode[];\n edges: StructuralEdge[];\n scannedAt: number;\n};\n\nexport type ContentAddedEvent = {\n nodes: ScannedNode[];\n edges: StructuralEdge[];\n addedAt: number;\n};\n\nexport type DOMScanner = {\n scan(): Promise<ScanResult>;\n observe(onContentAdded: (event: ContentAddedEvent) => void): void;\n getProminenceScore(element: Element): number;\n destroy(): void;\n};\n\nconst OBSERVE_TAGS = new Set(['SECTION', 'ARTICLE', 'MAIN', 'DIV']);\nconst HEADING_SELECTOR = 'h1, h2, h3';\n\n// Sibling detection is O(n²) per group and emits two edges per pair, so a page\n// with hundreds of co-located components (e.g. a 200-cell product grid) would\n// otherwise emit tens of thousands of low-signal sibling edges. We cap the\n// sibling fan-out per group and the total structural edges per detection pass.\n// The total stays well under the server's 2000-edge-per-sync limit, leaving room\n// for semantic edges. Parent→child edges (higher signal) are emitted first, so\n// the cap sheds sibling edges before it ever touches them.\nconst MAX_SIBLINGS_PER_GROUP = 30;\nconst MAX_STRUCTURAL_EDGES = 1500;\n\nconst SSR_SCANNER: DOMScanner = {\n scan: async () => ({ nodes: [], edges: [], scannedAt: 0 }),\n observe: () => undefined,\n getProminenceScore: () => 0,\n destroy: () => undefined,\n};\n\nfunction normalize(value: number, min: number, max: number): number {\n if (max <= min) return 0;\n return Math.max(0, Math.min(1, (value - min) / (max - min)));\n}\n\nfunction readReactComponentName(element: Element): string | undefined {\n try {\n const record = element as unknown as Record<string, unknown>;\n for (const key of Object.keys(record)) {\n if (!key.startsWith('__reactFiber') && !key.startsWith('__reactInternalInstance')) {\n continue;\n }\n const fiber = record[key] as { type?: { name?: string; displayName?: string } };\n const name = fiber?.type?.displayName ?? fiber?.type?.name;\n if (name && name.length > 1) {\n return name;\n }\n }\n } catch {\n /* ignore */\n }\n return undefined;\n}\n\nfunction extractDataAttributes(element: Element): Record<string, string> {\n const attrs: Record<string, string> = {};\n for (const attr of Array.from(element.attributes)) {\n if (attr.name.startsWith('data-')) {\n attrs[attr.name] = attr.value;\n }\n }\n return attrs;\n}\n\nconst SEMANTIC_SET: ReadonlySet<string> = new Set(SEMANTIC_TYPES);\n\n// Explicit tag wins → role → heuristic → generic. Every output is normalized to\n// the graph_nodes enum: an out-of-vocabulary data-sentient-type/role falls\n// through to the heuristic instead of being emitted raw (raw values violated\n// the graph_nodes CHECK constraint on insert).\nfunction inferSemanticType(element: Element): SemanticType {\n const explicit = element.getAttribute('data-sentient-type');\n if (explicit && SEMANTIC_SET.has(explicit)) return explicit as SemanticType;\n const role = element.getAttribute('role');\n if (role && SEMANTIC_SET.has(role)) return role as SemanticType;\n return classifySection(element);\n}\n\n// djb2 over a string → 8-hex-char digest. Stable and collision-resistant enough\n// to disambiguate co-located components that declare no id of their own.\nfunction shortHash(input: string): string {\n let h = 5381;\n for (let i = 0; i < input.length; i++) {\n h = ((h << 5) + h + input.charCodeAt(i)) & 0xffffffff;\n }\n return (h >>> 0).toString(16).padStart(8, '0');\n}\n\n// A structural path (tag + sibling index at each level up to the root) uniquely\n// and stably identifies an element's DOM position, so two id-less sections don't\n// hash to the same value the way a bare tagName would.\nfunction domPathSignature(element: Element): string {\n const parts: string[] = [];\n let current: Element | null = element;\n while (current) {\n const parent: Element | null = current.parentElement;\n if (!parent) {\n parts.push(current.tagName.toLowerCase());\n break;\n }\n const index = Array.prototype.indexOf.call(parent.children, current);\n parts.push(`${current.tagName.toLowerCase()}[${index}]`);\n current = parent;\n }\n return parts.reverse().join('/');\n}\n\n// Prefer an author-declared id. When none exists, synthesize a stable, unique id\n// from the element's DOM path — the old `tagName.toLowerCase()` fallback gave\n// every id-less <section> the same \"section\" id, so a second such node silently\n// overwrote the first in the componentId-keyed graph Map (node loss).\nfunction componentIdFor(element: Element): string {\n const declared =\n element.getAttribute('data-sentient-id') ?? element.getAttribute('id');\n if (declared) return declared;\n return `${element.tagName.toLowerCase()}-${shortHash(domPathSignature(element))}`;\n}\n\nfunction depthOf(element: Element): number {\n let depth = 0;\n let current: Element | null = element.parentElement;\n while (current) {\n depth++;\n current = current.parentElement;\n }\n return depth;\n}\n\nfunction scanElement(\n element: Element,\n getProminenceScore: (el: Element) => number,\n): ScannedNode {\n const heading = element.querySelector(HEADING_SELECTOR);\n return {\n componentId: componentIdFor(element),\n semanticType: inferSemanticType(element),\n ariaLabel: element.getAttribute('aria-label') ?? undefined,\n headingText: heading?.textContent?.trim() ?? undefined,\n isAboveFold: element.getBoundingClientRect().top < window.innerHeight,\n prominenceScore: getProminenceScore(element),\n depth: depthOf(element),\n reactComponentName: readReactComponentName(element),\n dataAttributes: extractDataAttributes(element),\n };\n}\n\n/**\n * Detects structural relationships between scanned component elements:\n * - parent → child (direct ancestor link, weight 0.6)\n * - sibling ↔ sibling (share nearest component ancestor, weight 0.3, bidirectional)\n * A pair appears at most once per direction.\n */\nfunction detectStructuralEdges(elementToId: Map<Element, string>): StructuralEdge[] {\n const edges: StructuralEdge[] = [];\n const seen = new Set<string>();\n const ROOT = '__root__';\n\n // Parent → child: nearest component ancestor only.\n const groups = new Map<string, Element[]>();\n for (const [el, _id] of elementToId) {\n let ancestor: Element | null = el.parentElement;\n let groupKey = ROOT;\n while (ancestor) {\n if (elementToId.has(ancestor)) {\n groupKey = elementToId.get(ancestor)!;\n const childId = elementToId.get(el)!;\n const key = `${groupKey}->${childId}`;\n if (!seen.has(key) && groupKey !== childId) {\n seen.add(key);\n edges.push({ fromComponentId: groupKey, toComponentId: childId, weight: 0.6 });\n }\n break;\n }\n ancestor = ancestor.parentElement;\n }\n const siblings = groups.get(groupKey) ?? [];\n siblings.push(el);\n groups.set(groupKey, siblings);\n }\n\n // Sibling ↔ sibling: same ancestor group.\n for (const sibs of groups.values()) {\n if (sibs.length < 2) continue;\n // Cap the fan-out of any single group before the O(n²) pairing.\n const capped = sibs.length > MAX_SIBLINGS_PER_GROUP ? sibs.slice(0, MAX_SIBLINGS_PER_GROUP) : sibs;\n for (let i = 0; i < capped.length; i++) {\n for (let j = i + 1; j < capped.length; j++) {\n if (edges.length >= MAX_STRUCTURAL_EDGES) return edges;\n const aId = elementToId.get(capped[i]!)!;\n const bId = elementToId.get(capped[j]!)!;\n if (aId === bId) continue;\n const fwd = `${aId}->${bId}::sib`;\n const rev = `${bId}->${aId}::sib`;\n if (!seen.has(fwd)) {\n seen.add(fwd);\n edges.push({ fromComponentId: aId, toComponentId: bId, weight: 0.3 });\n }\n if (!seen.has(rev)) {\n seen.add(rev);\n edges.push({ fromComponentId: bId, toComponentId: aId, weight: 0.3 });\n }\n }\n }\n }\n\n return edges;\n}\n\nfunction collectNodesAndEdges(\n getProminenceScore: (el: Element) => number,\n): { nodes: ScannedNode[]; edges: StructuralEdge[]; elementToId: Map<Element, string> } {\n const nodes: ScannedNode[] = [];\n const seen = new Set<Element>();\n const elementToId = new Map<Element, string>();\n\n const registered = document.querySelectorAll('[data-sentient-id]');\n registered.forEach((el) => {\n if (el instanceof Element && !seen.has(el)) {\n seen.add(el);\n const node = scanElement(el, getProminenceScore);\n nodes.push(node);\n elementToId.set(el, node.componentId);\n }\n });\n\n const structural = document.querySelectorAll('section, article, main, aside');\n structural.forEach((el) => {\n if (!(el instanceof Element) || seen.has(el)) return;\n const hasAria = el.hasAttribute('aria-label');\n const hasSentientId = el.hasAttribute('data-sentient-id');\n if (!hasAria && !hasSentientId) return;\n seen.add(el);\n const node = scanElement(el, getProminenceScore);\n nodes.push(node);\n elementToId.set(el, node.componentId);\n });\n\n return { nodes, edges: detectStructuralEdges(elementToId), elementToId };\n}\n\n/**\n * Creates a DOM scanner that uses idle callbacks and mutation observation.\n */\nexport function createDOMScanner(): DOMScanner {\n if (typeof window === 'undefined') {\n return SSR_SCANNER;\n }\n\n let observer: MutationObserver | null = null;\n let idleCallbackId = 0;\n let contentCallback: ((event: ContentAddedEvent) => void) | null = null;\n // Element→componentId for every node registered so far (initial scan + prior\n // mutations). The MutationObserver detects edges against this whole set — not\n // just the nodes in the current mutation — so a child inserted under an\n // already-scanned parent still gets its parent→child edge.\n const knownElementToId = new Map<Element, string>();\n\n const getProminenceScore = (element: Element): number => {\n try {\n const styles = window.getComputedStyle(element);\n const fontSize = parseFloat(styles.fontSize) || 12;\n const zIndex = parseFloat(styles.zIndex) || 0;\n const rect = element.getBoundingClientRect();\n const distanceFromTop = Math.max(rect.top, 0);\n const viewportHeight = window.innerHeight || 1;\n const inverseDistance = 1 / (distanceFromTop / viewportHeight + 1);\n\n // inverseDistance is already in (0, 1] by construction, so it needs no\n // further normalization — only fontSize and zIndex are rescaled.\n const score =\n normalize(fontSize, 12, 48) * 0.4 +\n inverseDistance * 0.4 +\n normalize(zIndex, 0, 100) * 0.2;\n\n return Math.max(0, Math.min(1, score));\n } catch {\n return 0.5;\n }\n };\n\n const scan = (): Promise<ScanResult> =>\n new Promise((resolve) => {\n const run = (): void => {\n const { nodes, edges, elementToId } = collectNodesAndEdges(getProminenceScore);\n // Seed the known-element registry so the observer can resolve parents that\n // were registered in this scan when later children are inserted.\n knownElementToId.clear();\n for (const [el, id] of elementToId) knownElementToId.set(el, id);\n resolve({ nodes, edges, scannedAt: Date.now() });\n };\n\n try {\n if (typeof requestIdleCallback === 'function') {\n idleCallbackId = requestIdleCallback(run, { timeout: 100 });\n } else {\n run();\n }\n } catch {\n run();\n }\n });\n\n const observe = (onContentAdded: (event: ContentAddedEvent) => void): void => {\n contentCallback = onContentAdded;\n try {\n observer = new MutationObserver((mutations) => {\n const added: ScannedNode[] = [];\n const addedIds = new Set<string>();\n for (const mutation of mutations) {\n if (mutation.type !== 'childList') continue;\n mutation.addedNodes.forEach((node) => {\n if (!(node instanceof Element)) return;\n if (!OBSERVE_TAGS.has(node.tagName)) return;\n const hasId = node.hasAttribute('data-sentient-id');\n const hasAria = node.hasAttribute('aria-label');\n if (!hasId && !hasAria) return;\n const scanned = scanElement(node, getProminenceScore);\n added.push(scanned);\n addedIds.add(scanned.componentId);\n knownElementToId.set(node, scanned.componentId);\n });\n }\n if (added.length === 0 || !contentCallback) return;\n // Drop elements no longer in the document so removed nodes don't dangle\n // and the map stays bounded.\n for (const el of [...knownElementToId.keys()]) {\n if (!el.isConnected) knownElementToId.delete(el);\n }\n // Detect over the FULL known set so a child inserted under an already-\n // scanned parent still gets its parent→child edge, then surface only the\n // edges that touch a newly-added node (existing edges were already emitted).\n const edges = detectStructuralEdges(knownElementToId).filter(\n (e) => addedIds.has(e.fromComponentId) || addedIds.has(e.toComponentId),\n );\n contentCallback({ nodes: added, edges, addedAt: Date.now() });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n } catch {\n /* ignore */\n }\n };\n\n const destroy = (): void => {\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n if (idleCallbackId && typeof cancelIdleCallback === 'function') {\n try {\n cancelIdleCallback(idleCallbackId);\n } catch {\n /* ignore */\n }\n }\n idleCallbackId = 0;\n contentCallback = null;\n knownElementToId.clear();\n };\n\n return {\n scan,\n observe,\n getProminenceScore,\n destroy,\n };\n}\n","/**\n * Graph-capable entry point for @sentientui/core.\n *\n * Import from `@sentientui/core/graph` when you need DOM graph scanning and\n * page-structure sync. This entry pulls in `scanner.ts` and `graph.ts` at\n * build time, giving bundlers a real tree-shaking boundary. Standard A/B tests\n * should use `@sentientui/core` (the lean entry) instead.\n */\n\n// Re-export everything from the lean entry except `init`, which we override below.\nexport {\n detectDeviceClass,\n detectTrafficSource,\n detectTimeOfDay,\n deriveSessionSegment,\n referrerDomainFromReferer,\n} from './index.js';\n// SSR preload helpers moved to `@sentientui/core/server` in 0.6.0.\nexport type {\n SentientConfig,\n AssignResult,\n SentientClient,\n} from './index.js';\nexport type {\n SessionConfig,\n SessionManager,\n EventType,\n SentientEvent,\n QueueConfig,\n Assignment,\n} from './index.js';\n// EventQueue/AssignmentCache are no longer on the lean barrel — source them from\n// their own modules so the `/graph` subpath keeps exposing them unchanged.\nexport type { EventQueue } from './queue.js';\nexport type { AssignmentCache } from './cache.js';\n// Scanner + graph types (live in this entry only).\nexport type {\n ScannedNode,\n ScanResult,\n ContentAddedEvent,\n DOMScanner,\n} from './scanner.js';\nexport type {\n PageNode,\n GraphSnapshot,\n GraphConfig,\n GraphClient,\n} from './graph.js';\nexport { sanitizePageUrl } from './graph.js';\n\nimport { init as initLean, isDoNotTrackEnabled, type SentientConfig, type SentientClient } from './index.js';\nimport { LEGACY_SESSION_COOKIE_NAME, sessionCookieName } from './storage-key.js';\n\nconst DEFAULT_INGEST_URL = 'https://api.sentient-ui.com/v1/events';\nimport { createDOMScanner } from './scanner.js';\nimport { createGraphClient } from './graph.js';\n\nexport type GraphSentientConfig = SentientConfig & {\n /**\n * Enable DOM graph scanning and page-structure sync. Wires a MutationObserver\n * and a localStorage-backed graph. When `false` (default) this entry behaves\n * identically to `@sentientui/core`.\n */\n graph?: boolean;\n /**\n * Include captured heading / DOM text in graph sync payloads. OFF by default —\n * headings can contain account names or user-generated content. Structure\n * (component ids, semantic types, prominence) still syncs when `graph: true`.\n */\n captureDomText?: boolean;\n};\n\n// The client writes the per-project SUFFIXED cookie (sessionCookieName in\n// storage-key.ts). This reader kept the bare `_snt_uid` after namespacing\n// landed, so graph sync sent `sessionId: undefined` for every keyed project.\n// The bare name stays as a fallback for pre-namespacing identities.\nfunction readSntUid(apiKey?: string): string | undefined {\n const read = (name: string): string | undefined => {\n try {\n // Cookie names are `_snt_uid` + `_` + a pk_ key prefix — no regex\n // metacharacters, so interpolation is safe (same pattern as session.ts).\n const m = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`));\n return m ? decodeURIComponent(m[1]!) : undefined;\n } catch {\n return undefined;\n }\n };\n return (apiKey ? read(sessionCookieName(apiKey)) : undefined) ?? read(LEGACY_SESSION_COOKIE_NAME);\n}\n\n/**\n * Graph-capable variant of `init()`. Identical to the lean `init` when\n * `config.graph` is `false` (or omitted). When `config.graph: true`, mounts\n * a DOM scanner + graph client and enables `client.getGraph()`.\n *\n * Import from `@sentientui/core/graph` — do not call the lean `init` alongside\n * this function as that would initialise two clients.\n */\n// Teardown for the graph resources (scanner + MutationObserver + debounce\n// timer + graph client) bound to each apiKey. initLean already disposes the\n// lean client's own timers/listeners on re-init, but it knows nothing about\n// these graph resources, so this entry tracks and tears them down itself —\n// otherwise an HMR / consent-toggle / provider-remount re-init would leak a\n// live MutationObserver and a pending sync timer per mount.\nconst _graphTeardowns = new Map<string, () => void>();\n\nexport function init(config: GraphSentientConfig): SentientClient {\n const client = initLean(config);\n\n // Mirror initLean's opt-out gate: a DNT/GPC visitor (or consent:false) must\n // not get the DOM scanner + graph sync, which POST page-structure beacons and\n // read `_snt_uid` — tracking that bypasses the lean client's own gating, even\n // under `preConsentBehavior: 'statistical_winner'` (audit P1).\n const dntBlocked = config.respectDoNotTrack !== false && isDoNotTrackEnabled();\n const gated = config.consent === false || dntBlocked;\n\n // Keyless zero-network contract: with no api key there is nothing to feed —\n // the scanner must never mount and /v1/graph/sync must never fire.\n if (!config.graph || !config.apiKey || gated || typeof window === 'undefined') return client;\n\n // A prior graph mount for this key is now superseded — tear it down first so\n // its observer/timer don't leak alongside the new mount's.\n const prevTeardown = _graphTeardowns.get(config.apiKey);\n if (prevTeardown) {\n try {\n prevTeardown();\n } catch {\n /* teardown must never throw on re-init */\n }\n }\n\n const domScanner = createDOMScanner();\n const resolvedIngestUrl = config.ingestUrl ?? DEFAULT_INGEST_URL;\n const graphClient = createGraphClient({\n syncUrl: resolvedIngestUrl.replace(/\\/events\\/?$/, '/graph/sync'),\n apiKey: config.apiKey,\n projectId: config.apiKey,\n sessionId: readSntUid(config.apiKey),\n });\n\n // Persisted page-node state from a previous page load is restored by the graph\n // client's own constructor (it reads `_snt_graph_nodes` on creation). We no\n // longer re-read the key and call restore() here — that was a redundant second\n // load path that cleared and reloaded identical data.\n\n void domScanner.scan().then((result) => {\n for (const node of result.nodes) {\n graphClient.addPageNode({\n id: node.componentId,\n componentId: node.componentId,\n semanticType: node.semanticType,\n answers: config.captureDomText && node.headingText ? [node.headingText] : [],\n prominenceScore: node.prominenceScore,\n depth: node.depth,\n });\n }\n for (const edge of result.edges) {\n graphClient.addStructuralEdge(edge);\n }\n graphClient.syncOnce();\n });\n\n let syncDebounceTimer: ReturnType<typeof setTimeout> | null = null;\n const debouncedSync = (): void => {\n if (syncDebounceTimer !== null) clearTimeout(syncDebounceTimer);\n syncDebounceTimer = setTimeout(() => {\n syncDebounceTimer = null;\n graphClient.syncOnce();\n }, 500);\n };\n\n domScanner.observe((event) => {\n for (const node of event.nodes) {\n graphClient.addPageNode({\n id: node.componentId,\n componentId: node.componentId,\n semanticType: node.semanticType,\n answers: config.captureDomText && node.headingText ? [node.headingText] : [],\n prominenceScore: node.prominenceScore,\n depth: node.depth,\n });\n }\n for (const edge of event.edges) {\n graphClient.addStructuralEdge(edge);\n }\n debouncedSync();\n });\n\n // Tears down only the graph resources; the caller pairs it with the lean\n // client's own dispose/destroy. Idempotent, and de-registers itself so a\n // later re-init or teardown can't run it twice on already-freed resources.\n const teardownGraph = (): void => {\n if (syncDebounceTimer !== null) {\n clearTimeout(syncDebounceTimer);\n syncDebounceTimer = null;\n }\n domScanner.destroy();\n graphClient.destroy();\n if (_graphTeardowns.get(config.apiKey) === teardownGraph) {\n _graphTeardowns.delete(config.apiKey);\n }\n };\n _graphTeardowns.set(config.apiKey, teardownGraph);\n\n return {\n ...client,\n getGraph: () => graphClient.snapshot(),\n dispose: () => {\n teardownGraph();\n client.dispose();\n },\n destroy: () => {\n teardownGraph();\n client.destroy();\n },\n };\n}\n"],"mappings":"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","names":["STALE_EDGES_KEY","SEMANTIC_NEIGHBOURS","neighboursFor","semanticType","_a","readStorage","key","fallback","raw","e","writeStorage","value","VALID_SEMANTIC_TYPES","toValidSemanticType","type","sanitizePageUrl","href","u","contentHashOf","componentId","answers","input","h","i","createGraphClient","config","pageNodes","structuralEdges","nodesKey","storageSuffix","persist","restore","data","parsed","node","storedNodes","edge","_b","nodes","nodesByType","n","list","edges","seen","source","neighbourType","targets","target","componentIds","payload","__spreadProps","__spreadValues","OBSERVE_TAGS","HEADING_SELECTOR","MAX_SIBLINGS_PER_GROUP","MAX_STRUCTURAL_EDGES","SSR_SCANNER","normalize","value","min","max","readReactComponentName","element","_a","_b","_c","record","key","fiber","name","e","extractDataAttributes","attrs","attr","SEMANTIC_SET","SEMANTIC_TYPES","inferSemanticType","explicit","role","classifySection","shortHash","input","h","i","domPathSignature","parts","current","parent","index","componentIdFor","declared","depthOf","depth","scanElement","getProminenceScore","heading","detectStructuralEdges","elementToId","edges","seen","ROOT","groups","el","_id","ancestor","groupKey","childId","siblings","sibs","capped","j","aId","bId","fwd","rev","collectNodesAndEdges","nodes","node","hasAria","hasSentientId","createDOMScanner","observer","idleCallbackId","contentCallback","knownElementToId","styles","fontSize","zIndex","rect","distanceFromTop","viewportHeight","inverseDistance","score","resolve","run","id","onContentAdded","mutations","added","addedIds","mutation","hasId","scanned","DEFAULT_INGEST_URL","readSntUid","apiKey","_a","read","name","m","e","sessionCookieName","LEGACY_SESSION_COOKIE_NAME","_graphTeardowns","init","config","client","dntBlocked","isDoNotTrackEnabled","gated","prevTeardown","domScanner","createDOMScanner","resolvedIngestUrl","graphClient","createGraphClient","result","node","edge","syncDebounceTimer","debouncedSync","event","teardownGraph","__spreadProps","__spreadValues"]}
|
|
1
|
+
{"version":3,"sources":["../src/graph.ts","../src/scanner.ts","../src/index-graph.ts"],"sourcesContent":["/** In-memory context graph with persistence and backend sync. */\n\nimport { storageSuffix } from './storage-key.js';\n\nexport type PageNode = {\n id: string;\n componentId: string;\n semanticType: string;\n answers: string[];\n prominenceScore: number;\n depth: number;\n};\n\nexport type GraphSnapshot = {\n pageNodes: PageNode[];\n capturedAt: number;\n};\n\nexport type GraphConfig = {\n syncUrl?: string;\n apiKey?: string;\n projectId?: string;\n sessionId?: string;\n};\n\nexport type StructuralEdge = {\n fromComponentId: string;\n toComponentId: string;\n weight: number;\n};\n\nexport type GraphClient = {\n addPageNode(node: PageNode): void;\n /** Record a DOM-derived parent/child or sibling relationship between two components. */\n addStructuralEdge(edge: StructuralEdge): void;\n /** One-shot batch sync of all current page nodes to the backend. */\n syncOnce(): void;\n snapshot(): GraphSnapshot;\n destroy(): void;\n};\n\n// _snt_graph_edges was written by earlier builds but never synced to the backend.\n// We still read and clear any leftover key on init/destroy so old clients don't\n// accumulate stale data, but we no longer write it.\nconst STALE_EDGES_KEY = '_snt_graph_edges';\n\nconst SEMANTIC_NEIGHBOURS: Record<string, string[]> = {\n pricing: ['features', 'faq'],\n features: ['pricing'],\n faq: ['pricing'],\n social_proof: ['cta'],\n cta: ['social_proof', 'hero', 'trust'],\n hero: ['cta'],\n comparison: ['pricing'],\n trust: ['cta'],\n};\n\nfunction neighboursFor(semanticType: string): string[] {\n return SEMANTIC_NEIGHBOURS[semanticType] ?? [];\n}\n\nfunction readStorage<T>(key: string, fallback: T): T {\n try {\n const raw = localStorage.getItem(key);\n if (!raw) return fallback;\n return JSON.parse(raw) as T;\n } catch {\n return fallback;\n }\n}\n\nfunction writeStorage(key: string, value: unknown): void {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n /* ignore */\n }\n}\n\nconst VALID_SEMANTIC_TYPES = new Set([\n 'pricing', 'hero', 'social_proof', 'cta', 'features',\n 'faq', 'comparison', 'trust', 'navigation', 'generic',\n]);\n\nfunction toValidSemanticType(type: string): string {\n return VALID_SEMANTIC_TYPES.has(type) ? type : 'generic';\n}\n\n/**\n * Path-only page URL for graph sync — strips query + fragment so tokens,\n * emails, and other sensitive URL params never leave the browser by default.\n */\nexport function sanitizePageUrl(href: string): string {\n try {\n const u = new URL(href);\n return `${u.origin}${u.pathname}`;\n } catch {\n return '/';\n }\n}\n\nfunction contentHashOf(componentId: string, semanticType: string, answers: string[]): string {\n const input = `${componentId}:${semanticType}:${answers.join(',')}`;\n let h = 5381;\n for (let i = 0; i < input.length; i++) {\n h = ((h << 5) + h + input.charCodeAt(i)) & 0xffffffff;\n }\n return (h >>> 0).toString(16).padStart(8, '0');\n}\n\n/**\n * Creates an in-memory graph client with optional persistence and sync.\n */\nexport function createGraphClient(config?: GraphConfig): GraphClient {\n const pageNodes = new Map<string, PageNode>();\n const structuralEdges = new Map<string, StructuralEdge>();\n\n // Per-project localStorage key so two projects on one origin don't share a\n // graph-node cache (see storage-key.ts). Legacy `_snt_graph_nodes` with no key.\n const nodesKey = `_snt_graph_nodes${storageSuffix(config?.apiKey)}`;\n\n const persist = (): void => {\n if (typeof window === 'undefined') return;\n writeStorage(nodesKey, [...pageNodes.values()]);\n };\n\n // serialize()/restore() were removed here: persisted-node restoration moved\n // into this constructor (below), leaving both dead — yet still shipping in\n // the graph bundle.\n if (typeof window !== 'undefined') {\n const storedNodes = readStorage<PageNode[]>(nodesKey, []);\n for (const node of storedNodes) {\n pageNodes.set(node.componentId, node);\n }\n // Clear any stale edge data written by older SDK versions.\n try { localStorage.removeItem(STALE_EDGES_KEY); } catch { /* ignore */ }\n }\n\n return {\n addPageNode(node: PageNode): void {\n pageNodes.set(node.componentId, node);\n persist();\n },\n\n addStructuralEdge(edge: StructuralEdge): void {\n const key = `${edge.fromComponentId}->${edge.toComponentId}`;\n structuralEdges.set(key, edge);\n },\n\n syncOnce(): void {\n if (!config?.syncUrl || typeof window === 'undefined') return;\n const nodes = [...pageNodes.values()];\n if (nodes.length === 0) return;\n try {\n // Build semantic edges from the SEMANTIC_NEIGHBOURS map. Each node emits\n // an edge to every present sibling that matches one of its neighbour types.\n // Weight matches propagate()'s 0.4 attention factor; confidence is high\n // because the mapping is curated, not inferred.\n const nodesByType = new Map<string, PageNode[]>();\n for (const n of nodes) {\n const list = nodesByType.get(n.semanticType) ?? [];\n list.push(n);\n nodesByType.set(n.semanticType, list);\n }\n const edges: Array<{\n fromComponentId: string;\n toComponentId: string;\n type: 'semantic' | 'structural';\n weight: number;\n confidence: number;\n }> = [];\n const seen = new Set<string>();\n for (const source of nodes) {\n for (const neighbourType of neighboursFor(source.semanticType)) {\n const targets = nodesByType.get(neighbourType) ?? [];\n for (const target of targets) {\n if (target.componentId === source.componentId) continue;\n const key = `semantic:${source.componentId}->${target.componentId}`;\n if (seen.has(key)) continue;\n seen.add(key);\n edges.push({\n fromComponentId: source.componentId,\n toComponentId: target.componentId,\n type: 'semantic',\n weight: 0.4,\n confidence: 0.9,\n });\n }\n }\n }\n\n // Structural edges from DOM relationships, recorded during scan.\n // Only emit when both endpoints are present in this page's node set —\n // a structural edge to/from a node that no longer exists would dangle.\n const componentIds = new Set(nodes.map((n) => n.componentId));\n for (const edge of structuralEdges.values()) {\n if (!componentIds.has(edge.fromComponentId) || !componentIds.has(edge.toComponentId)) continue;\n const key = `structural:${edge.fromComponentId}->${edge.toComponentId}`;\n if (seen.has(key)) continue;\n seen.add(key);\n edges.push({\n fromComponentId: edge.fromComponentId,\n toComponentId: edge.toComponentId,\n type: 'structural',\n weight: edge.weight,\n confidence: 1.0,\n });\n }\n\n const payload = {\n pageUrl: sanitizePageUrl(window.location.href),\n // Visitor/project attribution. The /graph/sync handler ignores unknown\n // top-level fields (Fastify additionalProperties + Zod strips extras),\n // so these ride along harmlessly and let beacons carry attribution.\n ...(config.sessionId ? { sessionId: config.sessionId } : {}),\n ...(config.projectId ? { projectId: config.projectId } : {}),\n nodes: nodes.map((n) => {\n const semanticType = toValidSemanticType(n.semanticType);\n return {\n componentId: n.componentId,\n semanticType,\n answers: n.answers,\n contentHash: contentHashOf(n.componentId, semanticType, n.answers),\n prominenceScore: n.prominenceScore,\n depthInPage: n.depth,\n };\n }),\n edges,\n };\n fetch(config.syncUrl, {\n method: 'POST',\n keepalive: true,\n headers: {\n 'Content-Type': 'application/json',\n ...(config.apiKey ? { Authorization: `Bearer ${config.apiKey}` } : {}),\n },\n body: JSON.stringify(payload),\n }).catch(() => undefined);\n } catch {\n /* ignore */\n }\n },\n\n snapshot(): GraphSnapshot {\n return {\n pageNodes: [...pageNodes.values()],\n capturedAt: Date.now(),\n };\n },\n\n destroy(): void {\n if (typeof window === 'undefined') return;\n try {\n localStorage.removeItem(nodesKey);\n localStorage.removeItem(STALE_EDGES_KEY);\n } catch {\n /* ignore */\n }\n },\n };\n}\n","/** Reads the rendered DOM to build the page-side context graph. */\n\nimport { classifySection, SEMANTIC_TYPES, type SemanticType } from './engagement/classify';\n\nexport type ScannedNode = {\n componentId: string;\n semanticType: string;\n ariaLabel?: string;\n headingText?: string;\n isAboveFold: boolean;\n prominenceScore: number;\n depth: number;\n reactComponentName?: string;\n dataAttributes: Record<string, string>;\n};\n\nexport type StructuralEdge = {\n fromComponentId: string;\n toComponentId: string;\n /** 0.6 for direct parent → child, 0.3 for sibling (both directions emitted). */\n weight: number;\n};\n\nexport type ScanResult = {\n nodes: ScannedNode[];\n edges: StructuralEdge[];\n scannedAt: number;\n};\n\nexport type ContentAddedEvent = {\n nodes: ScannedNode[];\n edges: StructuralEdge[];\n addedAt: number;\n};\n\nexport type DOMScanner = {\n scan(): Promise<ScanResult>;\n observe(onContentAdded: (event: ContentAddedEvent) => void): void;\n getProminenceScore(element: Element): number;\n destroy(): void;\n};\n\n// ASIDE included to match the initial scan (which queries `section, article,\n// main, aside`) — this set omitted it, so a server-rendered aside was captured\n// while an identical dynamically-inserted one was silently ignored.\nconst OBSERVE_TAGS = new Set(['SECTION', 'ARTICLE', 'MAIN', 'DIV', 'ASIDE']);\nconst HEADING_SELECTOR = 'h1, h2, h3';\n// Selector mirror of the initial scan's criteria (collectNodesAndEdges): any\n// element carrying a declared id, plus structural tags with an aria-label.\n// Used to walk INTO inserted subtrees — a SPA mounts ONE root node whose\n// interesting sections are all descendants, and inspecting only the root made\n// every framework-mounted component permanently invisible to graph capture.\nconst SUBTREE_SELECTOR =\n '[data-sentient-id], section[aria-label], article[aria-label], main[aria-label], aside[aria-label]';\n\n// Sibling detection is O(n²) per group and emits two edges per pair, so a page\n// with hundreds of co-located components (e.g. a 200-cell product grid) would\n// otherwise emit tens of thousands of low-signal sibling edges. We cap the\n// sibling fan-out per group and the total structural edges per detection pass.\n// The total stays well under the server's 2000-edge-per-sync limit, leaving room\n// for semantic edges. Parent→child edges (higher signal) are emitted first, so\n// the cap sheds sibling edges before it ever touches them.\nconst MAX_SIBLINGS_PER_GROUP = 30;\nconst MAX_STRUCTURAL_EDGES = 1500;\n\nconst SSR_SCANNER: DOMScanner = {\n scan: async () => ({ nodes: [], edges: [], scannedAt: 0 }),\n observe: () => undefined,\n getProminenceScore: () => 0,\n destroy: () => undefined,\n};\n\nfunction normalize(value: number, min: number, max: number): number {\n if (max <= min) return 0;\n return Math.max(0, Math.min(1, (value - min) / (max - min)));\n}\n\nfunction readReactComponentName(element: Element): string | undefined {\n try {\n const record = element as unknown as Record<string, unknown>;\n for (const key of Object.keys(record)) {\n if (!key.startsWith('__reactFiber') && !key.startsWith('__reactInternalInstance')) {\n continue;\n }\n const fiber = record[key] as { type?: { name?: string; displayName?: string } };\n const name = fiber?.type?.displayName ?? fiber?.type?.name;\n if (name && name.length > 1) {\n return name;\n }\n }\n } catch {\n /* ignore */\n }\n return undefined;\n}\n\nfunction extractDataAttributes(element: Element): Record<string, string> {\n const attrs: Record<string, string> = {};\n for (const attr of Array.from(element.attributes)) {\n if (attr.name.startsWith('data-')) {\n attrs[attr.name] = attr.value;\n }\n }\n return attrs;\n}\n\nconst SEMANTIC_SET: ReadonlySet<string> = new Set(SEMANTIC_TYPES);\n\n// Explicit tag wins → role → heuristic → generic. Every output is normalized to\n// the graph_nodes enum: an out-of-vocabulary data-sentient-type/role falls\n// through to the heuristic instead of being emitted raw (raw values violated\n// the graph_nodes CHECK constraint on insert).\nfunction inferSemanticType(element: Element): SemanticType {\n const explicit = element.getAttribute('data-sentient-type');\n if (explicit && SEMANTIC_SET.has(explicit)) return explicit as SemanticType;\n const role = element.getAttribute('role');\n if (role && SEMANTIC_SET.has(role)) return role as SemanticType;\n return classifySection(element);\n}\n\n// djb2 over a string → 8-hex-char digest. Stable and collision-resistant enough\n// to disambiguate co-located components that declare no id of their own.\nfunction shortHash(input: string): string {\n let h = 5381;\n for (let i = 0; i < input.length; i++) {\n h = ((h << 5) + h + input.charCodeAt(i)) & 0xffffffff;\n }\n return (h >>> 0).toString(16).padStart(8, '0');\n}\n\n// A structural path (tag + sibling index at each level up to the root) uniquely\n// and stably identifies an element's DOM position, so two id-less sections don't\n// hash to the same value the way a bare tagName would.\nfunction domPathSignature(element: Element): string {\n const parts: string[] = [];\n let current: Element | null = element;\n while (current) {\n const parent: Element | null = current.parentElement;\n if (!parent) {\n parts.push(current.tagName.toLowerCase());\n break;\n }\n const index = Array.prototype.indexOf.call(parent.children, current);\n parts.push(`${current.tagName.toLowerCase()}[${index}]`);\n current = parent;\n }\n return parts.reverse().join('/');\n}\n\n// Prefer an author-declared id. When none exists, synthesize a stable, unique id\n// from the element's DOM path — the old `tagName.toLowerCase()` fallback gave\n// every id-less <section> the same \"section\" id, so a second such node silently\n// overwrote the first in the componentId-keyed graph Map (node loss).\nfunction componentIdFor(element: Element): string {\n const declared =\n element.getAttribute('data-sentient-id') ?? element.getAttribute('id');\n if (declared) return declared;\n return `${element.tagName.toLowerCase()}-${shortHash(domPathSignature(element))}`;\n}\n\nfunction depthOf(element: Element): number {\n let depth = 0;\n let current: Element | null = element.parentElement;\n while (current) {\n depth++;\n current = current.parentElement;\n }\n return depth;\n}\n\nfunction scanElement(\n element: Element,\n getProminenceScore: (el: Element) => number,\n): ScannedNode {\n const heading = element.querySelector(HEADING_SELECTOR);\n return {\n componentId: componentIdFor(element),\n semanticType: inferSemanticType(element),\n ariaLabel: element.getAttribute('aria-label') ?? undefined,\n headingText: heading?.textContent?.trim() ?? undefined,\n isAboveFold: element.getBoundingClientRect().top < window.innerHeight,\n prominenceScore: getProminenceScore(element),\n depth: depthOf(element),\n reactComponentName: readReactComponentName(element),\n dataAttributes: extractDataAttributes(element),\n };\n}\n\n/**\n * Detects structural relationships between scanned component elements:\n * - parent → child (direct ancestor link, weight 0.6)\n * - sibling ↔ sibling (share nearest component ancestor, weight 0.3, bidirectional)\n * A pair appears at most once per direction.\n */\nfunction detectStructuralEdges(elementToId: Map<Element, string>): StructuralEdge[] {\n const edges: StructuralEdge[] = [];\n const seen = new Set<string>();\n const ROOT = '__root__';\n\n // Parent → child: nearest component ancestor only.\n const groups = new Map<string, Element[]>();\n for (const [el, _id] of elementToId) {\n let ancestor: Element | null = el.parentElement;\n let groupKey = ROOT;\n while (ancestor) {\n if (elementToId.has(ancestor)) {\n groupKey = elementToId.get(ancestor)!;\n const childId = elementToId.get(el)!;\n const key = `${groupKey}->${childId}`;\n if (!seen.has(key) && groupKey !== childId) {\n seen.add(key);\n edges.push({ fromComponentId: groupKey, toComponentId: childId, weight: 0.6 });\n }\n break;\n }\n ancestor = ancestor.parentElement;\n }\n const siblings = groups.get(groupKey) ?? [];\n siblings.push(el);\n groups.set(groupKey, siblings);\n }\n\n // Sibling ↔ sibling: same ancestor group.\n for (const sibs of groups.values()) {\n if (sibs.length < 2) continue;\n // Cap the fan-out of any single group before the O(n²) pairing.\n const capped = sibs.length > MAX_SIBLINGS_PER_GROUP ? sibs.slice(0, MAX_SIBLINGS_PER_GROUP) : sibs;\n for (let i = 0; i < capped.length; i++) {\n for (let j = i + 1; j < capped.length; j++) {\n if (edges.length >= MAX_STRUCTURAL_EDGES) return edges;\n const aId = elementToId.get(capped[i]!)!;\n const bId = elementToId.get(capped[j]!)!;\n if (aId === bId) continue;\n const fwd = `${aId}->${bId}::sib`;\n const rev = `${bId}->${aId}::sib`;\n if (!seen.has(fwd)) {\n seen.add(fwd);\n edges.push({ fromComponentId: aId, toComponentId: bId, weight: 0.3 });\n }\n if (!seen.has(rev)) {\n seen.add(rev);\n edges.push({ fromComponentId: bId, toComponentId: aId, weight: 0.3 });\n }\n }\n }\n }\n\n return edges;\n}\n\nfunction collectNodesAndEdges(\n getProminenceScore: (el: Element) => number,\n): { nodes: ScannedNode[]; edges: StructuralEdge[]; elementToId: Map<Element, string> } {\n const nodes: ScannedNode[] = [];\n const seen = new Set<Element>();\n const elementToId = new Map<Element, string>();\n\n const registered = document.querySelectorAll('[data-sentient-id]');\n registered.forEach((el) => {\n if (el instanceof Element && !seen.has(el)) {\n seen.add(el);\n const node = scanElement(el, getProminenceScore);\n nodes.push(node);\n elementToId.set(el, node.componentId);\n }\n });\n\n const structural = document.querySelectorAll('section, article, main, aside');\n structural.forEach((el) => {\n if (!(el instanceof Element) || seen.has(el)) return;\n const hasAria = el.hasAttribute('aria-label');\n const hasSentientId = el.hasAttribute('data-sentient-id');\n if (!hasAria && !hasSentientId) return;\n seen.add(el);\n const node = scanElement(el, getProminenceScore);\n nodes.push(node);\n elementToId.set(el, node.componentId);\n });\n\n return { nodes, edges: detectStructuralEdges(elementToId), elementToId };\n}\n\n/**\n * Creates a DOM scanner that uses idle callbacks and mutation observation.\n */\nexport function createDOMScanner(): DOMScanner {\n if (typeof window === 'undefined') {\n return SSR_SCANNER;\n }\n\n let observer: MutationObserver | null = null;\n let idleCallbackId = 0;\n let contentCallback: ((event: ContentAddedEvent) => void) | null = null;\n // Element→componentId for every node registered so far (initial scan + prior\n // mutations). The MutationObserver detects edges against this whole set — not\n // just the nodes in the current mutation — so a child inserted under an\n // already-scanned parent still gets its parent→child edge.\n const knownElementToId = new Map<Element, string>();\n\n const getProminenceScore = (element: Element): number => {\n try {\n const styles = window.getComputedStyle(element);\n const fontSize = parseFloat(styles.fontSize) || 12;\n const zIndex = parseFloat(styles.zIndex) || 0;\n const rect = element.getBoundingClientRect();\n const distanceFromTop = Math.max(rect.top, 0);\n const viewportHeight = window.innerHeight || 1;\n const inverseDistance = 1 / (distanceFromTop / viewportHeight + 1);\n\n // inverseDistance is already in (0, 1] by construction, so it needs no\n // further normalization — only fontSize and zIndex are rescaled.\n const score =\n normalize(fontSize, 12, 48) * 0.4 +\n inverseDistance * 0.4 +\n normalize(zIndex, 0, 100) * 0.2;\n\n return Math.max(0, Math.min(1, score));\n } catch {\n return 0.5;\n }\n };\n\n const scan = (): Promise<ScanResult> =>\n new Promise((resolve) => {\n const run = (): void => {\n const { nodes, edges, elementToId } = collectNodesAndEdges(getProminenceScore);\n // Seed the known-element registry so the observer can resolve parents that\n // were registered in this scan when later children are inserted.\n knownElementToId.clear();\n for (const [el, id] of elementToId) knownElementToId.set(el, id);\n resolve({ nodes, edges, scannedAt: Date.now() });\n };\n\n try {\n if (typeof requestIdleCallback === 'function') {\n idleCallbackId = requestIdleCallback(run, { timeout: 100 });\n } else {\n run();\n }\n } catch {\n run();\n }\n });\n\n const observe = (onContentAdded: (event: ContentAddedEvent) => void): void => {\n contentCallback = onContentAdded;\n try {\n observer = new MutationObserver((mutations) => {\n const added: ScannedNode[] = [];\n const addedIds = new Set<string>();\n for (const mutation of mutations) {\n if (mutation.type !== 'childList') continue;\n mutation.addedNodes.forEach((node) => {\n if (!(node instanceof Element)) return;\n const candidates: Element[] = [];\n if (\n OBSERVE_TAGS.has(node.tagName) &&\n (node.hasAttribute('data-sentient-id') || node.hasAttribute('aria-label'))\n ) {\n candidates.push(node);\n }\n // Also scan the inserted SUBTREE with the initial scan's criteria\n // (see SUBTREE_SELECTOR): the root of a SPA/framework mount is\n // usually a plain wrapper, and its sections arrive as descendants\n // of ONE childList mutation — inspecting only the root meant they\n // were never captured at all.\n try {\n node.querySelectorAll(SUBTREE_SELECTOR).forEach((el) => candidates.push(el));\n } catch {\n /* exotic host without querySelectorAll — root-only scan stands */\n }\n for (const el of candidates) {\n // Skip elements already registered: a parent and its child can\n // both appear in addedNodes (the child once via the parent's\n // subtree, once directly), which would emit duplicate nodes.\n if (knownElementToId.has(el)) continue;\n const scanned = scanElement(el, getProminenceScore);\n added.push(scanned);\n addedIds.add(scanned.componentId);\n knownElementToId.set(el, scanned.componentId);\n }\n });\n }\n if (added.length === 0 || !contentCallback) return;\n // Drop elements no longer in the document so removed nodes don't dangle\n // and the map stays bounded.\n for (const el of [...knownElementToId.keys()]) {\n if (!el.isConnected) knownElementToId.delete(el);\n }\n // Detect over the FULL known set so a child inserted under an already-\n // scanned parent still gets its parent→child edge, then surface only the\n // edges that touch a newly-added node (existing edges were already emitted).\n const edges = detectStructuralEdges(knownElementToId).filter(\n (e) => addedIds.has(e.fromComponentId) || addedIds.has(e.toComponentId),\n );\n contentCallback({ nodes: added, edges, addedAt: Date.now() });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n } catch {\n /* ignore */\n }\n };\n\n const destroy = (): void => {\n if (observer) {\n observer.disconnect();\n observer = null;\n }\n if (idleCallbackId && typeof cancelIdleCallback === 'function') {\n try {\n cancelIdleCallback(idleCallbackId);\n } catch {\n /* ignore */\n }\n }\n idleCallbackId = 0;\n contentCallback = null;\n knownElementToId.clear();\n };\n\n return {\n scan,\n observe,\n getProminenceScore,\n destroy,\n };\n}\n","/**\n * Graph-capable entry point for @sentientui/core.\n *\n * Import from `@sentientui/core/graph` when you need DOM graph scanning and\n * page-structure sync. This entry pulls in `scanner.ts` and `graph.ts` at\n * build time, giving bundlers a real tree-shaking boundary. Standard A/B tests\n * should use `@sentientui/core` (the lean entry) instead.\n */\n\n// Re-export everything from the lean entry except `init`, which we override\n// below — so a graph consumer never needs dual-entry imports (importing the\n// lean entry alongside this one risks initialising two clients).\nexport {\n detectDeviceClass,\n detectTrafficSource,\n detectTimeOfDay,\n deriveSessionSegment,\n referrerDomainFromReferer,\n grantConsent,\n} from './index.js';\n// Sourced from their own modules (identical bindings to the lean barrel's):\n// snapshot/pre-paint helpers, slot helpers, blocks, micro-signals, and the\n// session cookie name — all were missing here, which made the comment above\n// a lie and forced consumers into dual-entry imports.\nexport {\n SNAPSHOT_STORAGE_KEY_PREFIX,\n readSnapshot,\n writeSnapshot,\n renderPrePaintScript,\n} from './snapshot.js';\nexport type { DecisionSnapshot, SlotConfigEntry, SlotOps, CompoundLocator } from './snapshot.js';\nexport { armOfResult, baselineResultFor, baselineSlots, toWireSlot } from './slots.js';\nexport type { SlotDeclInput, SlotResult } from './slots.js';\nexport * from './blocks.js';\nexport { attachMicroSignalDetectors } from './micro-signals.js';\nexport type { MicroSignalEmitter, MicroSignalType } from './micro-signals.js';\nexport { sessionCookieName, LEGACY_SESSION_COOKIE_NAME } from './storage-key.js';\n// SSR preload helpers moved to `@sentientui/core/server` in 0.6.0.\nexport type {\n SentientConfig,\n AssignResult,\n SentientClient,\n} from './index.js';\nexport type {\n SessionConfig,\n SessionManager,\n EventType,\n SentientEvent,\n QueueConfig,\n Assignment,\n} from './index.js';\n// EventQueue/AssignmentCache are no longer on the lean barrel — source them from\n// their own modules so the `/graph` subpath keeps exposing them unchanged.\nexport type { EventQueue } from './queue.js';\nexport type { AssignmentCache } from './cache.js';\n// Scanner + graph types (live in this entry only).\nexport type {\n ScannedNode,\n ScanResult,\n ContentAddedEvent,\n DOMScanner,\n} from './scanner.js';\nexport type {\n PageNode,\n GraphSnapshot,\n GraphConfig,\n GraphClient,\n} from './graph.js';\nexport { sanitizePageUrl } from './graph.js';\n\nimport {\n init as initLean,\n isDoNotTrackEnabled,\n _registerConsentUpgradeInit,\n type SentientConfig,\n type SentientClient,\n} from './index.js';\nexport { isDoNotTrackEnabled };\nimport { LEGACY_SESSION_COOKIE_NAME, sessionCookieName } from './storage-key.js';\n\nconst DEFAULT_INGEST_URL = 'https://api.sentient-ui.com/v1/events';\nimport { createDOMScanner } from './scanner.js';\nimport { createGraphClient } from './graph.js';\n\nexport type GraphSentientConfig = SentientConfig & {\n /**\n * Enable DOM graph scanning and page-structure sync. Wires a MutationObserver\n * and a localStorage-backed graph. When `false` (default) this entry behaves\n * identically to `@sentientui/core`.\n */\n graph?: boolean;\n /**\n * Include captured heading / DOM text in graph sync payloads. OFF by default —\n * headings can contain account names or user-generated content. Structure\n * (component ids, semantic types, prominence) still syncs when `graph: true`.\n */\n captureDomText?: boolean;\n};\n\n// The client writes the per-project SUFFIXED cookie (sessionCookieName in\n// storage-key.ts). This reader kept the bare `_snt_uid` after namespacing\n// landed, so graph sync sent `sessionId: undefined` for every keyed project.\n// The bare name stays as a fallback for pre-namespacing identities.\nfunction readSntUid(apiKey?: string): string | undefined {\n const read = (name: string): string | undefined => {\n try {\n // Cookie names are `_snt_uid` + `_` + a pk_ key prefix — no regex\n // metacharacters, so interpolation is safe (same pattern as session.ts).\n const m = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`));\n return m ? decodeURIComponent(m[1]!) : undefined;\n } catch {\n return undefined;\n }\n };\n return (apiKey ? read(sessionCookieName(apiKey)) : undefined) ?? read(LEGACY_SESSION_COOKIE_NAME);\n}\n\n/**\n * Graph-capable variant of `init()`. Identical to the lean `init` when\n * `config.graph` is `false` (or omitted). When `config.graph: true`, mounts\n * a DOM scanner + graph client and enables `client.getGraph()`.\n *\n * Import from `@sentientui/core/graph` — do not call the lean `init` alongside\n * this function as that would initialise two clients.\n */\n// Teardown for the graph resources (scanner + MutationObserver + debounce\n// timer + graph client) bound to each apiKey. initLean already disposes the\n// lean client's own timers/listeners on re-init, but it knows nothing about\n// these graph resources, so this entry tracks and tears them down itself —\n// otherwise an HMR / consent-toggle / provider-remount re-init would leak a\n// live MutationObserver and a pending sync timer per mount.\nconst _graphTeardowns = new Map<string, () => void>();\n\nexport function init(config: GraphSentientConfig): SentientClient {\n const client = initLean(config);\n\n // Mirror initLean's opt-out gate: a DNT/GPC visitor (or consent:false) must\n // not get the DOM scanner + graph sync, which POST page-structure beacons and\n // read `_snt_uid` — tracking that bypasses the lean client's own gating, even\n // under `preConsentBehavior: 'statistical_winner'` (audit P1).\n const dntBlocked = config.respectDoNotTrack !== false && isDoNotTrackEnabled();\n const gated = config.consent === false || dntBlocked;\n\n // Zero-network contract, mirroring the lean init's own gate: `localMode:\n // true` forces the on-device engine, and a missing OR INVALID (non-`pk_`)\n // key means the lean client is keyless-local or disabled. This used to check\n // only `!apiKey`, so a typo'd key — which the React provider's default\n // `graph: true` reaches — still mounted the scanner and POSTed\n // /v1/graph/sync into a client that discards everything.\n const keyValid = typeof config.apiKey === 'string' && config.apiKey.startsWith('pk_');\n const zeroNetwork = config.localMode === true || !keyValid;\n if (!config.graph || zeroNetwork || typeof window === 'undefined') return client;\n\n if (gated) {\n // Consent may still be granted later: grantConsent() must re-init through\n // THIS entry so the post-consent client mounts the scanner — the lean init\n // it upgraded through before knows nothing about graph resources, so a\n // consent grant used to lose graph capture for the session. DNT-blocked\n // clients register nothing: consent cannot override a global opt-out.\n if (!dntBlocked) {\n _registerConsentUpgradeInit(config.apiKey, (c) => init(c as GraphSentientConfig));\n }\n return client;\n }\n\n // A prior graph mount for this key is now superseded — tear it down first so\n // its observer/timer don't leak alongside the new mount's.\n const prevTeardown = _graphTeardowns.get(config.apiKey);\n if (prevTeardown) {\n try {\n prevTeardown();\n } catch {\n /* teardown must never throw on re-init */\n }\n }\n\n const domScanner = createDOMScanner();\n const resolvedIngestUrl = config.ingestUrl ?? DEFAULT_INGEST_URL;\n const graphClient = createGraphClient({\n syncUrl: resolvedIngestUrl.replace(/\\/events\\/?$/, '/graph/sync'),\n apiKey: config.apiKey,\n projectId: config.apiKey,\n sessionId: readSntUid(config.apiKey),\n });\n\n // Persisted page-node state from a previous page load is restored by the graph\n // client's own constructor (it reads `_snt_graph_nodes` on creation). We no\n // longer re-read the key and call restore() here — that was a redundant second\n // load path that cleared and reloaded identical data.\n\n void domScanner.scan().then((result) => {\n for (const node of result.nodes) {\n graphClient.addPageNode({\n id: node.componentId,\n componentId: node.componentId,\n semanticType: node.semanticType,\n answers: config.captureDomText && node.headingText ? [node.headingText] : [],\n prominenceScore: node.prominenceScore,\n depth: node.depth,\n });\n }\n for (const edge of result.edges) {\n graphClient.addStructuralEdge(edge);\n }\n graphClient.syncOnce();\n });\n\n let syncDebounceTimer: ReturnType<typeof setTimeout> | null = null;\n const debouncedSync = (): void => {\n if (syncDebounceTimer !== null) clearTimeout(syncDebounceTimer);\n syncDebounceTimer = setTimeout(() => {\n syncDebounceTimer = null;\n graphClient.syncOnce();\n }, 500);\n };\n\n domScanner.observe((event) => {\n for (const node of event.nodes) {\n graphClient.addPageNode({\n id: node.componentId,\n componentId: node.componentId,\n semanticType: node.semanticType,\n answers: config.captureDomText && node.headingText ? [node.headingText] : [],\n prominenceScore: node.prominenceScore,\n depth: node.depth,\n });\n }\n for (const edge of event.edges) {\n graphClient.addStructuralEdge(edge);\n }\n debouncedSync();\n });\n\n // Tears down only the graph resources; the caller pairs it with the lean\n // client's own dispose/destroy. Idempotent, and de-registers itself so a\n // later re-init or teardown can't run it twice on already-freed resources.\n const teardownGraph = (): void => {\n if (syncDebounceTimer !== null) {\n clearTimeout(syncDebounceTimer);\n syncDebounceTimer = null;\n }\n domScanner.destroy();\n graphClient.destroy();\n if (_graphTeardowns.get(config.apiKey) === teardownGraph) {\n _graphTeardowns.delete(config.apiKey);\n }\n };\n _graphTeardowns.set(config.apiKey, teardownGraph);\n\n return {\n ...client,\n getGraph: () => graphClient.snapshot(),\n dispose: () => {\n teardownGraph();\n client.dispose();\n },\n destroy: () => {\n teardownGraph();\n client.destroy();\n },\n };\n}\n"],"mappings":"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","names":["STALE_EDGES_KEY","SEMANTIC_NEIGHBOURS","neighboursFor","semanticType","_a","readStorage","key","fallback","raw","e","writeStorage","value","VALID_SEMANTIC_TYPES","toValidSemanticType","type","sanitizePageUrl","href","u","contentHashOf","componentId","answers","input","h","createGraphClient","config","pageNodes","structuralEdges","nodesKey","storageSuffix","persist","storedNodes","node","edge","_b","nodes","nodesByType","n","list","edges","seen","source","neighbourType","targets","target","componentIds","payload","__spreadProps","__spreadValues","OBSERVE_TAGS","HEADING_SELECTOR","SUBTREE_SELECTOR","MAX_SIBLINGS_PER_GROUP","MAX_STRUCTURAL_EDGES","SSR_SCANNER","normalize","value","min","max","readReactComponentName","element","_a","_b","_c","record","key","fiber","name","e","extractDataAttributes","attrs","attr","SEMANTIC_SET","SEMANTIC_TYPES","inferSemanticType","explicit","role","classifySection","shortHash","input","h","i","domPathSignature","parts","current","parent","index","componentIdFor","declared","depthOf","depth","scanElement","getProminenceScore","heading","detectStructuralEdges","elementToId","edges","seen","ROOT","groups","el","_id","ancestor","groupKey","childId","siblings","sibs","capped","j","aId","bId","fwd","rev","collectNodesAndEdges","nodes","node","hasAria","hasSentientId","createDOMScanner","observer","idleCallbackId","contentCallback","knownElementToId","styles","fontSize","zIndex","rect","distanceFromTop","viewportHeight","inverseDistance","score","resolve","run","id","onContentAdded","mutations","added","addedIds","mutation","candidates","scanned","DEFAULT_INGEST_URL","readSntUid","apiKey","_a","read","name","m","e","sessionCookieName","LEGACY_SESSION_COOKIE_NAME","_graphTeardowns","init","config","client","dntBlocked","isDoNotTrackEnabled","gated","keyValid","zeroNetwork","_registerConsentUpgradeInit","c","prevTeardown","domScanner","createDOMScanner","resolvedIngestUrl","graphClient","createGraphClient","result","node","edge","syncDebounceTimer","debouncedSync","event","teardownGraph","__spreadProps","__spreadValues"]}
|
package/dist/index-local.d.cts
CHANGED
package/dist/index-local.d.ts
CHANGED
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { A as AssignResult, a as Assignment, B as BLOCK_ALIGNS, c as BLOCK_EMPHASES, d as BLOCK_FITS, e as BLOCK_GAPS, f as BLOCK_GRID_COLUMNS, g as BLOCK_HEADING_LEVELS, h as BLOCK_JUSTIFIES, i as BLOCK_RATIOS, j as BLOCK_SIZES, k as BLOCK_TEXT_ALIGNS, l as BLOCK_TONES, m as BLOCK_WEIGHTS, n as BadgeBlock, o as BlockAlign, p as BlockEmphasis, q as BlockFit, r as BlockGap, s as BlockJustify, t as BlockNode, u as BlockRatio, v as BlockSize, w as BlockTextAlign, x as BlockTone, y as BlockWeight, z as ButtonBlock, C as ComponentGoalOptions, D as ComponentWeightEntry, E as CompoundLocator, F as DecideInput, G as DecideOutcome, H as DecisionSnapshot, J as EventType, K as GoalDefinition, L as GoalOptions, N as GraphConfig, O as GraphSnapshot, P as GridBlock, Q as HeadingBlock, R as ImageBlock, S as LEGACY_SESSION_COOKIE_NAME, T as LOCAL_MODE_BANNER, U as LinkBlock, V as MAX_BLOCK_ARMS, W as MAX_BLOCK_CHILDREN, X as MAX_BLOCK_DEPTH, Y as MAX_BLOCK_NODES, Z as MAX_BLOCK_TEXT_LEN, _ as MicroSignalEmitter, $ as MicroSignalType, a0 as PROD_KEYLESS_ERROR, a2 as QueueConfig, a3 as SNAPSHOT_STORAGE_KEY_PREFIX, a4 as SectionMapEntry, a5 as SentientClient, a6 as SentientConfig, a7 as SentientEvent, a8 as SessionConfig, a9 as SessionManager, aa as SitePalette, ab as SlotConfigEntry, ac as SlotOps, ad as SpacerBlock, ae as StackBlock, af as TextBlock, ag as WeightEntry, ah as
|
|
1
|
+
export { A as AssignResult, a as Assignment, B as BLOCK_ALIGNS, c as BLOCK_EMPHASES, d as BLOCK_FITS, e as BLOCK_GAPS, f as BLOCK_GRID_COLUMNS, g as BLOCK_HEADING_LEVELS, h as BLOCK_JUSTIFIES, i as BLOCK_RATIOS, j as BLOCK_SIZES, k as BLOCK_TEXT_ALIGNS, l as BLOCK_TONES, m as BLOCK_WEIGHTS, n as BadgeBlock, o as BlockAlign, p as BlockEmphasis, q as BlockFit, r as BlockGap, s as BlockJustify, t as BlockNode, u as BlockRatio, v as BlockSize, w as BlockTextAlign, x as BlockTone, y as BlockWeight, z as ButtonBlock, C as ComponentGoalOptions, D as ComponentWeightEntry, E as CompoundLocator, F as DecideInput, G as DecideOutcome, H as DecisionSnapshot, J as EventType, K as GoalDefinition, L as GoalOptions, N as GraphConfig, O as GraphSnapshot, P as GridBlock, Q as HeadingBlock, R as ImageBlock, S as LEGACY_SESSION_COOKIE_NAME, T as LOCAL_MODE_BANNER, U as LinkBlock, V as MAX_BLOCK_ARMS, W as MAX_BLOCK_CHILDREN, X as MAX_BLOCK_DEPTH, Y as MAX_BLOCK_NODES, Z as MAX_BLOCK_TEXT_LEN, _ as MicroSignalEmitter, $ as MicroSignalType, a0 as PROD_KEYLESS_ERROR, a2 as QueueConfig, a3 as SNAPSHOT_STORAGE_KEY_PREFIX, a4 as SectionMapEntry, a5 as SentientClient, a6 as SentientConfig, a7 as SentientEvent, a8 as SessionConfig, a9 as SessionManager, aa as SitePalette, ab as SlotConfigEntry, ac as SlotOps, ad as SpacerBlock, ae as StackBlock, af as TextBlock, ag as WeightEntry, ah as _registerConsentUpgradeInit, ai as attachMicroSignalDetectors, aj as grantConsent, ak as init, al as isDoNotTrackEnabled, am as readSnapshot, an as renderPrePaintScript, ap as sessionCookieName, aq as writeSnapshot } from './index-CXxvWxCB.cjs';
|
|
2
2
|
export { A as AGENT_INTENTS, a as AgentIntent, b as SlotDeclInput, c as agentIntent, d as agentUaList, e as armOfResult, f as baselineResultFor, g as baselineSlots, i as classifiedAgents, j as deriveSessionSegment, k as detectDeviceClass, l as detectTimeOfDay, m as detectTrafficSource, n as matchedAgentToken, r as referrerDomainFromReferer, t as toWireSlot, u as uaTokenMatch } from './session-meta-BVvq5RBB.cjs';
|
|
3
3
|
export { SlotResult } from '@sentientui/policy';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { A as AssignResult, a as Assignment, B as BLOCK_ALIGNS, c as BLOCK_EMPHASES, d as BLOCK_FITS, e as BLOCK_GAPS, f as BLOCK_GRID_COLUMNS, g as BLOCK_HEADING_LEVELS, h as BLOCK_JUSTIFIES, i as BLOCK_RATIOS, j as BLOCK_SIZES, k as BLOCK_TEXT_ALIGNS, l as BLOCK_TONES, m as BLOCK_WEIGHTS, n as BadgeBlock, o as BlockAlign, p as BlockEmphasis, q as BlockFit, r as BlockGap, s as BlockJustify, t as BlockNode, u as BlockRatio, v as BlockSize, w as BlockTextAlign, x as BlockTone, y as BlockWeight, z as ButtonBlock, C as ComponentGoalOptions, D as ComponentWeightEntry, E as CompoundLocator, F as DecideInput, G as DecideOutcome, H as DecisionSnapshot, J as EventType, K as GoalDefinition, L as GoalOptions, N as GraphConfig, O as GraphSnapshot, P as GridBlock, Q as HeadingBlock, R as ImageBlock, S as LEGACY_SESSION_COOKIE_NAME, T as LOCAL_MODE_BANNER, U as LinkBlock, V as MAX_BLOCK_ARMS, W as MAX_BLOCK_CHILDREN, X as MAX_BLOCK_DEPTH, Y as MAX_BLOCK_NODES, Z as MAX_BLOCK_TEXT_LEN, _ as MicroSignalEmitter, $ as MicroSignalType, a0 as PROD_KEYLESS_ERROR, a2 as QueueConfig, a3 as SNAPSHOT_STORAGE_KEY_PREFIX, a4 as SectionMapEntry, a5 as SentientClient, a6 as SentientConfig, a7 as SentientEvent, a8 as SessionConfig, a9 as SessionManager, aa as SitePalette, ab as SlotConfigEntry, ac as SlotOps, ad as SpacerBlock, ae as StackBlock, af as TextBlock, ag as WeightEntry, ah as
|
|
1
|
+
export { A as AssignResult, a as Assignment, B as BLOCK_ALIGNS, c as BLOCK_EMPHASES, d as BLOCK_FITS, e as BLOCK_GAPS, f as BLOCK_GRID_COLUMNS, g as BLOCK_HEADING_LEVELS, h as BLOCK_JUSTIFIES, i as BLOCK_RATIOS, j as BLOCK_SIZES, k as BLOCK_TEXT_ALIGNS, l as BLOCK_TONES, m as BLOCK_WEIGHTS, n as BadgeBlock, o as BlockAlign, p as BlockEmphasis, q as BlockFit, r as BlockGap, s as BlockJustify, t as BlockNode, u as BlockRatio, v as BlockSize, w as BlockTextAlign, x as BlockTone, y as BlockWeight, z as ButtonBlock, C as ComponentGoalOptions, D as ComponentWeightEntry, E as CompoundLocator, F as DecideInput, G as DecideOutcome, H as DecisionSnapshot, J as EventType, K as GoalDefinition, L as GoalOptions, N as GraphConfig, O as GraphSnapshot, P as GridBlock, Q as HeadingBlock, R as ImageBlock, S as LEGACY_SESSION_COOKIE_NAME, T as LOCAL_MODE_BANNER, U as LinkBlock, V as MAX_BLOCK_ARMS, W as MAX_BLOCK_CHILDREN, X as MAX_BLOCK_DEPTH, Y as MAX_BLOCK_NODES, Z as MAX_BLOCK_TEXT_LEN, _ as MicroSignalEmitter, $ as MicroSignalType, a0 as PROD_KEYLESS_ERROR, a2 as QueueConfig, a3 as SNAPSHOT_STORAGE_KEY_PREFIX, a4 as SectionMapEntry, a5 as SentientClient, a6 as SentientConfig, a7 as SentientEvent, a8 as SessionConfig, a9 as SessionManager, aa as SitePalette, ab as SlotConfigEntry, ac as SlotOps, ad as SpacerBlock, ae as StackBlock, af as TextBlock, ag as WeightEntry, ah as _registerConsentUpgradeInit, ai as attachMicroSignalDetectors, aj as grantConsent, ak as init, al as isDoNotTrackEnabled, am as readSnapshot, an as renderPrePaintScript, ap as sessionCookieName, aq as writeSnapshot } from './index-BbrtAtrY.js';
|
|
2
2
|
export { A as AGENT_INTENTS, a as AgentIntent, b as SlotDeclInput, c as agentIntent, d as agentUaList, e as armOfResult, f as baselineResultFor, g as baselineSlots, i as classifiedAgents, j as deriveSessionSegment, k as detectDeviceClass, l as detectTimeOfDay, m as detectTrafficSource, n as matchedAgentToken, r as referrerDomainFromReferer, t as toWireSlot, u as uaTokenMatch } from './session-meta-BVvq5RBB.js';
|
|
3
3
|
export { SlotResult } from '@sentientui/policy';
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var mt=Object.create;var pe=Object.defineProperty,yt=Object.defineProperties,ht=Object.getOwnPropertyDescriptor,St=Object.getOwnPropertyDescriptors,vt=Object.getOwnPropertyNames,ze=Object.getOwnPropertySymbols,wt=Object.getPrototypeOf,Je=Object.prototype.hasOwnProperty,xt=Object.prototype.propertyIsEnumerable;var Qe=(e,t,n)=>t in e?pe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,k=(e,t)=>{for(var n in t||(t={}))Je.call(t,n)&&Qe(e,n,t[n]);if(ze)for(var n of ze(t))xt.call(t,n)&&Qe(e,n,t[n]);return e},oe=(e,t)=>yt(e,St(t));var bt=(e,t)=>{for(var n in t)pe(e,n,{get:t[n],enumerable:!0})},Ve=(e,t,n,c)=>{if(t&&typeof t=="object"||typeof t=="function")for(let u of vt(t))!Je.call(e,u)&&u!==n&&pe(e,u,{get:()=>t[u],enumerable:!(c=ht(t,u))||c.enumerable});return e};var kt=(e,t,n)=>(n=e!=null?mt(wt(e)):{},Ve(t||!e||!e.__esModule?pe(n,"default",{value:e,enumerable:!0}):n,e)),Et=e=>Ve(pe({},"__esModule",{value:!0}),e);var yn={};bt(yn,{AGENT_INTENTS:()=>Oe,BLOCK_ALIGNS:()=>zt,BLOCK_EMPHASES:()=>Yt,BLOCK_FITS:()=>en,BLOCK_GAPS:()=>Ht,BLOCK_GRID_COLUMNS:()=>tn,BLOCK_HEADING_LEVELS:()=>nn,BLOCK_JUSTIFIES:()=>Qt,BLOCK_RATIOS:()=>Zt,BLOCK_SIZES:()=>Jt,BLOCK_TEXT_ALIGNS:()=>qt,BLOCK_TONES:()=>Xt,BLOCK_WEIGHTS:()=>Vt,LEGACY_SESSION_COOKIE_NAME:()=>Me,LOCAL_MODE_BANNER:()=>$e,MAX_BLOCK_ARMS:()=>an,MAX_BLOCK_CHILDREN:()=>sn,MAX_BLOCK_DEPTH:()=>rn,MAX_BLOCK_NODES:()=>on,MAX_BLOCK_TEXT_LEN:()=>ln,PROD_KEYLESS_ERROR:()=>De,SNAPSHOT_STORAGE_KEY_PREFIX:()=>te,agentIntent:()=>nt,agentUaList:()=>fe,armOfResult:()=>Te,attachMicroSignalDetectors:()=>ct,baselineResultFor:()=>ie,baselineSlots:()=>st,classifiedAgents:()=>ot,deriveSessionSegment:()=>rt,detectDeviceClass:()=>ye,detectTimeOfDay:()=>ve,detectTrafficSource:()=>he,grantConsent:()=>fn,init:()=>ft,isDoNotTrackEnabled:()=>je,matchedAgentToken:()=>Ue,readSnapshot:()=>Re,referrerDomainFromReferer:()=>Se,renderPrePaintScript:()=>it,sessionCookieName:()=>Ee,toWireSlot:()=>we,uaTokenMatch:()=>me,writeSnapshot:()=>ae});module.exports=Et(yn);function ke(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}try{if(typeof crypto!="undefined"&&typeof crypto.getRandomValues=="function"){let e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t="";for(let n=0;n<16;n++)t+=e[n].toString(16).padStart(2,"0"),(n===3||n===5||n===7||n===9)&&(t+="-");return t}}catch(e){}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function ge(e){return e?`_${e.slice(0,12)}`:""}var Me="_snt_uid";function Ee(e){return`${Me}${ge(e)}`}var It="_snt_uid",Ct=365,Ne="_snt_uid";function _t(){return ke()}function Xe(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function At(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(c){}}function Ye(e){try{return localStorage.getItem(e)}catch(t){return null}}function Ot(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function qe(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function Tt(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function Rt(e){try{sessionStorage.removeItem(e)}catch(t){}}function Bt(e){try{return document.cookie=`${e}_probe=1; max-age=1; SameSite=strict; path=/`,document.cookie.indexOf(`${e}_probe=1`)!==-1}catch(t){return!1}}function Lt(e){try{localStorage.removeItem(e)}catch(t){}}function Dt(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var Pt={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function Ie(e){var b,D,C,_,O,K,A;if(typeof window=="undefined")return Pt;let t=ge(e==null?void 0:e.apiKey),n=(b=e==null?void 0:e.cookieName)!=null?b:Ee(e==null?void 0:e.apiKey),c=`${Ne}${t}`,i=((D=e==null?void 0:e.cookieTTLDays)!=null?D:Ct)*24*60*60,p=S=>S&&S.length>0?S:null,a=()=>{var S,R;return t&&!(e!=null&&e.cookieName)?(R=(S=p(Xe(It)))!=null?S:p(Ye(Ne)))!=null?R:p(qe(Ne)):null},r=(A=(K=(O=(_=(C=p(Xe(n)))!=null?C:p(Ye(c)))!=null?_:p(qe(c)))!=null?O:a())!=null?K:p(e==null?void 0:e.ssrSessionId))!=null?A:_t();At(n,r,i);let o=Ot(c,r),s=Bt(n),l=o?!1:Tt(c,r),y=!o&&!s&&!l;return{getSessionId:()=>r,isEphemeral:()=>y,destroy:()=>{r=null,Dt(n),Lt(c),Rt(c)}}}function q(e){return Math.min(6e4,1e3*2**Math.min(e,6))}function re(e){if(e.ok===!0)return"delivered";let{status:t}=e;return typeof t!="number"?"retry":t>=200&&t<300?"delivered":t>=400&&t<500&&t!==429?"dropped":"retry"}function Ce(e,t){try{let n=localStorage.getItem(e);if(!n)return[];let c=JSON.parse(n);return Array.isArray(c)?(localStorage.removeItem(e),c.slice(-t)):[]}catch(n){return[]}}function Z(e,t,n){try{let c=(()=>{try{let i=localStorage.getItem(n);if(!i)return[];let p=JSON.parse(i);return Array.isArray(p)?p:[]}catch(i){return[]}})(),u=new Map;for(let i of c)u.set(i.id,i);for(let i of e)u.set(i.id,i);localStorage.setItem(n,JSON.stringify([...u.values()].slice(-t)))}catch(c){}}function _e(e,t){try{let n=localStorage.getItem(t);if(!n)return;let c=JSON.parse(n);if(!Array.isArray(c))return;let u=new Set(e),i=c.filter(p=>!u.has(p.id));if(i.length===c.length)return;i.length===0?localStorage.removeItem(t):localStorage.setItem(t,JSON.stringify(i))}catch(n){}}var Mt=500,Nt=56*1024;function Ke(e){return`_snt_retry_${e.slice(0,12)}`}var Kt={push:()=>{},flush:()=>{},destroy:()=>{}};function Ze(e){var J,M,j;if(typeof window=="undefined")return Kt;let t=(J=e.flushIntervalMs)!=null?J:5e3,n=(M=e.maxBatchSize)!=null?M:20,c=(j=e.maxRetrySize)!=null?j:100,u=e.ingestUrl,i=e.apiKey,p=Ke(i),a=[],r=new Set,o=[],s=f=>{for(let w of f)l.delete(w),!r.has(w)&&(r.add(w),o.push(w));for(;o.length>Mt;){let w=o.shift();w&&r.delete(w)}_e(f,p)},l=new Set,y=f=>{r.has(f.id)||l.has(f.id)||(l.add(f.id),a.push(f))},b=f=>{for(let w of f)r.has(w.id)||(l.add(w.id),a.push(w))},D=Ce(p,c);for(let f of D)y(f);let C=0,_=0,O=(f,w=!0)=>{if(f.length===0)return;let H=JSON.stringify(f),ee=f.map(V=>V.id),F;try{F=fetch(u,{method:"POST",keepalive:!0,body:H,headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`}})}catch(V){Z(f,c,p),b(f),_++,C=Date.now()+q(_);return}let le=V=>{if(re(V)!=="retry"){if(!V.ok&&w){let ne=f.filter(X=>X.eventType!=="pageview");if(ne.length>0&&ne.length<f.length){s(f.filter(X=>X.eventType==="pageview").map(X=>X.id)),O(ne,!1);return}}s(ee),_=0,C=0;return}Z(f,c,p),b(f),_++,C=Date.now()+q(_)};F instanceof Promise?F.then(le).catch(()=>{Z(f,c,p),b(f),_++,C=Date.now()+q(_)}):le(F)},K=typeof TextEncoder!="undefined"?new TextEncoder:null,A=f=>K?K.encode(f).length:f.length,S=f=>{let w=[],H=2;for(let ee of f){let F=A(JSON.stringify(ee))+1;if(w.length>0&&H+F>Nt||w.length>=n)break;w.push(ee),H+=F}return w},R=()=>{try{if(Date.now()<C)return;for(;a.length>0&&!(Date.now()<C);){let f=a.filter(H=>!r.has(H.id));if(a.length=0,f.length===0)break;let w=S(f);if(w.length===0)break;w.length<f.length&&a.push(...f.slice(w.length)),O(w)}}catch(f){}},G=!0,m=null;m=setInterval(()=>{G&&R()},t);let E=()=>{document.visibilityState==="hidden"&&R()},Q=()=>{R()};return document.addEventListener("visibilitychange",E),window.addEventListener("pagehide",Q),{push(f){y(f),a.length>=n&&R()},flush:R,destroy(){G=!1,m!==null&&(clearInterval(m),m=null),document.removeEventListener("visibilitychange",E),window.removeEventListener("pagehide",Q),R()}}}var Gt=200;function Ge(e){return`_snt_goal_retry_${e.slice(0,12)}`}var Ut={send:()=>{},flush:()=>{},destroy:()=>{}};function et(e){var S,R,G;if(typeof window=="undefined")return Ut;let t=(S=e.flushIntervalMs)!=null?S:5e3,n=(R=e.maxRetrySize)!=null?R:100,c=(G=e.maxPerFlush)!=null?G:5,u=Ge(e.apiKey),i=[],p=new Set,a=new Set,r=[],o=0,s=0,l=!1,y=m=>{for(p.delete(m.id),a.has(m.id)||(a.add(m.id),r.push(m.id));r.length>Gt;){let E=r.shift();E&&a.delete(E)}_e([m.id],u)},b=m=>{Z([m],n,u),!a.has(m.id)&&!p.has(m.id)&&(p.add(m.id),i.push(m)),Date.now()>=o&&(s++,o=Date.now()+q(s))},D=m=>{let E;try{E=fetch(e.url,{method:"POST",keepalive:!0,body:m.body,headers:e.headers})}catch(J){b(m);return}let Q=J=>{var j;let M=re(J);if(M==="retry"){b(m);return}M==="dropped"&&((j=e.onDrop)==null||j.call(e,m,J.status)),y(m),s=0,o=0};E instanceof Promise?E.then(Q).catch(()=>b(m)):Q(E)},C=()=>{try{if(l||Date.now()<o)return;let m=0;for(;i.length>0&&m<c&&!(Date.now()<o);){let E=i.shift();p.delete(E.id),!a.has(E.id)&&(m++,D(E))}}catch(m){}},_=Ce(u,n);for(let m of _)p.has(m.id)||(p.add(m.id),i.push(m));_.length>0&&Z(_,n,u);let O=setInterval(C,t),K=()=>{document.visibilityState==="hidden"&&C()},A=()=>C();return document.addEventListener("visibilitychange",K),window.addEventListener("pagehide",A),{send(m){if(!l&&!(a.has(m.id)||p.has(m.id))){if(Date.now()<o){Z([m],n,u),p.add(m.id),i.push(m);return}D(m)}},flush:C,destroy(){clearInterval(O),document.removeEventListener("visibilitychange",K),window.removeEventListener("pagehide",A),C(),l=!0}}}var $t=1800*1e3;function Ae(e,t){return`${encodeURIComponent(e)}:${encodeURIComponent(t)}`}function tt(e=$t,t){let n=new Map,c=`_snt_asgn${ge(t)}_`,u=(o,s)=>`${c}${encodeURIComponent(o)}:${encodeURIComponent(s)}`,i=o=>{let s=o.slice(c.length),l=s.indexOf(":");if(l<0)return null;try{return{componentId:decodeURIComponent(s.slice(0,l)),segment:decodeURIComponent(s.slice(l+1))}}catch(y){return null}},p=()=>{try{let o=[];for(let s=0;s<localStorage.length;s++){let l=localStorage.key(s);l!=null&&l.startsWith(c)&&o.push(l)}return o}catch(o){return[]}},a=o=>o.assignedAt+(o.ttlMs&&o.ttlMs>0?o.ttlMs:e)<Date.now();return typeof window!="undefined"&&(()=>{for(let o of p())try{let s=localStorage.getItem(o);if(!s)continue;let l=JSON.parse(s);if(a(l)){localStorage.removeItem(o);continue}let y=i(o);if(!y)continue;n.set(Ae(y.componentId,y.segment),l)}catch(s){}})(),{get(o,s){let l=n.get(Ae(o,s));return l?a(l)?(n.delete(Ae(o,s)),null):l:null},set(o,s,l){let y=Ae(o,s);n.set(y,l);try{localStorage.setItem(u(o,s),JSON.stringify(l))}catch(b){}},invalidate(o){let s=`${encodeURIComponent(o)}:`;for(let l of[...n.keys()])l.startsWith(s)&&n.delete(l);for(let l of p()){let y=i(l);if((y==null?void 0:y.componentId)===o)try{localStorage.removeItem(l)}catch(b){}}},clear(){n.clear();for(let o of p())try{localStorage.removeItem(o)}catch(s){}}}}var fe=["GPTBot","ChatGPT-User","OAI-SearchBot","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","Meta-ExternalAgent","Bytespider","CCBot","Amazonbot","cohere-ai","Diffbot"];function me(e){return Ue(e)!==null}function Ue(e){var n;if(!e)return null;let t=e.toLowerCase();return(n=fe.find(c=>t.includes(c.toLowerCase())))!=null?n:null}var Oe={GPTBot:"training","ChatGPT-User":"user","OAI-SearchBot":"search",ClaudeBot:"training","Claude-User":"user","Claude-SearchBot":"search",PerplexityBot:"search","Perplexity-User":"user","Google-Extended":"training","Applebot-Extended":"training","Meta-ExternalAgent":"training",Bytespider:"training",CCBot:"training",Amazonbot:"other","cohere-ai":"training",Diffbot:"other"};function nt(e){if(!e)return"other";let t=fe.find(n=>n.toLowerCase()===e.toLowerCase());return t&&Oe[t]||"other"}function ot(){var t;let e={user:[],search:[],training:[],other:[]};for(let n of fe)e[(t=Oe[n])!=null?t:"other"].push(n);return e}function ye(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function he(e,t){if(!e)return"direct";try{let n=new URL(e);if(t)try{if(new URL(t).host===n.host)return"direct"}catch(u){}let c=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(c)?"search":/(^|\.)(twitter\.com|x\.com|facebook\.com|linkedin\.com|reddit\.com|t\.co)$/.test(c)?"social":"referral"}catch(n){return"direct"}}function Se(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function ve(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function rt(e){let t=Ft("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function Ft(e,t){var i,p,a,r,o,s,l;let n=(p=(i=t==null?void 0:t.userAgent)==null?void 0:i.trim())!=null?p:"",c=(r=(a=t==null?void 0:t.referer)==null?void 0:a.trim())!=null?r:"",u=(o=t==null?void 0:t.now)!=null?o:new Date;return{sessionId:e,ephemeral:!1,utmParams:(s=t==null?void 0:t.utmParams)!=null?s:{},deviceClass:n?ye(n):"desktop",trafficSource:c?he(c,t==null?void 0:t.appOrigin):"direct",referrerDomain:Se(c),timeOfDay:ve(u),dayOfWeek:(l=["sun","mon","tue","wed","thu","fri","sat"][u.getDay()])!=null?l:"sun",automation:(t==null?void 0:t.webdriver)===!0||me(n)}}var se=require("@sentientui/policy");function we(e){return k(k(k({id:e.id},e.arms?{arms:[...e.arms]}:{}),e.dims?{dims:Object.fromEntries(Object.entries(e.dims).map(([t,n])=>[t,[...n]]))}:{}),e.baseline!==void 0?{baseline:e.baseline}:{})}function ie(e){let t=we(e);return(0,se.slotResultFor)(t,(0,se.slotBaselineArm)(t))}function st(e){let t={};for(let n of e)t[n.id]=ie(n);return t}function Te(e){return typeof e=="string"?e:(0,se.canonicalArm)(e)}var te="_snt_snap:",Wt=["low","medium","high"];function Re(e){try{let t=localStorage.getItem(te+e);if(!t)return null;let n=JSON.parse(t);return!n||typeof n!="object"||n.v!==1||typeof n.persona!="string"||typeof n.band!="string"||!Wt.includes(n.band)||typeof n.slots!="object"||n.slots===null||Array.isArray(n.slots)||!(n.layoutOrder===null||Array.isArray(n.layoutOrder))||typeof n.savedAt!="number"||!(n.slotConfig===void 0||typeof n.slotConfig=="object"&&n.slotConfig!==null&&!Array.isArray(n.slotConfig))?null:n}catch(t){return null}}function ae(e,t){try{localStorage.setItem(te+e,JSON.stringify(t))}catch(n){}}function it(e){return"(function(){try{var r=localStorage.getItem("+JSON.stringify(te+e).replace(/</g,"\\u003c")+');if(!r)return;var s=JSON.parse(r);if(!s||s.v!==1||typeof s.persona!=="string"||typeof s.band!=="string")return;var d=document.documentElement;if(d.hasAttribute("data-sentient-persona"))return;d.setAttribute("data-sentient-persona",s.persona);d.setAttribute("data-sentient-confidence",s.band);}catch(e){}})();'}var We=require("@sentientui/policy");var Le=require("@sentientui/policy");var De="[sentient] No API key configured \u2014 nothing is being learned. Set NEXT_PUBLIC_SENTIENT_API_KEY or pass localMode: true for local development.",$e="[sentient] Local mode \u2014 decisions are simulated on-device and nothing is sent over the network. Add an API key to learn from real traffic.",at=!1,Be=!1;function jt(){var e;try{return(e=new URLSearchParams(window.location.search).get("sentient_persona"))!=null?e:void 0}catch(t){return}}function lt(e){var a;let t=Ie({ssrSessionId:e.ssrSessionId,apiKey:e.apiKey}),n=(a=t.getSessionId())!=null?a:"local",c=jt(),u=import("@sentientui/core/local").then(r=>{let o=r;return o.LOCAL_ENGINE_AVAILABLE?(at||(at=!0,console.info($e)),o):(Be||(Be=!0,console.error(De)),null)}).catch(()=>(Be||(Be=!0,console.error(De)),null)),i=null;function p(r){let o=document.documentElement;o.dataset.sentientPersona===void 0&&(o.dataset.sentientPersona=r.persona,o.dataset.sentientConfidence=(0,Le.confidenceBand)(r.confidence))}return{isLocal:!0,async decide(r){var l,y,b;let o=await u;if(!o)return null;let s=o.createLocalEngine({sessionId:n,forcedPersona:c}).decide(r);return i=oe(k({},s),{layoutOrder:(y=(l=s.layoutOrder)!=null?l:i==null?void 0:i.layoutOrder)!=null?y:null,slots:k(k({},(b=i==null?void 0:i.slots)!=null?b:{}),s.slots)}),ae(e.apiKey||"local",{v:1,persona:i.persona,band:(0,Le.confidenceBand)(i.confidence),slots:i.slots,layoutOrder:i.layoutOrder,savedAt:Date.now()}),p(s),s},getSlotResult(r){var o,s,l;return(l=(s=i==null?void 0:i.slots[r])!=null?s:(o=e.initialSlots)==null?void 0:o[r])!=null?l:null},getPersona(){return i?{persona:i.persona,confidence:i.confidence,band:(0,Le.confidenceBand)(i.confidence)}:null},async assign(r,o){var y;let s=await u;return!s||!o||o.length===0?o!=null&&o[0]?{variantId:o[0],assignmentTtlMs:0}:null:{variantId:(y=s.createLocalEngine({sessionId:n,forcedPersona:c}).decide({components:[{id:r,variantIds:o}]}).assignments[r])!=null?y:o[0],assignmentTtlMs:0}},track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>t.destroy()}}var Ht=["none","sm","md","lg"],zt=["start","center","end","stretch"],Qt=["start","center","end","between"],Jt=["sm","md","lg"],Vt=["normal","medium","bold"],Xt=["default","muted","accent"],Yt=["primary","secondary","ghost"],qt=["left","center","right"],Zt=["auto","square","landscape","wide"],en=["cover","contain"],tn=[2,3,4],nn=[2,3,4],on=64,rn=5,sn=12,an=4,ln=500;function ct(e,t,n,c){let u=[];{let a=!1,r=[],o=()=>{if(a)return;let s=Date.now();for(r.push(s);r.length>0&&s-r[0]>500;)r.shift();r.length>=3&&(a=!0,e("rage_click"))};t.addEventListener("click",o),u.push(()=>t.removeEventListener("click",o))}{let i=!1,p=a=>{if(i||!(a.target instanceof Node)||!t.contains(a.target)&&t!==a.target)return;i=!0;let r=typeof window!="undefined"?window.getSelection():null,o=r?r.toString().length:0;e("text_copy",{selectionLength:o})};document.addEventListener("copy",p),u.push(()=>document.removeEventListener("copy",p))}{let i=!1,p=!1,a=null,r=()=>{a!==null&&(clearTimeout(a),a=null)},o=()=>{i||!p||(r(),a=setTimeout(()=>{!i&&p&&(i=!0,e("scroll_hesitation"))},3e3))},s=()=>{r(),o()},l=b=>{for(let D of b)p=D.intersectionRatio>.3,p?o():r()},y=new IntersectionObserver(l,{threshold:[.3]});y.observe(t),window.addEventListener("scroll",s,{passive:!0}),u.push(()=>{y.disconnect(),window.removeEventListener("scroll",s),r()})}if((c==null?void 0:c.tabLoss)!==!1){let i=!1,p=n!=null?n:Date.now(),a=()=>{if(i||document.visibilityState!=="hidden")return;let r=Date.now()-p;r<15e3&&(i=!0,e("tab_loss",{timeOnPage:r}))};document.addEventListener("visibilitychange",a),u.push(()=>document.removeEventListener("visibilitychange",a))}return()=>{for(let i of u)i()}}var dt="https://api.sentient-ui.com/v1/events",N=new Map,ut=null;function cn(e){return"value"in e||"currency"in e||"externalId"in e||"metadata"in e||"weight"in e||"stepIndex"in e}var dn=3;function Fe(){return ke()}function Pe(){var e;if(typeof window!="undefined")return((e=window.location)==null?void 0:e.pathname)||void 0}function un(){let e=new WeakMap,t=new Map,n=!1,c=(a,r,o)=>{let s=a.get(r);return o===null?s?!0:(a.set(r,new Set),!1):s?s.has(o)?!0:(s.add(o),!1):(a.set(r,new Set([o])),!1)},u=typeof window!="undefined"&&"event"in window,i=()=>{if(!u)return;let a=window.event;return typeof Event=="function"&&a instanceof Event?a:void 0},p=()=>{if(u){Promise.resolve().then(()=>{n=!1,t.clear()});return}let a=!1,r=()=>{a||(a=!0,n=!1,t.clear())};if(setTimeout(r,0),typeof MessageChannel=="function"){let o=new MessageChannel;o.port1.onmessage=()=>{o.port1.close(),o.port2.close(),r()},o.port2.postMessage(0)}};return{firedBefore(a,r){let o=i();if(o){let l=e.get(o);return l||(l=new Map,e.set(o,l)),c(l,a,r)}let s=c(t,a,r);return!s&&!n&&(n=!0,p()),s}}}var pt=new Set;function pn(e,t,n){let c=typeof window=="undefined"?null:window.history;if(!c)return()=>{};let u=!1,i,p=()=>{if(u)return;let o=Pe();!o||o===i||(i=o,e.track({projectId:t,componentId:"__page__",eventType:"pageview",payload:{}}),n(`${t}:${o}`))},a=[];for(let o of["pushState","replaceState"]){let s=c[o],l=function(...y){let b=s.apply(this,y);return p(),b};c[o]=l,a.push([o,s,l])}window.addEventListener("popstate",p);let r=Pe();return r&&pt.has(`${t}:${r}`)?i=r:p(),()=>{if(!u){u=!0,window.removeEventListener("popstate",p);for(let[o,s,l]of a)c[o]===l&&(c[o]=s)}}}var xe={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),decide:()=>Promise.resolve(null),getSlotResult:()=>null,getPersona:()=>null,fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>{}};function gn(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,c]of t)n.startsWith("utm_")&&(e[n]=c);return e}catch(e){return{}}}function gt(e){return e.replace(/\/events\/?$/,"")}function je(){return typeof navigator!="undefined"&&navigator.globalPrivacyControl===!0?!0:[typeof navigator!="undefined"?navigator.doNotTrack:void 0,typeof window!="undefined"?window.doNotTrack:void 0,typeof navigator!="undefined"?navigator.msDoNotTrack:void 0].some(t=>t==="1"||t==="yes")}function fn(e){var a;if(typeof window=="undefined")return;let t=e!=null?e:ut;if(!t){console.warn("[sentient] grantConsent() called before init()");return}let n=N.get(t);if(!n){console.warn("[sentient] grantConsent() called before init()");return}let{config:c,upgrade:u}=n;if(!u||c.respectDoNotTrack!==!1&&je())return;let i=ft(oe(k({},c),{consent:!0}));u(i);let p=(a=N.get(t))==null?void 0:a.dispose;N.set(t,{config:oe(k({},c),{consent:!0}),upgrade:null,dispose:p})}function mn(e){var a;let t=e.preConsentBehavior==="statistical_winner",n=gt((a=e.ingestUrl)!=null?a:dt),c={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},u={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),async assign(r,o,s){if(!t)return null;try{let l=new URLSearchParams({componentId:r});for(let D of o!=null?o:[])l.append("variantIds[]",D);let y=await fetch(`${n}/winner?${l.toString()}`,{headers:c});return y.ok?{variantId:(await y.json()).variantId,assignmentTtlMs:0}:o!=null&&o[0]?{variantId:o[0],assignmentTtlMs:0}:null}catch(l){return o!=null&&o[0]?{variantId:o[0],assignmentTtlMs:0}:null}},decide:()=>Promise.resolve(null),getSlotResult:()=>null,getPersona:()=>null,getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>{}},i={track:r=>u.track(r),goal:((r,o,s,l)=>u.goal(r,o,s,l)),componentGoal:(r,o,s)=>u.componentGoal(r,o,s),identify:r=>u.identify(r),getAssignment:(r,o)=>u.getAssignment(r,o),assign:(r,o,s,l)=>u.assign(r,o,s,l),decide:r=>u.decide(r),getSlotResult:r=>u.getSlotResult(r),getPersona:()=>u.getPersona(),fetchWeights:()=>u.fetchWeights(),getGraph:()=>u.getGraph(),dispose:()=>u.dispose(),destroy:()=>u.destroy()};function p(r){u=r}return{proxy:i,setInner:p}}function ft(e){var w,H,ee,F,le,V,ne,X,He;if(typeof window=="undefined")return xe;ut=e.apiKey;let t=N.get(e.apiKey||"local");if(t!=null&&t.dispose)try{t.dispose()}catch(d){}let n=e.respectDoNotTrack!==!1&&je(),c=e.consent===!1||n,u=typeof e.apiKey=="string"&&e.apiKey.startsWith("pk_");if(e.localMode===!0||!u&&e.localMode!==!1)return c?(N.set(e.apiKey||"local",{config:e,upgrade:null}),xe):(N.set(e.apiKey||"local",{config:e,upgrade:null}),lt(e));if(c){if(!e.apiKey||!e.apiKey.startsWith("pk_"))return e.preConsentBehavior==="statistical_winner"&&console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),N.set(e.apiKey,{config:e,upgrade:null}),xe;let{proxy:d,setInner:g}=mn(e);return N.set(e.apiKey,{config:e,upgrade:n?null:g}),d}if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),xe;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),xe;let i=(w=e.ingestUrl)!=null?w:dt,p=Date.now(),a=Ie({ssrSessionId:e.ssrSessionId,apiKey:e.apiKey}),r=tt(void 0,e.apiKey),o=Ze({ingestUrl:i,apiKey:e.apiKey}),s=gt(i),l={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},y=new Set,b=et({url:`${s}/goals`,apiKey:e.apiKey,headers:l,onDrop:(d,g)=>{if(!e.debug){if(y.has(g))return;y.add(g)}console.warn(`[sentient] goal dropped (HTTP ${g}) \u2014 this will not be retried. `+(g===400?"The session was not found: call init() and let the session upsert complete before firing goals.":g===401||g===403?"Check the API key and that this origin is on the project allowlist.":"See the response status for the cause."),d)}}),D=ye((H=navigator.userAgent)!=null?H:""),C=typeof window!="undefined"?window.location.origin:void 0,_=he((ee=document.referrer)!=null?ee:"",C),O=(F=e.sessionSegment)!=null?F:`${D}:${_}`,K=new Map,A=new Map,S=null,R=d=>{for(let g of d)A.has(g.id)||A.set(g.id,ie(g))};if(e.initialSlots)for(let[d,g]of Object.entries(e.initialSlots))A.set(d,g);let G=Re(e.apiKey);if(G)for(let[d,g]of Object.entries(G.slots))A.has(d)||A.set(d,g);let m={low:.15,medium:.5,high:.85};if(e.initialPersona)S=k({},e.initialPersona);else{let d=document.documentElement.dataset;d.sentientPersona?S={persona:d.sentientPersona,confidence:(V=m[(le=d.sentientConfidence)!=null?le:"low"])!=null?V:.15}:G&&(S={persona:G.persona,confidence:(ne=m[G.band])!=null?ne:.15})}if(e.initialAssignments)for(let[d,g]of Object.entries(e.initialAssignments))r.set(d,O,{variantId:g,assignedAt:Date.now(),segment:O,confidence:1});let E=Promise.resolve(),Q=a.getSessionId();if(Q){let d=Se((X=document.referrer)!=null?X:""),g=k(k(k({sessionId:Q,deviceClass:D,trafficSource:_,referrerDomain:d,utmParams:gn(),timeOfDay:ve(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:a.isEphemeral(),automation:typeof navigator!="undefined"&&navigator.webdriver===!0||me((He=navigator.userAgent)!=null?He:"")},e.userId?{userId:e.userId}:{}),e.persona?{persona:e.persona}:{}),e.country?{country:e.country}:{}),h=async()=>{for(let T=0;;T++){try{let I=await fetch(`${s}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(g),headers:l});if(I.status===402){console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing");return}if(I.ok||re(I)==="dropped")return}catch(I){}if(T>=dn){console.warn("[SentientUI] Could not register the session after retries. Conversions in this visit may not be recorded.");return}await new Promise(I=>setTimeout(I,q(T+1)))}};try{E=h()}catch(T){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:o});let J=un(),M=null,j=!1,f={goal(d,g={},h=1,T=0){var ce,$,de,x,Y,be,L;let I=a.getSessionId();if(!I)return;let v=cn(g)?g:{metadata:g},z=[d,(ce=v.externalId)!=null?ce:"",($=v.stepIndex)!=null?$:T,(de=v.weight)!=null?de:h].join("\0"),W=v.value!==void 0?`${v.value}\0${(x=v.currency)!=null?x:""}`:null;if(J.firedBefore(z,W)){e.debug&&console.log(`[sentient] goal("${d}") already recorded for this action \u2014 not sent twice`);return}let B=Fe(),U={sessionId:I,name:d,metadata:(Y=v.metadata)!=null?Y:{},weight:(be=v.weight)!=null?be:h,stepIndex:(L=v.stepIndex)!=null?L:T,goalId:B,value:v.value,currency:v.currency,externalId:v.externalId};e.debug&&console.log("[sentient] goal",U);let P={id:B,body:JSON.stringify(U)};E.then(()=>b.send(P))},componentGoal(d,g,h){var B,U,P;let T=a.getSessionId();if(!T)return;let I=r.get(d,O),v=I?null:(B=A.get(d))!=null?B:null;if(!I&&v===null){e.debug&&console.warn(`[sentient] componentGoal("${d}"): no assignment or slot decision yet \u2014 render its <Adaptive>/adaptive hook or call assign()/decide() before recording a goal.`);return}let z=I?I.variantId:Te(v),W={id:Fe(),sessionId:T,projectId:e.apiKey,componentId:d,variantId:z,eventType:"goal_achieved",goalType:g,payload:k({reward:(U=h==null?void 0:h.reward)!=null?U:1,goalValue:h==null?void 0:h.value,currency:h==null?void 0:h.currency},(P=h==null?void 0:h.metadata)!=null?P:{}),timestamp:Date.now(),timeInSession:Date.now()-p,path:Pe()};e.debug&&console.log("[sentient] componentGoal",W),E.then(()=>o.push(W))},identify(d){let g=a.getSessionId();g&&E.then(()=>{fetch(`${s}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:g,userId:d,ephemeral:a.isEphemeral()}),headers:l}).catch(()=>{})})},track(d){let g=a.getSessionId();if(!g)return;let h=oe(k({path:Pe()},d),{id:Fe(),sessionId:g,timestamp:Date.now(),timeInSession:Date.now()-p});e.debug&&console.log("[sentient] track",h),E.then(()=>o.push(h))},getAssignment(d,g){return r.get(d,g)},async assign(d,g,h,T){let I=a.getSessionId();if(!I)return null;let v=r.get(d,O);if(v&&(g!=null&&g.length||v.content!==void 0)){let B=v.ttlMs&&v.ttlMs>0?Math.max(0,v.assignedAt+v.ttlMs-Date.now()):0;return{variantId:v.variantId,assignmentTtlMs:B,content:v.content}}let z=K.get(d);if(z)return z;let W=(async()=>{await E;try{let B={sessionId:I,componentId:d,variantIds:g};T!==void 0?B.agentDataByVariant=T:h!==void 0&&(B.agentData=h);let U=await fetch(`${s}/assign`,{method:"POST",body:JSON.stringify(B),headers:l});if(!U.ok)return null;let P=await U.json();return r.set(d,O,k({variantId:P.variantId,assignedAt:Date.now(),segment:O,confidence:1,content:P.content},P.assignmentTtlMs&&P.assignmentTtlMs>0?{ttlMs:P.assignmentTtlMs}:{})),P}catch(B){return null}finally{K.delete(d)}})();return K.set(d,W),W},async decide(d){var T,I,v,z,W,B,U,P,ce;let g=a.getSessionId();if(!g)return null;let h=(T=d.slots)!=null?T:[];await E;try{let $={sessionId:g};d.sections&&d.sections.length>0&&($.sections=d.sections.map(L=>({id:L}))),$.components=(I=d.components)!=null?I:[],h.length>0&&($.slots=h.map(we)),d.slotsFrom==="registry"&&($.slotsFrom="registry"),d.v&&($.v=d.v),e.persona&&($.persona=e.persona);let de=await fetch(`${s}/decide`,{method:"POST",body:JSON.stringify($),headers:l});if(!de.ok)return R(h),null;let x=await de.json(),Y={};for(let L of h)Y[L.id]=(z=(v=x.slots)==null?void 0:v[L.id])!=null?z:ie(L);if(x.slots)for(let[L,ue]of Object.entries(x.slots))L in Y||(Y[L]=ue);for(let[L,ue]of Object.entries(Y))A.set(L,ue);let be=S!=null&&S.persona!=="unknown";x.persona&&!(x.persona==="unknown"&&be)?S={persona:x.persona,confidence:(W=x.confidence)!=null?W:0}:S||(S={persona:"unknown",confidence:0});for(let[L,ue]of Object.entries((B=x.assignments)!=null?B:{}))r.set(L,O,{variantId:ue,assignedAt:Date.now(),segment:O,confidence:1});return ae(e.apiKey,k(k({v:1,persona:S.persona,band:(0,We.confidenceBand)(S.confidence),slots:Object.fromEntries(A),layoutOrder:(U=x.layoutOrder)!=null?U:null,savedAt:Date.now()},x.slotConfig?{slotConfig:x.slotConfig}:{}),x.palette?{palette:x.palette}:{})),k(k(k(k({layoutOrder:(P=x.layoutOrder)!=null?P:null,assignments:(ce=x.assignments)!=null?ce:{},slots:Y,persona:S.persona,confidence:S.confidence},x.slotConfig?{slotConfig:x.slotConfig}:{}),x.goals?{goals:x.goals}:{}),x.sectionMap?{sectionMap:x.sectionMap}:{}),x.palette?{palette:x.palette}:{})}catch($){return R(h),null}},getSlotResult(d){var g;return(g=A.get(d))!=null?g:null},getPersona(){return S?{persona:S.persona,confidence:S.confidence,band:(0,We.confidenceBand)(S.confidence)}:null},async fetchWeights(){var d;try{let g=await fetch(`${s}/weights`,{headers:l});return g.ok?(d=(await g.json()).components)!=null?d:[]:[]}catch(g){return[]}},getGraph(){return{pageNodes:[],capturedAt:0}},dispose(){var d;M==null||M(),j=!0,o.destroy(),b.destroy(),((d=N.get(e.apiKey))==null?void 0:d.dispose)===f.dispose&&N.delete(e.apiKey),e.debug&&console.log("[sentient] disposed")},destroy(){var d;M==null||M(),j=!0,o.destroy(),b.destroy(),a.destroy(),((d=N.get(e.apiKey))==null?void 0:d.dispose)===f.dispose&&N.delete(e.apiKey);try{localStorage.removeItem(te+e.apiKey),localStorage.removeItem(Ke(e.apiKey)),localStorage.removeItem(Ge(e.apiKey))}catch(g){}e.debug&&console.log("[sentient] destroyed")}};if(N.set(e.apiKey,{config:e,upgrade:null,dispose:f.dispose}),M=pn(f,e.apiKey,d=>{E.then(()=>{j||pt.add(d)})}),e.debug){let d=window;d.__sentient&&(d.__sentient.client=f)}return f}0&&(module.exports={AGENT_INTENTS,BLOCK_ALIGNS,BLOCK_EMPHASES,BLOCK_FITS,BLOCK_GAPS,BLOCK_GRID_COLUMNS,BLOCK_HEADING_LEVELS,BLOCK_JUSTIFIES,BLOCK_RATIOS,BLOCK_SIZES,BLOCK_TEXT_ALIGNS,BLOCK_TONES,BLOCK_WEIGHTS,LEGACY_SESSION_COOKIE_NAME,LOCAL_MODE_BANNER,MAX_BLOCK_ARMS,MAX_BLOCK_CHILDREN,MAX_BLOCK_DEPTH,MAX_BLOCK_NODES,MAX_BLOCK_TEXT_LEN,PROD_KEYLESS_ERROR,SNAPSHOT_STORAGE_KEY_PREFIX,agentIntent,agentUaList,armOfResult,attachMicroSignalDetectors,baselineResultFor,baselineSlots,classifiedAgents,deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,grantConsent,init,isDoNotTrackEnabled,matchedAgentToken,readSnapshot,referrerDomainFromReferer,renderPrePaintScript,sessionCookieName,toWireSlot,uaTokenMatch,writeSnapshot});
|
|
1
|
+
"use strict";var wt=Object.create;var fe=Object.defineProperty,xt=Object.defineProperties,bt=Object.getOwnPropertyDescriptor,kt=Object.getOwnPropertyDescriptors,Et=Object.getOwnPropertyNames,Ye=Object.getOwnPropertySymbols,Ct=Object.getPrototypeOf,Ze=Object.prototype.hasOwnProperty,It=Object.prototype.propertyIsEnumerable;var qe=(e,t,n)=>t in e?fe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,k=(e,t)=>{for(var n in t||(t={}))Ze.call(t,n)&&qe(e,n,t[n]);if(Ye)for(var n of Ye(t))It.call(t,n)&&qe(e,n,t[n]);return e},se=(e,t)=>xt(e,kt(t));var _t=(e,t)=>{for(var n in t)fe(e,n,{get:t[n],enumerable:!0})},et=(e,t,n,l)=>{if(t&&typeof t=="object"||typeof t=="function")for(let p of Et(t))!Ze.call(e,p)&&p!==n&&fe(e,p,{get:()=>t[p],enumerable:!(l=bt(t,p))||l.enumerable});return e};var At=(e,t,n)=>(n=e!=null?wt(Ct(e)):{},et(t||!e||!e.__esModule?fe(n,"default",{value:e,enumerable:!0}):n,e)),Ot=e=>et(fe({},"__esModule",{value:!0}),e);var xn={};_t(xn,{AGENT_INTENTS:()=>Be,BLOCK_ALIGNS:()=>Xt,BLOCK_EMPHASES:()=>tn,BLOCK_FITS:()=>rn,BLOCK_GAPS:()=>Vt,BLOCK_GRID_COLUMNS:()=>sn,BLOCK_HEADING_LEVELS:()=>an,BLOCK_JUSTIFIES:()=>Yt,BLOCK_RATIOS:()=>on,BLOCK_SIZES:()=>qt,BLOCK_TEXT_ALIGNS:()=>nn,BLOCK_TONES:()=>en,BLOCK_WEIGHTS:()=>Zt,LEGACY_SESSION_COOKIE_NAME:()=>Ke,LOCAL_MODE_BANNER:()=>We,MAX_BLOCK_ARMS:()=>un,MAX_BLOCK_CHILDREN:()=>dn,MAX_BLOCK_DEPTH:()=>cn,MAX_BLOCK_NODES:()=>ln,MAX_BLOCK_TEXT_LEN:()=>pn,PROD_KEYLESS_ERROR:()=>Me,SNAPSHOT_STORAGE_KEY_PREFIX:()=>te,_registerConsentUpgradeInit:()=>gn,agentIntent:()=>at,agentUaList:()=>ye,armOfResult:()=>De,attachMicroSignalDetectors:()=>ft,baselineResultFor:()=>le,baselineSlots:()=>dt,classifiedAgents:()=>lt,deriveSessionSegment:()=>ct,detectDeviceClass:()=>Se,detectTimeOfDay:()=>xe,detectTrafficSource:()=>ve,grantConsent:()=>vn,init:()=>vt,isDoNotTrackEnabled:()=>Qe,matchedAgentToken:()=>Fe,readSnapshot:()=>ce,referrerDomainFromReferer:()=>we,renderPrePaintScript:()=>ut,sessionCookieName:()=>Ie,toWireSlot:()=>be,uaTokenMatch:()=>he,writeSnapshot:()=>de});module.exports=Ot(xn);function Ce(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}try{if(typeof crypto!="undefined"&&typeof crypto.getRandomValues=="function"){let e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t="";for(let n=0;n<16;n++)t+=e[n].toString(16).padStart(2,"0"),(n===3||n===5||n===7||n===9)&&(t+="-");return t}}catch(e){}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function me(e){return e?`_${e.slice(0,12)}`:""}var Ke="_snt_uid";function Ie(e){return`${Ke}${me(e)}`}var Rt="_snt_uid",Tt=365,_e="_snt_uid";function Bt(){return Ce()}function tt(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function Dt(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(l){}}function Ge(e){try{return localStorage.getItem(e)}catch(t){return null}}function nt(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function ot(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function Lt(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function Pt(e){try{sessionStorage.removeItem(e)}catch(t){}}function Mt(e){try{return document.cookie=`${e}_probe=1; max-age=1; SameSite=strict; path=/`,document.cookie.indexOf(`${e}_probe=1`)!==-1}catch(t){return!1}}function Nt(e){try{localStorage.removeItem(e)}catch(t){}}function Kt(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var Gt={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function Ae(e){var E,R,T,C,G,$,_;if(typeof window=="undefined")return Gt;let t=me(e==null?void 0:e.apiKey),n=(E=e==null?void 0:e.cookieName)!=null?E:Ie(e==null?void 0:e.apiKey),l=`${_e}${t}`,p=`${_e}_tomb${t}`,c=((R=e==null?void 0:e.cookieTTLDays)!=null?R:Tt)*24*60*60,i=v=>v&&v.length>0?v:null,u=()=>{var v,D;return t&&!(e!=null&&e.cookieName)&&Ge(p)===null?(D=(v=i(tt(Rt)))!=null?v:i(Ge(_e)))!=null?D:i(ot(_e)):null},s=(_=($=(G=(C=(T=i(tt(n)))!=null?T:i(Ge(l)))!=null?C:i(ot(l)))!=null?G:u())!=null?$:i(e==null?void 0:e.ssrSessionId))!=null?_:Bt();Dt(n,s,c);let o=nt(l,s),r=Mt(n),y=o?!1:Lt(l,s),h=!o&&!r&&!y;return{getSessionId:()=>s,isEphemeral:()=>h,destroy:()=>{s=null,Kt(n),Nt(l),Pt(l),t&&!(e!=null&&e.cookieName)&&nt(p,"1")}}}function X(e){return Math.min(6e4,1e3*2**Math.min(e,6))}function ie(e){if(e.ok===!0)return"delivered";let{status:t}=e;return typeof t!="number"?"retry":t>=200&&t<300?"delivered":t>=400&&t<500&&t!==429?"dropped":"retry"}function Oe(e,t){try{let n=localStorage.getItem(e);if(!n)return[];let l=JSON.parse(n);return Array.isArray(l)?(localStorage.removeItem(e),l.slice(-t)):[]}catch(n){return[]}}function Y(e,t,n){try{let l=(()=>{try{let a=localStorage.getItem(n);if(!a)return[];let c=JSON.parse(a);return Array.isArray(c)?c:[]}catch(a){return[]}})(),p=new Map;for(let a of l)p.set(a.id,a);for(let a of e)p.set(a.id,a);localStorage.setItem(n,JSON.stringify([...p.values()].slice(-t)))}catch(l){}}function Re(e,t){try{let n=localStorage.getItem(t);if(!n)return;let l=JSON.parse(n);if(!Array.isArray(l))return;let p=new Set(e),a=l.filter(c=>!p.has(c.id));if(a.length===l.length)return;a.length===0?localStorage.removeItem(t):localStorage.setItem(t,JSON.stringify(a))}catch(n){}}var Ut=500,$t=56*1024;function Ue(e){return`_snt_retry_${e.slice(0,12)}`}var Ft={push:()=>{},flush:()=>{},destroy:()=>{}};function rt(e){var q,M,ne;if(typeof window=="undefined")return Ft;let t=(q=e.flushIntervalMs)!=null?q:5e3,n=(M=e.maxBatchSize)!=null?M:20,l=(ne=e.maxRetrySize)!=null?ne:100,p=e.ingestUrl,a=e.apiKey,c=Ue(a),i=[],u=new Set,s=[],o=f=>{for(let x of f)r.delete(x),!u.has(x)&&(u.add(x),s.push(x));for(;s.length>Ut;){let x=s.shift();x&&u.delete(x)}Re(f,c)},r=new Set,y=()=>{for(;i.length>l;){let f=i.shift();f&&r.delete(f.id)}},h=f=>{u.has(f.id)||r.has(f.id)||(r.add(f.id),i.push(f),y())},E=f=>{for(let x of f)u.has(x.id)||(r.add(x.id),i.push(x));y()},R=Oe(c,l);for(let f of R)h(f);let T=0,C=0,G=(f,x=!0)=>{if(f.length===0)return;let j=JSON.stringify(f),Z=f.map(z=>z.id),F;try{F=fetch(p,{method:"POST",keepalive:!0,body:j,headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`}})}catch(z){Y(f,l,c),E(f),C++,T=Date.now()+X(C);return}let ue=z=>{if(ie(z)!=="retry"){if(!z.ok&&x){let oe=f.filter(Q=>Q.eventType!=="pageview");if(oe.length>0&&oe.length<f.length){o(f.filter(Q=>Q.eventType==="pageview").map(Q=>Q.id)),G(oe,!1);return}}o(Z),C=0,T=0;return}Y(f,l,c),E(f),C++,T=Date.now()+X(C)};F instanceof Promise?F.then(ue).catch(()=>{Y(f,l,c),E(f),C++,T=Date.now()+X(C)}):ue(F)},$=typeof TextEncoder!="undefined"?new TextEncoder:null,_=f=>$?$.encode(f).length:f.length,v=f=>{let x=[],j=2;for(let Z of f){let F=_(JSON.stringify(Z))+1;if(x.length>0&&j+F>$t||x.length>=n)break;x.push(Z),j+=F}return x},D=()=>{try{if(Date.now()<T)return;for(;i.length>0&&!(Date.now()<T);){let f=i.filter(j=>!u.has(j.id));if(i.length=0,f.length===0)break;let x=v(f);if(x.length===0)break;x.length<f.length&&i.push(...f.slice(x.length)),G(x)}}catch(f){}},m=!0,O=null;O=setInterval(()=>{m&&D()},t);let P=()=>{document.visibilityState==="hidden"&&D()},W=()=>{D()};return document.addEventListener("visibilitychange",P),window.addEventListener("pagehide",W),{push(f){h(f),i.length>=n&&D()},flush:D,destroy(){m=!1,O!==null&&(clearInterval(O),O=null),document.removeEventListener("visibilitychange",P),window.removeEventListener("pagehide",W),D()}}}var Wt=200;function $e(e){return`_snt_goal_retry_${e.slice(0,12)}`}var jt={send:()=>{},flush:()=>{},destroy:()=>{}};function st(e){var _,v,D;if(typeof window=="undefined")return jt;let t=(_=e.flushIntervalMs)!=null?_:5e3,n=(v=e.maxRetrySize)!=null?v:100,l=(D=e.maxPerFlush)!=null?D:5,p=$e(e.apiKey),a=[],c=new Set,i=new Set,u=[],s=0,o=0,r=!1,y=m=>{for(c.delete(m.id),i.has(m.id)||(i.add(m.id),u.push(m.id));u.length>Wt;){let O=u.shift();O&&i.delete(O)}Re([m.id],p)},h=m=>{Y([m],n,p),!i.has(m.id)&&!c.has(m.id)&&(c.add(m.id),a.push(m)),Date.now()>=s&&(o++,s=Date.now()+X(o))},E=m=>{let O;try{O=fetch(e.url,{method:"POST",keepalive:!0,body:m.body,headers:e.headers})}catch(W){h(m);return}let P=W=>{var M;let q=ie(W);if(q==="retry"){h(m);return}q==="dropped"&&((M=e.onDrop)==null||M.call(e,m,W.status)),y(m),o=0,s=0};O instanceof Promise?O.then(P).catch(()=>h(m)):P(O)},R=()=>{try{if(r||Date.now()<s)return;let m=0;for(;a.length>0&&m<l&&!(Date.now()<s);){let O=a.shift();c.delete(O.id),!i.has(O.id)&&(m++,E(O))}}catch(m){}},T=Oe(p,n);for(let m of T)c.has(m.id)||(c.add(m.id),a.push(m));T.length>0&&Y(T,n,p);let C=setInterval(R,t),G=()=>{document.visibilityState==="hidden"&&R()},$=()=>R();return document.addEventListener("visibilitychange",G),window.addEventListener("pagehide",$),{send(m){if(!r&&!(i.has(m.id)||c.has(m.id))){if(Date.now()<s){Y([m],n,p),c.add(m.id),a.push(m);return}E(m)}},flush:R,destroy(){clearInterval(C),document.removeEventListener("visibilitychange",G),window.removeEventListener("pagehide",$),R(),r=!0}}}var Ht=1800*1e3;function Te(e,t){return`${encodeURIComponent(e)}:${encodeURIComponent(t)}`}function it(e=Ht,t){let n=new Map,l=`_snt_asgn${me(t)}_`,p=(s,o)=>`${l}${encodeURIComponent(s)}:${encodeURIComponent(o)}`,a=s=>{let o=s.slice(l.length),r=o.indexOf(":");if(r<0)return null;try{return{componentId:decodeURIComponent(o.slice(0,r)),segment:decodeURIComponent(o.slice(r+1))}}catch(y){return null}},c=()=>{try{let s=[];for(let o=0;o<localStorage.length;o++){let r=localStorage.key(o);r!=null&&r.startsWith(l)&&s.push(r)}return s}catch(s){return[]}},i=s=>s.assignedAt+(s.ttlMs&&s.ttlMs>0?s.ttlMs:e)<Date.now();return typeof window!="undefined"&&(()=>{for(let s of c())try{let o=localStorage.getItem(s);if(!o)continue;let r=JSON.parse(o);if(i(r)){localStorage.removeItem(s);continue}let y=a(s);if(!y)continue;n.set(Te(y.componentId,y.segment),r)}catch(o){}})(),{get(s,o){let r=n.get(Te(s,o));return r?i(r)?(n.delete(Te(s,o)),null):r:null},set(s,o,r){let y=Te(s,o);n.set(y,r);try{localStorage.setItem(p(s,o),JSON.stringify(r))}catch(h){}},clear(){n.clear();for(let s of c())try{localStorage.removeItem(s)}catch(o){}}}}var ye=["GPTBot","ChatGPT-User","OAI-SearchBot","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","Meta-ExternalAgent","Bytespider","CCBot","Amazonbot","cohere-ai","Diffbot"];function he(e){return Fe(e)!==null}function Fe(e){var n;if(!e)return null;let t=e.toLowerCase();return(n=ye.find(l=>t.includes(l.toLowerCase())))!=null?n:null}var Be={GPTBot:"training","ChatGPT-User":"user","OAI-SearchBot":"search",ClaudeBot:"training","Claude-User":"user","Claude-SearchBot":"search",PerplexityBot:"search","Perplexity-User":"user","Google-Extended":"training","Applebot-Extended":"training","Meta-ExternalAgent":"training",Bytespider:"training",CCBot:"training",Amazonbot:"other","cohere-ai":"training",Diffbot:"other"};function at(e){if(!e)return"other";let t=ye.find(n=>n.toLowerCase()===e.toLowerCase());return t&&Be[t]||"other"}function lt(){var t;let e={user:[],search:[],training:[],other:[]};for(let n of ye)e[(t=Be[n])!=null?t:"other"].push(n);return e}function Se(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function ve(e,t){if(!e)return"direct";try{let n=new URL(e);if(t)try{if(new URL(t).host===n.host)return"direct"}catch(p){}let l=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(l)?"search":/(^|\.)(twitter\.com|x\.com|facebook\.com|linkedin\.com|reddit\.com|t\.co)$/.test(l)?"social":"referral"}catch(n){return"direct"}}function we(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function xe(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function ct(e){let t=zt("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function zt(e,t){var a,c,i,u,s,o,r;let n=(c=(a=t==null?void 0:t.userAgent)==null?void 0:a.trim())!=null?c:"",l=(u=(i=t==null?void 0:t.referer)==null?void 0:i.trim())!=null?u:"",p=(s=t==null?void 0:t.now)!=null?s:new Date;return{sessionId:e,ephemeral:!1,utmParams:(o=t==null?void 0:t.utmParams)!=null?o:{},deviceClass:n?Se(n):"desktop",trafficSource:l?ve(l,t==null?void 0:t.appOrigin):"direct",referrerDomain:we(l),timeOfDay:xe(p),dayOfWeek:(r=["sun","mon","tue","wed","thu","fri","sat"][p.getDay()])!=null?r:"sun",automation:(t==null?void 0:t.webdriver)===!0||he(n)}}var ae=require("@sentientui/policy");function be(e){return k(k(k({id:e.id},e.arms?{arms:[...e.arms]}:{}),e.dims?{dims:Object.fromEntries(Object.entries(e.dims).map(([t,n])=>[t,[...n]]))}:{}),e.baseline!==void 0?{baseline:e.baseline}:{})}function le(e){let t=be(e);return(0,ae.slotResultFor)(t,(0,ae.slotBaselineArm)(t))}function dt(e){let t={};for(let n of e)t[n.id]=le(n);return t}function De(e){return typeof e=="string"?e:(0,ae.canonicalArm)(e)}var te="_snt_snap:",Qt=["low","medium","high"];function ce(e){try{let t=localStorage.getItem(te+e);if(!t)return null;let n=JSON.parse(t);return!n||typeof n!="object"||n.v!==1||typeof n.persona!="string"||typeof n.band!="string"||!Qt.includes(n.band)||typeof n.slots!="object"||n.slots===null||Array.isArray(n.slots)||!(n.layoutOrder===null||Array.isArray(n.layoutOrder))||typeof n.savedAt!="number"||!(n.slotConfig===void 0||typeof n.slotConfig=="object"&&n.slotConfig!==null&&!Array.isArray(n.slotConfig))?null:n}catch(t){return null}}function de(e,t){try{localStorage.setItem(te+e,JSON.stringify(t))}catch(n){}}function ut(e){return"(function(){try{var r=localStorage.getItem("+JSON.stringify(te+e).replace(/</g,"\\u003c")+');if(!r)return;var s=JSON.parse(r);if(!s||s.v!==1||typeof s.persona!=="string"||typeof s.band!=="string")return;var d=document.documentElement;if(d.hasAttribute("data-sentient-persona"))return;d.setAttribute("data-sentient-persona",s.persona);d.setAttribute("data-sentient-confidence",s.band);}catch(e){}})();'}var He=require("@sentientui/policy");var Pe=require("@sentientui/policy");var Me="[sentient] No API key configured \u2014 nothing is being learned. Set NEXT_PUBLIC_SENTIENT_API_KEY or pass localMode: true for local development.",We="[sentient] Local mode \u2014 decisions are simulated on-device and nothing is sent over the network. Add an API key to learn from real traffic.",pt=!1,Le=!1;function Jt(){var e;try{return(e=new URLSearchParams(window.location.search).get("sentient_persona"))!=null?e:void 0}catch(t){return}}function gt(e){var s;let t=Ae({ssrSessionId:e.ssrSessionId,apiKey:e.apiKey}),n=(s=t.getSessionId())!=null?s:"local",l=Jt(),p=import("@sentientui/core/local").then(o=>{let r=o;return r.LOCAL_ENGINE_AVAILABLE?(pt||(pt=!0,console.info(We)),r):(Le||(Le=!0,console.error(Me)),null)}).catch(()=>(Le||(Le=!0,console.error(Me)),null)),a=null,c={low:.15,medium:.5,high:.85},i=(()=>{var r;if(e.initialPersona)return k({},e.initialPersona);let o=ce(e.apiKey||"local");return o?{persona:o.persona,confidence:(r=c[o.band])!=null?r:.15}:null})();function u(o){let r=document.documentElement;r.dataset.sentientPersona===void 0&&(r.dataset.sentientPersona=o.persona,r.dataset.sentientConfidence=(0,Pe.confidenceBand)(o.confidence))}return{isLocal:!0,async decide(o){var h,E,R;let r=await p;if(!r)return null;let y=r.createLocalEngine({sessionId:n,forcedPersona:l}).decide(o);return a=se(k({},y),{layoutOrder:(E=(h=y.layoutOrder)!=null?h:a==null?void 0:a.layoutOrder)!=null?E:null,slots:k(k({},(R=a==null?void 0:a.slots)!=null?R:{}),y.slots)}),de(e.apiKey||"local",{v:1,persona:a.persona,band:(0,Pe.confidenceBand)(a.confidence),slots:a.slots,layoutOrder:a.layoutOrder,savedAt:Date.now()}),u(y),y},getSlotResult(o){var r,y,h;return(h=(y=a==null?void 0:a.slots[o])!=null?y:(r=e.initialSlots)==null?void 0:r[o])!=null?h:null},getPersona(){let o=a!=null?a:i;return o?{persona:o.persona,confidence:o.confidence,band:(0,Pe.confidenceBand)(o.confidence)}:null},async assign(o,r){var E;let y=await p;return!y||!r||r.length===0?r!=null&&r[0]?{variantId:r[0],assignmentTtlMs:0}:null:{variantId:(E=y.createLocalEngine({sessionId:n,forcedPersona:l}).decide({components:[{id:o,variantIds:r}]}).assignments[o])!=null?E:r[0],assignmentTtlMs:0}},track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>t.destroy()}}var Vt=["none","sm","md","lg"],Xt=["start","center","end","stretch"],Yt=["start","center","end","between"],qt=["sm","md","lg"],Zt=["normal","medium","bold"],en=["default","muted","accent"],tn=["primary","secondary","ghost"],nn=["left","center","right"],on=["auto","square","landscape","wide"],rn=["cover","contain"],sn=[2,3,4],an=[2,3,4],ln=64,cn=5,dn=12,un=4,pn=500;function ft(e,t,n,l){let p=[];{let i=!1,u=[],s=()=>{if(i)return;let o=Date.now();for(u.push(o);u.length>0&&o-u[0]>500;)u.shift();u.length>=3&&(i=!0,e("rage_click"))};t.addEventListener("click",s),p.push(()=>t.removeEventListener("click",s))}{let a=!1,c=i=>{if(a||!(i.target instanceof Node)||!t.contains(i.target)&&t!==i.target)return;a=!0;let u=typeof window!="undefined"?window.getSelection():null,s=u?u.toString().length:0;e("text_copy",{selectionLength:s})};document.addEventListener("copy",c),p.push(()=>document.removeEventListener("copy",c))}{let a=!1,c=!1,i=null,u=()=>{i!==null&&(clearTimeout(i),i=null)},s=()=>{a||!c||(u(),i=setTimeout(()=>{!a&&c&&(a=!0,e("scroll_hesitation"))},3e3))},o=()=>{u(),s()},r=h=>{for(let E of h)c=E.intersectionRatio>.3,c?s():u()},y=new IntersectionObserver(r,{threshold:[.3]});y.observe(t),window.addEventListener("scroll",o,{passive:!0}),p.push(()=>{y.disconnect(),window.removeEventListener("scroll",o),u()})}if((l==null?void 0:l.tabLoss)!==!1){let a=!1,c=n!=null?n:Date.now(),i=()=>{if(a||document.visibilityState!=="hidden")return;let u=Date.now()-c;u<15e3&&(a=!0,e("tab_loss",{timeOnPage:u}))};document.addEventListener("visibilitychange",i),p.push(()=>document.removeEventListener("visibilitychange",i))}return()=>{for(let a of p)a()}}var mt="https://api.sentient-ui.com/v1/events",K=new Map,yt=null;function gn(e,t){let n=K.get(e);n&&n.upgrade&&(n.reinit=t)}function fn(e){return"value"in e||"currency"in e||"externalId"in e||"metadata"in e||"weight"in e||"stepIndex"in e}var mn=3;function je(){return Ce()}function Ne(){var e;if(typeof window!="undefined")return((e=window.location)==null?void 0:e.pathname)||void 0}function yn(){let e=new WeakMap,t=new Map,n=!1,l=(i,u,s)=>{let o=i.get(u);return s===null?o?!0:(i.set(u,new Set),!1):o?o.has(s)?!0:(o.add(s),!1):(i.set(u,new Set([s])),!1)},p=typeof window!="undefined"&&"event"in window,a=()=>{if(!p)return;let i=window.event;return typeof Event=="function"&&i instanceof Event?i:void 0},c=()=>{if(p){Promise.resolve().then(()=>{n=!1,t.clear()});return}let i=!1,u=()=>{i||(i=!0,n=!1,t.clear())};if(setTimeout(u,0),typeof MessageChannel=="function"){let s=new MessageChannel;s.port1.onmessage=()=>{s.port1.close(),s.port2.close(),u()},s.port2.postMessage(0)}};return{firedBefore(i,u){let s=a();if(s){let r=e.get(s);return r||(r=new Map,e.set(s,r)),l(r,i,u)}let o=l(t,i,u);return!o&&!n&&(n=!0,c()),o}}}var ht=new Set;function hn(e,t,n){let l=typeof window=="undefined"?null:window.history;if(!l)return()=>{};let p=!1,a,c=()=>{if(p)return;let s=Ne();!s||s===a||(a=s,e.track({projectId:t,componentId:"__page__",eventType:"pageview",payload:{}}),n(`${t}:${s}`))},i=[];for(let s of["pushState","replaceState"]){let o=l[s],r=function(...y){let h=o.apply(this,y);return c(),h};l[s]=r,i.push([s,o,r])}window.addEventListener("popstate",c);let u=Ne();return u&&ht.has(`${t}:${u}`)?a=u:c(),()=>{if(!p){p=!0,window.removeEventListener("popstate",c);for(let[s,o,r]of i)l[s]===r&&(l[s]=o)}}}var ke={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),decide:()=>Promise.resolve(null),getSlotResult:()=>null,getPersona:()=>null,fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>{}};function Sn(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,l]of t)n.startsWith("utm_")&&(e[n]=l);return e}catch(e){return{}}}function St(e){return e.replace(/\/events\/?$/,"")}function Qe(){return typeof navigator!="undefined"&&navigator.globalPrivacyControl===!0?!0:[typeof navigator!="undefined"?navigator.doNotTrack:void 0,typeof window!="undefined"?window.doNotTrack:void 0,typeof navigator!="undefined"?navigator.msDoNotTrack:void 0].some(t=>t==="1"||t==="yes")}function vn(e){var u;if(typeof window=="undefined")return;let t=e!=null?e:yt;if(!t){console.warn("[sentient] grantConsent() called before init()");return}let n=K.get(t);if(!n){console.warn("[sentient] grantConsent() called before init()");return}let{config:l,upgrade:p,reinit:a}=n;if(!p){n.upgradeBlockedReason&&console.warn(n.upgradeBlockedReason);return}if(l.respectDoNotTrack!==!1&&Qe())return;let c=(a!=null?a:vt)(se(k({},l),{consent:!0}));p(c);let i=(u=K.get(t))==null?void 0:u.dispose;K.set(t,{config:se(k({},l),{consent:!0}),upgrade:null,dispose:i})}function wn(e){var s;let t=e.preConsentBehavior==="statistical_winner",n=St((s=e.ingestUrl)!=null?s:mt),l={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},p=new Map,a=new Map,c={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),assign(o,r,y){if(!t)return Promise.resolve(null);let h=p.get(o);return h?Promise.resolve(h):ze(a,o,async()=>{try{let E=new URLSearchParams({componentId:o});for(let G of r!=null?r:[])E.append("variantIds[]",G);let R=await fetch(`${n}/winner?${E.toString()}`,{headers:l});if(!R.ok)return r!=null&&r[0]?{variantId:r[0],assignmentTtlMs:0}:null;let C={variantId:(await R.json()).variantId,assignmentTtlMs:0};return p.set(o,C),C}catch(E){return r!=null&&r[0]?{variantId:r[0],assignmentTtlMs:0}:null}})},decide:()=>Promise.resolve(null),getSlotResult:()=>null,getPersona:()=>null,getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>{}},i={track:o=>c.track(o),goal:((o,r,y,h)=>c.goal(o,r,y,h)),componentGoal:(o,r,y)=>c.componentGoal(o,r,y),identify:o=>c.identify(o),getAssignment:(o,r)=>c.getAssignment(o,r),assign:(o,r,y,h)=>c.assign(o,r,y,h),decide:o=>c.decide(o),getSlotResult:o=>c.getSlotResult(o),getPersona:()=>c.getPersona(),fetchWeights:()=>c.fetchWeights(),getGraph:()=>c.getGraph(),dispose:()=>c.dispose(),destroy:()=>c.destroy()};function u(o){c=o}return{proxy:i,setInner:u}}function ze(e,t,n){let l=e.get(t);if(l)return l;let p=(async()=>{try{return await n()}finally{e.delete(t)}})();return e.set(t,p),p}function vt(e){var x,j,Z,F,ue,z,oe,Q,Je;if(typeof window=="undefined")return ke;yt=e.apiKey||"local";let t=K.get(e.apiKey||"local");if(t!=null&&t.dispose)try{t.dispose()}catch(d){}let n=e.respectDoNotTrack!==!1&&Qe(),l=e.consent===!1||n,p=typeof e.apiKey=="string"&&e.apiKey.startsWith("pk_");if(e.localMode===!0||!p&&e.localMode!==!1)return K.set(e.apiKey||"local",{config:e,upgrade:null,upgradeBlockedReason:"[sentient] grantConsent(): this client is keyless/local \u2014 there is no hosted client to upgrade to. Configure a pk_ API key to enable tracking."}),l?ke:gt(e);if(l){if(!e.apiKey||!e.apiKey.startsWith("pk_"))return e.preConsentBehavior==="statistical_winner"&&console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),K.set(e.apiKey||"local",{config:e,upgrade:null,upgradeBlockedReason:"[sentient] grantConsent(): the client was initialized with an invalid apiKey (expected a pk_ public key) \u2014 consent cannot enable tracking."}),ke;let{proxy:d,setInner:g}=wn(e);return K.set(e.apiKey,{config:e,upgrade:n?null:g}),d}if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),ke;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),ke;let a=(x=e.ingestUrl)!=null?x:mt,c=Date.now(),i=Ae({ssrSessionId:e.ssrSessionId,apiKey:e.apiKey}),u=it(void 0,e.apiKey),s=rt({ingestUrl:a,apiKey:e.apiKey}),o=St(a),r={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},y=new Set,h=st({url:`${o}/goals`,apiKey:e.apiKey,headers:r,onDrop:(d,g)=>{if(!e.debug){if(y.has(g))return;y.add(g)}console.warn(`[sentient] goal dropped (HTTP ${g}) \u2014 this will not be retried. `+(g===400?"The session was not found: call init() and let the session upsert complete before firing goals.":g===401||g===403?"Check the API key and that this origin is on the project allowlist.":"See the response status for the cause."),d)}}),E=Se((j=navigator.userAgent)!=null?j:""),R=window.location.origin,T=ve((Z=document.referrer)!=null?Z:"",R),C=(F=e.sessionSegment)!=null?F:`${E}:${T}`,G=new Map,$=new Map,_=new Map,v=null,D=d=>{for(let g of d)_.has(g.id)||_.set(g.id,le(g))};if(e.initialSlots)for(let[d,g]of Object.entries(e.initialSlots))_.set(d,g);let m=ce(e.apiKey);if(m)for(let[d,g]of Object.entries(m.slots))_.has(d)||_.set(d,g);let O={low:.15,medium:.5,high:.85};if(e.initialPersona)v=k({},e.initialPersona);else{let d=document.documentElement.dataset;d.sentientPersona?v={persona:d.sentientPersona,confidence:(z=O[(ue=d.sentientConfidence)!=null?ue:"low"])!=null?z:.15}:m&&(v={persona:m.persona,confidence:(oe=O[m.band])!=null?oe:.15})}if(e.initialAssignments)for(let[d,g]of Object.entries(e.initialAssignments))u.set(d,C,{variantId:g,assignedAt:Date.now(),segment:C,confidence:1});let P=Promise.resolve(),W=i.getSessionId();if(W){let d=we((Q=document.referrer)!=null?Q:""),g=k(k(k({sessionId:W,deviceClass:E,trafficSource:T,referrerDomain:d,utmParams:Sn(),timeOfDay:xe(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:i.isEphemeral(),automation:typeof navigator!="undefined"&&navigator.webdriver===!0||he((Je=navigator.userAgent)!=null?Je:"")},e.userId?{userId:e.userId}:{}),e.persona?{persona:e.persona}:{}),e.country?{country:e.country}:{}),S=async()=>{for(let I=0;;I++){try{let A=await fetch(`${o}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(g),headers:r});if(A.status===402){console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing");return}if(A.ok||ie(A)==="dropped")return}catch(A){}if(I>=mn){console.warn("[SentientUI] Could not register the session after retries. Conversions in this visit may not be recorded.");return}await new Promise(A=>setTimeout(A,X(I+1)))}};try{P=S()}catch(I){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:s});let q=yn(),M=null,ne=!1,f={goal(d,g={},S=1,I=0){var pe,ge,re,b,H,Ee,B;let A=i.getSessionId();if(!A)return;let w=fn(g)?g:{metadata:g},N=[d,(pe=w.externalId)!=null?pe:"",(ge=w.stepIndex)!=null?ge:I,(re=w.weight)!=null?re:S].join("\0"),U=w.value!==void 0?`${w.value}\0${(b=w.currency)!=null?b:""}`:null;if(q.firedBefore(N,U)){e.debug&&console.log(`[sentient] goal("${d}") already recorded for this action \u2014 not sent twice`);return}let L=je(),J={sessionId:A,name:d,metadata:(H=w.metadata)!=null?H:{},weight:(Ee=w.weight)!=null?Ee:S,stepIndex:(B=w.stepIndex)!=null?B:I,goalId:L,value:w.value,currency:w.currency,externalId:w.externalId};e.debug&&console.log("[sentient] goal",J);let ee={id:L,body:JSON.stringify(J)};P.then(()=>h.send(ee))},componentGoal(d,g,S){var L,J,ee;let I=i.getSessionId();if(!I)return;let A=u.get(d,C),w=A?null:(L=_.get(d))!=null?L:null;if(!A&&w===null){e.debug&&console.warn(`[sentient] componentGoal("${d}"): no assignment or slot decision yet \u2014 render its <Adaptive>/adaptive hook or call assign()/decide() before recording a goal.`);return}let N=A?A.variantId:De(w),U={id:je(),sessionId:I,projectId:e.apiKey,componentId:d,variantId:N,eventType:"goal_achieved",goalType:g,payload:k({reward:(J=S==null?void 0:S.reward)!=null?J:1,goalValue:S==null?void 0:S.value,currency:S==null?void 0:S.currency},(ee=S==null?void 0:S.metadata)!=null?ee:{}),timestamp:Date.now(),timeInSession:Date.now()-c,path:Ne()};e.debug&&console.log("[sentient] componentGoal",U),P.then(()=>s.push(U))},identify(d){let g=i.getSessionId();g&&P.then(()=>{fetch(`${o}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:g,userId:d,ephemeral:i.isEphemeral()}),headers:r}).catch(()=>{})})},track(d){let g=i.getSessionId();if(!g)return;let S=se(k({path:Ne()},d),{id:je(),sessionId:g,timestamp:Date.now(),timeInSession:Date.now()-c});e.debug&&console.log("[sentient] track",S),P.then(()=>s.push(S))},getAssignment(d,g){return u.get(d,g)},async assign(d,g,S,I){let A=i.getSessionId();if(!A)return null;let w=u.get(d,C);if(w&&(g!=null&&g.length||w.content!==void 0)){let N=w.ttlMs&&w.ttlMs>0?Math.max(0,w.assignedAt+w.ttlMs-Date.now()):0;return{variantId:w.variantId,assignmentTtlMs:N,content:w.content}}return ze(G,d,async()=>{await P;try{let N={sessionId:A,componentId:d,variantIds:g};I!==void 0?N.agentDataByVariant=I:S!==void 0&&(N.agentData=S);let U=await fetch(`${o}/assign`,{method:"POST",body:JSON.stringify(N),headers:r});if(!U.ok)return null;let L=await U.json();return u.set(d,C,k({variantId:L.variantId,assignedAt:Date.now(),segment:C,confidence:1,content:L.content},L.assignmentTtlMs&&L.assignmentTtlMs>0?{ttlMs:L.assignmentTtlMs}:{})),L}catch(N){return null}})},async decide(d){var w,N;let g=i.getSessionId();if(!g)return null;let S=(w=d.slots)!=null?w:[],I={sessionId:g};d.sections&&d.sections.length>0&&(I.sections=d.sections.map(U=>({id:U}))),I.components=(N=d.components)!=null?N:[],S.length>0&&(I.slots=S.map(be)),d.slotsFrom==="registry"&&(I.slotsFrom="registry"),d.v&&(I.v=d.v),e.persona&&(I.persona=e.persona);let A=JSON.stringify(I);return ze($,A,async()=>{var U,L,J,ee,pe,ge;await P;try{let re=await fetch(`${o}/decide`,{method:"POST",body:A,headers:r});if(!re.ok)return D(S),null;let b=await re.json(),H={};for(let B of S){let V=(U=b.slots)==null?void 0:U[B.id];if(V!==void 0){H[B.id]=V,_.set(B.id,V);continue}let Ve=_.get(B.id);if(Ve!==void 0)H[B.id]=Ve;else{let Xe=le(B);H[B.id]=Xe,_.set(B.id,Xe)}}if(b.slots)for(let[B,V]of Object.entries(b.slots))B in H||(H[B]=V,_.set(B,V));let Ee=v!=null&&v.persona!=="unknown";b.persona&&!(b.persona==="unknown"&&Ee)?v={persona:b.persona,confidence:(L=b.confidence)!=null?L:0}:v||(v={persona:"unknown",confidence:0});for(let[B,V]of Object.entries((J=b.assignments)!=null?J:{}))u.set(B,C,{variantId:V,assignedAt:Date.now(),segment:C,confidence:1});return de(e.apiKey,k(k({v:1,persona:v.persona,band:(0,He.confidenceBand)(v.confidence),slots:Object.fromEntries(_),layoutOrder:(ee=b.layoutOrder)!=null?ee:null,savedAt:Date.now()},b.slotConfig?{slotConfig:b.slotConfig}:{}),b.palette?{palette:b.palette}:{})),k(k(k(k({layoutOrder:(pe=b.layoutOrder)!=null?pe:null,assignments:(ge=b.assignments)!=null?ge:{},slots:H,persona:v.persona,confidence:v.confidence},b.slotConfig?{slotConfig:b.slotConfig}:{}),b.goals?{goals:b.goals}:{}),b.sectionMap?{sectionMap:b.sectionMap}:{}),b.palette?{palette:b.palette}:{})}catch(re){return D(S),null}})},getSlotResult(d){var g;return(g=_.get(d))!=null?g:null},getPersona(){return v?{persona:v.persona,confidence:v.confidence,band:(0,He.confidenceBand)(v.confidence)}:null},async fetchWeights(){var d;try{let g=await fetch(`${o}/weights`,{headers:r});return g.ok?(d=(await g.json()).components)!=null?d:[]:[]}catch(g){return[]}},getGraph(){return{pageNodes:[],capturedAt:0}},dispose(){var d;M==null||M(),ne=!0,s.destroy(),h.destroy(),((d=K.get(e.apiKey))==null?void 0:d.dispose)===f.dispose&&K.delete(e.apiKey),e.debug&&console.log("[sentient] disposed")},destroy(){var d;M==null||M(),ne=!0,s.destroy(),h.destroy(),i.destroy(),u.clear(),((d=K.get(e.apiKey))==null?void 0:d.dispose)===f.dispose&&K.delete(e.apiKey);try{localStorage.removeItem(te+e.apiKey),localStorage.removeItem(Ue(e.apiKey)),localStorage.removeItem($e(e.apiKey))}catch(g){}e.debug&&console.log("[sentient] destroyed")}};if(K.set(e.apiKey,{config:e,upgrade:null,dispose:f.dispose}),M=hn(f,e.apiKey,d=>{P.then(()=>{ne||ht.add(d)})}),e.debug){let d=window;d.__sentient&&(d.__sentient.client=f)}return f}0&&(module.exports={AGENT_INTENTS,BLOCK_ALIGNS,BLOCK_EMPHASES,BLOCK_FITS,BLOCK_GAPS,BLOCK_GRID_COLUMNS,BLOCK_HEADING_LEVELS,BLOCK_JUSTIFIES,BLOCK_RATIOS,BLOCK_SIZES,BLOCK_TEXT_ALIGNS,BLOCK_TONES,BLOCK_WEIGHTS,LEGACY_SESSION_COOKIE_NAME,LOCAL_MODE_BANNER,MAX_BLOCK_ARMS,MAX_BLOCK_CHILDREN,MAX_BLOCK_DEPTH,MAX_BLOCK_NODES,MAX_BLOCK_TEXT_LEN,PROD_KEYLESS_ERROR,SNAPSHOT_STORAGE_KEY_PREFIX,_registerConsentUpgradeInit,agentIntent,agentUaList,armOfResult,attachMicroSignalDetectors,baselineResultFor,baselineSlots,classifiedAgents,deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,grantConsent,init,isDoNotTrackEnabled,matchedAgentToken,readSnapshot,referrerDomainFromReferer,renderPrePaintScript,sessionCookieName,toWireSlot,uaTokenMatch,writeSnapshot});
|
|
2
2
|
//# sourceMappingURL=index.js.map
|