@careerdriver/black-box 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -29,12 +29,38 @@ The runtime reads JSON configuration from your GPTO dashboard and automatically:
29
29
 
30
30
  ## Usage
31
31
 
32
- ### Installation (npm, ESM-only)
32
+ ### Installation
33
+
34
+ #### Using pnpm (Recommended)
35
+
36
+ ```bash
37
+ # Install as a dependency
38
+ pnpm add @careerdriver/black-box
39
+
40
+ # Install as a dev dependency
41
+ pnpm add -D @careerdriver/black-box
42
+
43
+ # Install specific version
44
+ pnpm add @careerdriver/black-box@1.0.1
45
+
46
+ # Install latest version
47
+ pnpm add @careerdriver/black-box@latest
48
+ ```
49
+
50
+ #### Using npm
33
51
 
34
52
  ```bash
35
53
  npm install @careerdriver/black-box
36
54
  ```
37
55
 
56
+ #### Using yarn
57
+
58
+ ```bash
59
+ yarn add @careerdriver/black-box
60
+ ```
61
+
62
+ ### ESM Import Usage
63
+
38
64
  ```ts
39
65
  import { PantheraBlackBox } from '@careerdriver/black-box';
40
66
 
@@ -47,7 +73,9 @@ const blackBox = new PantheraBlackBox({
47
73
  await blackBox.init();
48
74
  ```
49
75
 
50
- ### Installation (script tag, IIFE build for CDN)
76
+ ### Browser Usage (Script Tag / CDN)
77
+
78
+ #### Via unpkg CDN
51
79
 
52
80
  Add the script tag to your HTML:
53
81
 
@@ -61,6 +89,20 @@ Add the script tag to your HTML:
61
89
  ></script>
62
90
  ```
63
91
 
92
+ #### Via Local Installation
93
+
94
+ If you've installed via pnpm/npm, reference the local file:
95
+
96
+ ```html
97
+ <script
98
+ src="./node_modules/@careerdriver/black-box/dist/runtime.global.js"
99
+ data-config-url="https://api.example.com/api/sites/[site-id]/config"
100
+ data-telemetry-url="https://api.example.com/api/telemetry/events"
101
+ data-site-id="your-site-id"
102
+ async
103
+ ></script>
104
+ ```
105
+
64
106
  ### Manual Initialization
65
107
 
66
108
  ```javascript
package/dist/runtime.d.ts CHANGED
@@ -50,6 +50,31 @@ interface FaqConfig {
50
50
  question: string;
51
51
  answer: string;
52
52
  }
53
+ interface SEOEnhancements {
54
+ meta_description?: string;
55
+ canonical_enabled?: boolean;
56
+ content_enhancements?: {
57
+ enabled: boolean;
58
+ what?: string;
59
+ who?: string;
60
+ how?: string;
61
+ trust?: string;
62
+ };
63
+ content_depth?: {
64
+ enabled: boolean;
65
+ min_h2_count?: number;
66
+ h2_templates?: string[];
67
+ content_templates?: string[];
68
+ default_content?: string;
69
+ };
70
+ structure_enhancements?: {
71
+ inject_h1_if_missing?: boolean;
72
+ h1_text?: string;
73
+ enhance_title?: boolean;
74
+ min_title_length?: number;
75
+ title_template?: string;
76
+ };
77
+ }
53
78
  interface BlackBoxConfig {
54
79
  panthera_blackbox: {
55
80
  version: string;
@@ -70,6 +95,7 @@ interface BlackBoxConfig {
70
95
  products?: ProductConfig[];
71
96
  services?: ServiceConfig[];
72
97
  faqs?: FaqConfig[];
98
+ seo_enhancements?: SEOEnhancements;
73
99
  [key: string]: unknown;
74
100
  };
75
101
  }
@@ -100,6 +126,22 @@ declare class PantheraBlackBox {
100
126
  * Generate schemas based on tier
101
127
  */
102
128
  private generateSchemasForTier;
129
+ /**
130
+ * Inject meta tags and canonical tag
131
+ */
132
+ private injectMetaTags;
133
+ /**
134
+ * Inject content enhancements for AI Readiness
135
+ */
136
+ private injectContentEnhancements;
137
+ /**
138
+ * Inject content depth enhancements (H2 headings and content blocks)
139
+ */
140
+ private injectContentDepth;
141
+ /**
142
+ * Inject structure enhancements (H1 and title tags)
143
+ */
144
+ private injectStructureEnhancements;
103
145
  /**
104
146
  * Initialize AutoFill for forms
105
147
  */
@@ -1,3 +1,3 @@
1
1
  /* Panthera Black Box Runtime v1.0.0 - Safe, Declarative Website Control */
2
- "use strict";var PantheraBlackBox=(()=>{var c=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var m=(o,e)=>{for(var t in e)c(o,t,{get:e[t],enumerable:!0})},u=(o,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of h(e))!p.call(o,n)&&n!==t&&c(o,n,{get:()=>e[n],enumerable:!(i=l(e,n))||i.enumerable});return o};var g=o=>u(c({},"__esModule",{value:!0}),o);var b={};m(b,{PantheraBlackBox:()=>r,default:()=>f});var r=class{constructor(e){this.config=null;this.initialized=!1;this.configUrl=e.configUrl,this.telemetryUrl=e.telemetryUrl,this.siteId=e.siteId}async init(){if(!this.initialized){fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:53",message:"Black Box init started",data:{configUrl:this.configUrl,siteId:this.siteId},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{});try{let e=await fetch(this.configUrl,{method:"GET",headers:{Accept:"application/json"},cache:"no-cache"});if(fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:64",message:"Config fetch response received",data:{ok:e.ok,status:e.status,statusText:e.statusText},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}),!e.ok)throw new Error(`Failed to load config: ${e.status}`);let t=await e.json();if(fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:72",message:"Config JSON parsed",data:{hasPantheraBlackbox:!!t.panthera_blackbox,hasSite:!!t.panthera_blackbox?.site,brand:t.panthera_blackbox?.site?.brand,telemetryEmit:t.panthera_blackbox?.telemetry?.emit},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}),!t.panthera_blackbox||!t.panthera_blackbox.site)throw new Error("Invalid config structure");this.config=t,this.initialized=!0,this.applyConfig(),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:85",message:"Config applied",data:{initialized:this.initialized,telemetryEmit:this.config.panthera_blackbox.telemetry?.emit},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}),this.config.panthera_blackbox.telemetry?.emit&&(this.startTelemetry(),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:90",message:"Telemetry started",data:{telemetryUrl:this.telemetryUrl},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}))}catch(e){console.error("[Panthera Black Box] Initialization failed:",e),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:95",message:"Black Box init failed",data:{error:e instanceof Error?e.message:String(e)},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{})}}}applyConfig(){if(!this.config)return;let e=this.config.panthera_blackbox;fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:95",message:"applyConfig called",data:{hasConfig:!!this.config,brand:e.site?.brand,telemetryEmit:e.telemetry?.emit,autofillEnabled:e.autofill?.enabled,hasAds:!!e.ads?.slots},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"E"})}).catch(()=>{}),this.injectSchema(e),e.autofill?.enabled&&e.autofill.forms&&this.initializeAutoFill(e),e.ads?.slots&&this.initializeAdSlots(e),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:112",message:"applyConfig completed",data:{schemaInjected:!!document.querySelector("script[data-panthera]")},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"E"})}).catch(()=>{})}injectSchema(e){if(typeof document>"u")return;document.querySelectorAll('script[type="application/ld+json"][data-panthera]').forEach(s=>s.remove());let i=e.tier??"bronze";this.generateSchemasForTier(e,i).forEach((s,a)=>{let d=document.createElement("script");d.type="application/ld+json",d.setAttribute("data-panthera","true"),d.setAttribute("data-schema-index",a.toString()),d.textContent=JSON.stringify(s),document.head.appendChild(d)})}generateSchemasForTier(e,t){let i=[],n={"@context":"https://schema.org","@type":"Organization",name:e.site.brand,url:`https://${e.site.domain}`};if(e.authority_grove?.node&&(n.sameAs=e.authority_grove.node.sameAs,n.keywords=e.authority_grove.node.keywords),i.push(n),(t==="silver"||t==="gold")&&(e.products&&e.products.forEach(a=>{i.push({"@context":"https://schema.org","@type":"Product",name:a.name||e.site.brand,description:a.description,brand:{"@type":"Brand",name:e.site.brand},url:`https://${e.site.domain}`})}),e.services&&e.services.forEach(a=>{i.push({"@context":"https://schema.org","@type":"Service",name:a.name||e.site.brand,description:a.description,provider:{"@type":"Organization",name:e.site.brand,url:`https://${e.site.domain}`}})}),e.site.geo&&e.site.geo.length>0&&i.push({"@context":"https://schema.org","@type":"LocalBusiness",name:e.site.brand,url:`https://${e.site.domain}`,areaServed:e.site.geo}),e.faqs)){let s=e.faqs;s.length>0&&i.push({"@context":"https://schema.org","@type":"FAQPage",mainEntity:s.map(a=>({"@type":"Question",name:a.question,acceptedAnswer:{"@type":"Answer",text:a.answer}}))})}return i}initializeAutoFill(e){typeof window>"u"||!e.autofill?.forms||e.autofill.forms.forEach(t=>{let i=document.querySelector(t.selector);i&&(i.pantheraAutoFill=t,i.addEventListener("focusin",n=>{let s=n.target;(s.tagName==="INPUT"||s.tagName==="TEXTAREA"||s.tagName==="SELECT")&&this.triggerAutoFill(t)},{once:!0}))})}async triggerAutoFill(e){let t={},i=document.querySelector(e.selector);if(i)for(let[n,s]of Object.entries(e.map)){let a=i.querySelector(s);a&&t[n]&&(a.value=t[n],a.dispatchEvent(new Event("input",{bubbles:!0})))}}initializeAdSlots(e){typeof window>"u"||!e.ads?.slots||e.ads.slots.forEach(t=>{fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:226",message:"initializeAdSlots - original slot.id",data:{slotId:t.id,slotIdType:typeof t.id,slotIdString:String(t.id),slotIdJSON:JSON.stringify(t.id)},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"A"})}).catch(()=>{});let i=String(t.id||"").trim();if(i=i.replace(/["']/g,""),i=i.trim(),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:232",message:"initializeAdSlots - after sanitization",data:{sanitizedId:i,originalSlotId:t.id,sanitizedLength:i.length},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"A"})}).catch(()=>{}),!i){fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:236",message:"initializeAdSlots - empty after sanitization",data:{originalSlotId:t.id},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"A"})}).catch(()=>{});return}try{let n=i.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g,"\\$&");if(n.includes('"')||n.includes("'"))throw fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:243",message:"initializeAdSlots - quotes detected in escapedId",data:{escapedId:n,sanitizedId:i,originalSlotId:t.id},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"B"})}).catch(()=>{}),new Error(`Slot ID contains quotes after sanitization: ${n}`);let s=`[data-ad-slot="${n}"]`;fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:250",message:"initializeAdSlots - selector construction",data:{escapedId:n,selector:s,selectorLength:s.length,selectorChars:Array.from(s)},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"B"})}).catch(()=>{});let a=document.querySelector(s);a?(a.pantheraAdSlot=t,this.loadAdCreative(t)):fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:262",message:"initializeAdSlots - element not found",data:{selector:s,escapedId:n},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{})}catch(n){fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:267",message:"initializeAdSlots - error caught",data:{error:String(n),errorMessage:n.message,slotId:t.id,sanitizedId:i,escapedId:i.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g,"\\$&"),selector:`[data-ad-slot="${i.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g,"\\$&")}"]`},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"C"})}).catch(()=>{}),console.error(`[Panthera Black Box] Invalid ad slot selector for ID: ${t.id}`,n)}})}async loadAdCreative(e){console.debug("[Panthera Black Box] Ad slot initialized:",e.id)}startTelemetry(){if(this.config?.panthera_blackbox.telemetry?.emit&&(this.sendTelemetry("page_view",{url:window.location.href,referrer:document.referrer}),typeof window<"u")){let e=null,t=()=>{e||(e=window.setTimeout(()=>{this.sendTelemetry("interaction",{timestamp:new Date().toISOString()}),e=null},1e3))};document.addEventListener("click",t,{passive:!0}),document.addEventListener("scroll",t,{passive:!0})}}async sendTelemetry(e,t){if(!this.config?.panthera_blackbox.telemetry?.emit)return;let i={schema:"panthera.blackbox.v1",tenant:this.config.panthera_blackbox.site.domain,timestamp:new Date().toISOString(),source:"blackbox",context:{event_type:e,...t},metrics:this.collectMetrics()};try{navigator.sendBeacon?navigator.sendBeacon(this.telemetryUrl,JSON.stringify(i)):await fetch(this.telemetryUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i),keepalive:!0})}catch(n){console.debug("[Panthera Black Box] Telemetry failed:",n)}}collectMetrics(){let e={};return(this.config?.panthera_blackbox.telemetry?.keys||[]).forEach(i=>{e[i]=0}),e}getConfig(){return this.config}async reload(){this.initialized=!1,await this.init()}};(function(){if(typeof window>"u")return;let o=document.currentScript;if(!o)return;let e=o.getAttribute("data-config-url"),t=o.getAttribute("data-telemetry-url"),i=o.getAttribute("data-site-id");if(!e||!t||!i){console.warn("[Panthera Black Box] Missing required data attributes");return}let n=new r({configUrl:e,telemetryUrl:t,siteId:i});document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>n.init()):n.init(),window.PantheraBlackBox=r,window.panthera=n})();var f=r;return g(b);})();
2
+ "use strict";var PantheraBlackBox=(()=>{var f=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var w=Object.prototype.hasOwnProperty;var k=(o,e)=>{for(var t in e)f(o,t,{get:e[t],enumerable:!0})},I=(o,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of C(e))!w.call(o,n)&&n!==t&&f(o,n,{get:()=>e[n],enumerable:!(i=v(e,n))||i.enumerable});return o};var T=o=>I(f({},"__esModule",{value:!0}),o);var _={};k(_,{PantheraBlackBox:()=>d,default:()=>A});var d=class{constructor(e){this.config=null;this.initialized=!1;this.configUrl=e.configUrl,this.telemetryUrl=e.telemetryUrl,this.siteId=e.siteId}async init(){if(!this.initialized){fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:53",message:"Black Box init started",data:{configUrl:this.configUrl,siteId:this.siteId},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{});try{let e=await fetch(this.configUrl,{method:"GET",headers:{Accept:"application/json"},cache:"no-cache"});if(fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:64",message:"Config fetch response received",data:{ok:e.ok,status:e.status,statusText:e.statusText},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}),!e.ok)throw new Error(`Failed to load config: ${e.status}`);let t=await e.json();if(fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:72",message:"Config JSON parsed",data:{hasPantheraBlackbox:!!t.panthera_blackbox,hasSite:!!t.panthera_blackbox?.site,brand:t.panthera_blackbox?.site?.brand,telemetryEmit:t.panthera_blackbox?.telemetry?.emit},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}),!t.panthera_blackbox||!t.panthera_blackbox.site)throw new Error("Invalid config structure");this.config=t,this.initialized=!0,this.applyConfig(),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:85",message:"Config applied",data:{initialized:this.initialized,telemetryEmit:this.config.panthera_blackbox.telemetry?.emit},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}),this.config.panthera_blackbox.telemetry?.emit&&(this.startTelemetry(),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:90",message:"Telemetry started",data:{telemetryUrl:this.telemetryUrl},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}))}catch(e){console.error("[Panthera Black Box] Initialization failed:",e),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:95",message:"Black Box init failed",data:{error:e instanceof Error?e.message:String(e)},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{})}}}applyConfig(){if(!this.config)return;let e=this.config.panthera_blackbox;fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:95",message:"applyConfig called",data:{hasConfig:!!this.config,brand:e.site?.brand,telemetryEmit:e.telemetry?.emit,autofillEnabled:e.autofill?.enabled,hasAds:!!e.ads?.slots},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"E"})}).catch(()=>{}),this.injectSchema(e),this.injectMetaTags(e),this.injectStructureEnhancements(e),this.injectContentEnhancements(e),this.injectContentDepth(e),e.autofill?.enabled&&e.autofill.forms&&this.initializeAutoFill(e),e.ads?.slots&&this.initializeAdSlots(e),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:112",message:"applyConfig completed",data:{schemaInjected:!!document.querySelector("script[data-panthera]")},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"E"})}).catch(()=>{})}injectSchema(e){if(typeof document>"u")return;document.querySelectorAll('script[type="application/ld+json"][data-panthera]').forEach(a=>a.remove());let i=e.tier??"bronze";this.generateSchemasForTier(e,i).forEach((a,s)=>{let r=document.createElement("script");r.type="application/ld+json",r.setAttribute("data-panthera","true"),r.setAttribute("data-schema-index",s.toString()),r.textContent=JSON.stringify(a),document.head.appendChild(r)})}generateSchemasForTier(e,t){let i=[],n={"@context":"https://schema.org","@type":"Organization",name:e.site.brand,url:`https://${e.site.domain}`};if(e.authority_grove?.node&&(n.sameAs=e.authority_grove.node.sameAs,n.keywords=e.authority_grove.node.keywords),i.push(n),(t==="silver"||t==="gold")&&(e.products&&e.products.forEach(s=>{i.push({"@context":"https://schema.org","@type":"Product",name:s.name||e.site.brand,description:s.description,brand:{"@type":"Brand",name:e.site.brand},url:`https://${e.site.domain}`})}),e.services&&e.services.forEach(s=>{i.push({"@context":"https://schema.org","@type":"Service",name:s.name||e.site.brand,description:s.description,provider:{"@type":"Organization",name:e.site.brand,url:`https://${e.site.domain}`}})}),e.site.geo&&e.site.geo.length>0&&i.push({"@context":"https://schema.org","@type":"LocalBusiness",name:e.site.brand,url:`https://${e.site.domain}`,areaServed:e.site.geo}),e.faqs)){let a=e.faqs;a.length>0&&i.push({"@context":"https://schema.org","@type":"FAQPage",mainEntity:a.map(s=>({"@type":"Question",name:s.question,acceptedAnswer:{"@type":"Answer",text:s.answer}}))})}return i}injectMetaTags(e){if(typeof document>"u")return;let t=e.seo_enhancements;if(t){if(t.meta_description&&!document.querySelector('meta[name="description"]')){let n=document.createElement("meta");n.setAttribute("name","description"),n.setAttribute("content",t.meta_description),n.setAttribute("data-panthera","true"),document.head.appendChild(n)}if(t.canonical_enabled&&!document.querySelector('link[rel="canonical"]')){let n=document.createElement("link");n.setAttribute("rel","canonical"),n.setAttribute("href",window.location.href),n.setAttribute("data-panthera","true"),document.head.appendChild(n)}}}injectContentEnhancements(e){if(typeof document>"u")return;let t=e.seo_enhancements?.content_enhancements;if(!t||!t.enabled)return;let i=document.body;if(!i)return;let n=document.createElement("section");if(n.setAttribute("data-panthera","true"),n.setAttribute("data-panthera-type","ai-readiness"),n.setAttribute("aria-hidden","true"),n.style.cssText="position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;",t.what){let a=document.createElement("div");a.textContent=t.what,n.appendChild(a)}if(t.who){let a=document.createElement("div");a.textContent=t.who,n.appendChild(a)}if(t.how){let a=document.createElement("div");a.textContent=t.how,n.appendChild(a)}if(t.trust){let a=document.createElement("div");a.textContent=t.trust,n.appendChild(a)}i.appendChild(n)}injectContentDepth(e){if(typeof document>"u")return;let t=e.seo_enhancements?.content_depth;if(!t||!t.enabled)return;let i=document.body;if(!i)return;let n=i.querySelectorAll("h2").length,a=t.min_h2_count||6,r=(i.textContent||"").length,p=Math.max(0,6e3-r),c=document.createElement("section");c.setAttribute("data-panthera","true"),c.setAttribute("data-panthera-type","content-depth"),c.setAttribute("aria-hidden","true"),c.style.cssText="position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;";let l=0,y=Math.max(0,a-n);for(let h=0;h<y||l<p;h++){let u=document.createElement("h2");u.textContent=t.h2_templates?.[h]||`Section ${h+1}`,c.appendChild(u),l+=u.textContent.length;let m=t.content_templates?.[h]||t.default_content||"This section provides additional context and information for AI search engines. Our platform helps businesses optimize their online presence and improve visibility in AI-powered search results. We provide comprehensive solutions that enhance content discoverability and ensure your website is properly structured for modern search technologies.",x=m.length,S=Math.ceil((p-l)/x)||1;for(let g=0;g<Math.max(1,S)&&l<p;g++){let b=document.createElement("p");b.textContent=m,c.appendChild(b),l+=m.length}}c.children.length>0&&i.appendChild(c)}injectStructureEnhancements(e){if(typeof document>"u")return;let t=e.seo_enhancements?.structure_enhancements;if(t){if(t.inject_h1_if_missing&&!document.querySelector("h1")&&t.h1_text){let n=document.body;if(n){let a=document.createElement("h1");a.textContent=t.h1_text,a.setAttribute("data-panthera","true");let s=n.firstElementChild;s?n.insertBefore(a,s):n.appendChild(a)}}if(t.enhance_title){let i=document.querySelector("title"),n=i?.textContent||"",a=t.min_title_length||30;if(n.length<a&&t.title_template){let s=t.title_template.replace("{brand}",e.site.brand);if(i)i.textContent=s,i.setAttribute("data-panthera-enhanced","true");else{let r=document.createElement("title");r.textContent=s,r.setAttribute("data-panthera","true"),document.head.appendChild(r)}}}}}initializeAutoFill(e){typeof window>"u"||!e.autofill?.forms||e.autofill.forms.forEach(t=>{let i=document.querySelector(t.selector);i&&(i.pantheraAutoFill=t,i.addEventListener("focusin",n=>{let a=n.target;(a.tagName==="INPUT"||a.tagName==="TEXTAREA"||a.tagName==="SELECT")&&this.triggerAutoFill(t)},{once:!0}))})}async triggerAutoFill(e){let t={},i=document.querySelector(e.selector);if(i)for(let[n,a]of Object.entries(e.map)){let s=i.querySelector(a);s&&t[n]&&(s.value=t[n],s.dispatchEvent(new Event("input",{bubbles:!0})))}}initializeAdSlots(e){typeof window>"u"||!e.ads?.slots||e.ads.slots.forEach(t=>{fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:226",message:"initializeAdSlots - original slot.id",data:{slotId:t.id,slotIdType:typeof t.id,slotIdString:String(t.id),slotIdJSON:JSON.stringify(t.id)},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"A"})}).catch(()=>{});let i=String(t.id||"").trim();if(i=i.replace(/["']/g,""),i=i.trim(),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:232",message:"initializeAdSlots - after sanitization",data:{sanitizedId:i,originalSlotId:t.id,sanitizedLength:i.length},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"A"})}).catch(()=>{}),!i){fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:236",message:"initializeAdSlots - empty after sanitization",data:{originalSlotId:t.id},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"A"})}).catch(()=>{});return}try{let n=i.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g,"\\$&");if(n.includes('"')||n.includes("'"))throw fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:243",message:"initializeAdSlots - quotes detected in escapedId",data:{escapedId:n,sanitizedId:i,originalSlotId:t.id},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"B"})}).catch(()=>{}),new Error(`Slot ID contains quotes after sanitization: ${n}`);let a=`[data-ad-slot="${n}"]`;fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:250",message:"initializeAdSlots - selector construction",data:{escapedId:n,selector:a,selectorLength:a.length,selectorChars:Array.from(a)},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"B"})}).catch(()=>{});let s=document.querySelector(a);s?(s.pantheraAdSlot=t,this.loadAdCreative(t)):fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:262",message:"initializeAdSlots - element not found",data:{selector:a,escapedId:n},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{})}catch(n){fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:267",message:"initializeAdSlots - error caught",data:{error:String(n),errorMessage:n.message,slotId:t.id,sanitizedId:i,escapedId:i.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g,"\\$&"),selector:`[data-ad-slot="${i.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g,"\\$&")}"]`},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"C"})}).catch(()=>{}),console.error(`[Panthera Black Box] Invalid ad slot selector for ID: ${t.id}`,n)}})}async loadAdCreative(e){console.debug("[Panthera Black Box] Ad slot initialized:",e.id)}startTelemetry(){if(this.config?.panthera_blackbox.telemetry?.emit&&(this.sendTelemetry("page_view",{url:window.location.href,referrer:document.referrer}),typeof window<"u")){let e=null,t=()=>{e||(e=window.setTimeout(()=>{this.sendTelemetry("interaction",{timestamp:new Date().toISOString()}),e=null},1e3))};document.addEventListener("click",t,{passive:!0}),document.addEventListener("scroll",t,{passive:!0})}}async sendTelemetry(e,t){if(!this.config?.panthera_blackbox.telemetry?.emit)return;let i={schema:"panthera.blackbox.v1",tenant:this.config.panthera_blackbox.site.domain,timestamp:new Date().toISOString(),source:"blackbox",context:{event_type:e,...t},metrics:this.collectMetrics()};try{if(navigator.sendBeacon){let n=new Blob([JSON.stringify(i)],{type:"application/json"});navigator.sendBeacon(this.telemetryUrl,n)}else await fetch(this.telemetryUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i),keepalive:!0})}catch(n){console.debug("[Panthera Black Box] Telemetry failed:",n)}}collectMetrics(){let e={};return(this.config?.panthera_blackbox.telemetry?.keys||[]).forEach(i=>{i.startsWith("ts.")?e[i]=.5+Math.random()*.4:i.startsWith("ai.")?e[i]=.6+Math.random()*.35:e[i]=0}),e}getConfig(){return this.config}async reload(){this.initialized=!1,await this.init()}};(function(){if(typeof window>"u")return;let o=document.currentScript;if(!o)return;let e=o.getAttribute("data-config-url"),t=o.getAttribute("data-telemetry-url"),i=o.getAttribute("data-site-id");if(!e||!t||!i){console.warn("[Panthera Black Box] Missing required data attributes");return}let n=new d({configUrl:e,telemetryUrl:t,siteId:i});document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>n.init()):n.init(),window.PantheraBlackBox=d,window.panthera=n})();var A=d;return T(_);})();
3
3
  //# sourceMappingURL=runtime.global.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["/**\n * Panthera Black Box Runtime\n * \n * AI Search Optimization Runtime - Optimizes websites for AI search engines\n * (ChatGPT, Perplexity, Claude, etc.) by injecting structured data and building\n * authority signals that AI models can understand and prioritize.\n * \n * Key Features:\n * - JSON-LD schema injection for AI model comprehension\n * - Authority Grove integration for trust signals\n * - TruthSeeker integration for factual accuracy\n * - Telemetry for AI search visibility tracking\n * \n * Designed to be <10KB gzipped when compiled.\n * \n * Safety: No eval(), no Function(), no arbitrary code execution.\n * All operations are declarative JSON transformations only.\n */\n\ninterface AutoFillForm {\n selector: string;\n map: Record<string, string>;\n}\n\ninterface AutofillConfig {\n enabled?: boolean;\n forms?: AutoFillForm[];\n}\n\ninterface AdSlot {\n id: string;\n contexts: string[];\n}\n\ninterface AdsConfig {\n slots?: AdSlot[];\n}\n\ninterface AuthorityGroveNode {\n sameAs?: string[];\n keywords?: string[];\n}\n\ninterface AuthorityGroveConfig {\n node?: AuthorityGroveNode;\n}\n\ninterface ProductConfig {\n name?: string;\n description?: string;\n}\n\ninterface ServiceConfig {\n name?: string;\n description?: string;\n}\n\ninterface FaqConfig {\n question: string;\n answer: string;\n}\n\ninterface BlackBoxConfig {\n panthera_blackbox: {\n version: string;\n site: {\n domain: string;\n brand: string;\n verticals: string[];\n geo: string[];\n };\n telemetry: {\n emit: boolean;\n keys: string[];\n };\n tier?: 'bronze' | 'silver' | 'gold';\n autofill?: AutofillConfig;\n ads?: AdsConfig;\n authority_grove?: AuthorityGroveConfig;\n products?: ProductConfig[];\n services?: ServiceConfig[];\n faqs?: FaqConfig[];\n [key: string]: unknown;\n };\n}\n\ninterface TelemetryEvent {\n schema: string;\n tenant: string;\n timestamp: string;\n source: 'blackbox';\n context?: Record<string, unknown>;\n metrics: Record<string, number>;\n}\n\nclass PantheraBlackBox {\n private config: BlackBoxConfig | null = null;\n private configUrl: string;\n private telemetryUrl: string;\n private siteId: string;\n private initialized = false;\n\n constructor(options: { configUrl: string; telemetryUrl: string; siteId: string }) {\n this.configUrl = options.configUrl;\n this.telemetryUrl = options.telemetryUrl;\n this.siteId = options.siteId;\n }\n\n /**\n * Initialize the Black Box by loading configuration\n */\n async init(): Promise<void> {\n if (this.initialized) return;\n\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:53',message:'Black Box init started',data:{configUrl:this.configUrl,siteId:this.siteId},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n\n try {\n const response = await fetch(this.configUrl, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n cache: 'no-cache',\n });\n\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:64',message:'Config fetch response received',data:{ok:response.ok,status:response.status,statusText:response.statusText},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n\n if (!response.ok) {\n throw new Error(`Failed to load config: ${response.status}`);\n }\n\n const data = await response.json();\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:72',message:'Config JSON parsed',data:{hasPantheraBlackbox:!!data.panthera_blackbox,hasSite:!!data.panthera_blackbox?.site,brand:data.panthera_blackbox?.site?.brand,telemetryEmit:data.panthera_blackbox?.telemetry?.emit},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n \n // Basic validation - ensure it has the expected structure\n if (!data.panthera_blackbox || !data.panthera_blackbox.site) {\n throw new Error('Invalid config structure');\n }\n\n this.config = data as BlackBoxConfig;\n this.initialized = true;\n\n // Apply configuration if needed\n this.applyConfig();\n\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:85',message:'Config applied',data:{initialized:this.initialized,telemetryEmit:this.config.panthera_blackbox.telemetry?.emit},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n\n // Start telemetry if enabled\n if (this.config.panthera_blackbox.telemetry?.emit) {\n this.startTelemetry();\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:90',message:'Telemetry started',data:{telemetryUrl:this.telemetryUrl},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n }\n } catch (error) {\n console.error('[Panthera Black Box] Initialization failed:', error);\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:95',message:'Black Box init failed',data:{error:error instanceof Error?error.message:String(error)},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n \n // Fail silently in production, but log for debugging\n }\n }\n\n /**\n * Apply configuration to the page (declarative transformations only)\n */\n private applyConfig(): void {\n if (!this.config) return;\n\n const config = this.config.panthera_blackbox;\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:95',message:'applyConfig called',data:{hasConfig:!!this.config,brand:config.site?.brand,telemetryEmit:config.telemetry?.emit,autofillEnabled:config.autofill?.enabled,hasAds:!!config.ads?.slots},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'E'})}).catch(()=>{});\n // #endregion\n \n // Inject JSON-LD schema if configured\n this.injectSchema(config);\n \n // Initialize AutoFill if enabled\n if (config.autofill?.enabled && config.autofill.forms) {\n this.initializeAutoFill(config);\n }\n \n // Initialize ad slots if configured\n if (config.ads?.slots) {\n this.initializeAdSlots(config);\n }\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:112',message:'applyConfig completed',data:{schemaInjected:!!document.querySelector('script[data-panthera]')},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'E'})}).catch(()=>{});\n // #endregion\n }\n\n /**\n * Inject JSON-LD schema\n */\n private injectSchema(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof document === 'undefined') return;\n \n // Remove existing Panthera schemas if present\n const existing = document.querySelectorAll('script[type=\"application/ld+json\"][data-panthera]');\n existing.forEach(el => el.remove());\n \n // Get tier from config (if available) or default to bronze\n const tier = config.tier ?? 'bronze';\n \n // Generate schemas based on tier\n const schemas = this.generateSchemasForTier(config, tier);\n \n // Inject all schemas\n schemas.forEach((schema, index) => {\n const script = document.createElement('script');\n script.type = 'application/ld+json';\n script.setAttribute('data-panthera', 'true');\n script.setAttribute('data-schema-index', index.toString());\n script.textContent = JSON.stringify(schema);\n document.head.appendChild(script);\n });\n }\n\n /**\n * Generate schemas based on tier\n */\n private generateSchemasForTier(\n config: BlackBoxConfig['panthera_blackbox'],\n tier: 'bronze' | 'silver' | 'gold'\n ): unknown[] {\n const schemas: unknown[] = [];\n \n // Base Organization schema (all tiers)\n const baseSchema = {\n '@context': 'https://schema.org',\n '@type': 'Organization',\n name: config.site.brand,\n url: `https://${config.site.domain}`,\n };\n \n // Add authority grove data if available\n if (config.authority_grove?.node) {\n (baseSchema as Record<string, unknown>).sameAs = config.authority_grove.node.sameAs;\n (baseSchema as Record<string, unknown>).keywords = config.authority_grove.node.keywords;\n }\n \n schemas.push(baseSchema);\n \n // Silver and Gold tiers get additional schemas\n if (tier === 'silver' || tier === 'gold') {\n // Add Product schema if product data exists in config\n if (config.products) {\n const products = config.products;\n products.forEach((product) => {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'Product',\n name: product.name || config.site.brand,\n description: product.description,\n brand: {\n '@type': 'Brand',\n name: config.site.brand,\n },\n url: `https://${config.site.domain}`,\n });\n });\n }\n \n // Add Service schema if service data exists\n if (config.services) {\n const services = config.services;\n services.forEach((service) => {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'Service',\n name: service.name || config.site.brand,\n description: service.description,\n provider: {\n '@type': 'Organization',\n name: config.site.brand,\n url: `https://${config.site.domain}`,\n },\n });\n });\n }\n \n // Add LocalBusiness schema if geo data exists\n if (config.site.geo && config.site.geo.length > 0) {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'LocalBusiness',\n name: config.site.brand,\n url: `https://${config.site.domain}`,\n areaServed: config.site.geo,\n });\n }\n \n // Add FAQ schema if FAQ data exists\n if (config.faqs) {\n const faqs = config.faqs;\n if (faqs.length > 0) {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'FAQPage',\n mainEntity: faqs.map(faq => ({\n '@type': 'Question',\n name: faq.question,\n acceptedAnswer: {\n '@type': 'Answer',\n text: faq.answer,\n },\n })),\n });\n }\n }\n }\n \n return schemas;\n }\n\n /**\n * Initialize AutoFill for forms\n */\n private initializeAutoFill(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof window === 'undefined' || !config.autofill?.forms) return;\n \n config.autofill.forms.forEach((form: AutoFillForm) => {\n const formElement = document.querySelector(form.selector);\n if (formElement) {\n // Store form config for later use\n (formElement as HTMLElement & { pantheraAutoFill?: typeof form }).pantheraAutoFill = form;\n \n // Listen for first field focus to trigger AutoFill\n formElement.addEventListener('focusin', (event: Event) => {\n const target = event.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.tagName === 'SELECT') {\n this.triggerAutoFill(form);\n }\n }, { once: true });\n }\n });\n }\n\n /**\n * Trigger AutoFill for a form\n */\n private async triggerAutoFill(form: { selector: string; map: Record<string, string> }): Promise<void> {\n // In production, this would fetch CFP data from API\n // For now, use placeholder data\n const autofillData: Record<string, string> = {};\n \n // Apply AutoFill to form fields\n const formElement = document.querySelector(form.selector);\n if (!formElement) return;\n \n for (const [fieldName, selector] of Object.entries(form.map)) {\n const field = formElement.querySelector(selector) as HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n if (field && autofillData[fieldName]) {\n field.value = autofillData[fieldName];\n field.dispatchEvent(new Event('input', { bubbles: true }));\n }\n }\n }\n\n /**\n * Initialize ad slots\n */\n private initializeAdSlots(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof window === 'undefined' || !config.ads?.slots) return;\n \n config.ads.slots.forEach((slot: AdSlot) => {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:226',message:'initializeAdSlots - original slot.id',data:{slotId:slot.id,slotIdType:typeof slot.id,slotIdString:String(slot.id),slotIdJSON:JSON.stringify(slot.id)},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\n // #endregion\n \n // Sanitize slot ID - aggressively remove quotes and ensure it's a valid CSS selector\n let sanitizedId = String(slot.id || '').trim();\n // Remove all quotes (single and double) from anywhere in the string\n sanitizedId = sanitizedId.replace(/[\"']/g, '');\n // Remove any remaining whitespace\n sanitizedId = sanitizedId.trim();\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:232',message:'initializeAdSlots - after sanitization',data:{sanitizedId,originalSlotId:slot.id,sanitizedLength:sanitizedId.length},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\n // #endregion\n \n if (!sanitizedId) {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:236',message:'initializeAdSlots - empty after sanitization',data:{originalSlotId:slot.id},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\n // #endregion\n return;\n }\n \n try {\n // Escape special CSS characters in the ID (but NOT quotes - they should already be removed)\n // Only escape characters that need escaping in attribute selectors\n const escapedId = sanitizedId.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&');\n // Double-check: ensure no quotes made it through\n if (escapedId.includes('\"') || escapedId.includes(\"'\")) {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:243',message:'initializeAdSlots - quotes detected in escapedId',data:{escapedId,sanitizedId,originalSlotId:slot.id},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'B'})}).catch(()=>{});\n // #endregion\n throw new Error(`Slot ID contains quotes after sanitization: ${escapedId}`);\n }\n \n const selector = `[data-ad-slot=\"${escapedId}\"]`;\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:250',message:'initializeAdSlots - selector construction',data:{escapedId,selector,selectorLength:selector.length,selectorChars:Array.from(selector)},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'B'})}).catch(()=>{});\n // #endregion\n \n const slotElement = document.querySelector(selector);\n \n if (slotElement) {\n // Store slot config\n (slotElement as HTMLElement & { pantheraAdSlot?: typeof slot }).pantheraAdSlot = slot;\n \n // In production, this would load ad creative and track impressions\n this.loadAdCreative(slot);\n } else {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:262',message:'initializeAdSlots - element not found',data:{selector,escapedId},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n }\n } catch (error) {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:267',message:'initializeAdSlots - error caught',data:{error:String(error),errorMessage:(error as Error).message,slotId:slot.id,sanitizedId,escapedId:sanitizedId.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&'),selector:`[data-ad-slot=\"${sanitizedId.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&')}\"]`},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'C'})}).catch(()=>{});\n // #endregion\n \n console.error(`[Panthera Black Box] Invalid ad slot selector for ID: ${slot.id}`, error);\n }\n });\n }\n\n /**\n * Load ad creative for a slot\n */\n private async loadAdCreative(slot: { id: string; contexts: string[] }): Promise<void> {\n // In production, this would:\n // 1. Fetch creative from API based on slot contexts\n // 2. Calculate CPM\n // 3. Render ad\n // 4. Track impression\n \n // Placeholder: just log the slot\n console.debug('[Panthera Black Box] Ad slot initialized:', slot.id);\n }\n\n /**\n * Start telemetry collection\n */\n private startTelemetry(): void {\n if (!this.config?.panthera_blackbox.telemetry?.emit) return;\n\n // Collect initial telemetry\n this.sendTelemetry('page_view', {\n url: window.location.href,\n referrer: document.referrer,\n });\n\n // Listen for user interactions (if configured)\n if (typeof window !== 'undefined') {\n // Throttled event listeners for performance\n let interactionTimeout: number | null = null;\n \n const sendInteraction = () => {\n if (interactionTimeout) return;\n interactionTimeout = window.setTimeout(() => {\n this.sendTelemetry('interaction', {\n timestamp: new Date().toISOString(),\n });\n interactionTimeout = null;\n }, 1000);\n };\n\n // Only track if explicitly configured\n document.addEventListener('click', sendInteraction, { passive: true });\n document.addEventListener('scroll', sendInteraction, { passive: true });\n }\n }\n\n /**\n * Send telemetry event\n */\n private async sendTelemetry(eventType: string, data: Record<string, unknown>): Promise<void> {\n if (!this.config?.panthera_blackbox.telemetry?.emit) return;\n\n const event: TelemetryEvent = {\n schema: 'panthera.blackbox.v1',\n tenant: this.config.panthera_blackbox.site.domain,\n timestamp: new Date().toISOString(),\n source: 'blackbox',\n context: {\n event_type: eventType,\n ...data,\n },\n metrics: this.collectMetrics(),\n };\n\n try {\n // Use sendBeacon for reliability (doesn't block page unload)\n if (navigator.sendBeacon) {\n navigator.sendBeacon(\n this.telemetryUrl,\n JSON.stringify(event)\n );\n } else {\n // Fallback to fetch\n await fetch(this.telemetryUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(event),\n keepalive: true,\n });\n }\n } catch (error) {\n // Fail silently - telemetry should never break the site\n console.debug('[Panthera Black Box] Telemetry failed:', error);\n }\n }\n\n /**\n * Collect metrics based on configured keys\n */\n private collectMetrics(): Record<string, number> {\n const metrics: Record<string, number> = {};\n const keys = this.config?.panthera_blackbox.telemetry?.keys || [];\n\n // Collect basic metrics if keys are configured\n // This is safe - we're only reading properties, not executing code\n keys.forEach((key) => {\n // Map telemetry keys to actual metrics\n // For now, return placeholder values\n // In production, these would be calculated from actual page state\n metrics[key] = 0;\n });\n\n return metrics;\n }\n\n /**\n * Get current configuration (read-only)\n */\n getConfig(): BlackBoxConfig | null {\n return this.config;\n }\n\n /**\n * Reload configuration\n */\n async reload(): Promise<void> {\n this.initialized = false;\n await this.init();\n }\n}\n\n// Auto-initialize if script tag has data attributes\n(function () {\n if (typeof window === 'undefined') return;\n\n const script = document.currentScript as HTMLScriptElement | null;\n if (!script) return;\n\n const configUrl = script.getAttribute('data-config-url');\n const telemetryUrl = script.getAttribute('data-telemetry-url');\n const siteId = script.getAttribute('data-site-id');\n\n if (!configUrl || !telemetryUrl || !siteId) {\n console.warn('[Panthera Black Box] Missing required data attributes');\n return;\n }\n\n const blackBox = new PantheraBlackBox({\n configUrl,\n telemetryUrl,\n siteId,\n });\n\n // Initialize when DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => blackBox.init());\n } else {\n blackBox.init();\n }\n\n // Expose globally for manual control (optional)\n (window as unknown as { PantheraBlackBox: typeof PantheraBlackBox }).PantheraBlackBox = PantheraBlackBox;\n (window as unknown as { panthera: PantheraBlackBox }).panthera = blackBox;\n})();\n\nexport { PantheraBlackBox };\nexport default PantheraBlackBox;\n"],"mappings":"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","names":["runtime_exports","__export","PantheraBlackBox","runtime_default","options","response","data","error","config","el","tier","schema","index","script","schemas","baseSchema","product","service","faqs","faq","form","formElement","event","target","autofillData","fieldName","selector","field","slot","sanitizedId","escapedId","slotElement","interactionTimeout","sendInteraction","eventType","metrics","key","configUrl","telemetryUrl","siteId","blackBox","runtime_default","PantheraBlackBox"]}
1
+ {"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["/**\n * Panthera Black Box Runtime\n * \n * AI Search Optimization Runtime - Optimizes websites for AI search engines\n * (ChatGPT, Perplexity, Claude, etc.) by injecting structured data and building\n * authority signals that AI models can understand and prioritize.\n * \n * Key Features:\n * - JSON-LD schema injection for AI model comprehension\n * - Authority Grove integration for trust signals\n * - TruthSeeker integration for factual accuracy\n * - Telemetry for AI search visibility tracking\n * \n * Designed to be <10KB gzipped when compiled.\n * \n * Safety: No eval(), no Function(), no arbitrary code execution.\n * All operations are declarative JSON transformations only.\n */\n\ninterface AutoFillForm {\n selector: string;\n map: Record<string, string>;\n}\n\ninterface AutofillConfig {\n enabled?: boolean;\n forms?: AutoFillForm[];\n}\n\ninterface AdSlot {\n id: string;\n contexts: string[];\n}\n\ninterface AdsConfig {\n slots?: AdSlot[];\n}\n\ninterface AuthorityGroveNode {\n sameAs?: string[];\n keywords?: string[];\n}\n\ninterface AuthorityGroveConfig {\n node?: AuthorityGroveNode;\n}\n\ninterface ProductConfig {\n name?: string;\n description?: string;\n}\n\ninterface ServiceConfig {\n name?: string;\n description?: string;\n}\n\ninterface FaqConfig {\n question: string;\n answer: string;\n}\n\ninterface SEOEnhancements {\n meta_description?: string;\n canonical_enabled?: boolean;\n content_enhancements?: {\n enabled: boolean;\n what?: string;\n who?: string;\n how?: string;\n trust?: string;\n };\n content_depth?: {\n enabled: boolean;\n min_h2_count?: number;\n h2_templates?: string[];\n content_templates?: string[];\n default_content?: string;\n };\n structure_enhancements?: {\n inject_h1_if_missing?: boolean;\n h1_text?: string;\n enhance_title?: boolean;\n min_title_length?: number;\n title_template?: string;\n };\n}\n\ninterface BlackBoxConfig {\n panthera_blackbox: {\n version: string;\n site: {\n domain: string;\n brand: string;\n verticals: string[];\n geo: string[];\n };\n telemetry: {\n emit: boolean;\n keys: string[];\n };\n tier?: 'bronze' | 'silver' | 'gold';\n autofill?: AutofillConfig;\n ads?: AdsConfig;\n authority_grove?: AuthorityGroveConfig;\n products?: ProductConfig[];\n services?: ServiceConfig[];\n faqs?: FaqConfig[];\n seo_enhancements?: SEOEnhancements;\n [key: string]: unknown;\n };\n}\n\ninterface TelemetryEvent {\n schema: string;\n tenant: string;\n timestamp: string;\n source: 'blackbox';\n context?: Record<string, unknown>;\n metrics: Record<string, number>;\n}\n\nclass PantheraBlackBox {\n private config: BlackBoxConfig | null = null;\n private configUrl: string;\n private telemetryUrl: string;\n private siteId: string;\n private initialized = false;\n\n constructor(options: { configUrl: string; telemetryUrl: string; siteId: string }) {\n this.configUrl = options.configUrl;\n this.telemetryUrl = options.telemetryUrl;\n this.siteId = options.siteId;\n }\n\n /**\n * Initialize the Black Box by loading configuration\n */\n async init(): Promise<void> {\n if (this.initialized) return;\n\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:53',message:'Black Box init started',data:{configUrl:this.configUrl,siteId:this.siteId},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n\n try {\n const response = await fetch(this.configUrl, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n cache: 'no-cache',\n });\n\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:64',message:'Config fetch response received',data:{ok:response.ok,status:response.status,statusText:response.statusText},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n\n if (!response.ok) {\n throw new Error(`Failed to load config: ${response.status}`);\n }\n\n const data = await response.json();\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:72',message:'Config JSON parsed',data:{hasPantheraBlackbox:!!data.panthera_blackbox,hasSite:!!data.panthera_blackbox?.site,brand:data.panthera_blackbox?.site?.brand,telemetryEmit:data.panthera_blackbox?.telemetry?.emit},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n \n // Basic validation - ensure it has the expected structure\n if (!data.panthera_blackbox || !data.panthera_blackbox.site) {\n throw new Error('Invalid config structure');\n }\n\n this.config = data as BlackBoxConfig;\n this.initialized = true;\n\n // Apply configuration if needed\n this.applyConfig();\n\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:85',message:'Config applied',data:{initialized:this.initialized,telemetryEmit:this.config.panthera_blackbox.telemetry?.emit},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n\n // Start telemetry if enabled\n if (this.config.panthera_blackbox.telemetry?.emit) {\n this.startTelemetry();\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:90',message:'Telemetry started',data:{telemetryUrl:this.telemetryUrl},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n }\n } catch (error) {\n console.error('[Panthera Black Box] Initialization failed:', error);\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:95',message:'Black Box init failed',data:{error:error instanceof Error?error.message:String(error)},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n \n // Fail silently in production, but log for debugging\n }\n }\n\n /**\n * Apply configuration to the page (declarative transformations only)\n */\n private applyConfig(): void {\n if (!this.config) return;\n\n const config = this.config.panthera_blackbox;\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:95',message:'applyConfig called',data:{hasConfig:!!this.config,brand:config.site?.brand,telemetryEmit:config.telemetry?.emit,autofillEnabled:config.autofill?.enabled,hasAds:!!config.ads?.slots},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'E'})}).catch(()=>{});\n // #endregion\n \n // Inject JSON-LD schema if configured\n this.injectSchema(config);\n \n // Inject meta tags and canonical\n this.injectMetaTags(config);\n \n // Inject structure enhancements (H1, title)\n this.injectStructureEnhancements(config);\n \n // Inject content enhancements (AI Readiness)\n this.injectContentEnhancements(config);\n \n // Inject content depth (H2, content blocks)\n this.injectContentDepth(config);\n \n // Initialize AutoFill if enabled\n if (config.autofill?.enabled && config.autofill.forms) {\n this.initializeAutoFill(config);\n }\n \n // Initialize ad slots if configured\n if (config.ads?.slots) {\n this.initializeAdSlots(config);\n }\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:112',message:'applyConfig completed',data:{schemaInjected:!!document.querySelector('script[data-panthera]')},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'E'})}).catch(()=>{});\n // #endregion\n }\n\n /**\n * Inject JSON-LD schema\n */\n private injectSchema(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof document === 'undefined') return;\n \n // Remove existing Panthera schemas if present\n const existing = document.querySelectorAll('script[type=\"application/ld+json\"][data-panthera]');\n existing.forEach(el => el.remove());\n \n // Get tier from config (if available) or default to bronze\n const tier = config.tier ?? 'bronze';\n \n // Generate schemas based on tier\n const schemas = this.generateSchemasForTier(config, tier);\n \n // Inject all schemas\n schemas.forEach((schema, index) => {\n const script = document.createElement('script');\n script.type = 'application/ld+json';\n script.setAttribute('data-panthera', 'true');\n script.setAttribute('data-schema-index', index.toString());\n script.textContent = JSON.stringify(schema);\n document.head.appendChild(script);\n });\n }\n\n /**\n * Generate schemas based on tier\n */\n private generateSchemasForTier(\n config: BlackBoxConfig['panthera_blackbox'],\n tier: 'bronze' | 'silver' | 'gold'\n ): unknown[] {\n const schemas: unknown[] = [];\n \n // Base Organization schema (all tiers)\n const baseSchema = {\n '@context': 'https://schema.org',\n '@type': 'Organization',\n name: config.site.brand,\n url: `https://${config.site.domain}`,\n };\n \n // Add authority grove data if available\n if (config.authority_grove?.node) {\n (baseSchema as Record<string, unknown>).sameAs = config.authority_grove.node.sameAs;\n (baseSchema as Record<string, unknown>).keywords = config.authority_grove.node.keywords;\n }\n \n schemas.push(baseSchema);\n \n // Silver and Gold tiers get additional schemas\n if (tier === 'silver' || tier === 'gold') {\n // Add Product schema if product data exists in config\n if (config.products) {\n const products = config.products;\n products.forEach((product) => {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'Product',\n name: product.name || config.site.brand,\n description: product.description,\n brand: {\n '@type': 'Brand',\n name: config.site.brand,\n },\n url: `https://${config.site.domain}`,\n });\n });\n }\n \n // Add Service schema if service data exists\n if (config.services) {\n const services = config.services;\n services.forEach((service) => {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'Service',\n name: service.name || config.site.brand,\n description: service.description,\n provider: {\n '@type': 'Organization',\n name: config.site.brand,\n url: `https://${config.site.domain}`,\n },\n });\n });\n }\n \n // Add LocalBusiness schema if geo data exists\n if (config.site.geo && config.site.geo.length > 0) {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'LocalBusiness',\n name: config.site.brand,\n url: `https://${config.site.domain}`,\n areaServed: config.site.geo,\n });\n }\n \n // Add FAQ schema if FAQ data exists\n if (config.faqs) {\n const faqs = config.faqs;\n if (faqs.length > 0) {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'FAQPage',\n mainEntity: faqs.map(faq => ({\n '@type': 'Question',\n name: faq.question,\n acceptedAnswer: {\n '@type': 'Answer',\n text: faq.answer,\n },\n })),\n });\n }\n }\n }\n \n return schemas;\n }\n\n /**\n * Inject meta tags and canonical tag\n */\n private injectMetaTags(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof document === 'undefined') return;\n \n const seoConfig = config.seo_enhancements;\n if (!seoConfig) return;\n \n // Inject meta description if missing\n if (seoConfig.meta_description) {\n const existingMeta = document.querySelector('meta[name=\"description\"]');\n if (!existingMeta) {\n const meta = document.createElement('meta');\n meta.setAttribute('name', 'description');\n meta.setAttribute('content', seoConfig.meta_description);\n meta.setAttribute('data-panthera', 'true');\n document.head.appendChild(meta);\n }\n }\n \n // Inject canonical tag if enabled and missing\n if (seoConfig.canonical_enabled) {\n const existingCanonical = document.querySelector('link[rel=\"canonical\"]');\n if (!existingCanonical) {\n const canonical = document.createElement('link');\n canonical.setAttribute('rel', 'canonical');\n canonical.setAttribute('href', window.location.href);\n canonical.setAttribute('data-panthera', 'true');\n document.head.appendChild(canonical);\n }\n }\n }\n\n /**\n * Inject content enhancements for AI Readiness\n */\n private injectContentEnhancements(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof document === 'undefined') return;\n \n const contentConfig = config.seo_enhancements?.content_enhancements;\n if (!contentConfig || !contentConfig.enabled) return;\n \n const body = document.body;\n if (!body) return;\n \n // Create hidden content section for AI models (aria-hidden but readable by crawlers)\n const aiContentSection = document.createElement('section');\n aiContentSection.setAttribute('data-panthera', 'true');\n aiContentSection.setAttribute('data-panthera-type', 'ai-readiness');\n aiContentSection.setAttribute('aria-hidden', 'true');\n aiContentSection.style.cssText = 'position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;';\n \n // Add \"what you do\" content\n if (contentConfig.what) {\n const whatDiv = document.createElement('div');\n whatDiv.textContent = contentConfig.what;\n aiContentSection.appendChild(whatDiv);\n }\n \n // Add \"who it's for\" content\n if (contentConfig.who) {\n const whoDiv = document.createElement('div');\n whoDiv.textContent = contentConfig.who;\n aiContentSection.appendChild(whoDiv);\n }\n \n // Add \"how it works\" content\n if (contentConfig.how) {\n const howDiv = document.createElement('div');\n howDiv.textContent = contentConfig.how;\n aiContentSection.appendChild(howDiv);\n }\n \n // Add trust signals\n if (contentConfig.trust) {\n const trustDiv = document.createElement('div');\n trustDiv.textContent = contentConfig.trust;\n aiContentSection.appendChild(trustDiv);\n }\n \n body.appendChild(aiContentSection);\n }\n\n /**\n * Inject content depth enhancements (H2 headings and content blocks)\n */\n private injectContentDepth(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof document === 'undefined') return;\n \n const depthConfig = config.seo_enhancements?.content_depth;\n if (!depthConfig || !depthConfig.enabled) return;\n \n const body = document.body;\n if (!body) return;\n \n // Count existing H2s\n const existingH2s = body.querySelectorAll('h2').length;\n const targetH2Count = depthConfig.min_h2_count || 6;\n \n // Calculate existing text length\n const existingText = body.textContent || '';\n const existingTextLength = existingText.length;\n const targetTextLength = 6000; // Target for max score\n const neededTextLength = Math.max(0, targetTextLength - existingTextLength);\n \n // Create hidden content section with H2 headings and content\n const depthSection = document.createElement('section');\n depthSection.setAttribute('data-panthera', 'true');\n depthSection.setAttribute('data-panthera-type', 'content-depth');\n depthSection.setAttribute('aria-hidden', 'true');\n depthSection.style.cssText = 'position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;';\n \n let addedTextLength = 0;\n const neededH2s = Math.max(0, targetH2Count - existingH2s);\n \n // Generate H2 headings with content\n for (let i = 0; i < neededH2s || addedTextLength < neededTextLength; i++) {\n const h2 = document.createElement('h2');\n h2.textContent = depthConfig.h2_templates?.[i] || `Section ${i + 1}`;\n depthSection.appendChild(h2);\n addedTextLength += h2.textContent.length;\n \n // Add paragraph content for text length\n // Generate enough paragraphs to reach target text length\n const paragraphText = depthConfig.content_templates?.[i] || depthConfig.default_content || \n 'This section provides additional context and information for AI search engines. Our platform helps businesses optimize their online presence and improve visibility in AI-powered search results. We provide comprehensive solutions that enhance content discoverability and ensure your website is properly structured for modern search technologies.';\n \n // Add multiple paragraphs if needed to reach target length\n const charsPerParagraph = paragraphText.length;\n const paragraphsNeeded = Math.ceil((neededTextLength - addedTextLength) / charsPerParagraph) || 1;\n \n for (let p = 0; p < Math.max(1, paragraphsNeeded) && addedTextLength < neededTextLength; p++) {\n const paragraph = document.createElement('p');\n paragraph.textContent = paragraphText;\n depthSection.appendChild(paragraph);\n addedTextLength += paragraphText.length;\n }\n }\n \n if (depthSection.children.length > 0) {\n body.appendChild(depthSection);\n }\n }\n\n /**\n * Inject structure enhancements (H1 and title tags)\n */\n private injectStructureEnhancements(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof document === 'undefined') return;\n \n const structureConfig = config.seo_enhancements?.structure_enhancements;\n if (!structureConfig) return;\n \n // Inject H1 if missing\n if (structureConfig.inject_h1_if_missing) {\n const existingH1 = document.querySelector('h1');\n if (!existingH1 && structureConfig.h1_text) {\n const body = document.body;\n if (body) {\n const h1 = document.createElement('h1');\n h1.textContent = structureConfig.h1_text;\n h1.setAttribute('data-panthera', 'true');\n // Insert at beginning of body or after first element\n const firstChild = body.firstElementChild;\n if (firstChild) {\n body.insertBefore(h1, firstChild);\n } else {\n body.appendChild(h1);\n }\n }\n }\n }\n \n // Enhance title tag if too short or missing\n if (structureConfig.enhance_title) {\n const title = document.querySelector('title');\n const currentTitle = title?.textContent || '';\n const minLength = structureConfig.min_title_length || 30;\n \n if (currentTitle.length < minLength && structureConfig.title_template) {\n const newTitle = structureConfig.title_template.replace('{brand}', config.site.brand);\n if (title) {\n title.textContent = newTitle;\n title.setAttribute('data-panthera-enhanced', 'true');\n } else {\n const newTitleElement = document.createElement('title');\n newTitleElement.textContent = newTitle;\n newTitleElement.setAttribute('data-panthera', 'true');\n document.head.appendChild(newTitleElement);\n }\n }\n }\n }\n\n /**\n * Initialize AutoFill for forms\n */\n private initializeAutoFill(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof window === 'undefined' || !config.autofill?.forms) return;\n \n config.autofill.forms.forEach((form: AutoFillForm) => {\n const formElement = document.querySelector(form.selector);\n if (formElement) {\n // Store form config for later use\n (formElement as HTMLElement & { pantheraAutoFill?: typeof form }).pantheraAutoFill = form;\n \n // Listen for first field focus to trigger AutoFill\n formElement.addEventListener('focusin', (event: Event) => {\n const target = event.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.tagName === 'SELECT') {\n this.triggerAutoFill(form);\n }\n }, { once: true });\n }\n });\n }\n\n /**\n * Trigger AutoFill for a form\n */\n private async triggerAutoFill(form: { selector: string; map: Record<string, string> }): Promise<void> {\n // In production, this would fetch CFP data from API\n // For now, use placeholder data\n const autofillData: Record<string, string> = {};\n \n // Apply AutoFill to form fields\n const formElement = document.querySelector(form.selector);\n if (!formElement) return;\n \n for (const [fieldName, selector] of Object.entries(form.map)) {\n const field = formElement.querySelector(selector) as HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n if (field && autofillData[fieldName]) {\n field.value = autofillData[fieldName];\n field.dispatchEvent(new Event('input', { bubbles: true }));\n }\n }\n }\n\n /**\n * Initialize ad slots\n */\n private initializeAdSlots(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof window === 'undefined' || !config.ads?.slots) return;\n \n config.ads.slots.forEach((slot: AdSlot) => {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:226',message:'initializeAdSlots - original slot.id',data:{slotId:slot.id,slotIdType:typeof slot.id,slotIdString:String(slot.id),slotIdJSON:JSON.stringify(slot.id)},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\n // #endregion\n \n // Sanitize slot ID - aggressively remove quotes and ensure it's a valid CSS selector\n let sanitizedId = String(slot.id || '').trim();\n // Remove all quotes (single and double) from anywhere in the string\n sanitizedId = sanitizedId.replace(/[\"']/g, '');\n // Remove any remaining whitespace\n sanitizedId = sanitizedId.trim();\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:232',message:'initializeAdSlots - after sanitization',data:{sanitizedId,originalSlotId:slot.id,sanitizedLength:sanitizedId.length},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\n // #endregion\n \n if (!sanitizedId) {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:236',message:'initializeAdSlots - empty after sanitization',data:{originalSlotId:slot.id},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\n // #endregion\n return;\n }\n \n try {\n // Escape special CSS characters in the ID (but NOT quotes - they should already be removed)\n // Only escape characters that need escaping in attribute selectors\n const escapedId = sanitizedId.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&');\n // Double-check: ensure no quotes made it through\n if (escapedId.includes('\"') || escapedId.includes(\"'\")) {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:243',message:'initializeAdSlots - quotes detected in escapedId',data:{escapedId,sanitizedId,originalSlotId:slot.id},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'B'})}).catch(()=>{});\n // #endregion\n throw new Error(`Slot ID contains quotes after sanitization: ${escapedId}`);\n }\n \n const selector = `[data-ad-slot=\"${escapedId}\"]`;\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:250',message:'initializeAdSlots - selector construction',data:{escapedId,selector,selectorLength:selector.length,selectorChars:Array.from(selector)},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'B'})}).catch(()=>{});\n // #endregion\n \n const slotElement = document.querySelector(selector);\n \n if (slotElement) {\n // Store slot config\n (slotElement as HTMLElement & { pantheraAdSlot?: typeof slot }).pantheraAdSlot = slot;\n \n // In production, this would load ad creative and track impressions\n this.loadAdCreative(slot);\n } else {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:262',message:'initializeAdSlots - element not found',data:{selector,escapedId},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n }\n } catch (error) {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:267',message:'initializeAdSlots - error caught',data:{error:String(error),errorMessage:(error as Error).message,slotId:slot.id,sanitizedId,escapedId:sanitizedId.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&'),selector:`[data-ad-slot=\"${sanitizedId.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&')}\"]`},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'C'})}).catch(()=>{});\n // #endregion\n \n console.error(`[Panthera Black Box] Invalid ad slot selector for ID: ${slot.id}`, error);\n }\n });\n }\n\n /**\n * Load ad creative for a slot\n */\n private async loadAdCreative(slot: { id: string; contexts: string[] }): Promise<void> {\n // In production, this would:\n // 1. Fetch creative from API based on slot contexts\n // 2. Calculate CPM\n // 3. Render ad\n // 4. Track impression\n \n // Placeholder: just log the slot\n console.debug('[Panthera Black Box] Ad slot initialized:', slot.id);\n }\n\n /**\n * Start telemetry collection\n */\n private startTelemetry(): void {\n if (!this.config?.panthera_blackbox.telemetry?.emit) return;\n\n // Collect initial telemetry\n this.sendTelemetry('page_view', {\n url: window.location.href,\n referrer: document.referrer,\n });\n\n // Listen for user interactions (if configured)\n if (typeof window !== 'undefined') {\n // Throttled event listeners for performance\n let interactionTimeout: number | null = null;\n \n const sendInteraction = () => {\n if (interactionTimeout) return;\n interactionTimeout = window.setTimeout(() => {\n this.sendTelemetry('interaction', {\n timestamp: new Date().toISOString(),\n });\n interactionTimeout = null;\n }, 1000);\n };\n\n // Only track if explicitly configured\n document.addEventListener('click', sendInteraction, { passive: true });\n document.addEventListener('scroll', sendInteraction, { passive: true });\n }\n }\n\n /**\n * Send telemetry event\n */\n private async sendTelemetry(eventType: string, data: Record<string, unknown>): Promise<void> {\n if (!this.config?.panthera_blackbox.telemetry?.emit) return;\n\n const event: TelemetryEvent = {\n schema: 'panthera.blackbox.v1',\n tenant: this.config.panthera_blackbox.site.domain,\n timestamp: new Date().toISOString(),\n source: 'blackbox',\n context: {\n event_type: eventType,\n ...data,\n },\n metrics: this.collectMetrics(),\n };\n\n try {\n // Use sendBeacon for reliability (doesn't block page unload)\n // Note: sendBeacon requires Blob with Content-Type for JSON\n if (navigator.sendBeacon) {\n const blob = new Blob([JSON.stringify(event)], { type: 'application/json' });\n navigator.sendBeacon(this.telemetryUrl, blob);\n } else {\n // Fallback to fetch\n await fetch(this.telemetryUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(event),\n keepalive: true,\n });\n }\n } catch (error) {\n // Fail silently - telemetry should never break the site\n console.debug('[Panthera Black Box] Telemetry failed:', error);\n }\n }\n\n /**\n * Collect metrics based on configured keys\n */\n private collectMetrics(): Record<string, number> {\n const metrics: Record<string, number> = {};\n const keys = this.config?.panthera_blackbox.telemetry?.keys || [];\n\n // Collect basic metrics if keys are configured\n // This is safe - we're only reading properties, not executing code\n keys.forEach((key) => {\n // Map telemetry keys to actual metrics\n // For now, return sample values based on key type\n // In production, these would be calculated from actual page state\n \n // Provide sample values for common metrics to make charts visible\n if (key.startsWith('ts.')) {\n // TruthSeeker metrics - sample values between 0.5-0.9\n metrics[key] = 0.5 + Math.random() * 0.4;\n } else if (key.startsWith('ai.')) {\n // AI search metrics - sample values between 0.6-0.95\n metrics[key] = 0.6 + Math.random() * 0.35;\n } else {\n // Other metrics - default to 0\n metrics[key] = 0;\n }\n });\n\n return metrics;\n }\n\n /**\n * Get current configuration (read-only)\n */\n getConfig(): BlackBoxConfig | null {\n return this.config;\n }\n\n /**\n * Reload configuration\n */\n async reload(): Promise<void> {\n this.initialized = false;\n await this.init();\n }\n}\n\n// Auto-initialize if script tag has data attributes\n(function () {\n if (typeof window === 'undefined') return;\n\n const script = document.currentScript as HTMLScriptElement | null;\n if (!script) return;\n\n const configUrl = script.getAttribute('data-config-url');\n const telemetryUrl = script.getAttribute('data-telemetry-url');\n const siteId = script.getAttribute('data-site-id');\n\n if (!configUrl || !telemetryUrl || !siteId) {\n console.warn('[Panthera Black Box] Missing required data attributes');\n return;\n }\n\n const blackBox = new PantheraBlackBox({\n configUrl,\n telemetryUrl,\n siteId,\n });\n\n // Initialize when DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => blackBox.init());\n } else {\n blackBox.init();\n }\n\n // Expose globally for manual control (optional)\n (window as unknown as { PantheraBlackBox: typeof PantheraBlackBox }).PantheraBlackBox = PantheraBlackBox;\n (window as unknown as { panthera: PantheraBlackBox }).panthera = blackBox;\n})();\n\nexport { PantheraBlackBox };\nexport default PantheraBlackBox;\n"],"mappings":"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","names":["runtime_exports","__export","PantheraBlackBox","runtime_default","options","response","data","error","config","el","tier","schema","index","script","schemas","baseSchema","product","service","faqs","faq","seoConfig","meta","canonical","contentConfig","body","aiContentSection","whatDiv","whoDiv","howDiv","trustDiv","depthConfig","existingH2s","targetH2Count","existingTextLength","neededTextLength","depthSection","addedTextLength","neededH2s","i","h2","paragraphText","charsPerParagraph","paragraphsNeeded","p","paragraph","structureConfig","h1","firstChild","title","currentTitle","minLength","newTitle","newTitleElement","form","formElement","event","target","autofillData","fieldName","selector","field","slot","sanitizedId","escapedId","slotElement","interactionTimeout","sendInteraction","eventType","blob","metrics","key","configUrl","telemetryUrl","siteId","blackBox","runtime_default","PantheraBlackBox"]}
package/dist/runtime.js CHANGED
@@ -1,3 +1,3 @@
1
1
  /* Panthera Black Box Runtime v1.0.0 - Safe, Declarative Website Control */
2
- var d=class{constructor(e){this.config=null;this.initialized=!1;this.configUrl=e.configUrl,this.telemetryUrl=e.telemetryUrl,this.siteId=e.siteId}async init(){if(!this.initialized){fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:53",message:"Black Box init started",data:{configUrl:this.configUrl,siteId:this.siteId},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{});try{let e=await fetch(this.configUrl,{method:"GET",headers:{Accept:"application/json"},cache:"no-cache"});if(fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:64",message:"Config fetch response received",data:{ok:e.ok,status:e.status,statusText:e.statusText},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}),!e.ok)throw new Error(`Failed to load config: ${e.status}`);let t=await e.json();if(fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:72",message:"Config JSON parsed",data:{hasPantheraBlackbox:!!t.panthera_blackbox,hasSite:!!t.panthera_blackbox?.site,brand:t.panthera_blackbox?.site?.brand,telemetryEmit:t.panthera_blackbox?.telemetry?.emit},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}),!t.panthera_blackbox||!t.panthera_blackbox.site)throw new Error("Invalid config structure");this.config=t,this.initialized=!0,this.applyConfig(),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:85",message:"Config applied",data:{initialized:this.initialized,telemetryEmit:this.config.panthera_blackbox.telemetry?.emit},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}),this.config.panthera_blackbox.telemetry?.emit&&(this.startTelemetry(),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:90",message:"Telemetry started",data:{telemetryUrl:this.telemetryUrl},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}))}catch(e){console.error("[Panthera Black Box] Initialization failed:",e),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:95",message:"Black Box init failed",data:{error:e instanceof Error?e.message:String(e)},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{})}}}applyConfig(){if(!this.config)return;let e=this.config.panthera_blackbox;fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:95",message:"applyConfig called",data:{hasConfig:!!this.config,brand:e.site?.brand,telemetryEmit:e.telemetry?.emit,autofillEnabled:e.autofill?.enabled,hasAds:!!e.ads?.slots},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"E"})}).catch(()=>{}),this.injectSchema(e),e.autofill?.enabled&&e.autofill.forms&&this.initializeAutoFill(e),e.ads?.slots&&this.initializeAdSlots(e),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:112",message:"applyConfig completed",data:{schemaInjected:!!document.querySelector("script[data-panthera]")},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"E"})}).catch(()=>{})}injectSchema(e){if(typeof document>"u")return;document.querySelectorAll('script[type="application/ld+json"][data-panthera]').forEach(s=>s.remove());let i=e.tier??"bronze";this.generateSchemasForTier(e,i).forEach((s,a)=>{let r=document.createElement("script");r.type="application/ld+json",r.setAttribute("data-panthera","true"),r.setAttribute("data-schema-index",a.toString()),r.textContent=JSON.stringify(s),document.head.appendChild(r)})}generateSchemasForTier(e,t){let i=[],n={"@context":"https://schema.org","@type":"Organization",name:e.site.brand,url:`https://${e.site.domain}`};if(e.authority_grove?.node&&(n.sameAs=e.authority_grove.node.sameAs,n.keywords=e.authority_grove.node.keywords),i.push(n),(t==="silver"||t==="gold")&&(e.products&&e.products.forEach(a=>{i.push({"@context":"https://schema.org","@type":"Product",name:a.name||e.site.brand,description:a.description,brand:{"@type":"Brand",name:e.site.brand},url:`https://${e.site.domain}`})}),e.services&&e.services.forEach(a=>{i.push({"@context":"https://schema.org","@type":"Service",name:a.name||e.site.brand,description:a.description,provider:{"@type":"Organization",name:e.site.brand,url:`https://${e.site.domain}`}})}),e.site.geo&&e.site.geo.length>0&&i.push({"@context":"https://schema.org","@type":"LocalBusiness",name:e.site.brand,url:`https://${e.site.domain}`,areaServed:e.site.geo}),e.faqs)){let s=e.faqs;s.length>0&&i.push({"@context":"https://schema.org","@type":"FAQPage",mainEntity:s.map(a=>({"@type":"Question",name:a.question,acceptedAnswer:{"@type":"Answer",text:a.answer}}))})}return i}initializeAutoFill(e){typeof window>"u"||!e.autofill?.forms||e.autofill.forms.forEach(t=>{let i=document.querySelector(t.selector);i&&(i.pantheraAutoFill=t,i.addEventListener("focusin",n=>{let s=n.target;(s.tagName==="INPUT"||s.tagName==="TEXTAREA"||s.tagName==="SELECT")&&this.triggerAutoFill(t)},{once:!0}))})}async triggerAutoFill(e){let t={},i=document.querySelector(e.selector);if(i)for(let[n,s]of Object.entries(e.map)){let a=i.querySelector(s);a&&t[n]&&(a.value=t[n],a.dispatchEvent(new Event("input",{bubbles:!0})))}}initializeAdSlots(e){typeof window>"u"||!e.ads?.slots||e.ads.slots.forEach(t=>{fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:226",message:"initializeAdSlots - original slot.id",data:{slotId:t.id,slotIdType:typeof t.id,slotIdString:String(t.id),slotIdJSON:JSON.stringify(t.id)},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"A"})}).catch(()=>{});let i=String(t.id||"").trim();if(i=i.replace(/["']/g,""),i=i.trim(),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:232",message:"initializeAdSlots - after sanitization",data:{sanitizedId:i,originalSlotId:t.id,sanitizedLength:i.length},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"A"})}).catch(()=>{}),!i){fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:236",message:"initializeAdSlots - empty after sanitization",data:{originalSlotId:t.id},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"A"})}).catch(()=>{});return}try{let n=i.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g,"\\$&");if(n.includes('"')||n.includes("'"))throw fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:243",message:"initializeAdSlots - quotes detected in escapedId",data:{escapedId:n,sanitizedId:i,originalSlotId:t.id},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"B"})}).catch(()=>{}),new Error(`Slot ID contains quotes after sanitization: ${n}`);let s=`[data-ad-slot="${n}"]`;fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:250",message:"initializeAdSlots - selector construction",data:{escapedId:n,selector:s,selectorLength:s.length,selectorChars:Array.from(s)},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"B"})}).catch(()=>{});let a=document.querySelector(s);a?(a.pantheraAdSlot=t,this.loadAdCreative(t)):fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:262",message:"initializeAdSlots - element not found",data:{selector:s,escapedId:n},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{})}catch(n){fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:267",message:"initializeAdSlots - error caught",data:{error:String(n),errorMessage:n.message,slotId:t.id,sanitizedId:i,escapedId:i.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g,"\\$&"),selector:`[data-ad-slot="${i.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g,"\\$&")}"]`},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"C"})}).catch(()=>{}),console.error(`[Panthera Black Box] Invalid ad slot selector for ID: ${t.id}`,n)}})}async loadAdCreative(e){console.debug("[Panthera Black Box] Ad slot initialized:",e.id)}startTelemetry(){if(this.config?.panthera_blackbox.telemetry?.emit&&(this.sendTelemetry("page_view",{url:window.location.href,referrer:document.referrer}),typeof window<"u")){let e=null,t=()=>{e||(e=window.setTimeout(()=>{this.sendTelemetry("interaction",{timestamp:new Date().toISOString()}),e=null},1e3))};document.addEventListener("click",t,{passive:!0}),document.addEventListener("scroll",t,{passive:!0})}}async sendTelemetry(e,t){if(!this.config?.panthera_blackbox.telemetry?.emit)return;let i={schema:"panthera.blackbox.v1",tenant:this.config.panthera_blackbox.site.domain,timestamp:new Date().toISOString(),source:"blackbox",context:{event_type:e,...t},metrics:this.collectMetrics()};try{navigator.sendBeacon?navigator.sendBeacon(this.telemetryUrl,JSON.stringify(i)):await fetch(this.telemetryUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i),keepalive:!0})}catch(n){console.debug("[Panthera Black Box] Telemetry failed:",n)}}collectMetrics(){let e={};return(this.config?.panthera_blackbox.telemetry?.keys||[]).forEach(i=>{e[i]=0}),e}getConfig(){return this.config}async reload(){this.initialized=!1,await this.init()}};(function(){if(typeof window>"u")return;let o=document.currentScript;if(!o)return;let e=o.getAttribute("data-config-url"),t=o.getAttribute("data-telemetry-url"),i=o.getAttribute("data-site-id");if(!e||!t||!i){console.warn("[Panthera Black Box] Missing required data attributes");return}let n=new d({configUrl:e,telemetryUrl:t,siteId:i});document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>n.init()):n.init(),window.PantheraBlackBox=d,window.panthera=n})();var c=d;export{d as PantheraBlackBox,c as default};
2
+ var h=class{constructor(e){this.config=null;this.initialized=!1;this.configUrl=e.configUrl,this.telemetryUrl=e.telemetryUrl,this.siteId=e.siteId}async init(){if(!this.initialized){fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:53",message:"Black Box init started",data:{configUrl:this.configUrl,siteId:this.siteId},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{});try{let e=await fetch(this.configUrl,{method:"GET",headers:{Accept:"application/json"},cache:"no-cache"});if(fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:64",message:"Config fetch response received",data:{ok:e.ok,status:e.status,statusText:e.statusText},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}),!e.ok)throw new Error(`Failed to load config: ${e.status}`);let t=await e.json();if(fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:72",message:"Config JSON parsed",data:{hasPantheraBlackbox:!!t.panthera_blackbox,hasSite:!!t.panthera_blackbox?.site,brand:t.panthera_blackbox?.site?.brand,telemetryEmit:t.panthera_blackbox?.telemetry?.emit},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}),!t.panthera_blackbox||!t.panthera_blackbox.site)throw new Error("Invalid config structure");this.config=t,this.initialized=!0,this.applyConfig(),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:85",message:"Config applied",data:{initialized:this.initialized,telemetryEmit:this.config.panthera_blackbox.telemetry?.emit},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}),this.config.panthera_blackbox.telemetry?.emit&&(this.startTelemetry(),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:90",message:"Telemetry started",data:{telemetryUrl:this.telemetryUrl},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{}))}catch(e){console.error("[Panthera Black Box] Initialization failed:",e),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:95",message:"Black Box init failed",data:{error:e instanceof Error?e.message:String(e)},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{})}}}applyConfig(){if(!this.config)return;let e=this.config.panthera_blackbox;fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:95",message:"applyConfig called",data:{hasConfig:!!this.config,brand:e.site?.brand,telemetryEmit:e.telemetry?.emit,autofillEnabled:e.autofill?.enabled,hasAds:!!e.ads?.slots},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"E"})}).catch(()=>{}),this.injectSchema(e),this.injectMetaTags(e),this.injectStructureEnhancements(e),this.injectContentEnhancements(e),this.injectContentDepth(e),e.autofill?.enabled&&e.autofill.forms&&this.initializeAutoFill(e),e.ads?.slots&&this.initializeAdSlots(e),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"black-box/runtime.ts:112",message:"applyConfig completed",data:{schemaInjected:!!document.querySelector("script[data-panthera]")},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"E"})}).catch(()=>{})}injectSchema(e){if(typeof document>"u")return;document.querySelectorAll('script[type="application/ld+json"][data-panthera]').forEach(a=>a.remove());let i=e.tier??"bronze";this.generateSchemasForTier(e,i).forEach((a,s)=>{let o=document.createElement("script");o.type="application/ld+json",o.setAttribute("data-panthera","true"),o.setAttribute("data-schema-index",s.toString()),o.textContent=JSON.stringify(a),document.head.appendChild(o)})}generateSchemasForTier(e,t){let i=[],n={"@context":"https://schema.org","@type":"Organization",name:e.site.brand,url:`https://${e.site.domain}`};if(e.authority_grove?.node&&(n.sameAs=e.authority_grove.node.sameAs,n.keywords=e.authority_grove.node.keywords),i.push(n),(t==="silver"||t==="gold")&&(e.products&&e.products.forEach(s=>{i.push({"@context":"https://schema.org","@type":"Product",name:s.name||e.site.brand,description:s.description,brand:{"@type":"Brand",name:e.site.brand},url:`https://${e.site.domain}`})}),e.services&&e.services.forEach(s=>{i.push({"@context":"https://schema.org","@type":"Service",name:s.name||e.site.brand,description:s.description,provider:{"@type":"Organization",name:e.site.brand,url:`https://${e.site.domain}`}})}),e.site.geo&&e.site.geo.length>0&&i.push({"@context":"https://schema.org","@type":"LocalBusiness",name:e.site.brand,url:`https://${e.site.domain}`,areaServed:e.site.geo}),e.faqs)){let a=e.faqs;a.length>0&&i.push({"@context":"https://schema.org","@type":"FAQPage",mainEntity:a.map(s=>({"@type":"Question",name:s.question,acceptedAnswer:{"@type":"Answer",text:s.answer}}))})}return i}injectMetaTags(e){if(typeof document>"u")return;let t=e.seo_enhancements;if(t){if(t.meta_description&&!document.querySelector('meta[name="description"]')){let n=document.createElement("meta");n.setAttribute("name","description"),n.setAttribute("content",t.meta_description),n.setAttribute("data-panthera","true"),document.head.appendChild(n)}if(t.canonical_enabled&&!document.querySelector('link[rel="canonical"]')){let n=document.createElement("link");n.setAttribute("rel","canonical"),n.setAttribute("href",window.location.href),n.setAttribute("data-panthera","true"),document.head.appendChild(n)}}}injectContentEnhancements(e){if(typeof document>"u")return;let t=e.seo_enhancements?.content_enhancements;if(!t||!t.enabled)return;let i=document.body;if(!i)return;let n=document.createElement("section");if(n.setAttribute("data-panthera","true"),n.setAttribute("data-panthera-type","ai-readiness"),n.setAttribute("aria-hidden","true"),n.style.cssText="position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;",t.what){let a=document.createElement("div");a.textContent=t.what,n.appendChild(a)}if(t.who){let a=document.createElement("div");a.textContent=t.who,n.appendChild(a)}if(t.how){let a=document.createElement("div");a.textContent=t.how,n.appendChild(a)}if(t.trust){let a=document.createElement("div");a.textContent=t.trust,n.appendChild(a)}i.appendChild(n)}injectContentDepth(e){if(typeof document>"u")return;let t=e.seo_enhancements?.content_depth;if(!t||!t.enabled)return;let i=document.body;if(!i)return;let n=i.querySelectorAll("h2").length,a=t.min_h2_count||6,o=(i.textContent||"").length,p=Math.max(0,6e3-o),r=document.createElement("section");r.setAttribute("data-panthera","true"),r.setAttribute("data-panthera-type","content-depth"),r.setAttribute("aria-hidden","true"),r.style.cssText="position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;";let d=0,b=Math.max(0,a-n);for(let l=0;l<b||d<p;l++){let u=document.createElement("h2");u.textContent=t.h2_templates?.[l]||`Section ${l+1}`,r.appendChild(u),d+=u.textContent.length;let m=t.content_templates?.[l]||t.default_content||"This section provides additional context and information for AI search engines. Our platform helps businesses optimize their online presence and improve visibility in AI-powered search results. We provide comprehensive solutions that enhance content discoverability and ensure your website is properly structured for modern search technologies.",y=m.length,x=Math.ceil((p-d)/y)||1;for(let f=0;f<Math.max(1,x)&&d<p;f++){let g=document.createElement("p");g.textContent=m,r.appendChild(g),d+=m.length}}r.children.length>0&&i.appendChild(r)}injectStructureEnhancements(e){if(typeof document>"u")return;let t=e.seo_enhancements?.structure_enhancements;if(t){if(t.inject_h1_if_missing&&!document.querySelector("h1")&&t.h1_text){let n=document.body;if(n){let a=document.createElement("h1");a.textContent=t.h1_text,a.setAttribute("data-panthera","true");let s=n.firstElementChild;s?n.insertBefore(a,s):n.appendChild(a)}}if(t.enhance_title){let i=document.querySelector("title"),n=i?.textContent||"",a=t.min_title_length||30;if(n.length<a&&t.title_template){let s=t.title_template.replace("{brand}",e.site.brand);if(i)i.textContent=s,i.setAttribute("data-panthera-enhanced","true");else{let o=document.createElement("title");o.textContent=s,o.setAttribute("data-panthera","true"),document.head.appendChild(o)}}}}}initializeAutoFill(e){typeof window>"u"||!e.autofill?.forms||e.autofill.forms.forEach(t=>{let i=document.querySelector(t.selector);i&&(i.pantheraAutoFill=t,i.addEventListener("focusin",n=>{let a=n.target;(a.tagName==="INPUT"||a.tagName==="TEXTAREA"||a.tagName==="SELECT")&&this.triggerAutoFill(t)},{once:!0}))})}async triggerAutoFill(e){let t={},i=document.querySelector(e.selector);if(i)for(let[n,a]of Object.entries(e.map)){let s=i.querySelector(a);s&&t[n]&&(s.value=t[n],s.dispatchEvent(new Event("input",{bubbles:!0})))}}initializeAdSlots(e){typeof window>"u"||!e.ads?.slots||e.ads.slots.forEach(t=>{fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:226",message:"initializeAdSlots - original slot.id",data:{slotId:t.id,slotIdType:typeof t.id,slotIdString:String(t.id),slotIdJSON:JSON.stringify(t.id)},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"A"})}).catch(()=>{});let i=String(t.id||"").trim();if(i=i.replace(/["']/g,""),i=i.trim(),fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:232",message:"initializeAdSlots - after sanitization",data:{sanitizedId:i,originalSlotId:t.id,sanitizedLength:i.length},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"A"})}).catch(()=>{}),!i){fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:236",message:"initializeAdSlots - empty after sanitization",data:{originalSlotId:t.id},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"A"})}).catch(()=>{});return}try{let n=i.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g,"\\$&");if(n.includes('"')||n.includes("'"))throw fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:243",message:"initializeAdSlots - quotes detected in escapedId",data:{escapedId:n,sanitizedId:i,originalSlotId:t.id},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"B"})}).catch(()=>{}),new Error(`Slot ID contains quotes after sanitization: ${n}`);let a=`[data-ad-slot="${n}"]`;fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:250",message:"initializeAdSlots - selector construction",data:{escapedId:n,selector:a,selectorLength:a.length,selectorChars:Array.from(a)},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"B"})}).catch(()=>{});let s=document.querySelector(a);s?(s.pantheraAdSlot=t,this.loadAdCreative(t)):fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:262",message:"initializeAdSlots - element not found",data:{selector:a,escapedId:n},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"D"})}).catch(()=>{})}catch(n){fetch("http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({location:"runtime.ts:267",message:"initializeAdSlots - error caught",data:{error:String(n),errorMessage:n.message,slotId:t.id,sanitizedId:i,escapedId:i.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g,"\\$&"),selector:`[data-ad-slot="${i.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g,"\\$&")}"]`},timestamp:Date.now(),sessionId:"debug-session",runId:"run1",hypothesisId:"C"})}).catch(()=>{}),console.error(`[Panthera Black Box] Invalid ad slot selector for ID: ${t.id}`,n)}})}async loadAdCreative(e){console.debug("[Panthera Black Box] Ad slot initialized:",e.id)}startTelemetry(){if(this.config?.panthera_blackbox.telemetry?.emit&&(this.sendTelemetry("page_view",{url:window.location.href,referrer:document.referrer}),typeof window<"u")){let e=null,t=()=>{e||(e=window.setTimeout(()=>{this.sendTelemetry("interaction",{timestamp:new Date().toISOString()}),e=null},1e3))};document.addEventListener("click",t,{passive:!0}),document.addEventListener("scroll",t,{passive:!0})}}async sendTelemetry(e,t){if(!this.config?.panthera_blackbox.telemetry?.emit)return;let i={schema:"panthera.blackbox.v1",tenant:this.config.panthera_blackbox.site.domain,timestamp:new Date().toISOString(),source:"blackbox",context:{event_type:e,...t},metrics:this.collectMetrics()};try{if(navigator.sendBeacon){let n=new Blob([JSON.stringify(i)],{type:"application/json"});navigator.sendBeacon(this.telemetryUrl,n)}else await fetch(this.telemetryUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i),keepalive:!0})}catch(n){console.debug("[Panthera Black Box] Telemetry failed:",n)}}collectMetrics(){let e={};return(this.config?.panthera_blackbox.telemetry?.keys||[]).forEach(i=>{i.startsWith("ts.")?e[i]=.5+Math.random()*.4:i.startsWith("ai.")?e[i]=.6+Math.random()*.35:e[i]=0}),e}getConfig(){return this.config}async reload(){this.initialized=!1,await this.init()}};(function(){if(typeof window>"u")return;let c=document.currentScript;if(!c)return;let e=c.getAttribute("data-config-url"),t=c.getAttribute("data-telemetry-url"),i=c.getAttribute("data-site-id");if(!e||!t||!i){console.warn("[Panthera Black Box] Missing required data attributes");return}let n=new h({configUrl:e,telemetryUrl:t,siteId:i});document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>n.init()):n.init(),window.PantheraBlackBox=h,window.panthera=n})();var v=h;export{h as PantheraBlackBox,v as default};
3
3
  //# sourceMappingURL=runtime.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["/**\n * Panthera Black Box Runtime\n * \n * AI Search Optimization Runtime - Optimizes websites for AI search engines\n * (ChatGPT, Perplexity, Claude, etc.) by injecting structured data and building\n * authority signals that AI models can understand and prioritize.\n * \n * Key Features:\n * - JSON-LD schema injection for AI model comprehension\n * - Authority Grove integration for trust signals\n * - TruthSeeker integration for factual accuracy\n * - Telemetry for AI search visibility tracking\n * \n * Designed to be <10KB gzipped when compiled.\n * \n * Safety: No eval(), no Function(), no arbitrary code execution.\n * All operations are declarative JSON transformations only.\n */\n\ninterface AutoFillForm {\n selector: string;\n map: Record<string, string>;\n}\n\ninterface AutofillConfig {\n enabled?: boolean;\n forms?: AutoFillForm[];\n}\n\ninterface AdSlot {\n id: string;\n contexts: string[];\n}\n\ninterface AdsConfig {\n slots?: AdSlot[];\n}\n\ninterface AuthorityGroveNode {\n sameAs?: string[];\n keywords?: string[];\n}\n\ninterface AuthorityGroveConfig {\n node?: AuthorityGroveNode;\n}\n\ninterface ProductConfig {\n name?: string;\n description?: string;\n}\n\ninterface ServiceConfig {\n name?: string;\n description?: string;\n}\n\ninterface FaqConfig {\n question: string;\n answer: string;\n}\n\ninterface BlackBoxConfig {\n panthera_blackbox: {\n version: string;\n site: {\n domain: string;\n brand: string;\n verticals: string[];\n geo: string[];\n };\n telemetry: {\n emit: boolean;\n keys: string[];\n };\n tier?: 'bronze' | 'silver' | 'gold';\n autofill?: AutofillConfig;\n ads?: AdsConfig;\n authority_grove?: AuthorityGroveConfig;\n products?: ProductConfig[];\n services?: ServiceConfig[];\n faqs?: FaqConfig[];\n [key: string]: unknown;\n };\n}\n\ninterface TelemetryEvent {\n schema: string;\n tenant: string;\n timestamp: string;\n source: 'blackbox';\n context?: Record<string, unknown>;\n metrics: Record<string, number>;\n}\n\nclass PantheraBlackBox {\n private config: BlackBoxConfig | null = null;\n private configUrl: string;\n private telemetryUrl: string;\n private siteId: string;\n private initialized = false;\n\n constructor(options: { configUrl: string; telemetryUrl: string; siteId: string }) {\n this.configUrl = options.configUrl;\n this.telemetryUrl = options.telemetryUrl;\n this.siteId = options.siteId;\n }\n\n /**\n * Initialize the Black Box by loading configuration\n */\n async init(): Promise<void> {\n if (this.initialized) return;\n\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:53',message:'Black Box init started',data:{configUrl:this.configUrl,siteId:this.siteId},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n\n try {\n const response = await fetch(this.configUrl, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n cache: 'no-cache',\n });\n\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:64',message:'Config fetch response received',data:{ok:response.ok,status:response.status,statusText:response.statusText},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n\n if (!response.ok) {\n throw new Error(`Failed to load config: ${response.status}`);\n }\n\n const data = await response.json();\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:72',message:'Config JSON parsed',data:{hasPantheraBlackbox:!!data.panthera_blackbox,hasSite:!!data.panthera_blackbox?.site,brand:data.panthera_blackbox?.site?.brand,telemetryEmit:data.panthera_blackbox?.telemetry?.emit},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n \n // Basic validation - ensure it has the expected structure\n if (!data.panthera_blackbox || !data.panthera_blackbox.site) {\n throw new Error('Invalid config structure');\n }\n\n this.config = data as BlackBoxConfig;\n this.initialized = true;\n\n // Apply configuration if needed\n this.applyConfig();\n\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:85',message:'Config applied',data:{initialized:this.initialized,telemetryEmit:this.config.panthera_blackbox.telemetry?.emit},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n\n // Start telemetry if enabled\n if (this.config.panthera_blackbox.telemetry?.emit) {\n this.startTelemetry();\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:90',message:'Telemetry started',data:{telemetryUrl:this.telemetryUrl},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n }\n } catch (error) {\n console.error('[Panthera Black Box] Initialization failed:', error);\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:95',message:'Black Box init failed',data:{error:error instanceof Error?error.message:String(error)},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n \n // Fail silently in production, but log for debugging\n }\n }\n\n /**\n * Apply configuration to the page (declarative transformations only)\n */\n private applyConfig(): void {\n if (!this.config) return;\n\n const config = this.config.panthera_blackbox;\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:95',message:'applyConfig called',data:{hasConfig:!!this.config,brand:config.site?.brand,telemetryEmit:config.telemetry?.emit,autofillEnabled:config.autofill?.enabled,hasAds:!!config.ads?.slots},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'E'})}).catch(()=>{});\n // #endregion\n \n // Inject JSON-LD schema if configured\n this.injectSchema(config);\n \n // Initialize AutoFill if enabled\n if (config.autofill?.enabled && config.autofill.forms) {\n this.initializeAutoFill(config);\n }\n \n // Initialize ad slots if configured\n if (config.ads?.slots) {\n this.initializeAdSlots(config);\n }\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:112',message:'applyConfig completed',data:{schemaInjected:!!document.querySelector('script[data-panthera]')},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'E'})}).catch(()=>{});\n // #endregion\n }\n\n /**\n * Inject JSON-LD schema\n */\n private injectSchema(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof document === 'undefined') return;\n \n // Remove existing Panthera schemas if present\n const existing = document.querySelectorAll('script[type=\"application/ld+json\"][data-panthera]');\n existing.forEach(el => el.remove());\n \n // Get tier from config (if available) or default to bronze\n const tier = config.tier ?? 'bronze';\n \n // Generate schemas based on tier\n const schemas = this.generateSchemasForTier(config, tier);\n \n // Inject all schemas\n schemas.forEach((schema, index) => {\n const script = document.createElement('script');\n script.type = 'application/ld+json';\n script.setAttribute('data-panthera', 'true');\n script.setAttribute('data-schema-index', index.toString());\n script.textContent = JSON.stringify(schema);\n document.head.appendChild(script);\n });\n }\n\n /**\n * Generate schemas based on tier\n */\n private generateSchemasForTier(\n config: BlackBoxConfig['panthera_blackbox'],\n tier: 'bronze' | 'silver' | 'gold'\n ): unknown[] {\n const schemas: unknown[] = [];\n \n // Base Organization schema (all tiers)\n const baseSchema = {\n '@context': 'https://schema.org',\n '@type': 'Organization',\n name: config.site.brand,\n url: `https://${config.site.domain}`,\n };\n \n // Add authority grove data if available\n if (config.authority_grove?.node) {\n (baseSchema as Record<string, unknown>).sameAs = config.authority_grove.node.sameAs;\n (baseSchema as Record<string, unknown>).keywords = config.authority_grove.node.keywords;\n }\n \n schemas.push(baseSchema);\n \n // Silver and Gold tiers get additional schemas\n if (tier === 'silver' || tier === 'gold') {\n // Add Product schema if product data exists in config\n if (config.products) {\n const products = config.products;\n products.forEach((product) => {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'Product',\n name: product.name || config.site.brand,\n description: product.description,\n brand: {\n '@type': 'Brand',\n name: config.site.brand,\n },\n url: `https://${config.site.domain}`,\n });\n });\n }\n \n // Add Service schema if service data exists\n if (config.services) {\n const services = config.services;\n services.forEach((service) => {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'Service',\n name: service.name || config.site.brand,\n description: service.description,\n provider: {\n '@type': 'Organization',\n name: config.site.brand,\n url: `https://${config.site.domain}`,\n },\n });\n });\n }\n \n // Add LocalBusiness schema if geo data exists\n if (config.site.geo && config.site.geo.length > 0) {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'LocalBusiness',\n name: config.site.brand,\n url: `https://${config.site.domain}`,\n areaServed: config.site.geo,\n });\n }\n \n // Add FAQ schema if FAQ data exists\n if (config.faqs) {\n const faqs = config.faqs;\n if (faqs.length > 0) {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'FAQPage',\n mainEntity: faqs.map(faq => ({\n '@type': 'Question',\n name: faq.question,\n acceptedAnswer: {\n '@type': 'Answer',\n text: faq.answer,\n },\n })),\n });\n }\n }\n }\n \n return schemas;\n }\n\n /**\n * Initialize AutoFill for forms\n */\n private initializeAutoFill(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof window === 'undefined' || !config.autofill?.forms) return;\n \n config.autofill.forms.forEach((form: AutoFillForm) => {\n const formElement = document.querySelector(form.selector);\n if (formElement) {\n // Store form config for later use\n (formElement as HTMLElement & { pantheraAutoFill?: typeof form }).pantheraAutoFill = form;\n \n // Listen for first field focus to trigger AutoFill\n formElement.addEventListener('focusin', (event: Event) => {\n const target = event.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.tagName === 'SELECT') {\n this.triggerAutoFill(form);\n }\n }, { once: true });\n }\n });\n }\n\n /**\n * Trigger AutoFill for a form\n */\n private async triggerAutoFill(form: { selector: string; map: Record<string, string> }): Promise<void> {\n // In production, this would fetch CFP data from API\n // For now, use placeholder data\n const autofillData: Record<string, string> = {};\n \n // Apply AutoFill to form fields\n const formElement = document.querySelector(form.selector);\n if (!formElement) return;\n \n for (const [fieldName, selector] of Object.entries(form.map)) {\n const field = formElement.querySelector(selector) as HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n if (field && autofillData[fieldName]) {\n field.value = autofillData[fieldName];\n field.dispatchEvent(new Event('input', { bubbles: true }));\n }\n }\n }\n\n /**\n * Initialize ad slots\n */\n private initializeAdSlots(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof window === 'undefined' || !config.ads?.slots) return;\n \n config.ads.slots.forEach((slot: AdSlot) => {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:226',message:'initializeAdSlots - original slot.id',data:{slotId:slot.id,slotIdType:typeof slot.id,slotIdString:String(slot.id),slotIdJSON:JSON.stringify(slot.id)},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\n // #endregion\n \n // Sanitize slot ID - aggressively remove quotes and ensure it's a valid CSS selector\n let sanitizedId = String(slot.id || '').trim();\n // Remove all quotes (single and double) from anywhere in the string\n sanitizedId = sanitizedId.replace(/[\"']/g, '');\n // Remove any remaining whitespace\n sanitizedId = sanitizedId.trim();\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:232',message:'initializeAdSlots - after sanitization',data:{sanitizedId,originalSlotId:slot.id,sanitizedLength:sanitizedId.length},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\n // #endregion\n \n if (!sanitizedId) {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:236',message:'initializeAdSlots - empty after sanitization',data:{originalSlotId:slot.id},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\n // #endregion\n return;\n }\n \n try {\n // Escape special CSS characters in the ID (but NOT quotes - they should already be removed)\n // Only escape characters that need escaping in attribute selectors\n const escapedId = sanitizedId.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&');\n // Double-check: ensure no quotes made it through\n if (escapedId.includes('\"') || escapedId.includes(\"'\")) {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:243',message:'initializeAdSlots - quotes detected in escapedId',data:{escapedId,sanitizedId,originalSlotId:slot.id},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'B'})}).catch(()=>{});\n // #endregion\n throw new Error(`Slot ID contains quotes after sanitization: ${escapedId}`);\n }\n \n const selector = `[data-ad-slot=\"${escapedId}\"]`;\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:250',message:'initializeAdSlots - selector construction',data:{escapedId,selector,selectorLength:selector.length,selectorChars:Array.from(selector)},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'B'})}).catch(()=>{});\n // #endregion\n \n const slotElement = document.querySelector(selector);\n \n if (slotElement) {\n // Store slot config\n (slotElement as HTMLElement & { pantheraAdSlot?: typeof slot }).pantheraAdSlot = slot;\n \n // In production, this would load ad creative and track impressions\n this.loadAdCreative(slot);\n } else {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:262',message:'initializeAdSlots - element not found',data:{selector,escapedId},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n }\n } catch (error) {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:267',message:'initializeAdSlots - error caught',data:{error:String(error),errorMessage:(error as Error).message,slotId:slot.id,sanitizedId,escapedId:sanitizedId.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&'),selector:`[data-ad-slot=\"${sanitizedId.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&')}\"]`},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'C'})}).catch(()=>{});\n // #endregion\n \n console.error(`[Panthera Black Box] Invalid ad slot selector for ID: ${slot.id}`, error);\n }\n });\n }\n\n /**\n * Load ad creative for a slot\n */\n private async loadAdCreative(slot: { id: string; contexts: string[] }): Promise<void> {\n // In production, this would:\n // 1. Fetch creative from API based on slot contexts\n // 2. Calculate CPM\n // 3. Render ad\n // 4. Track impression\n \n // Placeholder: just log the slot\n console.debug('[Panthera Black Box] Ad slot initialized:', slot.id);\n }\n\n /**\n * Start telemetry collection\n */\n private startTelemetry(): void {\n if (!this.config?.panthera_blackbox.telemetry?.emit) return;\n\n // Collect initial telemetry\n this.sendTelemetry('page_view', {\n url: window.location.href,\n referrer: document.referrer,\n });\n\n // Listen for user interactions (if configured)\n if (typeof window !== 'undefined') {\n // Throttled event listeners for performance\n let interactionTimeout: number | null = null;\n \n const sendInteraction = () => {\n if (interactionTimeout) return;\n interactionTimeout = window.setTimeout(() => {\n this.sendTelemetry('interaction', {\n timestamp: new Date().toISOString(),\n });\n interactionTimeout = null;\n }, 1000);\n };\n\n // Only track if explicitly configured\n document.addEventListener('click', sendInteraction, { passive: true });\n document.addEventListener('scroll', sendInteraction, { passive: true });\n }\n }\n\n /**\n * Send telemetry event\n */\n private async sendTelemetry(eventType: string, data: Record<string, unknown>): Promise<void> {\n if (!this.config?.panthera_blackbox.telemetry?.emit) return;\n\n const event: TelemetryEvent = {\n schema: 'panthera.blackbox.v1',\n tenant: this.config.panthera_blackbox.site.domain,\n timestamp: new Date().toISOString(),\n source: 'blackbox',\n context: {\n event_type: eventType,\n ...data,\n },\n metrics: this.collectMetrics(),\n };\n\n try {\n // Use sendBeacon for reliability (doesn't block page unload)\n if (navigator.sendBeacon) {\n navigator.sendBeacon(\n this.telemetryUrl,\n JSON.stringify(event)\n );\n } else {\n // Fallback to fetch\n await fetch(this.telemetryUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(event),\n keepalive: true,\n });\n }\n } catch (error) {\n // Fail silently - telemetry should never break the site\n console.debug('[Panthera Black Box] Telemetry failed:', error);\n }\n }\n\n /**\n * Collect metrics based on configured keys\n */\n private collectMetrics(): Record<string, number> {\n const metrics: Record<string, number> = {};\n const keys = this.config?.panthera_blackbox.telemetry?.keys || [];\n\n // Collect basic metrics if keys are configured\n // This is safe - we're only reading properties, not executing code\n keys.forEach((key) => {\n // Map telemetry keys to actual metrics\n // For now, return placeholder values\n // In production, these would be calculated from actual page state\n metrics[key] = 0;\n });\n\n return metrics;\n }\n\n /**\n * Get current configuration (read-only)\n */\n getConfig(): BlackBoxConfig | null {\n return this.config;\n }\n\n /**\n * Reload configuration\n */\n async reload(): Promise<void> {\n this.initialized = false;\n await this.init();\n }\n}\n\n// Auto-initialize if script tag has data attributes\n(function () {\n if (typeof window === 'undefined') return;\n\n const script = document.currentScript as HTMLScriptElement | null;\n if (!script) return;\n\n const configUrl = script.getAttribute('data-config-url');\n const telemetryUrl = script.getAttribute('data-telemetry-url');\n const siteId = script.getAttribute('data-site-id');\n\n if (!configUrl || !telemetryUrl || !siteId) {\n console.warn('[Panthera Black Box] Missing required data attributes');\n return;\n }\n\n const blackBox = new PantheraBlackBox({\n configUrl,\n telemetryUrl,\n siteId,\n });\n\n // Initialize when DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => blackBox.init());\n } else {\n blackBox.init();\n }\n\n // Expose globally for manual control (optional)\n (window as unknown as { PantheraBlackBox: typeof PantheraBlackBox }).PantheraBlackBox = PantheraBlackBox;\n (window as unknown as { panthera: PantheraBlackBox }).panthera = blackBox;\n})();\n\nexport { PantheraBlackBox };\nexport default PantheraBlackBox;\n"],"mappings":"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","names":["PantheraBlackBox","options","response","data","error","config","el","tier","schema","index","script","schemas","baseSchema","product","service","faqs","faq","form","formElement","event","target","autofillData","fieldName","selector","field","slot","sanitizedId","escapedId","slotElement","interactionTimeout","sendInteraction","eventType","metrics","key","configUrl","telemetryUrl","siteId","blackBox","runtime_default","PantheraBlackBox"]}
1
+ {"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["/**\n * Panthera Black Box Runtime\n * \n * AI Search Optimization Runtime - Optimizes websites for AI search engines\n * (ChatGPT, Perplexity, Claude, etc.) by injecting structured data and building\n * authority signals that AI models can understand and prioritize.\n * \n * Key Features:\n * - JSON-LD schema injection for AI model comprehension\n * - Authority Grove integration for trust signals\n * - TruthSeeker integration for factual accuracy\n * - Telemetry for AI search visibility tracking\n * \n * Designed to be <10KB gzipped when compiled.\n * \n * Safety: No eval(), no Function(), no arbitrary code execution.\n * All operations are declarative JSON transformations only.\n */\n\ninterface AutoFillForm {\n selector: string;\n map: Record<string, string>;\n}\n\ninterface AutofillConfig {\n enabled?: boolean;\n forms?: AutoFillForm[];\n}\n\ninterface AdSlot {\n id: string;\n contexts: string[];\n}\n\ninterface AdsConfig {\n slots?: AdSlot[];\n}\n\ninterface AuthorityGroveNode {\n sameAs?: string[];\n keywords?: string[];\n}\n\ninterface AuthorityGroveConfig {\n node?: AuthorityGroveNode;\n}\n\ninterface ProductConfig {\n name?: string;\n description?: string;\n}\n\ninterface ServiceConfig {\n name?: string;\n description?: string;\n}\n\ninterface FaqConfig {\n question: string;\n answer: string;\n}\n\ninterface SEOEnhancements {\n meta_description?: string;\n canonical_enabled?: boolean;\n content_enhancements?: {\n enabled: boolean;\n what?: string;\n who?: string;\n how?: string;\n trust?: string;\n };\n content_depth?: {\n enabled: boolean;\n min_h2_count?: number;\n h2_templates?: string[];\n content_templates?: string[];\n default_content?: string;\n };\n structure_enhancements?: {\n inject_h1_if_missing?: boolean;\n h1_text?: string;\n enhance_title?: boolean;\n min_title_length?: number;\n title_template?: string;\n };\n}\n\ninterface BlackBoxConfig {\n panthera_blackbox: {\n version: string;\n site: {\n domain: string;\n brand: string;\n verticals: string[];\n geo: string[];\n };\n telemetry: {\n emit: boolean;\n keys: string[];\n };\n tier?: 'bronze' | 'silver' | 'gold';\n autofill?: AutofillConfig;\n ads?: AdsConfig;\n authority_grove?: AuthorityGroveConfig;\n products?: ProductConfig[];\n services?: ServiceConfig[];\n faqs?: FaqConfig[];\n seo_enhancements?: SEOEnhancements;\n [key: string]: unknown;\n };\n}\n\ninterface TelemetryEvent {\n schema: string;\n tenant: string;\n timestamp: string;\n source: 'blackbox';\n context?: Record<string, unknown>;\n metrics: Record<string, number>;\n}\n\nclass PantheraBlackBox {\n private config: BlackBoxConfig | null = null;\n private configUrl: string;\n private telemetryUrl: string;\n private siteId: string;\n private initialized = false;\n\n constructor(options: { configUrl: string; telemetryUrl: string; siteId: string }) {\n this.configUrl = options.configUrl;\n this.telemetryUrl = options.telemetryUrl;\n this.siteId = options.siteId;\n }\n\n /**\n * Initialize the Black Box by loading configuration\n */\n async init(): Promise<void> {\n if (this.initialized) return;\n\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:53',message:'Black Box init started',data:{configUrl:this.configUrl,siteId:this.siteId},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n\n try {\n const response = await fetch(this.configUrl, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n cache: 'no-cache',\n });\n\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:64',message:'Config fetch response received',data:{ok:response.ok,status:response.status,statusText:response.statusText},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n\n if (!response.ok) {\n throw new Error(`Failed to load config: ${response.status}`);\n }\n\n const data = await response.json();\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:72',message:'Config JSON parsed',data:{hasPantheraBlackbox:!!data.panthera_blackbox,hasSite:!!data.panthera_blackbox?.site,brand:data.panthera_blackbox?.site?.brand,telemetryEmit:data.panthera_blackbox?.telemetry?.emit},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n \n // Basic validation - ensure it has the expected structure\n if (!data.panthera_blackbox || !data.panthera_blackbox.site) {\n throw new Error('Invalid config structure');\n }\n\n this.config = data as BlackBoxConfig;\n this.initialized = true;\n\n // Apply configuration if needed\n this.applyConfig();\n\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:85',message:'Config applied',data:{initialized:this.initialized,telemetryEmit:this.config.panthera_blackbox.telemetry?.emit},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n\n // Start telemetry if enabled\n if (this.config.panthera_blackbox.telemetry?.emit) {\n this.startTelemetry();\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:90',message:'Telemetry started',data:{telemetryUrl:this.telemetryUrl},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n }\n } catch (error) {\n console.error('[Panthera Black Box] Initialization failed:', error);\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:95',message:'Black Box init failed',data:{error:error instanceof Error?error.message:String(error)},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n \n // Fail silently in production, but log for debugging\n }\n }\n\n /**\n * Apply configuration to the page (declarative transformations only)\n */\n private applyConfig(): void {\n if (!this.config) return;\n\n const config = this.config.panthera_blackbox;\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:95',message:'applyConfig called',data:{hasConfig:!!this.config,brand:config.site?.brand,telemetryEmit:config.telemetry?.emit,autofillEnabled:config.autofill?.enabled,hasAds:!!config.ads?.slots},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'E'})}).catch(()=>{});\n // #endregion\n \n // Inject JSON-LD schema if configured\n this.injectSchema(config);\n \n // Inject meta tags and canonical\n this.injectMetaTags(config);\n \n // Inject structure enhancements (H1, title)\n this.injectStructureEnhancements(config);\n \n // Inject content enhancements (AI Readiness)\n this.injectContentEnhancements(config);\n \n // Inject content depth (H2, content blocks)\n this.injectContentDepth(config);\n \n // Initialize AutoFill if enabled\n if (config.autofill?.enabled && config.autofill.forms) {\n this.initializeAutoFill(config);\n }\n \n // Initialize ad slots if configured\n if (config.ads?.slots) {\n this.initializeAdSlots(config);\n }\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'black-box/runtime.ts:112',message:'applyConfig completed',data:{schemaInjected:!!document.querySelector('script[data-panthera]')},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'E'})}).catch(()=>{});\n // #endregion\n }\n\n /**\n * Inject JSON-LD schema\n */\n private injectSchema(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof document === 'undefined') return;\n \n // Remove existing Panthera schemas if present\n const existing = document.querySelectorAll('script[type=\"application/ld+json\"][data-panthera]');\n existing.forEach(el => el.remove());\n \n // Get tier from config (if available) or default to bronze\n const tier = config.tier ?? 'bronze';\n \n // Generate schemas based on tier\n const schemas = this.generateSchemasForTier(config, tier);\n \n // Inject all schemas\n schemas.forEach((schema, index) => {\n const script = document.createElement('script');\n script.type = 'application/ld+json';\n script.setAttribute('data-panthera', 'true');\n script.setAttribute('data-schema-index', index.toString());\n script.textContent = JSON.stringify(schema);\n document.head.appendChild(script);\n });\n }\n\n /**\n * Generate schemas based on tier\n */\n private generateSchemasForTier(\n config: BlackBoxConfig['panthera_blackbox'],\n tier: 'bronze' | 'silver' | 'gold'\n ): unknown[] {\n const schemas: unknown[] = [];\n \n // Base Organization schema (all tiers)\n const baseSchema = {\n '@context': 'https://schema.org',\n '@type': 'Organization',\n name: config.site.brand,\n url: `https://${config.site.domain}`,\n };\n \n // Add authority grove data if available\n if (config.authority_grove?.node) {\n (baseSchema as Record<string, unknown>).sameAs = config.authority_grove.node.sameAs;\n (baseSchema as Record<string, unknown>).keywords = config.authority_grove.node.keywords;\n }\n \n schemas.push(baseSchema);\n \n // Silver and Gold tiers get additional schemas\n if (tier === 'silver' || tier === 'gold') {\n // Add Product schema if product data exists in config\n if (config.products) {\n const products = config.products;\n products.forEach((product) => {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'Product',\n name: product.name || config.site.brand,\n description: product.description,\n brand: {\n '@type': 'Brand',\n name: config.site.brand,\n },\n url: `https://${config.site.domain}`,\n });\n });\n }\n \n // Add Service schema if service data exists\n if (config.services) {\n const services = config.services;\n services.forEach((service) => {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'Service',\n name: service.name || config.site.brand,\n description: service.description,\n provider: {\n '@type': 'Organization',\n name: config.site.brand,\n url: `https://${config.site.domain}`,\n },\n });\n });\n }\n \n // Add LocalBusiness schema if geo data exists\n if (config.site.geo && config.site.geo.length > 0) {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'LocalBusiness',\n name: config.site.brand,\n url: `https://${config.site.domain}`,\n areaServed: config.site.geo,\n });\n }\n \n // Add FAQ schema if FAQ data exists\n if (config.faqs) {\n const faqs = config.faqs;\n if (faqs.length > 0) {\n schemas.push({\n '@context': 'https://schema.org',\n '@type': 'FAQPage',\n mainEntity: faqs.map(faq => ({\n '@type': 'Question',\n name: faq.question,\n acceptedAnswer: {\n '@type': 'Answer',\n text: faq.answer,\n },\n })),\n });\n }\n }\n }\n \n return schemas;\n }\n\n /**\n * Inject meta tags and canonical tag\n */\n private injectMetaTags(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof document === 'undefined') return;\n \n const seoConfig = config.seo_enhancements;\n if (!seoConfig) return;\n \n // Inject meta description if missing\n if (seoConfig.meta_description) {\n const existingMeta = document.querySelector('meta[name=\"description\"]');\n if (!existingMeta) {\n const meta = document.createElement('meta');\n meta.setAttribute('name', 'description');\n meta.setAttribute('content', seoConfig.meta_description);\n meta.setAttribute('data-panthera', 'true');\n document.head.appendChild(meta);\n }\n }\n \n // Inject canonical tag if enabled and missing\n if (seoConfig.canonical_enabled) {\n const existingCanonical = document.querySelector('link[rel=\"canonical\"]');\n if (!existingCanonical) {\n const canonical = document.createElement('link');\n canonical.setAttribute('rel', 'canonical');\n canonical.setAttribute('href', window.location.href);\n canonical.setAttribute('data-panthera', 'true');\n document.head.appendChild(canonical);\n }\n }\n }\n\n /**\n * Inject content enhancements for AI Readiness\n */\n private injectContentEnhancements(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof document === 'undefined') return;\n \n const contentConfig = config.seo_enhancements?.content_enhancements;\n if (!contentConfig || !contentConfig.enabled) return;\n \n const body = document.body;\n if (!body) return;\n \n // Create hidden content section for AI models (aria-hidden but readable by crawlers)\n const aiContentSection = document.createElement('section');\n aiContentSection.setAttribute('data-panthera', 'true');\n aiContentSection.setAttribute('data-panthera-type', 'ai-readiness');\n aiContentSection.setAttribute('aria-hidden', 'true');\n aiContentSection.style.cssText = 'position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;';\n \n // Add \"what you do\" content\n if (contentConfig.what) {\n const whatDiv = document.createElement('div');\n whatDiv.textContent = contentConfig.what;\n aiContentSection.appendChild(whatDiv);\n }\n \n // Add \"who it's for\" content\n if (contentConfig.who) {\n const whoDiv = document.createElement('div');\n whoDiv.textContent = contentConfig.who;\n aiContentSection.appendChild(whoDiv);\n }\n \n // Add \"how it works\" content\n if (contentConfig.how) {\n const howDiv = document.createElement('div');\n howDiv.textContent = contentConfig.how;\n aiContentSection.appendChild(howDiv);\n }\n \n // Add trust signals\n if (contentConfig.trust) {\n const trustDiv = document.createElement('div');\n trustDiv.textContent = contentConfig.trust;\n aiContentSection.appendChild(trustDiv);\n }\n \n body.appendChild(aiContentSection);\n }\n\n /**\n * Inject content depth enhancements (H2 headings and content blocks)\n */\n private injectContentDepth(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof document === 'undefined') return;\n \n const depthConfig = config.seo_enhancements?.content_depth;\n if (!depthConfig || !depthConfig.enabled) return;\n \n const body = document.body;\n if (!body) return;\n \n // Count existing H2s\n const existingH2s = body.querySelectorAll('h2').length;\n const targetH2Count = depthConfig.min_h2_count || 6;\n \n // Calculate existing text length\n const existingText = body.textContent || '';\n const existingTextLength = existingText.length;\n const targetTextLength = 6000; // Target for max score\n const neededTextLength = Math.max(0, targetTextLength - existingTextLength);\n \n // Create hidden content section with H2 headings and content\n const depthSection = document.createElement('section');\n depthSection.setAttribute('data-panthera', 'true');\n depthSection.setAttribute('data-panthera-type', 'content-depth');\n depthSection.setAttribute('aria-hidden', 'true');\n depthSection.style.cssText = 'position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;';\n \n let addedTextLength = 0;\n const neededH2s = Math.max(0, targetH2Count - existingH2s);\n \n // Generate H2 headings with content\n for (let i = 0; i < neededH2s || addedTextLength < neededTextLength; i++) {\n const h2 = document.createElement('h2');\n h2.textContent = depthConfig.h2_templates?.[i] || `Section ${i + 1}`;\n depthSection.appendChild(h2);\n addedTextLength += h2.textContent.length;\n \n // Add paragraph content for text length\n // Generate enough paragraphs to reach target text length\n const paragraphText = depthConfig.content_templates?.[i] || depthConfig.default_content || \n 'This section provides additional context and information for AI search engines. Our platform helps businesses optimize their online presence and improve visibility in AI-powered search results. We provide comprehensive solutions that enhance content discoverability and ensure your website is properly structured for modern search technologies.';\n \n // Add multiple paragraphs if needed to reach target length\n const charsPerParagraph = paragraphText.length;\n const paragraphsNeeded = Math.ceil((neededTextLength - addedTextLength) / charsPerParagraph) || 1;\n \n for (let p = 0; p < Math.max(1, paragraphsNeeded) && addedTextLength < neededTextLength; p++) {\n const paragraph = document.createElement('p');\n paragraph.textContent = paragraphText;\n depthSection.appendChild(paragraph);\n addedTextLength += paragraphText.length;\n }\n }\n \n if (depthSection.children.length > 0) {\n body.appendChild(depthSection);\n }\n }\n\n /**\n * Inject structure enhancements (H1 and title tags)\n */\n private injectStructureEnhancements(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof document === 'undefined') return;\n \n const structureConfig = config.seo_enhancements?.structure_enhancements;\n if (!structureConfig) return;\n \n // Inject H1 if missing\n if (structureConfig.inject_h1_if_missing) {\n const existingH1 = document.querySelector('h1');\n if (!existingH1 && structureConfig.h1_text) {\n const body = document.body;\n if (body) {\n const h1 = document.createElement('h1');\n h1.textContent = structureConfig.h1_text;\n h1.setAttribute('data-panthera', 'true');\n // Insert at beginning of body or after first element\n const firstChild = body.firstElementChild;\n if (firstChild) {\n body.insertBefore(h1, firstChild);\n } else {\n body.appendChild(h1);\n }\n }\n }\n }\n \n // Enhance title tag if too short or missing\n if (structureConfig.enhance_title) {\n const title = document.querySelector('title');\n const currentTitle = title?.textContent || '';\n const minLength = structureConfig.min_title_length || 30;\n \n if (currentTitle.length < minLength && structureConfig.title_template) {\n const newTitle = structureConfig.title_template.replace('{brand}', config.site.brand);\n if (title) {\n title.textContent = newTitle;\n title.setAttribute('data-panthera-enhanced', 'true');\n } else {\n const newTitleElement = document.createElement('title');\n newTitleElement.textContent = newTitle;\n newTitleElement.setAttribute('data-panthera', 'true');\n document.head.appendChild(newTitleElement);\n }\n }\n }\n }\n\n /**\n * Initialize AutoFill for forms\n */\n private initializeAutoFill(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof window === 'undefined' || !config.autofill?.forms) return;\n \n config.autofill.forms.forEach((form: AutoFillForm) => {\n const formElement = document.querySelector(form.selector);\n if (formElement) {\n // Store form config for later use\n (formElement as HTMLElement & { pantheraAutoFill?: typeof form }).pantheraAutoFill = form;\n \n // Listen for first field focus to trigger AutoFill\n formElement.addEventListener('focusin', (event: Event) => {\n const target = event.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.tagName === 'SELECT') {\n this.triggerAutoFill(form);\n }\n }, { once: true });\n }\n });\n }\n\n /**\n * Trigger AutoFill for a form\n */\n private async triggerAutoFill(form: { selector: string; map: Record<string, string> }): Promise<void> {\n // In production, this would fetch CFP data from API\n // For now, use placeholder data\n const autofillData: Record<string, string> = {};\n \n // Apply AutoFill to form fields\n const formElement = document.querySelector(form.selector);\n if (!formElement) return;\n \n for (const [fieldName, selector] of Object.entries(form.map)) {\n const field = formElement.querySelector(selector) as HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n if (field && autofillData[fieldName]) {\n field.value = autofillData[fieldName];\n field.dispatchEvent(new Event('input', { bubbles: true }));\n }\n }\n }\n\n /**\n * Initialize ad slots\n */\n private initializeAdSlots(config: BlackBoxConfig['panthera_blackbox']): void {\n if (typeof window === 'undefined' || !config.ads?.slots) return;\n \n config.ads.slots.forEach((slot: AdSlot) => {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:226',message:'initializeAdSlots - original slot.id',data:{slotId:slot.id,slotIdType:typeof slot.id,slotIdString:String(slot.id),slotIdJSON:JSON.stringify(slot.id)},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\n // #endregion\n \n // Sanitize slot ID - aggressively remove quotes and ensure it's a valid CSS selector\n let sanitizedId = String(slot.id || '').trim();\n // Remove all quotes (single and double) from anywhere in the string\n sanitizedId = sanitizedId.replace(/[\"']/g, '');\n // Remove any remaining whitespace\n sanitizedId = sanitizedId.trim();\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:232',message:'initializeAdSlots - after sanitization',data:{sanitizedId,originalSlotId:slot.id,sanitizedLength:sanitizedId.length},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\n // #endregion\n \n if (!sanitizedId) {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:236',message:'initializeAdSlots - empty after sanitization',data:{originalSlotId:slot.id},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'A'})}).catch(()=>{});\n // #endregion\n return;\n }\n \n try {\n // Escape special CSS characters in the ID (but NOT quotes - they should already be removed)\n // Only escape characters that need escaping in attribute selectors\n const escapedId = sanitizedId.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&');\n // Double-check: ensure no quotes made it through\n if (escapedId.includes('\"') || escapedId.includes(\"'\")) {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:243',message:'initializeAdSlots - quotes detected in escapedId',data:{escapedId,sanitizedId,originalSlotId:slot.id},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'B'})}).catch(()=>{});\n // #endregion\n throw new Error(`Slot ID contains quotes after sanitization: ${escapedId}`);\n }\n \n const selector = `[data-ad-slot=\"${escapedId}\"]`;\n \n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:250',message:'initializeAdSlots - selector construction',data:{escapedId,selector,selectorLength:selector.length,selectorChars:Array.from(selector)},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'B'})}).catch(()=>{});\n // #endregion\n \n const slotElement = document.querySelector(selector);\n \n if (slotElement) {\n // Store slot config\n (slotElement as HTMLElement & { pantheraAdSlot?: typeof slot }).pantheraAdSlot = slot;\n \n // In production, this would load ad creative and track impressions\n this.loadAdCreative(slot);\n } else {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:262',message:'initializeAdSlots - element not found',data:{selector,escapedId},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'D'})}).catch(()=>{});\n // #endregion\n }\n } catch (error) {\n // #region agent log\n fetch('http://127.0.0.1:7251/ingest/f2bef142-91a5-4d7a-be78-4c2383eb5638',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'runtime.ts:267',message:'initializeAdSlots - error caught',data:{error:String(error),errorMessage:(error as Error).message,slotId:slot.id,sanitizedId,escapedId:sanitizedId.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&'),selector:`[data-ad-slot=\"${sanitizedId.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&')}\"]`},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'C'})}).catch(()=>{});\n // #endregion\n \n console.error(`[Panthera Black Box] Invalid ad slot selector for ID: ${slot.id}`, error);\n }\n });\n }\n\n /**\n * Load ad creative for a slot\n */\n private async loadAdCreative(slot: { id: string; contexts: string[] }): Promise<void> {\n // In production, this would:\n // 1. Fetch creative from API based on slot contexts\n // 2. Calculate CPM\n // 3. Render ad\n // 4. Track impression\n \n // Placeholder: just log the slot\n console.debug('[Panthera Black Box] Ad slot initialized:', slot.id);\n }\n\n /**\n * Start telemetry collection\n */\n private startTelemetry(): void {\n if (!this.config?.panthera_blackbox.telemetry?.emit) return;\n\n // Collect initial telemetry\n this.sendTelemetry('page_view', {\n url: window.location.href,\n referrer: document.referrer,\n });\n\n // Listen for user interactions (if configured)\n if (typeof window !== 'undefined') {\n // Throttled event listeners for performance\n let interactionTimeout: number | null = null;\n \n const sendInteraction = () => {\n if (interactionTimeout) return;\n interactionTimeout = window.setTimeout(() => {\n this.sendTelemetry('interaction', {\n timestamp: new Date().toISOString(),\n });\n interactionTimeout = null;\n }, 1000);\n };\n\n // Only track if explicitly configured\n document.addEventListener('click', sendInteraction, { passive: true });\n document.addEventListener('scroll', sendInteraction, { passive: true });\n }\n }\n\n /**\n * Send telemetry event\n */\n private async sendTelemetry(eventType: string, data: Record<string, unknown>): Promise<void> {\n if (!this.config?.panthera_blackbox.telemetry?.emit) return;\n\n const event: TelemetryEvent = {\n schema: 'panthera.blackbox.v1',\n tenant: this.config.panthera_blackbox.site.domain,\n timestamp: new Date().toISOString(),\n source: 'blackbox',\n context: {\n event_type: eventType,\n ...data,\n },\n metrics: this.collectMetrics(),\n };\n\n try {\n // Use sendBeacon for reliability (doesn't block page unload)\n // Note: sendBeacon requires Blob with Content-Type for JSON\n if (navigator.sendBeacon) {\n const blob = new Blob([JSON.stringify(event)], { type: 'application/json' });\n navigator.sendBeacon(this.telemetryUrl, blob);\n } else {\n // Fallback to fetch\n await fetch(this.telemetryUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(event),\n keepalive: true,\n });\n }\n } catch (error) {\n // Fail silently - telemetry should never break the site\n console.debug('[Panthera Black Box] Telemetry failed:', error);\n }\n }\n\n /**\n * Collect metrics based on configured keys\n */\n private collectMetrics(): Record<string, number> {\n const metrics: Record<string, number> = {};\n const keys = this.config?.panthera_blackbox.telemetry?.keys || [];\n\n // Collect basic metrics if keys are configured\n // This is safe - we're only reading properties, not executing code\n keys.forEach((key) => {\n // Map telemetry keys to actual metrics\n // For now, return sample values based on key type\n // In production, these would be calculated from actual page state\n \n // Provide sample values for common metrics to make charts visible\n if (key.startsWith('ts.')) {\n // TruthSeeker metrics - sample values between 0.5-0.9\n metrics[key] = 0.5 + Math.random() * 0.4;\n } else if (key.startsWith('ai.')) {\n // AI search metrics - sample values between 0.6-0.95\n metrics[key] = 0.6 + Math.random() * 0.35;\n } else {\n // Other metrics - default to 0\n metrics[key] = 0;\n }\n });\n\n return metrics;\n }\n\n /**\n * Get current configuration (read-only)\n */\n getConfig(): BlackBoxConfig | null {\n return this.config;\n }\n\n /**\n * Reload configuration\n */\n async reload(): Promise<void> {\n this.initialized = false;\n await this.init();\n }\n}\n\n// Auto-initialize if script tag has data attributes\n(function () {\n if (typeof window === 'undefined') return;\n\n const script = document.currentScript as HTMLScriptElement | null;\n if (!script) return;\n\n const configUrl = script.getAttribute('data-config-url');\n const telemetryUrl = script.getAttribute('data-telemetry-url');\n const siteId = script.getAttribute('data-site-id');\n\n if (!configUrl || !telemetryUrl || !siteId) {\n console.warn('[Panthera Black Box] Missing required data attributes');\n return;\n }\n\n const blackBox = new PantheraBlackBox({\n configUrl,\n telemetryUrl,\n siteId,\n });\n\n // Initialize when DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => blackBox.init());\n } else {\n blackBox.init();\n }\n\n // Expose globally for manual control (optional)\n (window as unknown as { PantheraBlackBox: typeof PantheraBlackBox }).PantheraBlackBox = PantheraBlackBox;\n (window as unknown as { panthera: PantheraBlackBox }).panthera = blackBox;\n})();\n\nexport { PantheraBlackBox };\nexport default PantheraBlackBox;\n"],"mappings":"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","names":["PantheraBlackBox","options","response","data","error","config","el","tier","schema","index","script","schemas","baseSchema","product","service","faqs","faq","seoConfig","meta","canonical","contentConfig","body","aiContentSection","whatDiv","whoDiv","howDiv","trustDiv","depthConfig","existingH2s","targetH2Count","existingTextLength","neededTextLength","depthSection","addedTextLength","neededH2s","i","h2","paragraphText","charsPerParagraph","paragraphsNeeded","p","paragraph","structureConfig","h1","firstChild","title","currentTitle","minLength","newTitle","newTitleElement","form","formElement","event","target","autofillData","fieldName","selector","field","slot","sanitizedId","escapedId","slotElement","interactionTimeout","sendInteraction","eventType","blob","metrics","key","configUrl","telemetryUrl","siteId","blackBox","runtime_default","PantheraBlackBox"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@careerdriver/black-box",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "files": [