@active-reach/web-sdk 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -0
- package/dist/aegis.min.js +1 -1
- package/dist/aegis.min.js.map +1 -1
- package/dist/{analytics-B11keZ55.mjs → analytics-CNtfsb7E.mjs} +214 -2
- package/dist/analytics-CNtfsb7E.mjs.map +1 -0
- package/dist/core/analytics.d.ts +13 -0
- package/dist/core/analytics.d.ts.map +1 -1
- package/dist/ecommerce/index.d.ts +46 -0
- package/dist/ecommerce/index.d.ts.map +1 -0
- package/dist/ecommerce/types.d.ts +77 -0
- package/dist/ecommerce/types.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +70 -1
- package/dist/index.js.map +1 -1
- package/dist/placements/AegisPlacementManager.d.ts +1 -1
- package/dist/placements/AegisPlacementManager.d.ts.map +1 -1
- package/dist/react.js +1 -1
- package/package.json +1 -1
- package/dist/analytics-B11keZ55.mjs.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/utils/debounce.ts","../src/inapp/AegisInAppManager.ts","../src/inapp/renderPreview.ts","../src/placements/AegisPlacementManager.ts","../src/widgets/AegisWidgetManager.ts","../src/triggers/TriggerEngine.ts","../src/core/sdk-config-poller.ts","../src/index.ts"],"sourcesContent":["export function debounce<T extends (...args: any[]) => any>(\n func: T,\n wait: number\n): (...args: Parameters<T>) => void {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n return function debounced(...args: Parameters<T>): void {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n }\n\n timeoutId = setTimeout(() => {\n func(...args);\n timeoutId = null;\n }, wait);\n };\n}\n\nexport function throttle<T extends (...args: any[]) => any>(\n func: T,\n limit: number\n): (...args: Parameters<T>) => void {\n let inThrottle = false;\n\n return function throttled(...args: Parameters<T>): void {\n if (!inThrottle) {\n func(...args);\n inThrottle = true;\n setTimeout(() => {\n inThrottle = false;\n }, limit);\n }\n };\n}\n","/**\n * AegisInAppManager - Web SDK In-App Messaging Module\n * \n * Real-time SSE architecture with client-side evaluation.\n * \n * Security:\n * - XSS Protection: Uses DOM APIs (createElement, textContent) instead of innerHTML\n * - URL Validation: Prevents javascript: protocol injection\n * - CSP Compatible: No inline styles in HTML strings\n * \n * Architecture:\n * - Connects to SSE endpoint for real-time campaign updates\n * - Initial fetch on load, then SSE for updates\n * - Caches campaigns locally in memory\n * - Evaluates trigger rules client-side\n * - Tracks events (impression, click, dismiss) asynchronously\n */\n\nexport interface InAppCampaign {\n id: string;\n type: 'modal' | 'banner' | 'tooltip' | 'full_screen' | 'half_interstitial' | 'alert' | 'pip';\n sub_type?: string;\n title: string;\n body: string;\n image_url?: string;\n video_url?: string;\n action_url?: string;\n button_text?: string;\n background_color?: string;\n text_color?: string;\n priority: number;\n expires_at?: string;\n frequency?: {\n max_impressions?: number;\n max_impressions_per_day?: number;\n cooldown_seconds?: number;\n };\n interactive_config?: Record<string, unknown>;\n client_trigger?: {\n type: string;\n config?: Record<string, unknown>;\n };\n assigned_variant_id?: string;\n}\n\nexport interface AegisInAppConfig {\n writeKey: string;\n apiHost?: string;\n userId?: string;\n contactId?: string;\n organizationId?: string;\n debugMode?: boolean;\n enableSSE?: boolean;\n}\n\nexport class AegisInAppManager {\n private writeKey: string;\n private apiHost: string;\n private userId?: string;\n private contactId?: string;\n private organizationId?: string;\n private debugMode: boolean;\n private enableSSE: boolean;\n \n private campaigns: InAppCampaign[] = [];\n private displayedCampaigns = new Set<string>();\n private eventSource?: EventSource;\n private isInitialized = false;\n private reconnectAttempts = 0;\n private maxReconnectAttempts = 5;\n \n constructor(config: AegisInAppConfig) {\n this.writeKey = config.writeKey;\n this.apiHost = config.apiHost || 'https://api.aegis.ai';\n this.userId = config.userId;\n this.contactId = config.contactId;\n this.organizationId = config.organizationId;\n this.debugMode = config.debugMode || false;\n this.enableSSE = config.enableSSE !== false;\n }\n \n async initialize(): Promise<void> {\n if (this.isInitialized) {\n this.log('AegisInApp already initialized');\n return;\n }\n\n // Mark user as returning for subsequent visits\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem('aegis_returning_user', '1');\n }\n\n await this.refreshCampaigns();\n\n if (this.enableSSE && this.organizationId) {\n this.connectSSE();\n }\n \n this.isInitialized = true;\n this.log('AegisInApp initialized successfully');\n }\n \n updateUserId(userId: string): void {\n this.userId = userId;\n this.refreshCampaigns();\n }\n \n updateContactId(contactId: string): void {\n this.contactId = contactId;\n this.disconnectSSE();\n if (this.enableSSE && this.organizationId) {\n this.connectSSE();\n }\n this.refreshCampaigns();\n }\n \n private connectSSE(): void {\n if (this.eventSource) {\n this.disconnectSSE();\n }\n \n if (!this.organizationId) {\n this.log('Cannot connect SSE without organization ID', 'warn');\n return;\n }\n \n const url = new URL('/v1/stream/realtime', this.apiHost);\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'X-Organization-ID': this.organizationId,\n };\n \n if (this.contactId) {\n headers['X-Contact-ID'] = this.contactId;\n }\n \n const queryParams = new URLSearchParams();\n Object.entries(headers).forEach(([key, value]) => {\n queryParams.append(key, value);\n });\n \n this.eventSource = new EventSource(`${url}?${queryParams.toString()}`);\n \n this.eventSource.addEventListener('open', () => {\n this.log('SSE connection established');\n this.reconnectAttempts = 0;\n });\n \n this.eventSource.addEventListener('in_app_campaign_updated', (event: MessageEvent) => {\n try {\n const data = JSON.parse(event.data);\n this.log(`Received in-app campaign update: ${data.campaign_id}`);\n this.refreshCampaigns();\n } catch (error) {\n this.log(`Error parsing SSE event: ${error}`, 'error');\n }\n });\n \n this.eventSource.addEventListener('heartbeat', (event: MessageEvent) => {\n this.log('SSE heartbeat received');\n });\n \n this.eventSource.addEventListener('error', (error) => {\n this.log('SSE connection error', 'error');\n \n if (this.eventSource?.readyState === EventSource.CLOSED) {\n this.attemptReconnect();\n }\n });\n }\n \n private disconnectSSE(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = undefined;\n this.log('SSE connection closed');\n }\n }\n \n private attemptReconnect(): void {\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n this.log('Max reconnect attempts reached, giving up', 'warn');\n return;\n }\n \n this.reconnectAttempts++;\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);\n \n this.log(`Reconnecting SSE in ${delay}ms (attempt ${this.reconnectAttempts})`);\n \n setTimeout(() => {\n if (this.isInitialized && this.enableSSE && this.organizationId) {\n this.connectSSE();\n }\n }, delay);\n }\n \n private async refreshCampaigns(): Promise<void> {\n try {\n // Build URL with client context for server-side targeting (Critical Fix B)\n const context = new URLSearchParams({\n device_type: this.detectDeviceType(),\n page_url: typeof window !== 'undefined' ? window.location.pathname : '/',\n });\n\n // Geo is resolved server-side from IP — no need to send\n context.set('is_new_user', this.isNewUser() ? 'true' : 'false');\n\n const url = `${this.apiHost}/v1/in-app/active?${context.toString()}`;\n\n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'Content-Type': 'application/json'\n };\n\n if (this.userId) {\n headers['X-User-ID'] = this.userId;\n }\n\n if (this.contactId) {\n headers['X-Contact-ID'] = this.contactId;\n }\n\n if (this.organizationId) {\n headers['X-Organization-ID'] = this.organizationId;\n }\n\n // Send cached A/B assignments so server can skip re-evaluation (Critical Fix C)\n const abAssignments = this.getABAssignments();\n if (Object.keys(abAssignments).length > 0) {\n headers['X-AB-Assignments'] = btoa(JSON.stringify(abAssignments));\n }\n\n const response = await fetch(url, {\n method: 'GET',\n headers\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch campaigns: ${response.status}`);\n }\n\n this.campaigns = await response.json();\n\n // Process A/B assignments from server response (Critical Fix C)\n this.processABAssignments(this.campaigns);\n\n this.log(`Fetched ${this.campaigns.length} campaigns`);\n\n this.tryDisplayNextCampaign();\n\n } catch (error) {\n this.log(`Error refreshing campaigns: ${error}`, 'error');\n }\n }\n\n // --- Client Context Helpers (Critical Fix B) ---\n\n private detectDeviceType(): 'mobile' | 'desktop' | 'tablet' {\n if (typeof navigator === 'undefined') return 'desktop';\n const ua = navigator.userAgent;\n if (/Mobi|Android/i.test(ua)) return 'mobile';\n if (/iPad|Tablet/i.test(ua)) return 'tablet';\n return 'desktop';\n }\n\n private isNewUser(): boolean {\n if (typeof localStorage === 'undefined') return true;\n return !localStorage.getItem('aegis_returning_user');\n }\n\n // --- A/B Assignment Persistence (Critical Fix C) ---\n\n private getABAssignments(): Record<string, string> {\n if (typeof localStorage === 'undefined') return {};\n try {\n return JSON.parse(localStorage.getItem('aegis_ab_assignments') || '{}');\n } catch {\n return {};\n }\n }\n\n private processABAssignments(campaigns: InAppCampaign[]): void {\n if (typeof localStorage === 'undefined') return;\n const stored = this.getABAssignments();\n for (const campaign of campaigns) {\n if (campaign.assigned_variant_id) {\n stored[campaign.id] = campaign.assigned_variant_id;\n }\n }\n localStorage.setItem('aegis_ab_assignments', JSON.stringify(stored));\n }\n\n private getVariantId(campaignId: string): string | undefined {\n const assignments = this.getABAssignments();\n return assignments[campaignId] ?? undefined;\n }\n \n private tryDisplayNextCampaign(): void {\n const campaign = this.campaigns.find(c => !this.displayedCampaigns.has(c.id));\n \n if (campaign) {\n this.displayCampaign(campaign);\n }\n }\n \n private displayCampaign(campaign: InAppCampaign): void {\n this.displayedCampaigns.add(campaign.id);\n\n // Sub-type routing: interactive types are handled by dedicated renderers\n const interactiveSubTypes = new Set([\n 'spin_wheel', 'scratch_card', 'nps_survey', 'quiz',\n 'countdown_offer', 'star_rating', 'quick_poll',\n ]);\n\n if (campaign.sub_type && interactiveSubTypes.has(campaign.sub_type)) {\n this.renderInteractive(campaign);\n this.trackEvent(campaign.id, 'impression');\n return;\n }\n\n switch (campaign.type) {\n case 'modal':\n this.renderModal(campaign);\n break;\n case 'banner':\n this.renderBanner(campaign);\n break;\n case 'full_screen':\n this.renderFullScreen(campaign);\n break;\n case 'half_interstitial':\n this.renderHalfInterstitial(campaign);\n break;\n case 'alert':\n this.renderAlert(campaign);\n break;\n case 'pip':\n this.renderPIP(campaign);\n break;\n case 'tooltip':\n this.renderTooltip(campaign);\n break;\n }\n\n this.trackEvent(campaign.id, 'impression');\n }\n\n /**\n * Renders interactive sub-type campaigns (spin wheel, NPS, quiz, etc.)\n * using DOM-safe rendering. These sub-types use the campaign's\n * interactive_config payload for type-specific behavior.\n */\n private renderInteractive(campaign: InAppCampaign): void {\n const ic = (campaign.interactive_config || {}) as Record<string, unknown>;\n const bg = this.sanitizeColor(campaign.background_color || '#4169e1');\n const text = this.sanitizeColor(campaign.text_color || '#ffffff');\n\n switch (campaign.sub_type) {\n case 'nps_survey':\n this.renderNPSSurvey(campaign, ic, bg, text);\n break;\n case 'countdown_offer':\n this.renderCountdownOffer(campaign, ic, bg, text);\n break;\n case 'star_rating':\n this.renderStarRating(campaign, ic, bg, text);\n break;\n case 'quick_poll':\n this.renderQuickPoll(campaign, ic, bg, text);\n break;\n case 'quiz':\n this.renderQuiz(campaign, ic, bg, text);\n break;\n case 'spin_wheel':\n case 'scratch_card':\n // These are handled by AegisWidgetManager — emit event for bridge\n this.log(`${campaign.sub_type} delegated to AegisWidgetManager`);\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent('aegis:render-widget', {\n detail: { campaign, sub_type: campaign.sub_type },\n }));\n }\n break;\n default:\n this.log(`Unknown interactive sub_type: ${campaign.sub_type}`, 'warn');\n this.renderModal(campaign);\n }\n }\n\n // --- Interactive Renderers ---\n\n private renderNPSSurvey(\n campaign: InAppCampaign,\n ic: Record<string, unknown>,\n bg: string,\n text: string\n ): void {\n const overlay = this.createOverlay('aegis-in-app-nps-overlay');\n const modal = document.createElement('div');\n modal.style.cssText = `\n max-width: 360px; width: 90%; border-radius: 16px; overflow: hidden;\n background: ${bg}; color: ${text}; animation: aegisScaleIn 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.15);\n `;\n\n const body = document.createElement('div');\n body.style.cssText = 'padding: 24px; text-align: center;';\n\n const question = document.createElement('div');\n question.style.cssText = 'font-size: 16px; font-weight: 700; margin-bottom: 16px;';\n question.textContent = (ic.nps_question as string) || 'How likely are you to recommend us?';\n body.appendChild(question);\n\n const scale = document.createElement('div');\n scale.style.cssText = 'display: flex; gap: 4px; justify-content: center; flex-wrap: wrap; margin-bottom: 12px;';\n for (let i = 0; i <= 10; i++) {\n const btn = document.createElement('span');\n btn.style.cssText = `\n width: 28px; height: 28px; border-radius: 6px; display: flex;\n align-items: center; justify-content: center; font-size: 11px;\n font-weight: 600; cursor: pointer; background: ${text}33; color: ${text};\n transition: transform 0.1s;\n `;\n btn.textContent = String(i);\n btn.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n });\n scale.appendChild(btn);\n }\n body.appendChild(scale);\n\n const labels = document.createElement('div');\n labels.style.cssText = 'display: flex; justify-content: space-between; font-size: 11px; opacity: 0.6; margin-bottom: 16px;';\n const notLikely = document.createElement('span');\n notLikely.textContent = 'Not likely';\n const veryLikely = document.createElement('span');\n veryLikely.textContent = 'Very likely';\n labels.appendChild(notLikely);\n labels.appendChild(veryLikely);\n body.appendChild(labels);\n\n this.addCloseButton(body, overlay, campaign.id);\n modal.appendChild(body);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n\n private renderCountdownOffer(\n campaign: InAppCampaign,\n ic: Record<string, unknown>,\n bg: string,\n text: string\n ): void {\n const overlay = this.createOverlay('aegis-in-app-countdown-overlay');\n const modal = document.createElement('div');\n modal.style.cssText = `\n max-width: 320px; width: 90%; border-radius: 16px; overflow: hidden;\n background: ${bg}; color: ${text}; animation: aegisScaleIn 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.15);\n `;\n\n const body = document.createElement('div');\n body.style.cssText = 'padding: 24px; text-align: center;';\n\n const title = document.createElement('div');\n title.style.cssText = 'font-size: 20px; font-weight: 700; margin-bottom: 8px;';\n title.textContent = campaign.title || 'Flash Sale';\n body.appendChild(title);\n\n const label = document.createElement('div');\n label.style.cssText = 'font-size: 13px; opacity: 0.8; margin-bottom: 12px;';\n label.textContent = (ic.countdown_label as string) || 'Sale ends in:';\n body.appendChild(label);\n\n // Countdown digits\n const digits = document.createElement('div');\n digits.style.cssText = 'display: flex; gap: 8px; justify-content: center; margin-bottom: 16px;';\n const digitStyle = `padding: 8px 12px; border-radius: 8px; font-size: 24px; font-weight: 700; font-family: monospace; background: ${text}22;`;\n for (const val of ['00', ':', '00', ':', '00']) {\n const el = document.createElement('span');\n if (val === ':') {\n el.style.cssText = 'font-size: 24px; font-weight: 700; align-self: center;';\n } else {\n el.style.cssText = digitStyle;\n }\n el.textContent = val;\n digits.appendChild(el);\n }\n body.appendChild(digits);\n\n // Start countdown from target or 2h default\n const targetStr = ic.countdown_target as string | undefined;\n if (targetStr) {\n const target = new Date(targetStr).getTime();\n const update = () => {\n const diff = Math.max(0, target - Date.now());\n const h = String(Math.floor(diff / 3600000)).padStart(2, '0');\n const m = String(Math.floor((diff % 3600000) / 60000)).padStart(2, '0');\n const s = String(Math.floor((diff % 60000) / 1000)).padStart(2, '0');\n const spans = digits.querySelectorAll('span');\n if (spans.length >= 5) {\n spans[0].textContent = h;\n spans[2].textContent = m;\n spans[4].textContent = s;\n }\n if (diff > 0) requestAnimationFrame(update);\n };\n update();\n }\n\n if (campaign.body) {\n const desc = document.createElement('div');\n desc.style.cssText = 'font-size: 14px; opacity: 0.85; margin-bottom: 16px;';\n desc.textContent = campaign.body;\n body.appendChild(desc);\n }\n\n if (campaign.button_text) {\n const btn = this.createCTAButton(campaign, bg, text);\n body.appendChild(btn);\n }\n\n this.addCloseButton(body, overlay, campaign.id);\n modal.appendChild(body);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n\n private renderStarRating(\n campaign: InAppCampaign,\n ic: Record<string, unknown>,\n bg: string,\n text: string\n ): void {\n const overlay = this.createOverlay('aegis-in-app-rating-overlay');\n const modal = document.createElement('div');\n modal.style.cssText = `\n max-width: 320px; width: 90%; border-radius: 16px; overflow: hidden;\n background: ${bg}; color: ${text}; animation: aegisScaleIn 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.15);\n `;\n\n const body = document.createElement('div');\n body.style.cssText = 'padding: 24px; text-align: center;';\n\n const title = document.createElement('div');\n title.style.cssText = 'font-size: 18px; font-weight: 700; margin-bottom: 16px;';\n title.textContent = campaign.title || 'Rate your experience';\n body.appendChild(title);\n\n const stars = document.createElement('div');\n stars.style.cssText = 'display: flex; gap: 8px; justify-content: center; margin-bottom: 16px;';\n const maxStars = (ic.rating_scale as number) || 5;\n for (let i = 1; i <= maxStars; i++) {\n const star = document.createElement('span');\n star.style.cssText = 'font-size: 32px; cursor: pointer; transition: transform 0.1s;';\n star.textContent = '\\u2606'; // ☆\n star.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n });\n star.addEventListener('mouseenter', () => { star.style.transform = 'scale(1.2)'; });\n star.addEventListener('mouseleave', () => { star.style.transform = 'scale(1)'; });\n stars.appendChild(star);\n }\n body.appendChild(stars);\n\n this.addCloseButton(body, overlay, campaign.id);\n modal.appendChild(body);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n\n private renderQuickPoll(\n campaign: InAppCampaign,\n ic: Record<string, unknown>,\n bg: string,\n text: string\n ): void {\n const overlay = this.createOverlay('aegis-in-app-poll-overlay');\n const modal = document.createElement('div');\n modal.style.cssText = `\n max-width: 320px; width: 90%; border-radius: 16px; overflow: hidden;\n background: ${bg}; color: ${text}; animation: aegisScaleIn 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.15);\n `;\n\n const body = document.createElement('div');\n body.style.cssText = 'padding: 24px; text-align: center;';\n\n const title = document.createElement('div');\n title.style.cssText = 'font-size: 16px; font-weight: 700; margin-bottom: 16px;';\n title.textContent = campaign.title || 'Quick question';\n body.appendChild(title);\n\n const options = (ic.poll_options as string[]) || [];\n const optionsList = document.createElement('div');\n optionsList.style.cssText = 'display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px;';\n for (const opt of options) {\n const optBtn = document.createElement('button');\n optBtn.style.cssText = `\n padding: 10px 16px; border-radius: 10px; border: 1px solid ${text}33;\n background: transparent; color: ${text}; font-size: 14px; cursor: pointer;\n text-align: left; transition: background 0.15s;\n `;\n optBtn.textContent = opt;\n optBtn.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n });\n optionsList.appendChild(optBtn);\n }\n body.appendChild(optionsList);\n\n this.addCloseButton(body, overlay, campaign.id);\n modal.appendChild(body);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n\n private renderQuiz(\n campaign: InAppCampaign,\n ic: Record<string, unknown>,\n bg: string,\n text: string\n ): void {\n const overlay = this.createOverlay('aegis-in-app-quiz-overlay');\n const modal = document.createElement('div');\n modal.style.cssText = `\n max-width: 360px; width: 90%; border-radius: 16px; overflow: hidden;\n background: ${bg}; color: ${text}; animation: aegisScaleIn 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.15);\n `;\n\n const body = document.createElement('div');\n body.style.cssText = 'padding: 24px; text-align: center;';\n\n const title = document.createElement('div');\n title.style.cssText = 'font-size: 18px; font-weight: 700; margin-bottom: 8px;';\n title.textContent = campaign.title || 'Quiz';\n body.appendChild(title);\n\n const questions = (ic.questions as Array<{ question: string; options: string[] }>) || [];\n let currentQ = 0;\n\n const renderQuestion = () => {\n // Clear previous content except title\n while (body.childNodes.length > 1) {\n body.removeChild(body.lastChild!);\n }\n\n if (currentQ >= questions.length) {\n const result = document.createElement('div');\n result.style.cssText = 'font-size: 16px; margin: 16px 0;';\n result.textContent = (ic.thank_you_message as string) || 'Thanks for completing the quiz!';\n body.appendChild(result);\n this.trackEvent(campaign.id, 'clicked');\n this.addCloseButton(body, overlay, campaign.id);\n return;\n }\n\n const q = questions[currentQ];\n const progress = document.createElement('div');\n progress.style.cssText = 'font-size: 12px; opacity: 0.6; margin-bottom: 12px;';\n progress.textContent = `Question ${currentQ + 1} of ${questions.length}`;\n body.appendChild(progress);\n\n const questionText = document.createElement('div');\n questionText.style.cssText = 'font-size: 14px; font-weight: 600; margin-bottom: 16px;';\n questionText.textContent = q.question;\n body.appendChild(questionText);\n\n const optionsDiv = document.createElement('div');\n optionsDiv.style.cssText = 'display: flex; flex-direction: column; gap: 8px;';\n for (const opt of q.options) {\n const optBtn = document.createElement('button');\n optBtn.style.cssText = `\n padding: 10px 16px; border-radius: 10px; border: 1px solid ${text}33;\n background: transparent; color: ${text}; font-size: 14px; cursor: pointer;\n text-align: left; transition: background 0.15s;\n `;\n optBtn.textContent = opt;\n optBtn.addEventListener('click', () => {\n currentQ++;\n renderQuestion();\n });\n optionsDiv.appendChild(optBtn);\n }\n body.appendChild(optionsDiv);\n this.addCloseButton(body, overlay, campaign.id);\n };\n\n renderQuestion();\n modal.appendChild(body);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n\n // --- Shared Rendering Helpers ---\n\n private createOverlay(className: string): HTMLElement {\n const overlay = document.createElement('div');\n overlay.className = className;\n overlay.style.cssText = `\n position: fixed; top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0,0,0,0.5); display: flex; align-items: center;\n justify-content: center; z-index: 99999; animation: aegisFadeIn 0.3s ease;\n `;\n return overlay;\n }\n\n private createCTAButton(campaign: InAppCampaign, bg: string, text: string): HTMLElement {\n const btn = document.createElement('button');\n btn.style.cssText = `\n display: inline-block; padding: 10px 28px; border-radius: 999px;\n font-size: 14px; font-weight: 600; cursor: pointer; border: none;\n background: ${text}; color: ${bg}; transition: transform 0.15s;\n `;\n btn.textContent = campaign.button_text || 'OK';\n btn.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n if (campaign.action_url) {\n const safeUrl = this.sanitizeUrl(campaign.action_url);\n if (safeUrl) window.open(safeUrl, '_blank');\n }\n });\n return btn;\n }\n\n private addCloseButton(container: HTMLElement, overlay: HTMLElement, campaignId: string): void {\n const close = document.createElement('div');\n close.style.cssText = 'margin-top: 12px; font-size: 12px; opacity: 0.6; cursor: pointer;';\n close.textContent = 'Close';\n close.addEventListener('click', () => {\n this.trackEvent(campaignId, 'dismissed');\n this.removeModal(overlay);\n });\n container.appendChild(close);\n }\n \n private renderBanner(campaign: InAppCampaign): void {\n const banner = document.createElement('div');\n banner.className = 'aegis-in-app-banner';\n banner.setAttribute('data-campaign-id', campaign.id);\n \n banner.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n background: ${this.sanitizeColor(campaign.background_color || '#1a73e8')};\n color: ${this.sanitizeColor(campaign.text_color || '#ffffff')};\n padding: 16px;\n z-index: 999999;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisSlideDown 0.3s ease-out;\n `;\n \n const contentContainer = document.createElement('div');\n contentContainer.style.cssText = 'flex: 1; display: flex; align-items: center; gap: 12px;';\n \n if (campaign.image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(campaign.image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = '';\n img.style.cssText = 'width: 40px; height: 40px; border-radius: 4px; object-fit: cover;';\n contentContainer.appendChild(img);\n }\n }\n \n const textContainer = document.createElement('div');\n textContainer.style.cssText = 'flex: 1;';\n \n const title = document.createElement('div');\n title.textContent = campaign.title;\n title.style.cssText = 'font-weight: 600; font-size: 14px; margin-bottom: 4px;';\n textContainer.appendChild(title);\n \n const body = document.createElement('div');\n body.textContent = campaign.body;\n body.style.cssText = 'font-size: 13px; opacity: 0.9;';\n textContainer.appendChild(body);\n \n contentContainer.appendChild(textContainer);\n \n const actionsContainer = document.createElement('div');\n actionsContainer.style.cssText = 'display: flex; align-items: center; gap: 12px; margin-left: 16px;';\n \n if (campaign.action_url && campaign.button_text) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = campaign.button_text;\n ctaButton.style.cssText = `\n background: white;\n color: ${this.sanitizeColor(campaign.background_color || '#1a73e8')};\n border: none;\n padding: 8px 16px;\n border-radius: 4px;\n font-weight: 600;\n cursor: pointer;\n font-size: 13px;\n white-space: nowrap;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n const safeUrl = this.sanitizeUrl(campaign.action_url!);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n this.removeBanner(banner);\n });\n \n actionsContainer.appendChild(ctaButton);\n }\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '✕';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n background: transparent;\n border: none;\n color: inherit;\n font-size: 20px;\n cursor: pointer;\n padding: 0;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0.7;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'dismissed');\n this.removeBanner(banner);\n });\n \n actionsContainer.appendChild(closeButton);\n \n banner.appendChild(contentContainer);\n banner.appendChild(actionsContainer);\n \n this.addAnimationStyles();\n document.body.appendChild(banner);\n }\n \n private renderModal(campaign: InAppCampaign): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-in-app-modal-overlay';\n overlay.setAttribute('data-campaign-id', campaign.id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: aegisFadeIn 0.3s ease-out;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-in-app-modal';\n modal.style.cssText = `\n background: white;\n border-radius: 8px;\n max-width: 500px;\n width: 90%;\n max-height: 80vh;\n overflow: auto;\n box-shadow: 0 10px 40px rgba(0,0,0,0.2);\n animation: aegisScaleIn 0.3s ease-out;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n `;\n \n if (campaign.image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(campaign.image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = '';\n img.style.cssText = 'width: 100%; height: 200px; object-fit: cover; border-radius: 8px 8px 0 0;';\n modal.appendChild(img);\n }\n }\n \n const content = document.createElement('div');\n content.style.cssText = 'padding: 24px;';\n \n const title = document.createElement('h2');\n title.textContent = campaign.title;\n title.style.cssText = 'margin: 0 0 12px 0; font-size: 20px; font-weight: 600; color: #1a1a1a;';\n content.appendChild(title);\n \n const body = document.createElement('p');\n body.textContent = campaign.body;\n body.style.cssText = 'margin: 0 0 20px 0; font-size: 15px; line-height: 1.5; color: #4a4a4a;';\n content.appendChild(body);\n \n const actions = document.createElement('div');\n actions.style.cssText = 'display: flex; gap: 12px; justify-content: flex-end;';\n \n if (campaign.action_url && campaign.button_text) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = campaign.button_text;\n ctaButton.style.cssText = `\n background: ${this.sanitizeColor(campaign.background_color || '#1a73e8')};\n color: ${this.sanitizeColor(campaign.text_color || '#ffffff')};\n border: none;\n padding: 10px 24px;\n border-radius: 6px;\n font-weight: 600;\n cursor: pointer;\n font-size: 14px;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n const safeUrl = this.sanitizeUrl(campaign.action_url!);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n this.removeModal(overlay);\n });\n \n actions.appendChild(ctaButton);\n }\n \n const closeButton = document.createElement('button');\n closeButton.textContent = 'Close';\n closeButton.style.cssText = `\n background: transparent;\n border: 1px solid #d0d0d0;\n color: #4a4a4a;\n padding: 10px 24px;\n border-radius: 6px;\n font-weight: 600;\n cursor: pointer;\n font-size: 14px;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'dismissed');\n this.removeModal(overlay);\n });\n \n actions.appendChild(closeButton);\n \n content.appendChild(actions);\n modal.appendChild(content);\n overlay.appendChild(modal);\n \n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private renderFullScreen(campaign: InAppCampaign): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-in-app-fullscreen-overlay';\n overlay.setAttribute('data-campaign-id', campaign.id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: ${this.sanitizeColor(campaign.background_color || '#ffffff')};\n color: ${this.sanitizeColor(campaign.text_color || '#1a1a1a')};\n z-index: 1000001;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n animation: aegisFadeIn 0.3s ease-out;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n overflow-y: auto;\n `;\n \n if (campaign.image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(campaign.image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = '';\n img.style.cssText = 'max-width: 100%; max-height: 40vh; object-fit: contain; margin-bottom: 32px;';\n overlay.appendChild(img);\n }\n }\n \n const contentContainer = document.createElement('div');\n contentContainer.style.cssText = 'max-width: 600px; text-align: center;';\n \n const title = document.createElement('h1');\n title.textContent = campaign.title;\n title.style.cssText = 'margin: 0 0 16px 0; font-size: 32px; font-weight: 700;';\n contentContainer.appendChild(title);\n \n const body = document.createElement('p');\n body.textContent = campaign.body;\n body.style.cssText = 'margin: 0 0 32px 0; font-size: 18px; line-height: 1.6; opacity: 0.9;';\n contentContainer.appendChild(body);\n \n if (campaign.action_url && campaign.button_text) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = campaign.button_text;\n ctaButton.style.cssText = `\n background: ${this.sanitizeColor(campaign.text_color || '#1a73e8')};\n color: ${this.sanitizeColor(campaign.background_color || '#ffffff')};\n border: none;\n padding: 16px 48px;\n border-radius: 8px;\n font-weight: 700;\n font-size: 18px;\n cursor: pointer;\n margin-bottom: 16px;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n const safeUrl = this.sanitizeUrl(campaign.action_url!);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n this.removeModal(overlay);\n });\n \n contentContainer.appendChild(ctaButton);\n }\n \n overlay.appendChild(contentContainer);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '✕';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 20px;\n right: 20px;\n background: transparent;\n border: none;\n color: inherit;\n font-size: 32px;\n cursor: pointer;\n padding: 0;\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0.6;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'dismissed');\n this.removeModal(overlay);\n });\n \n overlay.appendChild(closeButton);\n \n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private renderHalfInterstitial(campaign: InAppCampaign): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-in-app-half-interstitial-overlay';\n overlay.setAttribute('data-campaign-id', campaign.id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 1000000;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n animation: aegisFadeIn 0.3s ease-out;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-in-app-half-interstitial';\n modal.style.cssText = `\n background: white;\n border-radius: 16px 16px 0 0;\n width: 100%;\n max-width: 600px;\n max-height: 60vh;\n overflow: auto;\n box-shadow: 0 -4px 20px rgba(0,0,0,0.2);\n animation: aegisSlideUp 0.3s ease-out;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n `;\n \n if (campaign.image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(campaign.image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = '';\n img.style.cssText = 'width: 100%; height: 200px; object-fit: cover;';\n modal.appendChild(img);\n }\n }\n \n const content = document.createElement('div');\n content.style.cssText = 'padding: 32px 24px;';\n \n const title = document.createElement('h2');\n title.textContent = campaign.title;\n title.style.cssText = 'margin: 0 0 12px 0; font-size: 24px; font-weight: 700; color: #1a1a1a;';\n content.appendChild(title);\n \n const body = document.createElement('p');\n body.textContent = campaign.body;\n body.style.cssText = 'margin: 0 0 24px 0; font-size: 16px; line-height: 1.5; color: #4a4a4a;';\n content.appendChild(body);\n \n if (campaign.action_url && campaign.button_text) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = campaign.button_text;\n ctaButton.style.cssText = `\n background: ${this.sanitizeColor(campaign.background_color || '#1a73e8')};\n color: ${this.sanitizeColor(campaign.text_color || '#ffffff')};\n border: none;\n padding: 14px 32px;\n border-radius: 8px;\n font-weight: 700;\n font-size: 16px;\n cursor: pointer;\n width: 100%;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n const safeUrl = this.sanitizeUrl(campaign.action_url!);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n this.removeModal(overlay);\n });\n \n content.appendChild(ctaButton);\n }\n \n modal.appendChild(content);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '✕';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 16px;\n right: 16px;\n background: rgba(255,255,255,0.9);\n border: none;\n color: #333;\n font-size: 24px;\n cursor: pointer;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 2px 8px rgba(0,0,0,0.2);\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'dismissed');\n this.removeModal(overlay);\n });\n \n modal.style.position = 'relative';\n modal.appendChild(closeButton);\n \n overlay.appendChild(modal);\n \n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private renderAlert(campaign: InAppCampaign): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-in-app-alert-overlay';\n overlay.setAttribute('data-campaign-id', campaign.id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.6);\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: aegisFadeIn 0.2s ease-out;\n `;\n \n const alert = document.createElement('div');\n alert.className = 'aegis-in-app-alert';\n alert.style.cssText = `\n background: white;\n border-radius: 12px;\n max-width: 320px;\n width: 85%;\n box-shadow: 0 10px 40px rgba(0,0,0,0.3);\n animation: aegisScaleIn 0.2s ease-out;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n overflow: hidden;\n `;\n \n const content = document.createElement('div');\n content.style.cssText = 'padding: 24px 20px; text-align: center;';\n \n const title = document.createElement('h3');\n title.textContent = campaign.title;\n title.style.cssText = 'margin: 0 0 8px 0; font-size: 18px; font-weight: 700; color: #1a1a1a;';\n content.appendChild(title);\n \n const body = document.createElement('p');\n body.textContent = campaign.body;\n body.style.cssText = 'margin: 0; font-size: 14px; line-height: 1.4; color: #666;';\n content.appendChild(body);\n \n alert.appendChild(content);\n \n const buttonContainer = document.createElement('div');\n buttonContainer.style.cssText = 'display: flex; border-top: 1px solid #e0e0e0;';\n \n if (campaign.action_url && campaign.button_text) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = campaign.button_text;\n ctaButton.style.cssText = `\n flex: 1;\n background: transparent;\n border: none;\n border-right: 1px solid #e0e0e0;\n color: #1a73e8;\n padding: 14px;\n font-weight: 600;\n font-size: 16px;\n cursor: pointer;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n const safeUrl = this.sanitizeUrl(campaign.action_url!);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n this.removeModal(overlay);\n });\n \n buttonContainer.appendChild(ctaButton);\n }\n \n const cancelButton = document.createElement('button');\n cancelButton.textContent = 'Cancel';\n cancelButton.style.cssText = `\n flex: 1;\n background: transparent;\n border: none;\n color: #666;\n padding: 14px;\n font-weight: 600;\n font-size: 16px;\n cursor: pointer;\n `;\n \n cancelButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'dismissed');\n this.removeModal(overlay);\n });\n \n buttonContainer.appendChild(cancelButton);\n \n alert.appendChild(buttonContainer);\n overlay.appendChild(alert);\n \n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private renderPIP(campaign: InAppCampaign): void {\n const pip = document.createElement('div');\n pip.className = 'aegis-in-app-pip';\n pip.setAttribute('data-campaign-id', campaign.id);\n \n pip.style.cssText = `\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 320px;\n background: black;\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 8px 24px rgba(0,0,0,0.3);\n z-index: 999999;\n animation: aegisSlideUp 0.3s ease-out;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n `;\n \n if (campaign.video_url) {\n const video = document.createElement('video');\n const safeUrl = this.sanitizeUrl(campaign.video_url);\n if (safeUrl) {\n video.src = safeUrl;\n video.controls = true;\n video.autoplay = true;\n video.muted = true;\n video.style.cssText = 'width: 100%; display: block;';\n pip.appendChild(video);\n }\n } else if (campaign.image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(campaign.image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = '';\n img.style.cssText = 'width: 100%; display: block;';\n pip.appendChild(img);\n }\n }\n \n const overlay = document.createElement('div');\n overlay.style.cssText = `\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: linear-gradient(to top, rgba(0,0,0,0.9), transparent);\n padding: 40px 16px 16px;\n color: white;\n `;\n \n const title = document.createElement('div');\n title.textContent = campaign.title;\n title.style.cssText = 'font-size: 14px; font-weight: 600; margin-bottom: 4px;';\n overlay.appendChild(title);\n \n const body = document.createElement('div');\n body.textContent = campaign.body;\n body.style.cssText = 'font-size: 12px; opacity: 0.9;';\n overlay.appendChild(body);\n \n pip.appendChild(overlay);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '✕';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 8px;\n right: 8px;\n background: rgba(0,0,0,0.6);\n border: none;\n color: white;\n font-size: 18px;\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'dismissed');\n pip.style.animation = 'aegisSlideDown 0.3s ease-out';\n setTimeout(() => {\n if (pip.parentNode) {\n pip.parentNode.removeChild(pip);\n }\n }, 300);\n });\n \n pip.appendChild(closeButton);\n \n if (campaign.action_url) {\n pip.style.cursor = 'pointer';\n pip.addEventListener('click', (e) => {\n if (e.target !== closeButton) {\n this.trackEvent(campaign.id, 'clicked');\n const safeUrl = this.sanitizeUrl(campaign.action_url!);\n if (safeUrl) {\n window.open(safeUrl, '_blank');\n }\n }\n });\n }\n \n this.addAnimationStyles();\n document.body.appendChild(pip);\n }\n \n private removeBanner(banner: HTMLElement): void {\n banner.style.animation = 'aegisSlideUp 0.3s ease-out';\n setTimeout(() => {\n if (banner.parentNode) {\n banner.parentNode.removeChild(banner);\n }\n }, 300);\n }\n \n private removeModal(overlay: HTMLElement): void {\n overlay.style.animation = 'aegisFadeOut 0.3s ease-out';\n setTimeout(() => {\n if (overlay.parentNode) {\n overlay.parentNode.removeChild(overlay);\n }\n }, 300);\n }\n \n private renderTooltip(campaign: InAppCampaign): void {\n const ic = (campaign.interactive_config || {}) as Record<string, unknown>;\n const anchorSelector = (ic.tooltip_anchor_selector as string) || '[data-aegis-tooltip]';\n const preferredPosition = (ic.tooltip_position as string) || 'bottom'; // top | bottom | left | right\n\n const anchor = document.querySelector(anchorSelector);\n if (!anchor) {\n this.log(`Tooltip anchor not found: ${anchorSelector}`, 'warn');\n return;\n }\n\n const bg = this.sanitizeColor(campaign.background_color || '#1a1a1a');\n const textColor = this.sanitizeColor(campaign.text_color || '#ffffff');\n\n // Tooltip container (positioned absolute to body)\n const tooltip = document.createElement('div');\n tooltip.className = 'aegis-in-app-tooltip';\n tooltip.setAttribute('data-campaign-id', campaign.id);\n tooltip.style.cssText = `\n position: absolute; z-index: 1000001; max-width: 280px; width: max-content;\n background: ${bg}; color: ${textColor}; border-radius: 10px; padding: 14px 16px;\n box-shadow: 0 8px 24px rgba(0,0,0,0.18); font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisScaleIn 0.2s ease-out; pointer-events: auto;\n `;\n\n // Arrow\n const arrow = document.createElement('div');\n arrow.className = 'aegis-tooltip-arrow';\n arrow.style.cssText = `\n position: absolute; width: 10px; height: 10px; background: ${bg};\n transform: rotate(45deg);\n `;\n\n // Close button\n const closeBtn = document.createElement('button');\n closeBtn.textContent = '\\u00d7';\n closeBtn.style.cssText = `\n position: absolute; top: 6px; right: 8px; background: none; border: none;\n color: ${textColor}; opacity: 0.6; font-size: 16px; cursor: pointer; padding: 0; line-height: 1;\n `;\n\n const dismiss = () => {\n tooltip.style.animation = 'aegisFadeOut 0.2s ease-out';\n setTimeout(() => { tooltip.parentNode?.removeChild(tooltip); }, 200);\n this.trackEvent(campaign.id, 'dismissed');\n };\n\n closeBtn.addEventListener('click', (e) => { e.stopPropagation(); dismiss(); });\n\n // Title\n if (campaign.title) {\n const title = document.createElement('div');\n title.textContent = campaign.title;\n title.style.cssText = 'font-size: 13px; font-weight: 700; margin-bottom: 4px; padding-right: 16px;';\n tooltip.appendChild(title);\n }\n\n // Body\n const body = document.createElement('div');\n body.textContent = campaign.body;\n body.style.cssText = 'font-size: 12px; line-height: 1.4; opacity: 0.9;';\n tooltip.appendChild(body);\n\n // CTA button\n if (campaign.button_text && campaign.action_url) {\n const cta = document.createElement('a');\n cta.textContent = campaign.button_text;\n cta.href = campaign.action_url;\n cta.style.cssText = `\n display: inline-block; margin-top: 8px; font-size: 12px; font-weight: 600;\n color: ${textColor}; text-decoration: underline; cursor: pointer;\n `;\n cta.addEventListener('click', () => { this.trackEvent(campaign.id, 'clicked'); });\n tooltip.appendChild(cta);\n }\n\n tooltip.appendChild(closeBtn);\n tooltip.appendChild(arrow);\n document.body.appendChild(tooltip);\n\n // Position relative to anchor\n const anchorRect = anchor.getBoundingClientRect();\n const tooltipRect = tooltip.getBoundingClientRect();\n const scrollX = window.scrollX;\n const scrollY = window.scrollY;\n const gap = 10;\n\n let top = 0;\n let left = 0;\n let arrowTop = '';\n let arrowLeft = '';\n let arrowBottom = '';\n let arrowRight = '';\n\n switch (preferredPosition) {\n case 'top':\n top = anchorRect.top + scrollY - tooltipRect.height - gap;\n left = anchorRect.left + scrollX + (anchorRect.width - tooltipRect.width) / 2;\n arrowBottom = '-5px';\n arrowLeft = `${tooltipRect.width / 2 - 5}px`;\n break;\n case 'left':\n top = anchorRect.top + scrollY + (anchorRect.height - tooltipRect.height) / 2;\n left = anchorRect.left + scrollX - tooltipRect.width - gap;\n arrowRight = '-5px';\n arrowTop = `${tooltipRect.height / 2 - 5}px`;\n break;\n case 'right':\n top = anchorRect.top + scrollY + (anchorRect.height - tooltipRect.height) / 2;\n left = anchorRect.right + scrollX + gap;\n arrowLeft = '-5px';\n arrowTop = `${tooltipRect.height / 2 - 5}px`;\n break;\n default: // bottom\n top = anchorRect.bottom + scrollY + gap;\n left = anchorRect.left + scrollX + (anchorRect.width - tooltipRect.width) / 2;\n arrowTop = '-5px';\n arrowLeft = `${tooltipRect.width / 2 - 5}px`;\n break;\n }\n\n // Clamp to viewport\n left = Math.max(8, Math.min(left, window.innerWidth + scrollX - tooltipRect.width - 8));\n top = Math.max(8, top);\n\n tooltip.style.top = `${top}px`;\n tooltip.style.left = `${left}px`;\n arrow.style.top = arrowTop || '';\n arrow.style.left = arrowLeft || '';\n arrow.style.bottom = arrowBottom || '';\n arrow.style.right = arrowRight || '';\n\n // Dismiss on outside click\n const outsideClickHandler = (e: MouseEvent) => {\n if (!tooltip.contains(e.target as Node) && !anchor.contains(e.target as Node)) {\n document.removeEventListener('click', outsideClickHandler);\n dismiss();\n }\n };\n setTimeout(() => document.addEventListener('click', outsideClickHandler), 100);\n }\n\n private addAnimationStyles(): void {\n if (document.getElementById('aegis-in-app-styles')) {\n return;\n }\n \n const style = document.createElement('style');\n style.id = 'aegis-in-app-styles';\n style.textContent = `\n @keyframes aegisSlideDown {\n from { transform: translateY(-100%); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n }\n \n @keyframes aegisSlideUp {\n from { transform: translateY(0); opacity: 1; }\n to { transform: translateY(-100%); opacity: 0; }\n }\n \n @keyframes aegisFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n \n @keyframes aegisFadeOut {\n from { opacity: 1; }\n to { opacity: 0; }\n }\n \n @keyframes aegisScaleIn {\n from { transform: scale(0.9); opacity: 0; }\n to { transform: scale(1); opacity: 1; }\n }\n `;\n \n document.head.appendChild(style);\n }\n \n private sanitizeUrl(url: string): string | null {\n try {\n const parsedUrl = new URL(url, window.location.origin);\n \n if (parsedUrl.protocol === 'javascript:' || parsedUrl.protocol === 'data:') {\n this.log(`Blocked unsafe URL: ${url}`, 'error');\n return null;\n }\n \n return parsedUrl.href;\n } catch (error) {\n this.log(`Invalid URL: ${url}`, 'error');\n return null;\n }\n }\n \n private sanitizeColor(color: string): string {\n if (/^#[0-9A-Fa-f]{3,6}$/.test(color)) {\n return color;\n }\n \n if (/^rgb\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*\\)$/.test(color)) {\n return color;\n }\n \n if (/^rgba\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*[\\d.]+\\s*\\)$/.test(color)) {\n return color;\n }\n \n const namedColors = ['white', 'black', 'red', 'green', 'blue', 'yellow', 'orange', 'purple', 'pink', 'gray', 'transparent'];\n if (namedColors.includes(color.toLowerCase())) {\n return color;\n }\n \n return '#000000';\n }\n \n /**\n * Track in-app event via the standard Event Ingress pipeline.\n *\n * Events flow: SDK → Event Ingress → Kafka → Governance Consumer\n * → Event Engine → ClickHouse (in_app_events + events_with_ttl)\n *\n * The event_type uses the canonical prefix `in_app.` so the event\n * switchboard maps it to the correct canonical form:\n * in_app.impression → engagement.view\n * in_app.clicked → engagement.click\n * in_app.dismissed → engagement.dismiss\n */\n private async trackEvent(campaignId: string, eventType: 'impression' | 'clicked' | 'dismissed'): Promise<void> {\n try {\n const url = `${this.apiHost}/api/v1/events`;\n const now = new Date().toISOString();\n const externalEventId = `inapp_${campaignId}_${eventType}_${Date.now()}`;\n\n const ingressEvent = {\n tenant_id: this.organizationId || 'unknown',\n source: 'in_app_sdk',\n external_event_id: externalEventId,\n event_type: `in_app.${eventType}`,\n timestamp: now,\n payload: {\n campaign_id: campaignId,\n event_type: eventType,\n user_id: this.userId,\n contact_id: this.contactId,\n platform: 'web',\n variant_id: this.getVariantId(campaignId) ?? undefined,\n },\n trace_id: externalEventId,\n metadata: {\n write_key: this.writeKey,\n },\n };\n\n fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Aegis-Write-Key': this.writeKey,\n },\n body: JSON.stringify(ingressEvent),\n }).catch(error => {\n this.log(`Error tracking event: ${error}`, 'error');\n });\n\n this.log(`Tracked ${eventType} event for campaign ${campaignId}`);\n } catch (error) {\n this.log(`Error tracking event: ${error}`, 'error');\n }\n }\n \n private log(message: string, level: 'log' | 'warn' | 'error' = 'log'): void {\n if (this.debugMode) {\n console[level](`[AegisInApp] ${message}`);\n }\n }\n \n destroy(options?: { clearABState?: boolean }): void {\n this.disconnectSSE();\n\n document.querySelectorAll(\n '.aegis-in-app-banner, .aegis-in-app-modal-overlay, .aegis-in-app-fullscreen-overlay, ' +\n '.aegis-in-app-half-interstitial-overlay, .aegis-in-app-alert-overlay, .aegis-in-app-pip, ' +\n '.aegis-in-app-nps-overlay, .aegis-in-app-countdown-overlay, .aegis-in-app-rating-overlay, ' +\n '.aegis-in-app-poll-overlay, .aegis-in-app-quiz-overlay'\n ).forEach(el => {\n if (el.parentNode) {\n el.parentNode.removeChild(el);\n }\n });\n\n const styles = document.getElementById('aegis-in-app-styles');\n if (styles && styles.parentNode) {\n styles.parentNode.removeChild(styles);\n }\n\n // Optionally clear A/B assignment state\n if (options?.clearABState && typeof localStorage !== 'undefined') {\n localStorage.removeItem('aegis_ab_assignments');\n }\n\n this.isInitialized = false;\n this.log('AegisInApp destroyed');\n }\n}\n","/**\n * renderPreview — Static Preview Renderer for Dashboard iframe (Critical Fix A)\n *\n * Used exclusively by the sandboxed iframe preview route\n * (`/api/preview/in-app/route.tsx`). Renders a single campaign into the\n * current document body using the same rendering logic as the production SDK.\n *\n * Data flow:\n * editor-sidebar.tsx → onChange → formState → postMessage({type:'preview_update', config})\n * → iframe receives message → calls renderPreview(config)\n *\n * This ensures 100% fidelity between the dashboard editor preview and\n * production rendering — both use the same SDK code.\n */\n\nimport type { InAppCampaign } from './AegisInAppManager';\nimport { AegisInAppManager } from './AegisInAppManager';\n\n/**\n * Renders a single in-app campaign into the current document for preview.\n *\n * Creates a temporary AegisInAppManager with preview-only config (no tracking,\n * no SSE, no network requests). Calls the same rendering pipeline as production.\n */\nexport function renderPreview(config: InAppCampaign & { interactive_config?: Record<string, unknown> }): void {\n // Clear previous preview\n document.querySelectorAll(\n '[class^=\"aegis-in-app-\"]'\n ).forEach((el) => {\n if (el.parentNode) {\n el.parentNode.removeChild(el);\n }\n });\n\n if (!config) return;\n\n // Create a lightweight preview-only manager\n const manager = new AegisInAppManager({\n writeKey: 'preview-mode',\n apiHost: '',\n debugMode: false,\n enableSSE: false,\n });\n\n // Override trackEvent to be a no-op in preview mode\n // Access private via any cast — preview only, not production code\n const m = manager as unknown as {\n displayCampaign: (campaign: InAppCampaign) => void;\n trackEvent: (campaignId: string, eventType: string) => Promise<void>;\n addAnimationStyles: () => void;\n };\n\n // No-op tracking for preview\n m.trackEvent = async () => {};\n\n // Ensure animation styles are injected\n m.addAnimationStyles();\n\n // Render the campaign\n m.displayCampaign(config);\n}\n","/**\n * AegisPlacementManager - Web SDK Placement Module\n * \n * Real-time SSE architecture for inline content placements.\n * \n * Security:\n * - XSS Protection: Uses DOM APIs (createElement, textContent) instead of innerHTML\n * - URL Validation: Prevents javascript: protocol injection\n * - CSP Compatible: No inline styles in HTML strings\n * \n * Architecture:\n * - Connects to SSE endpoint for real-time placement updates\n * - Initial fetch on load, then SSE for updates\n * - Caches placement content locally in memory\n * - Renders content into pre-defined UI slots (inline, not overlay)\n * - Tracks events (impression, click, conversion) asynchronously\n * \n * Key Differences from In-App Messages:\n * - INLINE content (part of layout), not overlays\n * - Content rendered immediately on slot registration\n * - No trigger rules (shown when slot loads)\n * - Supports banner, card, carousel, video, HTML content types\n */\n\nexport interface PlacementContent {\n placement_id: string;\n variant_id: string;\n content_type: 'banner' | 'card' | 'carousel' | 'video' | 'html' | 'dynamic_injection';\n content: Record<string, any>;\n css_selector?: string;\n injection_mode?: 'replace' | 'append' | 'prepend';\n}\n\nexport interface PlacementSlot {\n placementId: string;\n containerId: string;\n fallbackContent?: string;\n onRender?: (content: PlacementContent) => void;\n onError?: (error: Error) => void;\n}\n\nexport interface AegisPlacementConfig {\n writeKey: string;\n apiHost?: string;\n userId?: string;\n contactId?: string;\n organizationId?: string;\n debugMode?: boolean;\n enableSSE?: boolean;\n}\n\nexport class AegisPlacementManager {\n private writeKey: string;\n private apiHost: string;\n private userId?: string;\n private contactId?: string;\n private organizationId?: string;\n private debugMode: boolean;\n private enableSSE: boolean;\n \n private placements: Map<string, PlacementContent> = new Map();\n private slots: Map<string, PlacementSlot> = new Map();\n private renderedSlots = new Set<string>();\n private eventSource?: EventSource;\n private isInitialized = false;\n private reconnectAttempts = 0;\n private maxReconnectAttempts = 5;\n \n constructor(config: AegisPlacementConfig) {\n this.writeKey = config.writeKey;\n this.apiHost = config.apiHost || 'https://api.aegis.ai';\n this.userId = config.userId;\n this.contactId = config.contactId;\n this.organizationId = config.organizationId;\n this.debugMode = config.debugMode || false;\n this.enableSSE = config.enableSSE !== false;\n }\n \n async initialize(): Promise<void> {\n if (this.isInitialized) {\n this.log('AegisPlacements already initialized');\n return;\n }\n \n await this.refreshPlacements();\n \n if (this.enableSSE && this.organizationId) {\n this.connectSSE();\n }\n \n this.isInitialized = true;\n this.log('AegisPlacements initialized successfully');\n }\n \n register(placementId: string, options: Omit<PlacementSlot, 'placementId'>): void {\n const slot: PlacementSlot = {\n placementId,\n ...options\n };\n \n this.slots.set(placementId, slot);\n this.log(`Registered placement slot: ${placementId}`);\n \n const existingContent = this.placements.get(placementId);\n if (existingContent) {\n this.renderSlot(slot, existingContent);\n } else if (options.fallbackContent) {\n this.renderFallback(slot);\n }\n }\n \n unregister(placementId: string): void {\n this.slots.delete(placementId);\n this.renderedSlots.delete(placementId);\n this.log(`Unregistered placement slot: ${placementId}`);\n }\n \n async refreshPlacements(): Promise<void> {\n try {\n const placementIds = Array.from(this.slots.keys());\n \n if (placementIds.length === 0) {\n this.log('No registered slots, skipping refresh');\n return;\n }\n \n const url = `${this.apiHost}/v1/placements/content?placement_ids=${placementIds.join(',')}`;\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'X-Device-Type': this.getDeviceType(),\n 'X-Platform': 'web'\n };\n \n if (this.userId) headers['X-User-ID'] = this.userId;\n if (this.contactId) headers['X-Contact-ID'] = this.contactId;\n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n \n const response = await fetch(url, { headers });\n \n if (!response.ok) {\n throw new Error(`Failed to fetch placements: ${response.status}`);\n }\n \n const data = await response.json();\n \n this.placements.clear();\n \n for (const placement of data.placements || []) {\n this.placements.set(placement.placement_id, placement);\n }\n \n this.renderAllSlots();\n \n this.log(`Refreshed ${this.placements.size} placements`);\n \n } catch (error) {\n this.log(`Error refreshing placements: ${error}`, true);\n }\n }\n \n private renderAllSlots(): void {\n for (const [placementId, slot] of this.slots.entries()) {\n const content = this.placements.get(placementId);\n \n if (content) {\n this.renderSlot(slot, content);\n } else if (slot.fallbackContent) {\n this.renderFallback(slot);\n }\n }\n }\n \n private renderSlot(slot: PlacementSlot, content: PlacementContent): void {\n try {\n if (content.content_type === 'dynamic_injection') {\n this.renderDynamicInjection(content);\n } else {\n const container = document.getElementById(slot.containerId);\n \n if (!container) {\n this.log(`Container not found: ${slot.containerId}`, true);\n return;\n }\n \n container.innerHTML = '';\n \n switch (content.content_type) {\n case 'banner':\n this.renderBanner(container, content);\n break;\n case 'card':\n this.renderCard(container, content);\n break;\n case 'carousel':\n this.renderCarousel(container, content);\n break;\n case 'video':\n this.renderVideo(container, content);\n break;\n case 'html':\n this.renderHTML(container, content);\n break;\n default:\n this.log(`Unknown content type: ${content.content_type}`, true);\n return;\n }\n }\n \n if (!this.renderedSlots.has(slot.placementId)) {\n this.trackEvent(content.placement_id, content.variant_id, 'impression');\n this.renderedSlots.add(slot.placementId);\n }\n \n if (slot.onRender) {\n slot.onRender(content);\n }\n \n this.log(`Rendered placement: ${content.placement_id} (${content.content_type})`);\n \n } catch (error) {\n this.log(`Error rendering placement: ${error}`, true);\n \n if (slot.onError) {\n slot.onError(error as Error);\n }\n }\n }\n \n private renderBanner(container: HTMLElement, content: PlacementContent): void {\n const { title, body, image_url, cta_text, cta_url, background_color, text_color } = content.content;\n \n const banner = document.createElement('div');\n banner.className = 'aegis-placement-banner';\n banner.style.cssText = `\n background: ${this.sanitizeColor(background_color || '#1a73e8')};\n color: ${this.sanitizeColor(text_color || '#ffffff')};\n padding: 24px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n gap: 16px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n `;\n \n if (image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = '';\n img.style.cssText = 'width: 80px; height: 80px; border-radius: 8px; object-fit: cover;';\n banner.appendChild(img);\n }\n }\n \n const textContainer = document.createElement('div');\n textContainer.style.cssText = 'flex: 1;';\n \n if (title) {\n const titleEl = document.createElement('div');\n titleEl.textContent = title;\n titleEl.style.cssText = 'font-size: 18px; font-weight: 600; margin-bottom: 8px;';\n textContainer.appendChild(titleEl);\n }\n \n if (body) {\n const bodyEl = document.createElement('div');\n bodyEl.textContent = body;\n bodyEl.style.cssText = 'font-size: 14px; opacity: 0.9;';\n textContainer.appendChild(bodyEl);\n }\n \n banner.appendChild(textContainer);\n \n if (cta_text && cta_url) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = cta_text;\n ctaButton.style.cssText = `\n background: white;\n color: ${this.sanitizeColor(background_color || '#1a73e8')};\n border: none;\n padding: 12px 24px;\n border-radius: 6px;\n font-weight: 600;\n cursor: pointer;\n font-size: 14px;\n white-space: nowrap;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(content.placement_id, content.variant_id, 'click');\n const safeUrl = this.sanitizeUrl(cta_url);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n });\n \n banner.appendChild(ctaButton);\n }\n \n container.appendChild(banner);\n }\n \n private renderCard(container: HTMLElement, content: PlacementContent): void {\n const { title, body, image_url, cta_text, cta_url } = content.content;\n \n const card = document.createElement('div');\n card.className = 'aegis-placement-card';\n card.style.cssText = `\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n overflow: hidden;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n `;\n \n if (image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = title || '';\n img.style.cssText = 'width: 100%; height: 200px; object-fit: cover;';\n card.appendChild(img);\n }\n }\n \n const cardBody = document.createElement('div');\n cardBody.style.cssText = 'padding: 20px;';\n \n if (title) {\n const titleEl = document.createElement('h3');\n titleEl.textContent = title;\n titleEl.style.cssText = 'margin: 0 0 12px 0; font-size: 20px; font-weight: 600; color: #1a1a1a;';\n cardBody.appendChild(titleEl);\n }\n \n if (body) {\n const bodyEl = document.createElement('p');\n bodyEl.textContent = body;\n bodyEl.style.cssText = 'margin: 0 0 16px 0; font-size: 14px; color: #666; line-height: 1.5;';\n cardBody.appendChild(bodyEl);\n }\n \n if (cta_text && cta_url) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = cta_text;\n ctaButton.style.cssText = `\n background: #1a73e8;\n color: white;\n border: none;\n padding: 10px 20px;\n border-radius: 6px;\n font-weight: 600;\n cursor: pointer;\n font-size: 14px;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(content.placement_id, content.variant_id, 'click');\n const safeUrl = this.sanitizeUrl(cta_url);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n });\n \n cardBody.appendChild(ctaButton);\n }\n \n card.appendChild(cardBody);\n container.appendChild(card);\n }\n \n private renderCarousel(container: HTMLElement, content: PlacementContent): void {\n const { items } = content.content;\n \n if (!Array.isArray(items) || items.length === 0) {\n this.log('Carousel items empty or invalid', true);\n return;\n }\n \n const carousel = document.createElement('div');\n carousel.className = 'aegis-placement-carousel';\n carousel.style.cssText = `\n display: flex;\n gap: 16px;\n overflow-x: auto;\n padding: 8px 0;\n scroll-behavior: smooth;\n -webkit-overflow-scrolling: touch;\n `;\n \n for (const item of items) {\n const carouselItem = document.createElement('div');\n carouselItem.style.cssText = `\n flex: 0 0 250px;\n background: white;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n overflow: hidden;\n cursor: pointer;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n `;\n \n if (item.image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(item.image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = item.title || '';\n img.style.cssText = 'width: 100%; height: 150px; object-fit: cover;';\n carouselItem.appendChild(img);\n }\n }\n \n const itemContent = document.createElement('div');\n itemContent.style.cssText = 'padding: 12px;';\n \n if (item.title) {\n const title = document.createElement('div');\n title.textContent = item.title;\n title.style.cssText = 'font-size: 14px; font-weight: 600; margin-bottom: 4px; color: #1a1a1a;';\n itemContent.appendChild(title);\n }\n \n if (item.price) {\n const price = document.createElement('div');\n price.textContent = item.price;\n price.style.cssText = 'font-size: 16px; font-weight: 700; color: #1a73e8;';\n itemContent.appendChild(price);\n }\n \n carouselItem.appendChild(itemContent);\n \n if (item.url) {\n carouselItem.addEventListener('click', () => {\n this.trackEvent(content.placement_id, content.variant_id, 'click', { item_index: items.indexOf(item) });\n const safeUrl = this.sanitizeUrl(item.url);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n });\n }\n \n carousel.appendChild(carouselItem);\n }\n \n container.appendChild(carousel);\n }\n \n private renderVideo(container: HTMLElement, content: PlacementContent): void {\n const { video_url, poster_url, autoplay, muted } = content.content;\n \n if (!video_url) {\n this.log('Video URL missing', true);\n return;\n }\n \n const safeVideoUrl = this.sanitizeUrl(video_url);\n if (!safeVideoUrl) {\n this.log('Invalid video URL', true);\n return;\n }\n \n const video = document.createElement('video');\n video.src = safeVideoUrl;\n video.controls = true;\n video.autoplay = autoplay || false;\n video.muted = muted || false;\n video.style.cssText = 'width: 100%; border-radius: 8px;';\n \n if (poster_url) {\n const safePosterUrl = this.sanitizeUrl(poster_url);\n if (safePosterUrl) {\n video.poster = safePosterUrl;\n }\n }\n \n video.addEventListener('play', () => {\n this.trackEvent(content.placement_id, content.variant_id, 'click', { action: 'video_play' });\n });\n \n container.appendChild(video);\n }\n \n private renderHTML(container: HTMLElement, content: PlacementContent): void {\n const { html } = content.content;\n \n if (!html) {\n this.log('HTML content missing', true);\n return;\n }\n \n const wrapper = document.createElement('div');\n wrapper.className = 'aegis-placement-html';\n wrapper.innerHTML = this.sanitizeHTML(html);\n \n const links = wrapper.querySelectorAll('a');\n links.forEach((link) => {\n link.addEventListener('click', (e) => {\n this.trackEvent(content.placement_id, content.variant_id, 'click');\n });\n });\n \n container.appendChild(wrapper);\n }\n \n private renderDynamicInjection(content: PlacementContent): void {\n const { html } = content.content;\n const cssSelector = content.css_selector;\n const injectionMode = content.injection_mode || 'replace';\n \n if (!cssSelector) {\n this.log('CSS selector missing for dynamic injection', true);\n return;\n }\n \n if (!html) {\n this.log('HTML content missing for dynamic injection', true);\n return;\n }\n \n let targetElement: HTMLElement | null = null;\n \n try {\n targetElement = document.querySelector(cssSelector);\n } catch (error) {\n this.log(`Invalid CSS selector: ${cssSelector}`, true);\n return;\n }\n \n if (!targetElement) {\n this.log(`Target element not found for selector: ${cssSelector}`, true);\n return;\n }\n \n const wrapper = document.createElement('div');\n wrapper.className = 'aegis-dynamic-injection';\n wrapper.setAttribute('data-placement-id', content.placement_id);\n wrapper.setAttribute('data-variant-id', content.variant_id);\n wrapper.innerHTML = this.sanitizeHTML(html);\n \n const links = wrapper.querySelectorAll('a');\n links.forEach((link) => {\n link.addEventListener('click', () => {\n this.trackEvent(content.placement_id, content.variant_id, 'click');\n });\n });\n \n switch (injectionMode) {\n case 'replace':\n targetElement.innerHTML = '';\n targetElement.appendChild(wrapper);\n this.log(`Replaced content in ${cssSelector}`, false);\n break;\n \n case 'append':\n targetElement.appendChild(wrapper);\n this.log(`Appended content to ${cssSelector}`, false);\n break;\n \n case 'prepend':\n targetElement.insertBefore(wrapper, targetElement.firstChild);\n this.log(`Prepended content to ${cssSelector}`, false);\n break;\n \n default:\n this.log(`Unknown injection mode: ${injectionMode}`, true);\n return;\n }\n \n this.log(`Dynamically injected content for ${content.placement_id} into ${cssSelector} (${injectionMode})`);\n }\n \n private renderFallback(slot: PlacementSlot): void {\n if (!slot.fallbackContent) return;\n \n const container = document.getElementById(slot.containerId);\n if (!container) return;\n \n container.innerHTML = slot.fallbackContent;\n this.log(`Rendered fallback content for: ${slot.placementId}`);\n }\n \n private async trackEvent(\n placementId: string,\n variantId: string,\n eventType: 'impression' | 'click' | 'conversion',\n metadata: Record<string, any> = {}\n ): Promise<void> {\n try {\n const url = `${this.apiHost}/v1/placements/track`;\n \n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Aegis-Write-Key': this.writeKey,\n 'X-Device-Type': this.getDeviceType(),\n 'X-Platform': 'web'\n };\n \n if (this.userId) headers['X-User-ID'] = this.userId;\n if (this.contactId) headers['X-Contact-ID'] = this.contactId;\n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n \n const body = {\n placement_id: placementId,\n variant_id: variantId,\n event_type: eventType,\n metadata: {\n device_type: this.getDeviceType(),\n platform: 'web',\n ...metadata\n }\n };\n \n fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n }).catch(err => this.log(`Track event failed: ${err}`, true));\n \n this.log(`Tracked ${eventType}: ${placementId}`);\n \n } catch (error) {\n this.log(`Error tracking event: ${error}`, true);\n }\n }\n \n private connectSSE(): void {\n if (this.eventSource) {\n this.disconnectSSE();\n }\n \n if (!this.organizationId) {\n this.log('Cannot connect SSE without organization ID', true);\n return;\n }\n \n const url = new URL('/v1/stream/realtime', this.apiHost);\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'X-Organization-ID': this.organizationId,\n };\n \n if (this.contactId) {\n headers['X-Contact-ID'] = this.contactId;\n }\n \n const queryParams = new URLSearchParams();\n Object.entries(headers).forEach(([key, value]) => {\n queryParams.append(key, value);\n });\n \n this.eventSource = new EventSource(`${url}?${queryParams.toString()}`);\n \n this.eventSource.addEventListener('open', () => {\n this.log('SSE connection established');\n this.reconnectAttempts = 0;\n });\n \n this.eventSource.addEventListener('placement_content_updated', (event: MessageEvent) => {\n try {\n const data = JSON.parse(event.data);\n this.log(`Received placement content update: ${data.placement_id}`);\n this.refreshPlacements();\n } catch (error) {\n this.log(`Error parsing SSE event: ${error}`, true);\n }\n });\n \n this.eventSource.addEventListener('heartbeat', (event: MessageEvent) => {\n this.log('SSE heartbeat received');\n });\n \n this.eventSource.addEventListener('error', (error) => {\n this.log('SSE connection error', true);\n \n if (this.eventSource?.readyState === EventSource.CLOSED) {\n this.attemptReconnect();\n }\n });\n }\n \n private disconnectSSE(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = undefined;\n this.log('SSE connection closed');\n }\n }\n \n private attemptReconnect(): void {\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n this.log('Max reconnect attempts reached, giving up', true);\n return;\n }\n \n this.reconnectAttempts++;\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);\n \n this.log(`Reconnecting SSE in ${delay}ms (attempt ${this.reconnectAttempts})`);\n \n setTimeout(() => {\n if (this.isInitialized && this.enableSSE && this.organizationId) {\n this.connectSSE();\n }\n }, delay);\n }\n \n private getDeviceType(): string {\n const width = window.innerWidth;\n if (width < 768) return 'mobile_web';\n if (width < 1024) return 'tablet_web';\n return 'desktop_web';\n }\n \n private sanitizeUrl(url: string): string | null {\n try {\n const parsed = new URL(url, window.location.href);\n \n if (parsed.protocol === 'javascript:' || parsed.protocol === 'data:') {\n this.log(`Blocked unsafe URL protocol: ${parsed.protocol}`, true);\n return null;\n }\n \n return parsed.href;\n } catch {\n this.log(`Invalid URL: ${url}`, true);\n return null;\n }\n }\n \n private sanitizeColor(color: string): string {\n const hexPattern = /^#[0-9A-Fa-f]{3,6}$/;\n const rgbPattern = /^rgba?\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*(,\\s*[\\d.]+\\s*)?\\)$/;\n const namedColors = ['white', 'black', 'red', 'blue', 'green', 'yellow', 'transparent'];\n \n if (hexPattern.test(color) || rgbPattern.test(color) || namedColors.includes(color.toLowerCase())) {\n return color;\n }\n \n this.log(`Invalid color: ${color}`, true);\n return '#000000';\n }\n \n private sanitizeHTML(html: string): string {\n const tempDiv = document.createElement('div');\n tempDiv.textContent = html;\n return tempDiv.innerHTML;\n }\n \n private log(message: string, isError = false): void {\n if (this.debugMode || isError) {\n console[isError ? 'error' : 'log'](`[AegisPlacements] ${message}`);\n }\n }\n \n destroy(): void {\n this.disconnectSSE();\n this.slots.clear();\n this.placements.clear();\n this.renderedSlots.clear();\n this.isInitialized = false;\n this.log('AegisPlacements destroyed');\n }\n}\n","/**\n * AegisWidgetManager - Web SDK Widget Module\n * \n * Smart Pull architecture for persistent web widgets.\n * \n * Features:\n * - Gamification (spin wheel, scratch card) with server-side prize generation\n * - Chat bubbles (WhatsApp, support)\n * - Social proof toasts (real-time purchase notifications)\n * - Feedback forms (NPS, surveys)\n * \n * Security:\n * - XSS Protection: Uses DOM APIs instead of innerHTML\n * - Server-side prize generation prevents client manipulation\n * - URL validation prevents javascript: protocol injection\n * \n * Architecture:\n * - Fetches widget configs from /v1/widgets/config on page load\n * - Integrates with TriggerEngine for behavioral triggers\n * - Tracks widget events (show, click, dismiss, submit)\n * - Server-side prize generation for gamification\n */\n\nimport { TriggerEngine } from '../triggers/TriggerEngine';\n\nexport interface WidgetConfig {\n widget_id: string;\n widget_type: 'chat_bubble' | 'spin_wheel' | 'scratch_card' | 'toast' | 'feedback_form' | 'exit_intent_popup';\n name: string;\n config: Record<string, any>;\n position?: string;\n priority: number;\n trigger_rules?: {\n type: 'exit_intent' | 'scroll_depth' | 'time_on_page' | 'immediate';\n config?: Record<string, any>;\n };\n}\n\nexport interface GamificationPrize {\n prize_label: string;\n prize_value?: string;\n coupon_code?: string;\n play_id: string;\n}\n\nexport interface AegisWidgetConfig {\n writeKey: string;\n apiHost?: string;\n userId?: string;\n contactId?: string;\n organizationId?: string;\n debugMode?: boolean;\n triggerEngine?: TriggerEngine;\n enablePrefetch?: boolean;\n cssCustomization?: WidgetCSSCustomization;\n onEvent?: (eventType: string, data: any) => void;\n /** Source platform passed as X-Source-Platform header so the API\n * can filter campaigns whose display_rules.sources restricts them\n * to specific integrations (e.g. 'shopify', 'woocommerce'). */\n sourcePlatform?: 'web' | 'shopify' | 'woocommerce' | 'mobile_sdk';\n}\n\nexport interface WidgetCSSCustomization {\n exitIntent?: {\n backgroundColor?: string;\n textColor?: string;\n accentColor?: string;\n borderRadius?: string;\n fontFamily?: string;\n overlayOpacity?: number;\n };\n spinWheel?: {\n backgroundColor?: string;\n textColor?: string;\n accentColor?: string;\n borderRadius?: string;\n fontFamily?: string;\n wheelColors?: string[];\n buttonColor?: string;\n };\n chatBubble?: {\n backgroundColor?: string;\n textColor?: string;\n position?: 'bottom_right' | 'bottom_left' | 'top_right' | 'top_left';\n size?: 'small' | 'medium' | 'large';\n };\n}\n\nexport interface PrefetchWidgetConfig {\n exit_intent?: {\n enabled: boolean;\n type: 'cart_recovery' | 'lead_gen';\n tier?: string;\n title?: string;\n message?: string;\n discount_code?: string;\n discount_percentage?: number;\n cta_text?: string;\n cta_url?: string;\n background_color?: string;\n text_color?: string;\n accent_color?: string;\n show_cart_items?: boolean;\n show_timer?: boolean;\n timer_minutes?: number;\n priority: number;\n mobile_triggers?: {\n scroll_velocity?: boolean;\n scroll_threshold?: number;\n scroll_min_position?: number;\n scroll_cooldown?: number;\n idle_timer?: boolean;\n idle_seconds?: number;\n visibility_change?: boolean;\n back_button?: boolean;\n };\n };\n spin_wheel?: {\n enabled: boolean;\n type: 'lead_gen' | 'cart_recovery';\n title?: string;\n prizes?: any[];\n priority: number;\n };\n}\n\nexport interface CartData {\n cart_id: string;\n cart_total: number;\n cart_currency: string;\n cart_items: Array<{\n product_id: string;\n product_name?: string;\n quantity: number;\n price?: number;\n }>;\n}\n\nexport class AegisWidgetManager {\n private writeKey: string;\n private apiHost: string;\n private userId?: string;\n private contactId?: string;\n private organizationId?: string;\n private debugMode: boolean;\n private triggerEngine?: TriggerEngine;\n private enablePrefetch: boolean;\n private cssCustomization: WidgetCSSCustomization;\n private onEvent?: (eventType: string, data: any) => void;\n private sourcePlatform?: string;\n\n private widgets: WidgetConfig[] = [];\n private renderedWidgets = new Set<string>();\n private isInitialized = false;\n \n private prefetchWidgetConfigs: PrefetchWidgetConfig = {};\n private cartData?: CartData;\n \n constructor(config: AegisWidgetConfig) {\n this.writeKey = config.writeKey;\n this.apiHost = config.apiHost || 'https://api.aegis.ai';\n this.userId = config.userId;\n this.contactId = config.contactId;\n this.organizationId = config.organizationId;\n this.debugMode = config.debugMode || false;\n this.triggerEngine = config.triggerEngine;\n this.enablePrefetch = config.enablePrefetch !== false;\n this.cssCustomization = config.cssCustomization || {};\n this.onEvent = config.onEvent;\n this.sourcePlatform = config.sourcePlatform;\n }\n \n updateCSSCustomization(customization: WidgetCSSCustomization): void {\n this.cssCustomization = { ...this.cssCustomization, ...customization };\n this.log('CSS customization updated');\n }\n \n private emitEvent(eventType: string, data: any): void {\n if (this.onEvent) {\n try {\n this.onEvent(eventType, data);\n } catch (error) {\n this.log(`Error in event callback: ${error}`, true);\n }\n }\n }\n \n async initialize(): Promise<void> {\n if (this.isInitialized) {\n this.log('AegisWidgets already initialized');\n return;\n }\n \n if (this.enablePrefetch && this.contactId) {\n await this.fetchPrefetchConfigs();\n this.preloadWidgetAssets();\n }\n \n await this.fetchWidgets();\n \n this.renderImmediateWidgets();\n \n this.setupTriggerListeners();\n \n this.setupExitIntentWithPrefetch();\n \n this.isInitialized = true;\n this.log('AegisWidgets initialized successfully');\n }\n \n setCartData(cartData: CartData): void {\n this.cartData = cartData;\n this.log(`Cart data updated: ${cartData.cart_items.length} items, total: ${cartData.cart_currency} ${cartData.cart_total}`);\n }\n \n private detectPlatformCart(): CartData | null {\n const shopifyCart = this.normalizeShopifyCart();\n if (shopifyCart) {\n this.log('Detected Shopify cart via browser globals');\n return shopifyCart;\n }\n \n const wooCart = this.normalizeWooCart();\n if (wooCart) {\n this.log('Detected WooCommerce cart via injected data');\n return wooCart;\n }\n \n const magentoCart = this.normalizeMagentoCart();\n if (magentoCart) {\n this.log('Detected Magento cart via localStorage');\n return magentoCart;\n }\n \n if (this.cartData) {\n this.log('Using manually set cart data');\n return this.cartData;\n }\n \n return null;\n }\n \n private normalizeShopifyCart(): CartData | null {\n try {\n if (typeof window === 'undefined') return null;\n \n const win = window as any;\n \n if (win.Shopify?.checkout) {\n const checkout = win.Shopify.checkout;\n return {\n cart_id: checkout.token || `shopify_${Date.now()}`,\n cart_total: parseFloat(checkout.total_price) || 0,\n cart_currency: checkout.currency || 'USD',\n cart_items: (checkout.line_items || []).map((item: any) => ({\n product_id: String(item.product_id || item.id),\n product_name: item.title || item.product_title,\n quantity: item.quantity || 1,\n price: parseFloat(item.price) || 0\n }))\n };\n }\n \n const cartJsonEl = document.getElementById('cart-json');\n if (cartJsonEl?.textContent) {\n const cart = JSON.parse(cartJsonEl.textContent);\n return {\n cart_id: cart.token || `shopify_${Date.now()}`,\n cart_total: (cart.total_price || 0) / 100,\n cart_currency: cart.currency || 'USD',\n cart_items: (cart.items || []).map((item: any) => ({\n product_id: String(item.product_id || item.id),\n product_name: item.product_title || item.title,\n quantity: item.quantity || 1,\n price: (item.price || 0) / 100\n }))\n };\n }\n \n return null;\n } catch (error) {\n this.log(`Error detecting Shopify cart: ${error}`, true);\n return null;\n }\n }\n \n private normalizeWooCart(): CartData | null {\n try {\n if (typeof window === 'undefined') return null;\n \n const win = window as any;\n \n if (win.aegis_cart) {\n const cart = win.aegis_cart;\n return {\n cart_id: cart.cart_id || `woo_${Date.now()}`,\n cart_total: parseFloat(cart.cart_total) || 0,\n cart_currency: cart.cart_currency || 'USD',\n cart_items: (cart.cart_items || []).map((item: any) => ({\n product_id: String(item.product_id),\n product_name: item.product_name,\n quantity: item.quantity || 1,\n price: parseFloat(item.price) || 0\n }))\n };\n }\n \n return null;\n } catch (error) {\n this.log(`Error detecting WooCommerce cart: ${error}`, true);\n return null;\n }\n }\n \n private normalizeMagentoCart(): CartData | null {\n try {\n if (typeof window === 'undefined' || !window.localStorage) return null;\n \n const mageCacheStr = localStorage.getItem('mage-cache-storage');\n if (!mageCacheStr) return null;\n \n const mageCache = JSON.parse(mageCacheStr);\n if (!mageCache?.cart) return null;\n \n const cart = mageCache.cart;\n \n return {\n cart_id: cart.quote_id || cart.id || `magento_${Date.now()}`,\n cart_total: parseFloat(cart.subtotalAmount || cart.subtotal || 0),\n cart_currency: cart.currencyCode || 'USD',\n cart_items: (cart.items || []).map((item: any) => ({\n product_id: String(item.item_id || item.product_id),\n product_name: item.product_name || item.name,\n quantity: item.qty || 1,\n price: parseFloat(item.product_price_value || item.price || 0)\n }))\n };\n } catch (error) {\n this.log(`Error detecting Magento cart: ${error}`, true);\n return null;\n }\n }\n \n private preloadWidgetAssets(): void {\n try {\n const exitIntentConfig = this.prefetchWidgetConfigs.exit_intent;\n if (exitIntentConfig?.enabled) {\n const imageUrl = (exitIntentConfig as any).image_url;\n if (imageUrl) {\n const img = new Image();\n img.src = imageUrl;\n this.log(`Preloading exit intent image: ${imageUrl}`);\n }\n }\n \n const spinWheelConfig = this.prefetchWidgetConfigs.spin_wheel;\n if (spinWheelConfig?.enabled) {\n const imageUrl = (spinWheelConfig as any).image_url;\n if (imageUrl) {\n const img = new Image();\n img.src = imageUrl;\n this.log(`Preloading spin wheel image: ${imageUrl}`);\n }\n }\n } catch (error) {\n this.log(`Error preloading widget assets: ${error}`, true);\n }\n }\n \n private async fetchPrefetchConfigs(): Promise<void> {\n try {\n const startTime = performance.now();\n const url = `${this.apiHost}/v1/widgets/config/prefetch`;\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n };\n \n if (this.contactId) headers['X-Contact-ID'] = this.contactId;\n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n \n const response = await fetch(url, { headers });\n \n if (!response.ok) {\n throw new Error(`Failed to fetch prefetch configs: ${response.status}`);\n }\n \n this.prefetchWidgetConfigs = await response.json();\n \n const elapsed = performance.now() - startTime;\n this.log(`Fetched prefetch widget configs in ${elapsed.toFixed(2)}ms`);\n \n } catch (error) {\n this.log(`Error fetching prefetch configs: ${error}`, true);\n }\n }\n \n private async fetchWidgets(): Promise<void> {\n try {\n const url = `${this.apiHost}/v1/widgets/config`;\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'X-Device-Platform': 'web',\n 'X-Device-Type': this.getDeviceType()\n };\n\n if (this.userId) headers['X-User-ID'] = this.userId;\n if (this.contactId) headers['X-Contact-ID'] = this.contactId;\n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n if (this.sourcePlatform) headers['X-Source-Platform'] = this.sourcePlatform;\n \n const response = await fetch(url, { headers });\n \n if (!response.ok) {\n throw new Error(`Failed to fetch widgets: ${response.status}`);\n }\n \n this.widgets = await response.json();\n \n this.log(`Fetched ${this.widgets.length} widgets`);\n \n } catch (error) {\n this.log(`Error fetching widgets: ${error}`, true);\n }\n }\n \n private renderImmediateWidgets(): void {\n const immediateWidgets = this.widgets.filter(w => \n !w.trigger_rules || w.trigger_rules.type === 'immediate'\n );\n \n immediateWidgets.forEach(widget => this.renderWidget(widget));\n }\n \n private setupTriggerListeners(): void {\n if (!this.triggerEngine) {\n this.log('TriggerEngine not provided, skipping trigger-based widgets');\n return;\n }\n \n this.widgets.forEach(widget => {\n if (!widget.trigger_rules) return;\n \n const { type, config } = widget.trigger_rules;\n \n switch (type) {\n case 'exit_intent':\n this.triggerEngine!.registerExitIntent();\n this.triggerEngine!.on('exit_intent', () => {\n if (!this.renderedWidgets.has(widget.widget_id)) {\n this.renderWidget(widget);\n }\n });\n break;\n \n case 'scroll_depth':\n const depthPercent = (config as any)?.depth_percent || 50;\n this.triggerEngine!.registerScrollDepth(depthPercent);\n this.triggerEngine!.on(`scroll_depth_${depthPercent}`, () => {\n if (!this.renderedWidgets.has(widget.widget_id)) {\n this.renderWidget(widget);\n }\n });\n break;\n \n case 'time_on_page':\n const seconds = (config as any)?.seconds || 30;\n this.triggerEngine!.registerTimeOnPage(seconds);\n this.triggerEngine!.on(`time_on_page_${seconds}`, () => {\n if (!this.renderedWidgets.has(widget.widget_id)) {\n this.renderWidget(widget);\n }\n });\n break;\n }\n });\n }\n \n private setupExitIntentWithPrefetch(): void {\n if (!this.enablePrefetch || !this.triggerEngine) {\n return;\n }\n \n const spinWheelConfig = this.prefetchWidgetConfigs.spin_wheel;\n const exitIntentConfig = this.prefetchWidgetConfigs.exit_intent;\n \n if (spinWheelConfig && spinWheelConfig.enabled) {\n const isMobile = this.isMobileDevice();\n const mobileConfig = exitIntentConfig?.mobile_triggers || {};\n \n const handleSpinWheelIntent = () => {\n const widgetId = `prefetch_spin_wheel_${Date.now()}`;\n \n if (this.renderedWidgets.has(widgetId)) {\n return;\n }\n \n this.renderedWidgets.add(widgetId);\n \n const detectedCart = this.detectPlatformCart();\n \n if (spinWheelConfig.type === 'cart_recovery' && detectedCart) {\n this.cartData = detectedCart;\n this.renderSpinWheelWidget(widgetId, spinWheelConfig);\n this.sendCartAbandonmentBeacon();\n } else if (spinWheelConfig.type === 'lead_gen') {\n this.renderSpinWheelWidget(widgetId, spinWheelConfig);\n }\n };\n \n if (isMobile) {\n const scrollVelocityEnabled = mobileConfig.scroll_velocity !== false;\n if (scrollVelocityEnabled) {\n this.triggerEngine.registerScrollVelocity({\n threshold: mobileConfig.scroll_threshold || 0.5,\n minScrollPosition: mobileConfig.scroll_min_position || 100,\n cooldown: mobileConfig.scroll_cooldown || 5000\n });\n this.triggerEngine.on('mobile_exit_intent', handleSpinWheelIntent);\n this.log('Registered mobile scroll velocity trigger for spin wheel');\n }\n \n const idleTimerEnabled = mobileConfig.idle_timer !== false;\n if (idleTimerEnabled) {\n const idleSeconds = mobileConfig.idle_seconds || 15;\n this.triggerEngine.registerInactivity(idleSeconds);\n this.triggerEngine.on(`inactivity_${idleSeconds}`, handleSpinWheelIntent);\n this.log(`Registered mobile idle timer trigger for spin wheel: ${idleSeconds}s`);\n }\n \n const visibilityChangeEnabled = mobileConfig.visibility_change !== false;\n if (visibilityChangeEnabled) {\n const detectedCart = this.detectPlatformCart();\n if (detectedCart && detectedCart.cart_items && detectedCart.cart_items.length > 0) {\n this.triggerEngine.registerVisibilityChange();\n this.triggerEngine.on('visibility_hidden', handleSpinWheelIntent);\n this.log('Registered mobile visibility change trigger for spin wheel (cart detected)');\n }\n }\n \n const backButtonEnabled = mobileConfig.back_button === true;\n if (backButtonEnabled) {\n this.triggerEngine.registerBackButton();\n this.triggerEngine.on('back_button', handleSpinWheelIntent);\n this.log('Registered mobile back button trigger for spin wheel');\n }\n \n this.log(`Setup mobile spin wheel: type=${spinWheelConfig.type}, priority=${spinWheelConfig.priority}`);\n } else {\n this.triggerEngine.registerExitIntent();\n this.triggerEngine.on('exit_intent', handleSpinWheelIntent);\n this.log(`Setup desktop spin wheel exit intent: type=${spinWheelConfig.type}, priority=${spinWheelConfig.priority}`);\n }\n \n return;\n }\n \n if (!exitIntentConfig || !exitIntentConfig.enabled) {\n this.log('No exit intent config found in prefetch');\n return;\n }\n \n const isMobile = this.isMobileDevice();\n const mobileConfig = exitIntentConfig.mobile_triggers || {};\n \n const handleExitIntent = () => {\n const widgetId = `prefetch_exit_intent_${Date.now()}`;\n \n if (this.renderedWidgets.has(widgetId)) {\n return;\n }\n \n this.renderedWidgets.add(widgetId);\n \n const detectedCart = this.detectPlatformCart();\n \n if (exitIntentConfig.type === 'cart_recovery' && detectedCart) {\n this.cartData = detectedCart;\n this.renderCartRecoveryPopup(widgetId, exitIntentConfig);\n this.sendCartAbandonmentBeacon();\n } else if (exitIntentConfig.type === 'lead_gen') {\n this.renderLeadGenPopup(widgetId, exitIntentConfig);\n } else {\n this.log('Unknown exit intent type or missing cart data');\n }\n };\n \n if (isMobile) {\n const scrollVelocityEnabled = mobileConfig.scroll_velocity !== false;\n if (scrollVelocityEnabled) {\n this.triggerEngine.registerScrollVelocity({\n threshold: mobileConfig.scroll_threshold || 0.5,\n minScrollPosition: mobileConfig.scroll_min_position || 100,\n cooldown: mobileConfig.scroll_cooldown || 5000\n });\n this.triggerEngine.on('mobile_exit_intent', handleExitIntent);\n this.log('Registered mobile scroll velocity trigger');\n }\n \n const idleTimerEnabled = mobileConfig.idle_timer !== false;\n if (idleTimerEnabled) {\n const idleSeconds = mobileConfig.idle_seconds || 15;\n this.triggerEngine.registerInactivity(idleSeconds);\n this.triggerEngine.on(`inactivity_${idleSeconds}`, handleExitIntent);\n this.log(`Registered mobile idle timer trigger: ${idleSeconds}s`);\n }\n \n const visibilityChangeEnabled = mobileConfig.visibility_change !== false;\n if (visibilityChangeEnabled) {\n const detectedCart = this.detectPlatformCart();\n if (detectedCart && detectedCart.cart_items && detectedCart.cart_items.length > 0) {\n this.triggerEngine.registerVisibilityChange();\n this.triggerEngine.on('visibility_hidden', handleExitIntent);\n this.log('Registered mobile visibility change trigger (cart detected)');\n } else {\n this.log('Skipped visibility change trigger (no cart items)');\n }\n }\n \n const backButtonEnabled = mobileConfig.back_button === true;\n if (backButtonEnabled) {\n this.triggerEngine.registerBackButton();\n this.triggerEngine.on('back_button', handleExitIntent);\n this.log('Registered mobile back button trigger (aggressive mode)');\n }\n \n this.log(`Setup mobile exit intent: type=${exitIntentConfig.type}, priority=${exitIntentConfig.priority}`);\n } else {\n this.triggerEngine.registerExitIntent();\n this.triggerEngine.on('exit_intent', handleExitIntent);\n this.log(`Setup desktop exit intent: type=${exitIntentConfig.type}, priority=${exitIntentConfig.priority}`);\n }\n }\n \n private sendCartAbandonmentBeacon(): void {\n if (!this.cartData) {\n this.log('No cart data available for beacon', true);\n return;\n }\n \n const beaconData = {\n organization_id: this.organizationId || 'default',\n contact_id: this.contactId,\n cart_id: this.cartData.cart_id,\n cart_total: this.cartData.cart_total,\n cart_currency: this.cartData.cart_currency,\n cart_items: this.cartData.cart_items,\n user_email: this.userId,\n abandoned_at: new Date().toISOString(),\n page_url: window.location.href,\n referrer: document.referrer\n };\n \n const beaconUrl = `${this.apiHost}/v1/widgets/beacon/cart-abandoned`;\n \n if (navigator.sendBeacon) {\n const blob = new Blob([JSON.stringify(beaconData)], { type: 'application/json' });\n const sent = navigator.sendBeacon(beaconUrl, blob);\n \n if (sent) {\n this.log('Cart abandonment beacon sent successfully');\n } else {\n this.log('Failed to send cart abandonment beacon', true);\n }\n } else {\n fetch(beaconUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Aegis-Write-Key': this.writeKey\n },\n body: JSON.stringify(beaconData),\n keepalive: true\n }).catch(err => {\n this.log(`Error sending cart abandonment via fetch: ${err}`, true);\n });\n }\n }\n \n private renderWidget(widget: WidgetConfig): void {\n if (this.renderedWidgets.has(widget.widget_id)) {\n return;\n }\n \n this.renderedWidgets.add(widget.widget_id);\n \n switch (widget.widget_type) {\n case 'chat_bubble':\n this.renderChatBubble(widget);\n break;\n case 'spin_wheel':\n this.renderSpinWheel(widget);\n break;\n case 'scratch_card':\n this.renderScratchCard(widget);\n break;\n case 'toast':\n this.renderToast(widget);\n break;\n case 'feedback_form':\n this.renderFeedbackForm(widget);\n break;\n case 'exit_intent_popup':\n this.renderExitIntentPopup(widget);\n break;\n default:\n this.log(`Unknown widget type: ${widget.widget_type}`, true);\n }\n \n this.trackEvent(widget.widget_id, 'show');\n }\n \n private renderChatBubble(widget: WidgetConfig): void {\n const { text, icon_url, link_url, background_color, text_color } = widget.config;\n const position = widget.position || 'bottom_right';\n \n const bubble = document.createElement('div');\n bubble.className = 'aegis-chat-bubble';\n bubble.setAttribute('data-widget-id', widget.widget_id);\n \n const positionStyles: Record<string, string> = {\n bottom_right: 'bottom: 20px; right: 20px;',\n bottom_left: 'bottom: 20px; left: 20px;',\n top_right: 'top: 20px; right: 20px;',\n top_left: 'top: 20px; left: 20px;'\n };\n \n bubble.style.cssText = `\n position: fixed;\n ${positionStyles[position] || positionStyles.bottom_right}\n background: ${this.sanitizeColor(background_color || '#25D366')};\n color: ${this.sanitizeColor(text_color || '#ffffff')};\n padding: 16px 24px;\n border-radius: 50px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n cursor: pointer;\n z-index: 999999;\n display: flex;\n align-items: center;\n gap: 12px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n font-weight: 600;\n font-size: 14px;\n animation: aegisBubbleIn 0.3s ease-out;\n `;\n \n if (icon_url) {\n const icon = document.createElement('img');\n const safeUrl = this.sanitizeUrl(icon_url);\n if (safeUrl) {\n icon.src = safeUrl;\n icon.alt = '';\n icon.style.cssText = 'width: 24px; height: 24px;';\n bubble.appendChild(icon);\n }\n }\n \n const textEl = document.createElement('span');\n textEl.textContent = text || 'Chat with us';\n bubble.appendChild(textEl);\n \n bubble.addEventListener('click', () => {\n this.trackEvent(widget.widget_id, 'click');\n const safeUrl = this.sanitizeUrl(link_url);\n if (safeUrl) {\n window.open(safeUrl, '_blank');\n }\n });\n \n this.addAnimationStyles();\n document.body.appendChild(bubble);\n }\n \n private renderSpinWheel(widget: WidgetConfig): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-gamification-overlay';\n overlay.setAttribute('data-widget-id', widget.widget_id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: aegisFadeIn 0.3s ease-out;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-spin-wheel-modal';\n modal.style.cssText = `\n background: white;\n border-radius: 16px;\n padding: 32px;\n max-width: 500px;\n width: 90%;\n box-shadow: 0 10px 40px rgba(0,0,0,0.3);\n text-align: center;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisScaleIn 0.3s ease-out;\n `;\n \n const title = document.createElement('h2');\n title.textContent = widget.config.title || 'Spin to Win!';\n title.style.cssText = 'margin: 0 0 16px 0; font-size: 24px; font-weight: 700; color: #1a1a1a;';\n modal.appendChild(title);\n \n const description = document.createElement('p');\n description.textContent = widget.config.description || 'Try your luck and win exclusive prizes!';\n description.style.cssText = 'margin: 0 0 24px 0; font-size: 14px; color: #666;';\n modal.appendChild(description);\n \n const wheelPlaceholder = document.createElement('div');\n wheelPlaceholder.style.cssText = `\n width: 300px;\n height: 300px;\n margin: 0 auto 24px;\n background: linear-gradient(45deg, #ff6b6b, #feca57, #48dbfb, #ff6348);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 48px;\n color: white;\n `;\n wheelPlaceholder.textContent = '🎰';\n modal.appendChild(wheelPlaceholder);\n \n const spinButton = document.createElement('button');\n spinButton.textContent = 'SPIN NOW!';\n spinButton.style.cssText = `\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: none;\n padding: 16px 48px;\n border-radius: 8px;\n font-weight: 700;\n font-size: 16px;\n cursor: pointer;\n margin-bottom: 16px;\n `;\n \n spinButton.addEventListener('click', async () => {\n spinButton.disabled = true;\n spinButton.textContent = 'SPINNING...';\n \n try {\n const prize = await this.generatePrize(widget.config.config_id);\n \n wheelPlaceholder.style.animation = 'aegisSpin 2s ease-out';\n \n setTimeout(() => {\n this.showPrizeResult(modal, prize);\n }, 2000);\n \n } catch (error) {\n this.log(`Error generating prize: ${error}`, true);\n spinButton.disabled = false;\n spinButton.textContent = 'TRY AGAIN';\n }\n });\n \n modal.appendChild(spinButton);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '×';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 16px;\n right: 16px;\n background: transparent;\n border: none;\n font-size: 28px;\n cursor: pointer;\n color: #999;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(widget.widget_id, 'dismiss');\n document.body.removeChild(overlay);\n this.renderedWidgets.delete(widget.widget_id);\n });\n \n modal.style.position = 'relative';\n modal.appendChild(closeButton);\n \n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private renderSpinWheelWidget(widgetId: string, config: NonNullable<PrefetchWidgetConfig['spin_wheel']>): void {\n const cart = this.detectPlatformCart();\n \n if (config.type === 'cart_recovery' && !cart) {\n this.log('Spin wheel requires cart, but none detected');\n return;\n }\n \n if (cart) {\n this.cartData = cart;\n }\n \n const customization = this.cssCustomization.spinWheel || {};\n const accentColor = customization.accentColor || (config as any).accent_color || '#FF6B6B';\n const backgroundColor = customization.backgroundColor || (config as any).background_color || '#FFFFFF';\n const textColor = customization.textColor || (config as any).text_color || '#333333';\n const buttonColor = customization.buttonColor || (config as any).button_color || accentColor;\n const wheelColors = customization.wheelColors || ['#FF6B6B', '#4ECDC4', '#FFE66D', '#95E1D3'];\n \n const overlay = document.createElement('div');\n overlay.className = 'aegis-spin-wheel-overlay';\n overlay.setAttribute('data-widget-id', widgetId);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.7);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 999999;\n animation: aegisFadeIn 0.3s ease;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-spin-wheel-modal';\n modal.style.cssText = `\n background: ${this.sanitizeColor(backgroundColor)};\n border-radius: 16px;\n padding: 32px;\n max-width: 500px;\n width: 90%;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n position: relative;\n animation: aegisScaleIn 0.4s ease;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n `;\n \n const closeBtn = document.createElement('button');\n closeBtn.innerHTML = '✕';\n closeBtn.className = 'aegis-spin-wheel-close';\n closeBtn.style.cssText = `\n position: absolute;\n top: 16px;\n right: 16px;\n background: none;\n border: none;\n font-size: 24px;\n cursor: pointer;\n color: #999;\n `;\n closeBtn.onclick = () => {\n this.trackEvent(widgetId, 'dismiss', { type: 'spin_wheel' });\n document.body.removeChild(overlay);\n this.renderedWidgets.delete(widgetId);\n };\n modal.appendChild(closeBtn);\n \n const title = document.createElement('h2');\n title.textContent = this.interpolateCartVariables((config as any).title || 'Spin to Win!');\n title.style.cssText = `\n margin: 0 0 16px 0;\n font-size: 28px;\n font-weight: bold;\n text-align: center;\n color: ${this.sanitizeColor(textColor)};\n `;\n modal.appendChild(title);\n \n if (cart) {\n const subtitle = document.createElement('p');\n subtitle.textContent = `Complete your ${cart.cart_currency} ${cart.cart_total.toFixed(2)} order and save!`;\n subtitle.style.cssText = `\n margin: 0 0 24px 0;\n font-size: 16px;\n text-align: center;\n color: #666;\n `;\n modal.appendChild(subtitle);\n }\n \n const wheelContainer = document.createElement('div');\n wheelContainer.className = 'aegis-wheel-container';\n wheelContainer.style.cssText = `\n width: 300px;\n height: 300px;\n margin: 0 auto 24px auto;\n background: conic-gradient(\n from 0deg,\n ${wheelColors[0]} 0deg 90deg,\n ${wheelColors[1]} 90deg 180deg,\n ${wheelColors[2]} 180deg 270deg,\n ${wheelColors[3]} 270deg 360deg\n );\n border-radius: 50%;\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n `;\n \n const form = document.createElement('form');\n form.className = 'aegis-spin-form';\n form.style.cssText = 'display: block;';\n \n const phoneInput = document.createElement('input');\n phoneInput.type = 'tel';\n phoneInput.placeholder = 'Enter your phone number';\n phoneInput.required = true;\n phoneInput.style.cssText = `\n width: 100%;\n padding: 14px;\n border: 2px solid #ddd;\n border-radius: 8px;\n font-size: 16px;\n margin-bottom: 12px;\n box-sizing: border-box;\n `;\n form.appendChild(phoneInput);\n \n const emailInput = document.createElement('input');\n emailInput.type = 'email';\n emailInput.placeholder = 'Enter your email (optional)';\n emailInput.style.cssText = `\n width: 100%;\n padding: 14px;\n border: 2px solid #ddd;\n border-radius: 8px;\n font-size: 16px;\n margin-bottom: 12px;\n box-sizing: border-box;\n `;\n form.appendChild(emailInput);\n \n const nameInput = document.createElement('input');\n nameInput.type = 'text';\n nameInput.placeholder = 'Enter your name (optional)';\n nameInput.style.cssText = `\n width: 100%;\n padding: 14px;\n border: 2px solid #ddd;\n border-radius: 8px;\n font-size: 16px;\n margin-bottom: 12px;\n box-sizing: border-box;\n `;\n form.appendChild(nameInput);\n \n const submitButton = document.createElement('button');\n submitButton.type = 'submit';\n submitButton.textContent = 'Spin the Wheel!';\n submitButton.style.cssText = `\n width: 100%;\n padding: 14px;\n background: ${this.sanitizeColor(buttonColor)};\n color: white;\n border: none;\n border-radius: 8px;\n font-size: 16px;\n font-weight: 700;\n cursor: pointer;\n `;\n form.appendChild(submitButton);\n \n const errorMessage = document.createElement('div');\n errorMessage.className = 'aegis-spin-error';\n errorMessage.style.cssText = `\n color: #d32f2f;\n font-size: 14px;\n margin-top: 12px;\n text-align: center;\n display: none;\n `;\n form.appendChild(errorMessage);\n \n form.addEventListener('submit', async (e) => {\n e.preventDefault();\n \n const phone = phoneInput.value.trim();\n const email = emailInput.value.trim();\n const name = nameInput.value.trim();\n \n if (!this.validatePhone(phone)) {\n errorMessage.textContent = 'Please enter a valid phone number (e.g., +1234567890)';\n errorMessage.style.display = 'block';\n return;\n }\n \n if (email && !this.validateEmail(email)) {\n errorMessage.textContent = 'Please enter a valid email address';\n errorMessage.style.display = 'block';\n return;\n }\n \n errorMessage.style.display = 'none';\n submitButton.disabled = true;\n submitButton.textContent = 'Spinning...';\n \n wheelContainer.style.animation = 'aegisSpin 2s ease-out';\n \n setTimeout(async () => {\n try {\n const prize = await this.submitSpinWheel({\n phone,\n email,\n name,\n cart,\n widgetId\n });\n \n this.showSpinWheelPrize(modal, prize);\n this.trackEvent(widgetId, 'submit', {\n type: 'spin_wheel',\n prize_label: prize.prize_label,\n has_email: !!email\n });\n \n } catch (error) {\n this.log(`Error submitting spin wheel: ${error}`, true);\n errorMessage.textContent = 'Failed to submit. Please try again.';\n errorMessage.style.display = 'block';\n submitButton.disabled = false;\n submitButton.textContent = 'Spin the Wheel!';\n wheelContainer.style.animation = '';\n }\n }, 2000);\n });\n \n modal.appendChild(wheelContainer);\n modal.appendChild(form);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n \n this.trackEvent(widgetId, 'show', { type: 'spin_wheel' });\n }\n \n private validatePhone(phone: string): boolean {\n const e164Regex = /^\\+?[1-9]\\d{1,14}$/;\n return e164Regex.test(phone.replace(/[\\s()-]/g, ''));\n }\n \n private validateEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n }\n \n private async submitSpinWheel(data: {\n phone: string;\n email: string;\n name: string;\n cart: CartData | null;\n widgetId: string;\n }): Promise<GamificationPrize> {\n const url = `${this.apiHost}/v1/widgets/spin-wheel/submit`;\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'Content-Type': 'application/json'\n };\n \n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n \n const geoRegion = this.detectGeoRegion();\n const deviceType = this.getDeviceType();\n const utmParams = this.getUTMParams();\n \n const body: any = {\n phone: data.phone.replace(/[\\s()-]/g, ''),\n email: data.email || undefined,\n name: data.name || undefined,\n cart_id: data.cart?.cart_id || `web_${Date.now()}`,\n cart_token: data.cart?.cart_id,\n cart_total: data.cart?.cart_total || 0,\n cart_currency: data.cart?.cart_currency || 'USD',\n cart_items: data.cart?.cart_items || [],\n cart_url: window.location.href,\n platform: 'web',\n geo_region: geoRegion,\n device_type: deviceType,\n session_id: this.getSessionId() || undefined,\n anonymous_id: this.getAnonymousId() || undefined,\n utm_source: utmParams.utm_source,\n utm_medium: utmParams.utm_medium,\n utm_campaign: utmParams.utm_campaign\n };\n \n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n });\n \n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to submit spin wheel: ${response.status} - ${errorText}`);\n }\n \n return await response.json();\n }\n \n private showSpinWheelPrize(modal: HTMLElement, prize: GamificationPrize): void {\n modal.innerHTML = '';\n \n const resultContainer = document.createElement('div');\n resultContainer.style.cssText = 'text-align: center; padding: 40px 20px;';\n \n const emoji = document.createElement('div');\n emoji.textContent = '🎉';\n emoji.style.cssText = 'font-size: 60px; margin-bottom: 20px;';\n resultContainer.appendChild(emoji);\n \n const title = document.createElement('h2');\n title.textContent = 'Congratulations!';\n title.style.cssText = 'margin: 0 0 12px 0; font-size: 28px; font-weight: 700; color: #1a73e8;';\n resultContainer.appendChild(title);\n \n const prizeLabel = document.createElement('p');\n prizeLabel.textContent = prize.prize_label;\n prizeLabel.style.cssText = 'margin: 0 0 20px 0; font-size: 20px; font-weight: 600; color: #333;';\n resultContainer.appendChild(prizeLabel);\n \n if (prize.coupon_code) {\n const couponContainer = document.createElement('div');\n couponContainer.style.cssText = `\n background: #f5f5f5;\n padding: 16px;\n border-radius: 8px;\n margin-bottom: 20px;\n border: 2px dashed #1a73e8;\n `;\n \n const couponLabel = document.createElement('div');\n couponLabel.textContent = 'Your coupon code:';\n couponLabel.style.cssText = 'font-size: 12px; color: #666; margin-bottom: 8px;';\n couponContainer.appendChild(couponLabel);\n \n const couponCode = document.createElement('div');\n couponCode.textContent = prize.coupon_code;\n couponCode.style.cssText = 'font-size: 24px; font-weight: 700; color: #1a73e8; letter-spacing: 2px;';\n couponContainer.appendChild(couponCode);\n \n resultContainer.appendChild(couponContainer);\n }\n \n const message = document.createElement('p');\n message.textContent = 'Check your WhatsApp/SMS for your discount code and cart link!';\n message.style.cssText = 'margin: 0 0 20px 0; font-size: 14px; color: #666;';\n resultContainer.appendChild(message);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = 'Close';\n closeButton.style.cssText = `\n background: #1a73e8;\n color: white;\n border: none;\n padding: 12px 32px;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n `;\n \n closeButton.addEventListener('click', () => {\n const overlay = modal.parentElement;\n if (overlay && document.body.contains(overlay)) {\n document.body.removeChild(overlay);\n }\n });\n \n resultContainer.appendChild(closeButton);\n modal.appendChild(resultContainer);\n }\n \n private detectGeoRegion(): string {\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n \n if (timezone.includes('America')) return 'north_america';\n if (timezone.includes('Europe')) return 'europe';\n if (timezone.includes('Asia/Kolkata') || timezone.includes('Asia/Calcutta')) return 'india';\n if (timezone.includes('Asia/Singapore') || timezone.includes('Asia/Bangkok') || timezone.includes('Asia/Jakarta')) return 'southeast_asia';\n if (timezone.includes('Asia/Dubai') || timezone.includes('Asia/Riyadh')) return 'middle_east';\n if (timezone.includes('America') && (timezone.includes('Sao_Paulo') || timezone.includes('Buenos_Aires'))) return 'latin_america';\n if (timezone.includes('Australia') || timezone.includes('Pacific/Auckland')) return 'oceania';\n \n return 'north_america';\n }\n \n private getUTMParams(): { utm_source?: string; utm_medium?: string; utm_campaign?: string } {\n const params = new URLSearchParams(window.location.search);\n return {\n utm_source: params.get('utm_source') || undefined,\n utm_medium: params.get('utm_medium') || undefined,\n utm_campaign: params.get('utm_campaign') || undefined\n };\n }\n \n private getSessionId(): string | null {\n return sessionStorage.getItem('aegis_session_id');\n }\n \n private getAnonymousId(): string | null {\n return localStorage.getItem('aegis_anonymous_id');\n }\n \n private renderScratchCard(widget: WidgetConfig): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-gamification-overlay';\n overlay.setAttribute('data-widget-id', widget.widget_id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: aegisFadeIn 0.3s ease-out;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-scratch-card-modal';\n modal.style.cssText = `\n background: white;\n border-radius: 16px;\n padding: 32px;\n max-width: 500px;\n width: 90%;\n box-shadow: 0 10px 40px rgba(0,0,0,0.3);\n text-align: center;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisScaleIn 0.3s ease-out;\n `;\n \n const title = document.createElement('h2');\n title.textContent = widget.config.title || 'Scratch & Win!';\n title.style.cssText = 'margin: 0 0 16px 0; font-size: 24px; font-weight: 700; color: #1a1a1a;';\n modal.appendChild(title);\n \n const description = document.createElement('p');\n description.textContent = widget.config.description || 'Scratch to reveal your prize!';\n description.style.cssText = 'margin: 0 0 24px 0; font-size: 14px; color: #666;';\n modal.appendChild(description);\n \n const canvas = document.createElement('canvas');\n canvas.width = 300;\n canvas.height = 200;\n canvas.style.cssText = `\n border-radius: 8px;\n cursor: pointer;\n margin: 0 auto 24px;\n display: block;\n box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n `;\n modal.appendChild(canvas);\n \n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.fillStyle = '#c0c0c0';\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.fillStyle = '#888';\n ctx.font = '20px Arial';\n ctx.textAlign = 'center';\n ctx.fillText('Scratch here!', canvas.width / 2, canvas.height / 2);\n \n let isScratching = false;\n \n const scratch = (x: number, y: number) => {\n ctx.globalCompositeOperation = 'destination-out';\n ctx.beginPath();\n ctx.arc(x, y, 20, 0, Math.PI * 2);\n ctx.fill();\n };\n \n canvas.addEventListener('mousedown', () => { isScratching = true; });\n canvas.addEventListener('mouseup', () => { isScratching = false; });\n canvas.addEventListener('mousemove', (e) => {\n if (isScratching) {\n const rect = canvas.getBoundingClientRect();\n scratch(e.clientX - rect.left, e.clientY - rect.top);\n }\n });\n }\n \n const scratchButton = document.createElement('button');\n scratchButton.textContent = 'REVEAL PRIZE';\n scratchButton.style.cssText = `\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n color: white;\n border: none;\n padding: 16px 48px;\n border-radius: 8px;\n font-weight: 700;\n font-size: 16px;\n cursor: pointer;\n `;\n \n scratchButton.addEventListener('click', async () => {\n scratchButton.disabled = true;\n scratchButton.textContent = 'REVEALING...';\n \n try {\n const prize = await this.generatePrize(widget.config.config_id);\n this.showPrizeResult(modal, prize);\n } catch (error) {\n this.log(`Error generating prize: ${error}`, true);\n scratchButton.disabled = false;\n scratchButton.textContent = 'TRY AGAIN';\n }\n });\n \n modal.appendChild(scratchButton);\n \n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private renderToast(widget: WidgetConfig): void {\n const { message, icon, duration } = widget.config;\n const position = widget.position || 'bottom_left';\n \n const toast = document.createElement('div');\n toast.className = 'aegis-toast';\n toast.setAttribute('data-widget-id', widget.widget_id);\n \n const positionStyles: Record<string, string> = {\n bottom_left: 'bottom: 20px; left: 20px;',\n bottom_right: 'bottom: 20px; right: 20px;',\n top_left: 'top: 20px; left: 20px;',\n top_right: 'top: 20px; right: 20px;'\n };\n \n toast.style.cssText = `\n position: fixed;\n ${positionStyles[position] || positionStyles.bottom_left}\n background: white;\n padding: 16px 20px;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n z-index: 999998;\n display: flex;\n align-items: center;\n gap: 12px;\n max-width: 350px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisToastIn 0.3s ease-out;\n `;\n \n if (icon) {\n const iconEl = document.createElement('div');\n iconEl.textContent = icon;\n iconEl.style.cssText = 'font-size: 20px;';\n toast.appendChild(iconEl);\n }\n \n const messageEl = document.createElement('div');\n messageEl.textContent = message || 'Someone just made a purchase!';\n messageEl.style.cssText = 'flex: 1; font-size: 13px; color: #333;';\n toast.appendChild(messageEl);\n \n this.addAnimationStyles();\n document.body.appendChild(toast);\n \n setTimeout(() => {\n toast.style.animation = 'aegisToastOut 0.3s ease-out';\n setTimeout(() => {\n if (document.body.contains(toast)) {\n document.body.removeChild(toast);\n }\n this.renderedWidgets.delete(widget.widget_id);\n }, 300);\n }, duration || 5000);\n }\n \n private renderFeedbackForm(widget: WidgetConfig): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-feedback-overlay';\n overlay.setAttribute('data-widget-id', widget.widget_id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 400px;\n background: white;\n box-shadow: -4px 0 20px rgba(0,0,0,0.15);\n z-index: 1000000;\n padding: 32px;\n overflow-y: auto;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisSlideInRight 0.3s ease-out;\n `;\n \n const title = document.createElement('h2');\n title.textContent = widget.config.title || 'We value your feedback!';\n title.style.cssText = 'margin: 0 0 8px 0; font-size: 20px; font-weight: 600; color: #1a1a1a;';\n overlay.appendChild(title);\n \n const description = document.createElement('p');\n description.textContent = widget.config.description || 'Help us improve your experience.';\n description.style.cssText = 'margin: 0 0 24px 0; font-size: 14px; color: #666;';\n overlay.appendChild(description);\n \n const form = document.createElement('form');\n \n const label = document.createElement('label');\n label.textContent = 'How likely are you to recommend us? (0-10)';\n label.style.cssText = 'display: block; font-size: 14px; font-weight: 600; margin-bottom: 8px; color: #333;';\n form.appendChild(label);\n \n const input = document.createElement('input');\n input.type = 'number';\n input.min = '0';\n input.max = '10';\n input.style.cssText = `\n width: 100%;\n padding: 12px;\n border: 1px solid #ddd;\n border-radius: 6px;\n font-size: 14px;\n margin-bottom: 16px;\n `;\n form.appendChild(input);\n \n const textareaLabel = document.createElement('label');\n textareaLabel.textContent = 'Tell us more (optional)';\n textareaLabel.style.cssText = 'display: block; font-size: 14px; font-weight: 600; margin-bottom: 8px; color: #333;';\n form.appendChild(textareaLabel);\n \n const textarea = document.createElement('textarea');\n textarea.rows = 4;\n textarea.style.cssText = `\n width: 100%;\n padding: 12px;\n border: 1px solid #ddd;\n border-radius: 6px;\n font-size: 14px;\n resize: vertical;\n margin-bottom: 16px;\n font-family: inherit;\n `;\n form.appendChild(textarea);\n \n const submitButton = document.createElement('button');\n submitButton.type = 'submit';\n submitButton.textContent = 'Submit Feedback';\n submitButton.style.cssText = `\n width: 100%;\n background: #1a73e8;\n color: white;\n border: none;\n padding: 12px;\n border-radius: 6px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n `;\n form.appendChild(submitButton);\n \n form.addEventListener('submit', async (e) => {\n e.preventDefault();\n \n submitButton.disabled = true;\n submitButton.textContent = 'Submitting...';\n \n try {\n await this.submitFeedback(widget.widget_id, {\n score: parseInt(input.value),\n comment: textarea.value\n });\n \n overlay.innerHTML = '<div style=\"text-align: center; padding: 60px 20px;\"><h3 style=\"margin: 0 0 12px 0; color: #1a73e8;\">Thank you!</h3><p style=\"margin: 0; color: #666;\">Your feedback helps us improve.</p></div>';\n \n setTimeout(() => {\n document.body.removeChild(overlay);\n }, 2000);\n \n } catch (error) {\n this.log(`Error submitting feedback: ${error}`, true);\n submitButton.disabled = false;\n submitButton.textContent = 'Submit Feedback';\n }\n });\n \n overlay.appendChild(form);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '×';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 16px;\n right: 16px;\n background: transparent;\n border: none;\n font-size: 28px;\n cursor: pointer;\n color: #999;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(widget.widget_id, 'dismiss');\n document.body.removeChild(overlay);\n this.renderedWidgets.delete(widget.widget_id);\n });\n \n overlay.appendChild(closeButton);\n \n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private renderExitIntentPopup(widget: WidgetConfig): void {\n const { title, description, cta_text, cta_url, image_url } = widget.config;\n \n const overlay = document.createElement('div');\n overlay.className = 'aegis-exit-popup-overlay';\n overlay.setAttribute('data-widget-id', widget.widget_id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: aegisFadeIn 0.3s ease-out;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-exit-popup-modal';\n modal.style.cssText = `\n background: white;\n border-radius: 16px;\n max-width: 600px;\n width: 90%;\n overflow: hidden;\n box-shadow: 0 10px 40px rgba(0,0,0,0.3);\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisScaleIn 0.3s ease-out;\n `;\n \n if (image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = '';\n img.style.cssText = 'width: 100%; height: 250px; object-fit: cover;';\n modal.appendChild(img);\n }\n }\n \n const content = document.createElement('div');\n content.style.cssText = 'padding: 32px;';\n \n const titleEl = document.createElement('h2');\n titleEl.textContent = title || 'Wait! Don\\'t leave yet!';\n titleEl.style.cssText = 'margin: 0 0 16px 0; font-size: 28px; font-weight: 700; color: #1a1a1a;';\n content.appendChild(titleEl);\n \n const descEl = document.createElement('p');\n descEl.textContent = description || 'Get 10% off your first order!';\n descEl.style.cssText = 'margin: 0 0 24px 0; font-size: 16px; color: #666; line-height: 1.5;';\n content.appendChild(descEl);\n \n if (cta_text && cta_url) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = cta_text;\n ctaButton.style.cssText = `\n background: #1a73e8;\n color: white;\n border: none;\n padding: 16px 32px;\n border-radius: 8px;\n font-weight: 600;\n font-size: 16px;\n cursor: pointer;\n width: 100%;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(widget.widget_id, 'click');\n const safeUrl = this.sanitizeUrl(cta_url);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n });\n \n content.appendChild(ctaButton);\n }\n \n modal.appendChild(content);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '×';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 16px;\n right: 16px;\n background: white;\n border: none;\n font-size: 28px;\n cursor: pointer;\n color: #666;\n width: 40px;\n height: 40px;\n border-radius: 50%;\n box-shadow: 0 2px 8px rgba(0,0,0,0.2);\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(widget.widget_id, 'dismiss');\n document.body.removeChild(overlay);\n this.renderedWidgets.delete(widget.widget_id);\n });\n \n modal.style.position = 'relative';\n modal.appendChild(closeButton);\n \n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private async generatePrize(configId: string): Promise<GamificationPrize> {\n const url = `${this.apiHost}/v1/widgets/gamification/generate-prize`;\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'Content-Type': 'application/json'\n };\n \n if (this.userId) headers['X-User-ID'] = this.userId;\n if (this.contactId) headers['X-Contact-ID'] = this.contactId;\n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n \n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({ config_id: configId })\n });\n \n if (!response.ok) {\n throw new Error(`Failed to generate prize: ${response.status}`);\n }\n \n return await response.json();\n }\n \n private showPrizeResult(modal: HTMLElement, prize: GamificationPrize): void {\n modal.innerHTML = '';\n \n const resultContainer = document.createElement('div');\n resultContainer.style.cssText = 'text-align: center; padding: 40px 20px;';\n \n const emoji = document.createElement('div');\n emoji.textContent = '🎉';\n emoji.style.cssText = 'font-size: 60px; margin-bottom: 20px;';\n resultContainer.appendChild(emoji);\n \n const title = document.createElement('h2');\n title.textContent = 'Congratulations!';\n title.style.cssText = 'margin: 0 0 12px 0; font-size: 28px; font-weight: 700; color: #1a73e8;';\n resultContainer.appendChild(title);\n \n const prizeLabel = document.createElement('p');\n prizeLabel.textContent = prize.prize_label;\n prizeLabel.style.cssText = 'margin: 0 0 20px 0; font-size: 20px; font-weight: 600; color: #333;';\n resultContainer.appendChild(prizeLabel);\n \n if (prize.coupon_code) {\n const couponContainer = document.createElement('div');\n couponContainer.style.cssText = `\n background: #f5f5f5;\n padding: 16px;\n border-radius: 8px;\n margin-bottom: 20px;\n border: 2px dashed #1a73e8;\n `;\n \n const couponLabel = document.createElement('div');\n couponLabel.textContent = 'Your coupon code:';\n couponLabel.style.cssText = 'font-size: 12px; color: #666; margin-bottom: 8px;';\n couponContainer.appendChild(couponLabel);\n \n const couponCode = document.createElement('div');\n couponCode.textContent = prize.coupon_code;\n couponCode.style.cssText = 'font-size: 24px; font-weight: 700; color: #1a73e8; letter-spacing: 2px;';\n couponContainer.appendChild(couponCode);\n \n resultContainer.appendChild(couponContainer);\n }\n \n const closeButton = document.createElement('button');\n closeButton.textContent = 'Close';\n closeButton.style.cssText = `\n background: #1a73e8;\n color: white;\n border: none;\n padding: 12px 32px;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n `;\n \n closeButton.addEventListener('click', () => {\n const overlay = modal.parentElement;\n if (overlay && document.body.contains(overlay)) {\n document.body.removeChild(overlay);\n }\n });\n \n resultContainer.appendChild(closeButton);\n modal.appendChild(resultContainer);\n }\n \n private async submitFeedback(widgetId: string, data: Record<string, any>): Promise<void> {\n const url = `${this.apiHost}/v1/widgets/track-event`;\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'Content-Type': 'application/json'\n };\n \n if (this.userId) headers['X-User-ID'] = this.userId;\n if (this.contactId) headers['X-Contact-ID'] = this.contactId;\n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n \n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n widget_id: widgetId,\n event_type: 'submit',\n event_data: data\n })\n });\n \n if (!response.ok) {\n throw new Error(`Failed to submit feedback: ${response.status}`);\n }\n }\n \n private async trackEvent(widgetId: string, eventType: string, metadata?: Record<string, any>): Promise<void> {\n try {\n const url = `${this.apiHost}/v1/widgets/track-event`;\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'Content-Type': 'application/json'\n };\n \n if (this.userId) headers['X-User-ID'] = this.userId;\n if (this.contactId) headers['X-Contact-ID'] = this.contactId;\n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n \n await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n widget_id: widgetId,\n event_type: eventType,\n event_data: metadata || {}\n })\n });\n \n } catch (error) {\n this.log(`Error tracking widget event: ${error}`, true);\n }\n }\n \n private sanitizeUrl(url?: string): string | null {\n if (!url) return null;\n \n try {\n const parsed = new URL(url, window.location.href);\n if (parsed.protocol === 'javascript:' || parsed.protocol === 'data:') {\n this.log(`Blocked dangerous URL: ${url}`, true);\n return null;\n }\n return parsed.href;\n } catch {\n this.log(`Invalid URL: ${url}`, true);\n return null;\n }\n }\n \n private sanitizeColor(color: string): string {\n if (/^#[0-9A-F]{3,8}$/i.test(color)) {\n return color;\n }\n \n if (/^rgb\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*\\)$/i.test(color)) {\n return color;\n }\n \n if (/^rgba\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*[\\d.]+\\s*\\)$/i.test(color)) {\n return color;\n }\n \n return '#1a73e8';\n }\n \n private getDeviceType(): string {\n const ua = navigator.userAgent;\n if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(ua)) {\n return 'tablet';\n }\n if (/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(ua)) {\n return 'mobile';\n }\n return 'desktop';\n }\n \n private isMobileDevice(): boolean {\n const deviceType = this.getDeviceType();\n return deviceType === 'mobile' || deviceType === 'tablet';\n }\n \n private addAnimationStyles(): void {\n if (document.getElementById('aegis-widget-animations')) {\n return;\n }\n \n const style = document.createElement('style');\n style.id = 'aegis-widget-animations';\n style.textContent = `\n @keyframes aegisFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n \n @keyframes aegisScaleIn {\n from { transform: scale(0.8); opacity: 0; }\n to { transform: scale(1); opacity: 1; }\n }\n \n @keyframes aegisBubbleIn {\n from { transform: translateY(20px); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n }\n \n @keyframes aegisToastIn {\n from { transform: translateX(-100%); opacity: 0; }\n to { transform: translateX(0); opacity: 1; }\n }\n \n @keyframes aegisToastOut {\n from { transform: translateX(0); opacity: 1; }\n to { transform: translateX(-100%); opacity: 0; }\n }\n \n @keyframes aegisSlideInRight {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n }\n \n @keyframes aegisSpin {\n from { transform: rotate(0deg); }\n to { transform: rotate(1440deg); }\n }\n `;\n document.head.appendChild(style);\n }\n \n private renderCartRecoveryPopup(widgetId: string, config: NonNullable<PrefetchWidgetConfig['exit_intent']>): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-exit-popup-overlay';\n overlay.setAttribute('data-widget-id', widgetId);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: aegisFadeIn 0.3s ease-out;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-cart-recovery-modal';\n modal.style.cssText = `\n background: ${this.sanitizeColor(config.background_color || '#FFFFFF')};\n color: ${this.sanitizeColor(config.text_color || '#333333')};\n border-radius: 16px;\n max-width: 600px;\n width: 90%;\n padding: 40px;\n box-shadow: 0 10px 40px rgba(0,0,0,0.3);\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisScaleIn 0.3s ease-out;\n position: relative;\n `;\n \n const title = document.createElement('h2');\n const titleText = this.interpolateCartVariables(config.title || 'Complete Your Order');\n title.textContent = titleText;\n title.style.cssText = `margin: 0 0 16px 0; font-size: 28px; font-weight: 700; color: ${this.sanitizeColor(config.accent_color || '#FF6B00')};`;\n modal.appendChild(title);\n \n const message = document.createElement('p');\n const messageText = this.interpolateCartVariables(config.message || 'Your cart is waiting for you!');\n message.textContent = messageText;\n message.style.cssText = 'margin: 0 0 24px 0; font-size: 16px; line-height: 1.5;';\n modal.appendChild(message);\n \n if (config.show_cart_items && this.cartData) {\n const cartItems = document.createElement('div');\n cartItems.style.cssText = 'margin: 0 0 24px 0; padding: 16px; background: rgba(0,0,0,0.05); border-radius: 8px;';\n \n const cartTitle = document.createElement('div');\n cartTitle.textContent = `${this.cartData.cart_items.length} items in your cart`;\n cartTitle.style.cssText = 'font-weight: 600; margin-bottom: 12px;';\n cartItems.appendChild(cartTitle);\n \n this.cartData.cart_items.slice(0, 3).forEach(item => {\n const itemDiv = document.createElement('div');\n itemDiv.textContent = `${item.quantity}× ${item.product_name || item.product_id}`;\n itemDiv.style.cssText = 'font-size: 14px; margin-bottom: 4px;';\n cartItems.appendChild(itemDiv);\n });\n \n modal.appendChild(cartItems);\n }\n \n if (config.discount_code) {\n const discountBox = document.createElement('div');\n discountBox.style.cssText = `\n margin: 0 0 24px 0;\n padding: 16px;\n background: ${this.sanitizeColor(config.accent_color || '#FF6B00')};\n color: white;\n border-radius: 8px;\n text-align: center;\n font-weight: 700;\n font-size: 18px;\n `;\n discountBox.textContent = `Use code: ${config.discount_code} for ${config.discount_percentage || 10}% off!`;\n modal.appendChild(discountBox);\n }\n \n if (config.show_timer && config.timer_minutes) {\n const timer = document.createElement('div');\n timer.style.cssText = 'margin: 0 0 24px 0; text-align: center; font-size: 14px; color: #999;';\n timer.textContent = `⏰ Offer expires in ${config.timer_minutes} minutes`;\n modal.appendChild(timer);\n }\n \n const ctaButton = document.createElement('button');\n ctaButton.textContent = config.cta_text || 'Complete Checkout';\n ctaButton.style.cssText = `\n background: ${this.sanitizeColor(config.accent_color || '#FF6B00')};\n color: white;\n border: none;\n padding: 16px 32px;\n border-radius: 8px;\n font-weight: 700;\n font-size: 16px;\n cursor: pointer;\n width: 100%;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(widgetId, 'click', { type: 'cart_recovery' });\n const checkoutUrl = this.sanitizeUrl(config.cta_url || '/checkout');\n if (checkoutUrl) {\n window.location.href = checkoutUrl;\n }\n });\n \n modal.appendChild(ctaButton);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '×';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 16px;\n right: 16px;\n background: transparent;\n border: none;\n font-size: 28px;\n cursor: pointer;\n color: #999;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(widgetId, 'dismiss', { type: 'cart_recovery' });\n document.body.removeChild(overlay);\n this.renderedWidgets.delete(widgetId);\n });\n \n modal.appendChild(closeButton);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n \n this.trackEvent(widgetId, 'show', { type: 'cart_recovery', tier: config.tier });\n }\n \n private renderLeadGenPopup(widgetId: string, config: NonNullable<PrefetchWidgetConfig['exit_intent']>): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-exit-popup-overlay';\n overlay.setAttribute('data-widget-id', widgetId);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: aegisFadeIn 0.3s ease-out;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-leadgen-modal';\n modal.style.cssText = `\n background: white;\n border-radius: 16px;\n max-width: 500px;\n width: 90%;\n padding: 40px;\n box-shadow: 0 10px 40px rgba(0,0,0,0.3);\n text-align: center;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisScaleIn 0.3s ease-out;\n position: relative;\n `;\n \n const title = document.createElement('h2');\n title.textContent = config.title || 'Get 10% Off Your First Order!';\n title.style.cssText = 'margin: 0 0 16px 0; font-size: 28px; font-weight: 700; color: #1a1a1a;';\n modal.appendChild(title);\n \n const message = document.createElement('p');\n message.textContent = config.message || 'Subscribe to our newsletter and get an exclusive discount code.';\n message.style.cssText = 'margin: 0 0 24px 0; font-size: 16px; color: #666;';\n modal.appendChild(message);\n \n const form = document.createElement('form');\n \n const emailInput = document.createElement('input');\n emailInput.type = 'email';\n emailInput.placeholder = 'Enter your email';\n emailInput.required = true;\n emailInput.style.cssText = `\n width: 100%;\n padding: 14px;\n border: 2px solid #ddd;\n border-radius: 8px;\n font-size: 16px;\n margin-bottom: 16px;\n box-sizing: border-box;\n `;\n form.appendChild(emailInput);\n \n const submitButton = document.createElement('button');\n submitButton.type = 'submit';\n submitButton.textContent = 'Get My Discount';\n submitButton.style.cssText = `\n width: 100%;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: none;\n padding: 16px 32px;\n border-radius: 8px;\n font-weight: 700;\n font-size: 16px;\n cursor: pointer;\n `;\n form.appendChild(submitButton);\n \n form.addEventListener('submit', async (e) => {\n e.preventDefault();\n \n submitButton.disabled = true;\n submitButton.textContent = 'Submitting...';\n \n try {\n await this.trackEvent(widgetId, 'submit', { \n type: 'lead_gen',\n email: emailInput.value \n });\n \n modal.innerHTML = `\n <div style=\"text-align: center; padding: 20px;\">\n <div style=\"font-size: 48px; margin-bottom: 16px;\">✅</div>\n <h3 style=\"margin: 0 0 12px 0; color: #1a73e8;\">Thank You!</h3>\n <p style=\"margin: 0; color: #666;\">Check your email for your discount code!</p>\n </div>\n `;\n \n setTimeout(() => {\n document.body.removeChild(overlay);\n }, 2500);\n \n } catch (error) {\n this.log(`Error submitting lead gen form: ${error}`, true);\n submitButton.disabled = false;\n submitButton.textContent = 'Get My Discount';\n }\n });\n \n modal.appendChild(form);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '×';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 16px;\n right: 16px;\n background: transparent;\n border: none;\n font-size: 28px;\n cursor: pointer;\n color: #999;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(widgetId, 'dismiss', { type: 'lead_gen' });\n document.body.removeChild(overlay);\n this.renderedWidgets.delete(widgetId);\n });\n \n modal.appendChild(closeButton);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n \n this.trackEvent(widgetId, 'show', { type: 'lead_gen' });\n }\n \n private interpolateCartVariables(template: string): string {\n if (!this.cartData) return template;\n \n return template\n .replace(/\\{\\{cart_total\\}\\}/g, `${this.cartData.cart_currency} ${this.cartData.cart_total.toFixed(2)}`)\n .replace(/\\{\\{cart_currency\\}\\}/g, this.cartData.cart_currency)\n .replace(/\\{\\{cart_items_count\\}\\}/g, this.cartData.cart_items.length.toString());\n }\n \n private log(message: string, isError: boolean = false): void {\n if (this.debugMode || isError) {\n const method = isError ? 'error' : 'log';\n console[method](`[AegisWidgets] ${message}`);\n }\n }\n}\n","/**\n * TriggerEngine - Client-Side Trigger Evaluation\n * \n * Evaluates behavioral triggers that require real-time client state:\n * - Scroll depth (e.g., user scrolled >= 50%)\n * - Time on page (e.g., >= 30 seconds on current page)\n * - Exit intent (mouse leaving viewport toward browser controls)\n * - Inactivity (no user interaction for X seconds)\n * - Scroll velocity (mobile exit intent - fast upward scroll)\n * - Visibility change (tab/app switching)\n * - Back button (history navigation)\n * \n * Architecture:\n * - Server evaluates historical triggers (event counts, segments)\n * - Client evaluates behavioral triggers (scroll, time, exit intent)\n * - Zero latency - no server round trip needed\n * \n * Usage:\n * const trigger = new TriggerEngine();\n * trigger.on('scroll_depth_50', (data) => {\n * console.log('User scrolled to 50%', data);\n * });\n * trigger.start();\n */\n\nexport interface TriggerRule {\n type: 'scroll_depth' | 'time_on_page' | 'exit_intent' | 'inactivity' | 'scroll_velocity' | 'visibility_change' | 'back_button';\n config: ScrollDepthConfig | TimeOnPageConfig | ExitIntentConfig | InactivityConfig | ScrollVelocityConfig | VisibilityChangeConfig | BackButtonConfig;\n}\n\nexport interface ScrollDepthConfig {\n depth_percent: number;\n}\n\nexport interface TimeOnPageConfig {\n seconds: number;\n}\n\nexport interface ExitIntentConfig {\n enabled: boolean;\n}\n\nexport interface InactivityConfig {\n idle_seconds: number;\n}\n\nexport interface ScrollVelocityConfig {\n threshold: number;\n minScrollPosition: number;\n cooldown: number;\n}\n\nexport interface VisibilityChangeConfig {\n enabled: boolean;\n}\n\nexport interface BackButtonConfig {\n enabled: boolean;\n}\n\nexport interface TriggerEvent {\n type: string;\n data: Record<string, any>;\n timestamp: number;\n}\n\ntype TriggerCallback = (event: TriggerEvent) => void;\n\nexport class TriggerEngine {\n private listeners: Map<string, Set<TriggerCallback>> = new Map();\n private isStarted = false;\n \n private scrollDepthTargets = new Set<number>();\n private scrollDepthReached = new Set<number>();\n \n private timeOnPageTargets = new Map<number, number>();\n private pageLoadTime?: number;\n \n private exitIntentEnabled = false;\n private exitIntentFired = false;\n \n private inactivityTargets = new Map<number, number>();\n private lastActivityTime = Date.now();\n private inactivityCheckInterval?: number;\n \n private scrollVelocityEnabled = false;\n private scrollVelocityFired = false;\n private scrollVelocityConfig: ScrollVelocityConfig = {\n threshold: 0.5,\n minScrollPosition: 100,\n cooldown: 5000\n };\n private lastScrollY = 0;\n private lastScrollTime = Date.now();\n private scrollVelocityCooldownTimer?: number;\n \n private visibilityChangeEnabled = false;\n \n private backButtonEnabled = false;\n private backButtonFired = false;\n \n constructor() {}\n \n on(eventType: string, callback: TriggerCallback): void {\n if (!this.listeners.has(eventType)) {\n this.listeners.set(eventType, new Set());\n }\n this.listeners.get(eventType)!.add(callback);\n }\n \n off(eventType: string, callback: TriggerCallback): void {\n const callbacks = this.listeners.get(eventType);\n if (callbacks) {\n callbacks.delete(callback);\n }\n }\n \n registerScrollDepth(depthPercent: number): void {\n this.scrollDepthTargets.add(depthPercent);\n }\n \n registerTimeOnPage(seconds: number): void {\n if (!this.timeOnPageTargets.has(seconds)) {\n const timerId = window.setTimeout(() => {\n this.emit(`time_on_page_${seconds}`, {\n seconds,\n page_url: window.location.href\n });\n this.timeOnPageTargets.delete(seconds);\n }, seconds * 1000);\n \n this.timeOnPageTargets.set(seconds, timerId);\n }\n }\n \n registerExitIntent(): void {\n this.exitIntentEnabled = true;\n }\n \n registerInactivity(idleSeconds: number): void {\n if (!this.inactivityTargets.has(idleSeconds)) {\n const timerId = window.setTimeout(() => {\n const idleTime = (Date.now() - this.lastActivityTime) / 1000;\n \n if (idleTime >= idleSeconds) {\n this.emit(`inactivity_${idleSeconds}`, {\n idle_seconds: idleSeconds,\n actual_idle_time: idleTime\n });\n }\n \n this.inactivityTargets.delete(idleSeconds);\n }, idleSeconds * 1000);\n \n this.inactivityTargets.set(idleSeconds, timerId);\n }\n }\n \n registerScrollVelocity(config?: Partial<ScrollVelocityConfig>): void {\n this.scrollVelocityEnabled = true;\n \n if (config) {\n this.scrollVelocityConfig = {\n threshold: config.threshold ?? this.scrollVelocityConfig.threshold,\n minScrollPosition: config.minScrollPosition ?? this.scrollVelocityConfig.minScrollPosition,\n cooldown: config.cooldown ?? this.scrollVelocityConfig.cooldown\n };\n }\n }\n \n registerVisibilityChange(): void {\n this.visibilityChangeEnabled = true;\n }\n \n registerBackButton(): void {\n this.backButtonEnabled = true;\n }\n \n start(): void {\n if (this.isStarted) {\n return;\n }\n \n this.pageLoadTime = Date.now();\n this.lastActivityTime = Date.now();\n this.lastScrollY = window.scrollY || 0;\n this.lastScrollTime = Date.now();\n \n if (this.scrollDepthTargets.size > 0) {\n this.attachScrollListener();\n }\n \n if (this.exitIntentEnabled) {\n this.attachExitIntentListener();\n }\n \n if (this.scrollVelocityEnabled) {\n this.attachScrollVelocityListener();\n }\n \n if (this.visibilityChangeEnabled) {\n this.attachVisibilityChangeListener();\n }\n \n if (this.backButtonEnabled) {\n this.attachBackButtonListener();\n }\n \n this.attachActivityListeners();\n \n this.startInactivityCheck();\n \n this.isStarted = true;\n }\n \n stop(): void {\n if (!this.isStarted) {\n return;\n }\n \n this.removeScrollListener();\n this.removeExitIntentListener();\n this.removeScrollVelocityListener();\n this.removeVisibilityChangeListener();\n this.removeBackButtonListener();\n this.removeActivityListeners();\n \n this.timeOnPageTargets.forEach(timerId => clearTimeout(timerId));\n this.timeOnPageTargets.clear();\n \n this.inactivityTargets.forEach(timerId => clearTimeout(timerId));\n this.inactivityTargets.clear();\n \n if (this.inactivityCheckInterval) {\n clearInterval(this.inactivityCheckInterval);\n this.inactivityCheckInterval = undefined;\n }\n \n if (this.scrollVelocityCooldownTimer) {\n clearTimeout(this.scrollVelocityCooldownTimer);\n this.scrollVelocityCooldownTimer = undefined;\n }\n \n this.isStarted = false;\n }\n \n reset(): void {\n this.scrollDepthReached.clear();\n this.exitIntentFired = false;\n this.scrollVelocityFired = false;\n this.backButtonFired = false;\n this.pageLoadTime = Date.now();\n this.lastActivityTime = Date.now();\n this.lastScrollY = window.scrollY || 0;\n this.lastScrollTime = Date.now();\n \n if (this.scrollVelocityCooldownTimer) {\n clearTimeout(this.scrollVelocityCooldownTimer);\n this.scrollVelocityCooldownTimer = undefined;\n }\n }\n \n private attachScrollListener(): void {\n window.addEventListener('scroll', this.handleScroll, { passive: true });\n this.handleScroll();\n }\n \n private removeScrollListener(): void {\n window.removeEventListener('scroll', this.handleScroll);\n }\n \n private handleScroll = (): void => {\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n const scrollHeight = document.documentElement.scrollHeight - window.innerHeight;\n const scrollPercent = scrollHeight > 0 ? (scrollTop / scrollHeight) * 100 : 0;\n \n for (const targetDepth of this.scrollDepthTargets) {\n if (scrollPercent >= targetDepth && !this.scrollDepthReached.has(targetDepth)) {\n this.scrollDepthReached.add(targetDepth);\n \n this.emit(`scroll_depth_${targetDepth}`, {\n depth_percent: targetDepth,\n actual_percent: scrollPercent,\n scroll_top: scrollTop,\n scroll_height: scrollHeight\n });\n }\n }\n };\n \n private attachExitIntentListener(): void {\n document.addEventListener('mouseleave', this.handleExitIntent);\n }\n \n private removeExitIntentListener(): void {\n document.removeEventListener('mouseleave', this.handleExitIntent);\n }\n \n private handleExitIntent = (event: MouseEvent): void => {\n if (this.exitIntentFired) {\n return;\n }\n \n if (event.clientY < 10) {\n this.exitIntentFired = true;\n \n this.emit('exit_intent', {\n client_y: event.clientY,\n page_url: window.location.href,\n time_on_page: this.pageLoadTime ? (Date.now() - this.pageLoadTime) / 1000 : 0\n });\n }\n };\n \n private attachScrollVelocityListener(): void {\n window.addEventListener('scroll', this.handleScrollVelocity, { passive: true });\n }\n \n private removeScrollVelocityListener(): void {\n window.removeEventListener('scroll', this.handleScrollVelocity);\n }\n \n private handleScrollVelocity = (): void => {\n if (this.scrollVelocityFired) {\n return;\n }\n \n const currentY = window.scrollY || document.documentElement.scrollTop;\n const currentTime = Date.now();\n const timeDiff = currentTime - this.lastScrollTime;\n \n if (timeDiff > 100) {\n const distance = this.lastScrollY - currentY;\n const velocity = Math.abs(distance / timeDiff);\n \n if (\n distance > 0 &&\n velocity > this.scrollVelocityConfig.threshold &&\n currentY > this.scrollVelocityConfig.minScrollPosition\n ) {\n this.scrollVelocityFired = true;\n \n this.emit('mobile_exit_intent', {\n scroll_velocity: velocity,\n scroll_distance: distance,\n current_position: currentY,\n page_url: window.location.href,\n time_on_page: this.pageLoadTime ? (Date.now() - this.pageLoadTime) / 1000 : 0\n });\n \n this.scrollVelocityCooldownTimer = window.setTimeout(() => {\n this.scrollVelocityFired = false;\n }, this.scrollVelocityConfig.cooldown);\n }\n \n this.lastScrollY = currentY;\n this.lastScrollTime = currentTime;\n }\n };\n \n private attachVisibilityChangeListener(): void {\n document.addEventListener('visibilitychange', this.handleVisibilityChange);\n }\n \n private removeVisibilityChangeListener(): void {\n document.removeEventListener('visibilitychange', this.handleVisibilityChange);\n }\n \n private handleVisibilityChange = (): void => {\n if (document.hidden) {\n this.emit('visibility_hidden', {\n page_url: window.location.href,\n time_on_page: this.pageLoadTime ? (Date.now() - this.pageLoadTime) / 1000 : 0\n });\n } else {\n this.emit('visibility_visible', {\n page_url: window.location.href\n });\n }\n };\n \n private attachBackButtonListener(): void {\n if (typeof window !== 'undefined' && window.history) {\n window.history.pushState(null, '', window.location.href);\n window.addEventListener('popstate', this.handleBackButton);\n }\n }\n \n private removeBackButtonListener(): void {\n window.removeEventListener('popstate', this.handleBackButton);\n }\n \n private handleBackButton = (): void => {\n if (this.backButtonFired) {\n return;\n }\n \n this.backButtonFired = true;\n \n window.history.pushState(null, '', window.location.href);\n \n this.emit('back_button', {\n page_url: window.location.href,\n time_on_page: this.pageLoadTime ? (Date.now() - this.pageLoadTime) / 1000 : 0\n });\n };\n \n private attachActivityListeners(): void {\n const events = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click'];\n events.forEach(event => {\n document.addEventListener(event, this.handleActivity, { passive: true });\n });\n }\n \n private removeActivityListeners(): void {\n const events = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click'];\n events.forEach(event => {\n document.removeEventListener(event, this.handleActivity);\n });\n }\n \n private handleActivity = (): void => {\n this.lastActivityTime = Date.now();\n };\n \n private startInactivityCheck(): void {\n this.inactivityCheckInterval = window.setInterval(() => {\n const idleTime = (Date.now() - this.lastActivityTime) / 1000;\n \n for (const [idleSeconds] of this.inactivityTargets) {\n if (idleTime >= idleSeconds) {\n this.emit(`inactivity_${idleSeconds}`, {\n idle_seconds: idleSeconds,\n actual_idle_time: idleTime\n });\n \n const timerId = this.inactivityTargets.get(idleSeconds);\n if (timerId) {\n clearTimeout(timerId);\n this.inactivityTargets.delete(idleSeconds);\n }\n }\n }\n }, 1000);\n }\n \n private emit(eventType: string, data: Record<string, any>): void {\n const event: TriggerEvent = {\n type: eventType,\n data,\n timestamp: Date.now()\n };\n \n const callbacks = this.listeners.get(eventType);\n if (callbacks) {\n callbacks.forEach(callback => {\n try {\n callback(event);\n } catch (error) {\n console.error(`Error in trigger callback for ${eventType}:`, error);\n }\n });\n }\n \n const wildcardCallbacks = this.listeners.get('*');\n if (wildcardCallbacks) {\n wildcardCallbacks.forEach(callback => {\n try {\n callback(event);\n } catch (error) {\n console.error(`Error in wildcard trigger callback:`, error);\n }\n });\n }\n }\n}\n","/**\n * SDK Config Poller\n *\n * Fetches non-sensitive SDK configuration from GET /v1/sdk/config\n * with ETag/If-None-Match support for 304 responses.\n *\n * Polls every 5 minutes by default. Config changes are applied\n * to push/in-app managers without re-initialization.\n */\n\nimport { logger } from '../utils/logger';\n\nexport interface SdkConfig {\n version: string;\n push: {\n enabled: boolean;\n vapid_public_key: string | null;\n platforms: string[];\n };\n in_app: {\n enabled: boolean;\n };\n consent: {\n channels_requiring_opt_in: string[];\n };\n}\n\nexport interface SdkConfigPollerOptions {\n apiHost: string;\n writeKey: string;\n organizationId?: string;\n pollIntervalMs?: number;\n}\n\nexport type ConfigChangeCallback = (config: SdkConfig) => void;\n\nexport class SdkConfigPoller {\n private options: Required<Omit<SdkConfigPollerOptions, 'organizationId'>> & { organizationId?: string };\n private currentETag: string | null = null;\n private currentConfig: SdkConfig | null = null;\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n private listeners: ConfigChangeCallback[] = [];\n\n constructor(options: SdkConfigPollerOptions) {\n this.options = {\n pollIntervalMs: 300_000, // 5 minutes\n ...options,\n };\n }\n\n /**\n * Fetch config once (on init) and start polling.\n */\n async start(): Promise<SdkConfig | null> {\n const config = await this.fetchConfig();\n\n this.pollTimer = setInterval(() => {\n this.fetchConfig().catch((err) => {\n logger.warn('SDK config poll failed:', err);\n });\n }, this.options.pollIntervalMs);\n\n return config;\n }\n\n /**\n * Stop polling.\n */\n stop(): void {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n }\n\n /**\n * Register a callback for config changes.\n */\n onChange(callback: ConfigChangeCallback): () => void {\n this.listeners.push(callback);\n return () => {\n const idx = this.listeners.indexOf(callback);\n if (idx >= 0) this.listeners.splice(idx, 1);\n };\n }\n\n /**\n * Get current cached config.\n */\n getConfig(): SdkConfig | null {\n return this.currentConfig;\n }\n\n /**\n * Fetch config with ETag/304 support.\n */\n private async fetchConfig(): Promise<SdkConfig | null> {\n try {\n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.options.writeKey,\n 'Accept': 'application/json',\n };\n\n if (this.options.organizationId) {\n headers['X-Organization-ID'] = this.options.organizationId;\n }\n\n if (this.currentETag) {\n headers['If-None-Match'] = this.currentETag;\n }\n\n const response = await fetch(`${this.options.apiHost}/v1/sdk/config`, {\n method: 'GET',\n headers,\n });\n\n // 304 Not Modified — config unchanged\n if (response.status === 304) {\n return this.currentConfig;\n }\n\n if (!response.ok) {\n logger.warn(`SDK config fetch failed: HTTP ${response.status}`);\n return this.currentConfig;\n }\n\n const config: SdkConfig = await response.json();\n const newETag = response.headers.get('ETag');\n\n if (newETag) {\n this.currentETag = newETag;\n }\n\n // Detect changes\n const changed = !this.currentConfig ||\n JSON.stringify(this.currentConfig) !== JSON.stringify(config);\n\n this.currentConfig = config;\n\n if (changed) {\n for (const listener of this.listeners) {\n try {\n listener(config);\n } catch (err) {\n logger.warn('SDK config change listener error:', err);\n }\n }\n }\n\n return config;\n } catch (err) {\n logger.warn('SDK config fetch error:', err);\n return this.currentConfig;\n }\n }\n}\n","import { Aegis } from './core/analytics';\n\nconst aegis = new Aegis();\n\nexport default aegis;\n\nexport { Aegis } from './core/analytics';\nexport type { AegisConfig, CellEndpoint, CellRegion } from './types/config';\nexport type {\n AegisEvent,\n TrackEvent,\n IdentifyEvent,\n PageEvent,\n GroupEvent,\n AliasEvent,\n EventContext,\n BatchPayload,\n BatchResponse,\n} from './types/events';\nexport type { Plugin, PluginRegistry } from './types/plugin';\nexport { debounce, throttle } from './utils/debounce';\nexport type {\n ConsentPreferences,\n ConsentCategory,\n ConsentStatus,\n} from './utils/consent';\nexport { AegisInAppManager } from './inapp';\nexport type { InAppCampaign, AegisInAppConfig } from './inapp';\nexport { renderPreview } from './inapp';\n\nexport { AegisPlacementManager } from './placements/AegisPlacementManager';\nexport type {\n PlacementContent,\n PlacementSlot,\n AegisPlacementConfig,\n} from './placements/AegisPlacementManager';\n\nexport { AegisWidgetManager } from './widgets';\nexport type {\n WidgetConfig,\n GamificationPrize,\n AegisWidgetConfig,\n} from './widgets';\n\nexport { TriggerEngine } from './triggers';\nexport type {\n TriggerRule,\n ScrollDepthConfig,\n TimeOnPageConfig,\n ExitIntentConfig,\n InactivityConfig,\n TriggerEvent,\n} from './triggers';\n\nexport { SdkConfigPoller } from './core/sdk-config-poller';\nexport type { SdkConfig, SdkConfigPollerOptions, ConfigChangeCallback } from './core/sdk-config-poller';\n\nexport { AegisWebPush } from './push/AegisWebPush';\nexport type {\n AegisWebPushConfig,\n AegisAPIClient,\n ContactIdentity,\n PushEventTracker,\n} from './push/AegisWebPush';\n"],"names":["isMobile","mobileConfig"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/utils/debounce.ts","../src/inapp/AegisInAppManager.ts","../src/inapp/renderPreview.ts","../src/placements/AegisPlacementManager.ts","../src/widgets/AegisWidgetManager.ts","../src/triggers/TriggerEngine.ts","../src/core/sdk-config-poller.ts","../src/index.ts"],"sourcesContent":["export function debounce<T extends (...args: any[]) => any>(\n func: T,\n wait: number\n): (...args: Parameters<T>) => void {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n return function debounced(...args: Parameters<T>): void {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n }\n\n timeoutId = setTimeout(() => {\n func(...args);\n timeoutId = null;\n }, wait);\n };\n}\n\nexport function throttle<T extends (...args: any[]) => any>(\n func: T,\n limit: number\n): (...args: Parameters<T>) => void {\n let inThrottle = false;\n\n return function throttled(...args: Parameters<T>): void {\n if (!inThrottle) {\n func(...args);\n inThrottle = true;\n setTimeout(() => {\n inThrottle = false;\n }, limit);\n }\n };\n}\n","/**\n * AegisInAppManager - Web SDK In-App Messaging Module\n * \n * Real-time SSE architecture with client-side evaluation.\n * \n * Security:\n * - XSS Protection: Uses DOM APIs (createElement, textContent) instead of innerHTML\n * - URL Validation: Prevents javascript: protocol injection\n * - CSP Compatible: No inline styles in HTML strings\n * \n * Architecture:\n * - Connects to SSE endpoint for real-time campaign updates\n * - Initial fetch on load, then SSE for updates\n * - Caches campaigns locally in memory\n * - Evaluates trigger rules client-side\n * - Tracks events (impression, click, dismiss) asynchronously\n */\n\nexport interface InAppCampaign {\n id: string;\n type: 'modal' | 'banner' | 'tooltip' | 'full_screen' | 'half_interstitial' | 'alert' | 'pip';\n sub_type?: string;\n title: string;\n body: string;\n image_url?: string;\n video_url?: string;\n action_url?: string;\n button_text?: string;\n background_color?: string;\n text_color?: string;\n priority: number;\n expires_at?: string;\n frequency?: {\n max_impressions?: number;\n max_impressions_per_day?: number;\n cooldown_seconds?: number;\n };\n interactive_config?: Record<string, unknown>;\n client_trigger?: {\n type: string;\n config?: Record<string, unknown>;\n };\n assigned_variant_id?: string;\n}\n\nexport interface AegisInAppConfig {\n writeKey: string;\n apiHost?: string;\n userId?: string;\n contactId?: string;\n organizationId?: string;\n debugMode?: boolean;\n enableSSE?: boolean;\n}\n\nexport class AegisInAppManager {\n private writeKey: string;\n private apiHost: string;\n private userId?: string;\n private contactId?: string;\n private organizationId?: string;\n private debugMode: boolean;\n private enableSSE: boolean;\n \n private campaigns: InAppCampaign[] = [];\n private displayedCampaigns = new Set<string>();\n private eventSource?: EventSource;\n private isInitialized = false;\n private reconnectAttempts = 0;\n private maxReconnectAttempts = 5;\n \n constructor(config: AegisInAppConfig) {\n this.writeKey = config.writeKey;\n this.apiHost = config.apiHost || 'https://api.aegis.ai';\n this.userId = config.userId;\n this.contactId = config.contactId;\n this.organizationId = config.organizationId;\n this.debugMode = config.debugMode || false;\n this.enableSSE = config.enableSSE !== false;\n }\n \n async initialize(): Promise<void> {\n if (this.isInitialized) {\n this.log('AegisInApp already initialized');\n return;\n }\n\n // Mark user as returning for subsequent visits\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem('aegis_returning_user', '1');\n }\n\n await this.refreshCampaigns();\n\n if (this.enableSSE && this.organizationId) {\n this.connectSSE();\n }\n \n this.isInitialized = true;\n this.log('AegisInApp initialized successfully');\n }\n \n updateUserId(userId: string): void {\n this.userId = userId;\n this.refreshCampaigns();\n }\n \n updateContactId(contactId: string): void {\n this.contactId = contactId;\n this.disconnectSSE();\n if (this.enableSSE && this.organizationId) {\n this.connectSSE();\n }\n this.refreshCampaigns();\n }\n \n private connectSSE(): void {\n if (this.eventSource) {\n this.disconnectSSE();\n }\n \n if (!this.organizationId) {\n this.log('Cannot connect SSE without organization ID', 'warn');\n return;\n }\n \n const url = new URL('/v1/stream/realtime', this.apiHost);\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'X-Organization-ID': this.organizationId,\n };\n \n if (this.contactId) {\n headers['X-Contact-ID'] = this.contactId;\n }\n \n const queryParams = new URLSearchParams();\n Object.entries(headers).forEach(([key, value]) => {\n queryParams.append(key, value);\n });\n \n this.eventSource = new EventSource(`${url}?${queryParams.toString()}`);\n \n this.eventSource.addEventListener('open', () => {\n this.log('SSE connection established');\n this.reconnectAttempts = 0;\n });\n \n this.eventSource.addEventListener('in_app_campaign_updated', (event: MessageEvent) => {\n try {\n const data = JSON.parse(event.data);\n this.log(`Received in-app campaign update: ${data.campaign_id}`);\n this.refreshCampaigns();\n } catch (error) {\n this.log(`Error parsing SSE event: ${error}`, 'error');\n }\n });\n \n this.eventSource.addEventListener('heartbeat', (event: MessageEvent) => {\n this.log('SSE heartbeat received');\n });\n \n this.eventSource.addEventListener('error', (error) => {\n this.log('SSE connection error', 'error');\n \n if (this.eventSource?.readyState === EventSource.CLOSED) {\n this.attemptReconnect();\n }\n });\n }\n \n private disconnectSSE(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = undefined;\n this.log('SSE connection closed');\n }\n }\n \n private attemptReconnect(): void {\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n this.log('Max reconnect attempts reached, giving up', 'warn');\n return;\n }\n \n this.reconnectAttempts++;\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);\n \n this.log(`Reconnecting SSE in ${delay}ms (attempt ${this.reconnectAttempts})`);\n \n setTimeout(() => {\n if (this.isInitialized && this.enableSSE && this.organizationId) {\n this.connectSSE();\n }\n }, delay);\n }\n \n private async refreshCampaigns(): Promise<void> {\n try {\n // Build URL with client context for server-side targeting (Critical Fix B)\n const context = new URLSearchParams({\n device_type: this.detectDeviceType(),\n page_url: typeof window !== 'undefined' ? window.location.pathname : '/',\n });\n\n // Geo is resolved server-side from IP — no need to send\n context.set('is_new_user', this.isNewUser() ? 'true' : 'false');\n\n const url = `${this.apiHost}/v1/in-app/active?${context.toString()}`;\n\n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'Content-Type': 'application/json'\n };\n\n if (this.userId) {\n headers['X-User-ID'] = this.userId;\n }\n\n if (this.contactId) {\n headers['X-Contact-ID'] = this.contactId;\n }\n\n if (this.organizationId) {\n headers['X-Organization-ID'] = this.organizationId;\n }\n\n // Send cached A/B assignments so server can skip re-evaluation (Critical Fix C)\n const abAssignments = this.getABAssignments();\n if (Object.keys(abAssignments).length > 0) {\n headers['X-AB-Assignments'] = btoa(JSON.stringify(abAssignments));\n }\n\n const response = await fetch(url, {\n method: 'GET',\n headers\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch campaigns: ${response.status}`);\n }\n\n this.campaigns = await response.json();\n\n // Process A/B assignments from server response (Critical Fix C)\n this.processABAssignments(this.campaigns);\n\n this.log(`Fetched ${this.campaigns.length} campaigns`);\n\n this.tryDisplayNextCampaign();\n\n } catch (error) {\n this.log(`Error refreshing campaigns: ${error}`, 'error');\n }\n }\n\n // --- Client Context Helpers (Critical Fix B) ---\n\n private detectDeviceType(): 'mobile' | 'desktop' | 'tablet' {\n if (typeof navigator === 'undefined') return 'desktop';\n const ua = navigator.userAgent;\n if (/Mobi|Android/i.test(ua)) return 'mobile';\n if (/iPad|Tablet/i.test(ua)) return 'tablet';\n return 'desktop';\n }\n\n private isNewUser(): boolean {\n if (typeof localStorage === 'undefined') return true;\n return !localStorage.getItem('aegis_returning_user');\n }\n\n // --- A/B Assignment Persistence (Critical Fix C) ---\n\n private getABAssignments(): Record<string, string> {\n if (typeof localStorage === 'undefined') return {};\n try {\n return JSON.parse(localStorage.getItem('aegis_ab_assignments') || '{}');\n } catch {\n return {};\n }\n }\n\n private processABAssignments(campaigns: InAppCampaign[]): void {\n if (typeof localStorage === 'undefined') return;\n const stored = this.getABAssignments();\n for (const campaign of campaigns) {\n if (campaign.assigned_variant_id) {\n stored[campaign.id] = campaign.assigned_variant_id;\n }\n }\n localStorage.setItem('aegis_ab_assignments', JSON.stringify(stored));\n }\n\n private getVariantId(campaignId: string): string | undefined {\n const assignments = this.getABAssignments();\n return assignments[campaignId] ?? undefined;\n }\n \n private tryDisplayNextCampaign(): void {\n const campaign = this.campaigns.find(c => !this.displayedCampaigns.has(c.id));\n \n if (campaign) {\n this.displayCampaign(campaign);\n }\n }\n \n private displayCampaign(campaign: InAppCampaign): void {\n this.displayedCampaigns.add(campaign.id);\n\n // Sub-type routing: interactive types are handled by dedicated renderers\n const interactiveSubTypes = new Set([\n 'spin_wheel', 'scratch_card', 'nps_survey', 'quiz',\n 'countdown_offer', 'star_rating', 'quick_poll',\n ]);\n\n if (campaign.sub_type && interactiveSubTypes.has(campaign.sub_type)) {\n this.renderInteractive(campaign);\n this.trackEvent(campaign.id, 'impression');\n return;\n }\n\n switch (campaign.type) {\n case 'modal':\n this.renderModal(campaign);\n break;\n case 'banner':\n this.renderBanner(campaign);\n break;\n case 'full_screen':\n this.renderFullScreen(campaign);\n break;\n case 'half_interstitial':\n this.renderHalfInterstitial(campaign);\n break;\n case 'alert':\n this.renderAlert(campaign);\n break;\n case 'pip':\n this.renderPIP(campaign);\n break;\n case 'tooltip':\n this.renderTooltip(campaign);\n break;\n }\n\n this.trackEvent(campaign.id, 'impression');\n }\n\n /**\n * Renders interactive sub-type campaigns (spin wheel, NPS, quiz, etc.)\n * using DOM-safe rendering. These sub-types use the campaign's\n * interactive_config payload for type-specific behavior.\n */\n private renderInteractive(campaign: InAppCampaign): void {\n const ic = (campaign.interactive_config || {}) as Record<string, unknown>;\n const bg = this.sanitizeColor(campaign.background_color || '#4169e1');\n const text = this.sanitizeColor(campaign.text_color || '#ffffff');\n\n switch (campaign.sub_type) {\n case 'nps_survey':\n this.renderNPSSurvey(campaign, ic, bg, text);\n break;\n case 'countdown_offer':\n this.renderCountdownOffer(campaign, ic, bg, text);\n break;\n case 'star_rating':\n this.renderStarRating(campaign, ic, bg, text);\n break;\n case 'quick_poll':\n this.renderQuickPoll(campaign, ic, bg, text);\n break;\n case 'quiz':\n this.renderQuiz(campaign, ic, bg, text);\n break;\n case 'spin_wheel':\n case 'scratch_card':\n // These are handled by AegisWidgetManager — emit event for bridge\n this.log(`${campaign.sub_type} delegated to AegisWidgetManager`);\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent('aegis:render-widget', {\n detail: { campaign, sub_type: campaign.sub_type },\n }));\n }\n break;\n default:\n this.log(`Unknown interactive sub_type: ${campaign.sub_type}`, 'warn');\n this.renderModal(campaign);\n }\n }\n\n // --- Interactive Renderers ---\n\n private renderNPSSurvey(\n campaign: InAppCampaign,\n ic: Record<string, unknown>,\n bg: string,\n text: string\n ): void {\n const overlay = this.createOverlay('aegis-in-app-nps-overlay');\n const modal = document.createElement('div');\n modal.style.cssText = `\n max-width: 360px; width: 90%; border-radius: 16px; overflow: hidden;\n background: ${bg}; color: ${text}; animation: aegisScaleIn 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.15);\n `;\n\n const body = document.createElement('div');\n body.style.cssText = 'padding: 24px; text-align: center;';\n\n const question = document.createElement('div');\n question.style.cssText = 'font-size: 16px; font-weight: 700; margin-bottom: 16px;';\n question.textContent = (ic.nps_question as string) || 'How likely are you to recommend us?';\n body.appendChild(question);\n\n const scale = document.createElement('div');\n scale.style.cssText = 'display: flex; gap: 4px; justify-content: center; flex-wrap: wrap; margin-bottom: 12px;';\n for (let i = 0; i <= 10; i++) {\n const btn = document.createElement('span');\n btn.style.cssText = `\n width: 28px; height: 28px; border-radius: 6px; display: flex;\n align-items: center; justify-content: center; font-size: 11px;\n font-weight: 600; cursor: pointer; background: ${text}33; color: ${text};\n transition: transform 0.1s;\n `;\n btn.textContent = String(i);\n btn.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n });\n scale.appendChild(btn);\n }\n body.appendChild(scale);\n\n const labels = document.createElement('div');\n labels.style.cssText = 'display: flex; justify-content: space-between; font-size: 11px; opacity: 0.6; margin-bottom: 16px;';\n const notLikely = document.createElement('span');\n notLikely.textContent = 'Not likely';\n const veryLikely = document.createElement('span');\n veryLikely.textContent = 'Very likely';\n labels.appendChild(notLikely);\n labels.appendChild(veryLikely);\n body.appendChild(labels);\n\n this.addCloseButton(body, overlay, campaign.id);\n modal.appendChild(body);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n\n private renderCountdownOffer(\n campaign: InAppCampaign,\n ic: Record<string, unknown>,\n bg: string,\n text: string\n ): void {\n const overlay = this.createOverlay('aegis-in-app-countdown-overlay');\n const modal = document.createElement('div');\n modal.style.cssText = `\n max-width: 320px; width: 90%; border-radius: 16px; overflow: hidden;\n background: ${bg}; color: ${text}; animation: aegisScaleIn 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.15);\n `;\n\n const body = document.createElement('div');\n body.style.cssText = 'padding: 24px; text-align: center;';\n\n const title = document.createElement('div');\n title.style.cssText = 'font-size: 20px; font-weight: 700; margin-bottom: 8px;';\n title.textContent = campaign.title || 'Flash Sale';\n body.appendChild(title);\n\n const label = document.createElement('div');\n label.style.cssText = 'font-size: 13px; opacity: 0.8; margin-bottom: 12px;';\n label.textContent = (ic.countdown_label as string) || 'Sale ends in:';\n body.appendChild(label);\n\n // Countdown digits\n const digits = document.createElement('div');\n digits.style.cssText = 'display: flex; gap: 8px; justify-content: center; margin-bottom: 16px;';\n const digitStyle = `padding: 8px 12px; border-radius: 8px; font-size: 24px; font-weight: 700; font-family: monospace; background: ${text}22;`;\n for (const val of ['00', ':', '00', ':', '00']) {\n const el = document.createElement('span');\n if (val === ':') {\n el.style.cssText = 'font-size: 24px; font-weight: 700; align-self: center;';\n } else {\n el.style.cssText = digitStyle;\n }\n el.textContent = val;\n digits.appendChild(el);\n }\n body.appendChild(digits);\n\n // Start countdown from target or 2h default\n const targetStr = ic.countdown_target as string | undefined;\n if (targetStr) {\n const target = new Date(targetStr).getTime();\n const update = () => {\n const diff = Math.max(0, target - Date.now());\n const h = String(Math.floor(diff / 3600000)).padStart(2, '0');\n const m = String(Math.floor((diff % 3600000) / 60000)).padStart(2, '0');\n const s = String(Math.floor((diff % 60000) / 1000)).padStart(2, '0');\n const spans = digits.querySelectorAll('span');\n if (spans.length >= 5) {\n spans[0].textContent = h;\n spans[2].textContent = m;\n spans[4].textContent = s;\n }\n if (diff > 0) requestAnimationFrame(update);\n };\n update();\n }\n\n if (campaign.body) {\n const desc = document.createElement('div');\n desc.style.cssText = 'font-size: 14px; opacity: 0.85; margin-bottom: 16px;';\n desc.textContent = campaign.body;\n body.appendChild(desc);\n }\n\n if (campaign.button_text) {\n const btn = this.createCTAButton(campaign, bg, text);\n body.appendChild(btn);\n }\n\n this.addCloseButton(body, overlay, campaign.id);\n modal.appendChild(body);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n\n private renderStarRating(\n campaign: InAppCampaign,\n ic: Record<string, unknown>,\n bg: string,\n text: string\n ): void {\n const overlay = this.createOverlay('aegis-in-app-rating-overlay');\n const modal = document.createElement('div');\n modal.style.cssText = `\n max-width: 320px; width: 90%; border-radius: 16px; overflow: hidden;\n background: ${bg}; color: ${text}; animation: aegisScaleIn 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.15);\n `;\n\n const body = document.createElement('div');\n body.style.cssText = 'padding: 24px; text-align: center;';\n\n const title = document.createElement('div');\n title.style.cssText = 'font-size: 18px; font-weight: 700; margin-bottom: 16px;';\n title.textContent = campaign.title || 'Rate your experience';\n body.appendChild(title);\n\n const stars = document.createElement('div');\n stars.style.cssText = 'display: flex; gap: 8px; justify-content: center; margin-bottom: 16px;';\n const maxStars = (ic.rating_scale as number) || 5;\n for (let i = 1; i <= maxStars; i++) {\n const star = document.createElement('span');\n star.style.cssText = 'font-size: 32px; cursor: pointer; transition: transform 0.1s;';\n star.textContent = '\\u2606'; // ☆\n star.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n });\n star.addEventListener('mouseenter', () => { star.style.transform = 'scale(1.2)'; });\n star.addEventListener('mouseleave', () => { star.style.transform = 'scale(1)'; });\n stars.appendChild(star);\n }\n body.appendChild(stars);\n\n this.addCloseButton(body, overlay, campaign.id);\n modal.appendChild(body);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n\n private renderQuickPoll(\n campaign: InAppCampaign,\n ic: Record<string, unknown>,\n bg: string,\n text: string\n ): void {\n const overlay = this.createOverlay('aegis-in-app-poll-overlay');\n const modal = document.createElement('div');\n modal.style.cssText = `\n max-width: 320px; width: 90%; border-radius: 16px; overflow: hidden;\n background: ${bg}; color: ${text}; animation: aegisScaleIn 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.15);\n `;\n\n const body = document.createElement('div');\n body.style.cssText = 'padding: 24px; text-align: center;';\n\n const title = document.createElement('div');\n title.style.cssText = 'font-size: 16px; font-weight: 700; margin-bottom: 16px;';\n title.textContent = campaign.title || 'Quick question';\n body.appendChild(title);\n\n const options = (ic.poll_options as string[]) || [];\n const optionsList = document.createElement('div');\n optionsList.style.cssText = 'display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px;';\n for (const opt of options) {\n const optBtn = document.createElement('button');\n optBtn.style.cssText = `\n padding: 10px 16px; border-radius: 10px; border: 1px solid ${text}33;\n background: transparent; color: ${text}; font-size: 14px; cursor: pointer;\n text-align: left; transition: background 0.15s;\n `;\n optBtn.textContent = opt;\n optBtn.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n });\n optionsList.appendChild(optBtn);\n }\n body.appendChild(optionsList);\n\n this.addCloseButton(body, overlay, campaign.id);\n modal.appendChild(body);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n\n private renderQuiz(\n campaign: InAppCampaign,\n ic: Record<string, unknown>,\n bg: string,\n text: string\n ): void {\n const overlay = this.createOverlay('aegis-in-app-quiz-overlay');\n const modal = document.createElement('div');\n modal.style.cssText = `\n max-width: 360px; width: 90%; border-radius: 16px; overflow: hidden;\n background: ${bg}; color: ${text}; animation: aegisScaleIn 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.15);\n `;\n\n const body = document.createElement('div');\n body.style.cssText = 'padding: 24px; text-align: center;';\n\n const title = document.createElement('div');\n title.style.cssText = 'font-size: 18px; font-weight: 700; margin-bottom: 8px;';\n title.textContent = campaign.title || 'Quiz';\n body.appendChild(title);\n\n const questions = (ic.questions as Array<{ question: string; options: string[] }>) || [];\n let currentQ = 0;\n\n const renderQuestion = () => {\n // Clear previous content except title\n while (body.childNodes.length > 1) {\n body.removeChild(body.lastChild!);\n }\n\n if (currentQ >= questions.length) {\n const result = document.createElement('div');\n result.style.cssText = 'font-size: 16px; margin: 16px 0;';\n result.textContent = (ic.thank_you_message as string) || 'Thanks for completing the quiz!';\n body.appendChild(result);\n this.trackEvent(campaign.id, 'clicked');\n this.addCloseButton(body, overlay, campaign.id);\n return;\n }\n\n const q = questions[currentQ];\n const progress = document.createElement('div');\n progress.style.cssText = 'font-size: 12px; opacity: 0.6; margin-bottom: 12px;';\n progress.textContent = `Question ${currentQ + 1} of ${questions.length}`;\n body.appendChild(progress);\n\n const questionText = document.createElement('div');\n questionText.style.cssText = 'font-size: 14px; font-weight: 600; margin-bottom: 16px;';\n questionText.textContent = q.question;\n body.appendChild(questionText);\n\n const optionsDiv = document.createElement('div');\n optionsDiv.style.cssText = 'display: flex; flex-direction: column; gap: 8px;';\n for (const opt of q.options) {\n const optBtn = document.createElement('button');\n optBtn.style.cssText = `\n padding: 10px 16px; border-radius: 10px; border: 1px solid ${text}33;\n background: transparent; color: ${text}; font-size: 14px; cursor: pointer;\n text-align: left; transition: background 0.15s;\n `;\n optBtn.textContent = opt;\n optBtn.addEventListener('click', () => {\n currentQ++;\n renderQuestion();\n });\n optionsDiv.appendChild(optBtn);\n }\n body.appendChild(optionsDiv);\n this.addCloseButton(body, overlay, campaign.id);\n };\n\n renderQuestion();\n modal.appendChild(body);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n\n // --- Shared Rendering Helpers ---\n\n private createOverlay(className: string): HTMLElement {\n const overlay = document.createElement('div');\n overlay.className = className;\n overlay.style.cssText = `\n position: fixed; top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0,0,0,0.5); display: flex; align-items: center;\n justify-content: center; z-index: 99999; animation: aegisFadeIn 0.3s ease;\n `;\n return overlay;\n }\n\n private createCTAButton(campaign: InAppCampaign, bg: string, text: string): HTMLElement {\n const btn = document.createElement('button');\n btn.style.cssText = `\n display: inline-block; padding: 10px 28px; border-radius: 999px;\n font-size: 14px; font-weight: 600; cursor: pointer; border: none;\n background: ${text}; color: ${bg}; transition: transform 0.15s;\n `;\n btn.textContent = campaign.button_text || 'OK';\n btn.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n if (campaign.action_url) {\n const safeUrl = this.sanitizeUrl(campaign.action_url);\n if (safeUrl) window.open(safeUrl, '_blank');\n }\n });\n return btn;\n }\n\n private addCloseButton(container: HTMLElement, overlay: HTMLElement, campaignId: string): void {\n const close = document.createElement('div');\n close.style.cssText = 'margin-top: 12px; font-size: 12px; opacity: 0.6; cursor: pointer;';\n close.textContent = 'Close';\n close.addEventListener('click', () => {\n this.trackEvent(campaignId, 'dismissed');\n this.removeModal(overlay);\n });\n container.appendChild(close);\n }\n \n private renderBanner(campaign: InAppCampaign): void {\n const banner = document.createElement('div');\n banner.className = 'aegis-in-app-banner';\n banner.setAttribute('data-campaign-id', campaign.id);\n \n banner.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n background: ${this.sanitizeColor(campaign.background_color || '#1a73e8')};\n color: ${this.sanitizeColor(campaign.text_color || '#ffffff')};\n padding: 16px;\n z-index: 999999;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisSlideDown 0.3s ease-out;\n `;\n \n const contentContainer = document.createElement('div');\n contentContainer.style.cssText = 'flex: 1; display: flex; align-items: center; gap: 12px;';\n \n if (campaign.image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(campaign.image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = '';\n img.style.cssText = 'width: 40px; height: 40px; border-radius: 4px; object-fit: cover;';\n contentContainer.appendChild(img);\n }\n }\n \n const textContainer = document.createElement('div');\n textContainer.style.cssText = 'flex: 1;';\n \n const title = document.createElement('div');\n title.textContent = campaign.title;\n title.style.cssText = 'font-weight: 600; font-size: 14px; margin-bottom: 4px;';\n textContainer.appendChild(title);\n \n const body = document.createElement('div');\n body.textContent = campaign.body;\n body.style.cssText = 'font-size: 13px; opacity: 0.9;';\n textContainer.appendChild(body);\n \n contentContainer.appendChild(textContainer);\n \n const actionsContainer = document.createElement('div');\n actionsContainer.style.cssText = 'display: flex; align-items: center; gap: 12px; margin-left: 16px;';\n \n if (campaign.action_url && campaign.button_text) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = campaign.button_text;\n ctaButton.style.cssText = `\n background: white;\n color: ${this.sanitizeColor(campaign.background_color || '#1a73e8')};\n border: none;\n padding: 8px 16px;\n border-radius: 4px;\n font-weight: 600;\n cursor: pointer;\n font-size: 13px;\n white-space: nowrap;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n const safeUrl = this.sanitizeUrl(campaign.action_url!);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n this.removeBanner(banner);\n });\n \n actionsContainer.appendChild(ctaButton);\n }\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '✕';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n background: transparent;\n border: none;\n color: inherit;\n font-size: 20px;\n cursor: pointer;\n padding: 0;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0.7;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'dismissed');\n this.removeBanner(banner);\n });\n \n actionsContainer.appendChild(closeButton);\n \n banner.appendChild(contentContainer);\n banner.appendChild(actionsContainer);\n \n this.addAnimationStyles();\n document.body.appendChild(banner);\n }\n \n private renderModal(campaign: InAppCampaign): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-in-app-modal-overlay';\n overlay.setAttribute('data-campaign-id', campaign.id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: aegisFadeIn 0.3s ease-out;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-in-app-modal';\n modal.style.cssText = `\n background: white;\n border-radius: 8px;\n max-width: 500px;\n width: 90%;\n max-height: 80vh;\n overflow: auto;\n box-shadow: 0 10px 40px rgba(0,0,0,0.2);\n animation: aegisScaleIn 0.3s ease-out;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n `;\n \n if (campaign.image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(campaign.image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = '';\n img.style.cssText = 'width: 100%; height: 200px; object-fit: cover; border-radius: 8px 8px 0 0;';\n modal.appendChild(img);\n }\n }\n \n const content = document.createElement('div');\n content.style.cssText = 'padding: 24px;';\n \n const title = document.createElement('h2');\n title.textContent = campaign.title;\n title.style.cssText = 'margin: 0 0 12px 0; font-size: 20px; font-weight: 600; color: #1a1a1a;';\n content.appendChild(title);\n \n const body = document.createElement('p');\n body.textContent = campaign.body;\n body.style.cssText = 'margin: 0 0 20px 0; font-size: 15px; line-height: 1.5; color: #4a4a4a;';\n content.appendChild(body);\n \n const actions = document.createElement('div');\n actions.style.cssText = 'display: flex; gap: 12px; justify-content: flex-end;';\n \n if (campaign.action_url && campaign.button_text) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = campaign.button_text;\n ctaButton.style.cssText = `\n background: ${this.sanitizeColor(campaign.background_color || '#1a73e8')};\n color: ${this.sanitizeColor(campaign.text_color || '#ffffff')};\n border: none;\n padding: 10px 24px;\n border-radius: 6px;\n font-weight: 600;\n cursor: pointer;\n font-size: 14px;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n const safeUrl = this.sanitizeUrl(campaign.action_url!);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n this.removeModal(overlay);\n });\n \n actions.appendChild(ctaButton);\n }\n \n const closeButton = document.createElement('button');\n closeButton.textContent = 'Close';\n closeButton.style.cssText = `\n background: transparent;\n border: 1px solid #d0d0d0;\n color: #4a4a4a;\n padding: 10px 24px;\n border-radius: 6px;\n font-weight: 600;\n cursor: pointer;\n font-size: 14px;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'dismissed');\n this.removeModal(overlay);\n });\n \n actions.appendChild(closeButton);\n \n content.appendChild(actions);\n modal.appendChild(content);\n overlay.appendChild(modal);\n \n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private renderFullScreen(campaign: InAppCampaign): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-in-app-fullscreen-overlay';\n overlay.setAttribute('data-campaign-id', campaign.id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: ${this.sanitizeColor(campaign.background_color || '#ffffff')};\n color: ${this.sanitizeColor(campaign.text_color || '#1a1a1a')};\n z-index: 1000001;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n animation: aegisFadeIn 0.3s ease-out;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n overflow-y: auto;\n `;\n \n if (campaign.image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(campaign.image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = '';\n img.style.cssText = 'max-width: 100%; max-height: 40vh; object-fit: contain; margin-bottom: 32px;';\n overlay.appendChild(img);\n }\n }\n \n const contentContainer = document.createElement('div');\n contentContainer.style.cssText = 'max-width: 600px; text-align: center;';\n \n const title = document.createElement('h1');\n title.textContent = campaign.title;\n title.style.cssText = 'margin: 0 0 16px 0; font-size: 32px; font-weight: 700;';\n contentContainer.appendChild(title);\n \n const body = document.createElement('p');\n body.textContent = campaign.body;\n body.style.cssText = 'margin: 0 0 32px 0; font-size: 18px; line-height: 1.6; opacity: 0.9;';\n contentContainer.appendChild(body);\n \n if (campaign.action_url && campaign.button_text) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = campaign.button_text;\n ctaButton.style.cssText = `\n background: ${this.sanitizeColor(campaign.text_color || '#1a73e8')};\n color: ${this.sanitizeColor(campaign.background_color || '#ffffff')};\n border: none;\n padding: 16px 48px;\n border-radius: 8px;\n font-weight: 700;\n font-size: 18px;\n cursor: pointer;\n margin-bottom: 16px;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n const safeUrl = this.sanitizeUrl(campaign.action_url!);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n this.removeModal(overlay);\n });\n \n contentContainer.appendChild(ctaButton);\n }\n \n overlay.appendChild(contentContainer);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '✕';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 20px;\n right: 20px;\n background: transparent;\n border: none;\n color: inherit;\n font-size: 32px;\n cursor: pointer;\n padding: 0;\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0.6;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'dismissed');\n this.removeModal(overlay);\n });\n \n overlay.appendChild(closeButton);\n \n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private renderHalfInterstitial(campaign: InAppCampaign): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-in-app-half-interstitial-overlay';\n overlay.setAttribute('data-campaign-id', campaign.id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 1000000;\n display: flex;\n align-items: flex-end;\n justify-content: center;\n animation: aegisFadeIn 0.3s ease-out;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-in-app-half-interstitial';\n modal.style.cssText = `\n background: white;\n border-radius: 16px 16px 0 0;\n width: 100%;\n max-width: 600px;\n max-height: 60vh;\n overflow: auto;\n box-shadow: 0 -4px 20px rgba(0,0,0,0.2);\n animation: aegisSlideUp 0.3s ease-out;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n `;\n \n if (campaign.image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(campaign.image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = '';\n img.style.cssText = 'width: 100%; height: 200px; object-fit: cover;';\n modal.appendChild(img);\n }\n }\n \n const content = document.createElement('div');\n content.style.cssText = 'padding: 32px 24px;';\n \n const title = document.createElement('h2');\n title.textContent = campaign.title;\n title.style.cssText = 'margin: 0 0 12px 0; font-size: 24px; font-weight: 700; color: #1a1a1a;';\n content.appendChild(title);\n \n const body = document.createElement('p');\n body.textContent = campaign.body;\n body.style.cssText = 'margin: 0 0 24px 0; font-size: 16px; line-height: 1.5; color: #4a4a4a;';\n content.appendChild(body);\n \n if (campaign.action_url && campaign.button_text) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = campaign.button_text;\n ctaButton.style.cssText = `\n background: ${this.sanitizeColor(campaign.background_color || '#1a73e8')};\n color: ${this.sanitizeColor(campaign.text_color || '#ffffff')};\n border: none;\n padding: 14px 32px;\n border-radius: 8px;\n font-weight: 700;\n font-size: 16px;\n cursor: pointer;\n width: 100%;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n const safeUrl = this.sanitizeUrl(campaign.action_url!);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n this.removeModal(overlay);\n });\n \n content.appendChild(ctaButton);\n }\n \n modal.appendChild(content);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '✕';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 16px;\n right: 16px;\n background: rgba(255,255,255,0.9);\n border: none;\n color: #333;\n font-size: 24px;\n cursor: pointer;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n box-shadow: 0 2px 8px rgba(0,0,0,0.2);\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'dismissed');\n this.removeModal(overlay);\n });\n \n modal.style.position = 'relative';\n modal.appendChild(closeButton);\n \n overlay.appendChild(modal);\n \n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private renderAlert(campaign: InAppCampaign): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-in-app-alert-overlay';\n overlay.setAttribute('data-campaign-id', campaign.id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.6);\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: aegisFadeIn 0.2s ease-out;\n `;\n \n const alert = document.createElement('div');\n alert.className = 'aegis-in-app-alert';\n alert.style.cssText = `\n background: white;\n border-radius: 12px;\n max-width: 320px;\n width: 85%;\n box-shadow: 0 10px 40px rgba(0,0,0,0.3);\n animation: aegisScaleIn 0.2s ease-out;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n overflow: hidden;\n `;\n \n const content = document.createElement('div');\n content.style.cssText = 'padding: 24px 20px; text-align: center;';\n \n const title = document.createElement('h3');\n title.textContent = campaign.title;\n title.style.cssText = 'margin: 0 0 8px 0; font-size: 18px; font-weight: 700; color: #1a1a1a;';\n content.appendChild(title);\n \n const body = document.createElement('p');\n body.textContent = campaign.body;\n body.style.cssText = 'margin: 0; font-size: 14px; line-height: 1.4; color: #666;';\n content.appendChild(body);\n \n alert.appendChild(content);\n \n const buttonContainer = document.createElement('div');\n buttonContainer.style.cssText = 'display: flex; border-top: 1px solid #e0e0e0;';\n \n if (campaign.action_url && campaign.button_text) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = campaign.button_text;\n ctaButton.style.cssText = `\n flex: 1;\n background: transparent;\n border: none;\n border-right: 1px solid #e0e0e0;\n color: #1a73e8;\n padding: 14px;\n font-weight: 600;\n font-size: 16px;\n cursor: pointer;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'clicked');\n const safeUrl = this.sanitizeUrl(campaign.action_url!);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n this.removeModal(overlay);\n });\n \n buttonContainer.appendChild(ctaButton);\n }\n \n const cancelButton = document.createElement('button');\n cancelButton.textContent = 'Cancel';\n cancelButton.style.cssText = `\n flex: 1;\n background: transparent;\n border: none;\n color: #666;\n padding: 14px;\n font-weight: 600;\n font-size: 16px;\n cursor: pointer;\n `;\n \n cancelButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'dismissed');\n this.removeModal(overlay);\n });\n \n buttonContainer.appendChild(cancelButton);\n \n alert.appendChild(buttonContainer);\n overlay.appendChild(alert);\n \n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private renderPIP(campaign: InAppCampaign): void {\n const pip = document.createElement('div');\n pip.className = 'aegis-in-app-pip';\n pip.setAttribute('data-campaign-id', campaign.id);\n \n pip.style.cssText = `\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 320px;\n background: black;\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 8px 24px rgba(0,0,0,0.3);\n z-index: 999999;\n animation: aegisSlideUp 0.3s ease-out;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n `;\n \n if (campaign.video_url) {\n const video = document.createElement('video');\n const safeUrl = this.sanitizeUrl(campaign.video_url);\n if (safeUrl) {\n video.src = safeUrl;\n video.controls = true;\n video.autoplay = true;\n video.muted = true;\n video.style.cssText = 'width: 100%; display: block;';\n pip.appendChild(video);\n }\n } else if (campaign.image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(campaign.image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = '';\n img.style.cssText = 'width: 100%; display: block;';\n pip.appendChild(img);\n }\n }\n \n const overlay = document.createElement('div');\n overlay.style.cssText = `\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background: linear-gradient(to top, rgba(0,0,0,0.9), transparent);\n padding: 40px 16px 16px;\n color: white;\n `;\n \n const title = document.createElement('div');\n title.textContent = campaign.title;\n title.style.cssText = 'font-size: 14px; font-weight: 600; margin-bottom: 4px;';\n overlay.appendChild(title);\n \n const body = document.createElement('div');\n body.textContent = campaign.body;\n body.style.cssText = 'font-size: 12px; opacity: 0.9;';\n overlay.appendChild(body);\n \n pip.appendChild(overlay);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '✕';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 8px;\n right: 8px;\n background: rgba(0,0,0,0.6);\n border: none;\n color: white;\n font-size: 18px;\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(campaign.id, 'dismissed');\n pip.style.animation = 'aegisSlideDown 0.3s ease-out';\n setTimeout(() => {\n if (pip.parentNode) {\n pip.parentNode.removeChild(pip);\n }\n }, 300);\n });\n \n pip.appendChild(closeButton);\n \n if (campaign.action_url) {\n pip.style.cursor = 'pointer';\n pip.addEventListener('click', (e) => {\n if (e.target !== closeButton) {\n this.trackEvent(campaign.id, 'clicked');\n const safeUrl = this.sanitizeUrl(campaign.action_url!);\n if (safeUrl) {\n window.open(safeUrl, '_blank');\n }\n }\n });\n }\n \n this.addAnimationStyles();\n document.body.appendChild(pip);\n }\n \n private removeBanner(banner: HTMLElement): void {\n banner.style.animation = 'aegisSlideUp 0.3s ease-out';\n setTimeout(() => {\n if (banner.parentNode) {\n banner.parentNode.removeChild(banner);\n }\n }, 300);\n }\n \n private removeModal(overlay: HTMLElement): void {\n overlay.style.animation = 'aegisFadeOut 0.3s ease-out';\n setTimeout(() => {\n if (overlay.parentNode) {\n overlay.parentNode.removeChild(overlay);\n }\n }, 300);\n }\n \n private renderTooltip(campaign: InAppCampaign): void {\n const ic = (campaign.interactive_config || {}) as Record<string, unknown>;\n const anchorSelector = (ic.tooltip_anchor_selector as string) || '[data-aegis-tooltip]';\n const preferredPosition = (ic.tooltip_position as string) || 'bottom'; // top | bottom | left | right\n\n const anchor = document.querySelector(anchorSelector);\n if (!anchor) {\n this.log(`Tooltip anchor not found: ${anchorSelector}`, 'warn');\n return;\n }\n\n const bg = this.sanitizeColor(campaign.background_color || '#1a1a1a');\n const textColor = this.sanitizeColor(campaign.text_color || '#ffffff');\n\n // Tooltip container (positioned absolute to body)\n const tooltip = document.createElement('div');\n tooltip.className = 'aegis-in-app-tooltip';\n tooltip.setAttribute('data-campaign-id', campaign.id);\n tooltip.style.cssText = `\n position: absolute; z-index: 1000001; max-width: 280px; width: max-content;\n background: ${bg}; color: ${textColor}; border-radius: 10px; padding: 14px 16px;\n box-shadow: 0 8px 24px rgba(0,0,0,0.18); font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisScaleIn 0.2s ease-out; pointer-events: auto;\n `;\n\n // Arrow\n const arrow = document.createElement('div');\n arrow.className = 'aegis-tooltip-arrow';\n arrow.style.cssText = `\n position: absolute; width: 10px; height: 10px; background: ${bg};\n transform: rotate(45deg);\n `;\n\n // Close button\n const closeBtn = document.createElement('button');\n closeBtn.textContent = '\\u00d7';\n closeBtn.style.cssText = `\n position: absolute; top: 6px; right: 8px; background: none; border: none;\n color: ${textColor}; opacity: 0.6; font-size: 16px; cursor: pointer; padding: 0; line-height: 1;\n `;\n\n const dismiss = () => {\n tooltip.style.animation = 'aegisFadeOut 0.2s ease-out';\n setTimeout(() => { tooltip.parentNode?.removeChild(tooltip); }, 200);\n this.trackEvent(campaign.id, 'dismissed');\n };\n\n closeBtn.addEventListener('click', (e) => { e.stopPropagation(); dismiss(); });\n\n // Title\n if (campaign.title) {\n const title = document.createElement('div');\n title.textContent = campaign.title;\n title.style.cssText = 'font-size: 13px; font-weight: 700; margin-bottom: 4px; padding-right: 16px;';\n tooltip.appendChild(title);\n }\n\n // Body\n const body = document.createElement('div');\n body.textContent = campaign.body;\n body.style.cssText = 'font-size: 12px; line-height: 1.4; opacity: 0.9;';\n tooltip.appendChild(body);\n\n // CTA button\n if (campaign.button_text && campaign.action_url) {\n const cta = document.createElement('a');\n cta.textContent = campaign.button_text;\n cta.href = campaign.action_url;\n cta.style.cssText = `\n display: inline-block; margin-top: 8px; font-size: 12px; font-weight: 600;\n color: ${textColor}; text-decoration: underline; cursor: pointer;\n `;\n cta.addEventListener('click', () => { this.trackEvent(campaign.id, 'clicked'); });\n tooltip.appendChild(cta);\n }\n\n tooltip.appendChild(closeBtn);\n tooltip.appendChild(arrow);\n document.body.appendChild(tooltip);\n\n // Position relative to anchor\n const anchorRect = anchor.getBoundingClientRect();\n const tooltipRect = tooltip.getBoundingClientRect();\n const scrollX = window.scrollX;\n const scrollY = window.scrollY;\n const gap = 10;\n\n let top = 0;\n let left = 0;\n let arrowTop = '';\n let arrowLeft = '';\n let arrowBottom = '';\n let arrowRight = '';\n\n switch (preferredPosition) {\n case 'top':\n top = anchorRect.top + scrollY - tooltipRect.height - gap;\n left = anchorRect.left + scrollX + (anchorRect.width - tooltipRect.width) / 2;\n arrowBottom = '-5px';\n arrowLeft = `${tooltipRect.width / 2 - 5}px`;\n break;\n case 'left':\n top = anchorRect.top + scrollY + (anchorRect.height - tooltipRect.height) / 2;\n left = anchorRect.left + scrollX - tooltipRect.width - gap;\n arrowRight = '-5px';\n arrowTop = `${tooltipRect.height / 2 - 5}px`;\n break;\n case 'right':\n top = anchorRect.top + scrollY + (anchorRect.height - tooltipRect.height) / 2;\n left = anchorRect.right + scrollX + gap;\n arrowLeft = '-5px';\n arrowTop = `${tooltipRect.height / 2 - 5}px`;\n break;\n default: // bottom\n top = anchorRect.bottom + scrollY + gap;\n left = anchorRect.left + scrollX + (anchorRect.width - tooltipRect.width) / 2;\n arrowTop = '-5px';\n arrowLeft = `${tooltipRect.width / 2 - 5}px`;\n break;\n }\n\n // Clamp to viewport\n left = Math.max(8, Math.min(left, window.innerWidth + scrollX - tooltipRect.width - 8));\n top = Math.max(8, top);\n\n tooltip.style.top = `${top}px`;\n tooltip.style.left = `${left}px`;\n arrow.style.top = arrowTop || '';\n arrow.style.left = arrowLeft || '';\n arrow.style.bottom = arrowBottom || '';\n arrow.style.right = arrowRight || '';\n\n // Dismiss on outside click\n const outsideClickHandler = (e: MouseEvent) => {\n if (!tooltip.contains(e.target as Node) && !anchor.contains(e.target as Node)) {\n document.removeEventListener('click', outsideClickHandler);\n dismiss();\n }\n };\n setTimeout(() => document.addEventListener('click', outsideClickHandler), 100);\n }\n\n private addAnimationStyles(): void {\n if (document.getElementById('aegis-in-app-styles')) {\n return;\n }\n \n const style = document.createElement('style');\n style.id = 'aegis-in-app-styles';\n style.textContent = `\n @keyframes aegisSlideDown {\n from { transform: translateY(-100%); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n }\n \n @keyframes aegisSlideUp {\n from { transform: translateY(0); opacity: 1; }\n to { transform: translateY(-100%); opacity: 0; }\n }\n \n @keyframes aegisFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n \n @keyframes aegisFadeOut {\n from { opacity: 1; }\n to { opacity: 0; }\n }\n \n @keyframes aegisScaleIn {\n from { transform: scale(0.9); opacity: 0; }\n to { transform: scale(1); opacity: 1; }\n }\n `;\n \n document.head.appendChild(style);\n }\n \n private sanitizeUrl(url: string): string | null {\n try {\n const parsedUrl = new URL(url, window.location.origin);\n \n if (parsedUrl.protocol === 'javascript:' || parsedUrl.protocol === 'data:') {\n this.log(`Blocked unsafe URL: ${url}`, 'error');\n return null;\n }\n \n return parsedUrl.href;\n } catch (error) {\n this.log(`Invalid URL: ${url}`, 'error');\n return null;\n }\n }\n \n private sanitizeColor(color: string): string {\n if (/^#[0-9A-Fa-f]{3,6}$/.test(color)) {\n return color;\n }\n \n if (/^rgb\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*\\)$/.test(color)) {\n return color;\n }\n \n if (/^rgba\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*[\\d.]+\\s*\\)$/.test(color)) {\n return color;\n }\n \n const namedColors = ['white', 'black', 'red', 'green', 'blue', 'yellow', 'orange', 'purple', 'pink', 'gray', 'transparent'];\n if (namedColors.includes(color.toLowerCase())) {\n return color;\n }\n \n return '#000000';\n }\n \n /**\n * Track in-app event via the standard Event Ingress pipeline.\n *\n * Events flow: SDK → Event Ingress → Kafka → Governance Consumer\n * → Event Engine → ClickHouse (in_app_events + events_with_ttl)\n *\n * The event_type uses the canonical prefix `in_app.` so the event\n * switchboard maps it to the correct canonical form:\n * in_app.impression → engagement.view\n * in_app.clicked → engagement.click\n * in_app.dismissed → engagement.dismiss\n */\n private async trackEvent(campaignId: string, eventType: 'impression' | 'clicked' | 'dismissed'): Promise<void> {\n try {\n const url = `${this.apiHost}/api/v1/events`;\n const now = new Date().toISOString();\n const externalEventId = `inapp_${campaignId}_${eventType}_${Date.now()}`;\n\n const ingressEvent = {\n tenant_id: this.organizationId || 'unknown',\n source: 'in_app_sdk',\n external_event_id: externalEventId,\n event_type: `in_app.${eventType}`,\n timestamp: now,\n payload: {\n campaign_id: campaignId,\n event_type: eventType,\n user_id: this.userId,\n contact_id: this.contactId,\n platform: 'web',\n variant_id: this.getVariantId(campaignId) ?? undefined,\n },\n trace_id: externalEventId,\n metadata: {\n write_key: this.writeKey,\n },\n };\n\n fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Aegis-Write-Key': this.writeKey,\n },\n body: JSON.stringify(ingressEvent),\n }).catch(error => {\n this.log(`Error tracking event: ${error}`, 'error');\n });\n\n this.log(`Tracked ${eventType} event for campaign ${campaignId}`);\n } catch (error) {\n this.log(`Error tracking event: ${error}`, 'error');\n }\n }\n \n private log(message: string, level: 'log' | 'warn' | 'error' = 'log'): void {\n if (this.debugMode) {\n console[level](`[AegisInApp] ${message}`);\n }\n }\n \n destroy(options?: { clearABState?: boolean }): void {\n this.disconnectSSE();\n\n document.querySelectorAll(\n '.aegis-in-app-banner, .aegis-in-app-modal-overlay, .aegis-in-app-fullscreen-overlay, ' +\n '.aegis-in-app-half-interstitial-overlay, .aegis-in-app-alert-overlay, .aegis-in-app-pip, ' +\n '.aegis-in-app-nps-overlay, .aegis-in-app-countdown-overlay, .aegis-in-app-rating-overlay, ' +\n '.aegis-in-app-poll-overlay, .aegis-in-app-quiz-overlay'\n ).forEach(el => {\n if (el.parentNode) {\n el.parentNode.removeChild(el);\n }\n });\n\n const styles = document.getElementById('aegis-in-app-styles');\n if (styles && styles.parentNode) {\n styles.parentNode.removeChild(styles);\n }\n\n // Optionally clear A/B assignment state\n if (options?.clearABState && typeof localStorage !== 'undefined') {\n localStorage.removeItem('aegis_ab_assignments');\n }\n\n this.isInitialized = false;\n this.log('AegisInApp destroyed');\n }\n}\n","/**\n * renderPreview — Static Preview Renderer for Dashboard iframe (Critical Fix A)\n *\n * Used exclusively by the sandboxed iframe preview route\n * (`/api/preview/in-app/route.tsx`). Renders a single campaign into the\n * current document body using the same rendering logic as the production SDK.\n *\n * Data flow:\n * editor-sidebar.tsx → onChange → formState → postMessage({type:'preview_update', config})\n * → iframe receives message → calls renderPreview(config)\n *\n * This ensures 100% fidelity between the dashboard editor preview and\n * production rendering — both use the same SDK code.\n */\n\nimport type { InAppCampaign } from './AegisInAppManager';\nimport { AegisInAppManager } from './AegisInAppManager';\n\n/**\n * Renders a single in-app campaign into the current document for preview.\n *\n * Creates a temporary AegisInAppManager with preview-only config (no tracking,\n * no SSE, no network requests). Calls the same rendering pipeline as production.\n */\nexport function renderPreview(config: InAppCampaign & { interactive_config?: Record<string, unknown> }): void {\n // Clear previous preview\n document.querySelectorAll(\n '[class^=\"aegis-in-app-\"]'\n ).forEach((el) => {\n if (el.parentNode) {\n el.parentNode.removeChild(el);\n }\n });\n\n if (!config) return;\n\n // Create a lightweight preview-only manager\n const manager = new AegisInAppManager({\n writeKey: 'preview-mode',\n apiHost: '',\n debugMode: false,\n enableSSE: false,\n });\n\n // Override trackEvent to be a no-op in preview mode\n // Access private via any cast — preview only, not production code\n const m = manager as unknown as {\n displayCampaign: (campaign: InAppCampaign) => void;\n trackEvent: (campaignId: string, eventType: string) => Promise<void>;\n addAnimationStyles: () => void;\n };\n\n // No-op tracking for preview\n m.trackEvent = async () => {};\n\n // Ensure animation styles are injected\n m.addAnimationStyles();\n\n // Render the campaign\n m.displayCampaign(config);\n}\n","/**\n * AegisPlacementManager - Web SDK Placement Module\n * \n * Real-time SSE architecture for inline content placements.\n * \n * Security:\n * - XSS Protection: Uses DOMPurify (when available) with allowlisted tags/attrs; safe text-only fallback\n * - URL Validation: Prevents javascript: protocol injection\n * - CSP Compatible: No inline styles in HTML strings\n * \n * Architecture:\n * - Connects to SSE endpoint for real-time placement updates\n * - Initial fetch on load, then SSE for updates\n * - Caches placement content locally in memory\n * - Renders content into pre-defined UI slots (inline, not overlay)\n * - Tracks events (impression, click, conversion) asynchronously\n * \n * Key Differences from In-App Messages:\n * - INLINE content (part of layout), not overlays\n * - Content rendered immediately on slot registration\n * - No trigger rules (shown when slot loads)\n * - Supports banner, card, carousel, video, HTML content types\n */\n\nexport interface PlacementContent {\n placement_id: string;\n variant_id: string;\n content_type: 'banner' | 'card' | 'carousel' | 'video' | 'html' | 'dynamic_injection';\n content: Record<string, any>;\n css_selector?: string;\n injection_mode?: 'replace' | 'append' | 'prepend';\n}\n\nexport interface PlacementSlot {\n placementId: string;\n containerId: string;\n fallbackContent?: string;\n onRender?: (content: PlacementContent) => void;\n onError?: (error: Error) => void;\n}\n\nexport interface AegisPlacementConfig {\n writeKey: string;\n apiHost?: string;\n userId?: string;\n contactId?: string;\n organizationId?: string;\n debugMode?: boolean;\n enableSSE?: boolean;\n}\n\nexport class AegisPlacementManager {\n private writeKey: string;\n private apiHost: string;\n private userId?: string;\n private contactId?: string;\n private organizationId?: string;\n private debugMode: boolean;\n private enableSSE: boolean;\n \n private placements: Map<string, PlacementContent> = new Map();\n private slots: Map<string, PlacementSlot> = new Map();\n private renderedSlots = new Set<string>();\n private eventSource?: EventSource;\n private isInitialized = false;\n private reconnectAttempts = 0;\n private maxReconnectAttempts = 5;\n \n constructor(config: AegisPlacementConfig) {\n this.writeKey = config.writeKey;\n this.apiHost = config.apiHost || 'https://api.aegis.ai';\n this.userId = config.userId;\n this.contactId = config.contactId;\n this.organizationId = config.organizationId;\n this.debugMode = config.debugMode || false;\n this.enableSSE = config.enableSSE !== false;\n }\n \n async initialize(): Promise<void> {\n if (this.isInitialized) {\n this.log('AegisPlacements already initialized');\n return;\n }\n \n await this.refreshPlacements();\n \n if (this.enableSSE && this.organizationId) {\n this.connectSSE();\n }\n \n this.isInitialized = true;\n this.log('AegisPlacements initialized successfully');\n }\n \n register(placementId: string, options: Omit<PlacementSlot, 'placementId'>): void {\n const slot: PlacementSlot = {\n placementId,\n ...options\n };\n \n this.slots.set(placementId, slot);\n this.log(`Registered placement slot: ${placementId}`);\n \n const existingContent = this.placements.get(placementId);\n if (existingContent) {\n this.renderSlot(slot, existingContent);\n } else if (options.fallbackContent) {\n this.renderFallback(slot);\n }\n }\n \n unregister(placementId: string): void {\n this.slots.delete(placementId);\n this.renderedSlots.delete(placementId);\n this.log(`Unregistered placement slot: ${placementId}`);\n }\n \n async refreshPlacements(): Promise<void> {\n try {\n const placementIds = Array.from(this.slots.keys());\n \n if (placementIds.length === 0) {\n this.log('No registered slots, skipping refresh');\n return;\n }\n \n const url = `${this.apiHost}/v1/placements/content?placement_ids=${placementIds.join(',')}`;\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'X-Device-Type': this.getDeviceType(),\n 'X-Platform': 'web'\n };\n \n if (this.userId) headers['X-User-ID'] = this.userId;\n if (this.contactId) headers['X-Contact-ID'] = this.contactId;\n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n \n const response = await fetch(url, { headers });\n \n if (!response.ok) {\n throw new Error(`Failed to fetch placements: ${response.status}`);\n }\n \n const data = await response.json();\n \n this.placements.clear();\n \n for (const placement of data.placements || []) {\n this.placements.set(placement.placement_id, placement);\n }\n \n this.renderAllSlots();\n \n this.log(`Refreshed ${this.placements.size} placements`);\n \n } catch (error) {\n this.log(`Error refreshing placements: ${error}`, true);\n }\n }\n \n private renderAllSlots(): void {\n for (const [placementId, slot] of this.slots.entries()) {\n const content = this.placements.get(placementId);\n \n if (content) {\n this.renderSlot(slot, content);\n } else if (slot.fallbackContent) {\n this.renderFallback(slot);\n }\n }\n }\n \n private renderSlot(slot: PlacementSlot, content: PlacementContent): void {\n try {\n if (content.content_type === 'dynamic_injection') {\n this.renderDynamicInjection(content);\n } else {\n const container = document.getElementById(slot.containerId);\n \n if (!container) {\n this.log(`Container not found: ${slot.containerId}`, true);\n return;\n }\n \n container.innerHTML = '';\n \n switch (content.content_type) {\n case 'banner':\n this.renderBanner(container, content);\n break;\n case 'card':\n this.renderCard(container, content);\n break;\n case 'carousel':\n this.renderCarousel(container, content);\n break;\n case 'video':\n this.renderVideo(container, content);\n break;\n case 'html':\n this.renderHTML(container, content);\n break;\n default:\n this.log(`Unknown content type: ${content.content_type}`, true);\n return;\n }\n }\n \n if (!this.renderedSlots.has(slot.placementId)) {\n this.trackEvent(content.placement_id, content.variant_id, 'impression');\n this.renderedSlots.add(slot.placementId);\n }\n \n if (slot.onRender) {\n slot.onRender(content);\n }\n \n this.log(`Rendered placement: ${content.placement_id} (${content.content_type})`);\n \n } catch (error) {\n this.log(`Error rendering placement: ${error}`, true);\n \n if (slot.onError) {\n slot.onError(error as Error);\n }\n }\n }\n \n private renderBanner(container: HTMLElement, content: PlacementContent): void {\n const { title, body, image_url, cta_text, cta_url, background_color, text_color } = content.content;\n \n const banner = document.createElement('div');\n banner.className = 'aegis-placement-banner';\n banner.style.cssText = `\n background: ${this.sanitizeColor(background_color || '#1a73e8')};\n color: ${this.sanitizeColor(text_color || '#ffffff')};\n padding: 24px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n gap: 16px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n `;\n \n if (image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = '';\n img.style.cssText = 'width: 80px; height: 80px; border-radius: 8px; object-fit: cover;';\n banner.appendChild(img);\n }\n }\n \n const textContainer = document.createElement('div');\n textContainer.style.cssText = 'flex: 1;';\n \n if (title) {\n const titleEl = document.createElement('div');\n titleEl.textContent = title;\n titleEl.style.cssText = 'font-size: 18px; font-weight: 600; margin-bottom: 8px;';\n textContainer.appendChild(titleEl);\n }\n \n if (body) {\n const bodyEl = document.createElement('div');\n bodyEl.textContent = body;\n bodyEl.style.cssText = 'font-size: 14px; opacity: 0.9;';\n textContainer.appendChild(bodyEl);\n }\n \n banner.appendChild(textContainer);\n \n if (cta_text && cta_url) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = cta_text;\n ctaButton.style.cssText = `\n background: white;\n color: ${this.sanitizeColor(background_color || '#1a73e8')};\n border: none;\n padding: 12px 24px;\n border-radius: 6px;\n font-weight: 600;\n cursor: pointer;\n font-size: 14px;\n white-space: nowrap;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(content.placement_id, content.variant_id, 'click');\n const safeUrl = this.sanitizeUrl(cta_url);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n });\n \n banner.appendChild(ctaButton);\n }\n \n container.appendChild(banner);\n }\n \n private renderCard(container: HTMLElement, content: PlacementContent): void {\n const { title, body, image_url, cta_text, cta_url } = content.content;\n \n const card = document.createElement('div');\n card.className = 'aegis-placement-card';\n card.style.cssText = `\n background: white;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n overflow: hidden;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n `;\n \n if (image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = title || '';\n img.style.cssText = 'width: 100%; height: 200px; object-fit: cover;';\n card.appendChild(img);\n }\n }\n \n const cardBody = document.createElement('div');\n cardBody.style.cssText = 'padding: 20px;';\n \n if (title) {\n const titleEl = document.createElement('h3');\n titleEl.textContent = title;\n titleEl.style.cssText = 'margin: 0 0 12px 0; font-size: 20px; font-weight: 600; color: #1a1a1a;';\n cardBody.appendChild(titleEl);\n }\n \n if (body) {\n const bodyEl = document.createElement('p');\n bodyEl.textContent = body;\n bodyEl.style.cssText = 'margin: 0 0 16px 0; font-size: 14px; color: #666; line-height: 1.5;';\n cardBody.appendChild(bodyEl);\n }\n \n if (cta_text && cta_url) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = cta_text;\n ctaButton.style.cssText = `\n background: #1a73e8;\n color: white;\n border: none;\n padding: 10px 20px;\n border-radius: 6px;\n font-weight: 600;\n cursor: pointer;\n font-size: 14px;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(content.placement_id, content.variant_id, 'click');\n const safeUrl = this.sanitizeUrl(cta_url);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n });\n \n cardBody.appendChild(ctaButton);\n }\n \n card.appendChild(cardBody);\n container.appendChild(card);\n }\n \n private renderCarousel(container: HTMLElement, content: PlacementContent): void {\n const { items } = content.content;\n \n if (!Array.isArray(items) || items.length === 0) {\n this.log('Carousel items empty or invalid', true);\n return;\n }\n \n const carousel = document.createElement('div');\n carousel.className = 'aegis-placement-carousel';\n carousel.style.cssText = `\n display: flex;\n gap: 16px;\n overflow-x: auto;\n padding: 8px 0;\n scroll-behavior: smooth;\n -webkit-overflow-scrolling: touch;\n `;\n \n for (const item of items) {\n const carouselItem = document.createElement('div');\n carouselItem.style.cssText = `\n flex: 0 0 250px;\n background: white;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n overflow: hidden;\n cursor: pointer;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n `;\n \n if (item.image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(item.image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = item.title || '';\n img.style.cssText = 'width: 100%; height: 150px; object-fit: cover;';\n carouselItem.appendChild(img);\n }\n }\n \n const itemContent = document.createElement('div');\n itemContent.style.cssText = 'padding: 12px;';\n \n if (item.title) {\n const title = document.createElement('div');\n title.textContent = item.title;\n title.style.cssText = 'font-size: 14px; font-weight: 600; margin-bottom: 4px; color: #1a1a1a;';\n itemContent.appendChild(title);\n }\n \n if (item.price) {\n const price = document.createElement('div');\n price.textContent = item.price;\n price.style.cssText = 'font-size: 16px; font-weight: 700; color: #1a73e8;';\n itemContent.appendChild(price);\n }\n \n carouselItem.appendChild(itemContent);\n \n if (item.url) {\n carouselItem.addEventListener('click', () => {\n this.trackEvent(content.placement_id, content.variant_id, 'click', { item_index: items.indexOf(item) });\n const safeUrl = this.sanitizeUrl(item.url);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n });\n }\n \n carousel.appendChild(carouselItem);\n }\n \n container.appendChild(carousel);\n }\n \n private renderVideo(container: HTMLElement, content: PlacementContent): void {\n const { video_url, poster_url, autoplay, muted } = content.content;\n \n if (!video_url) {\n this.log('Video URL missing', true);\n return;\n }\n \n const safeVideoUrl = this.sanitizeUrl(video_url);\n if (!safeVideoUrl) {\n this.log('Invalid video URL', true);\n return;\n }\n \n const video = document.createElement('video');\n video.src = safeVideoUrl;\n video.controls = true;\n video.autoplay = autoplay || false;\n video.muted = muted || false;\n video.style.cssText = 'width: 100%; border-radius: 8px;';\n \n if (poster_url) {\n const safePosterUrl = this.sanitizeUrl(poster_url);\n if (safePosterUrl) {\n video.poster = safePosterUrl;\n }\n }\n \n video.addEventListener('play', () => {\n this.trackEvent(content.placement_id, content.variant_id, 'click', { action: 'video_play' });\n });\n \n container.appendChild(video);\n }\n \n private renderHTML(container: HTMLElement, content: PlacementContent): void {\n const { html } = content.content;\n \n if (!html) {\n this.log('HTML content missing', true);\n return;\n }\n \n const wrapper = document.createElement('div');\n wrapper.className = 'aegis-placement-html';\n wrapper.innerHTML = this.sanitizeHTML(html);\n \n const links = wrapper.querySelectorAll('a');\n links.forEach((link) => {\n link.addEventListener('click', (e) => {\n this.trackEvent(content.placement_id, content.variant_id, 'click');\n });\n });\n \n container.appendChild(wrapper);\n }\n \n private renderDynamicInjection(content: PlacementContent): void {\n const { html } = content.content;\n const cssSelector = content.css_selector;\n const injectionMode = content.injection_mode || 'replace';\n \n if (!cssSelector) {\n this.log('CSS selector missing for dynamic injection', true);\n return;\n }\n \n if (!html) {\n this.log('HTML content missing for dynamic injection', true);\n return;\n }\n \n let targetElement: HTMLElement | null = null;\n \n try {\n targetElement = document.querySelector(cssSelector);\n } catch (error) {\n this.log(`Invalid CSS selector: ${cssSelector}`, true);\n return;\n }\n \n if (!targetElement) {\n this.log(`Target element not found for selector: ${cssSelector}`, true);\n return;\n }\n \n const wrapper = document.createElement('div');\n wrapper.className = 'aegis-dynamic-injection';\n wrapper.setAttribute('data-placement-id', content.placement_id);\n wrapper.setAttribute('data-variant-id', content.variant_id);\n wrapper.innerHTML = this.sanitizeHTML(html);\n \n const links = wrapper.querySelectorAll('a');\n links.forEach((link) => {\n link.addEventListener('click', () => {\n this.trackEvent(content.placement_id, content.variant_id, 'click');\n });\n });\n \n switch (injectionMode) {\n case 'replace':\n targetElement.innerHTML = '';\n targetElement.appendChild(wrapper);\n this.log(`Replaced content in ${cssSelector}`, false);\n break;\n \n case 'append':\n targetElement.appendChild(wrapper);\n this.log(`Appended content to ${cssSelector}`, false);\n break;\n \n case 'prepend':\n targetElement.insertBefore(wrapper, targetElement.firstChild);\n this.log(`Prepended content to ${cssSelector}`, false);\n break;\n \n default:\n this.log(`Unknown injection mode: ${injectionMode}`, true);\n return;\n }\n \n this.log(`Dynamically injected content for ${content.placement_id} into ${cssSelector} (${injectionMode})`);\n }\n \n private renderFallback(slot: PlacementSlot): void {\n if (!slot.fallbackContent) return;\n \n const container = document.getElementById(slot.containerId);\n if (!container) return;\n \n container.innerHTML = slot.fallbackContent;\n this.log(`Rendered fallback content for: ${slot.placementId}`);\n }\n \n private async trackEvent(\n placementId: string,\n variantId: string,\n eventType: 'impression' | 'click' | 'conversion',\n metadata: Record<string, any> = {}\n ): Promise<void> {\n try {\n const url = `${this.apiHost}/v1/placements/track`;\n \n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Aegis-Write-Key': this.writeKey,\n 'X-Device-Type': this.getDeviceType(),\n 'X-Platform': 'web'\n };\n \n if (this.userId) headers['X-User-ID'] = this.userId;\n if (this.contactId) headers['X-Contact-ID'] = this.contactId;\n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n \n const body = {\n placement_id: placementId,\n variant_id: variantId,\n event_type: eventType,\n metadata: {\n device_type: this.getDeviceType(),\n platform: 'web',\n ...metadata\n }\n };\n \n fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n }).catch(err => this.log(`Track event failed: ${err}`, true));\n \n this.log(`Tracked ${eventType}: ${placementId}`);\n \n } catch (error) {\n this.log(`Error tracking event: ${error}`, true);\n }\n }\n \n private connectSSE(): void {\n if (this.eventSource) {\n this.disconnectSSE();\n }\n \n if (!this.organizationId) {\n this.log('Cannot connect SSE without organization ID', true);\n return;\n }\n \n const url = new URL('/v1/stream/realtime', this.apiHost);\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'X-Organization-ID': this.organizationId,\n };\n \n if (this.contactId) {\n headers['X-Contact-ID'] = this.contactId;\n }\n \n const queryParams = new URLSearchParams();\n Object.entries(headers).forEach(([key, value]) => {\n queryParams.append(key, value);\n });\n \n this.eventSource = new EventSource(`${url}?${queryParams.toString()}`);\n \n this.eventSource.addEventListener('open', () => {\n this.log('SSE connection established');\n this.reconnectAttempts = 0;\n });\n \n this.eventSource.addEventListener('placement_content_updated', (event: MessageEvent) => {\n try {\n const data = JSON.parse(event.data);\n this.log(`Received placement content update: ${data.placement_id}`);\n this.refreshPlacements();\n } catch (error) {\n this.log(`Error parsing SSE event: ${error}`, true);\n }\n });\n \n this.eventSource.addEventListener('heartbeat', (event: MessageEvent) => {\n this.log('SSE heartbeat received');\n });\n \n this.eventSource.addEventListener('error', (error) => {\n this.log('SSE connection error', true);\n \n if (this.eventSource?.readyState === EventSource.CLOSED) {\n this.attemptReconnect();\n }\n });\n }\n \n private disconnectSSE(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = undefined;\n this.log('SSE connection closed');\n }\n }\n \n private attemptReconnect(): void {\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n this.log('Max reconnect attempts reached, giving up', true);\n return;\n }\n \n this.reconnectAttempts++;\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);\n \n this.log(`Reconnecting SSE in ${delay}ms (attempt ${this.reconnectAttempts})`);\n \n setTimeout(() => {\n if (this.isInitialized && this.enableSSE && this.organizationId) {\n this.connectSSE();\n }\n }, delay);\n }\n \n private getDeviceType(): string {\n const width = window.innerWidth;\n if (width < 768) return 'mobile_web';\n if (width < 1024) return 'tablet_web';\n return 'desktop_web';\n }\n \n private sanitizeUrl(url: string): string | null {\n try {\n const parsed = new URL(url, window.location.href);\n \n if (parsed.protocol === 'javascript:' || parsed.protocol === 'data:') {\n this.log(`Blocked unsafe URL protocol: ${parsed.protocol}`, true);\n return null;\n }\n \n return parsed.href;\n } catch {\n this.log(`Invalid URL: ${url}`, true);\n return null;\n }\n }\n \n private sanitizeColor(color: string): string {\n const hexPattern = /^#[0-9A-Fa-f]{3,6}$/;\n const rgbPattern = /^rgba?\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*(,\\s*[\\d.]+\\s*)?\\)$/;\n const namedColors = ['white', 'black', 'red', 'blue', 'green', 'yellow', 'transparent'];\n \n if (hexPattern.test(color) || rgbPattern.test(color) || namedColors.includes(color.toLowerCase())) {\n return color;\n }\n \n this.log(`Invalid color: ${color}`, true);\n return '#000000';\n }\n \n private sanitizeHTML(html: string): string {\n // Use DOMPurify if available (recommended for production)\n const purify = (window as unknown as Record<string, unknown>).DOMPurify as\n | { sanitize: (dirty: string, cfg?: Record<string, unknown>) => string }\n | undefined;\n\n if (purify?.sanitize) {\n return purify.sanitize(html, {\n ALLOWED_TAGS: [\n 'a', 'b', 'br', 'div', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'i', 'img', 'li', 'ol', 'p', 'span', 'strong', 'u', 'ul', 'table',\n 'thead', 'tbody', 'tr', 'th', 'td', 'blockquote', 'hr', 'figure',\n 'figcaption', 'picture', 'source', 'video', 'section', 'article',\n ],\n ALLOWED_ATTR: [\n 'href', 'target', 'rel', 'src', 'alt', 'width', 'height', 'class',\n 'id', 'style', 'title', 'loading', 'srcset', 'sizes', 'type',\n 'media', 'controls', 'poster',\n ],\n ALLOW_DATA_ATTR: false,\n });\n }\n\n // Built-in fallback: strip all tags via DOM parsing, then re-allow safe subset\n this.log(\n 'DOMPurify not found — falling back to built-in sanitizer. ' +\n 'For full HTML placement support, add <script src=\"https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.2.4/purify.min.js\"></script>',\n false\n );\n const tempDiv = document.createElement('div');\n tempDiv.textContent = html;\n return tempDiv.innerHTML;\n }\n \n private log(message: string, isError = false): void {\n if (this.debugMode || isError) {\n console[isError ? 'error' : 'log'](`[AegisPlacements] ${message}`);\n }\n }\n \n destroy(): void {\n this.disconnectSSE();\n this.slots.clear();\n this.placements.clear();\n this.renderedSlots.clear();\n this.isInitialized = false;\n this.log('AegisPlacements destroyed');\n }\n}\n","/**\n * AegisWidgetManager - Web SDK Widget Module\n * \n * Smart Pull architecture for persistent web widgets.\n * \n * Features:\n * - Gamification (spin wheel, scratch card) with server-side prize generation\n * - Chat bubbles (WhatsApp, support)\n * - Social proof toasts (real-time purchase notifications)\n * - Feedback forms (NPS, surveys)\n * \n * Security:\n * - XSS Protection: Uses DOM APIs instead of innerHTML\n * - Server-side prize generation prevents client manipulation\n * - URL validation prevents javascript: protocol injection\n * \n * Architecture:\n * - Fetches widget configs from /v1/widgets/config on page load\n * - Integrates with TriggerEngine for behavioral triggers\n * - Tracks widget events (show, click, dismiss, submit)\n * - Server-side prize generation for gamification\n */\n\nimport { TriggerEngine } from '../triggers/TriggerEngine';\n\nexport interface WidgetConfig {\n widget_id: string;\n widget_type: 'chat_bubble' | 'spin_wheel' | 'scratch_card' | 'toast' | 'feedback_form' | 'exit_intent_popup';\n name: string;\n config: Record<string, any>;\n position?: string;\n priority: number;\n trigger_rules?: {\n type: 'exit_intent' | 'scroll_depth' | 'time_on_page' | 'immediate';\n config?: Record<string, any>;\n };\n}\n\nexport interface GamificationPrize {\n prize_label: string;\n prize_value?: string;\n coupon_code?: string;\n play_id: string;\n}\n\nexport interface AegisWidgetConfig {\n writeKey: string;\n apiHost?: string;\n userId?: string;\n contactId?: string;\n organizationId?: string;\n debugMode?: boolean;\n triggerEngine?: TriggerEngine;\n enablePrefetch?: boolean;\n cssCustomization?: WidgetCSSCustomization;\n onEvent?: (eventType: string, data: any) => void;\n /** Source platform passed as X-Source-Platform header so the API\n * can filter campaigns whose display_rules.sources restricts them\n * to specific integrations (e.g. 'shopify', 'woocommerce'). */\n sourcePlatform?: 'web' | 'shopify' | 'woocommerce' | 'mobile_sdk';\n}\n\nexport interface WidgetCSSCustomization {\n exitIntent?: {\n backgroundColor?: string;\n textColor?: string;\n accentColor?: string;\n borderRadius?: string;\n fontFamily?: string;\n overlayOpacity?: number;\n };\n spinWheel?: {\n backgroundColor?: string;\n textColor?: string;\n accentColor?: string;\n borderRadius?: string;\n fontFamily?: string;\n wheelColors?: string[];\n buttonColor?: string;\n };\n chatBubble?: {\n backgroundColor?: string;\n textColor?: string;\n position?: 'bottom_right' | 'bottom_left' | 'top_right' | 'top_left';\n size?: 'small' | 'medium' | 'large';\n };\n}\n\nexport interface PrefetchWidgetConfig {\n exit_intent?: {\n enabled: boolean;\n type: 'cart_recovery' | 'lead_gen';\n tier?: string;\n title?: string;\n message?: string;\n discount_code?: string;\n discount_percentage?: number;\n cta_text?: string;\n cta_url?: string;\n background_color?: string;\n text_color?: string;\n accent_color?: string;\n show_cart_items?: boolean;\n show_timer?: boolean;\n timer_minutes?: number;\n priority: number;\n mobile_triggers?: {\n scroll_velocity?: boolean;\n scroll_threshold?: number;\n scroll_min_position?: number;\n scroll_cooldown?: number;\n idle_timer?: boolean;\n idle_seconds?: number;\n visibility_change?: boolean;\n back_button?: boolean;\n };\n };\n spin_wheel?: {\n enabled: boolean;\n type: 'lead_gen' | 'cart_recovery';\n title?: string;\n prizes?: any[];\n priority: number;\n };\n}\n\nexport interface CartData {\n cart_id: string;\n cart_total: number;\n cart_currency: string;\n cart_items: Array<{\n product_id: string;\n product_name?: string;\n quantity: number;\n price?: number;\n }>;\n}\n\nexport class AegisWidgetManager {\n private writeKey: string;\n private apiHost: string;\n private userId?: string;\n private contactId?: string;\n private organizationId?: string;\n private debugMode: boolean;\n private triggerEngine?: TriggerEngine;\n private enablePrefetch: boolean;\n private cssCustomization: WidgetCSSCustomization;\n private onEvent?: (eventType: string, data: any) => void;\n private sourcePlatform?: string;\n\n private widgets: WidgetConfig[] = [];\n private renderedWidgets = new Set<string>();\n private isInitialized = false;\n \n private prefetchWidgetConfigs: PrefetchWidgetConfig = {};\n private cartData?: CartData;\n \n constructor(config: AegisWidgetConfig) {\n this.writeKey = config.writeKey;\n this.apiHost = config.apiHost || 'https://api.aegis.ai';\n this.userId = config.userId;\n this.contactId = config.contactId;\n this.organizationId = config.organizationId;\n this.debugMode = config.debugMode || false;\n this.triggerEngine = config.triggerEngine;\n this.enablePrefetch = config.enablePrefetch !== false;\n this.cssCustomization = config.cssCustomization || {};\n this.onEvent = config.onEvent;\n this.sourcePlatform = config.sourcePlatform;\n }\n \n updateCSSCustomization(customization: WidgetCSSCustomization): void {\n this.cssCustomization = { ...this.cssCustomization, ...customization };\n this.log('CSS customization updated');\n }\n \n private emitEvent(eventType: string, data: any): void {\n if (this.onEvent) {\n try {\n this.onEvent(eventType, data);\n } catch (error) {\n this.log(`Error in event callback: ${error}`, true);\n }\n }\n }\n \n async initialize(): Promise<void> {\n if (this.isInitialized) {\n this.log('AegisWidgets already initialized');\n return;\n }\n \n if (this.enablePrefetch && this.contactId) {\n await this.fetchPrefetchConfigs();\n this.preloadWidgetAssets();\n }\n \n await this.fetchWidgets();\n \n this.renderImmediateWidgets();\n \n this.setupTriggerListeners();\n \n this.setupExitIntentWithPrefetch();\n \n this.isInitialized = true;\n this.log('AegisWidgets initialized successfully');\n }\n \n setCartData(cartData: CartData): void {\n this.cartData = cartData;\n this.log(`Cart data updated: ${cartData.cart_items.length} items, total: ${cartData.cart_currency} ${cartData.cart_total}`);\n }\n \n private detectPlatformCart(): CartData | null {\n const shopifyCart = this.normalizeShopifyCart();\n if (shopifyCart) {\n this.log('Detected Shopify cart via browser globals');\n return shopifyCart;\n }\n \n const wooCart = this.normalizeWooCart();\n if (wooCart) {\n this.log('Detected WooCommerce cart via injected data');\n return wooCart;\n }\n \n const magentoCart = this.normalizeMagentoCart();\n if (magentoCart) {\n this.log('Detected Magento cart via localStorage');\n return magentoCart;\n }\n \n if (this.cartData) {\n this.log('Using manually set cart data');\n return this.cartData;\n }\n \n return null;\n }\n \n private normalizeShopifyCart(): CartData | null {\n try {\n if (typeof window === 'undefined') return null;\n \n const win = window as any;\n \n if (win.Shopify?.checkout) {\n const checkout = win.Shopify.checkout;\n return {\n cart_id: checkout.token || `shopify_${Date.now()}`,\n cart_total: parseFloat(checkout.total_price) || 0,\n cart_currency: checkout.currency || 'USD',\n cart_items: (checkout.line_items || []).map((item: any) => ({\n product_id: String(item.product_id || item.id),\n product_name: item.title || item.product_title,\n quantity: item.quantity || 1,\n price: parseFloat(item.price) || 0\n }))\n };\n }\n \n const cartJsonEl = document.getElementById('cart-json');\n if (cartJsonEl?.textContent) {\n const cart = JSON.parse(cartJsonEl.textContent);\n return {\n cart_id: cart.token || `shopify_${Date.now()}`,\n cart_total: (cart.total_price || 0) / 100,\n cart_currency: cart.currency || 'USD',\n cart_items: (cart.items || []).map((item: any) => ({\n product_id: String(item.product_id || item.id),\n product_name: item.product_title || item.title,\n quantity: item.quantity || 1,\n price: (item.price || 0) / 100\n }))\n };\n }\n \n return null;\n } catch (error) {\n this.log(`Error detecting Shopify cart: ${error}`, true);\n return null;\n }\n }\n \n private normalizeWooCart(): CartData | null {\n try {\n if (typeof window === 'undefined') return null;\n \n const win = window as any;\n \n if (win.aegis_cart) {\n const cart = win.aegis_cart;\n return {\n cart_id: cart.cart_id || `woo_${Date.now()}`,\n cart_total: parseFloat(cart.cart_total) || 0,\n cart_currency: cart.cart_currency || 'USD',\n cart_items: (cart.cart_items || []).map((item: any) => ({\n product_id: String(item.product_id),\n product_name: item.product_name,\n quantity: item.quantity || 1,\n price: parseFloat(item.price) || 0\n }))\n };\n }\n \n return null;\n } catch (error) {\n this.log(`Error detecting WooCommerce cart: ${error}`, true);\n return null;\n }\n }\n \n private normalizeMagentoCart(): CartData | null {\n try {\n if (typeof window === 'undefined' || !window.localStorage) return null;\n \n const mageCacheStr = localStorage.getItem('mage-cache-storage');\n if (!mageCacheStr) return null;\n \n const mageCache = JSON.parse(mageCacheStr);\n if (!mageCache?.cart) return null;\n \n const cart = mageCache.cart;\n \n return {\n cart_id: cart.quote_id || cart.id || `magento_${Date.now()}`,\n cart_total: parseFloat(cart.subtotalAmount || cart.subtotal || 0),\n cart_currency: cart.currencyCode || 'USD',\n cart_items: (cart.items || []).map((item: any) => ({\n product_id: String(item.item_id || item.product_id),\n product_name: item.product_name || item.name,\n quantity: item.qty || 1,\n price: parseFloat(item.product_price_value || item.price || 0)\n }))\n };\n } catch (error) {\n this.log(`Error detecting Magento cart: ${error}`, true);\n return null;\n }\n }\n \n private preloadWidgetAssets(): void {\n try {\n const exitIntentConfig = this.prefetchWidgetConfigs.exit_intent;\n if (exitIntentConfig?.enabled) {\n const imageUrl = (exitIntentConfig as any).image_url;\n if (imageUrl) {\n const img = new Image();\n img.src = imageUrl;\n this.log(`Preloading exit intent image: ${imageUrl}`);\n }\n }\n \n const spinWheelConfig = this.prefetchWidgetConfigs.spin_wheel;\n if (spinWheelConfig?.enabled) {\n const imageUrl = (spinWheelConfig as any).image_url;\n if (imageUrl) {\n const img = new Image();\n img.src = imageUrl;\n this.log(`Preloading spin wheel image: ${imageUrl}`);\n }\n }\n } catch (error) {\n this.log(`Error preloading widget assets: ${error}`, true);\n }\n }\n \n private async fetchPrefetchConfigs(): Promise<void> {\n try {\n const startTime = performance.now();\n const url = `${this.apiHost}/v1/widgets/config/prefetch`;\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n };\n \n if (this.contactId) headers['X-Contact-ID'] = this.contactId;\n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n \n const response = await fetch(url, { headers });\n \n if (!response.ok) {\n throw new Error(`Failed to fetch prefetch configs: ${response.status}`);\n }\n \n this.prefetchWidgetConfigs = await response.json();\n \n const elapsed = performance.now() - startTime;\n this.log(`Fetched prefetch widget configs in ${elapsed.toFixed(2)}ms`);\n \n } catch (error) {\n this.log(`Error fetching prefetch configs: ${error}`, true);\n }\n }\n \n private async fetchWidgets(): Promise<void> {\n try {\n const url = `${this.apiHost}/v1/widgets/config`;\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'X-Device-Platform': 'web',\n 'X-Device-Type': this.getDeviceType()\n };\n\n if (this.userId) headers['X-User-ID'] = this.userId;\n if (this.contactId) headers['X-Contact-ID'] = this.contactId;\n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n if (this.sourcePlatform) headers['X-Source-Platform'] = this.sourcePlatform;\n \n const response = await fetch(url, { headers });\n \n if (!response.ok) {\n throw new Error(`Failed to fetch widgets: ${response.status}`);\n }\n \n this.widgets = await response.json();\n \n this.log(`Fetched ${this.widgets.length} widgets`);\n \n } catch (error) {\n this.log(`Error fetching widgets: ${error}`, true);\n }\n }\n \n private renderImmediateWidgets(): void {\n const immediateWidgets = this.widgets.filter(w => \n !w.trigger_rules || w.trigger_rules.type === 'immediate'\n );\n \n immediateWidgets.forEach(widget => this.renderWidget(widget));\n }\n \n private setupTriggerListeners(): void {\n if (!this.triggerEngine) {\n this.log('TriggerEngine not provided, skipping trigger-based widgets');\n return;\n }\n \n this.widgets.forEach(widget => {\n if (!widget.trigger_rules) return;\n \n const { type, config } = widget.trigger_rules;\n \n switch (type) {\n case 'exit_intent':\n this.triggerEngine!.registerExitIntent();\n this.triggerEngine!.on('exit_intent', () => {\n if (!this.renderedWidgets.has(widget.widget_id)) {\n this.renderWidget(widget);\n }\n });\n break;\n \n case 'scroll_depth':\n const depthPercent = (config as any)?.depth_percent || 50;\n this.triggerEngine!.registerScrollDepth(depthPercent);\n this.triggerEngine!.on(`scroll_depth_${depthPercent}`, () => {\n if (!this.renderedWidgets.has(widget.widget_id)) {\n this.renderWidget(widget);\n }\n });\n break;\n \n case 'time_on_page':\n const seconds = (config as any)?.seconds || 30;\n this.triggerEngine!.registerTimeOnPage(seconds);\n this.triggerEngine!.on(`time_on_page_${seconds}`, () => {\n if (!this.renderedWidgets.has(widget.widget_id)) {\n this.renderWidget(widget);\n }\n });\n break;\n }\n });\n }\n \n private setupExitIntentWithPrefetch(): void {\n if (!this.enablePrefetch || !this.triggerEngine) {\n return;\n }\n \n const spinWheelConfig = this.prefetchWidgetConfigs.spin_wheel;\n const exitIntentConfig = this.prefetchWidgetConfigs.exit_intent;\n \n if (spinWheelConfig && spinWheelConfig.enabled) {\n const isMobile = this.isMobileDevice();\n const mobileConfig = exitIntentConfig?.mobile_triggers || {};\n \n const handleSpinWheelIntent = () => {\n const widgetId = `prefetch_spin_wheel_${Date.now()}`;\n \n if (this.renderedWidgets.has(widgetId)) {\n return;\n }\n \n this.renderedWidgets.add(widgetId);\n \n const detectedCart = this.detectPlatformCart();\n \n if (spinWheelConfig.type === 'cart_recovery' && detectedCart) {\n this.cartData = detectedCart;\n this.renderSpinWheelWidget(widgetId, spinWheelConfig);\n this.sendCartAbandonmentBeacon();\n } else if (spinWheelConfig.type === 'lead_gen') {\n this.renderSpinWheelWidget(widgetId, spinWheelConfig);\n }\n };\n \n if (isMobile) {\n const scrollVelocityEnabled = mobileConfig.scroll_velocity !== false;\n if (scrollVelocityEnabled) {\n this.triggerEngine.registerScrollVelocity({\n threshold: mobileConfig.scroll_threshold || 0.5,\n minScrollPosition: mobileConfig.scroll_min_position || 100,\n cooldown: mobileConfig.scroll_cooldown || 5000\n });\n this.triggerEngine.on('mobile_exit_intent', handleSpinWheelIntent);\n this.log('Registered mobile scroll velocity trigger for spin wheel');\n }\n \n const idleTimerEnabled = mobileConfig.idle_timer !== false;\n if (idleTimerEnabled) {\n const idleSeconds = mobileConfig.idle_seconds || 15;\n this.triggerEngine.registerInactivity(idleSeconds);\n this.triggerEngine.on(`inactivity_${idleSeconds}`, handleSpinWheelIntent);\n this.log(`Registered mobile idle timer trigger for spin wheel: ${idleSeconds}s`);\n }\n \n const visibilityChangeEnabled = mobileConfig.visibility_change !== false;\n if (visibilityChangeEnabled) {\n const detectedCart = this.detectPlatformCart();\n if (detectedCart && detectedCart.cart_items && detectedCart.cart_items.length > 0) {\n this.triggerEngine.registerVisibilityChange();\n this.triggerEngine.on('visibility_hidden', handleSpinWheelIntent);\n this.log('Registered mobile visibility change trigger for spin wheel (cart detected)');\n }\n }\n \n const backButtonEnabled = mobileConfig.back_button === true;\n if (backButtonEnabled) {\n this.triggerEngine.registerBackButton();\n this.triggerEngine.on('back_button', handleSpinWheelIntent);\n this.log('Registered mobile back button trigger for spin wheel');\n }\n \n this.log(`Setup mobile spin wheel: type=${spinWheelConfig.type}, priority=${spinWheelConfig.priority}`);\n } else {\n this.triggerEngine.registerExitIntent();\n this.triggerEngine.on('exit_intent', handleSpinWheelIntent);\n this.log(`Setup desktop spin wheel exit intent: type=${spinWheelConfig.type}, priority=${spinWheelConfig.priority}`);\n }\n \n return;\n }\n \n if (!exitIntentConfig || !exitIntentConfig.enabled) {\n this.log('No exit intent config found in prefetch');\n return;\n }\n \n const isMobile = this.isMobileDevice();\n const mobileConfig = exitIntentConfig.mobile_triggers || {};\n \n const handleExitIntent = () => {\n const widgetId = `prefetch_exit_intent_${Date.now()}`;\n \n if (this.renderedWidgets.has(widgetId)) {\n return;\n }\n \n this.renderedWidgets.add(widgetId);\n \n const detectedCart = this.detectPlatformCart();\n \n if (exitIntentConfig.type === 'cart_recovery' && detectedCart) {\n this.cartData = detectedCart;\n this.renderCartRecoveryPopup(widgetId, exitIntentConfig);\n this.sendCartAbandonmentBeacon();\n } else if (exitIntentConfig.type === 'lead_gen') {\n this.renderLeadGenPopup(widgetId, exitIntentConfig);\n } else {\n this.log('Unknown exit intent type or missing cart data');\n }\n };\n \n if (isMobile) {\n const scrollVelocityEnabled = mobileConfig.scroll_velocity !== false;\n if (scrollVelocityEnabled) {\n this.triggerEngine.registerScrollVelocity({\n threshold: mobileConfig.scroll_threshold || 0.5,\n minScrollPosition: mobileConfig.scroll_min_position || 100,\n cooldown: mobileConfig.scroll_cooldown || 5000\n });\n this.triggerEngine.on('mobile_exit_intent', handleExitIntent);\n this.log('Registered mobile scroll velocity trigger');\n }\n \n const idleTimerEnabled = mobileConfig.idle_timer !== false;\n if (idleTimerEnabled) {\n const idleSeconds = mobileConfig.idle_seconds || 15;\n this.triggerEngine.registerInactivity(idleSeconds);\n this.triggerEngine.on(`inactivity_${idleSeconds}`, handleExitIntent);\n this.log(`Registered mobile idle timer trigger: ${idleSeconds}s`);\n }\n \n const visibilityChangeEnabled = mobileConfig.visibility_change !== false;\n if (visibilityChangeEnabled) {\n const detectedCart = this.detectPlatformCart();\n if (detectedCart && detectedCart.cart_items && detectedCart.cart_items.length > 0) {\n this.triggerEngine.registerVisibilityChange();\n this.triggerEngine.on('visibility_hidden', handleExitIntent);\n this.log('Registered mobile visibility change trigger (cart detected)');\n } else {\n this.log('Skipped visibility change trigger (no cart items)');\n }\n }\n \n const backButtonEnabled = mobileConfig.back_button === true;\n if (backButtonEnabled) {\n this.triggerEngine.registerBackButton();\n this.triggerEngine.on('back_button', handleExitIntent);\n this.log('Registered mobile back button trigger (aggressive mode)');\n }\n \n this.log(`Setup mobile exit intent: type=${exitIntentConfig.type}, priority=${exitIntentConfig.priority}`);\n } else {\n this.triggerEngine.registerExitIntent();\n this.triggerEngine.on('exit_intent', handleExitIntent);\n this.log(`Setup desktop exit intent: type=${exitIntentConfig.type}, priority=${exitIntentConfig.priority}`);\n }\n }\n \n private sendCartAbandonmentBeacon(): void {\n if (!this.cartData) {\n this.log('No cart data available for beacon', true);\n return;\n }\n \n const beaconData = {\n organization_id: this.organizationId || 'default',\n contact_id: this.contactId,\n cart_id: this.cartData.cart_id,\n cart_total: this.cartData.cart_total,\n cart_currency: this.cartData.cart_currency,\n cart_items: this.cartData.cart_items,\n user_email: this.userId,\n abandoned_at: new Date().toISOString(),\n page_url: window.location.href,\n referrer: document.referrer\n };\n \n const beaconUrl = `${this.apiHost}/v1/widgets/beacon/cart-abandoned`;\n \n if (navigator.sendBeacon) {\n const blob = new Blob([JSON.stringify(beaconData)], { type: 'application/json' });\n const sent = navigator.sendBeacon(beaconUrl, blob);\n \n if (sent) {\n this.log('Cart abandonment beacon sent successfully');\n } else {\n this.log('Failed to send cart abandonment beacon', true);\n }\n } else {\n fetch(beaconUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Aegis-Write-Key': this.writeKey\n },\n body: JSON.stringify(beaconData),\n keepalive: true\n }).catch(err => {\n this.log(`Error sending cart abandonment via fetch: ${err}`, true);\n });\n }\n }\n \n private renderWidget(widget: WidgetConfig): void {\n if (this.renderedWidgets.has(widget.widget_id)) {\n return;\n }\n \n this.renderedWidgets.add(widget.widget_id);\n \n switch (widget.widget_type) {\n case 'chat_bubble':\n this.renderChatBubble(widget);\n break;\n case 'spin_wheel':\n this.renderSpinWheel(widget);\n break;\n case 'scratch_card':\n this.renderScratchCard(widget);\n break;\n case 'toast':\n this.renderToast(widget);\n break;\n case 'feedback_form':\n this.renderFeedbackForm(widget);\n break;\n case 'exit_intent_popup':\n this.renderExitIntentPopup(widget);\n break;\n default:\n this.log(`Unknown widget type: ${widget.widget_type}`, true);\n }\n \n this.trackEvent(widget.widget_id, 'show');\n }\n \n private renderChatBubble(widget: WidgetConfig): void {\n const { text, icon_url, link_url, background_color, text_color } = widget.config;\n const position = widget.position || 'bottom_right';\n \n const bubble = document.createElement('div');\n bubble.className = 'aegis-chat-bubble';\n bubble.setAttribute('data-widget-id', widget.widget_id);\n \n const positionStyles: Record<string, string> = {\n bottom_right: 'bottom: 20px; right: 20px;',\n bottom_left: 'bottom: 20px; left: 20px;',\n top_right: 'top: 20px; right: 20px;',\n top_left: 'top: 20px; left: 20px;'\n };\n \n bubble.style.cssText = `\n position: fixed;\n ${positionStyles[position] || positionStyles.bottom_right}\n background: ${this.sanitizeColor(background_color || '#25D366')};\n color: ${this.sanitizeColor(text_color || '#ffffff')};\n padding: 16px 24px;\n border-radius: 50px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n cursor: pointer;\n z-index: 999999;\n display: flex;\n align-items: center;\n gap: 12px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n font-weight: 600;\n font-size: 14px;\n animation: aegisBubbleIn 0.3s ease-out;\n `;\n \n if (icon_url) {\n const icon = document.createElement('img');\n const safeUrl = this.sanitizeUrl(icon_url);\n if (safeUrl) {\n icon.src = safeUrl;\n icon.alt = '';\n icon.style.cssText = 'width: 24px; height: 24px;';\n bubble.appendChild(icon);\n }\n }\n \n const textEl = document.createElement('span');\n textEl.textContent = text || 'Chat with us';\n bubble.appendChild(textEl);\n \n bubble.addEventListener('click', () => {\n this.trackEvent(widget.widget_id, 'click');\n const safeUrl = this.sanitizeUrl(link_url);\n if (safeUrl) {\n window.open(safeUrl, '_blank');\n }\n });\n \n this.addAnimationStyles();\n document.body.appendChild(bubble);\n }\n \n private renderSpinWheel(widget: WidgetConfig): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-gamification-overlay';\n overlay.setAttribute('data-widget-id', widget.widget_id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: aegisFadeIn 0.3s ease-out;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-spin-wheel-modal';\n modal.style.cssText = `\n background: white;\n border-radius: 16px;\n padding: 32px;\n max-width: 500px;\n width: 90%;\n box-shadow: 0 10px 40px rgba(0,0,0,0.3);\n text-align: center;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisScaleIn 0.3s ease-out;\n `;\n \n const title = document.createElement('h2');\n title.textContent = widget.config.title || 'Spin to Win!';\n title.style.cssText = 'margin: 0 0 16px 0; font-size: 24px; font-weight: 700; color: #1a1a1a;';\n modal.appendChild(title);\n \n const description = document.createElement('p');\n description.textContent = widget.config.description || 'Try your luck and win exclusive prizes!';\n description.style.cssText = 'margin: 0 0 24px 0; font-size: 14px; color: #666;';\n modal.appendChild(description);\n \n const wheelPlaceholder = document.createElement('div');\n wheelPlaceholder.style.cssText = `\n width: 300px;\n height: 300px;\n margin: 0 auto 24px;\n background: linear-gradient(45deg, #ff6b6b, #feca57, #48dbfb, #ff6348);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 48px;\n color: white;\n `;\n wheelPlaceholder.textContent = '🎰';\n modal.appendChild(wheelPlaceholder);\n \n const spinButton = document.createElement('button');\n spinButton.textContent = 'SPIN NOW!';\n spinButton.style.cssText = `\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: none;\n padding: 16px 48px;\n border-radius: 8px;\n font-weight: 700;\n font-size: 16px;\n cursor: pointer;\n margin-bottom: 16px;\n `;\n \n spinButton.addEventListener('click', async () => {\n spinButton.disabled = true;\n spinButton.textContent = 'SPINNING...';\n \n try {\n const prize = await this.generatePrize(widget.config.config_id);\n \n wheelPlaceholder.style.animation = 'aegisSpin 2s ease-out';\n \n setTimeout(() => {\n this.showPrizeResult(modal, prize);\n }, 2000);\n \n } catch (error) {\n this.log(`Error generating prize: ${error}`, true);\n spinButton.disabled = false;\n spinButton.textContent = 'TRY AGAIN';\n }\n });\n \n modal.appendChild(spinButton);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '×';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 16px;\n right: 16px;\n background: transparent;\n border: none;\n font-size: 28px;\n cursor: pointer;\n color: #999;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(widget.widget_id, 'dismiss');\n document.body.removeChild(overlay);\n this.renderedWidgets.delete(widget.widget_id);\n });\n \n modal.style.position = 'relative';\n modal.appendChild(closeButton);\n \n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private renderSpinWheelWidget(widgetId: string, config: NonNullable<PrefetchWidgetConfig['spin_wheel']>): void {\n const cart = this.detectPlatformCart();\n \n if (config.type === 'cart_recovery' && !cart) {\n this.log('Spin wheel requires cart, but none detected');\n return;\n }\n \n if (cart) {\n this.cartData = cart;\n }\n \n const customization = this.cssCustomization.spinWheel || {};\n const accentColor = customization.accentColor || (config as any).accent_color || '#FF6B6B';\n const backgroundColor = customization.backgroundColor || (config as any).background_color || '#FFFFFF';\n const textColor = customization.textColor || (config as any).text_color || '#333333';\n const buttonColor = customization.buttonColor || (config as any).button_color || accentColor;\n const wheelColors = customization.wheelColors || ['#FF6B6B', '#4ECDC4', '#FFE66D', '#95E1D3'];\n \n const overlay = document.createElement('div');\n overlay.className = 'aegis-spin-wheel-overlay';\n overlay.setAttribute('data-widget-id', widgetId);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.7);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 999999;\n animation: aegisFadeIn 0.3s ease;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-spin-wheel-modal';\n modal.style.cssText = `\n background: ${this.sanitizeColor(backgroundColor)};\n border-radius: 16px;\n padding: 32px;\n max-width: 500px;\n width: 90%;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n position: relative;\n animation: aegisScaleIn 0.4s ease;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n `;\n \n const closeBtn = document.createElement('button');\n closeBtn.innerHTML = '✕';\n closeBtn.className = 'aegis-spin-wheel-close';\n closeBtn.style.cssText = `\n position: absolute;\n top: 16px;\n right: 16px;\n background: none;\n border: none;\n font-size: 24px;\n cursor: pointer;\n color: #999;\n `;\n closeBtn.onclick = () => {\n this.trackEvent(widgetId, 'dismiss', { type: 'spin_wheel' });\n document.body.removeChild(overlay);\n this.renderedWidgets.delete(widgetId);\n };\n modal.appendChild(closeBtn);\n \n const title = document.createElement('h2');\n title.textContent = this.interpolateCartVariables((config as any).title || 'Spin to Win!');\n title.style.cssText = `\n margin: 0 0 16px 0;\n font-size: 28px;\n font-weight: bold;\n text-align: center;\n color: ${this.sanitizeColor(textColor)};\n `;\n modal.appendChild(title);\n \n if (cart) {\n const subtitle = document.createElement('p');\n subtitle.textContent = `Complete your ${cart.cart_currency} ${cart.cart_total.toFixed(2)} order and save!`;\n subtitle.style.cssText = `\n margin: 0 0 24px 0;\n font-size: 16px;\n text-align: center;\n color: #666;\n `;\n modal.appendChild(subtitle);\n }\n \n const wheelContainer = document.createElement('div');\n wheelContainer.className = 'aegis-wheel-container';\n wheelContainer.style.cssText = `\n width: 300px;\n height: 300px;\n margin: 0 auto 24px auto;\n background: conic-gradient(\n from 0deg,\n ${wheelColors[0]} 0deg 90deg,\n ${wheelColors[1]} 90deg 180deg,\n ${wheelColors[2]} 180deg 270deg,\n ${wheelColors[3]} 270deg 360deg\n );\n border-radius: 50%;\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n `;\n \n const form = document.createElement('form');\n form.className = 'aegis-spin-form';\n form.style.cssText = 'display: block;';\n \n const phoneInput = document.createElement('input');\n phoneInput.type = 'tel';\n phoneInput.placeholder = 'Enter your phone number';\n phoneInput.required = true;\n phoneInput.style.cssText = `\n width: 100%;\n padding: 14px;\n border: 2px solid #ddd;\n border-radius: 8px;\n font-size: 16px;\n margin-bottom: 12px;\n box-sizing: border-box;\n `;\n form.appendChild(phoneInput);\n \n const emailInput = document.createElement('input');\n emailInput.type = 'email';\n emailInput.placeholder = 'Enter your email (optional)';\n emailInput.style.cssText = `\n width: 100%;\n padding: 14px;\n border: 2px solid #ddd;\n border-radius: 8px;\n font-size: 16px;\n margin-bottom: 12px;\n box-sizing: border-box;\n `;\n form.appendChild(emailInput);\n \n const nameInput = document.createElement('input');\n nameInput.type = 'text';\n nameInput.placeholder = 'Enter your name (optional)';\n nameInput.style.cssText = `\n width: 100%;\n padding: 14px;\n border: 2px solid #ddd;\n border-radius: 8px;\n font-size: 16px;\n margin-bottom: 12px;\n box-sizing: border-box;\n `;\n form.appendChild(nameInput);\n \n const submitButton = document.createElement('button');\n submitButton.type = 'submit';\n submitButton.textContent = 'Spin the Wheel!';\n submitButton.style.cssText = `\n width: 100%;\n padding: 14px;\n background: ${this.sanitizeColor(buttonColor)};\n color: white;\n border: none;\n border-radius: 8px;\n font-size: 16px;\n font-weight: 700;\n cursor: pointer;\n `;\n form.appendChild(submitButton);\n \n const errorMessage = document.createElement('div');\n errorMessage.className = 'aegis-spin-error';\n errorMessage.style.cssText = `\n color: #d32f2f;\n font-size: 14px;\n margin-top: 12px;\n text-align: center;\n display: none;\n `;\n form.appendChild(errorMessage);\n \n form.addEventListener('submit', async (e) => {\n e.preventDefault();\n \n const phone = phoneInput.value.trim();\n const email = emailInput.value.trim();\n const name = nameInput.value.trim();\n \n if (!this.validatePhone(phone)) {\n errorMessage.textContent = 'Please enter a valid phone number (e.g., +1234567890)';\n errorMessage.style.display = 'block';\n return;\n }\n \n if (email && !this.validateEmail(email)) {\n errorMessage.textContent = 'Please enter a valid email address';\n errorMessage.style.display = 'block';\n return;\n }\n \n errorMessage.style.display = 'none';\n submitButton.disabled = true;\n submitButton.textContent = 'Spinning...';\n \n wheelContainer.style.animation = 'aegisSpin 2s ease-out';\n \n setTimeout(async () => {\n try {\n const prize = await this.submitSpinWheel({\n phone,\n email,\n name,\n cart,\n widgetId\n });\n \n this.showSpinWheelPrize(modal, prize);\n this.trackEvent(widgetId, 'submit', {\n type: 'spin_wheel',\n prize_label: prize.prize_label,\n has_email: !!email\n });\n \n } catch (error) {\n this.log(`Error submitting spin wheel: ${error}`, true);\n errorMessage.textContent = 'Failed to submit. Please try again.';\n errorMessage.style.display = 'block';\n submitButton.disabled = false;\n submitButton.textContent = 'Spin the Wheel!';\n wheelContainer.style.animation = '';\n }\n }, 2000);\n });\n \n modal.appendChild(wheelContainer);\n modal.appendChild(form);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n \n this.trackEvent(widgetId, 'show', { type: 'spin_wheel' });\n }\n \n private validatePhone(phone: string): boolean {\n const e164Regex = /^\\+?[1-9]\\d{1,14}$/;\n return e164Regex.test(phone.replace(/[\\s()-]/g, ''));\n }\n \n private validateEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n }\n \n private async submitSpinWheel(data: {\n phone: string;\n email: string;\n name: string;\n cart: CartData | null;\n widgetId: string;\n }): Promise<GamificationPrize> {\n const url = `${this.apiHost}/v1/widgets/spin-wheel/submit`;\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'Content-Type': 'application/json'\n };\n \n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n \n const geoRegion = this.detectGeoRegion();\n const deviceType = this.getDeviceType();\n const utmParams = this.getUTMParams();\n \n const body: any = {\n phone: data.phone.replace(/[\\s()-]/g, ''),\n email: data.email || undefined,\n name: data.name || undefined,\n cart_id: data.cart?.cart_id || `web_${Date.now()}`,\n cart_token: data.cart?.cart_id,\n cart_total: data.cart?.cart_total || 0,\n cart_currency: data.cart?.cart_currency || 'USD',\n cart_items: data.cart?.cart_items || [],\n cart_url: window.location.href,\n platform: 'web',\n geo_region: geoRegion,\n device_type: deviceType,\n session_id: this.getSessionId() || undefined,\n anonymous_id: this.getAnonymousId() || undefined,\n utm_source: utmParams.utm_source,\n utm_medium: utmParams.utm_medium,\n utm_campaign: utmParams.utm_campaign\n };\n \n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n });\n \n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to submit spin wheel: ${response.status} - ${errorText}`);\n }\n \n return await response.json();\n }\n \n private showSpinWheelPrize(modal: HTMLElement, prize: GamificationPrize): void {\n modal.innerHTML = '';\n \n const resultContainer = document.createElement('div');\n resultContainer.style.cssText = 'text-align: center; padding: 40px 20px;';\n \n const emoji = document.createElement('div');\n emoji.textContent = '🎉';\n emoji.style.cssText = 'font-size: 60px; margin-bottom: 20px;';\n resultContainer.appendChild(emoji);\n \n const title = document.createElement('h2');\n title.textContent = 'Congratulations!';\n title.style.cssText = 'margin: 0 0 12px 0; font-size: 28px; font-weight: 700; color: #1a73e8;';\n resultContainer.appendChild(title);\n \n const prizeLabel = document.createElement('p');\n prizeLabel.textContent = prize.prize_label;\n prizeLabel.style.cssText = 'margin: 0 0 20px 0; font-size: 20px; font-weight: 600; color: #333;';\n resultContainer.appendChild(prizeLabel);\n \n if (prize.coupon_code) {\n const couponContainer = document.createElement('div');\n couponContainer.style.cssText = `\n background: #f5f5f5;\n padding: 16px;\n border-radius: 8px;\n margin-bottom: 20px;\n border: 2px dashed #1a73e8;\n `;\n \n const couponLabel = document.createElement('div');\n couponLabel.textContent = 'Your coupon code:';\n couponLabel.style.cssText = 'font-size: 12px; color: #666; margin-bottom: 8px;';\n couponContainer.appendChild(couponLabel);\n \n const couponCode = document.createElement('div');\n couponCode.textContent = prize.coupon_code;\n couponCode.style.cssText = 'font-size: 24px; font-weight: 700; color: #1a73e8; letter-spacing: 2px;';\n couponContainer.appendChild(couponCode);\n \n resultContainer.appendChild(couponContainer);\n }\n \n const message = document.createElement('p');\n message.textContent = 'Check your WhatsApp/SMS for your discount code and cart link!';\n message.style.cssText = 'margin: 0 0 20px 0; font-size: 14px; color: #666;';\n resultContainer.appendChild(message);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = 'Close';\n closeButton.style.cssText = `\n background: #1a73e8;\n color: white;\n border: none;\n padding: 12px 32px;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n `;\n \n closeButton.addEventListener('click', () => {\n const overlay = modal.parentElement;\n if (overlay && document.body.contains(overlay)) {\n document.body.removeChild(overlay);\n }\n });\n \n resultContainer.appendChild(closeButton);\n modal.appendChild(resultContainer);\n }\n \n private detectGeoRegion(): string {\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n \n if (timezone.includes('America')) return 'north_america';\n if (timezone.includes('Europe')) return 'europe';\n if (timezone.includes('Asia/Kolkata') || timezone.includes('Asia/Calcutta')) return 'india';\n if (timezone.includes('Asia/Singapore') || timezone.includes('Asia/Bangkok') || timezone.includes('Asia/Jakarta')) return 'southeast_asia';\n if (timezone.includes('Asia/Dubai') || timezone.includes('Asia/Riyadh')) return 'middle_east';\n if (timezone.includes('America') && (timezone.includes('Sao_Paulo') || timezone.includes('Buenos_Aires'))) return 'latin_america';\n if (timezone.includes('Australia') || timezone.includes('Pacific/Auckland')) return 'oceania';\n \n return 'north_america';\n }\n \n private getUTMParams(): { utm_source?: string; utm_medium?: string; utm_campaign?: string } {\n const params = new URLSearchParams(window.location.search);\n return {\n utm_source: params.get('utm_source') || undefined,\n utm_medium: params.get('utm_medium') || undefined,\n utm_campaign: params.get('utm_campaign') || undefined\n };\n }\n \n private getSessionId(): string | null {\n return sessionStorage.getItem('aegis_session_id');\n }\n \n private getAnonymousId(): string | null {\n return localStorage.getItem('aegis_anonymous_id');\n }\n \n private renderScratchCard(widget: WidgetConfig): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-gamification-overlay';\n overlay.setAttribute('data-widget-id', widget.widget_id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: aegisFadeIn 0.3s ease-out;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-scratch-card-modal';\n modal.style.cssText = `\n background: white;\n border-radius: 16px;\n padding: 32px;\n max-width: 500px;\n width: 90%;\n box-shadow: 0 10px 40px rgba(0,0,0,0.3);\n text-align: center;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisScaleIn 0.3s ease-out;\n `;\n \n const title = document.createElement('h2');\n title.textContent = widget.config.title || 'Scratch & Win!';\n title.style.cssText = 'margin: 0 0 16px 0; font-size: 24px; font-weight: 700; color: #1a1a1a;';\n modal.appendChild(title);\n \n const description = document.createElement('p');\n description.textContent = widget.config.description || 'Scratch to reveal your prize!';\n description.style.cssText = 'margin: 0 0 24px 0; font-size: 14px; color: #666;';\n modal.appendChild(description);\n \n const canvas = document.createElement('canvas');\n canvas.width = 300;\n canvas.height = 200;\n canvas.style.cssText = `\n border-radius: 8px;\n cursor: pointer;\n margin: 0 auto 24px;\n display: block;\n box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n `;\n modal.appendChild(canvas);\n \n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.fillStyle = '#c0c0c0';\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.fillStyle = '#888';\n ctx.font = '20px Arial';\n ctx.textAlign = 'center';\n ctx.fillText('Scratch here!', canvas.width / 2, canvas.height / 2);\n \n let isScratching = false;\n \n const scratch = (x: number, y: number) => {\n ctx.globalCompositeOperation = 'destination-out';\n ctx.beginPath();\n ctx.arc(x, y, 20, 0, Math.PI * 2);\n ctx.fill();\n };\n \n canvas.addEventListener('mousedown', () => { isScratching = true; });\n canvas.addEventListener('mouseup', () => { isScratching = false; });\n canvas.addEventListener('mousemove', (e) => {\n if (isScratching) {\n const rect = canvas.getBoundingClientRect();\n scratch(e.clientX - rect.left, e.clientY - rect.top);\n }\n });\n }\n \n const scratchButton = document.createElement('button');\n scratchButton.textContent = 'REVEAL PRIZE';\n scratchButton.style.cssText = `\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n color: white;\n border: none;\n padding: 16px 48px;\n border-radius: 8px;\n font-weight: 700;\n font-size: 16px;\n cursor: pointer;\n `;\n \n scratchButton.addEventListener('click', async () => {\n scratchButton.disabled = true;\n scratchButton.textContent = 'REVEALING...';\n \n try {\n const prize = await this.generatePrize(widget.config.config_id);\n this.showPrizeResult(modal, prize);\n } catch (error) {\n this.log(`Error generating prize: ${error}`, true);\n scratchButton.disabled = false;\n scratchButton.textContent = 'TRY AGAIN';\n }\n });\n \n modal.appendChild(scratchButton);\n \n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private renderToast(widget: WidgetConfig): void {\n const { message, icon, duration } = widget.config;\n const position = widget.position || 'bottom_left';\n \n const toast = document.createElement('div');\n toast.className = 'aegis-toast';\n toast.setAttribute('data-widget-id', widget.widget_id);\n \n const positionStyles: Record<string, string> = {\n bottom_left: 'bottom: 20px; left: 20px;',\n bottom_right: 'bottom: 20px; right: 20px;',\n top_left: 'top: 20px; left: 20px;',\n top_right: 'top: 20px; right: 20px;'\n };\n \n toast.style.cssText = `\n position: fixed;\n ${positionStyles[position] || positionStyles.bottom_left}\n background: white;\n padding: 16px 20px;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n z-index: 999998;\n display: flex;\n align-items: center;\n gap: 12px;\n max-width: 350px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisToastIn 0.3s ease-out;\n `;\n \n if (icon) {\n const iconEl = document.createElement('div');\n iconEl.textContent = icon;\n iconEl.style.cssText = 'font-size: 20px;';\n toast.appendChild(iconEl);\n }\n \n const messageEl = document.createElement('div');\n messageEl.textContent = message || 'Someone just made a purchase!';\n messageEl.style.cssText = 'flex: 1; font-size: 13px; color: #333;';\n toast.appendChild(messageEl);\n \n this.addAnimationStyles();\n document.body.appendChild(toast);\n \n setTimeout(() => {\n toast.style.animation = 'aegisToastOut 0.3s ease-out';\n setTimeout(() => {\n if (document.body.contains(toast)) {\n document.body.removeChild(toast);\n }\n this.renderedWidgets.delete(widget.widget_id);\n }, 300);\n }, duration || 5000);\n }\n \n private renderFeedbackForm(widget: WidgetConfig): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-feedback-overlay';\n overlay.setAttribute('data-widget-id', widget.widget_id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 400px;\n background: white;\n box-shadow: -4px 0 20px rgba(0,0,0,0.15);\n z-index: 1000000;\n padding: 32px;\n overflow-y: auto;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisSlideInRight 0.3s ease-out;\n `;\n \n const title = document.createElement('h2');\n title.textContent = widget.config.title || 'We value your feedback!';\n title.style.cssText = 'margin: 0 0 8px 0; font-size: 20px; font-weight: 600; color: #1a1a1a;';\n overlay.appendChild(title);\n \n const description = document.createElement('p');\n description.textContent = widget.config.description || 'Help us improve your experience.';\n description.style.cssText = 'margin: 0 0 24px 0; font-size: 14px; color: #666;';\n overlay.appendChild(description);\n \n const form = document.createElement('form');\n \n const label = document.createElement('label');\n label.textContent = 'How likely are you to recommend us? (0-10)';\n label.style.cssText = 'display: block; font-size: 14px; font-weight: 600; margin-bottom: 8px; color: #333;';\n form.appendChild(label);\n \n const input = document.createElement('input');\n input.type = 'number';\n input.min = '0';\n input.max = '10';\n input.style.cssText = `\n width: 100%;\n padding: 12px;\n border: 1px solid #ddd;\n border-radius: 6px;\n font-size: 14px;\n margin-bottom: 16px;\n `;\n form.appendChild(input);\n \n const textareaLabel = document.createElement('label');\n textareaLabel.textContent = 'Tell us more (optional)';\n textareaLabel.style.cssText = 'display: block; font-size: 14px; font-weight: 600; margin-bottom: 8px; color: #333;';\n form.appendChild(textareaLabel);\n \n const textarea = document.createElement('textarea');\n textarea.rows = 4;\n textarea.style.cssText = `\n width: 100%;\n padding: 12px;\n border: 1px solid #ddd;\n border-radius: 6px;\n font-size: 14px;\n resize: vertical;\n margin-bottom: 16px;\n font-family: inherit;\n `;\n form.appendChild(textarea);\n \n const submitButton = document.createElement('button');\n submitButton.type = 'submit';\n submitButton.textContent = 'Submit Feedback';\n submitButton.style.cssText = `\n width: 100%;\n background: #1a73e8;\n color: white;\n border: none;\n padding: 12px;\n border-radius: 6px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n `;\n form.appendChild(submitButton);\n \n form.addEventListener('submit', async (e) => {\n e.preventDefault();\n \n submitButton.disabled = true;\n submitButton.textContent = 'Submitting...';\n \n try {\n await this.submitFeedback(widget.widget_id, {\n score: parseInt(input.value),\n comment: textarea.value\n });\n \n overlay.innerHTML = '<div style=\"text-align: center; padding: 60px 20px;\"><h3 style=\"margin: 0 0 12px 0; color: #1a73e8;\">Thank you!</h3><p style=\"margin: 0; color: #666;\">Your feedback helps us improve.</p></div>';\n \n setTimeout(() => {\n document.body.removeChild(overlay);\n }, 2000);\n \n } catch (error) {\n this.log(`Error submitting feedback: ${error}`, true);\n submitButton.disabled = false;\n submitButton.textContent = 'Submit Feedback';\n }\n });\n \n overlay.appendChild(form);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '×';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 16px;\n right: 16px;\n background: transparent;\n border: none;\n font-size: 28px;\n cursor: pointer;\n color: #999;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(widget.widget_id, 'dismiss');\n document.body.removeChild(overlay);\n this.renderedWidgets.delete(widget.widget_id);\n });\n \n overlay.appendChild(closeButton);\n \n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private renderExitIntentPopup(widget: WidgetConfig): void {\n const { title, description, cta_text, cta_url, image_url } = widget.config;\n \n const overlay = document.createElement('div');\n overlay.className = 'aegis-exit-popup-overlay';\n overlay.setAttribute('data-widget-id', widget.widget_id);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: aegisFadeIn 0.3s ease-out;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-exit-popup-modal';\n modal.style.cssText = `\n background: white;\n border-radius: 16px;\n max-width: 600px;\n width: 90%;\n overflow: hidden;\n box-shadow: 0 10px 40px rgba(0,0,0,0.3);\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisScaleIn 0.3s ease-out;\n `;\n \n if (image_url) {\n const img = document.createElement('img');\n const safeUrl = this.sanitizeUrl(image_url);\n if (safeUrl) {\n img.src = safeUrl;\n img.alt = '';\n img.style.cssText = 'width: 100%; height: 250px; object-fit: cover;';\n modal.appendChild(img);\n }\n }\n \n const content = document.createElement('div');\n content.style.cssText = 'padding: 32px;';\n \n const titleEl = document.createElement('h2');\n titleEl.textContent = title || 'Wait! Don\\'t leave yet!';\n titleEl.style.cssText = 'margin: 0 0 16px 0; font-size: 28px; font-weight: 700; color: #1a1a1a;';\n content.appendChild(titleEl);\n \n const descEl = document.createElement('p');\n descEl.textContent = description || 'Get 10% off your first order!';\n descEl.style.cssText = 'margin: 0 0 24px 0; font-size: 16px; color: #666; line-height: 1.5;';\n content.appendChild(descEl);\n \n if (cta_text && cta_url) {\n const ctaButton = document.createElement('button');\n ctaButton.textContent = cta_text;\n ctaButton.style.cssText = `\n background: #1a73e8;\n color: white;\n border: none;\n padding: 16px 32px;\n border-radius: 8px;\n font-weight: 600;\n font-size: 16px;\n cursor: pointer;\n width: 100%;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(widget.widget_id, 'click');\n const safeUrl = this.sanitizeUrl(cta_url);\n if (safeUrl) {\n window.location.href = safeUrl;\n }\n });\n \n content.appendChild(ctaButton);\n }\n \n modal.appendChild(content);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '×';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 16px;\n right: 16px;\n background: white;\n border: none;\n font-size: 28px;\n cursor: pointer;\n color: #666;\n width: 40px;\n height: 40px;\n border-radius: 50%;\n box-shadow: 0 2px 8px rgba(0,0,0,0.2);\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(widget.widget_id, 'dismiss');\n document.body.removeChild(overlay);\n this.renderedWidgets.delete(widget.widget_id);\n });\n \n modal.style.position = 'relative';\n modal.appendChild(closeButton);\n \n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n }\n \n private async generatePrize(configId: string): Promise<GamificationPrize> {\n const url = `${this.apiHost}/v1/widgets/gamification/generate-prize`;\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'Content-Type': 'application/json'\n };\n \n if (this.userId) headers['X-User-ID'] = this.userId;\n if (this.contactId) headers['X-Contact-ID'] = this.contactId;\n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n \n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({ config_id: configId })\n });\n \n if (!response.ok) {\n throw new Error(`Failed to generate prize: ${response.status}`);\n }\n \n return await response.json();\n }\n \n private showPrizeResult(modal: HTMLElement, prize: GamificationPrize): void {\n modal.innerHTML = '';\n \n const resultContainer = document.createElement('div');\n resultContainer.style.cssText = 'text-align: center; padding: 40px 20px;';\n \n const emoji = document.createElement('div');\n emoji.textContent = '🎉';\n emoji.style.cssText = 'font-size: 60px; margin-bottom: 20px;';\n resultContainer.appendChild(emoji);\n \n const title = document.createElement('h2');\n title.textContent = 'Congratulations!';\n title.style.cssText = 'margin: 0 0 12px 0; font-size: 28px; font-weight: 700; color: #1a73e8;';\n resultContainer.appendChild(title);\n \n const prizeLabel = document.createElement('p');\n prizeLabel.textContent = prize.prize_label;\n prizeLabel.style.cssText = 'margin: 0 0 20px 0; font-size: 20px; font-weight: 600; color: #333;';\n resultContainer.appendChild(prizeLabel);\n \n if (prize.coupon_code) {\n const couponContainer = document.createElement('div');\n couponContainer.style.cssText = `\n background: #f5f5f5;\n padding: 16px;\n border-radius: 8px;\n margin-bottom: 20px;\n border: 2px dashed #1a73e8;\n `;\n \n const couponLabel = document.createElement('div');\n couponLabel.textContent = 'Your coupon code:';\n couponLabel.style.cssText = 'font-size: 12px; color: #666; margin-bottom: 8px;';\n couponContainer.appendChild(couponLabel);\n \n const couponCode = document.createElement('div');\n couponCode.textContent = prize.coupon_code;\n couponCode.style.cssText = 'font-size: 24px; font-weight: 700; color: #1a73e8; letter-spacing: 2px;';\n couponContainer.appendChild(couponCode);\n \n resultContainer.appendChild(couponContainer);\n }\n \n const closeButton = document.createElement('button');\n closeButton.textContent = 'Close';\n closeButton.style.cssText = `\n background: #1a73e8;\n color: white;\n border: none;\n padding: 12px 32px;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n `;\n \n closeButton.addEventListener('click', () => {\n const overlay = modal.parentElement;\n if (overlay && document.body.contains(overlay)) {\n document.body.removeChild(overlay);\n }\n });\n \n resultContainer.appendChild(closeButton);\n modal.appendChild(resultContainer);\n }\n \n private async submitFeedback(widgetId: string, data: Record<string, any>): Promise<void> {\n const url = `${this.apiHost}/v1/widgets/track-event`;\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'Content-Type': 'application/json'\n };\n \n if (this.userId) headers['X-User-ID'] = this.userId;\n if (this.contactId) headers['X-Contact-ID'] = this.contactId;\n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n \n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n widget_id: widgetId,\n event_type: 'submit',\n event_data: data\n })\n });\n \n if (!response.ok) {\n throw new Error(`Failed to submit feedback: ${response.status}`);\n }\n }\n \n private async trackEvent(widgetId: string, eventType: string, metadata?: Record<string, any>): Promise<void> {\n try {\n const url = `${this.apiHost}/v1/widgets/track-event`;\n \n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.writeKey,\n 'Content-Type': 'application/json'\n };\n \n if (this.userId) headers['X-User-ID'] = this.userId;\n if (this.contactId) headers['X-Contact-ID'] = this.contactId;\n if (this.organizationId) headers['X-Organization-ID'] = this.organizationId;\n \n await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n widget_id: widgetId,\n event_type: eventType,\n event_data: metadata || {}\n })\n });\n \n } catch (error) {\n this.log(`Error tracking widget event: ${error}`, true);\n }\n }\n \n private sanitizeUrl(url?: string): string | null {\n if (!url) return null;\n \n try {\n const parsed = new URL(url, window.location.href);\n if (parsed.protocol === 'javascript:' || parsed.protocol === 'data:') {\n this.log(`Blocked dangerous URL: ${url}`, true);\n return null;\n }\n return parsed.href;\n } catch {\n this.log(`Invalid URL: ${url}`, true);\n return null;\n }\n }\n \n private sanitizeColor(color: string): string {\n if (/^#[0-9A-F]{3,8}$/i.test(color)) {\n return color;\n }\n \n if (/^rgb\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*\\)$/i.test(color)) {\n return color;\n }\n \n if (/^rgba\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*[\\d.]+\\s*\\)$/i.test(color)) {\n return color;\n }\n \n return '#1a73e8';\n }\n \n private getDeviceType(): string {\n const ua = navigator.userAgent;\n if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(ua)) {\n return 'tablet';\n }\n if (/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(ua)) {\n return 'mobile';\n }\n return 'desktop';\n }\n \n private isMobileDevice(): boolean {\n const deviceType = this.getDeviceType();\n return deviceType === 'mobile' || deviceType === 'tablet';\n }\n \n private addAnimationStyles(): void {\n if (document.getElementById('aegis-widget-animations')) {\n return;\n }\n \n const style = document.createElement('style');\n style.id = 'aegis-widget-animations';\n style.textContent = `\n @keyframes aegisFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n \n @keyframes aegisScaleIn {\n from { transform: scale(0.8); opacity: 0; }\n to { transform: scale(1); opacity: 1; }\n }\n \n @keyframes aegisBubbleIn {\n from { transform: translateY(20px); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n }\n \n @keyframes aegisToastIn {\n from { transform: translateX(-100%); opacity: 0; }\n to { transform: translateX(0); opacity: 1; }\n }\n \n @keyframes aegisToastOut {\n from { transform: translateX(0); opacity: 1; }\n to { transform: translateX(-100%); opacity: 0; }\n }\n \n @keyframes aegisSlideInRight {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n }\n \n @keyframes aegisSpin {\n from { transform: rotate(0deg); }\n to { transform: rotate(1440deg); }\n }\n `;\n document.head.appendChild(style);\n }\n \n private renderCartRecoveryPopup(widgetId: string, config: NonNullable<PrefetchWidgetConfig['exit_intent']>): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-exit-popup-overlay';\n overlay.setAttribute('data-widget-id', widgetId);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: aegisFadeIn 0.3s ease-out;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-cart-recovery-modal';\n modal.style.cssText = `\n background: ${this.sanitizeColor(config.background_color || '#FFFFFF')};\n color: ${this.sanitizeColor(config.text_color || '#333333')};\n border-radius: 16px;\n max-width: 600px;\n width: 90%;\n padding: 40px;\n box-shadow: 0 10px 40px rgba(0,0,0,0.3);\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisScaleIn 0.3s ease-out;\n position: relative;\n `;\n \n const title = document.createElement('h2');\n const titleText = this.interpolateCartVariables(config.title || 'Complete Your Order');\n title.textContent = titleText;\n title.style.cssText = `margin: 0 0 16px 0; font-size: 28px; font-weight: 700; color: ${this.sanitizeColor(config.accent_color || '#FF6B00')};`;\n modal.appendChild(title);\n \n const message = document.createElement('p');\n const messageText = this.interpolateCartVariables(config.message || 'Your cart is waiting for you!');\n message.textContent = messageText;\n message.style.cssText = 'margin: 0 0 24px 0; font-size: 16px; line-height: 1.5;';\n modal.appendChild(message);\n \n if (config.show_cart_items && this.cartData) {\n const cartItems = document.createElement('div');\n cartItems.style.cssText = 'margin: 0 0 24px 0; padding: 16px; background: rgba(0,0,0,0.05); border-radius: 8px;';\n \n const cartTitle = document.createElement('div');\n cartTitle.textContent = `${this.cartData.cart_items.length} items in your cart`;\n cartTitle.style.cssText = 'font-weight: 600; margin-bottom: 12px;';\n cartItems.appendChild(cartTitle);\n \n this.cartData.cart_items.slice(0, 3).forEach(item => {\n const itemDiv = document.createElement('div');\n itemDiv.textContent = `${item.quantity}× ${item.product_name || item.product_id}`;\n itemDiv.style.cssText = 'font-size: 14px; margin-bottom: 4px;';\n cartItems.appendChild(itemDiv);\n });\n \n modal.appendChild(cartItems);\n }\n \n if (config.discount_code) {\n const discountBox = document.createElement('div');\n discountBox.style.cssText = `\n margin: 0 0 24px 0;\n padding: 16px;\n background: ${this.sanitizeColor(config.accent_color || '#FF6B00')};\n color: white;\n border-radius: 8px;\n text-align: center;\n font-weight: 700;\n font-size: 18px;\n `;\n discountBox.textContent = `Use code: ${config.discount_code} for ${config.discount_percentage || 10}% off!`;\n modal.appendChild(discountBox);\n }\n \n if (config.show_timer && config.timer_minutes) {\n const timer = document.createElement('div');\n timer.style.cssText = 'margin: 0 0 24px 0; text-align: center; font-size: 14px; color: #999;';\n timer.textContent = `⏰ Offer expires in ${config.timer_minutes} minutes`;\n modal.appendChild(timer);\n }\n \n const ctaButton = document.createElement('button');\n ctaButton.textContent = config.cta_text || 'Complete Checkout';\n ctaButton.style.cssText = `\n background: ${this.sanitizeColor(config.accent_color || '#FF6B00')};\n color: white;\n border: none;\n padding: 16px 32px;\n border-radius: 8px;\n font-weight: 700;\n font-size: 16px;\n cursor: pointer;\n width: 100%;\n `;\n \n ctaButton.addEventListener('click', () => {\n this.trackEvent(widgetId, 'click', { type: 'cart_recovery' });\n const checkoutUrl = this.sanitizeUrl(config.cta_url || '/checkout');\n if (checkoutUrl) {\n window.location.href = checkoutUrl;\n }\n });\n \n modal.appendChild(ctaButton);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '×';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 16px;\n right: 16px;\n background: transparent;\n border: none;\n font-size: 28px;\n cursor: pointer;\n color: #999;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(widgetId, 'dismiss', { type: 'cart_recovery' });\n document.body.removeChild(overlay);\n this.renderedWidgets.delete(widgetId);\n });\n \n modal.appendChild(closeButton);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n \n this.trackEvent(widgetId, 'show', { type: 'cart_recovery', tier: config.tier });\n }\n \n private renderLeadGenPopup(widgetId: string, config: NonNullable<PrefetchWidgetConfig['exit_intent']>): void {\n const overlay = document.createElement('div');\n overlay.className = 'aegis-exit-popup-overlay';\n overlay.setAttribute('data-widget-id', widgetId);\n \n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n z-index: 1000000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: aegisFadeIn 0.3s ease-out;\n `;\n \n const modal = document.createElement('div');\n modal.className = 'aegis-leadgen-modal';\n modal.style.cssText = `\n background: white;\n border-radius: 16px;\n max-width: 500px;\n width: 90%;\n padding: 40px;\n box-shadow: 0 10px 40px rgba(0,0,0,0.3);\n text-align: center;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n animation: aegisScaleIn 0.3s ease-out;\n position: relative;\n `;\n \n const title = document.createElement('h2');\n title.textContent = config.title || 'Get 10% Off Your First Order!';\n title.style.cssText = 'margin: 0 0 16px 0; font-size: 28px; font-weight: 700; color: #1a1a1a;';\n modal.appendChild(title);\n \n const message = document.createElement('p');\n message.textContent = config.message || 'Subscribe to our newsletter and get an exclusive discount code.';\n message.style.cssText = 'margin: 0 0 24px 0; font-size: 16px; color: #666;';\n modal.appendChild(message);\n \n const form = document.createElement('form');\n \n const emailInput = document.createElement('input');\n emailInput.type = 'email';\n emailInput.placeholder = 'Enter your email';\n emailInput.required = true;\n emailInput.style.cssText = `\n width: 100%;\n padding: 14px;\n border: 2px solid #ddd;\n border-radius: 8px;\n font-size: 16px;\n margin-bottom: 16px;\n box-sizing: border-box;\n `;\n form.appendChild(emailInput);\n \n const submitButton = document.createElement('button');\n submitButton.type = 'submit';\n submitButton.textContent = 'Get My Discount';\n submitButton.style.cssText = `\n width: 100%;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n border: none;\n padding: 16px 32px;\n border-radius: 8px;\n font-weight: 700;\n font-size: 16px;\n cursor: pointer;\n `;\n form.appendChild(submitButton);\n \n form.addEventListener('submit', async (e) => {\n e.preventDefault();\n \n submitButton.disabled = true;\n submitButton.textContent = 'Submitting...';\n \n try {\n await this.trackEvent(widgetId, 'submit', { \n type: 'lead_gen',\n email: emailInput.value \n });\n \n modal.innerHTML = `\n <div style=\"text-align: center; padding: 20px;\">\n <div style=\"font-size: 48px; margin-bottom: 16px;\">✅</div>\n <h3 style=\"margin: 0 0 12px 0; color: #1a73e8;\">Thank You!</h3>\n <p style=\"margin: 0; color: #666;\">Check your email for your discount code!</p>\n </div>\n `;\n \n setTimeout(() => {\n document.body.removeChild(overlay);\n }, 2500);\n \n } catch (error) {\n this.log(`Error submitting lead gen form: ${error}`, true);\n submitButton.disabled = false;\n submitButton.textContent = 'Get My Discount';\n }\n });\n \n modal.appendChild(form);\n \n const closeButton = document.createElement('button');\n closeButton.textContent = '×';\n closeButton.setAttribute('aria-label', 'Close');\n closeButton.style.cssText = `\n position: absolute;\n top: 16px;\n right: 16px;\n background: transparent;\n border: none;\n font-size: 28px;\n cursor: pointer;\n color: #999;\n `;\n \n closeButton.addEventListener('click', () => {\n this.trackEvent(widgetId, 'dismiss', { type: 'lead_gen' });\n document.body.removeChild(overlay);\n this.renderedWidgets.delete(widgetId);\n });\n \n modal.appendChild(closeButton);\n overlay.appendChild(modal);\n this.addAnimationStyles();\n document.body.appendChild(overlay);\n \n this.trackEvent(widgetId, 'show', { type: 'lead_gen' });\n }\n \n private interpolateCartVariables(template: string): string {\n if (!this.cartData) return template;\n \n return template\n .replace(/\\{\\{cart_total\\}\\}/g, `${this.cartData.cart_currency} ${this.cartData.cart_total.toFixed(2)}`)\n .replace(/\\{\\{cart_currency\\}\\}/g, this.cartData.cart_currency)\n .replace(/\\{\\{cart_items_count\\}\\}/g, this.cartData.cart_items.length.toString());\n }\n \n private log(message: string, isError: boolean = false): void {\n if (this.debugMode || isError) {\n const method = isError ? 'error' : 'log';\n console[method](`[AegisWidgets] ${message}`);\n }\n }\n}\n","/**\n * TriggerEngine - Client-Side Trigger Evaluation\n * \n * Evaluates behavioral triggers that require real-time client state:\n * - Scroll depth (e.g., user scrolled >= 50%)\n * - Time on page (e.g., >= 30 seconds on current page)\n * - Exit intent (mouse leaving viewport toward browser controls)\n * - Inactivity (no user interaction for X seconds)\n * - Scroll velocity (mobile exit intent - fast upward scroll)\n * - Visibility change (tab/app switching)\n * - Back button (history navigation)\n * \n * Architecture:\n * - Server evaluates historical triggers (event counts, segments)\n * - Client evaluates behavioral triggers (scroll, time, exit intent)\n * - Zero latency - no server round trip needed\n * \n * Usage:\n * const trigger = new TriggerEngine();\n * trigger.on('scroll_depth_50', (data) => {\n * console.log('User scrolled to 50%', data);\n * });\n * trigger.start();\n */\n\nexport interface TriggerRule {\n type: 'scroll_depth' | 'time_on_page' | 'exit_intent' | 'inactivity' | 'scroll_velocity' | 'visibility_change' | 'back_button';\n config: ScrollDepthConfig | TimeOnPageConfig | ExitIntentConfig | InactivityConfig | ScrollVelocityConfig | VisibilityChangeConfig | BackButtonConfig;\n}\n\nexport interface ScrollDepthConfig {\n depth_percent: number;\n}\n\nexport interface TimeOnPageConfig {\n seconds: number;\n}\n\nexport interface ExitIntentConfig {\n enabled: boolean;\n}\n\nexport interface InactivityConfig {\n idle_seconds: number;\n}\n\nexport interface ScrollVelocityConfig {\n threshold: number;\n minScrollPosition: number;\n cooldown: number;\n}\n\nexport interface VisibilityChangeConfig {\n enabled: boolean;\n}\n\nexport interface BackButtonConfig {\n enabled: boolean;\n}\n\nexport interface TriggerEvent {\n type: string;\n data: Record<string, any>;\n timestamp: number;\n}\n\ntype TriggerCallback = (event: TriggerEvent) => void;\n\nexport class TriggerEngine {\n private listeners: Map<string, Set<TriggerCallback>> = new Map();\n private isStarted = false;\n \n private scrollDepthTargets = new Set<number>();\n private scrollDepthReached = new Set<number>();\n \n private timeOnPageTargets = new Map<number, number>();\n private pageLoadTime?: number;\n \n private exitIntentEnabled = false;\n private exitIntentFired = false;\n \n private inactivityTargets = new Map<number, number>();\n private lastActivityTime = Date.now();\n private inactivityCheckInterval?: number;\n \n private scrollVelocityEnabled = false;\n private scrollVelocityFired = false;\n private scrollVelocityConfig: ScrollVelocityConfig = {\n threshold: 0.5,\n minScrollPosition: 100,\n cooldown: 5000\n };\n private lastScrollY = 0;\n private lastScrollTime = Date.now();\n private scrollVelocityCooldownTimer?: number;\n \n private visibilityChangeEnabled = false;\n \n private backButtonEnabled = false;\n private backButtonFired = false;\n \n constructor() {}\n \n on(eventType: string, callback: TriggerCallback): void {\n if (!this.listeners.has(eventType)) {\n this.listeners.set(eventType, new Set());\n }\n this.listeners.get(eventType)!.add(callback);\n }\n \n off(eventType: string, callback: TriggerCallback): void {\n const callbacks = this.listeners.get(eventType);\n if (callbacks) {\n callbacks.delete(callback);\n }\n }\n \n registerScrollDepth(depthPercent: number): void {\n this.scrollDepthTargets.add(depthPercent);\n }\n \n registerTimeOnPage(seconds: number): void {\n if (!this.timeOnPageTargets.has(seconds)) {\n const timerId = window.setTimeout(() => {\n this.emit(`time_on_page_${seconds}`, {\n seconds,\n page_url: window.location.href\n });\n this.timeOnPageTargets.delete(seconds);\n }, seconds * 1000);\n \n this.timeOnPageTargets.set(seconds, timerId);\n }\n }\n \n registerExitIntent(): void {\n this.exitIntentEnabled = true;\n }\n \n registerInactivity(idleSeconds: number): void {\n if (!this.inactivityTargets.has(idleSeconds)) {\n const timerId = window.setTimeout(() => {\n const idleTime = (Date.now() - this.lastActivityTime) / 1000;\n \n if (idleTime >= idleSeconds) {\n this.emit(`inactivity_${idleSeconds}`, {\n idle_seconds: idleSeconds,\n actual_idle_time: idleTime\n });\n }\n \n this.inactivityTargets.delete(idleSeconds);\n }, idleSeconds * 1000);\n \n this.inactivityTargets.set(idleSeconds, timerId);\n }\n }\n \n registerScrollVelocity(config?: Partial<ScrollVelocityConfig>): void {\n this.scrollVelocityEnabled = true;\n \n if (config) {\n this.scrollVelocityConfig = {\n threshold: config.threshold ?? this.scrollVelocityConfig.threshold,\n minScrollPosition: config.minScrollPosition ?? this.scrollVelocityConfig.minScrollPosition,\n cooldown: config.cooldown ?? this.scrollVelocityConfig.cooldown\n };\n }\n }\n \n registerVisibilityChange(): void {\n this.visibilityChangeEnabled = true;\n }\n \n registerBackButton(): void {\n this.backButtonEnabled = true;\n }\n \n start(): void {\n if (this.isStarted) {\n return;\n }\n \n this.pageLoadTime = Date.now();\n this.lastActivityTime = Date.now();\n this.lastScrollY = window.scrollY || 0;\n this.lastScrollTime = Date.now();\n \n if (this.scrollDepthTargets.size > 0) {\n this.attachScrollListener();\n }\n \n if (this.exitIntentEnabled) {\n this.attachExitIntentListener();\n }\n \n if (this.scrollVelocityEnabled) {\n this.attachScrollVelocityListener();\n }\n \n if (this.visibilityChangeEnabled) {\n this.attachVisibilityChangeListener();\n }\n \n if (this.backButtonEnabled) {\n this.attachBackButtonListener();\n }\n \n this.attachActivityListeners();\n \n this.startInactivityCheck();\n \n this.isStarted = true;\n }\n \n stop(): void {\n if (!this.isStarted) {\n return;\n }\n \n this.removeScrollListener();\n this.removeExitIntentListener();\n this.removeScrollVelocityListener();\n this.removeVisibilityChangeListener();\n this.removeBackButtonListener();\n this.removeActivityListeners();\n \n this.timeOnPageTargets.forEach(timerId => clearTimeout(timerId));\n this.timeOnPageTargets.clear();\n \n this.inactivityTargets.forEach(timerId => clearTimeout(timerId));\n this.inactivityTargets.clear();\n \n if (this.inactivityCheckInterval) {\n clearInterval(this.inactivityCheckInterval);\n this.inactivityCheckInterval = undefined;\n }\n \n if (this.scrollVelocityCooldownTimer) {\n clearTimeout(this.scrollVelocityCooldownTimer);\n this.scrollVelocityCooldownTimer = undefined;\n }\n \n this.isStarted = false;\n }\n \n reset(): void {\n this.scrollDepthReached.clear();\n this.exitIntentFired = false;\n this.scrollVelocityFired = false;\n this.backButtonFired = false;\n this.pageLoadTime = Date.now();\n this.lastActivityTime = Date.now();\n this.lastScrollY = window.scrollY || 0;\n this.lastScrollTime = Date.now();\n \n if (this.scrollVelocityCooldownTimer) {\n clearTimeout(this.scrollVelocityCooldownTimer);\n this.scrollVelocityCooldownTimer = undefined;\n }\n }\n \n private attachScrollListener(): void {\n window.addEventListener('scroll', this.handleScroll, { passive: true });\n this.handleScroll();\n }\n \n private removeScrollListener(): void {\n window.removeEventListener('scroll', this.handleScroll);\n }\n \n private handleScroll = (): void => {\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n const scrollHeight = document.documentElement.scrollHeight - window.innerHeight;\n const scrollPercent = scrollHeight > 0 ? (scrollTop / scrollHeight) * 100 : 0;\n \n for (const targetDepth of this.scrollDepthTargets) {\n if (scrollPercent >= targetDepth && !this.scrollDepthReached.has(targetDepth)) {\n this.scrollDepthReached.add(targetDepth);\n \n this.emit(`scroll_depth_${targetDepth}`, {\n depth_percent: targetDepth,\n actual_percent: scrollPercent,\n scroll_top: scrollTop,\n scroll_height: scrollHeight\n });\n }\n }\n };\n \n private attachExitIntentListener(): void {\n document.addEventListener('mouseleave', this.handleExitIntent);\n }\n \n private removeExitIntentListener(): void {\n document.removeEventListener('mouseleave', this.handleExitIntent);\n }\n \n private handleExitIntent = (event: MouseEvent): void => {\n if (this.exitIntentFired) {\n return;\n }\n \n if (event.clientY < 10) {\n this.exitIntentFired = true;\n \n this.emit('exit_intent', {\n client_y: event.clientY,\n page_url: window.location.href,\n time_on_page: this.pageLoadTime ? (Date.now() - this.pageLoadTime) / 1000 : 0\n });\n }\n };\n \n private attachScrollVelocityListener(): void {\n window.addEventListener('scroll', this.handleScrollVelocity, { passive: true });\n }\n \n private removeScrollVelocityListener(): void {\n window.removeEventListener('scroll', this.handleScrollVelocity);\n }\n \n private handleScrollVelocity = (): void => {\n if (this.scrollVelocityFired) {\n return;\n }\n \n const currentY = window.scrollY || document.documentElement.scrollTop;\n const currentTime = Date.now();\n const timeDiff = currentTime - this.lastScrollTime;\n \n if (timeDiff > 100) {\n const distance = this.lastScrollY - currentY;\n const velocity = Math.abs(distance / timeDiff);\n \n if (\n distance > 0 &&\n velocity > this.scrollVelocityConfig.threshold &&\n currentY > this.scrollVelocityConfig.minScrollPosition\n ) {\n this.scrollVelocityFired = true;\n \n this.emit('mobile_exit_intent', {\n scroll_velocity: velocity,\n scroll_distance: distance,\n current_position: currentY,\n page_url: window.location.href,\n time_on_page: this.pageLoadTime ? (Date.now() - this.pageLoadTime) / 1000 : 0\n });\n \n this.scrollVelocityCooldownTimer = window.setTimeout(() => {\n this.scrollVelocityFired = false;\n }, this.scrollVelocityConfig.cooldown);\n }\n \n this.lastScrollY = currentY;\n this.lastScrollTime = currentTime;\n }\n };\n \n private attachVisibilityChangeListener(): void {\n document.addEventListener('visibilitychange', this.handleVisibilityChange);\n }\n \n private removeVisibilityChangeListener(): void {\n document.removeEventListener('visibilitychange', this.handleVisibilityChange);\n }\n \n private handleVisibilityChange = (): void => {\n if (document.hidden) {\n this.emit('visibility_hidden', {\n page_url: window.location.href,\n time_on_page: this.pageLoadTime ? (Date.now() - this.pageLoadTime) / 1000 : 0\n });\n } else {\n this.emit('visibility_visible', {\n page_url: window.location.href\n });\n }\n };\n \n private attachBackButtonListener(): void {\n if (typeof window !== 'undefined' && window.history) {\n window.history.pushState(null, '', window.location.href);\n window.addEventListener('popstate', this.handleBackButton);\n }\n }\n \n private removeBackButtonListener(): void {\n window.removeEventListener('popstate', this.handleBackButton);\n }\n \n private handleBackButton = (): void => {\n if (this.backButtonFired) {\n return;\n }\n \n this.backButtonFired = true;\n \n window.history.pushState(null, '', window.location.href);\n \n this.emit('back_button', {\n page_url: window.location.href,\n time_on_page: this.pageLoadTime ? (Date.now() - this.pageLoadTime) / 1000 : 0\n });\n };\n \n private attachActivityListeners(): void {\n const events = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click'];\n events.forEach(event => {\n document.addEventListener(event, this.handleActivity, { passive: true });\n });\n }\n \n private removeActivityListeners(): void {\n const events = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click'];\n events.forEach(event => {\n document.removeEventListener(event, this.handleActivity);\n });\n }\n \n private handleActivity = (): void => {\n this.lastActivityTime = Date.now();\n };\n \n private startInactivityCheck(): void {\n this.inactivityCheckInterval = window.setInterval(() => {\n const idleTime = (Date.now() - this.lastActivityTime) / 1000;\n \n for (const [idleSeconds] of this.inactivityTargets) {\n if (idleTime >= idleSeconds) {\n this.emit(`inactivity_${idleSeconds}`, {\n idle_seconds: idleSeconds,\n actual_idle_time: idleTime\n });\n \n const timerId = this.inactivityTargets.get(idleSeconds);\n if (timerId) {\n clearTimeout(timerId);\n this.inactivityTargets.delete(idleSeconds);\n }\n }\n }\n }, 1000);\n }\n \n private emit(eventType: string, data: Record<string, any>): void {\n const event: TriggerEvent = {\n type: eventType,\n data,\n timestamp: Date.now()\n };\n \n const callbacks = this.listeners.get(eventType);\n if (callbacks) {\n callbacks.forEach(callback => {\n try {\n callback(event);\n } catch (error) {\n console.error(`Error in trigger callback for ${eventType}:`, error);\n }\n });\n }\n \n const wildcardCallbacks = this.listeners.get('*');\n if (wildcardCallbacks) {\n wildcardCallbacks.forEach(callback => {\n try {\n callback(event);\n } catch (error) {\n console.error(`Error in wildcard trigger callback:`, error);\n }\n });\n }\n }\n}\n","/**\n * SDK Config Poller\n *\n * Fetches non-sensitive SDK configuration from GET /v1/sdk/config\n * with ETag/If-None-Match support for 304 responses.\n *\n * Polls every 5 minutes by default. Config changes are applied\n * to push/in-app managers without re-initialization.\n */\n\nimport { logger } from '../utils/logger';\n\nexport interface SdkConfig {\n version: string;\n push: {\n enabled: boolean;\n vapid_public_key: string | null;\n platforms: string[];\n };\n in_app: {\n enabled: boolean;\n };\n consent: {\n channels_requiring_opt_in: string[];\n };\n}\n\nexport interface SdkConfigPollerOptions {\n apiHost: string;\n writeKey: string;\n organizationId?: string;\n pollIntervalMs?: number;\n}\n\nexport type ConfigChangeCallback = (config: SdkConfig) => void;\n\nexport class SdkConfigPoller {\n private options: Required<Omit<SdkConfigPollerOptions, 'organizationId'>> & { organizationId?: string };\n private currentETag: string | null = null;\n private currentConfig: SdkConfig | null = null;\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n private listeners: ConfigChangeCallback[] = [];\n\n constructor(options: SdkConfigPollerOptions) {\n this.options = {\n pollIntervalMs: 300_000, // 5 minutes\n ...options,\n };\n }\n\n /**\n * Fetch config once (on init) and start polling.\n */\n async start(): Promise<SdkConfig | null> {\n const config = await this.fetchConfig();\n\n this.pollTimer = setInterval(() => {\n this.fetchConfig().catch((err) => {\n logger.warn('SDK config poll failed:', err);\n });\n }, this.options.pollIntervalMs);\n\n return config;\n }\n\n /**\n * Stop polling.\n */\n stop(): void {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n }\n\n /**\n * Register a callback for config changes.\n */\n onChange(callback: ConfigChangeCallback): () => void {\n this.listeners.push(callback);\n return () => {\n const idx = this.listeners.indexOf(callback);\n if (idx >= 0) this.listeners.splice(idx, 1);\n };\n }\n\n /**\n * Get current cached config.\n */\n getConfig(): SdkConfig | null {\n return this.currentConfig;\n }\n\n /**\n * Fetch config with ETag/304 support.\n */\n private async fetchConfig(): Promise<SdkConfig | null> {\n try {\n const headers: Record<string, string> = {\n 'X-Aegis-Write-Key': this.options.writeKey,\n 'Accept': 'application/json',\n };\n\n if (this.options.organizationId) {\n headers['X-Organization-ID'] = this.options.organizationId;\n }\n\n if (this.currentETag) {\n headers['If-None-Match'] = this.currentETag;\n }\n\n const response = await fetch(`${this.options.apiHost}/v1/sdk/config`, {\n method: 'GET',\n headers,\n });\n\n // 304 Not Modified — config unchanged\n if (response.status === 304) {\n return this.currentConfig;\n }\n\n if (!response.ok) {\n logger.warn(`SDK config fetch failed: HTTP ${response.status}`);\n return this.currentConfig;\n }\n\n const config: SdkConfig = await response.json();\n const newETag = response.headers.get('ETag');\n\n if (newETag) {\n this.currentETag = newETag;\n }\n\n // Detect changes\n const changed = !this.currentConfig ||\n JSON.stringify(this.currentConfig) !== JSON.stringify(config);\n\n this.currentConfig = config;\n\n if (changed) {\n for (const listener of this.listeners) {\n try {\n listener(config);\n } catch (err) {\n logger.warn('SDK config change listener error:', err);\n }\n }\n }\n\n return config;\n } catch (err) {\n logger.warn('SDK config fetch error:', err);\n return this.currentConfig;\n }\n }\n}\n","import { Aegis } from './core/analytics';\n\nconst aegis = new Aegis();\n\nexport default aegis;\n\nexport { Aegis } from './core/analytics';\nexport type { AegisConfig, CellEndpoint, CellRegion } from './types/config';\nexport type {\n AegisEvent,\n TrackEvent,\n IdentifyEvent,\n PageEvent,\n GroupEvent,\n AliasEvent,\n EventContext,\n BatchPayload,\n BatchResponse,\n} from './types/events';\nexport type { Plugin, PluginRegistry } from './types/plugin';\nexport { debounce, throttle } from './utils/debounce';\nexport type {\n ConsentPreferences,\n ConsentCategory,\n ConsentStatus,\n} from './utils/consent';\nexport { AegisInAppManager } from './inapp';\nexport type { InAppCampaign, AegisInAppConfig } from './inapp';\nexport { renderPreview } from './inapp';\n\nexport { AegisPlacementManager } from './placements/AegisPlacementManager';\nexport type {\n PlacementContent,\n PlacementSlot,\n AegisPlacementConfig,\n} from './placements/AegisPlacementManager';\n\nexport { AegisWidgetManager } from './widgets';\nexport type {\n WidgetConfig,\n GamificationPrize,\n AegisWidgetConfig,\n} from './widgets';\n\nexport { TriggerEngine } from './triggers';\nexport type {\n TriggerRule,\n ScrollDepthConfig,\n TimeOnPageConfig,\n ExitIntentConfig,\n InactivityConfig,\n TriggerEvent,\n} from './triggers';\n\nexport { SdkConfigPoller } from './core/sdk-config-poller';\nexport type { SdkConfig, SdkConfigPollerOptions, ConfigChangeCallback } from './core/sdk-config-poller';\n\nexport { AegisWebPush } from './push/AegisWebPush';\nexport type {\n AegisWebPushConfig,\n AegisAPIClient,\n ContactIdentity,\n PushEventTracker,\n} from './push/AegisWebPush';\n\nexport { EcommerceTracker } from './ecommerce';\nexport type {\n EcommerceProduct,\n EcommerceCart,\n EcommerceCheckout,\n EcommerceOrder,\n EcommerceCoupon,\n EcommerceSearch,\n EcommerceProductList,\n EcommerceWishlist,\n EcommercePromotion,\n} from './ecommerce';\n"],"names":["isMobile","mobileConfig"],"mappings":"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"}
|