// Bar layout and name wrapping adapted from BuildingBench figure-kit/bar-static/build.py. // Data is exclusively the existing Code4Scene data/site.js paper board; no reference benchmark scores. (async function(){ const {bindChartTooltip}=await import("./chart-interactions.js?v=20261004kit"); await Promise.all([document.fonts.load('400 13px Inter'),document.fonts.load('700 13px Inter'),document.fonts.load('500 15.5px "IBM Plex Mono"')]); const ALL = {"t2s": [{"name": "Claude Fable 5.1 (max)", "org": "Anthropic", "score": 0.78775, "colour": "#D97757", "ink": "#ffffff", "label": "79", "new": false}, {"name": "GPT-6 Astra (max)", "org": "OpenAI", "score": 0.72382, "colour": "#10A37F", "ink": "#ffffff", "label": "72", "new": false}, {"name": "Claude Opus 5 (max)", "org": "Anthropic", "score": 0.7181599999999999, "colour": "#D97757", "ink": "#ffffff", "label": "72", "new": false}, {"name": "GPT-5.6 Sol (high)", "org": "OpenAI", "score": 0.70704, "colour": "#10A37F", "ink": "#ffffff", "label": "71", "new": false}, {"name": "Gemini 3.8 Flash (high)", "org": "Google", "score": 0.65689, "colour": "#7b1fa2", "ink": "#ffffff", "label": "66", "new": false}, {"name": "Muse Spark 1.3 (medium)", "org": "Meta", "score": 0.646195, "colour": "#42a5f5", "ink": "#111111", "label": "65", "new": false}, {"name": "Grok 4.6 (high)", "org": "xAI", "score": 0.56721, "colour": "#111111", "ink": "#ffffff", "label": "57", "new": false}, {"name": "Qwen 3.8 27B (thinking off)", "org": "Alibaba", "score": 0.55666, "colour": "#fe7016", "ink": "#111111", "label": "56", "new": false}, {"name": "Qwen 3.8 27B (thinking on)", "org": "Alibaba", "score": 0.51571, "colour": "#fe7016", "ink": "#111111", "label": "52", "new": false}, {"name": "GLM-5.3 Flash (max)", "org": "Z.ai", "score": 0.5094299999999999, "colour": "#96650b", "ink": "#ffffff", "label": "51", "new": false}, {"name": "Gemma 4 31B (thinking on)", "org": "Google", "score": 0.470705, "colour": "#7b1fa2", "ink": "#ffffff", "label": "47", "new": false}, {"name": "Gemma 4 31B (thinking off)", "org": "Google", "score": 0.45494, "colour": "#7b1fa2", "ink": "#ffffff", "label": "45", "new": false}, {"name": "Inkling (high)", "org": "Thinking Machines", "score": 0.42498500000000006, "colour": "#686868", "ink": "#ffffff", "label": "42", "new": false}, {"name": "DeepSeek V4.1 Flash (high)", "org": "DeepSeek", "score": 0.24269, "colour": "#3f51e0", "ink": "#ffffff", "label": "24", "new": false}], "i2s": [{"name": "Gemini 3.8 Flash (high)", "org": "Google", "score": 0.5810600533333334, "colour": "#7b1fa2", "ink": "#ffffff", "label": "58", "new": false}, {"name": "GPT-6 Astra (max)", "org": "OpenAI", "score": 0.5148505733333334, "colour": "#10A37F", "ink": "#ffffff", "label": "51", "new": false}, {"name": "Claude Opus 5 (max)", "org": "Anthropic", "score": 0.46809998666666675, "colour": "#D97757", "ink": "#ffffff", "label": "47", "new": false}, {"name": "Claude Fable 5.1 (max)", "org": "Anthropic", "score": 0.4243479600000001, "colour": "#D97757", "ink": "#ffffff", "label": "42", "new": false}, {"name": "GPT-5.6 Sol (high)", "org": "OpenAI", "score": 0.3929589333333333, "colour": "#10A37F", "ink": "#ffffff", "label": "39", "new": false}, {"name": "Muse Spark 1.3 (medium)", "org": "Meta", "score": 0.35821573333333334, "colour": "#42a5f5", "ink": "#111111", "label": "36", "new": false}, {"name": "GLM-5.3 Flash (max)", "org": "Z.ai", "score": 0.3199877333333333, "colour": "#96650b", "ink": "#ffffff", "label": "32", "new": false}, {"name": "Qwen 3.8 27B (thinking on)", "org": "Alibaba", "score": 0.2261779866666667, "colour": "#fe7016", "ink": "#111111", "label": "23", "new": false}, {"name": "DeepSeek V4.1 Flash (high)", "org": "DeepSeek", "score": 0.21048916, "colour": "#3f51e0", "ink": "#ffffff", "label": "21", "new": false}, {"name": "Qwen 3.8 27B (thinking off)", "org": "Alibaba", "score": 0.19970338666666668, "colour": "#fe7016", "ink": "#111111", "label": "20", "new": false}, {"name": "Inkling (high)", "org": "Thinking Machines", "score": 0.19801974666666666, "colour": "#686868", "ink": "#ffffff", "label": "20", "new": false}, {"name": "Grok 4.6 (high)", "org": "xAI", "score": 0.18414012, "colour": "#111111", "ink": "#ffffff", "label": "18", "new": false}, {"name": "Gemma 4 31B (thinking on)", "org": "Google", "score": 0.12554015999999998, "colour": "#7b1fa2", "ink": "#ffffff", "label": "13", "new": false}, {"name": "Gemma 4 31B (thinking off)", "org": "Google", "score": 0.11503794666666667, "colour": "#7b1fa2", "ink": "#ffffff", "label": "12", "new": false}]}; const LOGOS = {"Anthropic": {"icon": "anthropic", "fill": "#141413", "viewBox": "0 0 24 24", "inner": "", "rule": "evenodd"}, "OpenAI": {"icon": "openai", "fill": "#141413", "viewBox": "0 0 24 24", "inner": "", "rule": "evenodd"}, "Meta": {"icon": "meta-color", "viewBox": "0 0 24 24", "inner": "", "rule": null}, "Google": {"icon": "google-color", "viewBox": "0 0 24 24", "inner": "", "rule": null}, "DeepSeek": {"icon": "deepseek-color", "viewBox": "0 0 24 24", "inner": "", "rule": null}, "xAI": {"icon": "xai", "tile": "#111111", "shape": "square", "viewBox": "0 0 24 24", "inner": "", "rule": "evenodd"}, "Z.ai": {"icon": "zai", "tile": "#111111", "shape": "square", "viewBox": "0 0 24 24", "inner": "", "rule": "evenodd"}, "Moonshot": {"icon": "kimi", "tile": "#111111", "shape": "square", "viewBox": "0 0 24 24", "inner": "", "rule": "evenodd"}, "StepFun": {"icon": "stepfun", "tile": "#01d9cf", "shape": "circle", "viewBox": "0 0 24 24", "inner": "", "rule": "evenodd"}, "Undisclosed": {"icon": "unionalpha-color", "viewBox": "0 0 24 24", "inner": "", "rule": null}, "Cognition": {"icon": "devin-color", "viewBox": "0 0 24 24", "inner": "", "rule": null}, "Fireworks": {"icon": "fireworks-color", "viewBox": "0 0 24 24", "inner": "", "rule": null}, "Stealth": {"wordmark": ["STEALTH"]}, "Thinking Machines": {"wordmark": ["THINKING", "MACHINES"]}, "Alibaba": {"icon": "qwen-color", "viewBox": "0 0 24 24", "inner": "", "rule": null}}; for(const [key,DATA] of Object.entries(ALL)){ const svg=document.getElementById('bars-'+key), W=1200, H=420; const NS='http://www.w3.org/2000/svg', SANS='Inter, Arial, sans-serif', MONO='"IBM Plex Mono", monospace'; const G = { // geometry, CSS px left: 40, right: 24, top: 26, // the 100 gridline base: 248, // zero barFill: 0.62, // bar width / pitch, as measured off the reference radius: 4.5, // rounded top corners logo: 18, logoGap: 8, // logo box, and its gap under the baseline nameGap: 9, // gap from logo to the end of the name nameAngle: -60, // degrees nameSize: 13, nameLead: 14.5, nameOneLine: 97, // a name this wide or less stays on one line nameLine: 93, // otherwise, no wrapped line wider than this nameTol: 12, // splits this close to the most balanced count as ties }; let current=null; function el(tag, attrs, parent) { const e = document.createElementNS(NS, tag); for (const k in attrs) e.setAttribute(k, attrs[k]); (parent || current || svg).appendChild(e); return e; } const ctx = document.createElement("canvas").getContext("2d"); function width(text, font) { ctx.font = font; return ctx.measureText(text).width; } // Wrap a name the way the reference does: one line when it fits; otherwise the // fewest lines (2, then 3) that keep every line within nameLine. Among those, // the most balanced split wins -- and splits within nameTol of it count as // equally balanced, the tie going to the longer last line: the lines are // right-aligned against the logo, so the weight belongs at the end // ("DeepSeek / V4.1 / Flash (max)", not "... / V4.1 Flash / (max)"). function wrap(name, font) { if (width(name, font) <= G.nameOneLine) return [name]; const w = name.split(" "); const splits = k => { const out = []; if (k === 2) for (let i = 1; i < w.length; i++) out.push([w.slice(0, i), w.slice(i)]); if (k === 3) for (let i = 1; i < w.length; i++) for (let j = i + 1; j < w.length; j++) out.push([w.slice(0, i), w.slice(i, j), w.slice(j)]); return out.map(p => p.map(x => x.join(" "))); }; for (const k of [2, 3]) { const c = splits(k).map(lines => { const ws = lines.map(l => width(l, font)); return {lines, worst: Math.max(...ws), last: ws[ws.length - 1]}; }).filter(o => o.worst <= G.nameLine); if (!c.length) continue; const floor = Math.min(...c.map(o => o.worst)); return c.filter(o => o.worst <= floor + G.nameTol).sort((a, b) => b.last - a.last)[0].lines; } return [name]; } // A boxed name: at most two lines -- a three-line box is thicker than the spacing // between neighbouring names at this bar count -- the most balanced split, ties // to the longer last line. function wrap2(name, font) { if (width(name, font) <= G.nameOneLine) return [name]; const w = name.split(" "), c = []; for (let i = 1; i < w.length; i++) { const lines = [w.slice(0, i).join(" "), w.slice(i).join(" ")], ws = lines.map(l => width(l, font)); c.push({lines, worst: Math.max(...ws), last: ws[1]}); } const floor = Math.min(...c.map(o => o.worst)); return c.filter(o => o.worst <= floor + G.nameTol).sort((a, b) => b.last - a.last)[0].lines; } // -- grid --------------------------------------------------------------------- const y = v => G.base - v / 100 * (G.base - G.top); for (const v of [25, 50, 75, 100]) el("line", {x1: G.left - 8, x2: W - G.right, y1: y(v), y2: y(v), stroke: "#cfcfcf", "stroke-width": 1.4, "stroke-dasharray": "0.1 4.2", "stroke-linecap": "round"}); el("line", {x1: G.left - 8, x2: W - G.right, y1: G.base, y2: G.base, stroke: "#e6e6e6", "stroke-width": 1}); // -- bars --------------------------------------------------------------------- const n = DATA.length, pitch = (W - G.left - G.right) / n, bwid = pitch * G.barFill; const pos = {}; DATA.forEach((d, i) => { const cx = G.left + (i + 0.5) * pitch, x0 = cx - bwid / 2, x1 = cx + bwid / 2; const top = y(d.score * 100), r = Math.min(G.radius, bwid / 2); pos[d.name] = {cx, top, x0, x1}; current=el('g',{'class':'bar-node'},svg); el('rect',{x:G.left+i*pitch,y:G.top,width:pitch,height:H-G.top,fill:'transparent','class':'bar-hit'}); bindChartTooltip(current,svg,d.name,key,'.bar'); const bar = el("path", {class:"bar", d: `M${x0},${G.base} V${top + r} Q${x0},${top} ${x0 + r},${top} H${x1 - r} ` + `Q${x1},${top} ${x1},${top + r} V${G.base} Z`, fill: d.colour}); const v = el("text", {x: cx, y: (top + G.base) / 2 + 5.4, "text-anchor": "middle", "font-family": MONO, "font-weight": 500, "font-size": 15.5, fill: d.ink}); v.textContent = d.label; // logo const L = LOGOS[d.org], s = G.logo, lx = cx - s / 2, ly = G.base + G.logoGap; if (L.wordmark) { L.wordmark.forEach((w, k) => { const tw = el("text", {x: cx, y: ly + 7.5 + k * 6.2, "text-anchor": "middle", "font-family": SANS, "font-weight": 500, "font-size": 5.2, "letter-spacing": 0.35, fill: "#4a4a4a"}); tw.textContent = w; }); } else { let pad = 0, fill = L.fill || null; if (L.tile) { if (L.shape === "circle") el("circle", {cx, cy: ly + s / 2, r: s / 2, fill: L.tile}); else el("rect", {x: lx, y: ly, width: s, height: s, rx: 3.2, fill: L.tile}); pad = 3.4; fill = "#ffffff"; } const ic = el("svg", {x: lx + pad, y: ly + pad, width: s - 2 * pad, height: s - 2 * pad, viewBox: L.viewBox}); if (fill) { ic.setAttribute("fill", fill); ic.setAttribute("color", fill); } if (L.rule) ic.setAttribute("fill-rule", L.rule); ic.innerHTML = L.inner; } // name: rotated, right-aligned against the logo, wrapped const wt = d.new ? 700 : 400; const font = `${wt} ${G.nameSize}px ${SANS}`; const lines = d.new ? wrap2(d.name, font) : wrap(d.name, font); const ax = cx + 3, ay = G.base + G.logoGap + G.logo + G.nameGap + (d.new ? 5 : 0); const g = el("g", {transform: `translate(${ax},${ay}) rotate(${G.nameAngle})`}); const off = -(lines.length - 1) / 2 * G.nameLead; if (d.new) { // the model this figure is about: white on a box of its own colour const bw_ = Math.max(...lines.map(l => width(l, font))); const y0_ = off + 4.5 - 0.80 * G.nameSize - 2.5, y1_ = off + (lines.length - 1) * G.nameLead + 4.5 + 0.24 * G.nameSize + 2.5; el("rect", {x: -bw_ - 5, y: y0_, width: bw_ + 10, height: y1_ - y0_, rx: 4, fill: d.colour}, g); } lines.forEach((ln, k) => { const tl = el("text", {x: 0, y: off + k * G.nameLead + 4.5, "text-anchor": "end", "font-family": SANS, "font-weight": wt, "font-size": G.nameSize, fill: d.new ? "#ffffff" : "#262626"}, g); tl.textContent = ln; }); }); current=null;svg.dataset.ready='true'; } })();