OOKNET                             [ /  search the index  ]  
──────────────────────────────────────────────────────────────────────────────────────
══════════════════════════════════════════════════════════════════════════════════════
OOKNET   [ /  search  ]  
────────────────────────────────────────────────
════════════════════════════════════════════════
 
 
master @ 257 LINES
 
[ HISTORY ]  [ UP ]
 

import { calculateBarWidth, sortItems, type SortBy } from "../sorting";
import { generateLoadoutDropdown } from "../loadout";
import { formatRace as utilFormatRace, toTitleCase } from "../../../lib/utils";
import { getSpecIcon } from "../../../lib/client-utils";

type Item = {
  label: string;
  value: number;
  min: number;
  max: number;
  stdev: number;
  percent?: number;
  color?: string;
  loadout?: any;
  className?: string;
  specName?: string;
};

export function renderRankingsChartHTML(
  data: any,
  sortBy: SortBy,
  classColors: Record<string, string>,
): string {
  const items: Item[] = [];
  for (const [className, classData] of Object.entries<any>(
    data.results || {},
  )) {
    const colorKey = String(className).toLowerCase().replace(/\s+/g, "_");
    const barColor = classColors[colorKey] || "#666";
    for (const [specName, specData] of Object.entries<any>(classData)) {
      items.push({
        label: String(specName)
          .replace(/_/g, " ")
          .replace(/\b\w/g, (s) => s.toUpperCase()),
        value: specData.dps,
        min: specData.min,
        max: specData.max,
        stdev: specData.stdev,
        color: barColor,
        loadout: specData.loadout || null,
        className: String(className),
        specName: String(specName),
      });
    }
  }
  sortItems(items, sortBy);
  const metric = (it: Item) =>
    String(sortBy) === "max"
      ? it.max
      : String(sortBy) === "min"
        ? it.min
        : String(sortBy) === "stdev"
          ? it.stdev
          : it.value;
  const max = Math.max(...items.map(metric), 0);
  const min =
    String(sortBy) === "dps" ||
    String(sortBy) === "max" ||
    String(sortBy) === "min"
      ? 0
      : Math.min(...items.map(metric), max);

  const bars = items
    .map((it, idx) => {
      const mval = metric(it);
      const width = calculateBarWidth(mval, max, min, sortBy).toFixed(1);
      const displayRaw = String(sortBy) === "stdev" ? it.stdev : mval;
      const display = Math.round(displayRaw).toLocaleString();
      const tooltip = `${it.label}: ${display}`;

      let specIcon = "";

      if (it.className && it.specName) {
        const properClassName = toTitleCase(it.className);
        const properSpecName = toTitleCase(it.specName);

        const iconUrl = getSpecIcon(properClassName, properSpecName);
        if (iconUrl) {
          specIcon = `<img src="${iconUrl}" alt="${properSpecName}" class="spec-ic
on" style="width: 24px; height: 24px; border-radius: 2px;" />`;
        }
      }

      const dropdownHtml = generateLoadoutDropdown(it.loadout);
      const hasDropdown = dropdownHtml && dropdownHtml.length > 0;
      return `
      <div class="chart-item-wrapper" data-index="${idx}">
        <div class="chart-item-header" title="${tooltip}">
          <div class="chart-item">
            <div class="chart-labels">
              ${specIcon}
            </div>
            <div class="chart-bar-container">
              <div class="chart-bar-track">
                <div class="chart-bar" style="width: ${width}%; background: ${it.c
olor || "#6aa84f"};"></div>
              </div>
              <div class="chart-value">${display}</div>
            </div>
          </div>
        </div>
        ${hasDropdown ? `<div class="chart-dropdown">${dropdownHtml}</div>` : ""}
      </div>`;
    })
    .join("");
  const titles: Record<string, string> = {
    dps: "DPS Rankings (Average)",
    max: "DPS Rankings (Maximum)",
    min: "DPS Rankings (Minimum)",
    stdev: "DPS Consistency Rankings (Low StdDev = More Consistent)",
  };
  const title = titles[String(sortBy)] || "DPS Rankings";
  return `<h2 class="card-title-large">${title}</h2><div class="chart-bars">${bars
}</div>`;
}

function trinketIconDataFromLoadout(loadout: any) {
  try {
    const items = loadout?.equipment?.items;
    const t1 = items?.[12];
    const t2 = items?.[13];
    const tr = t1 && t1.id ? t1 : t2 && t2.id ? t2 : null;
    if (!tr) return null;
    const ilvl = tr.stats?.ilvl ?? "";
    return { icon: tr.icon, ilvl, name: tr.name };
  } catch {
    return null;
  }
}

export function renderComparisonChartHTML(
  data: any,
  sortBy: SortBy,
  comparisonType: "race" | "trinket" = "trinket",
  barColor: string = "#666",
): string {
  const baseline = data?.results?.baseline?.dps || 0;
  const baselineMax = data?.results?.baseline?.max || 0;
  const baselineMin = data?.results?.baseline?.min || 0;
  const items: Item[] = [];
  for (const [key, v] of Object.entries<any>(data.results || {})) {
    if (key === "baseline") continue;

    let label = key.replace(/_/g, " ");
    let iconData: any = null;
    let percent: number | undefined;
    let dpsIncrease: number | undefined;

    if (comparisonType === "race") {
      label = utilFormatRace(key);
    }
    if (comparisonType === "trinket") {
      iconData = trinketIconDataFromLoadout(v.loadout);
      if (iconData) label = iconData.ilvl ? `${iconData.ilvl}` : iconData.name;
    }
    percent = baseline > 0 ? ((v.dps - baseline) / baseline) * 100 : undefined;
    dpsIncrease = baseline > 0 ? v.dps - baseline : undefined;

    (items as any).push({
      label,
      value: v.dps,
      min: v.min,
      max: v.max,
      stdev: v.stdev,
      percent,
      dpsIncrease,
      maxIncrease: baselineMax > 0 ? v.max - baselineMax : undefined,
      minIncrease: baselineMin > 0 ? v.min - baselineMin : undefined,
      loadout: v.loadout,
      iconData,
    });
  }

  const effectiveSort: SortBy =
    comparisonType === "race" && String(sortBy) === "percent" ? "dps" : sortBy;
  sortItems(items, effectiveSort);
  const metric = (it: Item) =>
    String(effectiveSort) === "percent"
      ? (it.percent ?? 0)
      : String(effectiveSort) === "max"
        ? ((it as any).maxIncrease ?? 0)
        : String(effectiveSort) === "min"
          ? ((it as any).minIncrease ?? 0)
          : String(effectiveSort) === "stdev"
            ? it.stdev
            : ((it as any).dpsIncrease ?? 0);
  const max = Math.max(...items.map(metric), 0);
  const min =
    String(effectiveSort) === "percent" ||
    String(effectiveSort) === "dps" ||
    String(effectiveSort) === "max" ||
    String(effectiveSort) === "min"
      ? 0
      : Math.min(...items.map(metric), max);

  const bars = items
    .map((it, idx) => {
      const mval = metric(it);
      const width = calculateBarWidth(mval, max, min, effectiveSort).toFixed(1);
      const display = Math.round(mval).toLocaleString();
      const percentStr =
        it.percent != null ? ` (+${it.percent.toFixed(1)}%)` : "";
      const dropdownHtml = generateLoadoutDropdown(it.loadout);
      const hasDropdown = dropdownHtml && dropdownHtml.length > 0;
      const labelContent =
        comparisonType === "trinket" && (it as any).iconData
          ? `<img src="https://wow.zamimg.com/images/wow/icons/small/${(it as any)
.iconData.icon}.jpg" alt="${(it as any).iconData.name}" class="trinket-icon" title
="${(it as any).iconData.name}" /><span class="trinket-ilvl">${it.label}</span>`
          : `<span class="chart-label">${it.label}</span>`;
      let chartDisplay = display;
      let tooltip = display;
      if (comparisonType === "trinket" && it.percent != null) {
        const percentDisplay = `+${it.percent.toFixed(1)}%`;
        const dpsIncreaseDisplay = `+${Math.round((it as any).dpsIncrease || 0).to
LocaleString()}`;
        if (String(effectiveSort) === "percent") {
          chartDisplay = percentDisplay;
          tooltip = `${percentDisplay} (${display} DPS)`;
        } else if (String(effectiveSort) === "stdev") {
          chartDisplay = Math.round(it.stdev).toLocaleString();
          tooltip = `${chartDisplay} StdDev (${display} DPS avg, lower is more con
sistent)`;
        } else {
          chartDisplay = dpsIncreaseDisplay;
          tooltip =
            String(effectiveSort) === "dps"
              ? `${display} DPS (${dpsIncreaseDisplay} vs baseline)`
              : `${display} (Avg: ${display} DPS, ${dpsIncreaseDisplay} vs baselin
e)`;
        }
      }
      return `
      <div class="chart-item-wrapper" data-index="${idx}">
        <div class="chart-item-header">
          <div class="chart-item chart-item-comparison">
            <div class="chart-labels">
              <span class="chart-rank">#${idx + 1}</span>
              ${labelContent}
            </div>
            <div class="chart-bar-container">
              <div class="chart-bar-track">
                <div class="chart-bar" style="width: ${width}%; background: ${barC
olor};"></div>
              </div>
              <div class="chart-value" title="${tooltip}">${comparisonType === "tr
inket" && String(effectiveSort) === "percent" ? (it.percent === 0 ? "Baseline" : `
+${(it.percent || 0).toFixed(1)}%`) : chartDisplay}</div>
            </div>
          </div>
        </div>
        ${hasDropdown ? `<div class="chart-dropdown">${dropdownHtml}</div>` : ""}
      </div>`;
    })
    .join("");
  const titles: Record<string, string> = {
    dps: `${comparisonType === "race" ? "Race" : "Trinket"} DPS Rankings (Average)
`,
    max: `${comparisonType === "race" ? "Race" : "Trinket"} DPS Rankings (Maximum)
`,
    min: `${comparisonType === "race" ? "Race" : "Trinket"} DPS Rankings (Minimum)
`,
    stdev: `${comparisonType === "race" ? "Race" : "Trinket"} DPS Consistency Rank
ings (Low StdDev = More Consistent)`,
    percent: `${comparisonType === "race" ? "Race" : "Trinket"} Performance Rankin
gs (% Increase)`,
  };
  const title =
    titles[String(effectiveSort)] ||
    `${comparisonType === "race" ? "Race" : "Trinket"} DPS Rankings`;
  return `<h2 class="card-title-large">${title}</h2><div class="chart-bars">${bars
}</div>`;
}

import { calculateBarWidth, sortItems, type 
SortBy } from "../sorting";
import { generateLoadoutDropdown } from "../
loadout";
import { formatRace as utilFormatRace, toTit
leCase } from "../../../lib/utils";
import { getSpecIcon } from "../../../lib/cl
ient-utils";

type Item = {
  label: string;
  value: number;
  min: number;
  max: number;
  stdev: number;
  percent?: number;
  color?: string;
  loadout?: any;
  className?: string;
  specName?: string;
};

export function renderRankingsChartHTML(
  data: any,
  sortBy: SortBy,
  classColors: Record<string, string>,
): string {
  const items: Item[] = [];
  for (const [className, classData] of Objec
t.entries<any>(
    data.results || {},
  )) {
    const colorKey = String(className).toLow
erCase().replace(/\s+/g, "_");
    const barColor = classColors[colorKey] |
| "#666";
    for (const [specName, specData] of Objec
t.entries<any>(classData)) {
      items.push({
        label: String(specName)
          .replace(/_/g, " ")
          .replace(/\b\w/g, (s) => s.toUpper
Case()),
        value: specData.dps,
        min: specData.min,
        max: specData.max,
        stdev: specData.stdev,
        color: barColor,
        loadout: specData.loadout || null,
        className: String(className),
        specName: String(specName),
      });
    }
  }
  sortItems(items, sortBy);
  const metric = (it: Item) =>
    String(sortBy) === "max"
      ? it.max
      : String(sortBy) === "min"
        ? it.min
        : String(sortBy) === "stdev"
          ? it.stdev
          : it.value;
  const max = Math.max(...items.map(metric),
 0);
  const min =
    String(sortBy) === "dps" ||
    String(sortBy) === "max" ||
    String(sortBy) === "min"
      ? 0
      : Math.min(...items.map(metric), max);

  const bars = items
    .map((it, idx) => {
      const mval = metric(it);
      const width = calculateBarWidth(mval, 
max, min, sortBy).toFixed(1);
      const displayRaw = String(sortBy) === 
"stdev" ? it.stdev : mval;
      const display = Math.round(displayRaw)
.toLocaleString();
      const tooltip = `${it.label}: ${displa
y}`;

      let specIcon = "";

      if (it.className && it.specName) {
        const properClassName = toTitleCase(
it.className);
        const properSpecName = toTitleCase(i
t.specName);

        const iconUrl = getSpecIcon(properCl
assName, properSpecName);
        if (iconUrl) {
          specIcon = `<img src="${iconUrl}" 
alt="${properSpecName}" class="spec-icon" st
yle="width: 24px; height: 24px; border-radiu
s: 2px;" />`;
        }
      }

      const dropdownHtml = generateLoadoutDr
opdown(it.loadout);
      const hasDropdown = dropdownHtml && dr
opdownHtml.length > 0;
      return `
      <div class="chart-item-wrapper" data-i
ndex="${idx}">
        <div class="chart-item-header" title
="${tooltip}">
          <div class="chart-item">
            <div class="chart-labels">
              ${specIcon}
            </div>
            <div class="chart-bar-container"
>
              <div class="chart-bar-track">
                <div class="chart-bar" style
="width: ${width}%; background: ${it.color |
| "#6aa84f"};"></div>
              </div>
              <div class="chart-value">${dis
play}</div>
            </div>
          </div>
        </div>
        ${hasDropdown ? `<div class="chart-d
ropdown">${dropdownHtml}</div>` : ""}
      </div>`;
    })
    .join("");
  const titles: Record<string, string> = {
    dps: "DPS Rankings (Average)",
    max: "DPS Rankings (Maximum)",
    min: "DPS Rankings (Minimum)",
    stdev: "DPS Consistency Rankings (Low St
dDev = More Consistent)",
  };
  const title = titles[String(sortBy)] || "D
PS Rankings";
  return `<h2 class="card-title-large">${tit
le}</h2><div class="chart-bars">${bars}</div
>`;
}

function trinketIconDataFromLoadout(loadout:
 any) {
  try {
    const items = loadout?.equipment?.items;
    const t1 = items?.[12];
    const t2 = items?.[13];
    const tr = t1 && t1.id ? t1 : t2 && t2.i
d ? t2 : null;
    if (!tr) return null;
    const ilvl = tr.stats?.ilvl ?? "";
    return { icon: tr.icon, ilvl, name: tr.n
ame };
  } catch {
    return null;
  }
}

export function renderComparisonChartHTML(
  data: any,
  sortBy: SortBy,
  comparisonType: "race" | "trinket" = "trin
ket",
  barColor: string = "#666",
): string {
  const baseline = data?.results?.baseline?.
dps || 0;
  const baselineMax = data?.results?.baselin
e?.max || 0;
  const baselineMin = data?.results?.baselin
e?.min || 0;
  const items: Item[] = [];
  for (const [key, v] of Object.entries<any>
(data.results || {})) {
    if (key === "baseline") continue;

    let label = key.replace(/_/g, " ");
    let iconData: any = null;
    let percent: number | undefined;
    let dpsIncrease: number | undefined;

    if (comparisonType === "race") {
      label = utilFormatRace(key);
    }
    if (comparisonType === "trinket") {
      iconData = trinketIconDataFromLoadout(
v.loadout);
      if (iconData) label = iconData.ilvl ? 
`${iconData.ilvl}` : iconData.name;
    }
    percent = baseline > 0 ? ((v.dps - basel
ine) / baseline) * 100 : undefined;
    dpsIncrease = baseline > 0 ? v.dps - bas
eline : undefined;

    (items as any).push({
      label,
      value: v.dps,
      min: v.min,
      max: v.max,
      stdev: v.stdev,
      percent,
      dpsIncrease,
      maxIncrease: baselineMax > 0 ? v.max -
 baselineMax : undefined,
      minIncrease: baselineMin > 0 ? v.min -
 baselineMin : undefined,
      loadout: v.loadout,
      iconData,
    });
  }

  const effectiveSort: SortBy =
    comparisonType === "race" && String(sort
By) === "percent" ? "dps" : sortBy;
  sortItems(items, effectiveSort);
  const metric = (it: Item) =>
    String(effectiveSort) === "percent"
      ? (it.percent ?? 0)
      : String(effectiveSort) === "max"
        ? ((it as any).maxIncrease ?? 0)
        : String(effectiveSort) === "min"
          ? ((it as any).minIncrease ?? 0)
          : String(effectiveSort) === "stdev
"
            ? it.stdev
            : ((it as any).dpsIncrease ?? 0)
;
  const max = Math.max(...items.map(metric),
 0);
  const min =
    String(effectiveSort) === "percent" ||
    String(effectiveSort) === "dps" ||
    String(effectiveSort) === "max" ||
    String(effectiveSort) === "min"
      ? 0
      : Math.min(...items.map(metric), max);

  const bars = items
    .map((it, idx) => {
      const mval = metric(it);
      const width = calculateBarWidth(mval, 
max, min, effectiveSort).toFixed(1);
      const display = Math.round(mval).toLoc
aleString();
      const percentStr =
        it.percent != null ? ` (+${it.percen
t.toFixed(1)}%)` : "";
      const dropdownHtml = generateLoadoutDr
opdown(it.loadout);
      const hasDropdown = dropdownHtml && dr
opdownHtml.length > 0;
      const labelContent =
        comparisonType === "trinket" && (it 
as any).iconData
          ? `<img src="https://wow.zamimg.co
m/images/wow/icons/small/${(it as any).iconD
ata.icon}.jpg" alt="${(it as any).iconData.n
ame}" class="trinket-icon" title="${(it as a
ny).iconData.name}" /><span class="trinket-i
lvl">${it.label}</span>`
          : `<span class="chart-label">${it.
label}</span>`;
      let chartDisplay = display;
      let tooltip = display;
      if (comparisonType === "trinket" && it
.percent != null) {
        const percentDisplay = `+${it.percen
t.toFixed(1)}%`;
        const dpsIncreaseDisplay = `+${Math.
round((it as any).dpsIncrease || 0).toLocale
String()}`;
        if (String(effectiveSort) === "perce
nt") {
          chartDisplay = percentDisplay;
          tooltip = `${percentDisplay} (${di
splay} DPS)`;
        } else if (String(effectiveSort) ===
 "stdev") {
          chartDisplay = Math.round(it.stdev
).toLocaleString();
          tooltip = `${chartDisplay} StdDev 
(${display} DPS avg, lower is more consisten
t)`;
        } else {
          chartDisplay = dpsIncreaseDisplay;
          tooltip =
            String(effectiveSort) === "dps"
              ? `${display} DPS (${dpsIncrea
seDisplay} vs baseline)`
              : `${display} (Avg: ${display}
 DPS, ${dpsIncreaseDisplay} vs baseline)`;
        }
      }
      return `
      <div class="chart-item-wrapper" data-i
ndex="${idx}">
        <div class="chart-item-header">
          <div class="chart-item chart-item-
comparison">
            <div class="chart-labels">
              <span class="chart-rank">#${id
x + 1}</span>
              ${labelContent}
            </div>
            <div class="chart-bar-container"
>
              <div class="chart-bar-track">
                <div class="chart-bar" style
="width: ${width}%; background: ${barColor};
"></div>
              </div>
              <div class="chart-value" title
="${tooltip}">${comparisonType === "trinket"
 && String(effectiveSort) === "percent" ? (i
t.percent === 0 ? "Baseline" : `+${(it.perce
nt || 0).toFixed(1)}%`) : chartDisplay}</div
>
            </div>
          </div>
        </div>
        ${hasDropdown ? `<div class="chart-d
ropdown">${dropdownHtml}</div>` : ""}
      </div>`;
    })
    .join("");
  const titles: Record<string, string> = {
    dps: `${comparisonType === "race" ? "Rac
e" : "Trinket"} DPS Rankings (Average)`,
    max: `${comparisonType === "race" ? "Rac
e" : "Trinket"} DPS Rankings (Maximum)`,
    min: `${comparisonType === "race" ? "Rac
e" : "Trinket"} DPS Rankings (Minimum)`,
    stdev: `${comparisonType === "race" ? "R
ace" : "Trinket"} DPS Consistency Rankings (
Low StdDev = More Consistent)`,
    percent: `${comparisonType === "race" ? 
"Race" : "Trinket"} Performance Rankings (% 
Increase)`,
  };
  const title =
    titles[String(effectiveSort)] ||
    `${comparisonType === "race" ? "Race" : 
"Trinket"} DPS Rankings`;
  return `<h2 class="card-title-large">${tit
le}</h2><div class="chart-bars">${bars}</div
>`;
}
 
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET