{"version":3,"sources":["../src/analytics-host-utils.ts","../src/resource-classification.ts","../src/performance-collector.ts","../package.json","../src/version.ts","../src/send.ts","../src/storage-utils.ts","../src/visitor-tracker.tsx","../src/visitor-tracker-next.tsx"],"names":["window","classifyResourcePhase","now","VisitorTracker"],"mappings":"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","file":"next.mjs","sourcesContent":["export function getSiteIdWithFallback(host: string | null): string {\n  if (host && host !== 'unknown') {\n    return host;\n  }\n  \n  return 'unknown';\n} ","/**\n * Centralized resource classification utilities\n * Single source of truth for resource type mapping and classification logic\n */\n\n// Performance API initiator types to semantic categories mapping\nexport const RESOURCE_TYPE_MAPPING = {\n  // Static assets (initial rendering)\n  script: 'JavaScript',\n  link: 'CSS Stylesheets', // CSS files and preloaded resources\n  css: 'Web Fonts', // Fonts loaded via CSS\n  img: 'Images',\n  navigation: 'Navigation',\n\n  // Dynamic resources (post-load)\n  fetch: 'API Calls',\n  xmlhttprequest: 'API Calls',\n\n  // Fallback\n  other: 'Other Resources'\n} as const;\n\n// Category names to Performance API types (for filtering)\nexport const CATEGORY_TO_TYPE_MAPPING = {\n  'CSS Stylesheets': 'link',        // CSS files appear as 'link' type in Performance API\n  'Sync JavaScript': 'script',      // JavaScript files appear as 'script'\n  'Web Fonts': 'css',               // Web fonts appear as 'css' type when loaded via CSS\n  'Critical Images': 'img',         // Images appear as 'img'\n  'Navigation': 'navigation',       // Main document appears as 'navigation'\n  'API Calls': 'fetch',             // API calls appear as 'fetch'\n  'JavaScript': 'script',           // Dynamic table label\n  'Stylesheets': 'link',            // Dynamic table label\n  'Images': 'img',                  // Dynamic table label\n  'Other Resources': 'other'        // Dynamic table label\n} as const;\n\n/**\n * Check if a resource is a static asset based on URL patterns\n */\nexport function isStaticAsset(url: string): boolean {\n  // Static file extensions\n  const staticExtensions = [\n    '.js', '.css', '.woff2', '.woff', '.ttf',\n    '.png', '.jpg', '.jpeg', '.svg', '.webp',\n    '.ico', '.gif', '.bmp'\n  ];\n  \n  // Static asset patterns\n  const staticPatterns = [\n    '/_next/static/',\n    '/static/',\n    '/assets/',\n    '/public/'\n  ];\n  \n  // Check file extensions\n  if (staticExtensions.some(ext => url.endsWith(ext))) {\n    return true;\n  }\n  \n  // Check URL patterns\n  if (staticPatterns.some(pattern => url.includes(pattern))) {\n    return true;\n  }\n  \n  return false;\n}\n\n/**\n * Check if a URL represents a dynamic endpoint (API, analytics, auth, etc.)\n */\nexport function isDynamicEndpoint(url: string): boolean {\n  // Static assets are never dynamic endpoints\n  if (isStaticAsset(url)) {\n    return false;\n  }\n  \n  // Dynamic endpoint patterns\n  const dynamicPatterns = [\n    '/api/',\n    '/v1/',\n    '/log/',\n    '/analytics/',\n    '/auth/',\n    '/sign'\n  ];\n  \n  // Dashboard/admin endpoints (excluding static files)\n  if (url.includes('/dashboard') && !isStaticAsset(url)) {\n    return true;\n  }\n  \n  return dynamicPatterns.some(pattern => url.includes(pattern));\n}\n\nexport type ResourceKind =\n  | 'api'\n  | 'script'\n  | 'stylesheet'\n  | 'font'\n  | 'image'\n  | 'navigation'\n  | 'other';\n\nexport type ResourceConfidence = 'high' | 'medium' | 'low';\n\nexport interface ResourceTypeClassification {\n  kind: ResourceKind;\n  confidence: ResourceConfidence;\n  source?: string;\n}\n\nconst scriptExtensions = /\\.(js|mjs|cjs|jsx|ts|tsx)(\\?|$)/i;\nconst styleExtensions = /\\.(css|scss|sass|less)(\\?|$)/i;\nconst fontExtensions = /\\.(woff2?|ttf|eot|otf)(\\?|$)/i;\nconst imageExtensions = /\\.(jpg|jpeg|png|gif|svg|webp|avif|bmp|ico)(\\?|$)/i;\n\nfunction classifyFromInitiatorType(type: string | undefined): ResourceKind | undefined {\n  if (!type) return undefined;\n  const normalized = type.toLowerCase();\n\n  if (normalized === 'fetch' || normalized === 'xmlhttprequest') return 'api';\n  if (normalized === 'script') return 'script';\n  if (normalized === 'img' || normalized === 'image') return 'image';\n  if (normalized === 'navigation') return 'navigation';\n  if (normalized === 'stylesheet') return 'stylesheet';\n  if (normalized === 'css') return 'font'; // Fonts often surface as CSS\n  if (normalized === 'link') return undefined; // Needs further inspection\n\n  return undefined;\n}\n\nfunction classifyFromUrl(url: string): ResourceTypeClassification | undefined {\n  if (scriptExtensions.test(url)) return { kind: 'script', confidence: 'medium' };\n  if (styleExtensions.test(url)) return { kind: 'stylesheet', confidence: 'medium' };\n  if (fontExtensions.test(url)) return { kind: 'font', confidence: 'medium' };\n  if (imageExtensions.test(url)) return { kind: 'image', confidence: 'medium' };\n\n  if (url.includes('fonts.googleapis.com')) {\n    return { kind: 'font', confidence: 'medium', source: 'Google Fonts' };\n  }\n  if (url.includes('typekit.net') || url.includes('fonts.com')) {\n    return { kind: 'font', confidence: 'medium', source: 'External CDN' };\n  }\n\n  return undefined;\n}\n\n/**\n * Classify a resource into a semantic type with confidence scoring.\n * Used by both initial rendering and dynamic loading views to stay consistent.\n */\nexport function classifyResourceType(resource: {\n  name: string;\n  initiator_type?: string;\n}): ResourceTypeClassification {\n  const initiatorKind = classifyFromInitiatorType(resource.initiator_type);\n\n  if (initiatorKind) {\n    return { kind: initiatorKind, confidence: 'high' };\n  }\n\n  // Special handling for link initiators (preloads) and CSS-triggered fonts\n  const type = resource.initiator_type?.toLowerCase();\n  if (type === 'link') {\n    if (styleExtensions.test(resource.name) || resource.name.includes('_next/static/css')) {\n      return { kind: 'stylesheet', confidence: 'high' };\n    }\n    if (scriptExtensions.test(resource.name) || resource.name.includes('_next/static/chunks')) {\n      return { kind: 'script', confidence: 'medium', source: 'Link preload script' };\n    }\n    if (fontExtensions.test(resource.name)) {\n      return { kind: 'font', confidence: 'medium', source: 'Link preload font' };\n    }\n  }\n\n  if (type === 'css') {\n    const fromUrl = classifyFromUrl(resource.name);\n    if (fromUrl) return fromUrl;\n\n    return { kind: 'font', confidence: 'medium', source: 'CSS-triggered font' };\n  }\n\n  const urlClassification = classifyFromUrl(resource.name);\n  if (urlClassification) return urlClassification;\n\n  if (isDynamicEndpoint(resource.name)) {\n    return { kind: 'api', confidence: 'low', source: 'Dynamic endpoint heuristic' };\n  }\n\n  return {\n    kind: 'other',\n    confidence: 'low',\n    source: resource.initiator_type ? `Unknown initiator: ${resource.initiator_type}` : 'Unknown initiator'\n  };\n}\n\n/**\n * Classify a resource as initial rendering or dynamic loading phase\n */\nexport function classifyResourcePhase(resource: {\n  initiator_type: string;\n  name: string;\n  duplicate_count?: number;\n  initial_requests?: number;\n  dynamic_requests?: number;\n}): 'initial' | 'dynamic' {\n  const totalRequests = (resource.initial_requests || 0) + (resource.dynamic_requests || 0);\n  \n  // API endpoints with multiple hits are dynamic\n  if ((resource.initiator_type === 'fetch' || resource.initiator_type === 'xmlhttprequest')) {\n    if (totalRequests > 1 || isDynamicEndpoint(resource.name)) {\n      return 'dynamic';\n    }\n  }\n  \n  // Resources with more dynamic than initial requests\n  if ((resource.dynamic_requests || 0) > (resource.initial_requests || 0)) {\n    return 'dynamic';\n  }\n  \n  // Dynamic endpoints regardless of timing\n  if (isDynamicEndpoint(resource.name) && (resource.dynamic_requests || 0) > 0) {\n    return 'dynamic';\n  }\n  \n  // Default to initial for static assets\n  return 'initial';\n}\n\n/**\n * Get the semantic category name for a Performance API initiator type\n */\nexport function getSemanticCategory(initiatorType: string): string {\n  return RESOURCE_TYPE_MAPPING[initiatorType as keyof typeof RESOURCE_TYPE_MAPPING] || 'Other Resources';\n}\n\n/**\n * Map category name to Performance API type for filtering\n */\nexport function mapCategoryToFilterType(categoryName: string): string {\n  return CATEGORY_TO_TYPE_MAPPING[categoryName as keyof typeof CATEGORY_TO_TYPE_MAPPING] || 'all';\n}\n\n/**\n * Get the phase color for UI display\n */\nexport function getPhaseColor(phase: 'initial' | 'dynamic'): string {\n  return phase === 'initial' ? 'text-chart-1' : 'text-chart-4';\n}\n\n/**\n * Get the phase text for UI display\n */\nexport function getPhaseText(phase: 'initial' | 'dynamic'): string {\n  return phase === 'initial' ? 'INITIAL' : 'DYNAMIC';\n}\n","import { onLCP, onCLS, onINP, Metric } from 'web-vitals';\nimport { classifyResourcePhase as centralClassifyResourcePhase } from './resource-classification';\n\nexport interface FlattenedPageMetrics {\n  page: string;\n  dns_lookup?: number;\n  tcp_connect?: number;\n  ttfb?: number;\n  html_response?: number;\n  frontend_render?: number;\n  total_page_load?: number;\n  lcp?: number;\n  cls?: number;\n  inp?: number;\n  num_requests: number;\n  total_size_kb: number;\n  performance_grade: 'good' | 'needs work' | 'poor';\n  top_resources: Array<{\n    name: string;\n    initiator_type: string;\n    duration: number;\n    duplicate_count?: number;\n    initial_hits?: number;\n    dynamic_hits?: number;\n    transfer_size?: number;\n    decoded_body_size?: number;\n    domain?: string;\n    time_since_load?: number;\n    is_async?: boolean;\n  }>;\n  // Timeline positioning (relative to page load completion)\n  async_timeline_start?: number;\n  async_timeline_end?: number;\n  async_timeline_window?: number;\n  \n  // API timeline and analysis\n  async_api_end?: number;\n  async_api_count?: number;\n  async_api_parallelism?: number;\n  async_api_domains?: Record<string, { count: number; totalDuration: number }>;\n  async_api_slowest_endpoints?: Array<{ url: string; duration: number; count: number }>;\n  async_api_slowest?: { url: string; duration: number; domain: string };\n  \n  // Asset analysis (non-API resources)\n  async_asset_duration?: number;\n  async_asset_count?: number;\n  async_asset_by_type?: Record<string, { count: number; totalDuration: number }>;\n  async_asset_slowest?: Array<{ name: string; initiator_type: string; duration: number }>;\n  timestamp: string;\n}\n\nconst globalWebVitals: { lcp?: number; cls?: number; inp?: number } = {};\nlet webVitalsInitialized = false;\n\nfunction roundCLS(value: number): number {\n  return Math.round(value * 1000) / 1000;\n}\n\nfunction sendMetricsToAnalytics(metric: Metric) {\n  if (metric.name === 'LCP') globalWebVitals.lcp = Math.round(metric.value);\n  if (metric.name === 'CLS') globalWebVitals.cls = roundCLS(metric.value);\n  if (metric.name === 'INP') globalWebVitals.inp = Math.round(metric.value);\n}\n\nfunction initializeWebVitals() {\n  if (webVitalsInitialized || typeof window === 'undefined') return;\n  webVitalsInitialized = true;\n\n  onLCP(sendMetricsToAnalytics, { reportAllChanges: true });\n  onCLS(sendMetricsToAnalytics, { reportAllChanges: true });\n  onINP(sendMetricsToAnalytics, { reportAllChanges: true });\n}\n\nif (typeof window !== 'undefined') {\n  initializeWebVitals();\n}\n\nfunction calculatePerformanceGrade(m: {\n  total_page_load?: number;\n  lcp?: number;\n  cls?: number;\n  inp?: number;\n}): 'good' | 'needs work' | 'poor' {\n  let score = 0;\n  let maxScore = 3;\n\n  if (m.total_page_load !== undefined && m.total_page_load <= 2500) score++;\n  if (m.lcp !== undefined && m.lcp <= 2500) score++;\n  if (m.cls !== undefined && m.cls <= 0.1) score++;\n\n  if (m.inp !== undefined) {\n    maxScore++;\n    if (m.inp <= 200) score++;\n  }\n\n  if (score / maxScore >= 0.75) return 'good';\n  if (score / maxScore >= 0.5) return 'needs work';\n  return 'poor';\n}\n\nfunction calculateAsyncWindow(\n  resources: PerformanceResourceTiming[], \n  loadEventEnd: number,\n  maxWindowMs: number = 60000 // Default to 60 seconds for page-scoped analytics\n) {\n  // Filter resources to only those within the specified time window after page load\n  const pageResources = resources.filter(r => \n    r.startTime <= loadEventEnd + maxWindowMs\n  );\n  \n  if (pageResources.length === 0) {\n    return { start: undefined, end: undefined, duration: undefined, window: undefined };\n  }\n  \n  const start = Math.round(pageResources[0].startTime - loadEventEnd);\n  const end = Math.round(Math.max(...pageResources.map(r => r.responseEnd)) - loadEventEnd);\n  const window = end - start;\n  \n  return { start, end, duration: end, window };\n}\n\nfunction getWebVitalsFromPerformanceAPI() {\n  const perf = window.performance;\n  const result: { lcp?: number; cls?: number; inp?: number } = {};\n\n  const lcpEntries = perf.getEntriesByType('largest-contentful-paint');\n  if (lcpEntries.length > 0)\n    result.lcp = Math.round(lcpEntries[lcpEntries.length - 1].startTime);\n\n  let clsValue = 0;\n  const layoutShiftEntries = perf.getEntriesByType('layout-shift') as PerformanceEntry[];\n  layoutShiftEntries.forEach((entry) => {\n    const layoutEntry = entry as PerformanceEntry & { hadRecentInput?: boolean; value?: number };\n    if (!layoutEntry.hadRecentInput && layoutEntry.value)\n      clsValue += layoutEntry.value;\n  });\n  if (clsValue > 0) result.cls = roundCLS(clsValue);\n\n  if (globalWebVitals.inp) result.inp = globalWebVitals.inp;\n  return result;\n}\n\ninterface EnhancedResourceData {\n  name: string;\n  initiator_type: string;\n  total_duration: number;\n  initial_requests: number;\n  dynamic_requests: number;\n  transfer_size: number;\n  decoded_body_size: number;\n  domain: string;\n  first_start_time: number;\n  last_start_time: number;\n  time_since_load: number;\n  primary_phase: 'initial' | 'dynamic';\n  spans_both_phases: boolean;\n}\n\nfunction classifyResourcePhase(resource: EnhancedResourceData): 'initial' | 'dynamic' {\n  const totalRequests = resource.initial_requests + resource.dynamic_requests;\n  \n  // Use centralized classification logic\n  const phase = centralClassifyResourcePhase({\n    initiator_type: resource.initiator_type,\n    name: resource.name,\n    duplicate_count: totalRequests > 1 ? totalRequests : undefined,\n    initial_requests: resource.initial_requests,\n    dynamic_requests: resource.dynamic_requests\n  });\n  \n  return phase;\n}\n\nfunction selectRepresentativeResources(resourceMap: Record<string, EnhancedResourceData>): Array<{\n  name: string;\n  initiator_type: string;\n  duration: number;\n  duplicate_count?: number;\n  initial_hits?: number;\n  dynamic_hits?: number;\n  transfer_size?: number;\n  decoded_body_size?: number;\n  domain?: string;\n  time_since_load?: number;\n  is_async?: boolean;\n}> {\n  const allResources = Object.values(resourceMap);\n  \n  // Classify each resource's primary phase\n  for (const resource of allResources) {\n    resource.primary_phase = classifyResourcePhase(resource);\n    resource.spans_both_phases = resource.initial_requests > 0 && resource.dynamic_requests > 0;\n  }\n  \n  // Group by initiator type and phase\n  type ResourceData = EnhancedResourceData;\n  const byTypeAndPhase: Record<string, { initial: ResourceData[], dynamic: ResourceData[] }> = {};\n  \n  for (const resource of allResources) {\n    const type = resource.initiator_type;\n    if (!byTypeAndPhase[type]) {\n      byTypeAndPhase[type] = { initial: [], dynamic: [] };\n    }\n    \n    if (resource.primary_phase === 'dynamic') {\n      byTypeAndPhase[type].dynamic.push(resource);\n    } else {\n      byTypeAndPhase[type].initial.push(resource);\n    }\n  }\n  \n  // Sort each group by duration (slowest first)\n  for (const type in byTypeAndPhase) {\n    byTypeAndPhase[type].initial.sort((a, b) => b.total_duration - a.total_duration);\n    byTypeAndPhase[type].dynamic.sort((a, b) => b.total_duration - a.total_duration);\n  }\n  \n  const selected: ResourceData[] = [];\n  \n  // Define resource type importance and sampling limits\n  const resourceTypeConfig: Record<string, { initial: number, dynamic: number }> = {\n    // Usual suspects - often slow, capture more\n    'fetch': { initial: 2, dynamic: 5 },           // API calls\n    'xmlhttprequest': { initial: 2, dynamic: 5 },  // API calls\n    'script': { initial: 3, dynamic: 3 },          // JavaScript\n    'img': { initial: 2, dynamic: 2 },             // Images\n    \n    // Critical but often fast - ensure representation\n    'stylesheet': { initial: 2, dynamic: 1 },      // CSS files\n    'link': { initial: 2, dynamic: 1 },            // Fonts, preloads\n    'font': { initial: 2, dynamic: 1 },            // Web fonts\n    \n    // Less common but important to track\n    'navigation': { initial: 1, dynamic: 0 },      // Main document\n    'other': { initial: 1, dynamic: 1 },           // Miscellaneous\n  };\n  \n  // Sample resources according to strategy\n  for (const [type, limits] of Object.entries(resourceTypeConfig)) {\n    const groups = byTypeAndPhase[type];\n    if (!groups) continue;\n    \n    // Take initial rendering resources\n    if (groups.initial.length > 0) {\n      const count = Math.min(limits.initial, groups.initial.length);\n      selected.push(...groups.initial.slice(0, count));\n    }\n    \n    // Take dynamic resources\n    if (groups.dynamic.length > 0) {\n      const count = Math.min(limits.dynamic, groups.dynamic.length);\n      selected.push(...groups.dynamic.slice(0, count));\n    }\n  }\n  \n  // Handle any unknown resource types (capture at least 1)\n  for (const [type, groups] of Object.entries(byTypeAndPhase)) {\n    if (!resourceTypeConfig[type]) {\n      // Unknown type - take 1 from each phase if available\n      if (groups.initial.length > 0) selected.push(groups.initial[0]);\n      if (groups.dynamic.length > 0) selected.push(groups.dynamic[0]);\n    }\n  }\n  \n  // Ensure we include zero-duration resources if we haven't hit type diversity targets\n  // This handles heavily cached pages where CSS/fonts have 0ms duration\n  if (selected.length < 15) { // If we don't have enough diversity\n    const missingTypes = ['stylesheet', 'navigation', 'img', 'font'];\n    \n    for (const missingType of missingTypes) {\n      const hasType = selected.some(r => r.initiator_type === missingType);\n      if (!hasType && byTypeAndPhase[missingType]) {\n        // Add the fastest (possibly 0ms) resource of this missing type\n        const initialResources = byTypeAndPhase[missingType].initial;\n        const dynamicResources = byTypeAndPhase[missingType].dynamic;\n        \n        if (initialResources.length > 0) {\n          selected.push(initialResources[initialResources.length - 1]); // Take slowest of fast ones\n        } else if (dynamicResources.length > 0) {\n          selected.push(dynamicResources[dynamicResources.length - 1]);\n        }\n      }\n    }\n  }\n\n  // Sort final selection by total duration and apply reasonable limit\n  return selected\n    .sort((a, b) => b.total_duration - a.total_duration)\n    .slice(0, 35) // Increased from 10 to 35 for better coverage\n    .map(r => {\n      const totalRequests = r.initial_requests + r.dynamic_requests;\n      const result: {\n        name: string;\n        initiator_type: string;\n        duration: number;\n        duplicate_count?: number;\n        initial_hits?: number;\n        dynamic_hits?: number;\n        transfer_size?: number;\n        decoded_body_size?: number;\n        domain?: string;\n        time_since_load?: number;\n        is_async?: boolean;\n      } = {\n        name: r.name,\n        initiator_type: r.initiator_type,\n        duration: Math.round(r.total_duration / totalRequests),\n        transfer_size: Math.round(r.transfer_size / totalRequests),\n        decoded_body_size: Math.round(r.decoded_body_size / totalRequests),\n        domain: r.domain,\n        time_since_load: r.time_since_load,\n        is_async: r.primary_phase === 'dynamic'\n      };\n      \n      // Add duplicate tracking for resources with multiple hits\n      if (totalRequests > 1) {\n        result.duplicate_count = totalRequests;\n        result.initial_hits = r.initial_requests;\n        result.dynamic_hits = r.dynamic_requests;\n      }\n      \n      return result;\n    });\n}\n\nexport function collectPerfMetrics(): FlattenedPageMetrics | null {\n  if (typeof window === \"undefined\" || !window.performance) return null;\n\n  const navigation = window.performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming | undefined;\n  if (!navigation) return null;\n\n  const resources = window.performance.getEntriesByType('resource') as PerformanceResourceTiming[];\n\n  const totalSizeBytes = resources.reduce(\n    (sum, r) => sum + (r.transferSize || r.encodedBodySize || r.decodedBodySize || 0), 0\n  );\n\n  const webVitals = Object.keys(globalWebVitals).length > 0\n    ? globalWebVitals\n    : getWebVitalsFromPerformanceAPI();\n\n  const dnsLookup = navigation.domainLookupEnd > 0 && navigation.domainLookupStart > 0\n    ? Math.round(navigation.domainLookupEnd - navigation.domainLookupStart) : undefined;\n  const tcpConnect = navigation.connectEnd > 0 && navigation.connectStart > 0\n    ? Math.round(navigation.connectEnd - navigation.connectStart) : undefined;\n  \n  // Calculate timing values, only include them if valid\n  const rawTtfb = navigation.responseStart - navigation.requestStart;\n  const rawHtmlResponse = navigation.responseEnd - navigation.responseStart;\n  const rawTotalPageLoad = navigation.loadEventEnd - navigation.fetchStart;\n  const rawFrontendRender = navigation.loadEventEnd - navigation.responseStart;\n  \n  // Only include timing values if they're valid (positive)\n  const ttfb = rawTtfb >= 0 ? Math.round(rawTtfb) : undefined;\n  const htmlResponse = rawHtmlResponse >= 0 ? Math.round(rawHtmlResponse) : undefined;\n  const totalPageLoad = rawTotalPageLoad >= 0 ? Math.round(rawTotalPageLoad) : undefined;\n  \n  let frontendRender: number | undefined;\n  if (rawFrontendRender >= 0) {\n    frontendRender = Math.round(rawFrontendRender);\n    // Validate frontend render against other timing values if available\n    if (ttfb !== undefined && htmlResponse !== undefined && totalPageLoad !== undefined) {\n      const maxFrontendRender = totalPageLoad - ttfb - htmlResponse;\n      if (frontendRender > maxFrontendRender) {\n        frontendRender = Math.max(0, maxFrontendRender);\n      }\n    }\n  }\n  \n\n  const asyncResources = resources.filter(r => r.startTime > navigation.loadEventEnd);\n\n  // Calculate async timeline using utility function with 60-second page scope\n  const asyncTiming = calculateAsyncWindow(asyncResources, navigation.loadEventEnd, 60000);\n  const asyncTimelineStart = asyncTiming.start;\n  const asyncTimelineEnd = asyncTiming.end;\n  const asyncTimelineWindow = asyncTiming.window;\n\n  // Build enhanced resource map with separate initial/dynamic tracking\n  const resourceMap: Record<string, EnhancedResourceData> = {};\n\n  // Separate API calls from other async resources (within 60-second window)\n  const asyncApiResources = asyncResources.filter(r => \n    (r.initiatorType === 'fetch' || r.initiatorType === 'xmlhttprequest') &&\n    r.startTime <= navigation.loadEventEnd + 60000\n  );\n  const asyncNonApiResources = asyncResources.filter(r => \n    r.initiatorType !== 'fetch' && r.initiatorType !== 'xmlhttprequest' &&\n    r.startTime <= navigation.loadEventEnd + 60000\n  );\n\n  // Compute async API details\n  const asyncApiDomains: Record<string, { count: number; totalDuration: number }> = {};\n  const asyncApiEndpointsMap: Record<string, { duration: number; count: number }> = {};\n  let asyncApiSlowest: { url: string; duration: number; domain: string } | undefined;\n\n  for (const r of asyncApiResources) {\n    const duration = Math.round(r.responseEnd - r.startTime);\n    const url = r.name.split('?')[0];\n    const domain = new URL(r.name).hostname;\n\n    // Track domains\n    if (!asyncApiDomains[domain]) {\n      asyncApiDomains[domain] = { count: 0, totalDuration: 0 };\n    }\n    asyncApiDomains[domain].count += 1;\n    asyncApiDomains[domain].totalDuration += duration;\n\n    // Track endpoints\n    if (!asyncApiEndpointsMap[url]) {\n      asyncApiEndpointsMap[url] = { duration: 0, count: 0 };\n    }\n    asyncApiEndpointsMap[url].duration += duration;\n    asyncApiEndpointsMap[url].count += 1;\n\n    // Track slowest\n    if (!asyncApiSlowest || duration > asyncApiSlowest.duration) {\n      asyncApiSlowest = { url, duration, domain };\n    }\n  }\n\n  const asyncApiCount = asyncApiResources.length;\n  const apiTiming = calculateAsyncWindow(asyncApiResources, navigation.loadEventEnd, 60000);\n  const asyncApiEnd = apiTiming.duration;\n\n  // Calculate API parallelism efficiency\n  let asyncApiParallelism: number | undefined;\n  if (asyncApiCount > 0 && asyncApiEnd && asyncApiEnd > 0) {\n    const medianApiTime = asyncApiResources.length > 0\n      ? asyncApiResources\n          .map(r => r.responseEnd - r.startTime)\n          .sort((a, b) => a - b)[Math.floor(asyncApiResources.length / 2)]\n      : 0;\n    if (medianApiTime > 0) {\n      asyncApiParallelism = Math.round((asyncApiCount / (asyncApiEnd / medianApiTime)) * 100) / 100;\n    }\n  }\n\n  const asyncApiSlowestEndpoints = Object.entries(asyncApiEndpointsMap)\n    .map(([url, data]) => ({\n      url,\n      duration: Math.round(data.duration / data.count),\n      count: data.count\n    }))\n    .sort((a, b) => b.duration - a.duration)\n    .slice(0, 10);\n\n  // Compute async asset details (non-API async loads)\n  const asyncAssetByType: Record<string, { count: number; totalDuration: number }> = {};\n  let asyncAssetDuration = 0;\n\n  for (const r of asyncNonApiResources) {\n    const duration = Math.round(r.responseEnd - r.startTime);\n    const type = r.initiatorType || 'other';\n    \n    if (!asyncAssetByType[type]) {\n      asyncAssetByType[type] = { count: 0, totalDuration: 0 };\n    }\n    asyncAssetByType[type].count += 1;\n    asyncAssetByType[type].totalDuration += duration;\n    asyncAssetDuration += duration;\n  }\n\n  const asyncAssetCount = asyncNonApiResources.length;\n  const asyncAssetSlowest = asyncNonApiResources\n    .sort((a, b) => (b.responseEnd - b.startTime) - (a.responseEnd - a.startTime))\n    .slice(0, 5)\n    .map(r => ({\n      name: r.name.split('?')[0],\n      initiator_type: r.initiatorType,\n      duration: Math.round(r.responseEnd - r.startTime)\n    }));\n  \n  for (const r of resources) {\n    const url = r.name.split('?')[0];\n    const domain = new URL(r.name).hostname;\n    const duration = Math.round(r.responseEnd - r.startTime);\n    const timeSinceLoad = Math.round(r.startTime - navigation.loadEventEnd);\n    const key = url;\n    \n    // Skip resources that fall outside our page-scoped window (after 60 seconds)\n    if (r.startTime > navigation.loadEventEnd + 60000) {\n      continue;\n    }\n    \n    // Determine if this specific request is during initial load or dynamic\n    const isInitialRequest = r.startTime <= navigation.loadEventEnd + 1000; // 1s buffer for initial phase\n\n    if (!resourceMap[key]) {\n      resourceMap[key] = {\n        name: url,\n        initiator_type: r.initiatorType,\n        total_duration: 0,\n        initial_requests: 0,\n        dynamic_requests: 0,\n        transfer_size: 0,\n        decoded_body_size: 0,\n        domain,\n        first_start_time: r.startTime,\n        last_start_time: r.startTime,\n        time_since_load: timeSinceLoad,\n        primary_phase: 'initial', // Will be determined later\n        spans_both_phases: false,\n      };\n    }\n\n    const rec = resourceMap[key];\n    \n    // Track separate counters for initial vs dynamic requests\n    if (isInitialRequest) {\n      rec.initial_requests += 1;\n    } else {\n      rec.dynamic_requests += 1;\n    }\n    \n    // Update timing information\n    rec.first_start_time = Math.min(rec.first_start_time, r.startTime);\n    rec.last_start_time = Math.max(rec.last_start_time, r.startTime);\n    \n    // Accumulate duration and size data\n    rec.total_duration += duration;\n    rec.transfer_size += r.transferSize || 0;\n    rec.decoded_body_size += r.decodedBodySize || 0;\n  }\n\n  // Smart resource selection to ensure type diversity\n  const selectedResources = selectRepresentativeResources(resourceMap);\n  \n  // selectedResources already contains the properly formatted data with enhanced tracking\n  const topResources = selectedResources;\n\n  return {\n    page: window.location.pathname,\n    dns_lookup: dnsLookup,\n    tcp_connect: tcpConnect,\n    ttfb,\n    html_response: htmlResponse,\n    frontend_render: frontendRender,\n    total_page_load: totalPageLoad,\n    lcp: webVitals.lcp,\n    cls: webVitals.cls,\n    inp: webVitals.inp,\n    num_requests: resources.length,\n    total_size_kb: Math.round((totalSizeBytes / 1024) * 10) / 10,\n    performance_grade: calculatePerformanceGrade({\n      total_page_load: totalPageLoad,\n      lcp: webVitals.lcp,\n      cls: webVitals.cls,\n      inp: webVitals.inp\n    }),\n    top_resources: topResources,\n    // Timeline positioning (relative to page load completion)\n    async_timeline_start: asyncTimelineStart,\n    async_timeline_end: asyncTimelineEnd,\n    async_timeline_window: asyncTimelineWindow,\n    // API timeline and analysis\n    async_api_end: asyncApiEnd,\n    async_api_count: asyncApiCount > 0 ? asyncApiCount : undefined,\n    async_api_parallelism: asyncApiParallelism,\n    async_api_domains: asyncApiCount > 0 ? asyncApiDomains : undefined,\n    async_api_slowest_endpoints: asyncApiSlowestEndpoints.length > 0 ? asyncApiSlowestEndpoints : undefined,\n    async_api_slowest: asyncApiSlowest,\n    // Asset analysis (non-API resources)\n    async_asset_duration: asyncAssetCount > 0 ? asyncAssetDuration : undefined,\n    async_asset_count: asyncAssetCount > 0 ? asyncAssetCount : undefined,\n    async_asset_by_type: asyncAssetCount > 0 ? asyncAssetByType : undefined,\n    async_asset_slowest: asyncAssetSlowest.length > 0 ? asyncAssetSlowest : undefined,\n    timestamp: new Date().toISOString(),\n  };\n}\n\n","{\n  \"name\": \"@jillen/analytics\",\n  \"version\": \"5.0.0\",\n  \"description\": \"Lightweight human-visit and Web Vitals analytics for React apps. Framework-agnostic core with a Next.js adapter.\",\n  \"main\": \"./dist/index.js\",\n  \"module\": \"./dist/index.mjs\",\n  \"types\": \"./dist/index.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"types\": \"./dist/index.d.ts\",\n      \"import\": \"./dist/index.mjs\",\n      \"require\": \"./dist/index.js\"\n    },\n    \"./next\": {\n      \"types\": \"./dist/next.d.ts\",\n      \"import\": \"./dist/next.mjs\",\n      \"require\": \"./dist/next.js\"\n    }\n  },\n  \"files\": [\n    \"dist\",\n    \"README.md\",\n    \"CHANGELOG.md\",\n    \"LICENSE\"\n  ],\n  \"scripts\": {\n    \"build\": \"tsup\",\n    \"dev\": \"tsup --watch\",\n    \"clean\": \"rm -rf dist\",\n    \"prepublishOnly\": \"npm run clean && npm run build\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [\n    \"analytics\",\n    \"tracking\",\n    \"web-analytics\",\n    \"web-vitals\",\n    \"react\",\n    \"nextjs\",\n    \"vite\",\n    \"typescript\"\n  ],\n  \"author\": \"Jillen\",\n  \"license\": \"MIT\",\n  \"peerDependencies\": {\n    \"next\": \">=13.0.0\",\n    \"react\": \">=18.0.0\"\n  },\n  \"peerDependenciesMeta\": {\n    \"next\": {\n      \"optional\": true\n    }\n  },\n  \"dependencies\": {\n    \"isbot\": \"^5.1.31\",\n    \"web-vitals\": \"^5.1.0\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.19.23\",\n    \"@types/react\": \"^19.2.2\",\n    \"tsup\": \"^8.5.0\",\n    \"typescript\": \"^5.9.3\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/jillen/analytics.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/jillen/analytics/issues\"\n  },\n  \"homepage\": \"https://github.com/jillen/analytics#readme\"\n}\n","import packageJson from \"../package.json\";\n\nexport const sdk_version = packageJson.version;\n","import type { BaseHumanEvent, PerformanceEvent } from \"./event-types\";\nimport { sdk_version } from \"./version\";\n\n/**\n * Send analytics event using standard fetch with timeout\n */\nexport async function sendHumanEvent(payload: BaseHumanEvent): Promise<void> {\n  const endpoint = \"https://analytics.jillen.com/api/human\";\n  const payloadWithVersion: BaseHumanEvent = {\n    ...payload,\n    sdk_version,\n  };\n  const data = JSON.stringify(payloadWithVersion);\n\n  try {\n    const controller = new AbortController();\n    const timeoutId = setTimeout(() => controller.abort(), 30000);\n\n    const response = await fetch(endpoint, {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      },\n      mode: \"cors\",\n      body: data,\n      signal: controller.signal,\n    });\n\n    clearTimeout(timeoutId);\n\n    if (!response.ok) {\n      console.error(\n        `[Analytics] Server endpoint error: ${response.status} ${response.statusText} - human event failed`\n      );\n      return;\n    }\n  } catch (error) {\n    if (error instanceof TypeError) {\n      if (error.message.includes(\"fetch failed\") || error.message.includes(\"network\")) {\n        console.error(\"[Analytics] Network connectivity error in human event:\", error.message);\n      } else {\n        console.error(\"[Analytics] Request configuration error in human event:\", error.message);\n      }\n    } else if (error instanceof DOMException && error.name === \"AbortError\") {\n      console.error(\"[Analytics] Human event request timeout after 30 seconds\");\n    } else if (error instanceof Error) {\n      console.error(\"[Analytics] Human event error:\", error.name, error.message);\n    } else {\n      console.error(\"[Analytics] Unknown error in human event:\", error);\n    }\n    // Silent fail - never break the application\n    return;\n  }\n}\n\n/**\n * Send performance metrics using standard fetch with timeout\n */\nexport async function sendPerformanceEvent(payload: PerformanceEvent): Promise<void> {\n  const endpoint = \"https://analytics.jillen.com/api/perf\";\n  const payloadWithVersion: PerformanceEvent = {\n    ...payload,\n    sdk_version,\n  };\n  const data = JSON.stringify(payloadWithVersion);\n\n  try {\n    const controller = new AbortController();\n    const timeoutId = setTimeout(() => controller.abort(), 30000);\n\n    const response = await fetch(endpoint, {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n      },\n      mode: \"cors\",\n      body: data,\n      signal: controller.signal,\n    });\n\n    clearTimeout(timeoutId);\n\n    if (!response.ok) {\n      console.error(\n        `[Performance] Server endpoint error: ${response.status} ${response.statusText} - performance event failed`\n      );\n      return;\n    }\n  } catch (error) {\n    if (error instanceof TypeError) {\n      if (error.message.includes(\"fetch failed\") || error.message.includes(\"network\")) {\n        console.error(\n          \"[Performance] Network connectivity error in performance event:\",\n          error.message\n        );\n      } else {\n        console.error(\n          \"[Performance] Request configuration error in performance event:\",\n          error.message\n        );\n      }\n    } else if (error instanceof DOMException && error.name === \"AbortError\") {\n      console.error(\"[Performance] Performance event request timeout after 30 seconds\");\n    } else if (error instanceof Error) {\n      console.error(\"[Performance] Performance event error:\", error.name, error.message);\n    } else {\n      console.error(\"[Performance] Unknown error in performance event:\", error);\n    }\n    // Silent fail - never break the application\n    return;\n  }\n}\n","interface StorageItem<T> {\n  value: T;\n  expiry: number;\n}\n\nconst ANALYTICS_STORAGE_PREFIX = \"analytics_\";\n\nconst DEFAULT_TTL = {\n  VISITOR: 30 * 24 * 60 * 60 * 1000,\n} as const;\n\nexport class AnalyticsStorage {\n  private static isClient = typeof window !== \"undefined\";\n\n  static setItem<T>(\n    key: string,\n    value: T,\n    ttlMs: number = DEFAULT_TTL.VISITOR\n  ): boolean {\n    if (!this.isClient) return false;\n\n    try {\n      const item: StorageItem<T> = {\n        value,\n        expiry: Date.now() + ttlMs,\n      };\n      localStorage.setItem(\n        `${ANALYTICS_STORAGE_PREFIX}${key}`,\n        JSON.stringify(item)\n      );\n      return true;\n    } catch (error) {\n      console.warn(\"[Analytics] Failed to set localStorage item:\", error);\n      return false;\n    }\n  }\n\n  static getItem<T>(key: string): T | null {\n    if (!this.isClient) return null;\n\n    try {\n      const itemStr = localStorage.getItem(`${ANALYTICS_STORAGE_PREFIX}${key}`);\n      if (!itemStr) return null;\n\n      const item: StorageItem<T> = JSON.parse(itemStr);\n\n      if (Date.now() > item.expiry) {\n        localStorage.removeItem(`${ANALYTICS_STORAGE_PREFIX}${key}`);\n        return null;\n      }\n\n      return item.value;\n    } catch (error) {\n      console.warn(\"[Analytics] Failed to get localStorage item:\", error);\n      return null;\n    }\n  }\n\n  static removeItem(key: string): void {\n    if (!this.isClient) return;\n\n    try {\n      localStorage.removeItem(`${ANALYTICS_STORAGE_PREFIX}${key}`);\n    } catch (error) {\n      console.warn(\"[Analytics] Failed to remove localStorage item:\", error);\n    }\n  }\n\n  static setVisitor(visitorId: string): boolean {\n    return this.setItem(\n      `visitor_${visitorId}`,\n      Date.now(),\n      DEFAULT_TTL.VISITOR\n    );\n  }\n\n  static hasVisitor(visitorId: string): boolean {\n    return this.getItem<number>(`visitor_${visitorId}`) !== null;\n  }\n\n  static cleanupOldSessionEntries(): number {\n    if (!this.isClient) return 0;\n\n    let cleanedCount = 0;\n    const obsoletePrefixes = [\n      `${ANALYTICS_STORAGE_PREFIX}session_start_`,\n      `${ANALYTICS_STORAGE_PREFIX}session_active_`,\n    ];\n\n    try {\n      const keys = Object.keys(localStorage);\n\n      for (const key of keys) {\n        for (const prefix of obsoletePrefixes) {\n          if (key.startsWith(prefix)) {\n            localStorage.removeItem(key);\n            cleanedCount++;\n            break;\n          }\n        }\n      }\n    } catch (error) {\n      console.warn(\"[Analytics] Failed to cleanup old session entries:\", error);\n    }\n\n    return cleanedCount;\n  }\n\n  static cleanupExpiredItems(): number {\n    if (!this.isClient) return 0;\n\n    let cleanedCount = 0;\n\n    try {\n      const keys = Object.keys(localStorage);\n      const now = Date.now();\n\n      for (const key of keys) {\n        if (!key.startsWith(ANALYTICS_STORAGE_PREFIX)) continue;\n\n        try {\n          const itemStr = localStorage.getItem(key);\n          if (!itemStr) continue;\n\n          const item = JSON.parse(itemStr);\n          if (item.expiry && now > item.expiry) {\n            localStorage.removeItem(key);\n            cleanedCount++;\n          }\n        } catch {\n          localStorage.removeItem(key);\n          cleanedCount++;\n        }\n      }\n    } catch (error) {\n      console.warn(\"[Analytics] Failed to cleanup expired items:\", error);\n    }\n\n    return cleanedCount;\n  }\n\n  static migrateOldFormat(): number {\n    if (!this.isClient) return 0;\n\n    let migratedCount = 0;\n    const oldPrefixes = [\n      \"analytics_visitor_\",\n      \"analytics_session_start_\",\n      \"analytics_session_active_\",\n    ];\n\n    try {\n      const keys = Object.keys(localStorage);\n\n      for (const key of keys) {\n        for (const prefix of oldPrefixes) {\n          if (key.startsWith(prefix)) {\n            const value = localStorage.getItem(key);\n            if (value && !value.includes('\"expiry\":')) {\n              localStorage.removeItem(key);\n              migratedCount++;\n\n              const keyParts = key.replace(prefix, \"\").split(\"_\");\n              if (prefix === \"analytics_visitor_\" && keyParts.length > 0) {\n                const timestamp = parseInt(value);\n                if (\n                  !isNaN(timestamp) &&\n                  Date.now() - timestamp < DEFAULT_TTL.VISITOR\n                ) {\n                  this.setVisitor(keyParts.join(\"_\"));\n                }\n              }\n            }\n          }\n        }\n      }\n    } catch (error) {\n      console.warn(\"[Analytics] Failed to migrate old format:\", error);\n    }\n\n    return migratedCount;\n  }\n\n  static getStorageSize(): { count: number; sizeBytes: number } {\n    if (!this.isClient) return { count: 0, sizeBytes: 0 };\n\n    let count = 0;\n    let sizeBytes = 0;\n\n    try {\n      const keys = Object.keys(localStorage);\n\n      for (const key of keys) {\n        if (key.startsWith(ANALYTICS_STORAGE_PREFIX)) {\n          count++;\n          const value = localStorage.getItem(key) || \"\";\n          sizeBytes += key.length + value.length;\n        }\n      }\n    } catch (error) {\n      console.warn(\"[Analytics] Failed to calculate storage size:\", error);\n    }\n\n    return { count, sizeBytes };\n  }\n}\n\nexport class AnalyticsSessionStorage {\n  private static isClient = typeof window !== \"undefined\";\n\n  static setItem<T>(key: string, value: T): boolean {\n    if (!this.isClient) return false;\n\n    try {\n      sessionStorage.setItem(\n        `${ANALYTICS_STORAGE_PREFIX}${key}`,\n        JSON.stringify(value)\n      );\n      return true;\n    } catch (error) {\n      console.warn(\"[Analytics] Failed to set sessionStorage item:\", error);\n      return false;\n    }\n  }\n\n  static getItem<T>(key: string): T | null {\n    if (!this.isClient) return null;\n\n    try {\n      const itemStr = sessionStorage.getItem(\n        `${ANALYTICS_STORAGE_PREFIX}${key}`\n      );\n      if (!itemStr) return null;\n\n      return JSON.parse(itemStr);\n    } catch (error) {\n      console.warn(\"[Analytics] Failed to get sessionStorage item:\", error);\n      return null;\n    }\n  }\n\n  static removeItem(key: string): void {\n    if (!this.isClient) return;\n\n    try {\n      sessionStorage.removeItem(`${ANALYTICS_STORAGE_PREFIX}${key}`);\n    } catch (error) {\n      console.warn(\"[Analytics] Failed to remove sessionStorage item:\", error);\n    }\n  }\n}","\"use client\";\n\nimport { isbot } from \"isbot\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport type { BaseHumanEvent, PerformanceEvent } from \"./event-types\";\nimport { getSiteIdWithFallback } from \"./analytics-host-utils\";\nimport { collectPerfMetrics } from \"./performance-collector\";\nimport { sendHumanEvent, sendPerformanceEvent } from \"./send\";\nimport { AnalyticsSessionStorage, AnalyticsStorage } from \"./storage-utils\";\n\ninterface SessionData {\n  session_id: string;\n  last_activity: number;\n}\n\nfunction generateVisitorId(username?: string | null): string {\n  // For authenticated users, use username-based ID\n  if (username && username.trim() !== \"\") {\n    const cleanUsername =\n      username\n        .trim()\n        .toLowerCase()\n        .replace(/\\s+/g, \"-\")\n        .replace(/[^a-z0-9-]/g, \"\")\n        .replace(/-+/g, \"-\")\n        .replace(/^-+|-+$/g, \"\")\n        .substring(0, 50) || \"unknown-user\";\n\n    // Store the username-based ID\n    AnalyticsStorage.setItem(\"visitor_id\", cleanUsername);\n    return cleanUsername;\n  }\n\n  // For anonymous users, check if we have a stored fingerprint-based ID\n  const stored = AnalyticsStorage.getItem<string>(\"visitor_id\");\n  if (stored && !stored.includes(\"@\") && stored !== \"unknown-user\") {\n    return stored;\n  }\n\n  // Generate new fingerprint-based ID for anonymous users\n  const fingerprint = [\n    navigator.userAgent || \"unknown\",\n    navigator.language || \"unknown\",\n    `${screen.width}x${screen.height}`,\n    (navigator as Navigator & { hardwareConcurrency?: number })\n      .hardwareConcurrency || \"unknown\",\n    Intl.DateTimeFormat().resolvedOptions().timeZone || \"unknown\",\n  ].join(\"|\");\n\n  let hash = 0;\n  for (let i = 0; i < fingerprint.length; i++) {\n    const char = fingerprint.charCodeAt(i);\n    hash = (hash << 5) - hash + char;\n    hash = hash & hash;\n  }\n\n  const visitorId = Math.abs(hash).toString(36);\n  AnalyticsStorage.setItem(\"visitor_id\", visitorId);\n  return visitorId;\n}\n\nfunction generateSessionId(): { sessionId: string; isNewSession: boolean } {\n  if (typeof window !== \"undefined\") {\n    const sessionData =\n      AnalyticsSessionStorage.getItem<SessionData>(\"session_data\");\n\n    if (sessionData?.session_id) {\n      const now = Date.now();\n      const timeSinceActivity = now - sessionData.last_activity;\n      const SESSION_TIMEOUT = 30 * 60 * 1000;\n\n      if (timeSinceActivity < SESSION_TIMEOUT) {\n        return { sessionId: sessionData.session_id, isNewSession: false };\n      }\n\n      AnalyticsSessionStorage.removeItem(\"session_data\");\n    }\n  }\n\n  const generateLightweightId = (): string => {\n    try {\n      const array = new Uint8Array(4);\n      crypto.getRandomValues(array);\n\n      const timestamp = Date.now().toString(36).slice(-4);\n      const randomPart = Array.from(array)\n        .map((byte) => byte.toString(36))\n        .join(\"\")\n        .slice(0, 4);\n\n      return `${timestamp}${randomPart}`.substring(0, 8);\n    } catch {\n      const timestamp = Date.now().toString(36).slice(-4);\n      const randomPart = Math.random().toString(36).substring(2, 6);\n      return `${timestamp}${randomPart}`.substring(0, 8);\n    }\n  };\n\n  const newSessionId = generateLightweightId();\n  const now = Date.now();\n\n  // Store new session in sessionStorage\n  if (typeof window !== \"undefined\") {\n    AnalyticsSessionStorage.setItem(\"session_data\", {\n      session_id: newSessionId,\n      last_activity: now,\n    });\n  }\n\n  return { sessionId: newSessionId, isNewSession: true };\n}\n\nfunction getClientData(username?: string | null) {\n  if (typeof window === \"undefined\") {\n    return {\n      isNewVisitor: true,\n      screenResolution: null,\n      viewportSize: null,\n      connectionType: null,\n      clientTimeZone: null,\n      sessionStartTime: new Date().toISOString(),\n      isNewSession: true,\n    };\n  }\n\n  const visitorId = generateVisitorId(username);\n  const { sessionId, isNewSession } = generateSessionId();\n  let isNewVisitor: boolean;\n\n  if (username && username.trim() !== \"\") {\n    isNewVisitor = false;\n  } else {\n    const visitorCacheKey = `isNewVisitor_${visitorId}`;\n\n    const cachedIsNewVisitor =\n      AnalyticsSessionStorage.getItem<boolean>(visitorCacheKey);\n\n    if (cachedIsNewVisitor === null) {\n      const visitorExists = AnalyticsStorage.hasVisitor(visitorId);\n      isNewVisitor = !visitorExists;\n\n      AnalyticsSessionStorage.setItem(visitorCacheKey, isNewVisitor);\n\n      if (isNewVisitor) {\n        AnalyticsStorage.setVisitor(visitorId);\n      }\n    } else {\n      isNewVisitor = cachedIsNewVisitor;\n    }\n  }\n\n  let sessionStartTime = AnalyticsSessionStorage.getItem<string>(\n    `session_start_${sessionId}`\n  );\n  if (!sessionStartTime) {\n    sessionStartTime = new Date().toISOString();\n    AnalyticsSessionStorage.setItem(\n      `session_start_${sessionId}`,\n      sessionStartTime\n    );\n  }\n\n  const screenResolution = `${screen.width}x${screen.height}`;\n  const viewportSize = `${window.innerWidth}x${window.innerHeight}`;\n\n  const isMobile = /Mobile|Android|iPhone|iPad/.test(navigator.userAgent);\n  const connectionType = isMobile ? \"mobile\" : \"desktop\";\n\n  const clientTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n  return {\n    isNewVisitor,\n    screenResolution,\n    viewportSize,\n    connectionType,\n    clientTimeZone,\n    sessionStartTime,\n    isNewSession,\n  };\n}\n\nexport interface VisitorTrackerProps {\n  username?: string | null;\n  /**\n   * Current route pathname. Required — pass from your router:\n   *\n   *   • Next.js:        `usePathname()` from `next/navigation`\n   *                     (or use the `@jillen/analytics/next` adapter,\n   *                     which wires this for you).\n   *   • React Router:   `useLocation().pathname`\n   *   • TanStack Router: `useRouterState({ select: s => s.location.pathname })`\n   *   • Astro / vanilla: `window.location.pathname` and re-render on\n   *                     route change.\n   */\n  pathname: string;\n}\n\nexport function VisitorTracker({\n  username,\n  pathname: rawPathname,\n}: VisitorTrackerProps) {\n  // Runtime guard for JS callers who skip TypeScript. We always run the\n  // hooks below (Rules of Hooks) but no-op the side-effects when the\n  // pathname prop isn't a string.\n  const pathnameInvalid = typeof rawPathname !== \"string\";\n  const pathname = pathnameInvalid ? \"\" : rawPathname;\n  const warnedRef = useRef<boolean>(false);\n  useEffect(() => {\n    if (pathnameInvalid && !warnedRef.current && typeof window !== \"undefined\") {\n      warnedRef.current = true;\n      console.error(\n        \"[Analytics] VisitorTracker requires a `pathname` prop. \" +\n          \"For Next.js, import from '@jillen/analytics/next' (auto-pathname). \" +\n          \"For other routers, pass `pathname` from your router state \" +\n          \"(e.g. `useLocation().pathname` from react-router-dom).\"\n      );\n    }\n  }, [pathnameInvalid]);\n\n  const isInitialized = useRef<boolean>(false);\n  const lastTrackedPath = useRef<string>(pathname);\n  const heartbeatInterval = useRef<NodeJS.Timeout | undefined>(undefined);\n  const heartbeatEnabled = useRef<boolean>(true);\n  const currentInterval = useRef<number>(15000); // Start with 15s\n  const isActive = useRef<boolean>(true);\n\n  // Track if we've already sent performance event for this page load\n  const perfEventSent = useRef<boolean>(false);\n\n  // Deduplication cache to prevent burst requests\n  const sentEventsCache = useRef<Map<string, number>>(new Map());\n  const DEDUPE_WINDOW_MS = 100; // 100ms deduplication window\n\n  const isBot = useCallback(() => {\n    if (typeof navigator !== \"undefined\" && isbot(navigator.userAgent)) {\n      return true;\n    }\n    return false;\n  }, []);\n\n  const updateLastActivity = useCallback(() => {\n    if (typeof window !== \"undefined\") {\n      const sessionData =\n        AnalyticsSessionStorage.getItem<SessionData>(\"session_data\");\n      if (sessionData) {\n        sessionData.last_activity = Date.now();\n        AnalyticsSessionStorage.setItem(\"session_data\", sessionData);\n      }\n    }\n  }, []);\n\n  const sendPerfEvent = useCallback(async () => {\n    // Performance events should only be sent once per page load\n    if (perfEventSent.current) {\n      return;\n    }\n\n    perfEventSent.current = true;\n\n    setTimeout(async () => {\n      try {\n        const siteId = getSiteIdWithFallback(window.location.hostname);\n        const visitorId = generateVisitorId(username);\n        const perfMetrics = collectPerfMetrics();\n\n        if (!perfMetrics) return;\n\n        // Skip performance tracking for analytics interface pages on analytics.jillen.com\n        if (\n          siteId === \"analytics.jillen.com\" &&\n          perfMetrics.page.includes(\"/performance/\")\n        ) {\n          return;\n        }\n\n        const payload: PerformanceEvent = {\n          ...perfMetrics,\n          website_domain: siteId,\n          visitor_id: visitorId,\n        };\n\n        await sendPerformanceEvent(payload);\n      } catch (error) {\n        console.error(\"[Performance] Error sending perf event:\", error);\n      }\n    }, 1000);\n  }, [username]);\n\n  const sendEvent = useCallback(\n    async (\n      eventType: \"pageview\" | \"session_start\" | \"heartbeat\",\n      referrer?: string\n    ) => {\n      if (process.env.NODE_ENV !== \"production\") {\n        return;\n      }\n\n      // Deduplication: Check if same event was sent recently\n      const siteId = getSiteIdWithFallback(window.location.hostname);\n      const { sessionId } = generateSessionId();\n      const dedupeKey = `${sessionId}_${eventType}_${pathname}`;\n      const now = Date.now();\n      const lastSent = sentEventsCache.current.get(dedupeKey);\n\n      if (lastSent && now - lastSent < DEDUPE_WINDOW_MS) {\n        // Skip duplicate event within deduplication window\n        return;\n      }\n\n      // Update cache with current timestamp\n      sentEventsCache.current.set(dedupeKey, now);\n\n      // Cleanup old entries to prevent memory leak (keep cache size bounded)\n      if (sentEventsCache.current.size > 50) {\n        const oldestKey = sentEventsCache.current.keys().next().value;\n        if (oldestKey) {\n          sentEventsCache.current.delete(oldestKey);\n        }\n      }\n\n      // Send performance data on pageview events (production only)\n      if (eventType === \"pageview\") {\n        sendPerfEvent();\n      }\n\n      try {\n        const clientData = getClientData(username);\n        const visitorId = generateVisitorId(username);\n\n        const payload: BaseHumanEvent = {\n          website_domain: siteId,\n          path: pathname,\n          visitor_id: visitorId,\n          session_id: sessionId,\n          event_type: eventType,\n          is_new_visitor: clientData.isNewVisitor,\n          screen_resolution: clientData.screenResolution,\n          viewport_size: clientData.viewportSize,\n          connection_type: clientData.connectionType,\n          client_time_zone: clientData.clientTimeZone,\n          session_start_time: clientData.sessionStartTime,\n          visitor_name: username ?? undefined,\n          referrer: referrer,\n        };\n\n        await sendHumanEvent(payload);\n      } catch (error) {\n        console.error(\"[Analytics] Error sending event:\", error);\n      }\n    },\n    [pathname, username, sendPerfEvent]\n  );\n\n  const scheduleNextHeartbeat = useCallback(() => {\n    if (!heartbeatEnabled.current || typeof window === \"undefined\") return;\n\n    if (heartbeatInterval.current) {\n      return;\n    }\n\n    heartbeatInterval.current = setTimeout(() => {\n      heartbeatInterval.current = undefined;\n\n      const sessionData =\n        AnalyticsSessionStorage.getItem<SessionData>(\"session_data\");\n      const timeSinceActivity = sessionData\n        ? Date.now() - sessionData.last_activity\n        : 0;\n\n      const inactivityThreshold = 2 * 60 * 1000; // 2 minutes\n      const SESSION_TIMEOUT = 30 * 60 * 1000; // 30 minutes\n\n      if (timeSinceActivity >= SESSION_TIMEOUT) {\n        heartbeatEnabled.current = false;\n        return;\n      }\n\n      if (timeSinceActivity < inactivityThreshold) {\n        sendEvent(\"heartbeat\");\n      }\n\n      // Dynamic interval progression: 15s, 60s, 5m, 15m\n      const intervals = [15000, 60000, 5 * 60 * 1000, 15 * 60 * 1000];\n      const currentIndex = intervals.indexOf(currentInterval.current);\n\n      if (currentIndex !== -1 && currentIndex < intervals.length - 1) {\n        currentInterval.current = intervals[currentIndex + 1];\n      }\n\n      scheduleNextHeartbeat();\n    }, currentInterval.current);\n  }, [sendEvent]);\n\n  const handleActivity = useCallback(() => {\n    const now = Date.now();\n    isActive.current = true;\n\n    const sessionData =\n      AnalyticsSessionStorage.getItem<SessionData>(\"session_data\");\n    const timeSinceActivity = sessionData\n      ? now - sessionData.last_activity\n      : Infinity;\n    const SESSION_TIMEOUT = 30 * 60 * 1000; // 30 minutes\n\n    // Check if we need to start a new session due to timeout\n    if (timeSinceActivity > SESSION_TIMEOUT) {\n      const { isNewSession } = generateSessionId(); // This will create and store the new session\n\n      // Only send session_start if this is actually a new session\n      if (isNewSession) {\n        sendEvent(\"session_start\");\n        sendEvent(\"pageview\");\n      }\n\n      // Re-enable heartbeats for new session\n      heartbeatEnabled.current = true;\n    }\n\n    updateLastActivity();\n\n    // Reset to fastest interval on activity\n    currentInterval.current = 15000;\n\n    if (heartbeatEnabled.current) {\n      scheduleNextHeartbeat();\n    }\n  }, [scheduleNextHeartbeat, sendEvent, updateLastActivity]);\n\n  const throttleRef = useRef<{\n    timeoutId?: NodeJS.Timeout;\n    lastExecTime: number;\n  }>({ lastExecTime: 0 });\n\n  const throttledHandleActivity = useCallback(() => {\n    const delay = 250; // 250ms throttle\n    const currentTime = Date.now();\n\n    if (currentTime - throttleRef.current.lastExecTime > delay) {\n      handleActivity();\n      throttleRef.current.lastExecTime = currentTime;\n    } else {\n      if (throttleRef.current.timeoutId) {\n        clearTimeout(throttleRef.current.timeoutId);\n      }\n      throttleRef.current.timeoutId = setTimeout(() => {\n        handleActivity();\n        throttleRef.current.lastExecTime = Date.now();\n      }, delay - (currentTime - throttleRef.current.lastExecTime));\n    }\n  }, [handleActivity]);\n\n  // Track page views and set up activity detection\n  useEffect(() => {\n    // CRITICAL: Clean up any existing heartbeat when effect re-runs\n    if (heartbeatInterval.current) {\n      clearTimeout(heartbeatInterval.current);\n      heartbeatInterval.current = undefined;\n    }\n\n    // Reset performance event flag when pathname changes\n    if (lastTrackedPath.current !== pathname) {\n      perfEventSent.current = false;\n    }\n\n    if (pathnameInvalid) return;\n\n    if (process.env.NODE_ENV !== \"production\") return;\n\n    if (isBot()) {\n      return;\n    }\n\n    // Get client data which includes session state\n    const clientData = getClientData(username);\n    const isNewSession = clientData.isNewSession;\n\n    if (isNewSession && !isInitialized.current) {\n      sendEvent(\"session_start\");\n      isInitialized.current = true;\n    }\n\n    // Always send pageview for new sessions or path changes\n    if (isNewSession || lastTrackedPath.current !== pathname) {\n      updateLastActivity();\n\n      const referrer =\n        typeof window !== \"undefined\" &&\n        document.referrer &&\n        document.referrer.length > 0\n          ? document.referrer\n          : undefined;\n\n      sendEvent(\"pageview\", referrer);\n      lastTrackedPath.current = pathname;\n    }\n\n    // Set up activity event listeners\n    if (typeof window !== \"undefined\") {\n      const events = [\n        \"click\",\n        \"keydown\",\n        \"touchstart\",\n        \"scroll\",\n        \"wheel\",\n        \"play\",\n        \"pause\",\n        \"seeked\",\n        \"volumechange\",\n        \"input\",\n        \"change\",\n        \"focus\",\n        \"copy\",\n        \"cut\",\n        \"paste\",\n      ];\n\n      events.forEach((event) => {\n        window.addEventListener(event, throttledHandleActivity, {\n          passive: true,\n        });\n      });\n\n      const handleVisibilityChange = () => {\n        if (document.hidden) {\n          heartbeatEnabled.current = false;\n          if (heartbeatInterval.current) {\n            clearTimeout(heartbeatInterval.current);\n            heartbeatInterval.current = undefined;\n          }\n        } else {\n          heartbeatEnabled.current = true;\n          isActive.current = true;\n          scheduleNextHeartbeat();\n        }\n      };\n\n      document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n      // Start the dynamic heartbeat system\n      scheduleNextHeartbeat();\n\n      return () => {\n        events.forEach((event) => {\n          window.removeEventListener(event, throttledHandleActivity);\n        });\n        document.removeEventListener(\n          \"visibilitychange\",\n          handleVisibilityChange\n        );\n\n        if (heartbeatInterval.current) {\n          clearTimeout(heartbeatInterval.current);\n        }\n      };\n    }\n\n    // Return undefined when window is not available (SSR)\n    return undefined;\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [\n    pathname,\n    username,\n    isBot, // Start the dynamic heartbeat system\n    scheduleNextHeartbeat,\n    sendEvent,\n    throttledHandleActivity,\n    updateLastActivity,\n  ]);\n\n  return null;\n}\n","\"use client\";\n\nimport { usePathname } from \"next/navigation\";\n\nimport {\n  VisitorTracker as Core,\n  type VisitorTrackerProps as CoreProps,\n} from \"./visitor-tracker\";\n\nexport type VisitorTrackerProps = Omit<CoreProps, \"pathname\">;\n\n/**\n * Next.js adapter for VisitorTracker. Reads the current pathname via\n * `usePathname()` from `next/navigation` and forwards it to the\n * framework-agnostic core.\n *\n * Use this in a Next.js App Router project. For other React frameworks\n * (Vite, React Router, TanStack Router, Astro, etc.), import the core\n * from `@jillen/analytics` directly and pass `pathname` from your\n * router state.\n */\nexport function VisitorTracker(props: VisitorTrackerProps) {\n  const pathname = usePathname();\n  return <Core {...props} pathname={pathname ?? \"\"} />;\n}\n"]}