@metodokorexmk/tracking 1.1.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/analytics.ts","../src/core/gtm.ts","../src/trackers/video-tracker.ts","../src/trackers/events.ts","../src/trackers/wistia-adapter.ts","../src/trackers/voomly-adapter.ts","../src/trackers/html5-adapter.ts","../src/orchestrator/landing-tracker.ts","../src/persistence/api-client.ts","../src/persistence/lead-submission.ts","../src/persistence/dwell-time-tracker.ts","../src/persistence/tracking-queries.ts"],"names":["ReactGA","createStats"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Core de Google Analytics 4\r\n * Inicialización, tracking de eventos y captura de datos del visitante.\r\n * Desacoplado de cualquier framework (Next.js, React, etc.)\r\n */\r\n\r\nimport ReactGA from 'react-ga4';\r\nimport type { TrackingConfig, UTMParams, TrackingEventData } from './types';\r\n\r\n// ====================================\r\n// ESTADO INTERNO\r\n// ====================================\r\n\r\nlet isInitialized = false;\r\nlet currentConfig: TrackingConfig = {};\r\nlet resolvedTrackingId: string = '';\r\nlet cachedUserId: string | null = null;\r\nlet cachedUserName: string | null = null;\r\n\r\n// ====================================\r\n// RESOLUCIÓN DE GA TRACKING ID\r\n// ====================================\r\n\r\n/**\r\n * Obtiene el GA Tracking ID actual.\r\n * Si se configuró un `resolveTrackingId`, lo usa dinámicamente.\r\n * Si no, usa el `trackingId` fijo de la config.\r\n */\r\nexport const getGATrackingId = (): string => {\r\n if (typeof window === 'undefined') return resolvedTrackingId || '';\r\n\r\n if (currentConfig.resolveTrackingId) {\r\n try {\r\n const path = window.location.pathname;\r\n return currentConfig.resolveTrackingId(path);\r\n } catch {\r\n // fallback si la función falla\r\n }\r\n }\r\n\r\n return resolvedTrackingId;\r\n};\r\n\r\n// ====================================\r\n// INICIALIZACIÓN\r\n// ====================================\r\n\r\n/**\r\n * Inicializa Google Analytics con la configuración proporcionada.\r\n *\r\n * @example\r\n * ```ts\r\n * // Con ID fijo\r\n * initGA({ trackingId: 'G-XXXXXXX' })\r\n *\r\n * // Con resolución dinámica\r\n * initGA({\r\n * resolveTrackingId: (path) => {\r\n * if (path.startsWith('/kin')) return 'G-KIN-ID'\r\n * return localStorage.getItem('user_GA_id') || 'G-DEFAULT'\r\n * }\r\n * })\r\n * ```\r\n */\r\nexport const initGA = (config: TrackingConfig = {}): void => {\r\n if (typeof window === 'undefined') return;\r\n if (isInitialized) return;\r\n\r\n currentConfig = config;\r\n resolvedTrackingId = config.trackingId || '';\r\n\r\n const trackingId = getGATrackingId();\r\n if (!trackingId) {\r\n if (config.debug) {\r\n // eslint-disable-next-line no-console\r\n console.warn('[KorexTracking] No tracking ID provided. GA4 will not initialize.');\r\n }\r\n return;\r\n }\r\n\r\n try {\r\n ReactGA.initialize(trackingId);\r\n isInitialized = true;\r\n\r\n if (config.anonymizeIp) {\r\n window.gtag?.('config', trackingId, { anonymize_ip: true });\r\n }\r\n\r\n if (config.debug) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[KorexTracking] GA4 initialized with ID: ${trackingId}`);\r\n }\r\n } catch (error) {\r\n if (config.debug) {\r\n // eslint-disable-next-line no-console\r\n console.error('[KorexTracking] Failed to initialize GA4:', error);\r\n }\r\n }\r\n};\r\n\r\n/**\r\n * Reinicializa GA con un nuevo Tracking ID.\r\n * Útil cuando el ID cambia dinámicamente (ej. login del usuario).\r\n */\r\nexport const reinitGA = (newTrackingId: string): void => {\r\n isInitialized = false;\r\n resolvedTrackingId = newTrackingId;\r\n initGA({ ...currentConfig, trackingId: newTrackingId });\r\n};\r\n\r\n/**\r\n * Verificar si GA está inicializado\r\n */\r\nexport const isGAInitialized = (): boolean => isInitialized;\r\n\r\n// ====================================\r\n// CAPTURA DE DATOS DEL VISITANTE\r\n// ====================================\r\n\r\n/**\r\n * Extrae los parámetros UTM de la URL actual.\r\n */\r\nexport const captureUTMParams = (): UTMParams | null => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n const params = new URLSearchParams(window.location.search);\r\n const utmParams: UTMParams = {};\r\n let hasParams = false;\r\n\r\n const utmKeys: (keyof UTMParams)[] = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];\r\n\r\n for (const key of utmKeys) {\r\n const value = params.get(key);\r\n if (value) {\r\n utmParams[key] = value;\r\n hasParams = true;\r\n }\r\n }\r\n\r\n return hasParams ? utmParams : null;\r\n};\r\n\r\n/**\r\n * Captura el `user_id` desde la URL (?user_id=xxx).\r\n * Lo cachea internamente para enviarlo en todos los eventos.\r\n */\r\nexport const captureUserIdFromURL = (): string | null => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n const params = new URLSearchParams(window.location.search);\r\n const userId = params.get('user_id') || params.get('userId');\r\n\r\n if (userId) {\r\n cachedUserId = userId;\r\n try {\r\n localStorage.setItem('tracking_user_id', userId);\r\n } catch {\r\n // localStorage puede no estar disponible\r\n }\r\n }\r\n\r\n return userId;\r\n};\r\n\r\n/**\r\n * Resuelve el nombre del usuario desde múltiples fuentes.\r\n * Prioridad: URL > localStorage > null\r\n */\r\nexport const getUserName = (): string | null => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n // 1. Desde URL\r\n const params = new URLSearchParams(window.location.search);\r\n const fromUrl = params.get('user_name') || params.get('userName');\r\n if (fromUrl) {\r\n cachedUserName = fromUrl;\r\n return fromUrl;\r\n }\r\n\r\n // 2. Desde cache interno\r\n if (cachedUserName) return cachedUserName;\r\n\r\n // 3. Desde localStorage\r\n try {\r\n const fromStorage = localStorage.getItem('tracking_user_name');\r\n if (fromStorage) {\r\n cachedUserName = fromStorage;\r\n return fromStorage;\r\n }\r\n\r\n const userInfo = localStorage.getItem('userInfo');\r\n if (userInfo) {\r\n const parsed = JSON.parse(userInfo);\r\n const name = parsed?.name || parsed?.userName || parsed?.fullName;\r\n if (name) {\r\n cachedUserName = name;\r\n return name;\r\n }\r\n }\r\n } catch {\r\n // localStorage puede no estar disponible\r\n }\r\n\r\n return null;\r\n};\r\n\r\n/**\r\n * Obtiene el user_id cacheado.\r\n */\r\nexport const getUserId = (): string | null => {\r\n if (cachedUserId) return cachedUserId;\r\n\r\n if (typeof window === 'undefined') return null;\r\n\r\n try {\r\n return localStorage.getItem('tracking_user_id');\r\n } catch {\r\n return null;\r\n }\r\n};\r\n\r\n/**\r\n * Establece manualmente el user_id (ej. después de login).\r\n */\r\nexport const setUserId = (userId: string): void => {\r\n cachedUserId = userId;\r\n try {\r\n localStorage.setItem('tracking_user_id', userId);\r\n } catch {\r\n // ignore\r\n }\r\n // Configurar en GA4 como user property\r\n window.gtag?.('set', { user_id: userId });\r\n};\r\n\r\n/**\r\n * Establece manualmente el user_name.\r\n */\r\nexport const setUserName = (userName: string): void => {\r\n cachedUserName = userName;\r\n try {\r\n localStorage.setItem('tracking_user_name', userName);\r\n } catch {\r\n // ignore\r\n }\r\n};\r\n\r\n// ====================================\r\n// TRACKING DE PÁGINAS\r\n// ====================================\r\n\r\n/**\r\n * Envía un pageview a GA4.\r\n * Automáticamente incluye UTM params y user_id si están disponibles.\r\n */\r\nexport const trackPageView = (path: string): void => {\r\n if (typeof window === 'undefined') return;\r\n\r\n const userId = getUserId();\r\n const utmParams = captureUTMParams();\r\n\r\n // Construir path con UTMs si existen\r\n let pageWithParams = path;\r\n if (utmParams) {\r\n const searchParams = new URLSearchParams();\r\n Object.entries(utmParams).forEach(([key, value]) => {\r\n if (value) searchParams.set(key, value);\r\n });\r\n const paramString = searchParams.toString();\r\n if (paramString) {\r\n pageWithParams = `${path}${path.includes('?') ? '&' : '?'}${paramString}`;\r\n }\r\n }\r\n\r\n // Enviar por ReactGA\r\n try {\r\n ReactGA.send({\r\n hitType: 'pageview',\r\n page: pageWithParams,\r\n ...(userId && { user_id: userId }),\r\n });\r\n } catch {\r\n // ReactGA puede fallar si GA4 no está cargado (ad-blockers, carga lenta, etc.)\r\n }\r\n\r\n // Enviar por gtag nativo\r\n try {\r\n window.gtag?.('event', 'page_view', {\r\n page_path: pageWithParams,\r\n page_title: document.title,\r\n ...(userId && { user_id: userId }),\r\n });\r\n } catch {\r\n // gtag puede no estar disponible\r\n }\r\n\r\n if (currentConfig.debug) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[KorexTracking] PageView: ${pageWithParams}`, { userId });\r\n }\r\n};\r\n\r\n// ====================================\r\n// TRACKING DE EVENTOS\r\n// ====================================\r\n\r\n/**\r\n * Envía un evento personalizado a GA4.\r\n * Usa envío dual: `window.gtag()` + `ReactGA.event()`.\r\n * Siempre incluye `user_id` y `user_name` como parámetros.\r\n *\r\n * @example\r\n * ```ts\r\n * trackEvent('CTA', 'click', 'Botón Hero', undefined, { section: 'hero' })\r\n * ```\r\n */\r\nexport const trackEvent = (category: string, action: string, label?: string, value?: number, additionalData?: TrackingEventData): void => {\r\n if (typeof window === 'undefined') return;\r\n\r\n const userId = getUserId();\r\n const userName = getUserName();\r\n\r\n const eventData: TrackingEventData = {\r\n event_category: category,\r\n event_label: label || '',\r\n ...(value !== undefined && { value }),\r\n ...(userId && { user_id: userId }),\r\n ...(userName && { user_name: userName }),\r\n timestamp: Date.now(),\r\n ...additionalData,\r\n };\r\n\r\n // 1. Enviar por gtag nativo (más fiable)\r\n try {\r\n window.gtag?.('event', action, eventData);\r\n } catch {\r\n // ignore\r\n }\r\n\r\n // 2. Enviar por ReactGA como fallback\r\n try {\r\n ReactGA.event({\r\n category,\r\n action,\r\n label: label || undefined,\r\n value: value || undefined,\r\n ...(userId && { user_id: userId }),\r\n });\r\n } catch {\r\n // ignore\r\n }\r\n\r\n if (currentConfig.debug) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[KorexTracking] Event: ${category}/${action}`, eventData);\r\n }\r\n};\r\n\r\n// ====================================\r\n// UTILIDADES\r\n// ====================================\r\n\r\n/**\r\n * Resetea el estado interno (útil para tests y re-inicialización).\r\n */\r\nexport const resetAnalytics = (): void => {\r\n isInitialized = false;\r\n currentConfig = {};\r\n resolvedTrackingId = '';\r\n cachedUserId = null;\r\n cachedUserName = null;\r\n};\r\n","/**\r\n * Google Tag Manager — Carga e inyección vanilla (sin Next.js)\r\n * Proporciona pushToDataLayer e injectGTMScript.\r\n */\r\n\r\n/**\r\n * Inyecta el script de Google Tag Manager en el <head> del documento.\r\n * Equivalente al componente <Script> de Next.js, pero framework-agnostic.\r\n *\r\n * @param gtmId - ID de GTM (ej: 'GTM-5GMQNFMN')\r\n *\r\n * @example\r\n * ```ts\r\n * injectGTMScript('GTM-5GMQNFMN')\r\n * ```\r\n */\r\nexport const injectGTMScript = (gtmId: string): void => {\r\n if (typeof window === 'undefined') return;\r\n if (!gtmId) return;\r\n\r\n // Evitar inyección duplicada\r\n const existingScript = document.querySelector(`script[data-gtm-id=\"${gtmId}\"]`);\r\n if (existingScript) return;\r\n\r\n // Inicializar dataLayer\r\n window.dataLayer = window.dataLayer || [];\r\n window.dataLayer.push({\r\n 'gtm.start': new Date().getTime(),\r\n event: 'gtm.js',\r\n });\r\n\r\n // Crear e inyectar el script\r\n const script = document.createElement('script');\r\n script.async = true;\r\n script.src = `https://www.googletagmanager.com/gtm.js?id=${gtmId}`;\r\n script.setAttribute('data-gtm-id', gtmId);\r\n\r\n const firstScript = document.getElementsByTagName('script')[0];\r\n if (firstScript?.parentNode) {\r\n firstScript.parentNode.insertBefore(script, firstScript);\r\n } else {\r\n document.head.appendChild(script);\r\n }\r\n\r\n // Inyectar noscript fallback en body\r\n if (document.body) {\r\n const noscript = document.createElement('noscript');\r\n const iframe = document.createElement('iframe');\r\n iframe.src = `https://www.googletagmanager.com/ns.html?id=${gtmId}`;\r\n iframe.height = '0';\r\n iframe.width = '0';\r\n iframe.style.display = 'none';\r\n iframe.style.visibility = 'hidden';\r\n noscript.appendChild(iframe);\r\n document.body.insertBefore(noscript, document.body.firstChild);\r\n }\r\n};\r\n\r\n/**\r\n * Envía un evento al dataLayer de GTM.\r\n *\r\n * @param eventName - Nombre del evento\r\n * @param data - Datos adicionales del evento\r\n *\r\n * @example\r\n * ```ts\r\n * pushToDataLayer('page_view', { page_path: '/kin' })\r\n * pushToDataLayer('cta_click', { button_text: 'Únete', section: 'hero' })\r\n * ```\r\n */\r\nexport const pushToDataLayer = (eventName: string, data?: Record<string, unknown>): void => {\r\n if (typeof window === 'undefined') return;\r\n\r\n window.dataLayer = window.dataLayer || [];\r\n window.dataLayer.push({\r\n event: eventName,\r\n ...data,\r\n });\r\n};\r\n","/**\r\n * VideoTracker — Tracking avanzado de video para GA4\r\n * Gestiona el estado de reproducción por video y emite eventos a Google Analytics.\r\n * Framework-agnostic (no requiere React).\r\n */\r\n\r\nimport { trackEvent } from '../core/analytics';\r\nimport type { VideoTrackingState } from '../core/types';\r\n\r\nexport class VideoTracker {\r\n private videos: Map<string, VideoTrackingState> = new Map();\r\n private watchTimeIntervals: Map<string, ReturnType<typeof setInterval>> = new Map();\r\n\r\n /**\r\n * Inicializa el tracking para un video.\r\n */\r\n initVideo(videoId: string): void {\r\n if (this.videos.has(videoId)) return;\r\n\r\n const state: VideoTrackingState = {\r\n videoId,\r\n startTime: Date.now(),\r\n totalWatchTime: 0,\r\n playCount: 0,\r\n pauseCount: 0,\r\n seekCount: 0,\r\n completionPercentage: 0,\r\n lastPlayTimestamp: 0,\r\n isPlaying: false,\r\n currentTime: 0,\r\n duration: 0,\r\n pauseTimes: [],\r\n seekEvents: [],\r\n progressMilestones: new Set(),\r\n playbackSpeed: 1,\r\n };\r\n\r\n this.videos.set(videoId, state);\r\n\r\n trackEvent('Video', 'init', videoId, undefined, {\r\n video_id: videoId,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de evento play.\r\n */\r\n trackPlay(videoId: string, currentTime: number = 0): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.playCount++;\r\n state.isPlaying = true;\r\n state.lastPlayTimestamp = Date.now();\r\n state.currentTime = currentTime;\r\n\r\n // Iniciar conteo de tiempo de reproducción\r\n this.startWatchTimeTracking(videoId);\r\n\r\n trackEvent('Video', 'play', videoId, undefined, {\r\n video_id: videoId,\r\n play_count: state.playCount,\r\n current_time: Math.round(currentTime),\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de evento pause.\r\n */\r\n trackPause(videoId: string, currentTime: number, duration?: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.pauseCount++;\r\n state.isPlaying = false;\r\n state.currentTime = currentTime;\r\n state.pauseTimes.push(currentTime);\r\n\r\n if (duration) {\r\n state.duration = duration;\r\n state.completionPercentage = Math.round((currentTime / duration) * 100);\r\n }\r\n\r\n // Detener conteo de tiempo\r\n this.stopWatchTimeTracking(videoId);\r\n\r\n trackEvent('Video', 'pause', videoId, undefined, {\r\n video_id: videoId,\r\n pause_count: state.pauseCount,\r\n current_time: Math.round(currentTime),\r\n completion_percentage: state.completionPercentage,\r\n total_watch_time: Math.round(state.totalWatchTime),\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de evento seek (saltar en el timeline).\r\n */\r\n trackSeek(videoId: string, fromTime: number, toTime: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.seekCount++;\r\n state.seekEvents.push({ from: fromTime, to: toTime });\r\n\r\n trackEvent('Video', 'seek', videoId, undefined, {\r\n video_id: videoId,\r\n seek_count: state.seekCount,\r\n from_time: Math.round(fromTime),\r\n to_time: Math.round(toTime),\r\n skip_duration: Math.round(toTime - fromTime),\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de progreso (milestones: 25%, 50%, 75%).\r\n */\r\n trackProgress(videoId: string, percentage: number, currentTime: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n const milestone = Math.floor(percentage / 25) * 25;\r\n\r\n // Solo emitir cada milestone una vez\r\n if (milestone > 0 && milestone < 100 && !state.progressMilestones.has(milestone)) {\r\n state.progressMilestones.add(milestone);\r\n\r\n trackEvent('Video', 'progress', videoId, milestone, {\r\n video_id: videoId,\r\n progress_percentage: milestone,\r\n current_time: Math.round(currentTime),\r\n total_watch_time: Math.round(state.totalWatchTime),\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Tracking de completación del video (≥95%).\r\n */\r\n trackComplete(videoId: string, totalDuration: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.completionPercentage = 100;\r\n state.duration = totalDuration;\r\n this.stopWatchTimeTracking(videoId);\r\n\r\n trackEvent('Video', 'complete', videoId, undefined, {\r\n video_id: videoId,\r\n total_duration: Math.round(totalDuration),\r\n total_watch_time: Math.round(state.totalWatchTime),\r\n play_count: state.playCount,\r\n pause_count: state.pauseCount,\r\n seek_count: state.seekCount,\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de fin del video (evento ended nativo).\r\n */\r\n trackEnd(videoId: string): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.isPlaying = false;\r\n this.stopWatchTimeTracking(videoId);\r\n\r\n trackEvent('Video', 'end', videoId, undefined, {\r\n video_id: videoId,\r\n total_watch_time: Math.round(state.totalWatchTime),\r\n play_count: state.playCount,\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de cambio de velocidad de reproducción.\r\n */\r\n trackSpeedChange(videoId: string, speed: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n state.playbackSpeed = speed;\r\n\r\n trackEvent('Video', 'speed_change', videoId, undefined, {\r\n video_id: videoId,\r\n playback_speed: speed,\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de pantalla completa.\r\n */\r\n trackFullscreen(videoId: string, isFullscreen: boolean): void {\r\n trackEvent('Video', isFullscreen ? 'fullscreen_enter' : 'fullscreen_exit', videoId, undefined, {\r\n video_id: videoId,\r\n is_fullscreen: isFullscreen,\r\n });\r\n }\r\n\r\n /**\r\n * Tracking de no interacción (el usuario está en la página pero no interactúa con el video).\r\n */\r\n trackNoInteraction(videoId: string, timeOnPage: number): void {\r\n trackEvent('Video', 'no_interaction', videoId, undefined, {\r\n video_id: videoId,\r\n time_on_page: Math.round(timeOnPage),\r\n });\r\n }\r\n\r\n /**\r\n * Obtiene el estado actual de un video.\r\n */\r\n getState(videoId: string): VideoTrackingState | undefined {\r\n return this.videos.get(videoId);\r\n }\r\n\r\n /**\r\n * Limpia el tracking de un video específico.\r\n */\r\n cleanup(videoId: string): void {\r\n this.stopWatchTimeTracking(videoId);\r\n this.videos.delete(videoId);\r\n }\r\n\r\n /**\r\n * Limpia todo el tracking.\r\n */\r\n cleanupAll(): void {\r\n for (const videoId of this.videos.keys()) {\r\n this.stopWatchTimeTracking(videoId);\r\n }\r\n this.videos.clear();\r\n }\r\n\r\n // --- Métodos privados ---\r\n\r\n private getOrCreateState(videoId: string): VideoTrackingState {\r\n if (!this.videos.has(videoId)) {\r\n this.initVideo(videoId);\r\n }\r\n return this.videos.get(videoId)!;\r\n }\r\n\r\n private startWatchTimeTracking(videoId: string): void {\r\n this.stopWatchTimeTracking(videoId);\r\n\r\n const interval = setInterval(() => {\r\n const state = this.videos.get(videoId);\r\n if (state?.isPlaying) {\r\n state.totalWatchTime += 1;\r\n }\r\n }, 1000);\r\n\r\n this.watchTimeIntervals.set(videoId, interval);\r\n }\r\n\r\n private stopWatchTimeTracking(videoId: string): void {\r\n const interval = this.watchTimeIntervals.get(videoId);\r\n if (interval) {\r\n clearInterval(interval);\r\n this.watchTimeIntervals.delete(videoId);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Instancia singleton del VideoTracker.\r\n * Usar cuando se necesita una sola instancia global.\r\n */\r\nexport const videoTracker = new VideoTracker();\r\n","/**\r\n * Funciones genéricas de tracking de eventos para GA4.\r\n * Cada función es una abstracción de `trackEvent()` con categoría y acción predefinidas.\r\n */\r\n\r\nimport { trackEvent } from '../core/analytics';\r\nimport type { TrackingEventData } from '../core/types';\r\n\r\n// ====================================\r\n// CTA / BOTONES\r\n// ====================================\r\n\r\nexport const trackCTAClick = (buttonName: string, section: string, additionalData?: TrackingEventData): void => {\r\n trackEvent('CTA', 'click', buttonName, undefined, {\r\n button_name: buttonName,\r\n section,\r\n ...additionalData,\r\n });\r\n};\r\n\r\n// ====================================\r\n// FORMULARIOS\r\n// ====================================\r\n\r\nexport const trackFormStart = (formName: string): void => {\r\n trackEvent('Form', 'started', formName, undefined, {\r\n form_name: formName,\r\n timestamp: Date.now(),\r\n });\r\n};\r\n\r\nexport const trackFormFieldComplete = (formName: string, fieldName: string): void => {\r\n trackEvent('Form', 'field_completed', formName, undefined, {\r\n form_name: formName,\r\n field_name: fieldName,\r\n });\r\n};\r\n\r\nexport const trackFormSubmit = (formName: string, success: boolean, additionalData?: TrackingEventData): void => {\r\n trackEvent('Form', success ? 'submit_success' : 'submit_error', formName, undefined, {\r\n form_name: formName,\r\n success,\r\n ...additionalData,\r\n });\r\n};\r\n\r\nexport const trackFormValidationError = (formName: string, fieldName: string, errorMessage: string): void => {\r\n trackEvent('Error', 'validation', formName, undefined, {\r\n form_name: formName,\r\n field_name: fieldName,\r\n error_message: errorMessage,\r\n });\r\n};\r\n\r\n// ====================================\r\n// CONVERSIONES\r\n// ====================================\r\n\r\nexport const trackConversion = (conversionType: string, value?: number, additionalData?: TrackingEventData): void => {\r\n trackEvent('Conversion', conversionType, undefined, value, {\r\n conversion_type: conversionType,\r\n ...additionalData,\r\n });\r\n};\r\n\r\n// ====================================\r\n// REDES SOCIALES\r\n// ====================================\r\n\r\nexport const trackSocialClick = (platform: string, action: string, additionalData?: TrackingEventData): void => {\r\n trackEvent('Social', 'click', platform, undefined, {\r\n social_platform: platform,\r\n social_action: action,\r\n ...additionalData,\r\n });\r\n};\r\n\r\n// ====================================\r\n// FAQ\r\n// ====================================\r\n\r\nexport const trackFAQExpand = (question: string, index: number): void => {\r\n trackEvent('FAQ', 'expand', question, index, {\r\n question,\r\n question_index: index,\r\n });\r\n};\r\n\r\n// ====================================\r\n// ENGAGEMENT\r\n// ====================================\r\n\r\nexport const trackImageClick = (imageName: string, section: string): void => {\r\n trackEvent('Engagement', 'image_click', imageName, undefined, {\r\n image_name: imageName,\r\n section,\r\n });\r\n};\r\n\r\nexport const trackTimeInSection = (sectionName: string, seconds: number): void => {\r\n if (seconds < 3) return; // Ignorar secciones vistas menos de 3 segundos\r\n\r\n trackEvent('Engagement', 'time_in_section', sectionName, Math.round(seconds), {\r\n section_name: sectionName,\r\n time_seconds: Math.round(seconds),\r\n });\r\n};\r\n\r\n// ====================================\r\n// NAVEGACIÓN\r\n// ====================================\r\n\r\nexport const trackSectionClick = (section: string): void => {\r\n trackEvent('Navigation', 'section_click', section);\r\n};\r\n\r\nexport const trackScrollTo = (section: string): void => {\r\n trackEvent('Navigation', 'scroll_to', section);\r\n};\r\n\r\n// ====================================\r\n// PRICING\r\n// ====================================\r\n\r\nexport const trackPricingCardClick = (productName: string, price: number | string, additionalData?: TrackingEventData): void => {\r\n trackEvent('Pricing', 'card_click', productName, undefined, {\r\n product_name: productName,\r\n price: String(price),\r\n ...additionalData,\r\n });\r\n};\r\n\r\n// ====================================\r\n// CONTACTO\r\n// ====================================\r\n\r\nexport const trackContactClick = (method: string): void => {\r\n trackEvent('Contact', 'click', method, undefined, {\r\n contact_method: method,\r\n });\r\n};\r\n\r\n// ====================================\r\n// COMPARTIR\r\n// ====================================\r\n\r\nexport const trackShare = (platform: string, content: string): void => {\r\n trackEvent('Share', 'click', platform, undefined, {\r\n share_platform: platform,\r\n share_content: content,\r\n });\r\n};\r\n\r\n// ====================================\r\n// DESCARGAS\r\n// ====================================\r\n\r\nexport const trackDownload = (fileName: string, fileType: string): void => {\r\n trackEvent('Download', 'click', fileName, undefined, {\r\n file_name: fileName,\r\n file_type: fileType,\r\n });\r\n};\r\n\r\n// ====================================\r\n// FUNNEL — ETAPA 5: QUIZ (Regla 1)\r\n// ====================================\r\n\r\n/**\r\n * Trackea el inicio de un quiz (Regla 1, Etapa 5).\r\n * El quiz funciona como mecanismo de lead scoring implícito.\r\n */\r\nexport const trackQuizStart = (quizName: string): void => {\r\n trackEvent('Quiz', 'started', quizName, undefined, {\r\n quiz_name: quizName,\r\n });\r\n};\r\n\r\n/**\r\n * Trackea una respuesta individual del quiz.\r\n */\r\nexport const trackQuizAnswer = (\r\n quizName: string,\r\n questionIndex: number,\r\n answer: string,\r\n): void => {\r\n trackEvent('Quiz', 'answer', quizName, questionIndex, {\r\n quiz_name: quizName,\r\n question_index: questionIndex,\r\n answer,\r\n });\r\n};\r\n\r\n/**\r\n * Trackea la finalización del quiz (Regla 1, Etapa 5).\r\n */\r\nexport const trackQuizComplete = (\r\n quizName: string,\r\n totalQuestions?: number,\r\n score?: number,\r\n): void => {\r\n trackEvent('Quiz', 'completed', quizName, totalQuestions, {\r\n quiz_name: quizName,\r\n ...(totalQuestions !== undefined && { total_questions: totalQuestions }),\r\n ...(score !== undefined && { score }),\r\n });\r\n};\r\n\r\n// ====================================\r\n// FUNNEL — ETAPA 6: THANK YOU PAGE (Regla 1)\r\n// ====================================\r\n\r\n/**\r\n * Trackea la visita a la Thank You Page (Regla 1, Etapa 6).\r\n * Confirma que el lead completó el flujo del funnel.\r\n */\r\nexport const trackThankYouPageVisit = (source?: string): void => {\r\n trackEvent('Funnel', 'thank_you_page_visit', source);\r\n};\r\n\r\n// ====================================\r\n// FUNNEL — ETAPA 7: WHATSAPP CLICK (Regla 1)\r\n// ====================================\r\n\r\n/**\r\n * Trackea el clic al link de WhatsApp (Regla 1, Etapa 7).\r\n * Complementa markWhatsAppSent() que marca post-hoc.\r\n */\r\nexport const trackWhatsAppClick = (phoneNumber?: string, section?: string): void => {\r\n trackEvent('WhatsApp', 'click', section, undefined, {\r\n ...(phoneNumber && { phone_number: phoneNumber }),\r\n ...(section && { section }),\r\n });\r\n};\r\n","/**\r\n * Adaptador de video Wistia\r\n * Detecta automáticamente el SDK de Wistia y se enlaza a sus eventos.\r\n * Framework-agnostic.\r\n */\r\n\r\nimport type { VideoStats, VideoUpdateCallback, VideoTrackerHandle } from '../core/types';\r\n\r\nconst createStats = (timeWatched: number, completed: boolean): VideoStats => ({\r\n timeWatched: Math.max(0, Math.round(timeWatched)),\r\n completed,\r\n lastUpdate: Date.now(),\r\n});\r\n\r\n/**\r\n * Inicia tracking de un video Wistia por su Media ID.\r\n * Detecta si el player es Wistia nativo o un <video> HTML5.\r\n * Retorna un handle con getStats(), onUpdate() y stop().\r\n *\r\n * @example\r\n * ```ts\r\n * const tracker = await trackWistiaByMediaId('abc123')\r\n * tracker.onUpdate((stats) => {\r\n * console.log(stats.timeWatched, stats.completed)\r\n * })\r\n * // Al desmontar:\r\n * tracker.stop()\r\n * ```\r\n */\r\nexport const trackWistiaByMediaId = async (mediaId: string): Promise<VideoTrackerHandle | null> => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n let stats: VideoStats = createStats(0, false);\r\n let updateCallbacks: VideoUpdateCallback[] = [];\r\n let stopped = false;\r\n\r\n const callUpdate = (): void => {\r\n updateCallbacks.forEach((cb) => cb(stats));\r\n };\r\n\r\n // --- Estrategia 1: Wistia SDK nativo via window._wq ---\r\n const bindWistiaSDK = (): boolean => {\r\n if (!window._wq) return false;\r\n\r\n window._wq.push({\r\n id: mediaId,\r\n onReady: (rawVideo: unknown) => {\r\n if (stopped) return;\r\n\r\n const video = rawVideo as {\r\n time: () => number;\r\n duration: () => number;\r\n percentWatched: () => number;\r\n bind: (event: string, cb: (...args: unknown[]) => void) => void;\r\n unbind: (event: string) => void;\r\n };\r\n\r\n const updateFromWistia = (): void => {\r\n const t = video.time();\r\n const d = video.duration();\r\n const pct = d > 0 ? Math.round((t / d) * 100) : 0;\r\n const isCompleted = stats.completed || pct >= 95;\r\n const newTime = Math.max(stats.timeWatched, Math.round(t));\r\n\r\n if (newTime !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTime, isCompleted);\r\n callUpdate();\r\n }\r\n };\r\n\r\n video.bind('play', updateFromWistia);\r\n video.bind('pause', updateFromWistia);\r\n video.bind('secondchange', updateFromWistia);\r\n video.bind('end', () => {\r\n stats = createStats(Math.round(video.duration()), true);\r\n callUpdate();\r\n });\r\n },\r\n });\r\n\r\n return true;\r\n };\r\n\r\n // --- Estrategia 2: <video> HTML5 fallback ---\r\n const bindHTML5Fallback = (): void => {\r\n const selector = `[data-wistia-id=\"${mediaId}\"], .wistia_embed[data-media-id=\"${mediaId}\"]`;\r\n const container = document.querySelector(selector);\r\n if (!container) return;\r\n\r\n const video = container.querySelector('video');\r\n if (!video) return;\r\n\r\n const onTimeUpdate = (): void => {\r\n if (stopped) return;\r\n const ct = Math.round(video.currentTime || 0);\r\n const dur = video.duration || 0;\r\n const pct = dur > 0 ? Math.round((ct / dur) * 100) : 0;\r\n const isCompleted = stats.completed || pct >= 95 || video.ended;\r\n const newTime = Math.max(stats.timeWatched, ct);\r\n\r\n if (newTime !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTime, isCompleted);\r\n callUpdate();\r\n }\r\n };\r\n\r\n const onEnded = (): void => {\r\n if (stopped) return;\r\n stats = createStats(Math.max(stats.timeWatched, Math.round(video.duration || 0)), true);\r\n callUpdate();\r\n };\r\n\r\n video.addEventListener('timeupdate', onTimeUpdate);\r\n video.addEventListener('ended', onEnded);\r\n };\r\n\r\n // Intentar ambas estrategias\r\n const wistiaReady = bindWistiaSDK();\r\n if (!wistiaReady) {\r\n // Esperar un poco e intentar con HTML5\r\n await new Promise<void>((resolve) => setTimeout(resolve, 2000));\r\n bindHTML5Fallback();\r\n }\r\n\r\n return {\r\n getStats: () => stats,\r\n onUpdate: (cb: VideoUpdateCallback) => {\r\n updateCallbacks.push(cb);\r\n return () => {\r\n updateCallbacks = updateCallbacks.filter((x) => x !== cb);\r\n };\r\n },\r\n stop: () => {\r\n stopped = true;\r\n updateCallbacks = [];\r\n },\r\n };\r\n};\r\n","/**\r\n * Adaptador de video Voomly\r\n * Usa 3 estrategias complementarias para trackear videos embebidos de Voomly.\r\n * Framework-agnostic.\r\n */\r\n\r\nimport type { VideoStats, VideoUpdateCallback, VideoTrackerHandle } from '../core/types';\r\n\r\nconst createStats = (timeWatched: number, completed: boolean): VideoStats => ({\r\n timeWatched: Math.max(0, Math.round(timeWatched)),\r\n completed,\r\n lastUpdate: Date.now(),\r\n});\r\n\r\n/**\r\n * Busca recursivamente elementos <video> dentro de un root (document, shadow DOM, iframes).\r\n */\r\nconst findAllVideosInElement = (root: Element | Document | ShadowRoot): HTMLVideoElement[] => {\r\n const results: HTMLVideoElement[] = [];\r\n\r\n // Buscar videos directos\r\n const videos = Array.from(root.querySelectorAll('video')) as HTMLVideoElement[];\r\n results.push(...videos);\r\n\r\n // Buscar en Shadow DOM\r\n const allElements = root.querySelectorAll('*');\r\n for (const el of Array.from(allElements)) {\r\n if (el.shadowRoot) {\r\n results.push(...findAllVideosInElement(el.shadowRoot));\r\n }\r\n }\r\n\r\n // Buscar en iframes (solo same-origin)\r\n const iframes = root.querySelectorAll('iframe');\r\n for (const iframe of Array.from(iframes)) {\r\n try {\r\n const doc = iframe.contentDocument || iframe.contentWindow?.document;\r\n if (doc) {\r\n results.push(...findAllVideosInElement(doc));\r\n }\r\n } catch {\r\n // Ignorar iframes bloqueados por CORS\r\n }\r\n }\r\n\r\n return results;\r\n};\r\n\r\n/**\r\n * Inicia tracking de un video Voomly por su Embed ID.\r\n * Usa 3 estrategias complementarias:\r\n * 1. Scan periódico del DOM (cada 2s) buscando <video> dentro del embed\r\n * 2. Polling de respaldo (cada 1s) leyendo .currentTime\r\n * 3. Eventos globales de window (voomly:video:*)\r\n *\r\n * @example\r\n * ```ts\r\n * const tracker = await trackVoomlyByEmbedId('my-voomly-id')\r\n * tracker.onUpdate((stats) => console.log(stats))\r\n * // IMPORTANTE: llamar stop() al desmontar para evitar memory leaks\r\n * tracker.stop()\r\n * ```\r\n */\r\nexport const trackVoomlyByEmbedId = async (embedId: string): Promise<VideoTrackerHandle | null> => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n let stats: VideoStats = createStats(0, false);\r\n let updateCallbacks: VideoUpdateCallback[] = [];\r\n const trackedVideos = new Set<HTMLVideoElement>();\r\n\r\n const callUpdate = (): void => {\r\n updateCallbacks.forEach((cb) => cb(stats));\r\n };\r\n\r\n const updateStatsFromVideo = (video: HTMLVideoElement): void => {\r\n const ct = Math.round(video.currentTime || 0);\r\n const dur = video.duration || 0;\r\n const pct = dur ? Math.round((ct / dur) * 100) : 0;\r\n\r\n const isCompleted = stats.completed || pct >= 90 || video.ended;\r\n const newTimeWatched = Math.max(stats.timeWatched, ct);\r\n\r\n if (newTimeWatched !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTimeWatched, isCompleted);\r\n callUpdate();\r\n }\r\n };\r\n\r\n // --- Event handlers para <video> HTML5 ---\r\n const onPlay = (e: Event): void => updateStatsFromVideo(e.target as HTMLVideoElement);\r\n const onPause = (e: Event): void => updateStatsFromVideo(e.target as HTMLVideoElement);\r\n const onTime = (e: Event): void => updateStatsFromVideo(e.target as HTMLVideoElement);\r\n const onEnd = (e: Event): void => updateStatsFromVideo(e.target as HTMLVideoElement);\r\n\r\n const bindVideo = (video: HTMLVideoElement): void => {\r\n if (trackedVideos.has(video)) return;\r\n trackedVideos.add(video);\r\n\r\n video.addEventListener('play', onPlay);\r\n video.addEventListener('pause', onPause);\r\n video.addEventListener('timeupdate', onTime);\r\n video.addEventListener('ended', onEnd);\r\n };\r\n\r\n // --- Estrategia 1: Scan periódico del DOM ---\r\n const scanForVideos = (): void => {\r\n const selector = `.voomly-embed[data-id=\"${embedId}\"]`;\r\n const container = document.querySelector(selector);\r\n\r\n let foundVideos: HTMLVideoElement[] = [];\r\n\r\n if (container) {\r\n foundVideos = findAllVideosInElement(container);\r\n }\r\n\r\n // Fallback: buscar en todo el document si no hay en el container\r\n if (foundVideos.length === 0) {\r\n foundVideos = findAllVideosInElement(document);\r\n }\r\n\r\n foundVideos.forEach((v) => bindVideo(v));\r\n };\r\n\r\n scanForVideos();\r\n const scanInterval = setInterval(scanForVideos, 2000);\r\n\r\n // --- Estrategia 2: Polling de respaldo ---\r\n const pollingInterval = setInterval(() => {\r\n trackedVideos.forEach((video) => {\r\n const ct = Math.round(video.currentTime || 0);\r\n if (!video.paused || ct > 0) {\r\n updateStatsFromVideo(video);\r\n }\r\n });\r\n }, 1000);\r\n\r\n // --- Estrategia 3: Eventos globales de Voomly API ---\r\n const handleVoomlyWindowEvents = (e: Event): void => {\r\n try {\r\n const customEvent = e as CustomEvent;\r\n const payload = customEvent.detail || (customEvent as unknown as { payload: unknown }).payload;\r\n const playerInfo = (payload as Record<string, unknown>)?.playerInfo || payload;\r\n const id = (playerInfo as Record<string, unknown>)?.id || (playerInfo as Record<string, unknown>)?.videoId;\r\n\r\n // Si el evento tiene un ID y no coincide, ignorar\r\n if (id && id !== embedId) return;\r\n\r\n const currentTime =\r\n ((payload as Record<string, unknown>)?.currentTime as number) || ((payload as Record<string, unknown>)?.time as number) || 0;\r\n const duration =\r\n ((payload as Record<string, unknown>)?.duration as number) || ((payload as Record<string, unknown>)?.totalTime as number) || 0;\r\n let completed = false;\r\n\r\n if (e.type === 'voomly:video:ended' || e.type === 'voomly:video:complete') {\r\n completed = true;\r\n }\r\n\r\n if (currentTime > 0 || completed) {\r\n const pct = duration ? Math.round((currentTime / duration) * 100) : 0;\r\n const isCompleted = stats.completed || completed || pct >= 90;\r\n const newTimeWatched = Math.max(stats.timeWatched, Math.round(currentTime));\r\n\r\n if (newTimeWatched !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTimeWatched, isCompleted);\r\n callUpdate();\r\n }\r\n }\r\n } catch {\r\n // ignore parsing errors\r\n }\r\n };\r\n\r\n const windowEvents = ['voomly:video:play', 'voomly:video:timeupdate', 'voomly:video:ended', 'voomly:video:progress'];\r\n windowEvents.forEach((evt) => window.addEventListener(evt, handleVoomlyWindowEvents));\r\n\r\n // --- Stop / cleanup ---\r\n const stop = (): void => {\r\n clearInterval(scanInterval);\r\n clearInterval(pollingInterval);\r\n trackedVideos.forEach((video) => {\r\n video.removeEventListener('play', onPlay);\r\n video.removeEventListener('pause', onPause);\r\n video.removeEventListener('timeupdate', onTime);\r\n video.removeEventListener('ended', onEnd);\r\n });\r\n windowEvents.forEach((evt) => window.removeEventListener(evt, handleVoomlyWindowEvents));\r\n updateCallbacks = [];\r\n };\r\n\r\n return {\r\n getStats: () => stats,\r\n onUpdate: (cb: VideoUpdateCallback) => {\r\n updateCallbacks.push(cb);\r\n return () => {\r\n updateCallbacks = updateCallbacks.filter((x) => x !== cb);\r\n };\r\n },\r\n stop,\r\n };\r\n};\r\n","/**\r\n * Adaptador de video HTML5 nativo\r\n * Tracking puro de elementos <video> sin dependencia de React.\r\n */\r\n\r\nimport type { VideoStats, VideoUpdateCallback, VideoTrackerHandle } from '../core/types';\r\n\r\nconst createStats = (timeWatched: number, completed: boolean): VideoStats => ({\r\n timeWatched: Math.max(0, Math.round(timeWatched)),\r\n completed,\r\n lastUpdate: Date.now(),\r\n});\r\n\r\n/**\r\n * Inicia tracking de un elemento <video> HTML5 nativo.\r\n * Escucha eventos estándar del Video API del navegador.\r\n *\r\n * @example\r\n * ```ts\r\n * const video = document.querySelector('video')\r\n * const tracker = trackHTML5Video('hero-video', video)\r\n * tracker.onUpdate((stats) => console.log(stats))\r\n * // Al desmontar:\r\n * tracker.stop()\r\n * ```\r\n */\r\nexport const trackHTML5Video = (videoId: string, videoElement: HTMLVideoElement): VideoTrackerHandle => {\r\n let stats: VideoStats = createStats(0, false);\r\n let updateCallbacks: VideoUpdateCallback[] = [];\r\n const trackedMilestones = new Set<number>();\r\n\r\n const callUpdate = (): void => {\r\n updateCallbacks.forEach((cb) => cb(stats));\r\n };\r\n\r\n const onTimeUpdate = (): void => {\r\n const ct = Math.round(videoElement.currentTime || 0);\r\n const dur = videoElement.duration || 0;\r\n const pct = dur > 0 ? Math.round((ct / dur) * 100) : 0;\r\n\r\n // Actualizar stats\r\n const newTime = Math.max(stats.timeWatched, ct);\r\n const isCompleted = stats.completed || pct >= 95 || videoElement.ended;\r\n\r\n if (newTime !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTime, isCompleted);\r\n callUpdate();\r\n }\r\n\r\n // Milestones (25, 50, 75)\r\n for (const milestone of [25, 50, 75]) {\r\n if (pct >= milestone && !trackedMilestones.has(milestone)) {\r\n trackedMilestones.add(milestone);\r\n }\r\n }\r\n };\r\n\r\n const onEnded = (): void => {\r\n const dur = Math.round(videoElement.duration || 0);\r\n stats = createStats(Math.max(stats.timeWatched, dur), true);\r\n callUpdate();\r\n };\r\n\r\n const onPlay = (): void => {\r\n onTimeUpdate();\r\n };\r\n\r\n const onPause = (): void => {\r\n onTimeUpdate();\r\n };\r\n\r\n // Bind events\r\n videoElement.addEventListener('timeupdate', onTimeUpdate);\r\n videoElement.addEventListener('ended', onEnded);\r\n videoElement.addEventListener('play', onPlay);\r\n videoElement.addEventListener('pause', onPause);\r\n\r\n return {\r\n getStats: () => stats,\r\n onUpdate: (cb: VideoUpdateCallback) => {\r\n updateCallbacks.push(cb);\r\n return () => {\r\n updateCallbacks = updateCallbacks.filter((x) => x !== cb);\r\n };\r\n },\r\n stop: () => {\r\n videoElement.removeEventListener('timeupdate', onTimeUpdate);\r\n videoElement.removeEventListener('ended', onEnded);\r\n videoElement.removeEventListener('play', onPlay);\r\n videoElement.removeEventListener('pause', onPause);\r\n updateCallbacks = [];\r\n },\r\n };\r\n};\r\n","/**\r\n * LandingTracker — Orquestador de sesión completa\r\n * Inicializa y gestiona scroll tracking, click heatmap, section dwell time,\r\n * form auto-tracking y sesión start/end.\r\n * Framework-agnostic.\r\n */\r\n\r\nimport { trackEvent, captureUTMParams, captureUserIdFromURL, getUserName, trackPageView } from '../core/analytics';\r\nimport { pushToDataLayer, injectGTMScript } from '../core/gtm';\r\nimport { trackCTAClick, trackFormStart, trackFormSubmit, trackTimeInSection } from '../trackers/events';\r\nimport type { LandingTrackerConfig, ClickData } from '../core/types';\r\n\r\nexport class LandingTracker {\r\n private config: LandingTrackerConfig | null = null;\r\n private isInitialized = false;\r\n private sessionStartTime: number = 0;\r\n private scrollMilestonesReached = new Set<number>();\r\n private clicks: ClickData[] = [];\r\n private sectionTimers: Map<string, number> = new Map();\r\n private observers: IntersectionObserver[] = [];\r\n private listeners: Array<{ target: EventTarget; event: string; handler: EventListener }> = [];\r\n\r\n /**\r\n * Inicializa el tracking de la landing con la configuración dada.\r\n */\r\n init(config: LandingTrackerConfig): void {\r\n if (typeof window === 'undefined') return;\r\n if (this.isInitialized) return;\r\n\r\n this.config = {\r\n enableScrollTracking: true,\r\n enableCTATracking: true,\r\n enableTimeTracking: true,\r\n enableSectionTracking: true,\r\n enableFormTracking: true,\r\n enableHeatmap: false,\r\n eventSuffix: '',\r\n ...config,\r\n };\r\n\r\n this.isInitialized = true;\r\n this.sessionStartTime = Date.now();\r\n\r\n // Capturar datos iniciales del visitante\r\n this.captureInitialData();\r\n\r\n // Trackear carga de página\r\n trackPageView(this.config.pagePath);\r\n\r\n // Inyectar GTM si se proporcionó\r\n if (this.config.gtmId) {\r\n injectGTMScript(this.config.gtmId);\r\n pushToDataLayer(this.getEventName('page_load'), {\r\n page_path: this.config.pagePath,\r\n page_title: this.config.pageName,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n // Inicializar módulos de tracking\r\n if (this.config.enableScrollTracking) this.initScrollTracking();\r\n if (this.config.enableCTATracking) this.initCTATracking();\r\n if (this.config.enableTimeTracking) this.initTimeTracking();\r\n if (this.config.enableSectionTracking) this.initSectionTracking();\r\n if (this.config.enableFormTracking) this.initFormTracking();\r\n if (this.config.enableHeatmap) this.initClickHeatmap();\r\n\r\n // Trackear inicio de sesión\r\n this.trackSessionStart();\r\n }\r\n\r\n /**\r\n * Destruye el tracker y limpia todos los observers y listeners.\r\n */\r\n destroy(): void {\r\n // Cleanup observers\r\n this.observers.forEach((obs) => obs.disconnect());\r\n this.observers = [];\r\n\r\n // Cleanup event listeners\r\n this.listeners.forEach(({ target, event, handler }) => {\r\n target.removeEventListener(event, handler);\r\n });\r\n this.listeners = [];\r\n\r\n this.isInitialized = false;\r\n this.config = null;\r\n this.scrollMilestonesReached.clear();\r\n this.clicks = [];\r\n this.sectionTimers.clear();\r\n }\r\n\r\n // ====================================\r\n // MÉTODOS PÚBLICOS DE TRACKING\r\n // ====================================\r\n\r\n /** Trackear click en un CTA */\r\n trackCTAClick(buttonName: string, section: string, additionalData?: Record<string, unknown>): void {\r\n trackCTAClick(buttonName, section, additionalData);\r\n this.pushGTMEvent('cta_click', { button_text: buttonName, section });\r\n }\r\n\r\n /** Trackear conversión */\r\n trackConversion(type: string, value?: number, additionalData?: Record<string, unknown>): void {\r\n trackEvent('Conversion', type, undefined, value, additionalData);\r\n this.pushGTMEvent('conversion', { conversion_type: type, value });\r\n }\r\n\r\n /** Trackear click en FAQs */\r\n trackFAQExpand(question: string, index: number): void {\r\n trackEvent('FAQ', 'expand', question, index);\r\n }\r\n\r\n /** Trackear click social */\r\n trackSocialClick(platform: string, action: string): void {\r\n trackEvent('Social', 'click', platform, undefined, { social_action: action });\r\n }\r\n\r\n /** Trackear click en imagen */\r\n trackImageClick(imageName: string, section: string): void {\r\n trackEvent('Engagement', 'image_click', imageName, undefined, { section });\r\n }\r\n\r\n /** Trackear scroll a sección */\r\n trackScrollTo(section: string): void {\r\n trackEvent('Navigation', 'scroll_to', section);\r\n }\r\n\r\n /** Trackear share */\r\n trackShare(platform: string, content: string): void {\r\n trackEvent('Share', 'click', platform, undefined, { share_content: content });\r\n }\r\n\r\n /** Trackear descarga */\r\n trackDownload(fileName: string, fileType: string): void {\r\n trackEvent('Download', 'click', fileName, undefined, { file_type: fileType });\r\n }\r\n\r\n /** Obtener datos de la sesión actual */\r\n getSessionData(): { duration: number; clicks: number; scrollMilestones: number[] } {\r\n return {\r\n duration: Math.round((Date.now() - this.sessionStartTime) / 1000),\r\n clicks: this.clicks.length,\r\n scrollMilestones: Array.from(this.scrollMilestonesReached),\r\n };\r\n }\r\n\r\n // ====================================\r\n // MÉTODOS PRIVADOS\r\n // ====================================\r\n\r\n private captureInitialData(): void {\r\n const utmParams = captureUTMParams();\r\n const userId = captureUserIdFromURL();\r\n const userName = getUserName();\r\n\r\n const prefix = this.config!.pagePath.replace('/', '');\r\n\r\n try {\r\n localStorage.setItem(`${prefix}_entry_time`, new Date().toISOString());\r\n if (utmParams) {\r\n localStorage.setItem(`${prefix}_utm_params`, JSON.stringify(utmParams));\r\n }\r\n if (userId) {\r\n localStorage.setItem(`${prefix}_user_id`, userId);\r\n }\r\n } catch {\r\n // localStorage puede no estar disponible\r\n }\r\n\r\n // Enviar evento de carga\r\n trackEvent('Landing', 'page_load', this.config!.pageName, undefined, {\r\n page_path: this.config!.pagePath,\r\n user_id: userId,\r\n user_name: userName,\r\n utm_params: utmParams,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n private trackSessionStart(): void {\r\n trackEvent('Session', 'start', this.config!.pageName, undefined, {\r\n page_path: this.config!.pagePath,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n private getEventName(baseName: string): string {\r\n const suffix = this.config?.eventSuffix || '';\r\n return suffix ? `${baseName}${suffix}` : baseName;\r\n }\r\n\r\n private pushGTMEvent(eventName: string, data?: Record<string, unknown>): void {\r\n if (this.config?.gtmId) {\r\n pushToDataLayer(this.getEventName(eventName), {\r\n page_path: this.config.pagePath,\r\n ...data,\r\n });\r\n }\r\n }\r\n\r\n private addListener(target: EventTarget, event: string, handler: EventListener): void {\r\n target.addEventListener(event, handler);\r\n this.listeners.push({ target, event, handler });\r\n }\r\n\r\n // --- Scroll Tracking ---\r\n private initScrollTracking(): void {\r\n let scrollTimeout: ReturnType<typeof setTimeout>;\r\n\r\n const handler = (): void => {\r\n clearTimeout(scrollTimeout);\r\n scrollTimeout = setTimeout(() => {\r\n const scrollHeight = document.documentElement.scrollHeight - window.innerHeight;\r\n if (scrollHeight <= 0) return;\r\n\r\n const pct = Math.round((window.scrollY / scrollHeight) * 100);\r\n\r\n for (const milestone of [25, 50, 75, 100]) {\r\n if (pct >= milestone && !this.scrollMilestonesReached.has(milestone)) {\r\n this.scrollMilestonesReached.add(milestone);\r\n\r\n trackEvent('Scroll', 'milestone', `${milestone}%`, milestone, {\r\n page_path: this.config!.pagePath,\r\n scroll_percentage: milestone,\r\n });\r\n\r\n this.pushGTMEvent('scroll_milestone', { scroll_percentage: milestone });\r\n }\r\n }\r\n }, 100);\r\n };\r\n\r\n this.addListener(window, 'scroll', handler as EventListener);\r\n }\r\n\r\n // --- CTA Tracking ---\r\n private initCTATracking(): void {\r\n setTimeout(() => {\r\n const ctaButtons = document.querySelectorAll('button, a[href*=\"#\"], [data-cta]');\r\n ctaButtons.forEach((button) => {\r\n const handler = (): void => {\r\n const el = button as HTMLElement;\r\n const text = el.textContent?.trim() || el.getAttribute('data-cta') || 'Unknown CTA';\r\n const section = el.closest('section')?.id || el.closest('[data-section]')?.getAttribute('data-section') || 'unknown';\r\n\r\n this.trackCTAClick(text, section);\r\n };\r\n this.addListener(button, 'click', handler as EventListener);\r\n });\r\n }, 2000); // Esperar a que el DOM esté completo\r\n }\r\n\r\n // --- Time Tracking (page exit) ---\r\n private initTimeTracking(): void {\r\n const handler = (): void => {\r\n const duration = Math.round((Date.now() - this.sessionStartTime) / 1000);\r\n\r\n trackEvent('Session', 'end', this.config!.pageName, duration, {\r\n session_duration: duration,\r\n page_path: this.config!.pagePath,\r\n exit_timestamp: Date.now(),\r\n });\r\n\r\n this.pushGTMEvent('page_exit', {\r\n session_duration: duration,\r\n exit_timestamp: Date.now(),\r\n });\r\n };\r\n\r\n this.addListener(window, 'beforeunload', handler as EventListener);\r\n }\r\n\r\n // --- Section Dwell Time (IntersectionObserver) ---\r\n private initSectionTracking(): void {\r\n const sectionEntryTimes = new Map<string, number>();\r\n\r\n const observer = new IntersectionObserver(\r\n (entries) => {\r\n entries.forEach((entry) => {\r\n const sectionId = (entry.target as HTMLElement).id || (entry.target as HTMLElement).getAttribute('data-section') || 'unknown';\r\n\r\n if (entry.isIntersecting) {\r\n sectionEntryTimes.set(sectionId, Date.now());\r\n } else {\r\n const entryTime = sectionEntryTimes.get(sectionId);\r\n if (entryTime) {\r\n const seconds = (Date.now() - entryTime) / 1000;\r\n trackTimeInSection(sectionId, seconds);\r\n sectionEntryTimes.delete(sectionId);\r\n }\r\n }\r\n });\r\n },\r\n { threshold: 0.5 },\r\n );\r\n\r\n // Observar todas las secciones\r\n setTimeout(() => {\r\n const sections = document.querySelectorAll('section, [data-section]');\r\n sections.forEach((section) => observer.observe(section));\r\n }, 1000);\r\n\r\n this.observers.push(observer);\r\n }\r\n\r\n // --- Form Auto-Tracking ---\r\n private initFormTracking(): void {\r\n setTimeout(() => {\r\n const forms = document.querySelectorAll('form');\r\n forms.forEach((form) => {\r\n const formName = form.getAttribute('name') || form.id || 'unknown-form';\r\n\r\n // Track form focus (start)\r\n let started = false;\r\n const inputs = form.querySelectorAll('input, textarea, select');\r\n inputs.forEach((input) => {\r\n this.addListener(input, 'focus', (() => {\r\n if (!started) {\r\n started = true;\r\n trackFormStart(formName);\r\n }\r\n }) as EventListener);\r\n });\r\n\r\n // Track form submit\r\n this.addListener(form, 'submit', ((_e: Event) => {\r\n trackFormSubmit(formName, true, {\r\n page_path: this.config!.pagePath,\r\n });\r\n this.pushGTMEvent('form_submit', { form_name: formName });\r\n }) as EventListener);\r\n });\r\n }, 2000);\r\n }\r\n\r\n // --- Click Heatmap ---\r\n private initClickHeatmap(): void {\r\n const handler = (e: Event): void => {\r\n const mouseEvent = e as MouseEvent;\r\n const target = mouseEvent.target as HTMLElement;\r\n\r\n const clickData: ClickData = {\r\n x: mouseEvent.clientX,\r\n y: mouseEvent.clientY,\r\n element: target.tagName.toLowerCase(),\r\n section: target.closest('section')?.id || 'unknown',\r\n timestamp: Date.now(),\r\n viewportWidth: window.innerWidth,\r\n viewportHeight: window.innerHeight,\r\n };\r\n\r\n this.clicks.push(clickData);\r\n };\r\n\r\n this.addListener(document, 'click', handler as EventListener);\r\n }\r\n}\r\n\r\n/**\r\n * Factory function para crear un LandingTracker.\r\n *\r\n * @example\r\n * ```ts\r\n * const tracker = createLandingTracker({\r\n * pagePath: '/kin',\r\n * pageName: 'Kin Landing Page',\r\n * gtmId: 'GTM-5GMQNFMN',\r\n * })\r\n * // Al desmontar:\r\n * tracker.destroy()\r\n * ```\r\n */\r\nexport const createLandingTracker = (config: LandingTrackerConfig): LandingTracker => {\r\n const tracker = new LandingTracker();\r\n tracker.init(config);\r\n return tracker;\r\n};\r\n","/**\r\n * API Client — Cliente HTTP configurable para persistencia al backend.\r\n * Framework-agnostic. Usa fetch nativo.\r\n *\r\n * @example\r\n * ```ts\r\n * import { initTrackingAPI } from '@metodokorexmk/tracking';\r\n *\r\n * initTrackingAPI({\r\n * baseUrl: 'https://api.korex.com/api/v1',\r\n * getAuthToken: () => localStorage.getItem('access_token'),\r\n * });\r\n * ```\r\n */\r\n\r\nimport type { TrackingAPIConfig } from '../core/types';\r\n\r\nlet apiConfig: TrackingAPIConfig | null = null;\r\n\r\n/**\r\n * Inicializa el cliente HTTP para la capa de persistencia.\r\n * Debe llamarse antes de usar funciones de lead submission, dwell time o queries.\r\n */\r\nexport const initTrackingAPI = (config: TrackingAPIConfig): void => {\r\n apiConfig = {\r\n ...config,\r\n baseUrl: config.baseUrl.replace(/\\/+$/, ''),\r\n };\r\n};\r\n\r\n/**\r\n * Retorna la config actual. Lanza error si no se ha inicializado.\r\n */\r\nexport const getAPIConfig = (): TrackingAPIConfig => {\r\n if (!apiConfig) {\r\n throw new Error('[@metodokorexmk/tracking] initTrackingAPI() debe llamarse antes de usar funciones de persistencia.');\r\n }\r\n return apiConfig;\r\n};\r\n\r\n/**\r\n * Verifica si el API client ha sido inicializado.\r\n */\r\nexport const isTrackingAPIInitialized = (): boolean => apiConfig !== null;\r\n\r\n/**\r\n * Construye los headers de la petición, incluyendo auth token si está disponible.\r\n */\r\nconst buildHeaders = (): HeadersInit => {\r\n const config = getAPIConfig();\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n if (config.getAuthToken) {\r\n const token = config.getAuthToken();\r\n if (token) {\r\n headers.Authorization = `Bearer ${token}`;\r\n }\r\n }\r\n\r\n if (config.getCustomHeaders) {\r\n Object.assign(headers, config.getCustomHeaders());\r\n }\r\n\r\n return headers;\r\n};\r\n\r\n/**\r\n * GET request al API.\r\n */\r\nexport const apiGet = async <T>(path: string): Promise<T> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}${path}`;\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: buildHeaders(),\r\n credentials: 'include',\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text().catch(() => '');\r\n throw new Error(`API GET ${path} failed (${response.status}): ${errorText}`);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n};\r\n\r\n/**\r\n * POST request al API.\r\n */\r\nexport const apiPost = async <T>(path: string, body: Record<string, unknown>): Promise<T> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}${path}`;\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: buildHeaders(),\r\n body: JSON.stringify(body),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text().catch(() => '');\r\n throw new Error(`API POST ${path} failed (${response.status}): ${errorText}`);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n};\r\n\r\n/**\r\n * PATCH request al API con soporte para keepalive (útil en beforeunload).\r\n */\r\nexport const apiPatch = async <T>(\r\n path: string,\r\n body: Record<string, unknown>,\r\n options?: { keepalive?: boolean; timeoutMs?: number },\r\n): Promise<T> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}${path}`;\r\n const controller = new AbortController();\r\n\r\n const timeoutMs = options?.timeoutMs ?? 10000;\r\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers: buildHeaders(),\r\n body: JSON.stringify(body),\r\n keepalive: options?.keepalive ?? false,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text().catch(() => '');\r\n throw new Error(`API PATCH ${path} failed (${response.status}): ${errorText}`);\r\n }\r\n\r\n // Intentar parsear JSON, si falla retornar objeto vacío\r\n const text = await response.text();\r\n try {\r\n return JSON.parse(text) as T;\r\n } catch {\r\n return {} as T;\r\n }\r\n } catch (error) {\r\n clearTimeout(timeoutId);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * PATCH request usando fetch con keepalive (para beforeunload).\r\n * No espera respuesta. Fire-and-forget.\r\n */\r\nexport const apiPatchFireAndForget = (path: string, body: Record<string, unknown>): void => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}${path}`;\r\n\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n if (config.getAuthToken) {\r\n const token = config.getAuthToken();\r\n if (token) {\r\n headers.Authorization = `Bearer ${token}`;\r\n }\r\n }\r\n\r\n // Fire-and-forget con keepalive\r\n fetch(url, {\r\n method: 'PATCH',\r\n headers,\r\n body: JSON.stringify(body),\r\n keepalive: true,\r\n }).catch(() => {\r\n // Ignorar errores en fire-and-forget\r\n });\r\n};\r\n","/**\r\n * Lead Submission — Creación y actualización de leads en el backend.\r\n * Migrado de lead-origin-detector.ts, framework-agnostic.\r\n */\r\n\r\nimport type {\r\n UrlParams,\r\n LeadOrigin,\r\n LeadFormData,\r\n TrackingLeadResponse,\r\n SubmitTrackingLeadResponse,\r\n BuildRequestBodyOptions,\r\n} from '../core/types';\r\nimport { getAPIConfig } from './api-client';\r\n\r\n// ====================================\r\n// URL PARAMS\r\n// ====================================\r\n\r\n/**\r\n * Extrae todos los parámetros relevantes de la URL.\r\n *\r\n * @param url - URL opcional (si no se proporciona, usa window.location)\r\n * @returns Objeto con todos los parámetros extraídos\r\n */\r\nexport const extractUrlParams = (url?: string): UrlParams => {\r\n if (typeof window === 'undefined' && !url) {\r\n return {\r\n userId: '',\r\n idCampana: '',\r\n adsetId: '',\r\n adId: '',\r\n utmContent: '',\r\n fbclid: '',\r\n nombreNetworker: '',\r\n whatsapp: '',\r\n pipelineId: '',\r\n leadCampaign: 'Funnel Organico',\r\n leadCampaing: 'Funnel Organico',\r\n isOrganico: true,\r\n };\r\n }\r\n\r\n let searchParams: URLSearchParams;\r\n if (url) {\r\n try {\r\n const urlObj = new URL(url);\r\n searchParams = new URLSearchParams(urlObj.search);\r\n } catch {\r\n searchParams = new URLSearchParams();\r\n }\r\n } else {\r\n searchParams = new URLSearchParams(window.location.search);\r\n }\r\n\r\n const userId = searchParams.get('user_id') || '';\r\n const idCampana = searchParams.get('campaign_id') || searchParams.get('utm_id') || '';\r\n // Regla 3: Capturar adset_id y ad_id para trazabilidad Campaña → Conjunto → Anuncio\r\n const adsetId = searchParams.get('adset_id') || '';\r\n const adId = searchParams.get('ad_id') || '';\r\n const utmContent = searchParams.get('utm_content') || '';\r\n const fbclid = searchParams.get('fbclid') || '';\r\n const whatsapp = searchParams.get('whatsapp') || '';\r\n const nombreNetworker = searchParams.get('user_name') || searchParams.get('networker') || searchParams.get('name') || '';\r\n const pipelineId = searchParams.get('pipeline_id') || '';\r\n const funnelId = searchParams.get('funnel_id') || '';\r\n const metricId = searchParams.get('metric_id') || '';\r\n const utmSource = searchParams.get('utm_source') || '';\r\n const utmMedium = searchParams.get('utm_medium') || '';\r\n const utmCampaign = searchParams.get('utm_campaign') || '';\r\n const isOrganico = !!(whatsapp && !idCampana && !fbclid);\r\n const leadCampaing = fbclid ? 'Funnel FB' : 'Funnel Organico';\r\n\r\n return {\r\n userId,\r\n idCampana,\r\n adsetId,\r\n adId,\r\n utmContent,\r\n fbclid,\r\n nombreNetworker,\r\n whatsapp,\r\n pipelineId,\r\n funnelId,\r\n metricId,\r\n utmSource,\r\n utmMedium,\r\n utmCampaign,\r\n leadCampaign: leadCampaing,\r\n leadCampaing,\r\n isOrganico,\r\n };\r\n};\r\n\r\n// ====================================\r\n// ORIGIN DETECTION\r\n// ====================================\r\n\r\n/**\r\n * Detecta el origen del lead basándose en los parámetros de la URL.\r\n * Facebook Ads: tiene fbclid O campaign_id\r\n * Orgánico: tiene whatsapp Y NO tiene fbclid Y NO tiene campaign_id\r\n */\r\nexport const detectLeadOrigin = (url?: string): LeadOrigin => {\r\n const params = extractUrlParams(url);\r\n const hasCampaign = Boolean(params.idCampana || params.fbclid);\r\n const type: 'facebook' | 'organic' = hasCampaign ? 'facebook' : 'organic';\r\n\r\n const endpoint = hasCampaign ? '/tracking/create-with-lead-and-distribution' : '/tracking/create-organic-lead';\r\n\r\n return { type, endpoint, params, hasCampaign };\r\n};\r\n\r\n// ====================================\r\n// BODY BUILDER\r\n// ====================================\r\n\r\n/**\r\n * Construye el body de la petición según el tipo de origen.\r\n */\r\nexport const buildTrackingRequestBody = (\r\n params: UrlParams,\r\n formData: LeadFormData,\r\n origin: LeadOrigin,\r\n options?: BuildRequestBodyOptions,\r\n): Record<string, unknown> => {\r\n const collaboratorId = params.userId ? parseInt(params.userId, 10) : null;\r\n const telefonoLimpio = formData.telefono.replace(/\\s+/g, '');\r\n\r\n const body: Record<string, unknown> = {\r\n userName: formData.nombre.trim(),\r\n userEmail: formData.correo.trim(),\r\n entryDate: new Date().toISOString(),\r\n accessUrl: typeof window !== 'undefined' ? window.location.href : '',\r\n leadName: formData.nombre.trim(),\r\n leadEmail: formData.correo.trim(),\r\n leadPhone: formData.countryLada ? `${formData.countryLada}${telefonoLimpio}` : telefonoLimpio,\r\n };\r\n\r\n // Campos opcionales\r\n if (options?.nameForm) body.nameForm = options.nameForm;\r\n if (options?.msgForm) body.msgForm = options.msgForm;\r\n if (options?.status) body.status = options.status;\r\n if (options?.whatsappSent !== undefined) body.whatsapp_sent = options.whatsappSent;\r\n if (options?.dwellTime !== undefined) body.dwellTime = options.dwellTime;\r\n if (options?.videoTimeWatched !== undefined) body.videoTimeWatched = options.videoTimeWatched;\r\n if (options?.videoCompleted !== undefined) {\r\n body.videoCompleted = options.videoCompleted;\r\n body.video_completed = options.videoCompleted;\r\n }\r\n\r\n // Campos según tipo de origen\r\n if (origin.hasCampaign) {\r\n if (collaboratorId) body.userId = collaboratorId;\r\n if (params.idCampana) body.idCampana = params.idCampana;\r\n // Regla 3: Enviar adsetId y adId para trazabilidad completa\r\n if (params.adsetId) body.adsetId = params.adsetId;\r\n if (params.adId) body.adId = params.adId;\r\n if (params.utmContent) body.utmContent = params.utmContent;\r\n if (params.fbclid) body.fbclid = params.fbclid;\r\n } else if (collaboratorId) {\r\n body.referringUserId = collaboratorId;\r\n body.referring_user_id = collaboratorId;\r\n }\r\n\r\n // Pipeline, funnel, metric IDs\r\n if (params.pipelineId) {\r\n const parsed = parseInt(params.pipelineId, 10);\r\n if (!isNaN(parsed)) body.pipeline_id = parsed;\r\n }\r\n if (params.funnelId) {\r\n const parsed = parseInt(params.funnelId, 10);\r\n if (!isNaN(parsed)) body.funnel_id = parsed;\r\n }\r\n if (params.metricId) {\r\n const parsed = parseInt(params.metricId, 10);\r\n if (!isNaN(parsed)) body.metric_id = parsed;\r\n }\r\n\r\n // Campos adicionales\r\n if (options?.additionalFields) {\r\n Object.assign(body, options.additionalFields);\r\n }\r\n\r\n return body;\r\n};\r\n\r\n// ====================================\r\n// SUBMIT / UPDATE\r\n// ====================================\r\n\r\n/**\r\n * Envía el lead al endpoint correcto según su origen.\r\n */\r\nexport const submitTrackingLead = async (body: Record<string, unknown>, origin: LeadOrigin): Promise<SubmitTrackingLeadResponse> => {\r\n const config = getAPIConfig();\r\n const fullUrl = `${config.baseUrl}${origin.endpoint}`;\r\n\r\n try {\r\n const response = await fetch(fullUrl, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(body),\r\n });\r\n\r\n let data: TrackingLeadResponse | null = null;\r\n try {\r\n const text = await response.text();\r\n if (text) {\r\n const parsed = JSON.parse(text);\r\n if (parsed && typeof parsed === 'object') {\r\n data = parsed as TrackingLeadResponse;\r\n }\r\n }\r\n } catch {\r\n // Error de parsing, data queda null\r\n }\r\n\r\n return { ok: response.ok, status: response.status, data };\r\n } catch {\r\n return { ok: false, status: 0, data: null };\r\n }\r\n};\r\n\r\n/**\r\n * Función completa: detecta origen, construye body y envía el lead.\r\n *\r\n * @example\r\n * ```ts\r\n * const result = await submitLead(\r\n * { nombre: 'Juan', correo: 'juan@mail.com', telefono: '+34600...' },\r\n * { nameForm: 'Formulario Kin', videoCompleted: true },\r\n * );\r\n * ```\r\n */\r\nexport const submitLead = async (\r\n formData: LeadFormData,\r\n options?: BuildRequestBodyOptions,\r\n url?: string,\r\n): Promise<SubmitTrackingLeadResponse> => {\r\n const origin = detectLeadOrigin(url);\r\n const body = buildTrackingRequestBody(origin.params, formData, origin, options);\r\n return submitTrackingLead(body, origin);\r\n};\r\n\r\n/**\r\n * Actualiza un lead existente mediante PATCH.\r\n */\r\nexport const updateTrackingLead = async (trackingId: number | string, updates: Record<string, unknown>): Promise<boolean> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}/tracking/${trackingId}`;\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(updates),\r\n });\r\n return response.ok;\r\n } catch {\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Marca un lead como \"WhatsApp enviado\".\r\n */\r\nexport const markWhatsAppSent = async (leadId: number | string): Promise<boolean> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}/tracking/lead/${leadId}/whatsapp-sent`;\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ whatsapp_sent: true }),\r\n });\r\n return response.ok;\r\n } catch {\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Construye un msgForm como JSON stringificado.\r\n */\r\nexport const buildMsgFormJSON = (mensaje: string, datosAdicionales?: Record<string, unknown>): string => {\r\n return JSON.stringify({ mensaje: mensaje || '', ...datosAdicionales });\r\n};\r\n","/**\r\n * DwellTimeTracker — Tracking de tiempo de permanencia con envío periódico al backend.\r\n * Migrado de dwell-time.ts (~960 líneas → ~280 líneas limpias).\r\n * Framework-agnostic.\r\n */\r\n\r\nimport type { DwellTimeConfig } from '../core/types';\r\nimport { getAPIConfig, isTrackingAPIInitialized } from './api-client';\r\n\r\n/**\r\n * Clase que mide el tiempo de permanencia del usuario en una página\r\n * y lo envía periódicamente al backend de tracking.\r\n *\r\n * Características:\r\n * - Envío automático cada 30 segundos\r\n * - Pausa automática cuando la pestaña se oculta\r\n * - sendBeacon en beforeunload para máxima confiabilidad\r\n * - Retry de updates pendientes via sessionStorage\r\n * - Tracking de video integrado (videoTimeWatched, videoCompleted)\r\n */\r\nexport class DwellTimeTracker {\r\n private startTime: number | null = null;\r\n\r\n private trackingDataId: number | string | null = null;\r\n\r\n private enabled = false;\r\n\r\n private onSuccess?: () => void;\r\n\r\n private onError?: (error: Error) => void;\r\n\r\n private intervalId: ReturnType<typeof setInterval> | null = null;\r\n\r\n private isSending = false;\r\n\r\n private videoTimeWatched = 0;\r\n\r\n private videoCompleted = false;\r\n\r\n private videoTrackingStopped = false;\r\n\r\n private lastDwellTimeSent = 0;\r\n\r\n private lastVideoTimeSent = 0;\r\n\r\n private pausedTime = 0;\r\n\r\n private pauseStartTime: number | null = null;\r\n\r\n private boundBeforeUnload: (e: BeforeUnloadEvent) => void;\r\n\r\n private boundVisibilityChange: () => void;\r\n\r\n constructor() {\r\n this.boundBeforeUnload = this.handleBeforeUnload.bind(this);\r\n this.boundVisibilityChange = this.handleVisibilityChange.bind(this);\r\n }\r\n\r\n /**\r\n * Inicia el tracking del tiempo de permanencia.\r\n */\r\n start(config: DwellTimeConfig): void {\r\n if (typeof window === 'undefined') return;\r\n\r\n const wasAlreadyTracking = this.enabled;\r\n this.enabled = config.enabled !== false;\r\n this.trackingDataId = config.trackingDataId;\r\n this.onSuccess = config.onSuccess;\r\n this.onError = config.onError;\r\n\r\n if (!this.enabled) return;\r\n\r\n this.cleanupListeners();\r\n\r\n window.addEventListener('beforeunload', this.boundBeforeUnload);\r\n document.addEventListener('visibilitychange', this.boundVisibilityChange);\r\n\r\n if (!wasAlreadyTracking) {\r\n this.startTime = Date.now();\r\n }\r\n\r\n if (!this.intervalId) {\r\n this.intervalId = setInterval(() => {\r\n if (this.videoCompleted && this.videoTrackingStopped) {\r\n if (document.visibilityState === 'visible' && this.startTime) {\r\n this.sendDwellTime(false);\r\n }\r\n return;\r\n }\r\n\r\n if (this.videoCompleted && !this.videoTrackingStopped) {\r\n this.sendDwellTime(false);\r\n this.videoTrackingStopped = true;\r\n return;\r\n }\r\n\r\n if (document.visibilityState === 'visible' && this.startTime) {\r\n this.sendDwellTime(false);\r\n }\r\n }, 30000);\r\n }\r\n\r\n this.retryPendingUpdates();\r\n }\r\n\r\n /**\r\n * Detiene el tracking y envía el tiempo acumulado.\r\n */\r\n stop(): void {\r\n if (this.startTime) {\r\n this.sendDwellTime(true);\r\n }\r\n\r\n this.startTime = null;\r\n this.lastVideoTimeSent = 0;\r\n this.lastDwellTimeSent = 0;\r\n this.videoTrackingStopped = false;\r\n this.pausedTime = 0;\r\n this.pauseStartTime = null;\r\n this.cleanup();\r\n }\r\n\r\n /**\r\n * Obtiene el tiempo transcurrido en segundos (restando tiempo pausado).\r\n */\r\n getElapsedTime(): number {\r\n if (!this.startTime) return 0;\r\n\r\n const totalTime = Math.floor((Date.now() - this.startTime) / 1000);\r\n let currentPauseTime = this.pausedTime;\r\n\r\n if (this.pauseStartTime !== null) {\r\n currentPauseTime += Math.floor((Date.now() - this.pauseStartTime) / 1000);\r\n }\r\n\r\n return Math.max(0, totalTime - currentPauseTime);\r\n }\r\n\r\n /**\r\n * Actualiza manualmente el tiempo del video.\r\n * Llamar desde el VideoTracker u otros adaptadores.\r\n */\r\n updateVideoTime(videoTimeWatched: number, videoCompleted = false): void {\r\n const hasNewTime = videoTimeWatched > this.videoTimeWatched;\r\n const hasNewCompletion = videoCompleted && !this.videoCompleted;\r\n\r\n if (hasNewTime || hasNewCompletion) {\r\n this.videoTimeWatched = Math.max(this.videoTimeWatched, videoTimeWatched);\r\n this.videoCompleted = videoCompleted || this.videoCompleted;\r\n\r\n if (this.trackingDataId && this.trackingDataId !== 'pending' && this.startTime && hasNewCompletion) {\r\n this.sendDwellTime(false);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Actualiza el trackingDataId (útil cuando se obtiene después del registro).\r\n */\r\n updateTrackingId(trackingDataId: number | string): void {\r\n if (!trackingDataId || (typeof trackingDataId === 'string' && trackingDataId.trim() === '')) return;\r\n\r\n const oldTrackingId = this.trackingDataId;\r\n this.trackingDataId = trackingDataId;\r\n\r\n if (oldTrackingId === 'pending' && this.trackingDataId !== 'pending') {\r\n this.lastDwellTimeSent = 0;\r\n this.lastVideoTimeSent = 0;\r\n this.videoTrackingStopped = false;\r\n }\r\n\r\n if (this.startTime && oldTrackingId === 'pending') {\r\n this.sendDwellTime(false);\r\n }\r\n\r\n if (!this.intervalId && this.enabled && this.startTime) {\r\n this.intervalId = setInterval(() => {\r\n if (document.visibilityState === 'visible' && this.startTime) {\r\n this.sendDwellTime(false);\r\n }\r\n }, 30000);\r\n }\r\n }\r\n\r\n /**\r\n * Limpia todos los listeners y timers.\r\n */\r\n destroy(): void {\r\n this.stop();\r\n }\r\n\r\n // ====================================\r\n // PRIVATE\r\n // ====================================\r\n\r\n private checkLocalStorageForId(): void {\r\n if (typeof window === 'undefined') return;\r\n\r\n if (!this.trackingDataId || this.trackingDataId === 'pending') {\r\n const tid = localStorage.getItem('tracking_id') || localStorage.getItem('landing_tracking_id');\r\n if (tid) this.updateTrackingId(tid);\r\n }\r\n }\r\n\r\n private async sendDwellTime(isFinal: boolean = false): Promise<void> {\r\n if (!isTrackingAPIInitialized()) return;\r\n\r\n this.checkLocalStorageForId();\r\n\r\n if (!this.startTime || this.isSending) return;\r\n\r\n if (!this.trackingDataId || this.trackingDataId === 'pending') return;\r\n\r\n const trackingIdNum = typeof this.trackingDataId === 'string' ? parseInt(this.trackingDataId, 10) : this.trackingDataId;\r\n\r\n if (isNaN(trackingIdNum as number) || (trackingIdNum as number) <= 0) return;\r\n\r\n const elapsedTime = this.getElapsedTime();\r\n if (elapsedTime < 1 && !isFinal) return;\r\n\r\n this.isSending = true;\r\n const config = getAPIConfig();\r\n const token = config.getAuthToken?.() ?? null;\r\n\r\n try {\r\n const url = `${config.baseUrl}/tracking/${trackingIdNum}`;\r\n\r\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\r\n if (token) headers.Authorization = `Bearer ${token}`;\r\n\r\n const body: Record<string, unknown> = { dwellTime: elapsedTime };\r\n\r\n if (this.videoTimeWatched > 0 && !this.videoTrackingStopped) {\r\n body.videoTimeWatched = this.videoTimeWatched;\r\n body.videoCompleted = this.videoCompleted;\r\n }\r\n\r\n this.lastDwellTimeSent = elapsedTime;\r\n if (this.videoTimeWatched > 0 && !this.videoTrackingStopped) {\r\n this.lastVideoTimeSent = this.videoTimeWatched;\r\n }\r\n\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), 10000);\r\n\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers,\r\n body: JSON.stringify(body),\r\n keepalive: isFinal,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n throw new Error(`Error ${response.status}: ${response.statusText}`);\r\n }\r\n\r\n this.onSuccess?.();\r\n this.clearPendingUpdate();\r\n } catch (error: unknown) {\r\n const err = error as { name?: string; message?: string };\r\n const isNetworkError =\r\n err.name === 'AbortError' || err.name === 'TimeoutError' || (err.name === 'TypeError' && err.message?.includes('Failed to fetch'));\r\n\r\n if (token) this.savePendingUpdate(elapsedTime);\r\n\r\n if (this.onError && !isNetworkError) {\r\n this.onError(error instanceof Error ? error : new Error('Error desconocido'));\r\n }\r\n } finally {\r\n this.isSending = false;\r\n }\r\n }\r\n\r\n private handleBeforeUnload(_event: BeforeUnloadEvent): void {\r\n this.sendDwellTimeWithBeacon();\r\n }\r\n\r\n private handleVisibilityChange(): void {\r\n if (document.visibilityState === 'hidden') {\r\n if (this.pauseStartTime === null && this.startTime) {\r\n this.pauseStartTime = Date.now();\r\n this.sendDwellTime(false);\r\n }\r\n } else if (document.visibilityState === 'visible') {\r\n if (this.pauseStartTime !== null) {\r\n this.pausedTime += Math.floor((Date.now() - this.pauseStartTime) / 1000);\r\n this.pauseStartTime = null;\r\n } else if (!this.startTime) {\r\n this.startTime = Date.now();\r\n this.pausedTime = 0;\r\n this.pauseStartTime = null;\r\n }\r\n }\r\n }\r\n\r\n private sendDwellTimeWithBeacon(): void {\r\n if (!isTrackingAPIInitialized()) return;\r\n\r\n this.checkLocalStorageForId();\r\n if (!this.startTime || !this.trackingDataId || this.trackingDataId === 'pending') return;\r\n\r\n const trackingIdNum = typeof this.trackingDataId === 'string' ? parseInt(this.trackingDataId, 10) : this.trackingDataId;\r\n\r\n if (isNaN(trackingIdNum as number) || (trackingIdNum as number) <= 0) return;\r\n\r\n const config = getAPIConfig();\r\n const elapsedTime = this.getElapsedTime();\r\n const token = config.getAuthToken?.() ?? null;\r\n\r\n const body: Record<string, unknown> = { dwellTime: elapsedTime };\r\n if (this.videoTimeWatched > 0 && !this.videoTrackingStopped) {\r\n body.videoTimeWatched = this.videoTimeWatched;\r\n body.videoCompleted = this.videoCompleted;\r\n }\r\n\r\n if (token) this.savePendingUpdate(elapsedTime);\r\n\r\n const url = `${config.baseUrl}/tracking/${trackingIdNum}`;\r\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\r\n if (token) headers.Authorization = `Bearer ${token}`;\r\n\r\n fetch(url, {\r\n method: 'PATCH',\r\n headers,\r\n body: JSON.stringify(body),\r\n keepalive: true,\r\n })\r\n .then((response) => {\r\n if (response.ok) this.clearPendingUpdate();\r\n })\r\n .catch(() => {});\r\n }\r\n\r\n private savePendingUpdate(time: number): void {\r\n if (typeof window === 'undefined' || !this.trackingDataId) return;\r\n try {\r\n sessionStorage.setItem('dwellTime_pending', JSON.stringify({ trackingDataId: this.trackingDataId, time, timestamp: Date.now() }));\r\n } catch {\r\n // sessionStorage may be unavailable\r\n }\r\n }\r\n\r\n private async retryPendingUpdates(): Promise<void> {\r\n if (typeof window === 'undefined' || !isTrackingAPIInitialized()) return;\r\n\r\n try {\r\n const pendingData = sessionStorage.getItem('dwellTime_pending');\r\n if (!pendingData) return;\r\n\r\n const { trackingDataId, time } = JSON.parse(pendingData);\r\n if (trackingDataId !== this.trackingDataId) {\r\n this.clearPendingUpdate();\r\n return;\r\n }\r\n\r\n const config = getAPIConfig();\r\n const token = config.getAuthToken?.() ?? null;\r\n if (!token) {\r\n this.clearPendingUpdate();\r\n return;\r\n }\r\n\r\n const url = `${config.baseUrl}/tracking/${trackingDataId}`;\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\r\n body: JSON.stringify({ dwellTime: time }),\r\n });\r\n\r\n if (response.ok) this.clearPendingUpdate();\r\n } catch {\r\n // Retry silently\r\n }\r\n }\r\n\r\n private clearPendingUpdate(): void {\r\n if (typeof window === 'undefined') return;\r\n try {\r\n sessionStorage.removeItem('dwellTime_pending');\r\n } catch {\r\n // sessionStorage may be unavailable\r\n }\r\n }\r\n\r\n private cleanupListeners(): void {\r\n if (typeof window === 'undefined') return;\r\n window.removeEventListener('beforeunload', this.boundBeforeUnload);\r\n document.removeEventListener('visibilitychange', this.boundVisibilityChange);\r\n }\r\n\r\n private cleanup(): void {\r\n if (typeof window === 'undefined') return;\r\n this.cleanupListeners();\r\n\r\n if (this.intervalId) {\r\n clearInterval(this.intervalId);\r\n this.intervalId = null;\r\n }\r\n }\r\n}\r\n\r\n// Singleton para uso global\r\nexport const dwellTimeTracker = new DwellTimeTracker();\r\n\r\n/**\r\n * Inicia el tracking del tiempo de permanencia.\r\n */\r\nexport const startDwellTimeTracking = (config: DwellTimeConfig): void => {\r\n dwellTimeTracker.start(config);\r\n};\r\n\r\n/**\r\n * Detiene el tracking y envía el tiempo acumulado.\r\n */\r\nexport const stopDwellTimeTracking = (): void => {\r\n dwellTimeTracker.stop();\r\n};\r\n","/**\r\n * Tracking Queries — Consultas GET al backend de tracking.\r\n * Migrado de TrackingService.ts y LeadTrackingService.ts.\r\n * Framework-agnostic.\r\n */\r\n\r\nimport type { TrackingLead, LeadTrackingData } from '../core/types';\r\nimport { apiGet, apiPost } from './api-client';\r\n\r\n/**\r\n * Obtiene los datos de un tracking lead por su ID.\r\n *\r\n * @example\r\n * ```ts\r\n * const tracking = await getTrackingById(123);\r\n * console.log(tracking.videoTimeWatched, tracking.dwellTime);\r\n * ```\r\n */\r\nexport const getTrackingById = async (trackingId: number | string): Promise<TrackingLead> => {\r\n return apiGet<TrackingLead>(`/tracking/${trackingId}`);\r\n};\r\n\r\n/**\r\n * Obtiene un lead con sus datos de tracking asociados.\r\n * Procesa la respuesta para extraer videoVisto, tiempoReproducido, etc.\r\n *\r\n * @example\r\n * ```ts\r\n * const data = await getLeadWithTracking('456');\r\n * console.log(data.videoVisto, data.dwellTime);\r\n * ```\r\n */\r\nexport const getLeadWithTracking = async (leadId: string): Promise<LeadTrackingData> => {\r\n const defaultData: LeadTrackingData = {\r\n videoVisto: false,\r\n tiempoReproducido: '00:00',\r\n envioWhatsapp: false,\r\n videoTimeWatched: 0,\r\n dwellTime: 0,\r\n };\r\n\r\n try {\r\n const data = await apiGet<Record<string, unknown>>(`/leads/${leadId}/with-tracking`);\r\n\r\n // Extraer tracking info del array trackingData\r\n const trackingDataArray = data.trackingData as Array<Record<string, unknown>> | undefined;\r\n const trackingInfo = trackingDataArray && trackingDataArray.length > 0 ? trackingDataArray[0] : null;\r\n\r\n // Datos del nivel superior del lead\r\n const leadData = data as {\r\n accessUrl?: string;\r\n nameForm?: string;\r\n msgForm?: string;\r\n plataforma?: string;\r\n platform?: string;\r\n aliasName?: string;\r\n campaignName?: string;\r\n };\r\n\r\n if (!trackingInfo) {\r\n return {\r\n ...defaultData,\r\n accessUrl: leadData.accessUrl,\r\n nameForm: leadData.nameForm,\r\n msgForm: leadData.msgForm,\r\n platform: leadData.plataforma || leadData.platform,\r\n aliasName: leadData.aliasName || leadData.campaignName,\r\n };\r\n }\r\n\r\n const formatTime = (seconds: number): string => {\r\n const minutes = Math.floor(seconds / 60);\r\n const remainingSeconds = seconds % 60;\r\n return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;\r\n };\r\n\r\n const videoTimeWatched = (trackingInfo.videoTimeWatched as number) || 0;\r\n const dwellTime = (trackingInfo.dwellTime as number) || (trackingInfo.dwell_time as number) || 0;\r\n\r\n return {\r\n videoVisto: (trackingInfo.videoCompleted as boolean) || false,\r\n tiempoReproducido: videoTimeWatched ? formatTime(videoTimeWatched) : '00:00',\r\n envioWhatsapp: (trackingInfo.whatsappSent as boolean) || false,\r\n accessUrl: (trackingInfo.accessUrl as string) || leadData.accessUrl,\r\n nameForm: (trackingInfo.nameForm as string) || leadData.nameForm,\r\n msgForm: (trackingInfo.msgForm as string) || leadData.msgForm,\r\n platform: leadData.plataforma || leadData.platform || (trackingInfo.platform as string),\r\n aliasName: leadData.aliasName || leadData.campaignName || (trackingInfo.aliasName as string),\r\n trackingId: (trackingInfo as { id?: number }).id,\r\n videoTimeWatched,\r\n dwellTime,\r\n };\r\n } catch {\r\n return defaultData;\r\n }\r\n};\r\n\r\n/**\r\n * Genera un link de tracking para un funnel.\r\n *\r\n * @example\r\n * ```ts\r\n * const { link } = await generateTrackingLink(1, 'mi-dominio.com');\r\n * ```\r\n */\r\nexport const generateTrackingLink = async (funnelId: number, customDomain: string): Promise<{ link: string }> => {\r\n return apiPost<{ link: string }>('/tracking/generate-link', {\r\n funnel_id: funnelId,\r\n custom_domain: customDomain,\r\n });\r\n};\r\n"]}
1
+ {"version":3,"sources":["../src/core/analytics.ts","../src/core/gtm.ts","../src/trackers/video-tracker.ts","../src/trackers/events.ts","../src/trackers/wistia-adapter.ts","../src/trackers/voomly-adapter.ts","../src/trackers/html5-adapter.ts","../src/orchestrator/landing-tracker.ts","../src/persistence/api-client.ts","../src/persistence/lead-submission.ts","../src/persistence/dwell-time-tracker.ts","../src/persistence/tracking-queries.ts"],"names":["ReactGA","createStats"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Google Analytics 4 core module.\r\n * Initialization, event tracking, and visitor data capture.\r\n * Framework-agnostic (no Next.js, React, etc. dependency).\r\n */\r\n\r\nimport ReactGA from 'react-ga4';\r\nimport type { TrackingConfig, UTMParams, TrackingEventData } from './types';\r\n\r\n// ====================================\r\n// INTERNAL STATE\r\n// ====================================\r\n\r\nlet isInitialized = false;\r\nlet currentConfig: TrackingConfig = {};\r\nlet resolvedTrackingId: string = '';\r\nlet cachedUserId: string | null = null;\r\nlet cachedUserName: string | null = null;\r\n\r\n// ====================================\r\n// GA TRACKING ID RESOLUTION\r\n// ====================================\r\n\r\n/**\r\n * Returns the current GA Tracking ID.\r\n * Uses `resolveTrackingId` dynamically if configured, otherwise falls back to the static `trackingId`.\r\n */\r\nexport const getGATrackingId = (): string => {\r\n if (typeof window === 'undefined') return resolvedTrackingId || '';\r\n\r\n if (currentConfig.resolveTrackingId) {\r\n try {\r\n const path = window.location.pathname;\r\n return currentConfig.resolveTrackingId(path);\r\n } catch {\r\n // Fallback if resolver function throws\r\n }\r\n }\r\n\r\n return resolvedTrackingId;\r\n};\r\n\r\n// ====================================\r\n// INITIALIZATION\r\n// ====================================\r\n\r\n/**\r\n * Initializes Google Analytics with the provided configuration.\r\n *\r\n * @example\r\n * ```ts\r\n * // With a fixed ID\r\n * initGA({ trackingId: 'G-XXXXXXX' })\r\n *\r\n * // With dynamic resolution\r\n * initGA({\r\n * resolveTrackingId: (path) => {\r\n * if (path.startsWith('/kin')) return 'G-KIN-ID'\r\n * return localStorage.getItem('user_GA_id') || 'G-DEFAULT'\r\n * }\r\n * })\r\n * ```\r\n */\r\nexport const initGA = (config: TrackingConfig = {}): void => {\r\n if (typeof window === 'undefined') return;\r\n if (isInitialized) return;\r\n\r\n currentConfig = config;\r\n resolvedTrackingId = config.trackingId || '';\r\n\r\n const trackingId = getGATrackingId();\r\n if (!trackingId) {\r\n if (config.debug) {\r\n // eslint-disable-next-line no-console\r\n console.warn('[KorexTracking] No tracking ID provided. GA4 will not initialize.');\r\n }\r\n return;\r\n }\r\n\r\n try {\r\n ReactGA.initialize(trackingId);\r\n isInitialized = true;\r\n\r\n if (config.anonymizeIp) {\r\n window.gtag?.('config', trackingId, { anonymize_ip: true });\r\n }\r\n\r\n if (config.debug) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[KorexTracking] GA4 initialized with ID: ${trackingId}`);\r\n }\r\n } catch (error) {\r\n if (config.debug) {\r\n // eslint-disable-next-line no-console\r\n console.error('[KorexTracking] Failed to initialize GA4:', error);\r\n }\r\n }\r\n};\r\n\r\n/**\r\n * Reinitializes GA with a new Tracking ID.\r\n * Useful when the ID changes dynamically (e.g., after user login).\r\n */\r\nexport const reinitGA = (newTrackingId: string): void => {\r\n isInitialized = false;\r\n resolvedTrackingId = newTrackingId;\r\n initGA({ ...currentConfig, trackingId: newTrackingId });\r\n};\r\n\r\n/**\r\n * Returns whether GA has been initialized.\r\n */\r\nexport const isGAInitialized = (): boolean => isInitialized;\r\n\r\n// ====================================\r\n// VISITOR DATA CAPTURE\r\n// ====================================\r\n\r\n/**\r\n * Extracts UTM parameters from the current URL.\r\n */\r\nexport const captureUTMParams = (): UTMParams | null => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n const params = new URLSearchParams(window.location.search);\r\n const utmParams: UTMParams = {};\r\n let hasParams = false;\r\n\r\n const utmKeys: (keyof UTMParams)[] = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];\r\n\r\n for (const key of utmKeys) {\r\n const value = params.get(key);\r\n if (value) {\r\n utmParams[key] = value;\r\n hasParams = true;\r\n }\r\n }\r\n\r\n return hasParams ? utmParams : null;\r\n};\r\n\r\n/**\r\n * Captures the `user_id` from the URL query string (?user_id=xxx).\r\n * Caches it internally to include in all subsequent events.\r\n */\r\nexport const captureUserIdFromURL = (): string | null => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n const params = new URLSearchParams(window.location.search);\r\n const userId = params.get('user_id') || params.get('userId');\r\n\r\n if (userId) {\r\n cachedUserId = userId;\r\n try {\r\n localStorage.setItem('tracking_user_id', userId);\r\n } catch {\r\n // localStorage may be unavailable\r\n }\r\n }\r\n\r\n return userId;\r\n};\r\n\r\n/**\r\n * Resolves the user name from multiple sources.\r\n * Priority: URL > in-memory cache > localStorage > null\r\n */\r\nexport const getUserName = (): string | null => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n // 1. From URL\r\n const params = new URLSearchParams(window.location.search);\r\n const fromUrl = params.get('user_name') || params.get('userName');\r\n if (fromUrl) {\r\n cachedUserName = fromUrl;\r\n return fromUrl;\r\n }\r\n\r\n // 2. From in-memory cache\r\n if (cachedUserName) return cachedUserName;\r\n\r\n // 3. From localStorage\r\n try {\r\n const fromStorage = localStorage.getItem('tracking_user_name');\r\n if (fromStorage) {\r\n cachedUserName = fromStorage;\r\n return fromStorage;\r\n }\r\n\r\n const userInfo = localStorage.getItem('userInfo');\r\n if (userInfo) {\r\n const parsed = JSON.parse(userInfo);\r\n const name = parsed?.name || parsed?.userName || parsed?.fullName;\r\n if (name) {\r\n cachedUserName = name;\r\n return name;\r\n }\r\n }\r\n } catch {\r\n // localStorage may be unavailable\r\n }\r\n\r\n return null;\r\n};\r\n\r\n/**\r\n * Returns the cached user_id.\r\n */\r\nexport const getUserId = (): string | null => {\r\n if (cachedUserId) return cachedUserId;\r\n\r\n if (typeof window === 'undefined') return null;\r\n\r\n try {\r\n return localStorage.getItem('tracking_user_id');\r\n } catch {\r\n return null;\r\n }\r\n};\r\n\r\n/**\r\n * Manually sets the user_id (e.g., after login).\r\n */\r\nexport const setUserId = (userId: string): void => {\r\n cachedUserId = userId;\r\n try {\r\n localStorage.setItem('tracking_user_id', userId);\r\n } catch {\r\n // ignore\r\n }\r\n // Set as GA4 user property\r\n window.gtag?.('set', { user_id: userId });\r\n};\r\n\r\n/**\r\n * Manually sets the user_name.\r\n */\r\nexport const setUserName = (userName: string): void => {\r\n cachedUserName = userName;\r\n try {\r\n localStorage.setItem('tracking_user_name', userName);\r\n } catch {\r\n // ignore\r\n }\r\n};\r\n\r\n// ====================================\r\n// PAGE TRACKING\r\n// ====================================\r\n\r\n/**\r\n * Sends a pageview to GA4.\r\n * Automatically includes UTM params and user_id if available.\r\n */\r\nexport const trackPageView = (path: string): void => {\r\n if (typeof window === 'undefined') return;\r\n\r\n const userId = getUserId();\r\n const utmParams = captureUTMParams();\r\n\r\n // Append UTM params to the path if present\r\n let pageWithParams = path;\r\n if (utmParams) {\r\n const searchParams = new URLSearchParams();\r\n Object.entries(utmParams).forEach(([key, value]) => {\r\n if (value) searchParams.set(key, value);\r\n });\r\n const paramString = searchParams.toString();\r\n if (paramString) {\r\n pageWithParams = `${path}${path.includes('?') ? '&' : '?'}${paramString}`;\r\n }\r\n }\r\n\r\n // Send via ReactGA\r\n try {\r\n ReactGA.send({\r\n hitType: 'pageview',\r\n page: pageWithParams,\r\n ...(userId && { user_id: userId }),\r\n });\r\n } catch {\r\n // ReactGA may fail if GA4 is not loaded (ad-blockers, slow load, etc.)\r\n }\r\n\r\n // Send via native gtag\r\n try {\r\n window.gtag?.('event', 'page_view', {\r\n page_path: pageWithParams,\r\n page_title: document.title,\r\n ...(userId && { user_id: userId }),\r\n });\r\n } catch {\r\n // gtag may not be available\r\n }\r\n\r\n if (currentConfig.debug) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[KorexTracking] PageView: ${pageWithParams}`, { userId });\r\n }\r\n};\r\n\r\n// ====================================\r\n// EVENT TRACKING\r\n// ====================================\r\n\r\n/**\r\n * Sends a custom event to GA4.\r\n * Uses dual dispatch: `window.gtag()` + `ReactGA.event()`.\r\n * Always includes `user_id` and `user_name` as parameters.\r\n *\r\n * @example\r\n * ```ts\r\n * trackEvent('CTA', 'click', 'Hero Button', undefined, { section: 'hero' })\r\n * ```\r\n */\r\nexport const trackEvent = (category: string, action: string, label?: string, value?: number, additionalData?: TrackingEventData): void => {\r\n if (typeof window === 'undefined') return;\r\n\r\n const userId = getUserId();\r\n const userName = getUserName();\r\n\r\n const eventData: TrackingEventData = {\r\n event_category: category,\r\n event_label: label || '',\r\n ...(value !== undefined && { value }),\r\n ...(userId && { user_id: userId }),\r\n ...(userName && { user_name: userName }),\r\n timestamp: Date.now(),\r\n ...additionalData,\r\n };\r\n\r\n // 1. Send via native gtag (more reliable)\r\n try {\r\n window.gtag?.('event', action, eventData);\r\n } catch {\r\n // ignore\r\n }\r\n\r\n // 2. Send via ReactGA as fallback\r\n try {\r\n ReactGA.event({\r\n category,\r\n action,\r\n label: label || undefined,\r\n value: value || undefined,\r\n ...(userId && { user_id: userId }),\r\n });\r\n } catch {\r\n // ignore\r\n }\r\n\r\n if (currentConfig.debug) {\r\n // eslint-disable-next-line no-console\r\n console.log(`[KorexTracking] Event: ${category}/${action}`, eventData);\r\n }\r\n};\r\n\r\n// ====================================\r\n// UTILITIES\r\n// ====================================\r\n\r\n/**\r\n * Resets all internal state (useful for tests and reinitialization).\r\n */\r\nexport const resetAnalytics = (): void => {\r\n isInitialized = false;\r\n currentConfig = {};\r\n resolvedTrackingId = '';\r\n cachedUserId = null;\r\n cachedUserName = null;\r\n};\r\n","/**\r\n * Google Tag Manager — Vanilla injection (no Next.js dependency).\r\n * Provides pushToDataLayer and injectGTMScript.\r\n */\r\n\r\n/**\r\n * Injects the Google Tag Manager script into the document <head>.\r\n * Framework-agnostic equivalent of Next.js <Script> component.\r\n *\r\n * @param gtmId - GTM container ID (e.g., 'GTM-5GMQNFMN')\r\n *\r\n * @example\r\n * ```ts\r\n * injectGTMScript('GTM-5GMQNFMN')\r\n * ```\r\n */\r\nexport const injectGTMScript = (gtmId: string): void => {\r\n if (typeof window === 'undefined') return;\r\n if (!gtmId) return;\r\n\r\n // Prevent duplicate injection\r\n const existingScript = document.querySelector(`script[data-gtm-id=\"${gtmId}\"]`);\r\n if (existingScript) return;\r\n\r\n // Initialize dataLayer\r\n window.dataLayer = window.dataLayer || [];\r\n window.dataLayer.push({\r\n 'gtm.start': new Date().getTime(),\r\n event: 'gtm.js',\r\n });\r\n\r\n // Create and inject the script\r\n const script = document.createElement('script');\r\n script.async = true;\r\n script.src = `https://www.googletagmanager.com/gtm.js?id=${gtmId}`;\r\n script.setAttribute('data-gtm-id', gtmId);\r\n\r\n const firstScript = document.getElementsByTagName('script')[0];\r\n if (firstScript?.parentNode) {\r\n firstScript.parentNode.insertBefore(script, firstScript);\r\n } else {\r\n document.head.appendChild(script);\r\n }\r\n\r\n // Inject noscript fallback in body\r\n if (document.body) {\r\n const noscript = document.createElement('noscript');\r\n const iframe = document.createElement('iframe');\r\n iframe.src = `https://www.googletagmanager.com/ns.html?id=${gtmId}`;\r\n iframe.height = '0';\r\n iframe.width = '0';\r\n iframe.style.display = 'none';\r\n iframe.style.visibility = 'hidden';\r\n noscript.appendChild(iframe);\r\n document.body.insertBefore(noscript, document.body.firstChild);\r\n }\r\n};\r\n\r\n/**\r\n * Pushes an event to the GTM dataLayer.\r\n *\r\n * @param eventName - Name of the event\r\n * @param data - Additional event data\r\n *\r\n * @example\r\n * ```ts\r\n * pushToDataLayer('page_view', { page_path: '/kin' })\r\n * pushToDataLayer('cta_click', { button_text: 'Join Now', section: 'hero' })\r\n * ```\r\n */\r\nexport const pushToDataLayer = (eventName: string, data?: Record<string, unknown>): void => {\r\n if (typeof window === 'undefined') return;\r\n\r\n window.dataLayer = window.dataLayer || [];\r\n window.dataLayer.push({\r\n event: eventName,\r\n ...data,\r\n });\r\n};\r\n","/**\r\n * VideoTracker — Advanced video tracking for GA4.\r\n * Manages per-video playback state and emits events to Google Analytics.\r\n * Framework-agnostic (no React dependency).\r\n */\r\n\r\nimport { trackEvent } from '../core/analytics';\r\nimport type { VideoTrackingState } from '../core/types';\r\n\r\nexport class VideoTracker {\r\n private videos: Map<string, VideoTrackingState> = new Map();\r\n private watchTimeIntervals: Map<string, ReturnType<typeof setInterval>> = new Map();\r\n\r\n /**\r\n * Initializes tracking for a video.\r\n */\r\n initVideo(videoId: string): void {\r\n if (this.videos.has(videoId)) return;\r\n\r\n const state: VideoTrackingState = {\r\n videoId,\r\n startTime: Date.now(),\r\n totalWatchTime: 0,\r\n playCount: 0,\r\n pauseCount: 0,\r\n seekCount: 0,\r\n completionPercentage: 0,\r\n lastPlayTimestamp: 0,\r\n isPlaying: false,\r\n currentTime: 0,\r\n duration: 0,\r\n pauseTimes: [],\r\n seekEvents: [],\r\n progressMilestones: new Set(),\r\n playbackSpeed: 1,\r\n };\r\n\r\n this.videos.set(videoId, state);\r\n\r\n trackEvent('Video', 'init', videoId, undefined, {\r\n video_id: videoId,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n /**\r\n * Tracks a play event.\r\n */\r\n trackPlay(videoId: string, currentTime: number = 0): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.playCount++;\r\n state.isPlaying = true;\r\n state.lastPlayTimestamp = Date.now();\r\n state.currentTime = currentTime;\r\n\r\n // Start watch time counter\r\n this.startWatchTimeTracking(videoId);\r\n\r\n trackEvent('Video', 'play', videoId, undefined, {\r\n video_id: videoId,\r\n play_count: state.playCount,\r\n current_time: Math.round(currentTime),\r\n });\r\n }\r\n\r\n /**\r\n * Tracks a pause event.\r\n */\r\n trackPause(videoId: string, currentTime: number, duration?: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.pauseCount++;\r\n state.isPlaying = false;\r\n state.currentTime = currentTime;\r\n state.pauseTimes.push(currentTime);\r\n\r\n if (duration) {\r\n state.duration = duration;\r\n state.completionPercentage = Math.round((currentTime / duration) * 100);\r\n }\r\n\r\n // Stop watch time counter\r\n this.stopWatchTimeTracking(videoId);\r\n\r\n trackEvent('Video', 'pause', videoId, undefined, {\r\n video_id: videoId,\r\n pause_count: state.pauseCount,\r\n current_time: Math.round(currentTime),\r\n completion_percentage: state.completionPercentage,\r\n total_watch_time: Math.round(state.totalWatchTime),\r\n });\r\n }\r\n\r\n /**\r\n * Tracks a seek event (timeline jump).\r\n */\r\n trackSeek(videoId: string, fromTime: number, toTime: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.seekCount++;\r\n state.seekEvents.push({ from: fromTime, to: toTime });\r\n\r\n trackEvent('Video', 'seek', videoId, undefined, {\r\n video_id: videoId,\r\n seek_count: state.seekCount,\r\n from_time: Math.round(fromTime),\r\n to_time: Math.round(toTime),\r\n skip_duration: Math.round(toTime - fromTime),\r\n });\r\n }\r\n\r\n /**\r\n * Tracks progress milestones (25%, 50%, 75%).\r\n */\r\n trackProgress(videoId: string, percentage: number, currentTime: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n const milestone = Math.floor(percentage / 25) * 25;\r\n\r\n // Emit each milestone only once\r\n if (milestone > 0 && milestone < 100 && !state.progressMilestones.has(milestone)) {\r\n state.progressMilestones.add(milestone);\r\n\r\n trackEvent('Video', 'progress', videoId, milestone, {\r\n video_id: videoId,\r\n progress_percentage: milestone,\r\n current_time: Math.round(currentTime),\r\n total_watch_time: Math.round(state.totalWatchTime),\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Tracks video completion (>=95%).\r\n */\r\n trackComplete(videoId: string, totalDuration: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.completionPercentage = 100;\r\n state.duration = totalDuration;\r\n this.stopWatchTimeTracking(videoId);\r\n\r\n trackEvent('Video', 'complete', videoId, undefined, {\r\n video_id: videoId,\r\n total_duration: Math.round(totalDuration),\r\n total_watch_time: Math.round(state.totalWatchTime),\r\n play_count: state.playCount,\r\n pause_count: state.pauseCount,\r\n seek_count: state.seekCount,\r\n });\r\n }\r\n\r\n /**\r\n * Tracks video end (native ended event).\r\n */\r\n trackEnd(videoId: string): void {\r\n const state = this.getOrCreateState(videoId);\r\n\r\n state.isPlaying = false;\r\n this.stopWatchTimeTracking(videoId);\r\n\r\n trackEvent('Video', 'end', videoId, undefined, {\r\n video_id: videoId,\r\n total_watch_time: Math.round(state.totalWatchTime),\r\n play_count: state.playCount,\r\n });\r\n }\r\n\r\n /**\r\n * Tracks playback speed change.\r\n */\r\n trackSpeedChange(videoId: string, speed: number): void {\r\n const state = this.getOrCreateState(videoId);\r\n state.playbackSpeed = speed;\r\n\r\n trackEvent('Video', 'speed_change', videoId, undefined, {\r\n video_id: videoId,\r\n playback_speed: speed,\r\n });\r\n }\r\n\r\n /**\r\n * Tracks fullscreen toggle.\r\n */\r\n trackFullscreen(videoId: string, isFullscreen: boolean): void {\r\n trackEvent('Video', isFullscreen ? 'fullscreen_enter' : 'fullscreen_exit', videoId, undefined, {\r\n video_id: videoId,\r\n is_fullscreen: isFullscreen,\r\n });\r\n }\r\n\r\n /**\r\n * Tracks no interaction (user is on the page but not interacting with the video).\r\n */\r\n trackNoInteraction(videoId: string, timeOnPage: number): void {\r\n trackEvent('Video', 'no_interaction', videoId, undefined, {\r\n video_id: videoId,\r\n time_on_page: Math.round(timeOnPage),\r\n });\r\n }\r\n\r\n /**\r\n * Returns the current state of a video.\r\n */\r\n getState(videoId: string): VideoTrackingState | undefined {\r\n return this.videos.get(videoId);\r\n }\r\n\r\n /**\r\n * Cleans up tracking for a specific video.\r\n */\r\n cleanup(videoId: string): void {\r\n this.stopWatchTimeTracking(videoId);\r\n this.videos.delete(videoId);\r\n }\r\n\r\n /**\r\n * Cleans up all video tracking.\r\n */\r\n cleanupAll(): void {\r\n for (const videoId of this.videos.keys()) {\r\n this.stopWatchTimeTracking(videoId);\r\n }\r\n this.videos.clear();\r\n }\r\n\r\n // --- Private methods ---\r\n\r\n private getOrCreateState(videoId: string): VideoTrackingState {\r\n if (!this.videos.has(videoId)) {\r\n this.initVideo(videoId);\r\n }\r\n return this.videos.get(videoId)!;\r\n }\r\n\r\n private startWatchTimeTracking(videoId: string): void {\r\n this.stopWatchTimeTracking(videoId);\r\n\r\n const interval = setInterval(() => {\r\n const state = this.videos.get(videoId);\r\n if (state?.isPlaying) {\r\n state.totalWatchTime += 1;\r\n }\r\n }, 1000);\r\n\r\n this.watchTimeIntervals.set(videoId, interval);\r\n }\r\n\r\n private stopWatchTimeTracking(videoId: string): void {\r\n const interval = this.watchTimeIntervals.get(videoId);\r\n if (interval) {\r\n clearInterval(interval);\r\n this.watchTimeIntervals.delete(videoId);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Singleton VideoTracker instance.\r\n * Use when a single global instance is needed.\r\n */\r\nexport const videoTracker = new VideoTracker();\r\n","/**\r\n * Generic GA4 event tracking functions.\r\n * Each function wraps `trackEvent()` with a predefined category and action.\r\n */\r\n\r\nimport { trackEvent } from '../core/analytics';\r\nimport type { TrackingEventData } from '../core/types';\r\n\r\n// ====================================\r\n// CTA / BUTTONS\r\n// ====================================\r\n\r\nexport const trackCTAClick = (buttonName: string, section: string, additionalData?: TrackingEventData): void => {\r\n trackEvent('CTA', 'click', buttonName, undefined, {\r\n button_name: buttonName,\r\n section,\r\n ...additionalData,\r\n });\r\n};\r\n\r\n// ====================================\r\n// FORMS\r\n// ====================================\r\n\r\nexport const trackFormStart = (formName: string): void => {\r\n trackEvent('Form', 'started', formName, undefined, {\r\n form_name: formName,\r\n timestamp: Date.now(),\r\n });\r\n};\r\n\r\nexport const trackFormFieldComplete = (formName: string, fieldName: string): void => {\r\n trackEvent('Form', 'field_completed', formName, undefined, {\r\n form_name: formName,\r\n field_name: fieldName,\r\n });\r\n};\r\n\r\nexport const trackFormSubmit = (formName: string, success: boolean, additionalData?: TrackingEventData): void => {\r\n trackEvent('Form', success ? 'submit_success' : 'submit_error', formName, undefined, {\r\n form_name: formName,\r\n success,\r\n ...additionalData,\r\n });\r\n};\r\n\r\nexport const trackFormValidationError = (formName: string, fieldName: string, errorMessage: string): void => {\r\n trackEvent('Error', 'validation', formName, undefined, {\r\n form_name: formName,\r\n field_name: fieldName,\r\n error_message: errorMessage,\r\n });\r\n};\r\n\r\n// ====================================\r\n// CONVERSIONS\r\n// ====================================\r\n\r\nexport const trackConversion = (conversionType: string, value?: number, additionalData?: TrackingEventData): void => {\r\n trackEvent('Conversion', conversionType, undefined, value, {\r\n conversion_type: conversionType,\r\n ...additionalData,\r\n });\r\n};\r\n\r\n// ====================================\r\n// SOCIAL MEDIA\r\n// ====================================\r\n\r\nexport const trackSocialClick = (platform: string, action: string, additionalData?: TrackingEventData): void => {\r\n trackEvent('Social', 'click', platform, undefined, {\r\n social_platform: platform,\r\n social_action: action,\r\n ...additionalData,\r\n });\r\n};\r\n\r\n// ====================================\r\n// FAQ\r\n// ====================================\r\n\r\nexport const trackFAQExpand = (question: string, index: number): void => {\r\n trackEvent('FAQ', 'expand', question, index, {\r\n question,\r\n question_index: index,\r\n });\r\n};\r\n\r\n// ====================================\r\n// ENGAGEMENT\r\n// ====================================\r\n\r\nexport const trackImageClick = (imageName: string, section: string): void => {\r\n trackEvent('Engagement', 'image_click', imageName, undefined, {\r\n image_name: imageName,\r\n section,\r\n });\r\n};\r\n\r\nexport const trackTimeInSection = (sectionName: string, seconds: number): void => {\r\n if (seconds < 3) return; // Ignore sections viewed for less than 3 seconds\r\n\r\n trackEvent('Engagement', 'time_in_section', sectionName, Math.round(seconds), {\r\n section_name: sectionName,\r\n time_seconds: Math.round(seconds),\r\n });\r\n};\r\n\r\n// ====================================\r\n// NAVIGATION\r\n// ====================================\r\n\r\nexport const trackSectionClick = (section: string): void => {\r\n trackEvent('Navigation', 'section_click', section);\r\n};\r\n\r\nexport const trackScrollTo = (section: string): void => {\r\n trackEvent('Navigation', 'scroll_to', section);\r\n};\r\n\r\n// ====================================\r\n// PRICING\r\n// ====================================\r\n\r\nexport const trackPricingCardClick = (productName: string, price: number | string, additionalData?: TrackingEventData): void => {\r\n trackEvent('Pricing', 'card_click', productName, undefined, {\r\n product_name: productName,\r\n price: String(price),\r\n ...additionalData,\r\n });\r\n};\r\n\r\n// ====================================\r\n// CONTACT\r\n// ====================================\r\n\r\nexport const trackContactClick = (method: string): void => {\r\n trackEvent('Contact', 'click', method, undefined, {\r\n contact_method: method,\r\n });\r\n};\r\n\r\n// ====================================\r\n// SHARING\r\n// ====================================\r\n\r\nexport const trackShare = (platform: string, content: string): void => {\r\n trackEvent('Share', 'click', platform, undefined, {\r\n share_platform: platform,\r\n share_content: content,\r\n });\r\n};\r\n\r\n// ====================================\r\n// DOWNLOADS\r\n// ====================================\r\n\r\nexport const trackDownload = (fileName: string, fileType: string): void => {\r\n trackEvent('Download', 'click', fileName, undefined, {\r\n file_name: fileName,\r\n file_type: fileType,\r\n });\r\n};\r\n\r\n// ====================================\r\n// FUNNEL — STAGE 5: QUIZ\r\n// ====================================\r\n\r\n/**\r\n * Tracks quiz start (funnel stage 5).\r\n * The quiz serves as an implicit lead scoring mechanism.\r\n */\r\nexport const trackQuizStart = (quizName: string): void => {\r\n trackEvent('Quiz', 'started', quizName, undefined, {\r\n quiz_name: quizName,\r\n });\r\n};\r\n\r\n/**\r\n * Tracks an individual quiz answer.\r\n */\r\nexport const trackQuizAnswer = (\r\n quizName: string,\r\n questionIndex: number,\r\n answer: string,\r\n): void => {\r\n trackEvent('Quiz', 'answer', quizName, questionIndex, {\r\n quiz_name: quizName,\r\n question_index: questionIndex,\r\n answer,\r\n });\r\n};\r\n\r\n/**\r\n * Tracks quiz completion (funnel stage 5).\r\n */\r\nexport const trackQuizComplete = (\r\n quizName: string,\r\n totalQuestions?: number,\r\n score?: number,\r\n): void => {\r\n trackEvent('Quiz', 'completed', quizName, totalQuestions, {\r\n quiz_name: quizName,\r\n ...(totalQuestions !== undefined && { total_questions: totalQuestions }),\r\n ...(score !== undefined && { score }),\r\n });\r\n};\r\n\r\n// ====================================\r\n// FUNNEL — STAGE 6: THANK YOU PAGE\r\n// ====================================\r\n\r\n/**\r\n * Tracks a Thank You Page visit (funnel stage 6).\r\n * Confirms the lead completed the funnel flow.\r\n */\r\nexport const trackThankYouPageVisit = (source?: string): void => {\r\n trackEvent('Funnel', 'thank_you_page_visit', source);\r\n};\r\n\r\n// ====================================\r\n// FUNNEL — STAGE 7: WHATSAPP CLICK\r\n// ====================================\r\n\r\n/**\r\n * Tracks a WhatsApp link click (funnel stage 7).\r\n * Complements markWhatsAppSent() which marks post-hoc.\r\n */\r\nexport const trackWhatsAppClick = (phoneNumber?: string, section?: string): void => {\r\n trackEvent('WhatsApp', 'click', section, undefined, {\r\n ...(phoneNumber && { phone_number: phoneNumber }),\r\n ...(section && { section }),\r\n });\r\n};\r\n","/**\r\n * Wistia video adapter.\r\n * Auto-detects the Wistia SDK and binds to its events.\r\n * Framework-agnostic.\r\n */\r\n\r\nimport type { VideoStats, VideoUpdateCallback, VideoTrackerHandle } from '../core/types';\r\n\r\nconst createStats = (timeWatched: number, completed: boolean): VideoStats => ({\r\n timeWatched: Math.max(0, Math.round(timeWatched)),\r\n completed,\r\n lastUpdate: Date.now(),\r\n});\r\n\r\n/**\r\n * Starts tracking a Wistia video by its Media ID.\r\n * Detects whether to use the native Wistia player or an HTML5 <video> fallback.\r\n * Returns a handle with getStats(), onUpdate(), and stop().\r\n *\r\n * @example\r\n * ```ts\r\n * const tracker = await trackWistiaByMediaId('abc123')\r\n * tracker.onUpdate((stats) => {\r\n * console.log(stats.timeWatched, stats.completed)\r\n * })\r\n * // On unmount:\r\n * tracker.stop()\r\n * ```\r\n */\r\nexport const trackWistiaByMediaId = async (mediaId: string): Promise<VideoTrackerHandle | null> => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n let stats: VideoStats = createStats(0, false);\r\n let updateCallbacks: VideoUpdateCallback[] = [];\r\n let stopped = false;\r\n\r\n const callUpdate = (): void => {\r\n updateCallbacks.forEach((cb) => cb(stats));\r\n };\r\n\r\n // --- Strategy 1: Native Wistia SDK via window._wq ---\r\n const bindWistiaSDK = (): boolean => {\r\n if (!window._wq) return false;\r\n\r\n window._wq.push({\r\n id: mediaId,\r\n onReady: (rawVideo: unknown) => {\r\n if (stopped) return;\r\n\r\n const video = rawVideo as {\r\n time: () => number;\r\n duration: () => number;\r\n percentWatched: () => number;\r\n bind: (event: string, cb: (...args: unknown[]) => void) => void;\r\n unbind: (event: string) => void;\r\n };\r\n\r\n const updateFromWistia = (): void => {\r\n const t = video.time();\r\n const d = video.duration();\r\n const pct = d > 0 ? Math.round((t / d) * 100) : 0;\r\n const isCompleted = stats.completed || pct >= 95;\r\n const newTime = Math.max(stats.timeWatched, Math.round(t));\r\n\r\n if (newTime !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTime, isCompleted);\r\n callUpdate();\r\n }\r\n };\r\n\r\n video.bind('play', updateFromWistia);\r\n video.bind('pause', updateFromWistia);\r\n video.bind('secondchange', updateFromWistia);\r\n video.bind('end', () => {\r\n stats = createStats(Math.round(video.duration()), true);\r\n callUpdate();\r\n });\r\n },\r\n });\r\n\r\n return true;\r\n };\r\n\r\n // --- Strategy 2: HTML5 <video> fallback ---\r\n const bindHTML5Fallback = (): void => {\r\n const selector = `[data-wistia-id=\"${mediaId}\"], .wistia_embed[data-media-id=\"${mediaId}\"]`;\r\n const container = document.querySelector(selector);\r\n if (!container) return;\r\n\r\n const video = container.querySelector('video');\r\n if (!video) return;\r\n\r\n const onTimeUpdate = (): void => {\r\n if (stopped) return;\r\n const ct = Math.round(video.currentTime || 0);\r\n const dur = video.duration || 0;\r\n const pct = dur > 0 ? Math.round((ct / dur) * 100) : 0;\r\n const isCompleted = stats.completed || pct >= 95 || video.ended;\r\n const newTime = Math.max(stats.timeWatched, ct);\r\n\r\n if (newTime !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTime, isCompleted);\r\n callUpdate();\r\n }\r\n };\r\n\r\n const onEnded = (): void => {\r\n if (stopped) return;\r\n stats = createStats(Math.max(stats.timeWatched, Math.round(video.duration || 0)), true);\r\n callUpdate();\r\n };\r\n\r\n video.addEventListener('timeupdate', onTimeUpdate);\r\n video.addEventListener('ended', onEnded);\r\n };\r\n\r\n // Try both strategies\r\n const wistiaReady = bindWistiaSDK();\r\n if (!wistiaReady) {\r\n // Wait briefly then try HTML5 fallback\r\n await new Promise<void>((resolve) => setTimeout(resolve, 2000));\r\n bindHTML5Fallback();\r\n }\r\n\r\n return {\r\n getStats: () => stats,\r\n onUpdate: (cb: VideoUpdateCallback) => {\r\n updateCallbacks.push(cb);\r\n return () => {\r\n updateCallbacks = updateCallbacks.filter((x) => x !== cb);\r\n };\r\n },\r\n stop: () => {\r\n stopped = true;\r\n updateCallbacks = [];\r\n },\r\n };\r\n};\r\n","/**\r\n * Voomly video adapter.\r\n * Uses 3 complementary strategies to track embedded Voomly videos.\r\n * Framework-agnostic.\r\n */\r\n\r\nimport type { VideoStats, VideoUpdateCallback, VideoTrackerHandle } from '../core/types';\r\n\r\nconst createStats = (timeWatched: number, completed: boolean): VideoStats => ({\r\n timeWatched: Math.max(0, Math.round(timeWatched)),\r\n completed,\r\n lastUpdate: Date.now(),\r\n});\r\n\r\n/**\r\n * Recursively finds <video> elements within a root (document, shadow DOM, iframes).\r\n */\r\nconst findAllVideosInElement = (root: Element | Document | ShadowRoot): HTMLVideoElement[] => {\r\n const results: HTMLVideoElement[] = [];\r\n\r\n // Direct video elements\r\n const videos = Array.from(root.querySelectorAll('video')) as HTMLVideoElement[];\r\n results.push(...videos);\r\n\r\n // Search in Shadow DOM\r\n const allElements = root.querySelectorAll('*');\r\n for (const el of Array.from(allElements)) {\r\n if (el.shadowRoot) {\r\n results.push(...findAllVideosInElement(el.shadowRoot));\r\n }\r\n }\r\n\r\n // Search in iframes (same-origin only)\r\n const iframes = root.querySelectorAll('iframe');\r\n for (const iframe of Array.from(iframes)) {\r\n try {\r\n const doc = iframe.contentDocument || iframe.contentWindow?.document;\r\n if (doc) {\r\n results.push(...findAllVideosInElement(doc));\r\n }\r\n } catch {\r\n // Ignore CORS-blocked iframes\r\n }\r\n }\r\n\r\n return results;\r\n};\r\n\r\n/**\r\n * Starts tracking a Voomly video by its Embed ID.\r\n * Uses 3 complementary strategies:\r\n * 1. Periodic DOM scan (every 2s) searching for <video> inside the embed\r\n * 2. Fallback polling (every 1s) reading .currentTime\r\n * 3. Global window events (voomly:video:*)\r\n *\r\n * @example\r\n * ```ts\r\n * const tracker = await trackVoomlyByEmbedId('my-voomly-id')\r\n * tracker.onUpdate((stats) => console.log(stats))\r\n * // IMPORTANT: call stop() on unmount to prevent memory leaks\r\n * tracker.stop()\r\n * ```\r\n */\r\nexport const trackVoomlyByEmbedId = async (embedId: string): Promise<VideoTrackerHandle | null> => {\r\n if (typeof window === 'undefined') return null;\r\n\r\n let stats: VideoStats = createStats(0, false);\r\n let updateCallbacks: VideoUpdateCallback[] = [];\r\n const trackedVideos = new Set<HTMLVideoElement>();\r\n\r\n const callUpdate = (): void => {\r\n updateCallbacks.forEach((cb) => cb(stats));\r\n };\r\n\r\n const updateStatsFromVideo = (video: HTMLVideoElement): void => {\r\n const ct = Math.round(video.currentTime || 0);\r\n const dur = video.duration || 0;\r\n const pct = dur ? Math.round((ct / dur) * 100) : 0;\r\n\r\n const isCompleted = stats.completed || pct >= 90 || video.ended;\r\n const newTimeWatched = Math.max(stats.timeWatched, ct);\r\n\r\n if (newTimeWatched !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTimeWatched, isCompleted);\r\n callUpdate();\r\n }\r\n };\r\n\r\n // --- HTML5 <video> event handlers ---\r\n const onPlay = (e: Event): void => updateStatsFromVideo(e.target as HTMLVideoElement);\r\n const onPause = (e: Event): void => updateStatsFromVideo(e.target as HTMLVideoElement);\r\n const onTime = (e: Event): void => updateStatsFromVideo(e.target as HTMLVideoElement);\r\n const onEnd = (e: Event): void => updateStatsFromVideo(e.target as HTMLVideoElement);\r\n\r\n const bindVideo = (video: HTMLVideoElement): void => {\r\n if (trackedVideos.has(video)) return;\r\n trackedVideos.add(video);\r\n\r\n video.addEventListener('play', onPlay);\r\n video.addEventListener('pause', onPause);\r\n video.addEventListener('timeupdate', onTime);\r\n video.addEventListener('ended', onEnd);\r\n };\r\n\r\n // --- Strategy 1: Periodic DOM scan ---\r\n const scanForVideos = (): void => {\r\n const selector = `.voomly-embed[data-id=\"${embedId}\"]`;\r\n const container = document.querySelector(selector);\r\n\r\n let foundVideos: HTMLVideoElement[] = [];\r\n\r\n if (container) {\r\n foundVideos = findAllVideosInElement(container);\r\n }\r\n\r\n // Fallback: search entire document if none found in container\r\n if (foundVideos.length === 0) {\r\n foundVideos = findAllVideosInElement(document);\r\n }\r\n\r\n foundVideos.forEach((v) => bindVideo(v));\r\n };\r\n\r\n scanForVideos();\r\n const scanInterval = setInterval(scanForVideos, 2000);\r\n\r\n // --- Strategy 2: Fallback polling ---\r\n const pollingInterval = setInterval(() => {\r\n trackedVideos.forEach((video) => {\r\n const ct = Math.round(video.currentTime || 0);\r\n if (!video.paused || ct > 0) {\r\n updateStatsFromVideo(video);\r\n }\r\n });\r\n }, 1000);\r\n\r\n // --- Strategy 3: Voomly API global events ---\r\n const handleVoomlyWindowEvents = (e: Event): void => {\r\n try {\r\n const customEvent = e as CustomEvent;\r\n const payload = customEvent.detail || (customEvent as unknown as { payload: unknown }).payload;\r\n const playerInfo = (payload as Record<string, unknown>)?.playerInfo || payload;\r\n const id = (playerInfo as Record<string, unknown>)?.id || (playerInfo as Record<string, unknown>)?.videoId;\r\n\r\n // Ignore events for other videos\r\n if (id && id !== embedId) return;\r\n\r\n const currentTime =\r\n ((payload as Record<string, unknown>)?.currentTime as number) || ((payload as Record<string, unknown>)?.time as number) || 0;\r\n const duration =\r\n ((payload as Record<string, unknown>)?.duration as number) || ((payload as Record<string, unknown>)?.totalTime as number) || 0;\r\n let completed = false;\r\n\r\n if (e.type === 'voomly:video:ended' || e.type === 'voomly:video:complete') {\r\n completed = true;\r\n }\r\n\r\n if (currentTime > 0 || completed) {\r\n const pct = duration ? Math.round((currentTime / duration) * 100) : 0;\r\n const isCompleted = stats.completed || completed || pct >= 90;\r\n const newTimeWatched = Math.max(stats.timeWatched, Math.round(currentTime));\r\n\r\n if (newTimeWatched !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTimeWatched, isCompleted);\r\n callUpdate();\r\n }\r\n }\r\n } catch {\r\n // Ignore parsing errors\r\n }\r\n };\r\n\r\n const windowEvents = ['voomly:video:play', 'voomly:video:timeupdate', 'voomly:video:ended', 'voomly:video:progress'];\r\n windowEvents.forEach((evt) => window.addEventListener(evt, handleVoomlyWindowEvents));\r\n\r\n // --- Stop / cleanup ---\r\n const stop = (): void => {\r\n clearInterval(scanInterval);\r\n clearInterval(pollingInterval);\r\n trackedVideos.forEach((video) => {\r\n video.removeEventListener('play', onPlay);\r\n video.removeEventListener('pause', onPause);\r\n video.removeEventListener('timeupdate', onTime);\r\n video.removeEventListener('ended', onEnd);\r\n });\r\n windowEvents.forEach((evt) => window.removeEventListener(evt, handleVoomlyWindowEvents));\r\n updateCallbacks = [];\r\n };\r\n\r\n return {\r\n getStats: () => stats,\r\n onUpdate: (cb: VideoUpdateCallback) => {\r\n updateCallbacks.push(cb);\r\n return () => {\r\n updateCallbacks = updateCallbacks.filter((x) => x !== cb);\r\n };\r\n },\r\n stop,\r\n };\r\n};\r\n","/**\r\n * Native HTML5 video adapter.\r\n * Pure tracking for <video> elements with no React dependency.\r\n */\r\n\r\nimport type { VideoStats, VideoUpdateCallback, VideoTrackerHandle } from '../core/types';\r\n\r\nconst createStats = (timeWatched: number, completed: boolean): VideoStats => ({\r\n timeWatched: Math.max(0, Math.round(timeWatched)),\r\n completed,\r\n lastUpdate: Date.now(),\r\n});\r\n\r\n/**\r\n * Starts tracking a native HTML5 <video> element.\r\n * Listens to standard browser Video API events.\r\n *\r\n * @example\r\n * ```ts\r\n * const video = document.querySelector('video')\r\n * const tracker = trackHTML5Video('hero-video', video)\r\n * tracker.onUpdate((stats) => console.log(stats))\r\n * // On unmount:\r\n * tracker.stop()\r\n * ```\r\n */\r\nexport const trackHTML5Video = (videoId: string, videoElement: HTMLVideoElement): VideoTrackerHandle => {\r\n let stats: VideoStats = createStats(0, false);\r\n let updateCallbacks: VideoUpdateCallback[] = [];\r\n const trackedMilestones = new Set<number>();\r\n\r\n const callUpdate = (): void => {\r\n updateCallbacks.forEach((cb) => cb(stats));\r\n };\r\n\r\n const onTimeUpdate = (): void => {\r\n const ct = Math.round(videoElement.currentTime || 0);\r\n const dur = videoElement.duration || 0;\r\n const pct = dur > 0 ? Math.round((ct / dur) * 100) : 0;\r\n\r\n // Update stats\r\n const newTime = Math.max(stats.timeWatched, ct);\r\n const isCompleted = stats.completed || pct >= 95 || videoElement.ended;\r\n\r\n if (newTime !== stats.timeWatched || isCompleted !== stats.completed) {\r\n stats = createStats(newTime, isCompleted);\r\n callUpdate();\r\n }\r\n\r\n // Milestones (25, 50, 75)\r\n for (const milestone of [25, 50, 75]) {\r\n if (pct >= milestone && !trackedMilestones.has(milestone)) {\r\n trackedMilestones.add(milestone);\r\n }\r\n }\r\n };\r\n\r\n const onEnded = (): void => {\r\n const dur = Math.round(videoElement.duration || 0);\r\n stats = createStats(Math.max(stats.timeWatched, dur), true);\r\n callUpdate();\r\n };\r\n\r\n const onPlay = (): void => {\r\n onTimeUpdate();\r\n };\r\n\r\n const onPause = (): void => {\r\n onTimeUpdate();\r\n };\r\n\r\n // Bind events\r\n videoElement.addEventListener('timeupdate', onTimeUpdate);\r\n videoElement.addEventListener('ended', onEnded);\r\n videoElement.addEventListener('play', onPlay);\r\n videoElement.addEventListener('pause', onPause);\r\n\r\n return {\r\n getStats: () => stats,\r\n onUpdate: (cb: VideoUpdateCallback) => {\r\n updateCallbacks.push(cb);\r\n return () => {\r\n updateCallbacks = updateCallbacks.filter((x) => x !== cb);\r\n };\r\n },\r\n stop: () => {\r\n videoElement.removeEventListener('timeupdate', onTimeUpdate);\r\n videoElement.removeEventListener('ended', onEnded);\r\n videoElement.removeEventListener('play', onPlay);\r\n videoElement.removeEventListener('pause', onPause);\r\n updateCallbacks = [];\r\n },\r\n };\r\n};\r\n","/**\r\n * LandingTracker — Full session orchestrator.\r\n * Initializes and manages scroll tracking, click heatmap, section dwell time,\r\n * form auto-tracking, and session start/end.\r\n * Framework-agnostic.\r\n */\r\n\r\nimport { trackEvent, captureUTMParams, captureUserIdFromURL, getUserName, trackPageView } from '../core/analytics';\r\nimport { pushToDataLayer, injectGTMScript } from '../core/gtm';\r\nimport { trackCTAClick, trackFormStart, trackFormSubmit, trackTimeInSection } from '../trackers/events';\r\nimport type { LandingTrackerConfig, ClickData } from '../core/types';\r\n\r\nexport class LandingTracker {\r\n private config: LandingTrackerConfig | null = null;\r\n private isInitialized = false;\r\n private sessionStartTime: number = 0;\r\n private scrollMilestonesReached = new Set<number>();\r\n private clicks: ClickData[] = [];\r\n private sectionTimers: Map<string, number> = new Map();\r\n private observers: IntersectionObserver[] = [];\r\n private listeners: Array<{ target: EventTarget; event: string; handler: EventListener }> = [];\r\n\r\n /**\r\n * Initializes landing page tracking with the given configuration.\r\n */\r\n init(config: LandingTrackerConfig): void {\r\n if (typeof window === 'undefined') return;\r\n if (this.isInitialized) return;\r\n\r\n this.config = {\r\n enableScrollTracking: true,\r\n enableCTATracking: true,\r\n enableTimeTracking: true,\r\n enableSectionTracking: true,\r\n enableFormTracking: true,\r\n enableHeatmap: false,\r\n eventSuffix: '',\r\n ...config,\r\n };\r\n\r\n this.isInitialized = true;\r\n this.sessionStartTime = Date.now();\r\n\r\n // Capture initial visitor data\r\n this.captureInitialData();\r\n\r\n // Track page load\r\n trackPageView(this.config.pagePath);\r\n\r\n // Inject GTM if configured\r\n if (this.config.gtmId) {\r\n injectGTMScript(this.config.gtmId);\r\n pushToDataLayer(this.getEventName('page_load'), {\r\n page_path: this.config.pagePath,\r\n page_title: this.config.pageName,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n // Initialize tracking modules\r\n if (this.config.enableScrollTracking) this.initScrollTracking();\r\n if (this.config.enableCTATracking) this.initCTATracking();\r\n if (this.config.enableTimeTracking) this.initTimeTracking();\r\n if (this.config.enableSectionTracking) this.initSectionTracking();\r\n if (this.config.enableFormTracking) this.initFormTracking();\r\n if (this.config.enableHeatmap) this.initClickHeatmap();\r\n\r\n // Track session start\r\n this.trackSessionStart();\r\n }\r\n\r\n /**\r\n * Destroys the tracker and cleans up all observers and listeners.\r\n */\r\n destroy(): void {\r\n // Cleanup observers\r\n this.observers.forEach((obs) => obs.disconnect());\r\n this.observers = [];\r\n\r\n // Cleanup event listeners\r\n this.listeners.forEach(({ target, event, handler }) => {\r\n target.removeEventListener(event, handler);\r\n });\r\n this.listeners = [];\r\n\r\n this.isInitialized = false;\r\n this.config = null;\r\n this.scrollMilestonesReached.clear();\r\n this.clicks = [];\r\n this.sectionTimers.clear();\r\n }\r\n\r\n // ====================================\r\n // PUBLIC TRACKING METHODS\r\n // ====================================\r\n\r\n /** Track a CTA click */\r\n trackCTAClick(buttonName: string, section: string, additionalData?: Record<string, unknown>): void {\r\n trackCTAClick(buttonName, section, additionalData);\r\n this.pushGTMEvent('cta_click', { button_text: buttonName, section });\r\n }\r\n\r\n /** Track a conversion */\r\n trackConversion(type: string, value?: number, additionalData?: Record<string, unknown>): void {\r\n trackEvent('Conversion', type, undefined, value, additionalData);\r\n this.pushGTMEvent('conversion', { conversion_type: type, value });\r\n }\r\n\r\n /** Track FAQ expansion */\r\n trackFAQExpand(question: string, index: number): void {\r\n trackEvent('FAQ', 'expand', question, index);\r\n }\r\n\r\n /** Track social link click */\r\n trackSocialClick(platform: string, action: string): void {\r\n trackEvent('Social', 'click', platform, undefined, { social_action: action });\r\n }\r\n\r\n /** Track image click */\r\n trackImageClick(imageName: string, section: string): void {\r\n trackEvent('Engagement', 'image_click', imageName, undefined, { section });\r\n }\r\n\r\n /** Track scroll to a section */\r\n trackScrollTo(section: string): void {\r\n trackEvent('Navigation', 'scroll_to', section);\r\n }\r\n\r\n /** Track content share */\r\n trackShare(platform: string, content: string): void {\r\n trackEvent('Share', 'click', platform, undefined, { share_content: content });\r\n }\r\n\r\n /** Track file download */\r\n trackDownload(fileName: string, fileType: string): void {\r\n trackEvent('Download', 'click', fileName, undefined, { file_type: fileType });\r\n }\r\n\r\n /** Get current session data */\r\n getSessionData(): { duration: number; clicks: number; scrollMilestones: number[] } {\r\n return {\r\n duration: Math.round((Date.now() - this.sessionStartTime) / 1000),\r\n clicks: this.clicks.length,\r\n scrollMilestones: Array.from(this.scrollMilestonesReached),\r\n };\r\n }\r\n\r\n // ====================================\r\n // PRIVATE METHODS\r\n // ====================================\r\n\r\n private captureInitialData(): void {\r\n const utmParams = captureUTMParams();\r\n const userId = captureUserIdFromURL();\r\n const userName = getUserName();\r\n\r\n const prefix = this.config!.pagePath.replace('/', '');\r\n\r\n try {\r\n localStorage.setItem(`${prefix}_entry_time`, new Date().toISOString());\r\n if (utmParams) {\r\n localStorage.setItem(`${prefix}_utm_params`, JSON.stringify(utmParams));\r\n }\r\n if (userId) {\r\n localStorage.setItem(`${prefix}_user_id`, userId);\r\n }\r\n } catch {\r\n // localStorage may be unavailable\r\n }\r\n\r\n // Send page load event\r\n trackEvent('Landing', 'page_load', this.config!.pageName, undefined, {\r\n page_path: this.config!.pagePath,\r\n user_id: userId,\r\n user_name: userName,\r\n utm_params: utmParams,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n private trackSessionStart(): void {\r\n trackEvent('Session', 'start', this.config!.pageName, undefined, {\r\n page_path: this.config!.pagePath,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n private getEventName(baseName: string): string {\r\n const suffix = this.config?.eventSuffix || '';\r\n return suffix ? `${baseName}${suffix}` : baseName;\r\n }\r\n\r\n private pushGTMEvent(eventName: string, data?: Record<string, unknown>): void {\r\n if (this.config?.gtmId) {\r\n pushToDataLayer(this.getEventName(eventName), {\r\n page_path: this.config.pagePath,\r\n ...data,\r\n });\r\n }\r\n }\r\n\r\n private addListener(target: EventTarget, event: string, handler: EventListener): void {\r\n target.addEventListener(event, handler);\r\n this.listeners.push({ target, event, handler });\r\n }\r\n\r\n // --- Scroll Tracking ---\r\n private initScrollTracking(): void {\r\n let scrollTimeout: ReturnType<typeof setTimeout>;\r\n\r\n const handler = (): void => {\r\n clearTimeout(scrollTimeout);\r\n scrollTimeout = setTimeout(() => {\r\n const scrollHeight = document.documentElement.scrollHeight - window.innerHeight;\r\n if (scrollHeight <= 0) return;\r\n\r\n const pct = Math.round((window.scrollY / scrollHeight) * 100);\r\n\r\n for (const milestone of [25, 50, 75, 100]) {\r\n if (pct >= milestone && !this.scrollMilestonesReached.has(milestone)) {\r\n this.scrollMilestonesReached.add(milestone);\r\n\r\n trackEvent('Scroll', 'milestone', `${milestone}%`, milestone, {\r\n page_path: this.config!.pagePath,\r\n scroll_percentage: milestone,\r\n });\r\n\r\n this.pushGTMEvent('scroll_milestone', { scroll_percentage: milestone });\r\n }\r\n }\r\n }, 100);\r\n };\r\n\r\n this.addListener(window, 'scroll', handler as EventListener);\r\n }\r\n\r\n // --- CTA Tracking ---\r\n private initCTATracking(): void {\r\n setTimeout(() => {\r\n const ctaButtons = document.querySelectorAll('button, a[href*=\"#\"], [data-cta]');\r\n ctaButtons.forEach((button) => {\r\n const handler = (): void => {\r\n const el = button as HTMLElement;\r\n const text = el.textContent?.trim() || el.getAttribute('data-cta') || 'Unknown CTA';\r\n const section = el.closest('section')?.id || el.closest('[data-section]')?.getAttribute('data-section') || 'unknown';\r\n\r\n this.trackCTAClick(text, section);\r\n };\r\n this.addListener(button, 'click', handler as EventListener);\r\n });\r\n }, 2000); // Wait for DOM to be fully rendered\r\n }\r\n\r\n // --- Time Tracking (page exit) ---\r\n private initTimeTracking(): void {\r\n const handler = (): void => {\r\n const duration = Math.round((Date.now() - this.sessionStartTime) / 1000);\r\n\r\n trackEvent('Session', 'end', this.config!.pageName, duration, {\r\n session_duration: duration,\r\n page_path: this.config!.pagePath,\r\n exit_timestamp: Date.now(),\r\n });\r\n\r\n this.pushGTMEvent('page_exit', {\r\n session_duration: duration,\r\n exit_timestamp: Date.now(),\r\n });\r\n };\r\n\r\n this.addListener(window, 'beforeunload', handler as EventListener);\r\n }\r\n\r\n // --- Section Dwell Time (IntersectionObserver) ---\r\n private initSectionTracking(): void {\r\n const sectionEntryTimes = new Map<string, number>();\r\n\r\n const observer = new IntersectionObserver(\r\n (entries) => {\r\n entries.forEach((entry) => {\r\n const sectionId = (entry.target as HTMLElement).id || (entry.target as HTMLElement).getAttribute('data-section') || 'unknown';\r\n\r\n if (entry.isIntersecting) {\r\n sectionEntryTimes.set(sectionId, Date.now());\r\n } else {\r\n const entryTime = sectionEntryTimes.get(sectionId);\r\n if (entryTime) {\r\n const seconds = (Date.now() - entryTime) / 1000;\r\n trackTimeInSection(sectionId, seconds);\r\n sectionEntryTimes.delete(sectionId);\r\n }\r\n }\r\n });\r\n },\r\n { threshold: 0.5 },\r\n );\r\n\r\n // Observe all sections\r\n setTimeout(() => {\r\n const sections = document.querySelectorAll('section, [data-section]');\r\n sections.forEach((section) => observer.observe(section));\r\n }, 1000);\r\n\r\n this.observers.push(observer);\r\n }\r\n\r\n // --- Form Auto-Tracking ---\r\n private initFormTracking(): void {\r\n setTimeout(() => {\r\n const forms = document.querySelectorAll('form');\r\n forms.forEach((form) => {\r\n const formName = form.getAttribute('name') || form.id || 'unknown-form';\r\n\r\n // Track form focus (start)\r\n let started = false;\r\n const inputs = form.querySelectorAll('input, textarea, select');\r\n inputs.forEach((input) => {\r\n this.addListener(input, 'focus', (() => {\r\n if (!started) {\r\n started = true;\r\n trackFormStart(formName);\r\n }\r\n }) as EventListener);\r\n });\r\n\r\n // Track form submit\r\n this.addListener(form, 'submit', ((_e: Event) => {\r\n trackFormSubmit(formName, true, {\r\n page_path: this.config!.pagePath,\r\n });\r\n this.pushGTMEvent('form_submit', { form_name: formName });\r\n }) as EventListener);\r\n });\r\n }, 2000);\r\n }\r\n\r\n // --- Click Heatmap ---\r\n private initClickHeatmap(): void {\r\n const handler = (e: Event): void => {\r\n const mouseEvent = e as MouseEvent;\r\n const target = mouseEvent.target as HTMLElement;\r\n\r\n const clickData: ClickData = {\r\n x: mouseEvent.clientX,\r\n y: mouseEvent.clientY,\r\n element: target.tagName.toLowerCase(),\r\n section: target.closest('section')?.id || 'unknown',\r\n timestamp: Date.now(),\r\n viewportWidth: window.innerWidth,\r\n viewportHeight: window.innerHeight,\r\n };\r\n\r\n this.clicks.push(clickData);\r\n };\r\n\r\n this.addListener(document, 'click', handler as EventListener);\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create a LandingTracker.\r\n *\r\n * @example\r\n * ```ts\r\n * const tracker = createLandingTracker({\r\n * pagePath: '/kin',\r\n * pageName: 'Kin Landing Page',\r\n * gtmId: 'GTM-5GMQNFMN',\r\n * })\r\n * // On unmount:\r\n * tracker.destroy()\r\n * ```\r\n */\r\nexport const createLandingTracker = (config: LandingTrackerConfig): LandingTracker => {\r\n const tracker = new LandingTracker();\r\n tracker.init(config);\r\n return tracker;\r\n};\r\n","/**\r\n * API Client — Configurable HTTP client for backend persistence.\r\n * Framework-agnostic. Uses native fetch.\r\n *\r\n * @example\r\n * ```ts\r\n * import { initTrackingAPI } from '@metodokorexmk/tracking';\r\n *\r\n * initTrackingAPI({\r\n * baseUrl: 'https://api.korex.com/api/v1',\r\n * getAuthToken: () => localStorage.getItem('access_token'),\r\n * });\r\n * ```\r\n */\r\n\r\nimport type { TrackingAPIConfig } from '../core/types';\r\n\r\nlet apiConfig: TrackingAPIConfig | null = null;\r\n\r\n/**\r\n * Initializes the HTTP client for the persistence layer.\r\n * Must be called before using lead submission, dwell time, or query functions.\r\n */\r\nexport const initTrackingAPI = (config: TrackingAPIConfig): void => {\r\n apiConfig = {\r\n ...config,\r\n baseUrl: config.baseUrl.replace(/\\/+$/, ''),\r\n };\r\n};\r\n\r\n/**\r\n * Returns the current config. Throws if not initialized.\r\n */\r\nexport const getAPIConfig = (): TrackingAPIConfig => {\r\n if (!apiConfig) {\r\n throw new Error('[@metodokorexmk/tracking] initTrackingAPI() must be called before using persistence functions.');\r\n }\r\n return apiConfig;\r\n};\r\n\r\n/**\r\n * Returns whether the API client has been initialized.\r\n */\r\nexport const isTrackingAPIInitialized = (): boolean => apiConfig !== null;\r\n\r\n/**\r\n * Builds request headers, including auth token if available.\r\n */\r\nconst buildHeaders = (): HeadersInit => {\r\n const config = getAPIConfig();\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n if (config.getAuthToken) {\r\n const token = config.getAuthToken();\r\n if (token) {\r\n headers.Authorization = `Bearer ${token}`;\r\n }\r\n }\r\n\r\n if (config.getCustomHeaders) {\r\n Object.assign(headers, config.getCustomHeaders());\r\n }\r\n\r\n return headers;\r\n};\r\n\r\n/**\r\n * Performs a GET request to the API.\r\n */\r\nexport const apiGet = async <T>(path: string): Promise<T> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}${path}`;\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: buildHeaders(),\r\n credentials: 'include',\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text().catch(() => '');\r\n throw new Error(`API GET ${path} failed (${response.status}): ${errorText}`);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n};\r\n\r\n/**\r\n * Performs a POST request to the API.\r\n */\r\nexport const apiPost = async <T>(path: string, body: Record<string, unknown>): Promise<T> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}${path}`;\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: buildHeaders(),\r\n body: JSON.stringify(body),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text().catch(() => '');\r\n throw new Error(`API POST ${path} failed (${response.status}): ${errorText}`);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n};\r\n\r\n/**\r\n * Performs a PATCH request to the API with keepalive support (useful in beforeunload).\r\n */\r\nexport const apiPatch = async <T>(\r\n path: string,\r\n body: Record<string, unknown>,\r\n options?: { keepalive?: boolean; timeoutMs?: number },\r\n): Promise<T> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}${path}`;\r\n const controller = new AbortController();\r\n\r\n const timeoutMs = options?.timeoutMs ?? 10000;\r\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers: buildHeaders(),\r\n body: JSON.stringify(body),\r\n keepalive: options?.keepalive ?? false,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text().catch(() => '');\r\n throw new Error(`API PATCH ${path} failed (${response.status}): ${errorText}`);\r\n }\r\n\r\n // Attempt JSON parse; return empty object on failure\r\n const text = await response.text();\r\n try {\r\n return JSON.parse(text) as T;\r\n } catch {\r\n return {} as T;\r\n }\r\n } catch (error) {\r\n clearTimeout(timeoutId);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * Fire-and-forget PATCH request using fetch with keepalive (for beforeunload).\r\n * Does not wait for a response.\r\n */\r\nexport const apiPatchFireAndForget = (path: string, body: Record<string, unknown>): void => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}${path}`;\r\n\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n };\r\n\r\n if (config.getAuthToken) {\r\n const token = config.getAuthToken();\r\n if (token) {\r\n headers.Authorization = `Bearer ${token}`;\r\n }\r\n }\r\n\r\n // Fire-and-forget with keepalive\r\n fetch(url, {\r\n method: 'PATCH',\r\n headers,\r\n body: JSON.stringify(body),\r\n keepalive: true,\r\n }).catch(() => {\r\n // Ignore errors in fire-and-forget\r\n });\r\n};\r\n","/**\r\n * Lead Submission — Lead creation and update against the backend.\r\n * Migrated from lead-origin-detector.ts, framework-agnostic.\r\n */\r\n\r\nimport type {\r\n UrlParams,\r\n LeadOrigin,\r\n LeadFormData,\r\n TrackingLeadResponse,\r\n SubmitTrackingLeadResponse,\r\n BuildRequestBodyOptions,\r\n} from '../core/types';\r\nimport { getAPIConfig } from './api-client';\r\n\r\n// ====================================\r\n// URL PARAMS\r\n// ====================================\r\n\r\n/**\r\n * Extracts all relevant parameters from the URL.\r\n *\r\n * @param url - Optional URL (defaults to window.location if omitted)\r\n * @returns Object containing all extracted parameters\r\n */\r\nexport const extractUrlParams = (url?: string): UrlParams => {\r\n if (typeof window === 'undefined' && !url) {\r\n return {\r\n userId: '',\r\n idCampana: '',\r\n adsetId: '',\r\n adId: '',\r\n utmContent: '',\r\n fbclid: '',\r\n nombreNetworker: '',\r\n whatsapp: '',\r\n pipelineId: '',\r\n leadCampaign: 'Funnel Organico',\r\n leadCampaing: 'Funnel Organico',\r\n isOrganico: true,\r\n };\r\n }\r\n\r\n let searchParams: URLSearchParams;\r\n if (url) {\r\n try {\r\n const urlObj = new URL(url);\r\n searchParams = new URLSearchParams(urlObj.search);\r\n } catch {\r\n searchParams = new URLSearchParams();\r\n }\r\n } else {\r\n searchParams = new URLSearchParams(window.location.search);\r\n }\r\n\r\n const userId = searchParams.get('user_id') || '';\r\n const idCampana = searchParams.get('campaign_id') || searchParams.get('utm_id') || '';\r\n // Capture adset_id and ad_id for Campaign > Ad Set > Ad traceability\r\n const adsetId = searchParams.get('adset_id') || '';\r\n const adId = searchParams.get('ad_id') || '';\r\n const utmContent = searchParams.get('utm_content') || '';\r\n const fbclid = searchParams.get('fbclid') || '';\r\n const whatsapp = searchParams.get('whatsapp') || '';\r\n const nombreNetworker = searchParams.get('user_name') || searchParams.get('networker') || searchParams.get('name') || '';\r\n const pipelineId = searchParams.get('pipeline_id') || '';\r\n const funnelId = searchParams.get('funnel_id') || '';\r\n const metricId = searchParams.get('metric_id') || '';\r\n const utmSource = searchParams.get('utm_source') || '';\r\n const utmMedium = searchParams.get('utm_medium') || '';\r\n const utmCampaign = searchParams.get('utm_campaign') || '';\r\n const isOrganico = !!(whatsapp && !idCampana && !fbclid);\r\n const leadCampaing = fbclid ? 'Funnel FB' : 'Funnel Organico';\r\n\r\n return {\r\n userId,\r\n idCampana,\r\n adsetId,\r\n adId,\r\n utmContent,\r\n fbclid,\r\n nombreNetworker,\r\n whatsapp,\r\n pipelineId,\r\n funnelId,\r\n metricId,\r\n utmSource,\r\n utmMedium,\r\n utmCampaign,\r\n leadCampaign: leadCampaing,\r\n leadCampaing,\r\n isOrganico,\r\n };\r\n};\r\n\r\n// ====================================\r\n// ORIGIN DETECTION\r\n// ====================================\r\n\r\n/**\r\n * Detects the lead origin based on URL parameters.\r\n * Facebook Ads: has fbclid OR campaign_id\r\n * Organic: has whatsapp AND does NOT have fbclid AND does NOT have campaign_id\r\n */\r\nexport const detectLeadOrigin = (url?: string): LeadOrigin => {\r\n const params = extractUrlParams(url);\r\n const hasCampaign = Boolean(params.idCampana || params.fbclid);\r\n const type: 'facebook' | 'organic' = hasCampaign ? 'facebook' : 'organic';\r\n\r\n const endpoint = hasCampaign ? '/tracking/create-with-lead-and-distribution' : '/tracking/create-organic-lead';\r\n\r\n return { type, endpoint, params, hasCampaign };\r\n};\r\n\r\n// ====================================\r\n// BODY BUILDER\r\n// ====================================\r\n\r\n/**\r\n * Builds the request body based on the lead origin type.\r\n */\r\nexport const buildTrackingRequestBody = (\r\n params: UrlParams,\r\n formData: LeadFormData,\r\n origin: LeadOrigin,\r\n options?: BuildRequestBodyOptions,\r\n): Record<string, unknown> => {\r\n const collaboratorId = params.userId ? parseInt(params.userId, 10) : null;\r\n const telefonoLimpio = formData.telefono.replace(/\\s+/g, '');\r\n\r\n const body: Record<string, unknown> = {\r\n userName: formData.nombre.trim(),\r\n userEmail: formData.correo.trim(),\r\n entryDate: new Date().toISOString(),\r\n accessUrl: typeof window !== 'undefined' ? window.location.href : '',\r\n leadName: formData.nombre.trim(),\r\n leadEmail: formData.correo.trim(),\r\n leadPhone: formData.countryLada ? `${formData.countryLada}${telefonoLimpio}` : telefonoLimpio,\r\n };\r\n\r\n // Optional fields\r\n if (options?.nameForm) body.nameForm = options.nameForm;\r\n if (options?.msgForm) body.msgForm = options.msgForm;\r\n if (options?.status) body.status = options.status;\r\n if (options?.whatsappSent !== undefined) body.whatsapp_sent = options.whatsappSent;\r\n if (options?.dwellTime !== undefined) body.dwellTime = options.dwellTime;\r\n if (options?.videoTimeWatched !== undefined) body.videoTimeWatched = options.videoTimeWatched;\r\n if (options?.videoCompleted !== undefined) {\r\n body.videoCompleted = options.videoCompleted;\r\n body.video_completed = options.videoCompleted;\r\n }\r\n\r\n // Origin-specific fields\r\n if (origin.hasCampaign) {\r\n if (collaboratorId) body.userId = collaboratorId;\r\n if (params.idCampana) body.idCampana = params.idCampana;\r\n if (params.utmContent) body.utmContent = params.utmContent;\r\n if (params.fbclid) body.fbclid = params.fbclid;\r\n } else if (collaboratorId) {\r\n body.referringUserId = collaboratorId;\r\n body.referring_user_id = collaboratorId;\r\n }\r\n\r\n // Ad traceability — sent for BOTH flows\r\n if (params.adsetId) body.adsetId = params.adsetId;\r\n if (params.adId) body.adId = params.adId;\r\n\r\n // UTM params — sent for BOTH flows (Facebook and organic)\r\n if (params.utmSource) body.utmSource = params.utmSource;\r\n if (params.utmMedium) body.utmMedium = params.utmMedium;\r\n if (params.utmCampaign) body.utmCampaign = params.utmCampaign;\r\n if (params.leadCampaign) body.leadCampaign = params.leadCampaign;\r\n\r\n // Pipeline, funnel, metric IDs\r\n if (params.pipelineId) {\r\n const parsed = parseInt(params.pipelineId, 10);\r\n if (!isNaN(parsed)) body.pipeline_id = parsed;\r\n }\r\n if (params.funnelId) {\r\n const parsed = parseInt(params.funnelId, 10);\r\n if (!isNaN(parsed)) body.funnel_id = parsed;\r\n }\r\n if (params.metricId) {\r\n const parsed = parseInt(params.metricId, 10);\r\n if (!isNaN(parsed)) body.metric_id = parsed;\r\n }\r\n\r\n // Additional fields\r\n if (options?.additionalFields) {\r\n Object.assign(body, options.additionalFields);\r\n }\r\n\r\n return body;\r\n};\r\n\r\n// ====================================\r\n// SUBMIT / UPDATE\r\n// ====================================\r\n\r\n/**\r\n * Submits the lead to the correct endpoint based on its origin.\r\n */\r\nexport const submitTrackingLead = async (body: Record<string, unknown>, origin: LeadOrigin): Promise<SubmitTrackingLeadResponse> => {\r\n const config = getAPIConfig();\r\n const fullUrl = `${config.baseUrl}${origin.endpoint}`;\r\n\r\n try {\r\n const response = await fetch(fullUrl, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(body),\r\n });\r\n\r\n let data: TrackingLeadResponse | null = null;\r\n try {\r\n const text = await response.text();\r\n if (text) {\r\n const parsed = JSON.parse(text);\r\n if (parsed && typeof parsed === 'object') {\r\n data = parsed as TrackingLeadResponse;\r\n }\r\n }\r\n } catch {\r\n // Parse error, data remains null\r\n }\r\n\r\n return { ok: response.ok, status: response.status, data };\r\n } catch {\r\n return { ok: false, status: 0, data: null };\r\n }\r\n};\r\n\r\n/**\r\n * End-to-end function: detects origin, builds body, and submits the lead.\r\n *\r\n * @example\r\n * ```ts\r\n * const result = await submitLead(\r\n * { nombre: 'Juan', correo: 'juan@mail.com', telefono: '+34600...' },\r\n * { nameForm: 'Kin Form', videoCompleted: true },\r\n * );\r\n * ```\r\n */\r\nexport const submitLead = async (\r\n formData: LeadFormData,\r\n options?: BuildRequestBodyOptions,\r\n url?: string,\r\n): Promise<SubmitTrackingLeadResponse> => {\r\n const origin = detectLeadOrigin(url);\r\n const body = buildTrackingRequestBody(origin.params, formData, origin, options);\r\n return submitTrackingLead(body, origin);\r\n};\r\n\r\n/**\r\n * Updates an existing lead via PATCH.\r\n */\r\nexport const updateTrackingLead = async (trackingId: number | string, updates: Record<string, unknown>): Promise<boolean> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}/tracking/${trackingId}`;\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(updates),\r\n });\r\n return response.ok;\r\n } catch {\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Marks a lead as \"WhatsApp sent\".\r\n */\r\nexport const markWhatsAppSent = async (leadId: number | string): Promise<boolean> => {\r\n const config = getAPIConfig();\r\n const url = `${config.baseUrl}/tracking/lead/${leadId}/whatsapp-sent`;\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ whatsapp_sent: true }),\r\n });\r\n return response.ok;\r\n } catch {\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * Builds a msgForm as a JSON-stringified value.\r\n */\r\nexport const buildMsgFormJSON = (mensaje: string, datosAdicionales?: Record<string, unknown>): string => {\r\n return JSON.stringify({ mensaje: mensaje || '', ...datosAdicionales });\r\n};\r\n","/**\r\n * DwellTimeTracker — Dwell time tracking with periodic backend reporting.\r\n * Migrated from dwell-time.ts (~960 lines -> ~280 clean lines).\r\n * Framework-agnostic.\r\n */\r\n\r\nimport type { DwellTimeConfig } from '../core/types';\r\nimport { getAPIConfig, isTrackingAPIInitialized } from './api-client';\r\n\r\n/**\r\n * Measures user dwell time on a page and periodically sends it to the tracking backend.\r\n *\r\n * Features:\r\n * - Automatic send every 30 seconds\r\n * - Auto-pause when tab is hidden\r\n * - sendBeacon on beforeunload for maximum reliability\r\n * - Retry pending updates via sessionStorage\r\n * - Integrated video tracking (videoTimeWatched, videoCompleted)\r\n */\r\nexport class DwellTimeTracker {\r\n private startTime: number | null = null;\r\n\r\n private trackingDataId: number | string | null = null;\r\n\r\n private enabled = false;\r\n\r\n private onSuccess?: () => void;\r\n\r\n private onError?: (error: Error) => void;\r\n\r\n private intervalId: ReturnType<typeof setInterval> | null = null;\r\n\r\n private isSending = false;\r\n\r\n private videoTimeWatched = 0;\r\n\r\n private videoCompleted = false;\r\n\r\n private videoTrackingStopped = false;\r\n\r\n private lastDwellTimeSent = 0;\r\n\r\n private lastVideoTimeSent = 0;\r\n\r\n private pausedTime = 0;\r\n\r\n private pauseStartTime: number | null = null;\r\n\r\n private boundBeforeUnload: (e: BeforeUnloadEvent) => void;\r\n\r\n private boundVisibilityChange: () => void;\r\n\r\n constructor() {\r\n this.boundBeforeUnload = this.handleBeforeUnload.bind(this);\r\n this.boundVisibilityChange = this.handleVisibilityChange.bind(this);\r\n }\r\n\r\n /**\r\n * Starts dwell time tracking.\r\n */\r\n start(config: DwellTimeConfig): void {\r\n if (typeof window === 'undefined') return;\r\n\r\n const wasAlreadyTracking = this.enabled;\r\n this.enabled = config.enabled !== false;\r\n this.trackingDataId = config.trackingDataId;\r\n this.onSuccess = config.onSuccess;\r\n this.onError = config.onError;\r\n\r\n if (!this.enabled) return;\r\n\r\n this.cleanupListeners();\r\n\r\n window.addEventListener('beforeunload', this.boundBeforeUnload);\r\n document.addEventListener('visibilitychange', this.boundVisibilityChange);\r\n\r\n if (!wasAlreadyTracking) {\r\n this.startTime = Date.now();\r\n }\r\n\r\n if (!this.intervalId) {\r\n this.intervalId = setInterval(() => {\r\n if (this.videoCompleted && this.videoTrackingStopped) {\r\n if (document.visibilityState === 'visible' && this.startTime) {\r\n this.sendDwellTime(false);\r\n }\r\n return;\r\n }\r\n\r\n if (this.videoCompleted && !this.videoTrackingStopped) {\r\n this.sendDwellTime(false);\r\n this.videoTrackingStopped = true;\r\n return;\r\n }\r\n\r\n if (document.visibilityState === 'visible' && this.startTime) {\r\n this.sendDwellTime(false);\r\n }\r\n }, 30000);\r\n }\r\n\r\n this.retryPendingUpdates();\r\n }\r\n\r\n /**\r\n * Stops tracking and sends accumulated time.\r\n */\r\n stop(): void {\r\n if (this.startTime) {\r\n this.sendDwellTime(true);\r\n }\r\n\r\n this.startTime = null;\r\n this.lastVideoTimeSent = 0;\r\n this.lastDwellTimeSent = 0;\r\n this.videoTrackingStopped = false;\r\n this.pausedTime = 0;\r\n this.pauseStartTime = null;\r\n this.cleanup();\r\n }\r\n\r\n /**\r\n * Returns elapsed time in seconds (excluding paused time).\r\n */\r\n getElapsedTime(): number {\r\n if (!this.startTime) return 0;\r\n\r\n const totalTime = Math.floor((Date.now() - this.startTime) / 1000);\r\n let currentPauseTime = this.pausedTime;\r\n\r\n if (this.pauseStartTime !== null) {\r\n currentPauseTime += Math.floor((Date.now() - this.pauseStartTime) / 1000);\r\n }\r\n\r\n return Math.max(0, totalTime - currentPauseTime);\r\n }\r\n\r\n /**\r\n * Manually updates video time.\r\n * Called from VideoTracker or other adapters.\r\n */\r\n updateVideoTime(videoTimeWatched: number, videoCompleted = false): void {\r\n const hasNewTime = videoTimeWatched > this.videoTimeWatched;\r\n const hasNewCompletion = videoCompleted && !this.videoCompleted;\r\n\r\n if (hasNewTime || hasNewCompletion) {\r\n this.videoTimeWatched = Math.max(this.videoTimeWatched, videoTimeWatched);\r\n this.videoCompleted = videoCompleted || this.videoCompleted;\r\n\r\n if (this.trackingDataId && this.trackingDataId !== 'pending' && this.startTime && hasNewCompletion) {\r\n this.sendDwellTime(false);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Updates the trackingDataId (useful when obtained after registration).\r\n */\r\n updateTrackingId(trackingDataId: number | string): void {\r\n if (!trackingDataId || (typeof trackingDataId === 'string' && trackingDataId.trim() === '')) return;\r\n\r\n const oldTrackingId = this.trackingDataId;\r\n this.trackingDataId = trackingDataId;\r\n\r\n if (oldTrackingId === 'pending' && this.trackingDataId !== 'pending') {\r\n this.lastDwellTimeSent = 0;\r\n this.lastVideoTimeSent = 0;\r\n this.videoTrackingStopped = false;\r\n }\r\n\r\n if (this.startTime && oldTrackingId === 'pending') {\r\n this.sendDwellTime(false);\r\n }\r\n\r\n if (!this.intervalId && this.enabled && this.startTime) {\r\n this.intervalId = setInterval(() => {\r\n if (document.visibilityState === 'visible' && this.startTime) {\r\n this.sendDwellTime(false);\r\n }\r\n }, 30000);\r\n }\r\n }\r\n\r\n /**\r\n * Cleans up all listeners and timers.\r\n */\r\n destroy(): void {\r\n this.stop();\r\n }\r\n\r\n // ====================================\r\n // PRIVATE\r\n // ====================================\r\n\r\n private checkLocalStorageForId(): void {\r\n if (typeof window === 'undefined') return;\r\n\r\n if (!this.trackingDataId || this.trackingDataId === 'pending') {\r\n const tid = localStorage.getItem('tracking_id') || localStorage.getItem('landing_tracking_id');\r\n if (tid) this.updateTrackingId(tid);\r\n }\r\n }\r\n\r\n private async sendDwellTime(isFinal: boolean = false): Promise<void> {\r\n if (!isTrackingAPIInitialized()) return;\r\n\r\n this.checkLocalStorageForId();\r\n\r\n if (!this.startTime || this.isSending) return;\r\n\r\n if (!this.trackingDataId || this.trackingDataId === 'pending') return;\r\n\r\n const trackingIdNum = typeof this.trackingDataId === 'string' ? parseInt(this.trackingDataId, 10) : this.trackingDataId;\r\n\r\n if (isNaN(trackingIdNum as number) || (trackingIdNum as number) <= 0) return;\r\n\r\n const elapsedTime = this.getElapsedTime();\r\n if (elapsedTime < 1 && !isFinal) return;\r\n\r\n this.isSending = true;\r\n const config = getAPIConfig();\r\n const token = config.getAuthToken?.() ?? null;\r\n\r\n try {\r\n const url = `${config.baseUrl}/tracking/${trackingIdNum}`;\r\n\r\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\r\n if (token) headers.Authorization = `Bearer ${token}`;\r\n\r\n const body: Record<string, unknown> = { dwellTime: elapsedTime };\r\n\r\n if (this.videoTimeWatched > 0 && !this.videoTrackingStopped) {\r\n body.videoTimeWatched = this.videoTimeWatched;\r\n body.videoCompleted = this.videoCompleted;\r\n }\r\n\r\n this.lastDwellTimeSent = elapsedTime;\r\n if (this.videoTimeWatched > 0 && !this.videoTrackingStopped) {\r\n this.lastVideoTimeSent = this.videoTimeWatched;\r\n }\r\n\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), 10000);\r\n\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers,\r\n body: JSON.stringify(body),\r\n keepalive: isFinal,\r\n signal: controller.signal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n throw new Error(`Error ${response.status}: ${response.statusText}`);\r\n }\r\n\r\n this.onSuccess?.();\r\n this.clearPendingUpdate();\r\n } catch (error: unknown) {\r\n const err = error as { name?: string; message?: string };\r\n const isNetworkError =\r\n err.name === 'AbortError' || err.name === 'TimeoutError' || (err.name === 'TypeError' && err.message?.includes('Failed to fetch'));\r\n\r\n if (token) this.savePendingUpdate(elapsedTime);\r\n\r\n if (this.onError && !isNetworkError) {\r\n this.onError(error instanceof Error ? error : new Error('Unknown error'));\r\n }\r\n } finally {\r\n this.isSending = false;\r\n }\r\n }\r\n\r\n private handleBeforeUnload(_event: BeforeUnloadEvent): void {\r\n this.sendDwellTimeWithBeacon();\r\n }\r\n\r\n private handleVisibilityChange(): void {\r\n if (document.visibilityState === 'hidden') {\r\n if (this.pauseStartTime === null && this.startTime) {\r\n this.pauseStartTime = Date.now();\r\n this.sendDwellTime(false);\r\n }\r\n } else if (document.visibilityState === 'visible') {\r\n if (this.pauseStartTime !== null) {\r\n this.pausedTime += Math.floor((Date.now() - this.pauseStartTime) / 1000);\r\n this.pauseStartTime = null;\r\n } else if (!this.startTime) {\r\n this.startTime = Date.now();\r\n this.pausedTime = 0;\r\n this.pauseStartTime = null;\r\n }\r\n }\r\n }\r\n\r\n private sendDwellTimeWithBeacon(): void {\r\n if (!isTrackingAPIInitialized()) return;\r\n\r\n this.checkLocalStorageForId();\r\n if (!this.startTime || !this.trackingDataId || this.trackingDataId === 'pending') return;\r\n\r\n const trackingIdNum = typeof this.trackingDataId === 'string' ? parseInt(this.trackingDataId, 10) : this.trackingDataId;\r\n\r\n if (isNaN(trackingIdNum as number) || (trackingIdNum as number) <= 0) return;\r\n\r\n const config = getAPIConfig();\r\n const elapsedTime = this.getElapsedTime();\r\n const token = config.getAuthToken?.() ?? null;\r\n\r\n const body: Record<string, unknown> = { dwellTime: elapsedTime };\r\n if (this.videoTimeWatched > 0 && !this.videoTrackingStopped) {\r\n body.videoTimeWatched = this.videoTimeWatched;\r\n body.videoCompleted = this.videoCompleted;\r\n }\r\n\r\n if (token) this.savePendingUpdate(elapsedTime);\r\n\r\n const url = `${config.baseUrl}/tracking/${trackingIdNum}`;\r\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\r\n if (token) headers.Authorization = `Bearer ${token}`;\r\n\r\n fetch(url, {\r\n method: 'PATCH',\r\n headers,\r\n body: JSON.stringify(body),\r\n keepalive: true,\r\n })\r\n .then((response) => {\r\n if (response.ok) this.clearPendingUpdate();\r\n })\r\n .catch(() => {});\r\n }\r\n\r\n private savePendingUpdate(time: number): void {\r\n if (typeof window === 'undefined' || !this.trackingDataId) return;\r\n try {\r\n sessionStorage.setItem('dwellTime_pending', JSON.stringify({ trackingDataId: this.trackingDataId, time, timestamp: Date.now() }));\r\n } catch {\r\n // sessionStorage may be unavailable\r\n }\r\n }\r\n\r\n private async retryPendingUpdates(): Promise<void> {\r\n if (typeof window === 'undefined' || !isTrackingAPIInitialized()) return;\r\n\r\n try {\r\n const pendingData = sessionStorage.getItem('dwellTime_pending');\r\n if (!pendingData) return;\r\n\r\n const { trackingDataId, time } = JSON.parse(pendingData);\r\n if (trackingDataId !== this.trackingDataId) {\r\n this.clearPendingUpdate();\r\n return;\r\n }\r\n\r\n const config = getAPIConfig();\r\n const token = config.getAuthToken?.() ?? null;\r\n if (!token) {\r\n this.clearPendingUpdate();\r\n return;\r\n }\r\n\r\n const url = `${config.baseUrl}/tracking/${trackingDataId}`;\r\n const response = await fetch(url, {\r\n method: 'PATCH',\r\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\r\n body: JSON.stringify({ dwellTime: time }),\r\n });\r\n\r\n if (response.ok) this.clearPendingUpdate();\r\n } catch {\r\n // Retry silently\r\n }\r\n }\r\n\r\n private clearPendingUpdate(): void {\r\n if (typeof window === 'undefined') return;\r\n try {\r\n sessionStorage.removeItem('dwellTime_pending');\r\n } catch {\r\n // sessionStorage may be unavailable\r\n }\r\n }\r\n\r\n private cleanupListeners(): void {\r\n if (typeof window === 'undefined') return;\r\n window.removeEventListener('beforeunload', this.boundBeforeUnload);\r\n document.removeEventListener('visibilitychange', this.boundVisibilityChange);\r\n }\r\n\r\n private cleanup(): void {\r\n if (typeof window === 'undefined') return;\r\n this.cleanupListeners();\r\n\r\n if (this.intervalId) {\r\n clearInterval(this.intervalId);\r\n this.intervalId = null;\r\n }\r\n }\r\n}\r\n\r\n// Global singleton instance\r\nexport const dwellTimeTracker = new DwellTimeTracker();\r\n\r\n/**\r\n * Starts dwell time tracking.\r\n */\r\nexport const startDwellTimeTracking = (config: DwellTimeConfig): void => {\r\n dwellTimeTracker.start(config);\r\n};\r\n\r\n/**\r\n * Stops tracking and sends accumulated time.\r\n */\r\nexport const stopDwellTimeTracking = (): void => {\r\n dwellTimeTracker.stop();\r\n};\r\n","/**\r\n * Tracking Queries — GET queries to the tracking backend.\r\n * Migrated from TrackingService.ts and LeadTrackingService.ts.\r\n * Framework-agnostic.\r\n */\r\n\r\nimport type { TrackingLead, LeadTrackingData } from '../core/types';\r\nimport { apiGet, apiPost } from './api-client';\r\n\r\n/**\r\n * Retrieves tracking lead data by its ID.\r\n *\r\n * @example\r\n * ```ts\r\n * const tracking = await getTrackingById(123);\r\n * console.log(tracking.videoTimeWatched, tracking.dwellTime);\r\n * ```\r\n */\r\nexport const getTrackingById = async (trackingId: number | string): Promise<TrackingLead> => {\r\n return apiGet<TrackingLead>(`/tracking/${trackingId}`);\r\n};\r\n\r\n/**\r\n * Retrieves a lead with its associated tracking data.\r\n * Processes the response to extract videoVisto, tiempoReproducido, etc.\r\n *\r\n * @example\r\n * ```ts\r\n * const data = await getLeadWithTracking('456');\r\n * console.log(data.videoVisto, data.dwellTime);\r\n * ```\r\n */\r\nexport const getLeadWithTracking = async (leadId: string): Promise<LeadTrackingData> => {\r\n const defaultData: LeadTrackingData = {\r\n videoVisto: false,\r\n tiempoReproducido: '00:00',\r\n envioWhatsapp: false,\r\n videoTimeWatched: 0,\r\n dwellTime: 0,\r\n };\r\n\r\n try {\r\n const data = await apiGet<Record<string, unknown>>(`/leads/${leadId}/with-tracking`);\r\n\r\n // Extract tracking info from the trackingData array\r\n const trackingDataArray = data.trackingData as Array<Record<string, unknown>> | undefined;\r\n const trackingInfo = trackingDataArray && trackingDataArray.length > 0 ? trackingDataArray[0] : null;\r\n\r\n // Top-level lead data\r\n const leadData = data as {\r\n accessUrl?: string;\r\n nameForm?: string;\r\n msgForm?: string;\r\n plataforma?: string;\r\n platform?: string;\r\n aliasName?: string;\r\n campaignName?: string;\r\n };\r\n\r\n if (!trackingInfo) {\r\n return {\r\n ...defaultData,\r\n accessUrl: leadData.accessUrl,\r\n nameForm: leadData.nameForm,\r\n msgForm: leadData.msgForm,\r\n platform: leadData.plataforma || leadData.platform,\r\n aliasName: leadData.aliasName || leadData.campaignName,\r\n };\r\n }\r\n\r\n const formatTime = (seconds: number): string => {\r\n const minutes = Math.floor(seconds / 60);\r\n const remainingSeconds = seconds % 60;\r\n return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;\r\n };\r\n\r\n const videoTimeWatched = (trackingInfo.videoTimeWatched as number) || 0;\r\n const dwellTime = (trackingInfo.dwellTime as number) || (trackingInfo.dwell_time as number) || 0;\r\n\r\n return {\r\n videoVisto: (trackingInfo.videoCompleted as boolean) || false,\r\n tiempoReproducido: videoTimeWatched ? formatTime(videoTimeWatched) : '00:00',\r\n envioWhatsapp: (trackingInfo.whatsappSent as boolean) || false,\r\n accessUrl: (trackingInfo.accessUrl as string) || leadData.accessUrl,\r\n nameForm: (trackingInfo.nameForm as string) || leadData.nameForm,\r\n msgForm: (trackingInfo.msgForm as string) || leadData.msgForm,\r\n platform: leadData.plataforma || leadData.platform || (trackingInfo.platform as string),\r\n aliasName: leadData.aliasName || leadData.campaignName || (trackingInfo.aliasName as string),\r\n trackingId: (trackingInfo as { id?: number }).id,\r\n videoTimeWatched,\r\n dwellTime,\r\n };\r\n } catch {\r\n return defaultData;\r\n }\r\n};\r\n\r\n/**\r\n * Generates a tracking link for a funnel.\r\n *\r\n * @example\r\n * ```ts\r\n * const { link } = await generateTrackingLink(1, 'my-domain.com');\r\n * ```\r\n */\r\nexport const generateTrackingLink = async (funnelId: number, customDomain: string): Promise<{ link: string }> => {\r\n return apiPost<{ link: string }>('/tracking/generate-link', {\r\n funnel_id: funnelId,\r\n custom_domain: customDomain,\r\n });\r\n};\r\n"]}