{"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/common/benchmark/utils.ts"],"sourcesContent":["import { getTextWidth } from '@/utils/getMaxLabelLength';\n\nimport type {\n  BenchmarkFieldKeys,\n  BenchmarkRecord,\n  BenchmarkRenderIcon,\n  NormalizedBenchmarkItem,\n} from './types';\n\nexport const DEFAULT_BENCHMARK_KEYS = {\n  colorKey: 'color',\n  errorKey: 'error',\n  iconKey: 'icon',\n  index: 'name',\n  lineKey: 'line',\n  providerKey: 'provider',\n  valueKey: 'score',\n} as const;\n\nexport const resolveBenchmarkKeys = (keys: BenchmarkFieldKeys = {}) => ({\n  colorKey: keys.colorKey ?? DEFAULT_BENCHMARK_KEYS.colorKey,\n  errorKey: keys.errorKey ?? DEFAULT_BENCHMARK_KEYS.errorKey,\n  iconKey: keys.iconKey ?? DEFAULT_BENCHMARK_KEYS.iconKey,\n  index: keys.index ?? DEFAULT_BENCHMARK_KEYS.index,\n  lineKey: keys.lineKey ?? DEFAULT_BENCHMARK_KEYS.lineKey,\n  providerKey: keys.providerKey ?? DEFAULT_BENCHMARK_KEYS.providerKey,\n  valueKey: keys.valueKey ?? DEFAULT_BENCHMARK_KEYS.valueKey,\n});\n\nexport const getBenchmarkIcon = (\n  record: BenchmarkRecord,\n  iconKey: string,\n  renderIcon?: BenchmarkRenderIcon,\n  index = 0,\n) => {\n  if (renderIcon) return renderIcon(record, index);\n  return record[iconKey] as BenchmarkRecord['icon'];\n};\n\nexport const normalizeBenchmarkData = ({\n  colorKey,\n  data,\n  errorKey,\n  iconKey,\n  index,\n  lineKey,\n  providerKey,\n  renderIcon,\n  sortOrder = 'descending',\n  valueKey,\n}: BenchmarkFieldKeys & {\n  data: BenchmarkRecord[];\n  renderIcon?: BenchmarkRenderIcon;\n  sortOrder?: 'ascending' | 'descending' | 'none';\n}): NormalizedBenchmarkItem[] => {\n  const keys = resolveBenchmarkKeys({\n    colorKey,\n    errorKey,\n    iconKey,\n    index,\n    lineKey,\n    providerKey,\n    valueKey,\n  });\n\n  const sorted =\n    sortOrder === 'none'\n      ? [...data]\n      : [...data].sort((a, b) => {\n          const aUnranked = Boolean(a.unranked);\n          const bUnranked = Boolean(b.unranked);\n          if (aUnranked !== bUnranked) return aUnranked ? 1 : -1;\n\n          const aValue = Number(a[keys.valueKey] ?? 0);\n          const bValue = Number(b[keys.valueKey] ?? 0);\n          return sortOrder === 'ascending' ? aValue - bValue : bValue - aValue;\n        });\n\n  return sorted.map((record, idx) => {\n    const name = record[keys.index] ?? record.name ?? '';\n    const value = Number(record[keys.valueKey] ?? 0);\n    const rank = typeof record.rank === 'number' ? record.rank : idx + 1;\n    const rawError = record[keys.errorKey];\n    const error =\n      rawError === undefined || rawError === null || rawError === '' ? undefined : Number(rawError);\n    const rawLine = record[keys.lineKey] ?? record.line;\n    const lineValue =\n      rawLine === undefined || rawLine === null || rawLine === '' ? undefined : Number(rawLine);\n\n    return {\n      color: record[keys.colorKey] ?? record.color,\n      error: Number.isFinite(error) ? error : undefined,\n      highlighted: Boolean(record.highlighted),\n      href: record.href,\n      icon: getBenchmarkIcon(record, keys.iconKey, renderIcon, idx),\n      key: record.key ?? (name === '' || name === undefined || name === null ? idx : String(name)),\n      lineValue: Number.isFinite(lineValue) ? lineValue : undefined,\n      name,\n      original: record,\n      provider: record[keys.providerKey] ?? record.provider,\n      rank,\n      target: record.target,\n      unranked: Boolean(record.unranked),\n      value,\n    };\n  });\n};\n\nexport const getBenchmarkMaxValue = (\n  items: NormalizedBenchmarkItem[],\n  maxValue?: number,\n): number => {\n  if (typeof maxValue === 'number') return maxValue;\n  return Math.max(...items.flatMap((item) => [item.value, item.lineValue ?? 0]), 0);\n};\n\nexport const getBenchmarkBarPercent = (value: number, maxValue: number, minPercent = 2) => {\n  if (maxValue <= 0 || value <= 0) return 0;\n  return Math.max((value / maxValue) * 100, minPercent);\n};\n\nexport const defaultBenchmarkValueFormatter = (value: number) => {\n  if (Number.isInteger(value)) return String(value);\n  return value.toFixed(1);\n};\n\nexport const defaultBenchmarkAccuracyFormatter = (value: number) => `${value.toFixed(1)}%`;\n\nexport const defaultBenchmarkErrorFormatter = (value: number) => value.toFixed(1);\n\nexport const formatBenchmarkAccuracyDisplay = ({\n  accuracyFormatter,\n  error,\n  errorFormatter = defaultBenchmarkErrorFormatter,\n  showError = true,\n  value,\n  valueFormatter = defaultBenchmarkValueFormatter,\n}: {\n  accuracyFormatter?: (value: number) => string;\n  error?: number;\n  errorFormatter?: (value: number) => string;\n  showError?: boolean;\n  value: number;\n  valueFormatter?: (value: number) => string;\n}) => {\n  const formatValue = accuracyFormatter ?? valueFormatter;\n  const main = formatValue(value);\n  if (!showError || error === undefined || error === null || Number.isNaN(error)) {\n    return { errorText: undefined, main, text: main };\n  }\n  const errorText = errorFormatter(error);\n  return { errorText, main, text: `${main} ± ${errorText}` };\n};\n\n/**\n * Split a label into lines. Supports `\\n` / `\\r\\n`.\n */\nexport const splitBenchmarkLabel = (label: unknown): string[] => {\n  const text = String(label ?? '');\n  if (!text) return [''];\n  return text.split(/\\r?\\n/);\n};\n\nexport const getBenchmarkLabelMetrics = (label: unknown) => {\n  const lines = splitBenchmarkLabel(label);\n  const longestWidth = lines.reduce((max, line) => Math.max(max, getTextWidth(line)), 0);\n  return { lineCount: Math.max(lines.length, 1), lines, longestWidth };\n};\n"],"mappings":"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"}