Skip to main content

SHARED_JS

Constant SHARED_JS 

Source
const SHARED_JS: &str = "\"use strict\";\n\nconst FONT = \"\'Geist\', system-ui, sans-serif\";\n\nconst PALETTE = [\n  \"oklch(0.77 0.16 70)\",\n  \"oklch(0.7 0.16 250)\",\n  \"oklch(0.72 0.13 154)\",\n  \"oklch(0.66 0.2 304)\",\n  \"oklch(0.7 0.16 42)\",\n  \"oklch(0.65 0.15 200)\",\n  \"oklch(0.85 0.14 85)\",\n  \"oklch(0.72 0.18 0)\",\n  \"oklch(0.78 0.13 130)\",\n  \"oklch(0.7 0.18 290)\",\n  \"oklch(0.75 0.15 65)\",\n  \"oklch(0.65 0.14 225)\",\n];\n\nconst FG = \"oklch(0.985 0.005 270)\";\nconst FG_MUTED = \"oklch(0.72 0.022 270)\";\nconst BORDER = \"oklch(0.985 0.005 270 / 0.18)\";\nconst GRID_LINE = \"oklch(0.985 0.005 270 / 0.08)\";\n\nconst AXIS_STYLE = {\n  axisLabel: { color: FG_MUTED, fontFamily: FONT, fontSize: 11 },\n  axisLine: { lineStyle: { color: BORDER } },\n  axisTick: { lineStyle: { color: BORDER } },\n  nameTextStyle: { color: FG_MUTED, fontFamily: FONT, fontSize: 11 },\n  splitLine: { lineStyle: { color: GRID_LINE } },\n};\n\nif (typeof echarts !== \"undefined\") {\n  echarts.registerTheme(\"wowlab-dark\", {\n    backgroundColor: \"transparent\",\n    categoryAxis: AXIS_STYLE,\n    color: PALETTE,\n    legend: {\n      textStyle: { color: FG_MUTED, fontFamily: FONT, fontSize: 11 },\n      type: \"scroll\",\n    },\n    textStyle: { color: FG, fontFamily: FONT, fontSize: 12 },\n    title: { textStyle: { color: FG, fontFamily: FONT } },\n    tooltip: {\n      backgroundColor: \"oklch(0.21 0.02 270 / 0.95)\",\n      borderColor: BORDER,\n      confine: true,\n      extraCssText:\n        \"box-shadow: 0 4px 12px rgba(0,0,0,0.4); backdrop-filter: blur(4px);\",\n      textStyle: { color: FG, fontFamily: FONT, fontSize: 12 },\n    },\n    valueAxis: AXIS_STYLE,\n  });\n}\n\nconst charts = {};\n\nconst prefersReducedMotion =\n  globalThis.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches ?? false;\n\nfunction initChart(el, opts) {\n  if (!el || !opts) {\n    return;\n  }\n  if (prefersReducedMotion) {\n    opts.animation = false;\n  }\n\n  const key = el.getAttribute(\"data-chart\") ?? el.id;\n  let chart = charts[key];\n  if (!chart || chart.isDisposed()) {\n    chart = echarts.init(el, \"wowlab-dark\");\n    charts[key] = chart;\n  }\n  chart.setOption(opts, { notMerge: true });\n}\n\nfunction initGlobalChart(chartId, dataId) {\n  const el = document.getElementById(chartId);\n  const script = document.getElementById(dataId);\n  if (el && script) {\n    initChart(el, parseJSON(script));\n  }\n}\n\nfunction parseJSON(el) {\n  try {\n    return JSON.parse(el.textContent);\n  } catch {\n    return null;\n  }\n}\n\nfunction resizeAll() {\n  for (const chart of Object.values(charts)) {\n    chart.resize();\n  }\n}\n\nfunction setupTabsKeyboard() {\n  const tablist = document.getElementById(\"report-tabs\");\n  if (!tablist) {\n    return;\n  }\n  const tabs = [...tablist.querySelectorAll(\'[role=\"tab\"]\')];\n  if (tabs.length === 0) {\n    return;\n  }\n\n  tablist.addEventListener(\"keydown\", (event) => {\n    const current = tabs.indexOf(document.activeElement);\n    if (current === -1) {\n      return;\n    }\n\n    const next = {\n      ArrowLeft: tabs[(current - 1 + tabs.length) % tabs.length],\n      ArrowRight: tabs[(current + 1) % tabs.length],\n      End: tabs.at(-1),\n      Home: tabs[0],\n    }[event.key];\n\n    if (!next) {\n      return;\n    }\n\n    event.preventDefault();\n    next.focus();\n    switchSection(next.dataset.tab);\n  });\n}\n\nfunction switchSection(id) {\n  const tablist = document.getElementById(\"report-tabs\");\n  for (const tab of tablist?.querySelectorAll(\'[role=\"tab\"]\') ?? []) {\n    const match = tab.dataset.tab === id;\n    tab.setAttribute(\"aria-selected\", match ? \"true\" : \"false\");\n    tab.setAttribute(\"tabindex\", match ? \"0\" : \"-1\");\n    tab.classList.toggle(\"is-active\", match);\n  }\n  for (const section of document.querySelectorAll(\".report-section\")) {\n    section.hidden = section.id !== `section-${id}`;\n  }\n  setTimeout(resizeAll, 50);\n}\n\nlet resizeTimer;\nwindow.addEventListener(\"resize\", () => {\n  clearTimeout(resizeTimer);\n  resizeTimer = setTimeout(resizeAll, 100);\n});\n\nsetupTabsKeyboard();\n";