{"version":3,"sources":["../../src/report/utils.ts","../../src/report/diagnostics.ts","../../src/report/lcp.ts","../../src/report/opportunities.ts","../../src/report/generator.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @silverassist/performance-toolkit\n *\n * Report utility functions for formatting and severity calculations.\n *\n * @module report/utils\n * @author Miguel Colmenares <me@miguelcolmenares.com>\n * @license PolyForm-Noncommercial-1.0.0\n */\n\nimport type { DiagnosticItem } from \"../types\";\n\n/**\n * Formats bytes into human-readable string\n */\nexport function formatBytes(bytes: number): string {\n  if (bytes < 1024) return `${bytes} B`;\n  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KiB`;\n  return `${(bytes / (1024 * 1024)).toFixed(1)} MiB`;\n}\n\n/**\n * Truncates URL to specified length with ellipsis\n */\nexport function truncateUrl(url: string, maxLength: number = 50): string {\n  if (url.length <= maxLength) return url;\n  return url.substring(0, maxLength - 3) + \"...\";\n}\n\n/**\n * Calculates a normalized score between 0-1 based on thresholds\n */\nexport function calculateScore(\n  value: number,\n  goodThreshold: number,\n  poorThreshold: number,\n): number {\n  if (value <= goodThreshold) return 1;\n  if (value >= poorThreshold) return 0;\n  return 1 - (value - goodThreshold) / (poorThreshold - goodThreshold);\n}\n\n/**\n * Determines severity level based on byte size\n */\nexport function getSeverityByBytes(\n  bytes: number,\n  moderate: number = 100000,\n  serious: number = 300000,\n  critical: number = 500000,\n): DiagnosticItem[\"severity\"] {\n  if (bytes >= critical) return \"critical\";\n  if (bytes >= serious) return \"serious\";\n  if (bytes >= moderate) return \"moderate\";\n  return \"minor\";\n}\n\n/**\n * Determines severity level based on time in milliseconds\n */\nexport function getSeverityByTime(\n  ms: number,\n  moderate: number = 300,\n  serious: number = 800,\n  critical: number = 1500,\n): DiagnosticItem[\"severity\"] {\n  if (ms >= critical) return \"critical\";\n  if (ms >= serious) return \"serious\";\n  if (ms >= moderate) return \"moderate\";\n  return \"minor\";\n}\n","/**\n * @silverassist/performance-toolkit\n *\n * Diagnostics table generation similar to PageSpeed Insights.\n *\n * @module report/diagnostics\n * @author Miguel Colmenares <me@miguelcolmenares.com>\n * @license PolyForm-Noncommercial-1.0.0\n */\n\nimport type { DiagnosticItem, PerformanceResult } from \"../types\";\nimport {\n  formatBytes,\n  truncateUrl,\n  calculateScore,\n  getSeverityByBytes,\n  getSeverityByTime,\n} from \"./utils\";\n\n/**\n * Generates enhanced diagnostics table from performance insights\n */\nexport function generateDiagnosticsTable(\n  result: PerformanceResult,\n): DiagnosticItem[] {\n  const items: DiagnosticItem[] = [];\n  const { insights } = result;\n\n  // Unused JavaScript\n  if (insights?.unusedJavaScript?.length) {\n    const totalWasted = insights.unusedJavaScript.reduce(\n      (sum, js) => sum + js.wastedBytes,\n      0,\n    );\n    items.push({\n      id: \"unused-javascript\",\n      title: \"Reduce unused JavaScript\",\n      displayValue: `Est savings of ${formatBytes(totalWasted)}`,\n      description:\n        \"Remove unused JavaScript to reduce bytes consumed by network activity and improve page load performance.\",\n      score: calculateScore(totalWasted, 150000, 500000),\n      severity: getSeverityByBytes(totalWasted),\n      savings: { bytes: totalWasted },\n      items: insights.unusedJavaScript.slice(0, 10).map((js) => ({\n        url: js.url,\n        size: js.transferSize,\n        wastedBytes: js.wastedBytes,\n        metadata: {\n          isFirstParty: js.isFirstParty,\n          wastedPercent: js.wastedPercent,\n          entity: js.entity,\n        },\n      })),\n      category: \"javascript\",\n    });\n  }\n\n  // Unused CSS\n  if (insights?.unusedCSS?.length) {\n    const totalWasted = insights.unusedCSS.reduce(\n      (sum, css) => sum + css.wastedBytes,\n      0,\n    );\n    items.push({\n      id: \"unused-css\",\n      title: \"Reduce unused CSS\",\n      displayValue: `Est savings of ${formatBytes(totalWasted)}`,\n      description:\n        \"Remove unused CSS rules to reduce bytes consumed by network activity.\",\n      score: calculateScore(totalWasted, 50000, 200000),\n      severity: getSeverityByBytes(totalWasted, 50000, 100000, 200000),\n      savings: { bytes: totalWasted },\n      items: insights.unusedCSS.slice(0, 10).map((css) => ({\n        url: css.url,\n        size: css.transferSize,\n        wastedBytes: css.wastedBytes,\n        metadata: { wastedPercent: css.wastedPercent },\n      })),\n      category: \"resource\",\n    });\n  }\n\n  // Long Tasks\n  if (insights?.longTasks?.length) {\n    const count = insights.longTasks.length;\n    const totalDuration = insights.longTasks.reduce(\n      (sum, task) => sum + task.duration,\n      0,\n    );\n    items.push({\n      id: \"long-tasks\",\n      title: \"Avoid long main-thread tasks\",\n      displayValue: `${count} long task${count > 1 ? \"s\" : \"\"} found`,\n      description: `Long tasks block the main thread for ${Math.round(totalDuration)}ms total, causing the page to feel unresponsive.`,\n      score: calculateScore(count, 2, 5),\n      severity:\n        count > 5\n          ? \"critical\"\n          : count > 3\n            ? \"serious\"\n            : count > 1\n              ? \"moderate\"\n              : \"minor\",\n      savings: { timeMs: totalDuration },\n      items: insights.longTasks.map((task) => ({\n        label: task.url ? truncateUrl(task.url) : \"Unknown source\",\n        timeMs: task.duration,\n        metadata: { startTime: task.startTime, attribution: task.attribution },\n      })),\n      category: \"javascript\",\n    });\n  }\n\n  // Render-Blocking Resources\n  if (insights?.renderBlocking?.length) {\n    const totalWastedMs = insights.renderBlocking.reduce(\n      (sum, rb) => sum + rb.wastedMs,\n      0,\n    );\n    items.push({\n      id: \"render-blocking\",\n      title: \"Eliminate render-blocking resources\",\n      displayValue: `Est savings of ${Math.round(totalWastedMs)}ms`,\n      description:\n        \"Resources are blocking the first paint of your page. Consider delivering critical JS/CSS inline and deferring non-critical resources.\",\n      score: calculateScore(totalWastedMs, 500, 1500),\n      severity: getSeverityByTime(totalWastedMs),\n      savings: { timeMs: totalWastedMs },\n      items: insights.renderBlocking.map((rb) => ({\n        url: rb.url,\n        size: rb.transferSize,\n        timeMs: rb.wastedMs,\n        metadata: { resourceType: rb.resourceType },\n      })),\n      category: \"rendering\",\n    });\n  }\n\n  // Third-Party Impact\n  if (insights?.thirdParties?.length) {\n    const totalBlocking = insights.thirdParties.reduce(\n      (sum, tp) => sum + tp.blockingTime,\n      0,\n    );\n    const totalSize = insights.thirdParties.reduce(\n      (sum, tp) => sum + tp.transferSize,\n      0,\n    );\n    items.push({\n      id: \"third-party-summary\",\n      title: \"Reduce impact of third-party code\",\n      displayValue: `${Math.round(totalBlocking)}ms blocking time`,\n      description: `Third-party code blocked the main thread for ${Math.round(totalBlocking)}ms and transferred ${formatBytes(totalSize)}.`,\n      score: calculateScore(totalBlocking, 250, 1000),\n      severity:\n        totalBlocking > 1000\n          ? \"critical\"\n          : totalBlocking > 500\n            ? \"serious\"\n            : \"moderate\",\n      savings: { timeMs: totalBlocking, bytes: totalSize },\n      items: insights.thirdParties.slice(0, 10).map((tp) => ({\n        label: tp.entity,\n        timeMs: tp.blockingTime,\n        size: tp.transferSize,\n        metadata: { category: tp.category, requestCount: tp.requestCount },\n      })),\n      category: \"network\",\n    });\n  }\n\n  // Cache Issues\n  if (insights?.cacheIssues?.length) {\n    const totalWasted = insights.cacheIssues.reduce(\n      (sum, c) => sum + c.wastedBytes,\n      0,\n    );\n    items.push({\n      id: \"cache-policy\",\n      title: \"Serve static assets with efficient cache policy\",\n      displayValue: `${insights.cacheIssues.length} resources found`,\n      description: `${insights.cacheIssues.length} static resources have short cache lifetimes. A longer cache lifetime can speed up repeat visits.`,\n      score: calculateScore(totalWasted, 100000, 500000),\n      severity: totalWasted > 500000 ? \"serious\" : \"moderate\",\n      savings: { bytes: totalWasted },\n      items: insights.cacheIssues.slice(0, 10).map((c) => ({\n        url: c.url,\n        size: c.transferSize,\n        wastedBytes: c.wastedBytes,\n        metadata: { cacheTTL: c.cacheTTLDisplay, entity: c.entity },\n      })),\n      category: \"network\",\n    });\n  }\n\n  // Image Issues\n  if (insights?.imageIssues?.length) {\n    const totalWasted = insights.imageIssues.reduce(\n      (sum, img) => sum + img.wastedBytes,\n      0,\n    );\n    const issueTypes = [\n      ...new Set(insights.imageIssues.map((i) => i.issueType)),\n    ];\n    items.push({\n      id: \"image-optimization\",\n      title: \"Properly size and optimize images\",\n      displayValue: `Est savings of ${formatBytes(totalWasted)}`,\n      description: `Images have optimization opportunities: ${issueTypes.join(\", \")}. Properly sizing and formatting images can significantly reduce load time.`,\n      score: calculateScore(totalWasted, 100000, 500000),\n      severity: getSeverityByBytes(totalWasted),\n      savings: { bytes: totalWasted },\n      items: insights.imageIssues.slice(0, 10).map((img) => ({\n        url: img.url,\n        size: img.totalBytes,\n        wastedBytes: img.wastedBytes,\n        metadata: {\n          issueType: img.issueType,\n          recommendation: img.recommendation,\n          snippet: img.snippet,\n        },\n      })),\n      category: \"resource\",\n    });\n  }\n\n  // Legacy JavaScript\n  if (insights?.legacyJavaScript?.length) {\n    const totalWasted = insights.legacyJavaScript.reduce(\n      (sum, l) => sum + l.wastedBytes,\n      0,\n    );\n    items.push({\n      id: \"legacy-javascript\",\n      title: \"Avoid serving legacy JavaScript to modern browsers\",\n      displayValue: `Est savings of ${formatBytes(totalWasted)}`,\n      description:\n        \"Polyfills and transforms are shipped to modern browsers. Remove unnecessary polyfills by updating browser targets.\",\n      score: calculateScore(totalWasted, 30000, 100000),\n      severity: getSeverityByBytes(totalWasted, 30000, 60000, 100000),\n      savings: { bytes: totalWasted },\n      items: insights.legacyJavaScript.map((l) => ({\n        url: l.url,\n        wastedBytes: l.wastedBytes,\n        metadata: { polyfills: l.polyfills },\n      })),\n      category: \"javascript\",\n    });\n  }\n\n  // Sort by severity (critical first)\n  const severityOrder = { critical: 0, serious: 1, moderate: 2, minor: 3 };\n  return items.sort(\n    (a, b) => severityOrder[a.severity] - severityOrder[b.severity],\n  );\n}\n","/**\n * @silverassist/performance-toolkit\n *\n * LCP analysis and framework-specific recommendations.\n *\n * @module report/lcp\n * @author Miguel Colmenares <me@miguelcolmenares.com>\n * @license PolyForm-Noncommercial-1.0.0\n */\n\nimport type {\n  EnhancedLCPElement,\n  LCPBreakdown,\n  LCPRecommendation,\n  PerformanceResult,\n  ProjectContext,\n} from \"../types\";\n\n/**\n * Detects LCP element type from element info\n */\nexport function detectLCPType(\n  lcpElement: PerformanceResult[\"lcpElement\"],\n): EnhancedLCPElement[\"type\"] {\n  if (!lcpElement) return \"unknown\";\n\n  const tag = lcpElement.tagName.toLowerCase();\n  if (tag === \"img\") return \"image\";\n  if (tag === \"video\") return \"video\";\n  if (tag === \"svg\") return \"image\";\n  if (lcpElement.url?.match(/\\.(jpg|jpeg|png|gif|webp|avif|svg)/i))\n    return \"background-image\";\n  if ([\"h1\", \"h2\", \"h3\", \"p\", \"span\", \"div\"].includes(tag)) return \"text\";\n\n  return \"unknown\";\n}\n\n/**\n * Detects loading mechanism from element snippet\n */\nexport function detectLoadingMechanism(\n  lcpElement: PerformanceResult[\"lcpElement\"],\n): EnhancedLCPElement[\"loadingMechanism\"] {\n  if (!lcpElement?.snippet) return \"unknown\";\n\n  const snippet = lcpElement.snippet.toLowerCase();\n  if (snippet.includes('loading=\"lazy\"')) return \"lazy\";\n  if (snippet.includes(\"fetchpriority\") || snippet.includes(\"priority\"))\n    return \"priority\";\n  if (snippet.includes(\"defer\")) return \"deferred\";\n\n  return \"eager\";\n}\n\n/**\n * Generates LCP-specific recommendations based on type and breakdown\n */\nexport function generateLCPRecommendations(\n  type: EnhancedLCPElement[\"type\"],\n  breakdown: LCPBreakdown | undefined,\n  lcpValue: number | undefined,\n  context: ProjectContext | null,\n): LCPRecommendation[] {\n  const recommendations: LCPRecommendation[] = [];\n\n  // Type-specific recommendations\n  if (type === \"image\") {\n    recommendations.push({\n      id: \"lcp-priority-hint\",\n      title: \"Add priority hint to LCP image\",\n      description:\n        'Use fetchpriority=\"high\" on the LCP image to prioritize its loading.',\n      impact: \"high\",\n      effort: \"easy\",\n      codeHints: ['<img src=\"...\" fetchpriority=\"high\" />'],\n    });\n\n    if (context?.framework?.name === \"next\") {\n      recommendations.push({\n        id: \"lcp-next-image-priority\",\n        title: \"Use Next.js Image with priority\",\n        description:\n          \"Use next/image component with priority prop for the LCP image.\",\n        impact: \"high\",\n        effort: \"easy\",\n        codeHints: ['<Image src=\"...\" priority />'],\n      });\n    }\n  }\n\n  // Breakdown-based recommendations\n  if (breakdown) {\n    if (breakdown.ttfb > 800) {\n      recommendations.push({\n        id: \"lcp-reduce-ttfb\",\n        title: \"Reduce server response time (TTFB)\",\n        description: `TTFB is ${breakdown.ttfb}ms. Consider using a CDN, optimizing server logic, or implementing edge caching.`,\n        impact: \"high\",\n        effort: \"moderate\",\n      });\n    }\n\n    if (breakdown.resourceLoadDelay > 500) {\n      recommendations.push({\n        id: \"lcp-preload\",\n        title: \"Preload the LCP resource\",\n        description: `The LCP resource has ${breakdown.resourceLoadDelay}ms load delay. Use <link rel=\"preload\"> to start loading earlier.`,\n        impact: \"medium\",\n        effort: \"easy\",\n        codeHints: ['<link rel=\"preload\" href=\"...\" as=\"image\" />'],\n      });\n    }\n\n    if (breakdown.elementRenderDelay > 300) {\n      recommendations.push({\n        id: \"lcp-reduce-render-delay\",\n        title: \"Reduce render-blocking resources\",\n        description: `Element render is delayed by ${breakdown.elementRenderDelay}ms. Remove or defer render-blocking CSS/JS.`,\n        impact: \"medium\",\n        effort: \"moderate\",\n      });\n    }\n  }\n\n  // General LCP recommendations\n  if (lcpValue && lcpValue > 2500) {\n    recommendations.push({\n      id: \"lcp-critical-css\",\n      title: \"Inline critical CSS\",\n      description:\n        \"Extract and inline the CSS needed for above-the-fold content to avoid render blocking.\",\n      impact: lcpValue > 4000 ? \"high\" : \"medium\",\n      effort: \"moderate\",\n    });\n  }\n\n  return recommendations;\n}\n\n/**\n * Generates enhanced LCP element information with recommendations\n */\nexport function generateEnhancedLCP(\n  result: PerformanceResult,\n  context: ProjectContext | null,\n): EnhancedLCPElement | undefined {\n  const { lcpElement, insights, metrics } = result;\n  if (!lcpElement) return undefined;\n\n  const type = detectLCPType(lcpElement);\n  const recommendations = generateLCPRecommendations(\n    type,\n    insights?.lcpBreakdown,\n    metrics.lcp.value,\n    context,\n  );\n\n  return {\n    ...lcpElement,\n    type,\n    loadingMechanism: detectLoadingMechanism(lcpElement),\n    isAboveTheFold: true, // LCP is by definition above-the-fold\n    recommendations,\n    timing: insights?.lcpBreakdown\n      ? {\n          requestStart: insights.lcpBreakdown.ttfb,\n          loadEnd:\n            insights.lcpBreakdown.ttfb +\n            insights.lcpBreakdown.resourceLoadDelay +\n            insights.lcpBreakdown.resourceLoadDuration,\n          renderTime: insights.lcpBreakdown.elementRenderDelay,\n        }\n      : undefined,\n  };\n}\n","/**\n * @silverassist/performance-toolkit\n *\n * Key opportunities generation with framework-specific guidance.\n *\n * @module report/opportunities\n * @author Miguel Colmenares <me@miguelcolmenares.com>\n * @license PolyForm-Noncommercial-1.0.0\n */\n\nimport type {\n  ActionStep,\n  FrameworkSpecificNote,\n  KeyOpportunity,\n  PerformanceResult,\n  ProjectContext,\n} from \"../types\";\nimport { formatBytes } from \"./utils\";\nimport { detectLCPType } from \"./lcp\";\n\n/**\n * Generates ranked key opportunities with framework-specific guidance\n */\nexport function generateKeyOpportunities(\n  result: PerformanceResult,\n  context: ProjectContext | null,\n): KeyOpportunity[] {\n  const opportunities: KeyOpportunity[] = [];\n  const { insights, metrics } = result;\n\n  // Opportunity 1: LCP Optimization\n  if (metrics.lcp.rating !== \"good\") {\n    opportunities.push(createLCPOpportunity(result, context));\n  }\n\n  // Opportunity 2: JavaScript Optimization\n  const jsWaste =\n    insights?.unusedJavaScript?.reduce((sum, js) => sum + js.wastedBytes, 0) ??\n    0;\n  if (jsWaste > 100000) {\n    opportunities.push(createJavaScriptOpportunity(result, context, jsWaste));\n  }\n\n  // Opportunity 3: Image Optimization\n  const imgWaste =\n    insights?.imageIssues?.reduce((sum, img) => sum + img.wastedBytes, 0) ?? 0;\n  if (imgWaste > 50000) {\n    opportunities.push(createImageOpportunity(result, context, imgWaste));\n  }\n\n  // Opportunity 4: Third-Party Script Management\n  const tpBlocking =\n    insights?.thirdParties?.reduce((sum, tp) => sum + tp.blockingTime, 0) ?? 0;\n  if (tpBlocking > 250) {\n    opportunities.push(\n      createThirdPartyOpportunity(result, context, tpBlocking),\n    );\n  }\n\n  // Opportunity 5: Render-Blocking Resources\n  const rbWaste =\n    insights?.renderBlocking?.reduce((sum, rb) => sum + rb.wastedMs, 0) ?? 0;\n  if (rbWaste > 200) {\n    opportunities.push(createRenderBlockingOpportunity(rbWaste));\n  }\n\n  // Opportunity 6: CLS Improvement\n  if (metrics.cls.rating !== \"good\") {\n    opportunities.push(createCLSOpportunity(result));\n  }\n\n  // Sort by priority and return\n  return opportunities.sort((a, b) => a.priority - b.priority);\n}\n\n/**\n * Creates LCP optimization opportunity\n */\nexport function createLCPOpportunity(\n  result: PerformanceResult,\n  context: ProjectContext | null,\n): KeyOpportunity {\n  const { metrics, lcpElement, insights } = result;\n  const lcpType = lcpElement ? detectLCPType(lcpElement) : \"unknown\";\n\n  const steps: ActionStep[] = [];\n  const frameworkNotes: FrameworkSpecificNote[] = [];\n\n  // Step 1: Identify LCP element\n  steps.push({\n    order: 1,\n    title: \"Identify and understand your LCP element\",\n    instructions: `Your LCP element is a ${lcpType}${lcpElement?.tagName ? ` (${lcpElement.tagName})` : \"\"}. The current LCP time is ${metrics.lcp.displayValue}.`,\n  });\n\n  // Step 2: Add priority hint\n  if (lcpType === \"image\") {\n    steps.push({\n      order: 2,\n      title: \"Add priority hint to LCP image\",\n      instructions:\n        'Add fetchpriority=\"high\" to ensure the browser prioritizes loading this image.',\n      codeExample: {\n        language: \"html\",\n        code: `<img src=\"${lcpElement?.url || \"hero-image.jpg\"}\" fetchpriority=\"high\" alt=\"...\" />`,\n      },\n    });\n\n    // Next.js specific\n    if (context?.framework?.name === \"next\") {\n      frameworkNotes.push({\n        framework: \"Next.js\",\n        note: \"Use the Image component with priority prop instead of native img tag.\",\n        codeExample: `import Image from 'next/image';\\n\\n<Image\\n  src=\"${lcpElement?.url || \"/hero.jpg\"}\"\\n  priority\\n  alt=\"...\"\\n  width={1200}\\n  height={600}\\n/>`,\n        docLink:\n          \"https://nextjs.org/docs/app/api-reference/components/image#priority\",\n      });\n    }\n  }\n\n  // Step 3: Preload if needed\n  if (\n    insights?.lcpBreakdown?.resourceLoadDelay &&\n    insights.lcpBreakdown.resourceLoadDelay > 300\n  ) {\n    steps.push({\n      order: 3,\n      title: \"Preload the LCP resource\",\n      instructions:\n        \"Add a preload link in the document head to start fetching the resource earlier.\",\n      codeExample: {\n        language: \"html\",\n        code: `<link rel=\"preload\" href=\"${lcpElement?.url || \"/hero.jpg\"}\" as=\"${lcpType === \"image\" ? \"image\" : \"fetch\"}\" />`,\n        filePath: \"app/layout.tsx or pages/_document.tsx\",\n      },\n    });\n  }\n\n  // Step 4: TTFB optimization\n  if (insights?.lcpBreakdown?.ttfb && insights.lcpBreakdown.ttfb > 600) {\n    steps.push({\n      order: 4,\n      title: \"Improve server response time\",\n      instructions: `Your TTFB is ${insights.lcpBreakdown.ttfb}ms. Consider implementing caching, using a CDN, or optimizing your server.`,\n      estimatedTime: \"2-4 hours\",\n    });\n  }\n\n  return {\n    id: \"optimize-lcp\",\n    priority: 1,\n    title: \"Optimize Largest Contentful Paint (LCP)\",\n    description: `Your LCP is ${metrics.lcp.displayValue}, rated as \"${metrics.lcp.rating}\". The target is under 2.5 seconds.`,\n    impact: {\n      level: metrics.lcp.value > 4000 ? \"critical\" : \"high\",\n      lcpImprovementMs: Math.max(0, metrics.lcp.value - 2500),\n      scoreImprovement: metrics.lcp.rating === \"poor\" ? 15 : 8,\n    },\n    steps,\n    relatedAudits: [\n      \"largest-contentful-paint\",\n      \"largest-contentful-paint-element\",\n    ],\n    frameworkNotes: frameworkNotes.length > 0 ? frameworkNotes : undefined,\n    resources: [\n      { title: \"Optimize LCP\", url: \"https://web.dev/optimize-lcp/\" },\n      { title: \"LCP Guide\", url: \"https://web.dev/lcp/\" },\n    ],\n  };\n}\n\n/**\n * Creates JavaScript optimization opportunity\n */\nexport function createJavaScriptOpportunity(\n  result: PerformanceResult,\n  context: ProjectContext | null,\n  wastedBytes: number,\n): KeyOpportunity {\n  const steps: ActionStep[] = [];\n  const frameworkNotes: FrameworkSpecificNote[] = [];\n  const firstPartyWaste =\n    result.insights?.unusedJavaScript\n      ?.filter((js) => js.isFirstParty)\n      .reduce((sum, js) => sum + js.wastedBytes, 0) ?? 0;\n\n  steps.push({\n    order: 1,\n    title: \"Audit JavaScript bundles\",\n    instructions:\n      \"Use webpack-bundle-analyzer or source-map-explorer to identify large modules.\",\n    codeExample: {\n      language: \"bash\",\n      code: \"npx source-map-explorer dist/**/*.js\",\n    },\n  });\n\n  if (firstPartyWaste > 50000) {\n    steps.push({\n      order: 2,\n      title: \"Implement code splitting\",\n      instructions:\n        \"Split your JavaScript into smaller chunks that can be loaded on demand.\",\n    });\n\n    if (context?.framework?.name === \"next\") {\n      frameworkNotes.push({\n        framework: \"Next.js\",\n        note: \"Use dynamic imports for components that aren't needed immediately.\",\n        codeExample: `import dynamic from 'next/dynamic';\\n\\nconst HeavyComponent = dynamic(() => import('./HeavyComponent'), {\\n  loading: () => <p>Loading...</p>,\\n  ssr: false, // Optional: disable SSR for client-only components\\n});`,\n        docLink:\n          \"https://nextjs.org/docs/app/building-your-application/optimizing/lazy-loading\",\n      });\n    }\n  }\n\n  steps.push({\n    order: 3,\n    title: \"Review and remove unused dependencies\",\n    instructions:\n      \"Check your package.json for dependencies that are no longer used.\",\n    codeExample: {\n      language: \"bash\",\n      code: \"npx depcheck\",\n    },\n  });\n\n  return {\n    id: \"optimize-javascript\",\n    priority: 2,\n    title: \"Reduce JavaScript bundle size\",\n    description: `${formatBytes(wastedBytes)} of JavaScript is unused. Reducing bundle size improves load time and TBT.`,\n    impact: {\n      level:\n        wastedBytes > 500000\n          ? \"critical\"\n          : wastedBytes > 200000\n            ? \"high\"\n            : \"medium\",\n      sizeSavings: wastedBytes,\n      scoreImprovement: Math.min(15, Math.floor(wastedBytes / 50000)),\n    },\n    steps,\n    relatedAudits: [\n      \"unused-javascript\",\n      \"bootup-time\",\n      \"mainthread-work-breakdown\",\n    ],\n    frameworkNotes: frameworkNotes.length > 0 ? frameworkNotes : undefined,\n    resources: [\n      {\n        title: \"Reduce JavaScript Payloads\",\n        url: \"https://web.dev/reduce-javascript-payloads-with-code-splitting/\",\n      },\n    ],\n  };\n}\n\n/**\n * Creates image optimization opportunity\n */\nexport function createImageOpportunity(\n  result: PerformanceResult,\n  context: ProjectContext | null,\n  wastedBytes: number,\n): KeyOpportunity {\n  const issues = result.insights?.imageIssues ?? [];\n  const formatIssues = issues.filter((i) => i.issueType === \"format\");\n  const sizeIssues = issues.filter((i) => i.issueType === \"oversized\");\n  const offscreenIssues = issues.filter((i) => i.issueType === \"offscreen\");\n\n  const steps: ActionStep[] = [];\n  const frameworkNotes: FrameworkSpecificNote[] = [];\n\n  if (formatIssues.length > 0) {\n    steps.push({\n      order: 1,\n      title: \"Convert images to modern formats\",\n      instructions: `${formatIssues.length} images should be converted to WebP or AVIF format for better compression.`,\n    });\n  }\n\n  if (sizeIssues.length > 0) {\n    steps.push({\n      order: 2,\n      title: \"Serve properly sized images\",\n      instructions: `${sizeIssues.length} images are larger than their display size. Resize images to match their rendered dimensions.`,\n    });\n  }\n\n  if (offscreenIssues.length > 0) {\n    steps.push({\n      order: 3,\n      title: \"Lazy load offscreen images\",\n      instructions: `${offscreenIssues.length} images are below the fold and should be lazy loaded.`,\n      codeExample: {\n        language: \"html\",\n        code: '<img src=\"...\" loading=\"lazy\" alt=\"...\" />',\n      },\n    });\n  }\n\n  // Framework-specific notes\n  if (context?.framework?.name === \"next\") {\n    frameworkNotes.push({\n      framework: \"Next.js\",\n      note: \"Next.js Image component automatically handles format conversion, sizing, and lazy loading.\",\n      codeExample: `import Image from 'next/image';\\n\\n<Image\\n  src=\"/photo.jpg\"\\n  alt=\"Description\"\\n  width={800}\\n  height={600}\\n  // priority // Only for above-the-fold images\\n/>`,\n      docLink:\n        \"https://nextjs.org/docs/app/building-your-application/optimizing/images\",\n    });\n  }\n\n  return {\n    id: \"optimize-images\",\n    priority: 3,\n    title: \"Optimize images\",\n    description: `${formatBytes(wastedBytes)} can be saved by properly optimizing ${issues.length} images.`,\n    impact: {\n      level: wastedBytes > 500000 ? \"high\" : \"medium\",\n      sizeSavings: wastedBytes,\n      lcpImprovementMs: issues.some((i) => i.issueType === \"format\") ? 200 : 0,\n    },\n    steps,\n    relatedAudits: [\n      \"modern-image-formats\",\n      \"uses-responsive-images\",\n      \"offscreen-images\",\n    ],\n    frameworkNotes: frameworkNotes.length > 0 ? frameworkNotes : undefined,\n    resources: [\n      {\n        title: \"Use Modern Image Formats\",\n        url: \"https://web.dev/uses-webp-images/\",\n      },\n      {\n        title: \"Properly Size Images\",\n        url: \"https://web.dev/uses-responsive-images/\",\n      },\n    ],\n  };\n}\n\n/**\n * Creates third-party script opportunity\n */\nexport function createThirdPartyOpportunity(\n  result: PerformanceResult,\n  context: ProjectContext | null,\n  blockingTime: number,\n): KeyOpportunity {\n  const thirdParties = result.insights?.thirdParties ?? [];\n  const topBlockers = thirdParties.slice(0, 3);\n\n  return {\n    id: \"optimize-third-parties\",\n    priority: 4,\n    title: \"Reduce third-party script impact\",\n    description: `Third-party scripts block the main thread for ${Math.round(blockingTime)}ms. Top blockers: ${topBlockers.map((t) => t.entity).join(\", \")}.`,\n    impact: {\n      level: blockingTime > 1000 ? \"high\" : \"medium\",\n      lcpImprovementMs: Math.round(blockingTime * 0.3),\n    },\n    steps: [\n      {\n        order: 1,\n        title: \"Audit third-party scripts\",\n        instructions:\n          \"Review each third-party script and determine if it's truly necessary.\",\n      },\n      {\n        order: 2,\n        title: \"Defer non-critical scripts\",\n        instructions:\n          \"Load analytics and tracking scripts after the page has finished loading.\",\n        codeExample: {\n          language: \"javascript\",\n          code: `// Load analytics after page load\\nwindow.addEventListener('load', () => {\\n  // Initialize analytics\\n});`,\n        },\n      },\n      {\n        order: 3,\n        title: \"Use Partytown for heavy scripts\",\n        instructions:\n          \"Consider using Partytown to run third-party scripts in a web worker.\",\n      },\n    ],\n    relatedAudits: [\"third-party-summary\", \"bootup-time\"],\n    frameworkNotes:\n      context?.framework?.name === \"next\"\n        ? [\n            {\n              framework: \"Next.js\",\n              note: \"Use next/script with appropriate strategy to control loading behavior.\",\n              codeExample: `import Script from 'next/script';\\n\\n<Script\\n  src=\"https://analytics.example.com\"\\n  strategy=\"lazyOnload\" // or \"afterInteractive\"\\n/>`,\n              docLink:\n                \"https://nextjs.org/docs/app/building-your-application/optimizing/scripts\",\n            },\n          ]\n        : undefined,\n  };\n}\n\n/**\n * Creates render-blocking resources opportunity\n */\nexport function createRenderBlockingOpportunity(\n  wastedMs: number,\n): KeyOpportunity {\n  return {\n    id: \"eliminate-render-blocking\",\n    priority: 5,\n    title: \"Eliminate render-blocking resources\",\n    description: `Render-blocking resources delay first paint by ${Math.round(wastedMs)}ms.`,\n    impact: {\n      level: wastedMs > 1000 ? \"high\" : \"medium\",\n      lcpImprovementMs: Math.round(wastedMs * 0.7),\n    },\n    steps: [\n      {\n        order: 1,\n        title: \"Inline critical CSS\",\n        instructions:\n          \"Extract CSS needed for above-the-fold content and inline it in the HTML.\",\n      },\n      {\n        order: 2,\n        title: \"Defer non-critical CSS\",\n        instructions:\n          \"Load non-critical CSS asynchronously using media queries or JavaScript.\",\n        codeExample: {\n          language: \"html\",\n          code: '<link rel=\"stylesheet\" href=\"non-critical.css\" media=\"print\" onload=\"this.media=\\'all\\'\">',\n        },\n      },\n      {\n        order: 3,\n        title: \"Add async/defer to scripts\",\n        instructions:\n          \"Non-critical scripts should use async or defer attributes.\",\n        codeExample: {\n          language: \"html\",\n          code: '<script src=\"app.js\" defer></script>',\n        },\n      },\n    ],\n    relatedAudits: [\"render-blocking-resources\", \"critical-request-chains\"],\n  };\n}\n\n/**\n * Creates CLS improvement opportunity\n */\nexport function createCLSOpportunity(\n  result: PerformanceResult,\n): KeyOpportunity {\n  const { metrics } = result;\n\n  return {\n    id: \"improve-cls\",\n    priority: 6,\n    title: \"Improve Cumulative Layout Shift (CLS)\",\n    description: `Your CLS is ${metrics.cls.displayValue}, rated as \"${metrics.cls.rating}\". Target is under 0.1.`,\n    impact: {\n      level: metrics.cls.value > 0.25 ? \"high\" : \"medium\",\n      scoreImprovement: 5,\n    },\n    steps: [\n      {\n        order: 1,\n        title: \"Set explicit dimensions on images and videos\",\n        instructions:\n          \"Always specify width and height attributes on media elements.\",\n        codeExample: {\n          language: \"html\",\n          code: '<img src=\"...\" width=\"800\" height=\"600\" alt=\"...\" />',\n        },\n      },\n      {\n        order: 2,\n        title: \"Reserve space for dynamic content\",\n        instructions:\n          \"Use CSS to reserve space for ads, embeds, and dynamically injected content.\",\n      },\n      {\n        order: 3,\n        title: \"Avoid inserting content above existing content\",\n        instructions:\n          \"New content should be inserted below the current viewport or with user action.\",\n      },\n      {\n        order: 4,\n        title: \"Use CSS transform for animations\",\n        instructions:\n          \"Prefer transform and opacity for animations instead of properties that trigger layout.\",\n      },\n    ],\n    relatedAudits: [\"cumulative-layout-shift\", \"unsized-images\"],\n    resources: [\n      { title: \"Optimize CLS\", url: \"https://web.dev/optimize-cls/\" },\n    ],\n  };\n}\n","/**\n * @silverassist/performance-toolkit\n *\n * Main report generator orchestrating report generation.\n *\n * @module report/generator\n * @author Miguel Colmenares <me@miguelcolmenares.com>\n * @license PolyForm-Noncommercial-1.0.0\n */\n\nimport type {\n  ActionableReport,\n  DiagnosticItem,\n  KeyOpportunity,\n  NextStep,\n  PerformanceResult,\n  ProjectContext,\n} from \"../types\";\nimport { generateDiagnosticsTable } from \"./diagnostics\";\nimport { generateEnhancedLCP } from \"./lcp\";\nimport { generateKeyOpportunities } from \"./opportunities\";\n\n/**\n * Generates actionable performance reports with framework-specific recommendations\n */\nexport class ActionableReportGenerator {\n  private result: PerformanceResult;\n  private context: ProjectContext | null;\n\n  constructor(result: PerformanceResult, context?: ProjectContext | null) {\n    this.result = result;\n    this.context = context ?? null;\n  }\n\n  /**\n   * Generates a complete actionable report\n   */\n  generate(): ActionableReport {\n    const diagnosticsTable = generateDiagnosticsTable(this.result);\n    const enhancedLCP = generateEnhancedLCP(this.result, this.context);\n    const keyOpportunities = generateKeyOpportunities(\n      this.result,\n      this.context,\n    );\n    const nextSteps = this.generateNextSteps(keyOpportunities);\n    const summary = this.generateSummary(diagnosticsTable, keyOpportunities);\n\n    return {\n      performanceResult: this.result,\n      projectContext: this.context ?? undefined,\n      enhancedLCP,\n      diagnosticsTable,\n      keyOpportunities,\n      nextSteps,\n      summary,\n      generatedAt: new Date().toISOString(),\n    };\n  }\n\n  /**\n   * Generates recommended next steps\n   */\n  private generateNextSteps(opportunities: KeyOpportunity[]): NextStep[] {\n    const steps: NextStep[] = [];\n    const topOpportunities = opportunities.slice(0, 3);\n\n    // Immediate actions from top opportunities\n    for (const opp of topOpportunities) {\n      if (opp.impact.level === \"critical\" || opp.impact.level === \"high\") {\n        steps.push({\n          id: `next-${opp.id}`,\n          title: opp.steps[0]?.title ?? opp.title,\n          description: `Start with the first step of \"${opp.title}\" - this has ${opp.impact.level} impact.`,\n          type: \"code-change\",\n          urgency: opp.impact.level === \"critical\" ? \"immediate\" : \"soon\",\n          relatedOpportunities: [opp.id],\n        });\n      }\n    }\n\n    // Add monitoring step\n    steps.push({\n      id: \"next-setup-monitoring\",\n      title: \"Set up continuous performance monitoring\",\n      description:\n        \"Use this toolkit in your CI/CD pipeline to catch regressions early.\",\n      type: \"monitoring\",\n      urgency: \"when-possible\",\n    });\n\n    // Add testing step\n    if (this.result.scores.performance && this.result.scores.performance < 90) {\n      steps.push({\n        id: \"next-perf-testing\",\n        title: \"Add performance tests to CI pipeline\",\n        description:\n          \"Create performance budgets and fail builds that exceed thresholds.\",\n        type: \"testing\",\n        urgency: \"soon\",\n      });\n    }\n\n    return steps.slice(0, 5);\n  }\n\n  /**\n   * Generates executive summary\n   */\n  private generateSummary(\n    diagnostics: DiagnosticItem[],\n    opportunities: KeyOpportunity[],\n  ): ActionableReport[\"summary\"] {\n    const { scores, insights } = this.result;\n\n    // Determine health status\n    let healthStatus: ActionableReport[\"summary\"][\"healthStatus\"];\n    if ((scores.performance ?? 0) >= 90) {\n      healthStatus = \"healthy\";\n    } else if ((scores.performance ?? 0) >= 50) {\n      healthStatus = \"needs-attention\";\n    } else {\n      healthStatus = \"critical\";\n    }\n\n    // Count quick wins (easy effort, high/medium impact)\n    const quickWins = opportunities.filter((o) =>\n      o.steps.some((s) => s.estimatedTime?.includes(\"minute\") || s.codeExample),\n    ).length;\n\n    // Calculate total potential savings\n    const timeMs =\n      insights?.totalSavings?.timeMs ??\n      diagnostics.reduce((sum, d) => sum + (d.savings?.timeMs ?? 0), 0);\n    const sizeBytes =\n      insights?.totalSavings?.sizeBytes ??\n      diagnostics.reduce((sum, d) => sum + (d.savings?.bytes ?? 0), 0);\n\n    // Get top 3 priorities\n    const topPriorities = opportunities.slice(0, 3).map((o) => o.title);\n\n    return {\n      healthStatus,\n      quickWinsCount: quickWins,\n      potentialSavings: {\n        timeMs: Math.round(timeMs),\n        sizeBytes: Math.round(sizeBytes),\n      },\n      topPriorities,\n    };\n  }\n}\n\n/**\n * Creates an actionable report generator\n */\nexport function createReportGenerator(\n  result: PerformanceResult,\n  context?: ProjectContext | null,\n): ActionableReportGenerator {\n  return new ActionableReportGenerator(result, context);\n}\n\n/**\n * Quick function to generate an actionable report\n */\nexport function generateActionableReport(\n  result: PerformanceResult,\n  context?: ProjectContext | null,\n): ActionableReport {\n  const generator = new ActionableReportGenerator(result, context);\n  return generator.generate();\n}\n"]}