Spaces:
Running
Running
Upload viewer
Browse files- index.html +1116 -249
index.html
CHANGED
|
@@ -1,292 +1,1159 @@
|
|
| 1 |
<!doctype html>
|
| 2 |
-
<html lang="en">
|
| 3 |
<head>
|
| 4 |
<meta charset="utf-8" />
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 6 |
<title>SFT v4 Dataset Viewer</title>
|
| 7 |
-
<link rel="stylesheet" href="vendor/katex.min.css" />
|
| 8 |
-
<script src="vendor/katex.min.js"></script>
|
| 9 |
-
<script src="vendor/marked.min.js"></script>
|
| 10 |
<style>
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
:
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
</style>
|
| 98 |
</head>
|
| 99 |
<body>
|
| 100 |
-
<header>
|
| 101 |
-
<h1>SFT v4 Dataset Viewer</h1>
|
| 102 |
-
<span class="sub" id="hdr">loading…</span>
|
| 103 |
-
<span class="spacer"></span>
|
| 104 |
-
<button class="theme" onclick="toggleTheme()">theme</button>
|
| 105 |
-
</header>
|
| 106 |
|
| 107 |
-
<
|
| 108 |
-
<
|
| 109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
</div>
|
| 111 |
|
|
|
|
| 112 |
<script>
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
document.documentElement.setAttribute("data-theme", dark ? "light" : "dark");
|
| 121 |
-
}
|
| 122 |
-
const escapeHtml = s => (s||"").replace(/[&<>"']/g, c =>
|
| 123 |
-
({"&":"&","<":"<",">":">",'"':""","'":"'"}[c]));
|
| 124 |
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
{ re: /\$\$([\s\S]+?)\$\$/g, display: true },
|
| 129 |
-
{ re: /\\\[([\s\S]+?)\\\]/g, display: true },
|
| 130 |
-
{ re: /\\\(([\s\S]+?)\\\)/g, display: false },
|
| 131 |
-
{ re: /(?<![\\$])\$(?!\$)([^\n$]+?)\$(?!\$)/g, display: false },
|
| 132 |
];
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
}
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
}
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 151 |
}
|
| 152 |
-
function prose(t){ const d=document.createElement("div"); d.className="prose";
|
| 153 |
-
d.innerHTML=md(t||""); return d; }
|
| 154 |
|
| 155 |
-
//
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 165 |
return out;
|
| 166 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 167 |
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
el.
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
});
|
| 184 |
}
|
| 185 |
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
}
|
| 208 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
<span class="tag">${kept} retained</span></summary>`;
|
| 217 |
-
const body=document.createElement("div"); body.className="body";
|
| 218 |
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
box.appendChild(prose(t.think));
|
| 224 |
-
if(t.dirs.length){
|
| 225 |
-
const h=document.createElement("h3"); h.textContent="committed directions";
|
| 226 |
-
box.appendChild(h);
|
| 227 |
-
t.dirs.forEach(d=>box.appendChild(prose("- "+d)));
|
| 228 |
-
}
|
| 229 |
-
if(L.mr_fragments.length){
|
| 230 |
-
const f=document.createElement("div"); f.style.marginTop="8px";
|
| 231 |
-
f.innerHTML = L.mr_fragments.map(x=>
|
| 232 |
-
`<span class="frag ${x.disposition==="selected"?"sel":"rej"}">${escapeHtml(x.candidate_id||"?")} · ${escapeHtml(x.disposition||"")}</span>`
|
| 233 |
-
).join("");
|
| 234 |
-
box.appendChild(f);
|
| 235 |
-
}
|
| 236 |
-
body.appendChild(box);
|
| 237 |
-
}
|
| 238 |
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 247 |
});
|
|
|
|
|
|
|
|
|
|
| 248 |
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
}
|
| 255 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 256 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 257 |
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 263 |
}
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 272 |
}
|
| 273 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 274 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 275 |
}
|
| 276 |
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
|
| 284 |
-
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 290 |
</script>
|
| 291 |
</body>
|
| 292 |
</html>
|
|
|
|
| 1 |
<!doctype html>
|
| 2 |
+
<html lang="en" data-theme="dark">
|
| 3 |
<head>
|
| 4 |
<meta charset="utf-8" />
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 6 |
<title>SFT v4 Dataset Viewer</title>
|
|
|
|
|
|
|
|
|
|
| 7 |
<style>
|
| 8 |
+
*,*::before,*::after{box-sizing:border-box}
|
| 9 |
+
:root{
|
| 10 |
+
color-scheme:dark;
|
| 11 |
+
--bg:#14161b; --panel:#1b1e26; --panel2:#22262f; --panel3:#2a2f3a;
|
| 12 |
+
--line:#333a49; --fg:#e7e9ef; --dim:#a3aabb; --faint:#7d8595;
|
| 13 |
+
--accent:#7aa2f7; --good:#79dd8a; --bad:#ff8078; --warn:#f2c66a;
|
| 14 |
+
--info:#6fd0e2; --muted:#8f97a8; --guided:#c4a2ff; --mark:#ffd866;
|
| 15 |
+
--shadow:0 1px 2px rgba(0,0,0,.4);
|
| 16 |
+
}
|
| 17 |
+
:root[data-theme="light"]{
|
| 18 |
+
color-scheme:light;
|
| 19 |
+
--bg:#f6f7f9; --panel:#ffffff; --panel2:#f0f2f6; --panel3:#e4e8ef;
|
| 20 |
+
--line:#d3d9e3; --fg:#161a21; --dim:#4d5566; --faint:#6b7385;
|
| 21 |
+
--accent:#2c5fd0; --good:#1c7a3a; --bad:#c02a20; --warn:#8a6100;
|
| 22 |
+
--info:#116b7c; --muted:#5e6678; --guided:#6b3fc4; --mark:#ffe066;
|
| 23 |
+
--shadow:0 1px 2px rgba(16,24,40,.08);
|
| 24 |
+
}
|
| 25 |
+
html,body{margin:0;padding:0}
|
| 26 |
+
body{
|
| 27 |
+
background:var(--bg); color:var(--fg); font:14px/1.55 -apple-system,BlinkMacSystemFont,
|
| 28 |
+
"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
|
| 29 |
+
}
|
| 30 |
+
button,input,select{font:inherit;color:inherit}
|
| 31 |
+
.hidden{display:none !important}
|
| 32 |
+
a{color:var(--accent)}
|
| 33 |
+
|
| 34 |
+
header.top{
|
| 35 |
+
position:sticky; top:0; z-index:20; background:var(--panel); border-bottom:1px solid var(--line);
|
| 36 |
+
padding:8px 14px; display:flex; flex-direction:column; gap:8px;
|
| 37 |
+
}
|
| 38 |
+
.top-row{display:flex; flex-wrap:wrap; align-items:center; gap:8px}
|
| 39 |
+
.brand{font-weight:700; letter-spacing:.02em}
|
| 40 |
+
.brand span{color:var(--dim); font-weight:400; margin-left:8px; font-size:12px}
|
| 41 |
+
.spacer{flex:1 1 auto}
|
| 42 |
+
.ctl{
|
| 43 |
+
background:var(--panel2); border:1px solid var(--line); color:var(--fg);
|
| 44 |
+
border-radius:6px; padding:4px 9px; cursor:pointer; font-size:12px; white-space:nowrap;
|
| 45 |
+
}
|
| 46 |
+
.ctl:hover{background:var(--panel3)}
|
| 47 |
+
.ctl.on{background:var(--accent); border-color:var(--accent); color:#0b1220; font-weight:600}
|
| 48 |
+
:root[data-theme="light"] .ctl.on{color:#fff}
|
| 49 |
+
.ctl.tiny{padding:2px 7px; font-size:11px}
|
| 50 |
+
.group{display:flex; flex-wrap:wrap; align-items:center; gap:4px}
|
| 51 |
+
.group-label{color:var(--faint); font-size:11px; text-transform:uppercase; letter-spacing:.08em; margin-right:2px}
|
| 52 |
+
input[type=text],input[type=search]{
|
| 53 |
+
background:var(--panel2); border:1px solid var(--line); border-radius:6px; padding:4px 8px; min-width:180px;
|
| 54 |
+
}
|
| 55 |
+
.hitcount{font-size:11px; color:var(--dim); min-width:70px}
|
| 56 |
+
|
| 57 |
+
.app{display:flex; align-items:flex-start; gap:0}
|
| 58 |
+
.sidebar{
|
| 59 |
+
width:330px; flex:0 0 330px; border-right:1px solid var(--line); background:var(--panel);
|
| 60 |
+
position:sticky; top:0; max-height:100vh; overflow:auto; padding:10px;
|
| 61 |
+
}
|
| 62 |
+
.runstats{font-size:11px; color:var(--dim); line-height:1.7; margin-bottom:8px}
|
| 63 |
+
.runstats b{color:var(--fg)}
|
| 64 |
+
.side-h{font-size:11px; text-transform:uppercase; letter-spacing:.08em; color:var(--faint); margin:12px 0 6px}
|
| 65 |
+
.traj{
|
| 66 |
+
display:block; width:100%; text-align:left; background:var(--panel2); border:1px solid var(--line);
|
| 67 |
+
border-left:3px solid var(--line); border-radius:6px; padding:6px 8px; margin-bottom:6px; cursor:pointer;
|
| 68 |
+
}
|
| 69 |
+
.traj:hover{background:var(--panel3)}
|
| 70 |
+
.traj.sel{border-left-color:var(--accent); background:var(--panel3)}
|
| 71 |
+
.traj.superseded{opacity:.62; border-style:dashed}
|
| 72 |
+
.traj .tid{font-weight:600; font-size:12px; word-break:break-all}
|
| 73 |
+
.traj .row{display:flex; flex-wrap:wrap; gap:4px; margin-top:4px}
|
| 74 |
+
|
| 75 |
+
.badge{
|
| 76 |
+
display:inline-block; font-size:10.5px; line-height:1.5; padding:1px 6px; border-radius:999px;
|
| 77 |
+
border:1px solid currentColor; white-space:nowrap;
|
| 78 |
+
}
|
| 79 |
+
.b-good{color:var(--good)} .b-bad{color:var(--bad)} .b-warn{color:var(--warn)}
|
| 80 |
+
.b-info{color:var(--info)} .b-muted{color:var(--muted)} .b-guided{color:var(--guided)}
|
| 81 |
+
.b-accent{color:var(--accent)} .b-plain{color:var(--dim)}
|
| 82 |
+
.badge.solid{background:currentColor}
|
| 83 |
+
.badge.solid span{color:var(--panel); font-weight:700}
|
| 84 |
+
|
| 85 |
+
main{flex:1 1 auto; min-width:0; padding:12px 16px 120px}
|
| 86 |
+
.card{
|
| 87 |
+
background:var(--panel); border:1px solid var(--line); border-radius:8px;
|
| 88 |
+
margin:0 0 10px; box-shadow:var(--shadow); overflow:hidden;
|
| 89 |
+
}
|
| 90 |
+
.card>.card-h{
|
| 91 |
+
display:flex; flex-wrap:wrap; align-items:center; gap:6px; padding:7px 10px;
|
| 92 |
+
background:var(--panel2); border-bottom:1px solid var(--line); font-weight:600; font-size:13px;
|
| 93 |
+
}
|
| 94 |
+
.card>.card-b{padding:9px 10px}
|
| 95 |
+
.card.nested{margin:8px 0 0; background:var(--panel2)}
|
| 96 |
+
.card.nested>.card-h{background:var(--panel3)}
|
| 97 |
+
details.card>summary{
|
| 98 |
+
list-style:none; cursor:pointer; display:flex; flex-wrap:wrap; align-items:center; gap:6px;
|
| 99 |
+
padding:7px 10px; background:var(--panel2); border-bottom:1px solid transparent; font-weight:600; font-size:13px;
|
| 100 |
+
}
|
| 101 |
+
details.card[open]>summary{border-bottom-color:var(--line)}
|
| 102 |
+
details.card>summary::-webkit-details-marker{display:none}
|
| 103 |
+
details.card>summary::before{content:"\25B8"; color:var(--faint); margin-right:2px}
|
| 104 |
+
details.card[open]>summary::before{content:"\25BE"}
|
| 105 |
+
.layer.card{border-color:var(--line)}
|
| 106 |
+
.layer.guided-layer{border-left:3px solid var(--guided)}
|
| 107 |
+
.cand{border-left:3px solid var(--line)}
|
| 108 |
+
.cand.guided-cand{border-left-color:var(--guided)}
|
| 109 |
+
.cand:target,.flash{animation:flash 1.4s ease-out}
|
| 110 |
+
@keyframes flash{from{background:rgba(122,162,247,.28)} to{background:transparent}}
|
| 111 |
+
|
| 112 |
+
.meta{display:flex; flex-wrap:wrap; gap:4px 14px; font-size:11.5px; color:var(--dim); margin:2px 0 6px}
|
| 113 |
+
.meta b{color:var(--fg); font-weight:600}
|
| 114 |
+
.lbl{font-size:11px; text-transform:uppercase; letter-spacing:.07em; color:var(--faint); margin:8px 0 3px}
|
| 115 |
+
.lbl:first-child{margin-top:0}
|
| 116 |
+
ul.plain{margin:2px 0 6px; padding-left:18px}
|
| 117 |
+
ul.plain li{margin:2px 0}
|
| 118 |
+
.err{
|
| 119 |
+
background:rgba(255,128,120,.14); border:1px solid var(--bad); color:var(--bad);
|
| 120 |
+
border-radius:6px; padding:5px 8px; margin:6px 0; font-size:12px; font-weight:600;
|
| 121 |
+
white-space:pre-wrap; word-break:break-word;
|
| 122 |
+
}
|
| 123 |
+
.err-h{font-weight:700; margin-bottom:3px}
|
| 124 |
+
.err-b{font-weight:600; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
|
| 125 |
+
font-size:11.5px; margin-bottom:3px}
|
| 126 |
+
.err-f{font-weight:400; font-style:italic; opacity:.85}
|
| 127 |
+
.empty{color:var(--faint); font-style:italic; font-size:12px}
|
| 128 |
+
.cid{
|
| 129 |
+
font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:11.5px;
|
| 130 |
+
background:var(--panel3); border:1px solid var(--line); border-radius:5px; padding:0 5px;
|
| 131 |
+
cursor:pointer; color:var(--accent);
|
| 132 |
+
}
|
| 133 |
+
.cid.plain{color:var(--dim); cursor:default}
|
| 134 |
+
|
| 135 |
+
.tb{margin:3px 0 8px}
|
| 136 |
+
.txt{
|
| 137 |
+
font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
|
| 138 |
+
font-size:12.5px; line-height:1.62; white-space:pre-wrap; word-break:break-word;
|
| 139 |
+
background:var(--panel2); border:1px solid var(--line); border-radius:6px; padding:8px 10px;
|
| 140 |
+
overflow-x:auto; position:relative;
|
| 141 |
+
}
|
| 142 |
+
.txt.prose{font-family:inherit; font-size:13px; line-height:1.6}
|
| 143 |
+
.txt.clamped{max-height:16em; overflow:hidden}
|
| 144 |
+
.tb.clamp-on .txt.clamped::after{
|
| 145 |
+
content:""; position:absolute; left:0; right:0; bottom:0; height:3.2em; pointer-events:none;
|
| 146 |
+
background:linear-gradient(to bottom,transparent,var(--panel2));
|
| 147 |
+
}
|
| 148 |
+
.tb-tools{display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin-top:3px}
|
| 149 |
+
.tb-note{font-size:11px; color:var(--faint)}
|
| 150 |
+
mark{background:var(--mark); color:#171717; border-radius:2px}
|
| 151 |
+
mark.here{outline:2px solid var(--accent)}
|
| 152 |
+
|
| 153 |
+
table.grid{border-collapse:collapse; width:100%; font-size:12.5px; margin:4px 0 6px}
|
| 154 |
+
table.grid th,table.grid td{border:1px solid var(--line); padding:4px 7px; text-align:left; vertical-align:top}
|
| 155 |
+
table.grid th{background:var(--panel2); font-weight:600; font-size:11px; text-transform:uppercase;
|
| 156 |
+
letter-spacing:.05em; color:var(--faint)}
|
| 157 |
+
.wrap-scroll{overflow-x:auto}
|
| 158 |
+
|
| 159 |
+
@media (max-width:900px){
|
| 160 |
+
/* stretch, not flex-start: in a column flex box flex-start sizes children to
|
| 161 |
+
max-content and the page would scroll sideways */
|
| 162 |
+
.app{flex-direction:column; align-items:stretch}
|
| 163 |
+
.sidebar{flex:none; max-height:44vh; border-right:none; border-bottom:1px solid var(--line);
|
| 164 |
+
position:static; width:100%}
|
| 165 |
+
main{padding:10px; width:100%}
|
| 166 |
+
.card-h,details.card>summary{word-break:break-word}
|
| 167 |
+
.meta span,.meta b{min-width:0; word-break:break-word}
|
| 168 |
+
input[type=text],input[type=search]{min-width:120px}
|
| 169 |
+
}
|
| 170 |
</style>
|
| 171 |
</head>
|
| 172 |
<body>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
|
| 174 |
+
<header class="top">
|
| 175 |
+
<div class="top-row">
|
| 176 |
+
<div class="brand">SFT v4 Dataset Viewer<span id="run-name"></span></div>
|
| 177 |
+
<div class="spacer"></div>
|
| 178 |
+
<button class="ctl on" id="cot" title="Collapse everything before </think>">CoT hidden</button>
|
| 179 |
+
<button class="ctl" id="raw" title="Open every raw provider output block">Raw hidden</button>
|
| 180 |
+
<button class="ctl" id="expand-all">Expand all</button>
|
| 181 |
+
<button class="ctl" id="collapse-layers">Collapse layers</button>
|
| 182 |
+
<button class="ctl" id="theme">Light theme</button>
|
| 183 |
+
</div>
|
| 184 |
+
<div class="top-row">
|
| 185 |
+
<span class="group-label">stages</span>
|
| 186 |
+
<span class="group" id="stage-chips"></span>
|
| 187 |
+
<button class="ctl tiny" id="stages-all">all</button>
|
| 188 |
+
<button class="ctl tiny" id="stages-none">none</button>
|
| 189 |
+
<div class="spacer"></div>
|
| 190 |
+
<input type="search" id="search" placeholder="search this trajectory" />
|
| 191 |
+
<button class="ctl tiny" id="prev">prev</button>
|
| 192 |
+
<button class="ctl tiny" id="next">next</button>
|
| 193 |
+
<button class="ctl tiny" id="only-matches">only matches</button>
|
| 194 |
+
<span class="hitcount" id="hits"></span>
|
| 195 |
+
</div>
|
| 196 |
+
</header>
|
| 197 |
+
<div class="app">
|
| 198 |
+
<aside class="sidebar">
|
| 199 |
+
<div class="runstats" id="stats"></div>
|
| 200 |
+
<div class="runstats" id="gen"></div>
|
| 201 |
+
<input type="text" id="traj-filter" placeholder="filter trajectories" style="width:100%" />
|
| 202 |
+
<div class="side-h">Trajectories</div>
|
| 203 |
+
<div id="traj-list"></div>
|
| 204 |
+
<div class="side-h hidden" id="filtered-h">Filtered out by F0</div>
|
| 205 |
+
<div id="filtered-list"></div>
|
| 206 |
+
</aside>
|
| 207 |
+
<main id="main"></main>
|
| 208 |
</div>
|
| 209 |
|
| 210 |
+
<script src="data/run-data.js"></script>
|
| 211 |
<script>
|
| 212 |
+
'use strict';
|
| 213 |
+
var DATA = window.__RUN_DATA__;
|
| 214 |
+
var THINK_OPEN = '<think>';
|
| 215 |
+
var THINK_CLOSE = '</think>';
|
| 216 |
+
var MAX_MARKS_PER_BLOCK = 300;
|
| 217 |
+
var LAZY_MIN = 24000; // chars: bigger blocks are only materialised on demand
|
| 218 |
+
var CLAMP_MIN = 700; // chars: shorter blocks need no expand control
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
|
| 220 |
+
var STAGES = [
|
| 221 |
+
['f0','F0'],['f1','F1'],['f2','F2'],['f3','F3'],['f4','F4'],['f5','F5'],
|
| 222 |
+
['answer','Final answer'],['judge','Judge'],['mr','MR target'],['term','Termination']
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
];
|
| 224 |
+
var CONTRIB_CLASS = {
|
| 225 |
+
new_information:'b-good', closes_gap:'b-good', correction_or_stronger:'b-good',
|
| 226 |
+
independent_verification:'b-info', useful_negative:'b-warn', redundant:'b-muted',
|
| 227 |
+
no_result:'b-muted', flawed_execution:'b-bad'
|
| 228 |
+
};
|
| 229 |
+
var STATUS_CLASS = {present:'b-good', partial:'b-warn', missing:'b-bad', not_applicable:'b-muted'};
|
| 230 |
+
|
| 231 |
+
var state = {
|
| 232 |
+
uid:null, stages:new Set(STAGES.map(function(s){return s[0];})),
|
| 233 |
+
hideCot:true, showRaw:false, query:'', filterMatches:false
|
| 234 |
+
};
|
| 235 |
+
var blocks = [];
|
| 236 |
+
var markNodes = [];
|
| 237 |
+
var markPos = -1;
|
| 238 |
+
var explorationIndex = {}; // exploration_id -> anchor id
|
| 239 |
+
|
| 240 |
+
function $(sel){ return document.querySelector(sel); }
|
| 241 |
+
function el(tag, cls, text){
|
| 242 |
+
var node = document.createElement(tag);
|
| 243 |
+
if(cls) node.className = cls;
|
| 244 |
+
if(text !== undefined && text !== null && text !== '') node.textContent = String(text);
|
| 245 |
+
return node;
|
| 246 |
+
}
|
| 247 |
+
function badge(text, cls){ return el('span', 'badge ' + (cls || 'b-plain'), text); }
|
| 248 |
+
function num(x){ return (x === null || x === undefined) ? '—' : String(x); }
|
| 249 |
+
|
| 250 |
+
// ---------------------------------------------------------------- text blocks
|
| 251 |
+
function postThink(text){
|
| 252 |
+
var i = text.lastIndexOf(THINK_CLOSE);
|
| 253 |
+
if(i < 0) return null;
|
| 254 |
+
return text.slice(i + THINK_CLOSE.length).replace(/^\s+/, '');
|
| 255 |
+
}
|
| 256 |
+
function displayText(b){
|
| 257 |
+
if(b.cot && state.hideCot && !b.showCot){
|
| 258 |
+
var tail = postThink(b.text);
|
| 259 |
+
if(tail !== null) return tail;
|
| 260 |
+
}
|
| 261 |
+
return b.text;
|
| 262 |
+
}
|
| 263 |
+
function countMatches(hay, needle){
|
| 264 |
+
if(!needle) return 0;
|
| 265 |
+
var h = hay.toLowerCase(), n = needle.toLowerCase(), c = 0, i = h.indexOf(n);
|
| 266 |
+
while(i >= 0){ c++; i = h.indexOf(n, i + n.length); }
|
| 267 |
+
return c;
|
| 268 |
+
}
|
| 269 |
+
function paint(node, text, query){
|
| 270 |
+
node.textContent = '';
|
| 271 |
+
if(!query){ node.textContent = text; return 0; }
|
| 272 |
+
var h = text.toLowerCase(), n = query.toLowerCase();
|
| 273 |
+
var frag = document.createDocumentFragment(), from = 0, hits = 0, i = h.indexOf(n);
|
| 274 |
+
while(i >= 0 && hits < MAX_MARKS_PER_BLOCK){
|
| 275 |
+
if(i > from) frag.appendChild(document.createTextNode(text.slice(from, i)));
|
| 276 |
+
var m = el('mark'); m.textContent = text.slice(i, i + n.length); frag.appendChild(m);
|
| 277 |
+
from = i + n.length; hits++;
|
| 278 |
+
i = h.indexOf(n, from);
|
| 279 |
+
}
|
| 280 |
+
frag.appendChild(document.createTextNode(text.slice(from)));
|
| 281 |
+
node.appendChild(frag);
|
| 282 |
+
return hits;
|
| 283 |
+
}
|
| 284 |
+
function refreshBlock(b){
|
| 285 |
+
var text = displayText(b);
|
| 286 |
+
var q = state.query;
|
| 287 |
+
var hits = q ? countMatches(text, q) : 0;
|
| 288 |
+
// a match hiding below the fold (or inside an unloaded block) is useless
|
| 289 |
+
if(hits > 0 && b.lazy && !b.loaded){ b.loaded = true; b.autoExpanded = true; }
|
| 290 |
+
if(hits > 0 && !b.expanded){ b.expanded = true; b.autoExpanded = true; }
|
| 291 |
+
if(hits === 0 && b.autoExpanded){ b.expanded = false; b.autoExpanded = false; }
|
| 292 |
+
var long = text.length > CLAMP_MIN;
|
| 293 |
+
var clamp = long && !b.expanded;
|
| 294 |
+
if(b.lazy && !b.loaded){
|
| 295 |
+
b.node.textContent = '(' + text.length.toLocaleString() + ' characters — press Load to render)';
|
| 296 |
+
b.node.classList.remove('clamped');
|
| 297 |
+
b.wrap.classList.remove('clamp-on');
|
| 298 |
+
} else {
|
| 299 |
+
paint(b.node, text, q);
|
| 300 |
+
b.node.classList.toggle('clamped', clamp);
|
| 301 |
+
b.wrap.classList.toggle('clamp-on', clamp);
|
| 302 |
+
}
|
| 303 |
+
b.matches = hits;
|
| 304 |
+
if(b.expandBtn){
|
| 305 |
+
b.expandBtn.classList.toggle('hidden', !(long || b.lazy));
|
| 306 |
+
b.expandBtn.textContent = (b.lazy && !b.loaded)
|
| 307 |
+
? 'Load (' + text.length.toLocaleString() + ' chars)'
|
| 308 |
+
: (b.expanded ? 'Collapse' : 'Expand (' + text.length.toLocaleString() + ' chars)');
|
| 309 |
+
}
|
| 310 |
+
if(b.cotBtn){
|
| 311 |
+
var tail = postThink(b.text);
|
| 312 |
+
var hidden = b.text.length - (tail === null ? b.text.length : tail.length);
|
| 313 |
+
var isHiding = state.hideCot && !b.showCot && tail !== null;
|
| 314 |
+
b.cotBtn.textContent = isHiding ? 'show CoT (' + hidden.toLocaleString() + ' chars)' : 'hide CoT';
|
| 315 |
+
b.cotBtn.classList.toggle('on', !isHiding);
|
| 316 |
+
b.cotBtn.classList.toggle('hidden', tail === null && !(b.text.indexOf(THINK_OPEN) >= 0));
|
| 317 |
+
}
|
| 318 |
+
if(b.note) b.note.textContent = b.noteText || '';
|
| 319 |
+
}
|
| 320 |
+
function refreshAll(){
|
| 321 |
+
blocks.forEach(refreshBlock);
|
| 322 |
+
markNodes = Array.prototype.slice.call(document.querySelectorAll('#main mark'));
|
| 323 |
+
markPos = -1;
|
| 324 |
+
var total = blocks.reduce(function(a, b){ return a + b.matches; }, 0);
|
| 325 |
+
$('#hits').textContent = state.query ? (total + ' match' + (total === 1 ? '' : 'es')) : '';
|
| 326 |
+
applyMatchFilter();
|
| 327 |
+
}
|
| 328 |
+
function textBlock(parent, text, opts){
|
| 329 |
+
opts = opts || {};
|
| 330 |
+
text = (text === null || text === undefined) ? '' : String(text);
|
| 331 |
+
if(!text && opts.hideEmpty) return null;
|
| 332 |
+
var wrap = el('div', 'tb');
|
| 333 |
+
if(opts.label) wrap.appendChild(el('div', 'lbl', opts.label));
|
| 334 |
+
if(!text){
|
| 335 |
+
wrap.appendChild(el('div', 'empty', '(empty)'));
|
| 336 |
+
parent.appendChild(wrap);
|
| 337 |
+
return null;
|
| 338 |
}
|
| 339 |
+
var node = el('div', 'txt' + (opts.prose ? ' prose' : ''));
|
| 340 |
+
wrap.appendChild(node);
|
| 341 |
+
var tools = el('div', 'tb-tools');
|
| 342 |
+
// any block that actually carries a closed think span is CoT-toggleable,
|
| 343 |
+
// whether or not the caller expected reasoning in that field
|
| 344 |
+
var isCot = !!opts.cot || text.indexOf(THINK_CLOSE) >= 0;
|
| 345 |
+
var b = {
|
| 346 |
+
node:node, wrap:wrap, text:text, cot:isCot, expanded:!!opts.expanded,
|
| 347 |
+
showCot:false, lazy:text.length > LAZY_MIN, loaded:false, matches:0, autoExpanded:false,
|
| 348 |
+
noteText:opts.note || '', note:null, expandBtn:null, cotBtn:null
|
| 349 |
+
};
|
| 350 |
+
var expandBtn = el('button', 'ctl tiny', 'Expand');
|
| 351 |
+
expandBtn.addEventListener('click', function(){
|
| 352 |
+
if(b.lazy && !b.loaded){ b.loaded = true; b.expanded = true; }
|
| 353 |
+
else b.expanded = !b.expanded;
|
| 354 |
+
refreshBlock(b);
|
| 355 |
+
markNodes = Array.prototype.slice.call(document.querySelectorAll('#main mark'));
|
| 356 |
+
});
|
| 357 |
+
tools.appendChild(expandBtn);
|
| 358 |
+
b.expandBtn = expandBtn;
|
| 359 |
+
if(isCot){
|
| 360 |
+
var cotBtn = el('button', 'ctl tiny', 'show CoT');
|
| 361 |
+
cotBtn.addEventListener('click', function(){ b.showCot = !b.showCot; refreshBlock(b); });
|
| 362 |
+
tools.appendChild(cotBtn);
|
| 363 |
+
b.cotBtn = cotBtn;
|
| 364 |
+
}
|
| 365 |
+
var note = el('span', 'tb-note', opts.note || '');
|
| 366 |
+
tools.appendChild(note);
|
| 367 |
+
b.note = note;
|
| 368 |
+
wrap.appendChild(tools);
|
| 369 |
+
parent.appendChild(wrap);
|
| 370 |
+
blocks.push(b);
|
| 371 |
+
refreshBlock(b);
|
| 372 |
+
return b;
|
| 373 |
+
}
|
| 374 |
+
|
| 375 |
+
// ---------------------------------------------------------------- primitives
|
| 376 |
+
function card(title, stage, opts){
|
| 377 |
+
opts = opts || {};
|
| 378 |
+
var root, body;
|
| 379 |
+
if(opts.collapsible){
|
| 380 |
+
root = el('details', 'card' + (opts.cls ? ' ' + opts.cls : ''));
|
| 381 |
+
if(opts.open) root.open = true;
|
| 382 |
+
var head = el('summary');
|
| 383 |
+
head.appendChild(el('span', null, title));
|
| 384 |
+
(opts.badges || []).forEach(function(b){ head.appendChild(b); });
|
| 385 |
+
root.appendChild(head);
|
| 386 |
+
body = el('div', 'card-b');
|
| 387 |
+
root.appendChild(body);
|
| 388 |
+
} else {
|
| 389 |
+
root = el('div', 'card' + (opts.cls ? ' ' + opts.cls : ''));
|
| 390 |
+
var h = el('div', 'card-h');
|
| 391 |
+
h.appendChild(el('span', null, title));
|
| 392 |
+
(opts.badges || []).forEach(function(b){ h.appendChild(b); });
|
| 393 |
+
root.appendChild(h);
|
| 394 |
+
body = el('div', 'card-b');
|
| 395 |
+
root.appendChild(body);
|
| 396 |
+
}
|
| 397 |
+
if(stage) root.dataset.stage = stage;
|
| 398 |
+
return {root:root, body:body};
|
| 399 |
+
}
|
| 400 |
+
function metaRow(parent, pairs){
|
| 401 |
+
var row = el('div', 'meta');
|
| 402 |
+
pairs.forEach(function(p){
|
| 403 |
+
if(p[1] === null || p[1] === undefined || p[1] === '') return;
|
| 404 |
+
var span = el('span', null, p[0] + ': ');
|
| 405 |
+
span.appendChild(el('b', null, String(p[1])));
|
| 406 |
+
row.appendChild(span);
|
| 407 |
+
});
|
| 408 |
+
if(row.childNodes.length) parent.appendChild(row);
|
| 409 |
+
}
|
| 410 |
+
function parseError(parent, value, where){
|
| 411 |
+
if(!value) return;
|
| 412 |
+
// Say plainly that the pipeline failed to produce this, and that the message
|
| 413 |
+
// is the recorded reason. Printing a bare `parse_error: ...` under a heading
|
| 414 |
+
// reads as though the viewer failed to render something that exists.
|
| 415 |
+
var box = el('div', 'err');
|
| 416 |
+
box.appendChild(el('div', 'err-h',
|
| 417 |
+
'The pipeline produced no ' + (where || 'output') + ' here.'));
|
| 418 |
+
box.appendChild(el('div', 'err-b', 'Recorded reason: ' + value));
|
| 419 |
+
box.appendChild(el('div', 'err-f',
|
| 420 |
+
'This is stored run data, not a display problem \\u2014 the phase failed and ' +
|
| 421 |
+
'the record was kept for audit.'));
|
| 422 |
+
parent.appendChild(box);
|
| 423 |
+
}
|
| 424 |
+
function modelNote(meta){
|
| 425 |
+
if(!meta) return '';
|
| 426 |
+
var bits = [];
|
| 427 |
+
if(meta.model) bits.push(meta.model);
|
| 428 |
+
if(meta.attempts > 1) bits.push(meta.attempts + ' attempts');
|
| 429 |
+
if(meta.output_tokens) bits.push(meta.output_tokens.toLocaleString() + ' out-tok');
|
| 430 |
+
if(meta.reasoning_tokens) bits.push(meta.reasoning_tokens.toLocaleString() + ' reason-tok');
|
| 431 |
+
if(meta.latency_s) bits.push(meta.latency_s + 's');
|
| 432 |
+
return bits.join(' · ');
|
| 433 |
+
}
|
| 434 |
+
function bulletList(parent, label, items){
|
| 435 |
+
if(!items || !items.length) return;
|
| 436 |
+
parent.appendChild(el('div', 'lbl', label + ' (' + items.length + ')'));
|
| 437 |
+
var ul = el('ul', 'plain');
|
| 438 |
+
items.forEach(function(x){ ul.appendChild(el('li', null, x)); });
|
| 439 |
+
parent.appendChild(ul);
|
| 440 |
+
}
|
| 441 |
+
function anchorFor(layerIdx, cid){ return 'cand-' + layerIdx + '-' + cid; }
|
| 442 |
+
function cidChip(cid, layerIdx, linkable){
|
| 443 |
+
var chip = el('span', 'cid' + (linkable ? '' : ' plain'), cid);
|
| 444 |
+
if(linkable){
|
| 445 |
+
chip.title = 'jump to ' + cid;
|
| 446 |
+
chip.addEventListener('click', function(){
|
| 447 |
+
var target = document.getElementById(anchorFor(layerIdx, cid));
|
| 448 |
+
if(!target) return;
|
| 449 |
+
if(target.tagName === 'DETAILS') target.open = true;
|
| 450 |
+
var parentDetails = target.closest('details.layer');
|
| 451 |
+
if(parentDetails) parentDetails.open = true;
|
| 452 |
+
target.scrollIntoView({block:'center'});
|
| 453 |
+
target.classList.remove('flash');
|
| 454 |
+
void target.offsetWidth;
|
| 455 |
+
target.classList.add('flash');
|
| 456 |
+
});
|
| 457 |
}
|
| 458 |
+
return chip;
|
| 459 |
+
}
|
| 460 |
+
function explorationChip(id){
|
| 461 |
+
var chip = el('span', 'cid', id);
|
| 462 |
+
var anchor = explorationIndex[id];
|
| 463 |
+
if(!anchor){ chip.className = 'cid plain'; return chip; }
|
| 464 |
+
chip.addEventListener('click', function(){
|
| 465 |
+
var target = document.getElementById(anchor);
|
| 466 |
+
if(!target) return;
|
| 467 |
+
var parentDetails = target.closest('details.layer');
|
| 468 |
+
if(parentDetails) parentDetails.open = true;
|
| 469 |
+
target.scrollIntoView({block:'center'});
|
| 470 |
+
target.classList.remove('flash');
|
| 471 |
+
void target.offsetWidth;
|
| 472 |
+
target.classList.add('flash');
|
| 473 |
+
});
|
| 474 |
+
return chip;
|
| 475 |
+
}
|
| 476 |
+
function chipRow(parent, label, ids, layerIdx, linkable){
|
| 477 |
+
if(!ids || !ids.length) return;
|
| 478 |
+
var row = el('div', 'meta');
|
| 479 |
+
row.appendChild(el('span', null, label + ': '));
|
| 480 |
+
ids.forEach(function(id){ row.appendChild(cidChip(id, layerIdx, linkable)); });
|
| 481 |
+
parent.appendChild(row);
|
| 482 |
}
|
|
|
|
|
|
|
| 483 |
|
| 484 |
+
// ---------------------------------------------------------------- sidebar
|
| 485 |
+
function trajBadges(s, entry){
|
| 486 |
+
var out = [];
|
| 487 |
+
if(s.source) out.push(badge(s.source, 'b-plain'));
|
| 488 |
+
out.push(badge(s.terminated ? 'terminated' : 'incomplete', s.terminated ? 'b-good' : 'b-warn'));
|
| 489 |
+
if(s.guided) out.push(badge('guided', 'b-guided'));
|
| 490 |
+
if(s.minimum_layers_waived) out.push(badge('minimum waived', 'b-warn'));
|
| 491 |
+
out.push(badge(s.n_layers + ' layer' + (s.n_layers === 1 ? '' : 's'), 'b-info'));
|
| 492 |
+
if(s.normalized !== null && s.normalized !== undefined){
|
| 493 |
+
var cls = s.normalized >= 0.75 ? 'b-good' : (s.normalized >= 0.4 ? 'b-warn' : 'b-bad');
|
| 494 |
+
out.push(badge(scoreText(s), cls));
|
| 495 |
+
} else {
|
| 496 |
+
out.push(badge('no score', 'b-muted'));
|
| 497 |
+
}
|
| 498 |
+
if(s.excluded_reason) out.push(badge(s.excluded_reason, 'b-bad'));
|
| 499 |
+
if(s.parse_errors) out.push(badge(s.parse_errors + ' parse_error', 'b-bad'));
|
| 500 |
+
if(entry && entry.superseded) out.push(badge('superseded rev ' + entry.revision, 'b-muted'));
|
| 501 |
+
else if(entry && entry.revision_count > 1) out.push(badge('rev ' + entry.revision + '/' + entry.revision_count, 'b-accent'));
|
| 502 |
return out;
|
| 503 |
}
|
| 504 |
+
function scoreText(s){
|
| 505 |
+
if(s.score === null || s.score === undefined) return 'no score';
|
| 506 |
+
var raw = String(s.score) + (s.score_scale ? ' of ' + s.score_scale.split('-').pop() : '');
|
| 507 |
+
if(s.normalized === null || s.normalized === undefined) return raw;
|
| 508 |
+
return raw + ' (' + s.normalized.toFixed(2) + ')';
|
| 509 |
+
}
|
| 510 |
+
function renderSidebar(){
|
| 511 |
+
var list = $('#traj-list');
|
| 512 |
+
list.textContent = '';
|
| 513 |
+
var q = ($('#traj-filter').value || '').toLowerCase();
|
| 514 |
+
var shown = 0;
|
| 515 |
+
DATA.trajectories.forEach(function(entry){
|
| 516 |
+
var s = entry.summary;
|
| 517 |
+
var hay = (s.problem_id + ' ' + s.source + ' ' + s.excluded_reason + ' ' + s.trajectory_id).toLowerCase();
|
| 518 |
+
if(q && hay.indexOf(q) < 0) return;
|
| 519 |
+
shown++;
|
| 520 |
+
var item = el('button', 'traj' + (entry.superseded ? ' superseded' : '') + (entry.uid === state.uid ? ' sel' : ''));
|
| 521 |
+
item.appendChild(el('div', 'tid', s.problem_id || entry.identity));
|
| 522 |
+
var row = el('div', 'row');
|
| 523 |
+
trajBadges(s, entry).forEach(function(b){ row.appendChild(b); });
|
| 524 |
+
item.appendChild(row);
|
| 525 |
+
item.addEventListener('click', function(){ select(entry.uid); });
|
| 526 |
+
list.appendChild(item);
|
| 527 |
+
});
|
| 528 |
+
if(!shown) list.appendChild(el('div', 'empty', 'no trajectory matches this filter'));
|
| 529 |
|
| 530 |
+
var flist = $('#filtered-list');
|
| 531 |
+
flist.textContent = '';
|
| 532 |
+
$('#filtered-h').classList.toggle('hidden', !DATA.filtered.length);
|
| 533 |
+
DATA.filtered.forEach(function(row){
|
| 534 |
+
var hay = (row.problem_id + ' ' + row.source + ' ' + row.reason).toLowerCase();
|
| 535 |
+
if(q && hay.indexOf(q) < 0) return;
|
| 536 |
+
var item = el('button', 'traj' + (row.uid === state.uid ? ' sel' : ''));
|
| 537 |
+
item.appendChild(el('div', 'tid', row.problem_id));
|
| 538 |
+
var r = el('div', 'row');
|
| 539 |
+
if(row.source) r.appendChild(badge(row.source, 'b-plain'));
|
| 540 |
+
r.appendChild(badge('F0 rejected', 'b-bad'));
|
| 541 |
+
if(row.f0 && row.f0.validity) r.appendChild(badge(row.f0.validity, 'b-warn'));
|
| 542 |
+
item.appendChild(r);
|
| 543 |
+
item.addEventListener('click', function(){ select(row.uid); });
|
| 544 |
+
flist.appendChild(item);
|
| 545 |
});
|
| 546 |
}
|
| 547 |
|
| 548 |
+
// ---------------------------------------------------------------- sections
|
| 549 |
+
function renderProblem(main, p, outcome, s, entry){
|
| 550 |
+
var head = card('Problem · ' + (p.problem_id || '(no id)'), null, {badges:trajBadges(s, entry)});
|
| 551 |
+
metaRow(head.body, [
|
| 552 |
+
['trajectory', outcome.trajectory_id], ['version', outcome.version_id],
|
| 553 |
+
['final_layer', outcome.final_layer], ['terminated', outcome.terminated],
|
| 554 |
+
['guided', outcome.guided], ['excluded_reason', outcome.excluded_reason || '—'],
|
| 555 |
+
['productive_layers', outcome.productive_layers],
|
| 556 |
+
['minimum_layers', outcome.minimum_layers],
|
| 557 |
+
['minimum waived', outcome.minimum_layers_waived ? (outcome.minimum_waiver_reason || 'yes') : 'no'],
|
| 558 |
+
['MR targets', s.n_mr_targets], ['candidates', s.n_candidates],
|
| 559 |
+
['executions', s.n_executions], ['retained', s.n_retained]
|
| 560 |
+
]);
|
| 561 |
+
if(entry.superseded){
|
| 562 |
+
head.body.appendChild(el('div', 'err',
|
| 563 |
+
'This is revision ' + entry.revision + ' of ' + entry.revision_count +
|
| 564 |
+
' for this identity; a later line in trajectories.jsonl supersedes it.'));
|
| 565 |
+
}
|
| 566 |
+
textBlock(head.body, p.problem, {label:'Problem statement', prose:true});
|
| 567 |
+
textBlock(head.body, p.rubric, {label:'Rubric', prose:true});
|
| 568 |
+
if(p.reference_solution) textBlock(head.body, p.reference_solution, {label:'Reference solution (metadata)', prose:true});
|
| 569 |
+
main.appendChild(head.root);
|
| 570 |
+
}
|
| 571 |
+
function renderF0(main, f0){
|
| 572 |
+
if(!f0) return;
|
| 573 |
+
var vcls = f0.validity === 'valid' ? 'b-good' : (f0.validity === 'invalid' ? 'b-bad' : 'b-warn');
|
| 574 |
+
var c = card('F0 — problem validity & solution checklist', 'f0', {
|
| 575 |
+
collapsible:true, open:true,
|
| 576 |
+
badges:[badge(f0.validity || 'unknown', vcls),
|
| 577 |
+
badge((f0.checklist || []).length + ' checklist items', 'b-info')]
|
| 578 |
+
});
|
| 579 |
+
parseError(c.body, f0.parse_error, 'f0');
|
| 580 |
+
metaRow(c.body, [['model', modelNote(f0.model)]]);
|
| 581 |
+
bulletList(c.body, 'Validity issues', f0.validity_issues);
|
| 582 |
+
if((f0.checklist || []).length){
|
| 583 |
+
var wrap = el('div', 'wrap-scroll');
|
| 584 |
+
var t = el('table', 'grid');
|
| 585 |
+
var thead = el('tr');
|
| 586 |
+
['item', 'importance', 'verify?', 'obligation', 'acceptable evidence'].forEach(function(h){
|
| 587 |
+
thead.appendChild(el('th', null, h));
|
| 588 |
+
});
|
| 589 |
+
t.appendChild(thead);
|
| 590 |
+
f0.checklist.forEach(function(item){
|
| 591 |
+
var tr = el('tr');
|
| 592 |
+
var idcell = el('td');
|
| 593 |
+
idcell.appendChild(cidChip(item.item_id, -1, false));
|
| 594 |
+
tr.appendChild(idcell);
|
| 595 |
+
tr.appendChild(el('td', null, item.importance || '—'));
|
| 596 |
+
tr.appendChild(el('td', null, item.verification_needed ? 'yes' : 'no'));
|
| 597 |
+
tr.appendChild(el('td', null, item.obligation));
|
| 598 |
+
var ev = el('td');
|
| 599 |
+
if((item.acceptable_evidence || []).length){
|
| 600 |
+
var ul = el('ul', 'plain');
|
| 601 |
+
item.acceptable_evidence.forEach(function(x){ ul.appendChild(el('li', null, x)); });
|
| 602 |
+
ev.appendChild(ul);
|
| 603 |
+
} else ev.appendChild(el('span', 'empty', '—'));
|
| 604 |
+
tr.appendChild(ev);
|
| 605 |
+
t.appendChild(tr);
|
| 606 |
+
});
|
| 607 |
+
wrap.appendChild(t);
|
| 608 |
+
c.body.appendChild(wrap);
|
| 609 |
+
}
|
| 610 |
+
rawBlock(c.body, 'F0 raw output', f0.raw_output);
|
| 611 |
+
main.appendChild(c.root);
|
| 612 |
+
}
|
| 613 |
+
function rawBlock(parent, label, text, note){
|
| 614 |
+
if(!text) return;
|
| 615 |
+
var d = el('details', 'card nested');
|
| 616 |
+
var s = el('summary');
|
| 617 |
+
s.appendChild(el('span', null, label));
|
| 618 |
+
s.appendChild(badge('raw', 'b-muted'));
|
| 619 |
+
s.appendChild(el('span', 'tb-note', ' ' + text.length.toLocaleString() + ' chars'));
|
| 620 |
+
d.appendChild(s);
|
| 621 |
+
var body = el('div', 'card-b');
|
| 622 |
+
d.appendChild(body);
|
| 623 |
+
d.classList.add('raw-wrap');
|
| 624 |
+
if(state.showRaw) d.open = true;
|
| 625 |
+
textBlock(body, text, {cot:true, note:note || ''});
|
| 626 |
+
parent.appendChild(d);
|
| 627 |
+
}
|
| 628 |
+
function renderAssessment(parent, a){
|
| 629 |
+
if(!a) return;
|
| 630 |
+
bulletList(parent, 'Last-layer assessment', a.last_layer_assessment);
|
| 631 |
+
bulletList(parent, 'Current strategies', a.current_strategies);
|
| 632 |
+
bulletList(parent, 'Open questions & unknowns', a.open_questions_and_unknowns);
|
| 633 |
+
bulletList(parent, 'Claims needing verification', a.claims_needing_verification);
|
| 634 |
+
}
|
| 635 |
+
function chainRows(layer){
|
| 636 |
+
var order = [], map = {};
|
| 637 |
+
function touch(cid){
|
| 638 |
+
cid = cid || '(no id)';
|
| 639 |
+
if(!map[cid]){ map[cid] = {cid:cid, cand:null, assess:null, execs:[], retries:[], review:null}; order.push(cid); }
|
| 640 |
+
return map[cid];
|
| 641 |
+
}
|
| 642 |
+
((layer.f1 || {}).candidates || []).forEach(function(c){ touch(c.candidate_id).cand = c; });
|
| 643 |
+
((layer.f2 || {}).assessments || []).forEach(function(a){ touch(a.candidate_id).assess = a; });
|
| 644 |
+
(layer.executions || []).forEach(function(e){ touch(e.candidate_id).execs.push(e); });
|
| 645 |
+
(layer.retry_executions || []).forEach(function(e){
|
| 646 |
+
var row = touch(e.candidate_id);
|
| 647 |
+
var already = row.execs.some(function(x){ return x.attempt === e.attempt && x.report === e.report; });
|
| 648 |
+
if(!already) row.retries.push(e);
|
| 649 |
+
});
|
| 650 |
+
((layer.f4 || {}).reviews || []).forEach(function(r){ touch(r.candidate_id).review = r; });
|
| 651 |
+
return order.map(function(cid){ return map[cid]; });
|
| 652 |
+
}
|
| 653 |
+
function renderCandidate(parent, layer, row){
|
| 654 |
+
var cand = row.cand, assess = row.assess, review = row.review;
|
| 655 |
+
var guided = !!(cand && cand.guided) || row.execs.some(function(e){ return e.guided; });
|
| 656 |
+
var badges = [];
|
| 657 |
+
if(cand && cand.candidate_type) badges.push(badge(cand.candidate_type, 'b-accent'));
|
| 658 |
+
if(assess) badges.push(badge('F2 ' + assess.decision + (assess.rank >= 0 ? ' #' + assess.rank : ''),
|
| 659 |
+
assess.decision === 'pass' ? 'b-good' : 'b-bad'));
|
| 660 |
+
if(row.execs.length) badges.push(badge(row.execs.length + ' execution' + (row.execs.length === 1 ? '' : 's'), 'b-info'));
|
| 661 |
+
if(row.retries.length) badges.push(badge(row.retries.length + ' retry', 'b-warn'));
|
| 662 |
+
if(review){
|
| 663 |
+
badges.push(badge(review.contribution || 'no contribution', CONTRIB_CLASS[review.contribution] || 'b-muted'));
|
| 664 |
+
badges.push(badge(review.retain ? 'retained' : 'dropped', review.retain ? 'b-good' : 'b-muted'));
|
| 665 |
+
}
|
| 666 |
+
if(guided) badges.push(badge('guided', 'b-guided'));
|
| 667 |
+
var c = card('candidate ' + row.cid, null, {
|
| 668 |
+
collapsible:true, open:true, badges:badges,
|
| 669 |
+
cls:'nested cand' + (guided ? ' guided-cand' : '')
|
| 670 |
+
});
|
| 671 |
+
c.root.id = anchorFor(layer.layer_idx, row.cid);
|
| 672 |
|
| 673 |
+
if(cand){
|
| 674 |
+
var f1 = el('div');
|
| 675 |
+
f1.dataset.stage = 'f1';
|
| 676 |
+
f1.appendChild(el('div', 'lbl', 'F1 proposal'));
|
| 677 |
+
metaRow(f1, [['type', cand.candidate_type], ['guided', cand.guided ? 'yes' : ''],
|
| 678 |
+
['source_item_id', cand.source_item_id || '']]);
|
| 679 |
+
textBlock(f1, cand.direction, {label:'direction', prose:true});
|
| 680 |
+
textBlock(f1, cand.target, {label:'target', prose:true, hideEmpty:true});
|
| 681 |
+
textBlock(f1, cand.why_valuable, {label:'why valuable', prose:true, hideEmpty:true});
|
| 682 |
+
c.body.appendChild(f1);
|
| 683 |
+
}
|
| 684 |
+
if(assess){
|
| 685 |
+
var f2 = el('div');
|
| 686 |
+
f2.dataset.stage = 'f2';
|
| 687 |
+
f2.appendChild(el('div', 'lbl', 'F2 verdict'));
|
| 688 |
+
metaRow(f2, [['decision', assess.decision], ['rank', assess.rank]]);
|
| 689 |
+
chipRow(f2, 'overlaps with', assess.overlaps_with, layer.layer_idx, true);
|
| 690 |
+
textBlock(f2, assess.expected_information_value, {label:'expected information value', prose:true, hideEmpty:true});
|
| 691 |
+
textBlock(f2, assess.critique, {label:'critique', prose:true, hideEmpty:true});
|
| 692 |
+
textBlock(f2, assess.reasoning, {label:'reasoning', prose:true, hideEmpty:true});
|
| 693 |
+
c.body.appendChild(f2);
|
| 694 |
+
}
|
| 695 |
+
row.execs.concat(row.retries).forEach(function(e, i){
|
| 696 |
+
var f3 = el('div');
|
| 697 |
+
f3.dataset.stage = 'f3';
|
| 698 |
+
var isRetryOnly = i >= row.execs.length;
|
| 699 |
+
f3.appendChild(el('div', 'lbl',
|
| 700 |
+
'F3 execution' + (e.attempt ? ' · attempt ' + e.attempt : '') + (isRetryOnly ? ' (retry record)' : '')));
|
| 701 |
+
parseError(f3, e.parse_error, 'f3');
|
| 702 |
+
metaRow(f3, [['guided', e.guided ? 'yes' : ''], ['model', modelNote(e.model)]]);
|
| 703 |
+
textBlock(f3, e.report, {label:'report (durable target)', note:'durable'});
|
| 704 |
+
rawBlock(f3, 'F3 raw provider output', e.raw_output);
|
| 705 |
+
c.body.appendChild(f3);
|
| 706 |
+
});
|
| 707 |
+
if(review){
|
| 708 |
+
var f4 = el('div');
|
| 709 |
+
f4.dataset.stage = 'f4';
|
| 710 |
+
f4.appendChild(el('div', 'lbl', 'F4 review'));
|
| 711 |
+
parseError(f4, review.parse_error, 'f4 review');
|
| 712 |
+
var flags = el('div', 'meta');
|
| 713 |
+
// usable/faithful/retain read good when true, obvious_flaw when false;
|
| 714 |
+
// forward_rejection_supported is informational either way
|
| 715 |
+
[['usable', review.usable], ['faithful', review.faithful], ['obvious_flaw', review.obvious_flaw],
|
| 716 |
+
['retain', review.retain]
|
| 717 |
+
].forEach(function(p){
|
| 718 |
+
var good = p[0] === 'obvious_flaw' ? !p[1] : !!p[1];
|
| 719 |
+
flags.appendChild(badge(p[0] + ': ' + (p[1] ? 'yes' : 'no'), good ? 'b-good' : 'b-bad'));
|
| 720 |
+
});
|
| 721 |
+
flags.appendChild(badge('forward_rejection_supported: ' + (review.forward_rejection_supported ? 'yes' : 'no'),
|
| 722 |
+
review.forward_rejection_supported ? 'b-info' : 'b-muted'));
|
| 723 |
+
flags.appendChild(badge('contribution: ' + (review.contribution || '—'),
|
| 724 |
+
CONTRIB_CLASS[review.contribution] || 'b-muted'));
|
| 725 |
+
if(review.redundancy_cause && review.redundancy_cause !== 'not_applicable'){
|
| 726 |
+
flags.appendChild(badge('redundancy: ' + review.redundancy_cause, 'b-warn'));
|
| 727 |
+
}
|
| 728 |
+
f4.appendChild(flags);
|
| 729 |
+
textBlock(f4, review.forward_rejection_reason, {label:'forward rejection reason', prose:true, hideEmpty:true});
|
| 730 |
+
if(review.summary){
|
| 731 |
+
var sm = el('div');
|
| 732 |
+
sm.appendChild(el('div', 'lbl', 'frontier summary' +
|
| 733 |
+
(review.summary.exploration_id ? ' · exploration ' + review.summary.exploration_id : '')));
|
| 734 |
+
textBlock(sm, review.summary.detailed_summary, {label:'detailed summary', prose:true, hideEmpty:true});
|
| 735 |
+
textBlock(sm, review.summary.rationale, {label:'rationale', prose:true, hideEmpty:true});
|
| 736 |
+
textBlock(sm, review.summary.core_result, {label:'core result', prose:true, hideEmpty:true});
|
| 737 |
+
f4.appendChild(sm);
|
| 738 |
+
}
|
| 739 |
+
c.body.appendChild(f4);
|
| 740 |
+
}
|
| 741 |
+
parent.appendChild(c.root);
|
| 742 |
+
}
|
| 743 |
+
function renderF5(parent, f5, layerIdx){
|
| 744 |
+
if(!f5) return;
|
| 745 |
+
var c = card('F5 — checklist audit & termination decision', 'f5', {
|
| 746 |
+
collapsible:true, open:true, cls:'nested',
|
| 747 |
+
badges:[badge(f5.decision || 'no decision', f5.decision === 'terminate' ? 'b-good' : 'b-warn')]
|
| 748 |
+
.concat(f5.confirmation_used ? [badge('confirmation used', 'b-info')] : [])
|
| 749 |
+
.concat(f5.guided_item_id ? [badge('guided item ' + f5.guided_item_id, 'b-guided')] : [])
|
| 750 |
+
});
|
| 751 |
+
parseError(c.body, f5.parse_error, 'f5');
|
| 752 |
+
metaRow(c.body, [['model', modelNote(f5.model)]]);
|
| 753 |
+
if((f5.checklist || []).length){
|
| 754 |
+
var wrap = el('div', 'wrap-scroll');
|
| 755 |
+
var t = el('table', 'grid');
|
| 756 |
+
var head = el('tr');
|
| 757 |
+
['item', 'status', 'supporting', 'verification', 'explanation'].forEach(function(h){ head.appendChild(el('th', null, h)); });
|
| 758 |
+
t.appendChild(head);
|
| 759 |
+
f5.checklist.forEach(function(item){
|
| 760 |
+
var tr = el('tr');
|
| 761 |
+
var idc = el('td'); idc.appendChild(cidChip(item.item_id, -1, false)); tr.appendChild(idc);
|
| 762 |
+
var st = el('td'); st.appendChild(badge(item.status || '—', STATUS_CLASS[item.status] || 'b-muted')); tr.appendChild(st);
|
| 763 |
+
var sup = el('td');
|
| 764 |
+
(item.supporting_explorations || []).forEach(function(x){ sup.appendChild(explorationChip(x)); });
|
| 765 |
+
if(!(item.supporting_explorations || []).length) sup.appendChild(el('span', 'empty', '—'));
|
| 766 |
+
tr.appendChild(sup);
|
| 767 |
+
tr.appendChild(el('td', null, item.verification || '—'));
|
| 768 |
+
tr.appendChild(el('td', null, item.explanation || '—'));
|
| 769 |
+
t.appendChild(tr);
|
| 770 |
+
});
|
| 771 |
+
wrap.appendChild(t);
|
| 772 |
+
c.body.appendChild(wrap);
|
| 773 |
+
}
|
| 774 |
+
bulletList(c.body, 'Major unverified claims', f5.major_unverified_claims);
|
| 775 |
+
textBlock(c.body, f5.reason, {label:'decision reason', prose:true, hideEmpty:true});
|
| 776 |
+
textBlock(c.body, f5.guided_diagnostic, {label:'guided diagnostic', prose:true, hideEmpty:true});
|
| 777 |
+
rawBlock(c.body, 'F5 raw output', f5.raw_output);
|
| 778 |
+
if(f5.initial_raw_output && f5.initial_raw_output !== f5.raw_output){
|
| 779 |
+
rawBlock(c.body, 'F5 initial raw output (before confirmation)', f5.initial_raw_output);
|
| 780 |
}
|
| 781 |
+
parent.appendChild(c.root);
|
| 782 |
+
}
|
| 783 |
+
function renderMR(parent, mr){
|
| 784 |
+
var badges = [badge('layer ' + mr.layer_idx, 'b-info')];
|
| 785 |
+
if(mr.parse_error) badges.push(badge('parse_error', 'b-bad'));
|
| 786 |
+
var c = card('MR target — layer ' + mr.layer_idx, 'mr', {
|
| 787 |
+
collapsible:true, open:true, cls:'nested', badges:badges
|
| 788 |
+
});
|
| 789 |
+
parseError(c.body, mr.parse_error, 'mr target');
|
| 790 |
+
metaRow(c.body, [['model', modelNote(mr.model)],
|
| 791 |
+
['assistant_target chars', (mr.assistant_target || '').length.toLocaleString()]]);
|
| 792 |
+
chipRow(c.body, 'selected', mr.selected_candidate_ids, mr.layer_idx, true);
|
| 793 |
+
chipRow(c.body, 'rejected', mr.rejected_candidate_ids, mr.layer_idx, true);
|
| 794 |
+
chipRow(c.body, 'dropped after synthesis failure', mr.dropped_candidate_ids, mr.layer_idx, true);
|
| 795 |
+
textBlock(c.body, mr.assistant_target, {label:'assistant target (training text)', cot:true});
|
| 796 |
+
textBlock(c.body, mr.stocktake, {label:'stocktake', cot:true, hideEmpty:true});
|
| 797 |
+
textBlock(c.body, mr.deliberation, {label:'deliberation', cot:true, hideEmpty:true});
|
| 798 |
+
(mr.direction_fragments || []).forEach(function(f){
|
| 799 |
+
var d = el('div');
|
| 800 |
+
var lbl = el('div', 'lbl');
|
| 801 |
+
lbl.appendChild(document.createTextNode('fragment '));
|
| 802 |
+
lbl.appendChild(cidChip(f.candidate_id, mr.layer_idx, true));
|
| 803 |
+
lbl.appendChild(document.createTextNode(' '));
|
| 804 |
+
lbl.appendChild(badge(f.disposition || '—', f.disposition === 'selected' ? 'b-good' : 'b-muted'));
|
| 805 |
+
d.appendChild(lbl);
|
| 806 |
+
textBlock(d, f.continuation, {cot:true});
|
| 807 |
+
c.body.appendChild(d);
|
| 808 |
+
});
|
| 809 |
+
rawBlock(c.body, 'failed synthesis raw output', mr.failure_raw_output);
|
| 810 |
+
parent.appendChild(c.root);
|
| 811 |
+
}
|
| 812 |
+
function renderLayer(main, layer, mrByLayer){
|
| 813 |
+
var badges = [];
|
| 814 |
+
if(layer.guided) badges.push(badge('guided layer', 'b-guided'));
|
| 815 |
+
if(layer.productive) badges.push(badge('productive', 'b-good'));
|
| 816 |
+
if(layer.termination_deferred) badges.push(badge('termination deferred', 'b-warn'));
|
| 817 |
+
var f1 = layer.f1 || {}, f2 = layer.f2 || {}, f4 = layer.f4 || {}, f5 = layer.f5 || {};
|
| 818 |
+
var passes = (f2.assessments || []).filter(function(a){ return a.decision === 'pass'; }).length;
|
| 819 |
+
badges.push(badge((f1.candidates || []).length + ' candidates', 'b-plain'));
|
| 820 |
+
badges.push(badge(passes + ' pass', 'b-good'));
|
| 821 |
+
badges.push(badge((layer.executions || []).length + ' executions', 'b-info'));
|
| 822 |
+
var retained = (f4.reviews || []).filter(function(r){ return r.retain; }).length;
|
| 823 |
+
badges.push(badge(retained + ' retained', 'b-accent'));
|
| 824 |
+
if(f4.escalated) badges.push(badge('F4 escalated', 'b-warn'));
|
| 825 |
+
if(f5.decision) badges.push(badge('F5 ' + f5.decision, f5.decision === 'terminate' ? 'b-good' : 'b-warn'));
|
| 826 |
+
var errs = countErrors(layer);
|
| 827 |
+
if(errs) badges.push(badge(errs + ' parse_error', 'b-bad'));
|
| 828 |
|
| 829 |
+
var c = card('Layer ' + layer.layer_idx, null, {
|
| 830 |
+
collapsible:true, open:false, badges:badges,
|
| 831 |
+
cls:'layer' + (layer.guided ? ' guided-layer' : '')
|
| 832 |
+
});
|
| 833 |
+
textBlock(c.body, layer.search_context, {label:'search-budget context', prose:true, hideEmpty:true});
|
| 834 |
+
c.root.classList.add('layer');
|
|
|
|
|
|
|
| 835 |
|
| 836 |
+
var fb = el('div');
|
| 837 |
+
fb.dataset.stage = 'f1';
|
| 838 |
+
textBlock(fb, layer.frontier_before, {label:'frontier before this layer', hideEmpty:true});
|
| 839 |
+
c.body.appendChild(fb);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 840 |
|
| 841 |
+
if(layer.f1){
|
| 842 |
+
var f1c = card('F1 — assessment & candidate proposals', 'f1', {
|
| 843 |
+
collapsible:true, open:true, cls:'nested',
|
| 844 |
+
badges:[badge((layer.f1.candidates || []).length + ' candidates', 'b-plain')]
|
| 845 |
+
});
|
| 846 |
+
parseError(f1c.body, layer.f1.parse_error, 'f1');
|
| 847 |
+
metaRow(f1c.body, [['model', modelNote(layer.f1.model)]]);
|
| 848 |
+
renderAssessment(f1c.body, layer.f1.assessment);
|
| 849 |
+
rawBlock(f1c.body, 'F1 raw output', layer.f1.raw_output);
|
| 850 |
+
c.body.appendChild(f1c.root);
|
| 851 |
+
}
|
| 852 |
+
if(layer.unguided_f1){
|
| 853 |
+
var uc = card('F1 before teacher guidance — what the model proposed unaided', 'f1', {
|
| 854 |
+
collapsible:true, open:false, cls:'nested',
|
| 855 |
+
badges:[badge('unguided', 'b-muted'),
|
| 856 |
+
badge((layer.unguided_f1.candidates || []).length + ' candidates', 'b-plain')]
|
| 857 |
+
});
|
| 858 |
+
var ownIds = {};
|
| 859 |
+
(layer.unguided_f1.candidates || []).forEach(function(x){ ownIds[x.candidate_id] = true; });
|
| 860 |
+
var added = ((layer.f1 || {}).candidates || [])
|
| 861 |
+
.filter(function(x){ return !ownIds[x.candidate_id]; })
|
| 862 |
+
.map(function(x){ return x.candidate_id; });
|
| 863 |
+
if(added.length) chipRow(uc.body, 'candidates added by guidance', added, layer.layer_idx, true);
|
| 864 |
+
parseError(uc.body, layer.unguided_f1.parse_error, 'unguided f1');
|
| 865 |
+
renderAssessment(uc.body, layer.unguided_f1.assessment);
|
| 866 |
+
(layer.unguided_f1.candidates || []).forEach(function(cand){
|
| 867 |
+
var d = el('div');
|
| 868 |
+
var lbl = el('div', 'lbl');
|
| 869 |
+
lbl.appendChild(cidChip(cand.candidate_id, -1, false));
|
| 870 |
+
lbl.appendChild(document.createTextNode(' '));
|
| 871 |
+
lbl.appendChild(badge(cand.candidate_type || '—', 'b-accent'));
|
| 872 |
+
d.appendChild(lbl);
|
| 873 |
+
textBlock(d, cand.direction, {prose:true});
|
| 874 |
+
uc.body.appendChild(d);
|
| 875 |
});
|
| 876 |
+
rawBlock(uc.body, 'unguided F1 raw output', layer.unguided_f1.raw_output);
|
| 877 |
+
c.body.appendChild(uc.root);
|
| 878 |
+
}
|
| 879 |
|
| 880 |
+
var chain = chainRows(layer);
|
| 881 |
+
if(chain.length){
|
| 882 |
+
var cc = card('F1 → F2 → F3 → F4 per candidate', null, {
|
| 883 |
+
collapsible:true, open:true, cls:'nested',
|
| 884 |
+
badges:[badge(chain.length + ' candidate ids', 'b-plain')]
|
| 885 |
+
});
|
| 886 |
+
chain.forEach(function(row){ renderCandidate(cc.body, layer, row); });
|
| 887 |
+
c.body.appendChild(cc.root);
|
| 888 |
+
}
|
| 889 |
+
if(layer.f2 && (layer.f2.raw_output || layer.f2.parse_error)){
|
| 890 |
+
var f2c = card('F2 — raw verdict output', 'f2', {collapsible:true, open:false, cls:'nested'});
|
| 891 |
+
parseError(f2c.body, layer.f2.parse_error, 'f2');
|
| 892 |
+
metaRow(f2c.body, [['model', modelNote(layer.f2.model)]]);
|
| 893 |
+
textBlock(f2c.body, layer.f2.raw_output, {cot:true, hideEmpty:true});
|
| 894 |
+
c.body.appendChild(f2c.root);
|
| 895 |
+
}
|
| 896 |
+
if(layer.f4){
|
| 897 |
+
var f4c = card('F4 — review pass output', 'f4', {
|
| 898 |
+
collapsible:true, open:false, cls:'nested',
|
| 899 |
+
badges:(layer.f4.escalated ? [badge('escalated', 'b-warn')] : [])
|
| 900 |
+
});
|
| 901 |
+
parseError(f4c.body, layer.f4.parse_error, 'f4');
|
| 902 |
+
metaRow(f4c.body, [['model', modelNote(layer.f4.model)]]);
|
| 903 |
+
rawBlock(f4c.body, 'F4 raw output', layer.f4.raw_output);
|
| 904 |
+
if(layer.f4.initial_raw_output && layer.f4.initial_raw_output !== layer.f4.raw_output){
|
| 905 |
+
rawBlock(f4c.body, 'F4 initial raw output (before escalation)', layer.f4.initial_raw_output);
|
| 906 |
}
|
| 907 |
+
c.body.appendChild(f4c.root);
|
| 908 |
+
}
|
| 909 |
+
renderF5(c.body, layer.f5, layer.layer_idx);
|
| 910 |
+
(mrByLayer[layer.layer_idx] || []).forEach(function(mr){ renderMR(c.body, mr); });
|
| 911 |
+
main.appendChild(c.root);
|
| 912 |
+
}
|
| 913 |
+
function countErrors(node){
|
| 914 |
+
var n = 0;
|
| 915 |
+
if(node && typeof node === 'object'){
|
| 916 |
+
if(Array.isArray(node)) node.forEach(function(x){ n += countErrors(x); });
|
| 917 |
+
else Object.keys(node).forEach(function(k){
|
| 918 |
+
if(k === 'parse_error'){ if(node[k]) n++; }
|
| 919 |
+
else n += countErrors(node[k]);
|
| 920 |
+
});
|
| 921 |
+
}
|
| 922 |
+
return n;
|
| 923 |
+
}
|
| 924 |
+
function renderAnswer(main, fa){
|
| 925 |
+
if(!fa) return;
|
| 926 |
+
var c = card('Final answer', 'answer', {
|
| 927 |
+
collapsible:true, open:true,
|
| 928 |
+
badges:[badge(fa.terminated ? 'terminated' : 'not terminated', fa.terminated ? 'b-good' : 'b-warn')]
|
| 929 |
+
});
|
| 930 |
+
parseError(c.body, fa.parse_error, 'final answer');
|
| 931 |
+
metaRow(c.body, [['model', modelNote(fa.model)]]);
|
| 932 |
+
textBlock(c.body, fa.answer, {label:'answer (durable)'});
|
| 933 |
+
textBlock(c.body, fa.frontier, {label:'frontier the answer was written from', hideEmpty:true});
|
| 934 |
+
rawBlock(c.body, 'final answer raw output', fa.raw_output);
|
| 935 |
+
main.appendChild(c.root);
|
| 936 |
+
}
|
| 937 |
+
function renderJudge(main, j){
|
| 938 |
+
if(!j) return;
|
| 939 |
+
var cls = (j.normalized === null || j.normalized === undefined) ? 'b-muted'
|
| 940 |
+
: (j.normalized >= 0.75 ? 'b-good' : (j.normalized >= 0.4 ? 'b-warn' : 'b-bad'));
|
| 941 |
+
var text = (j.score === null || j.score === undefined)
|
| 942 |
+
? 'no score'
|
| 943 |
+
: num(j.score) + (j.score_max ? '/' + j.score_max : '') +
|
| 944 |
+
(j.normalized === null || j.normalized === undefined ? '' : ' (' + j.normalized.toFixed(2) + ')');
|
| 945 |
+
var c = card('Final judge', 'judge', {
|
| 946 |
+
collapsible:true, open:true,
|
| 947 |
+
badges:[badge(text, cls), badge('scale ' + (j.score_scale || '?'), 'b-plain')]
|
| 948 |
+
});
|
| 949 |
+
parseError(c.body, j.parse_error, 'judge');
|
| 950 |
+
metaRow(c.body, [['raw score', num(j.score)], ['scale', j.score_scale],
|
| 951 |
+
['normalized', j.normalized === null || j.normalized === undefined ? '—' : j.normalized.toFixed(3)],
|
| 952 |
+
['model', modelNote(j.model)]]);
|
| 953 |
+
textBlock(c.body, j.explanation, {label:'explanation', prose:true});
|
| 954 |
+
rawBlock(c.body, 'judge raw output', j.raw_output);
|
| 955 |
+
main.appendChild(c.root);
|
| 956 |
+
}
|
| 957 |
+
function renderTermination(main, t){
|
| 958 |
+
if(!t) return;
|
| 959 |
+
var c = card('Termination target', 'term', {
|
| 960 |
+
collapsible:true, open:true,
|
| 961 |
+
badges:t.parse_error ? [badge('parse_error', 'b-bad')] : []
|
| 962 |
});
|
| 963 |
+
parseError(c.body, t.parse_error, 'termination target');
|
| 964 |
+
metaRow(c.body, [['model', modelNote(t.model)],
|
| 965 |
+
['assistant_target chars', (t.assistant_target || '').length.toLocaleString()]]);
|
| 966 |
+
textBlock(c.body, t.assistant_target, {label:'assistant target (training text)', cot:true});
|
| 967 |
+
textBlock(c.body, t.cot, {label:'cot', cot:true, hideEmpty:true});
|
| 968 |
+
textBlock(c.body, t.rationale, {label:'rationale', cot:true, hideEmpty:true});
|
| 969 |
+
main.appendChild(c.root);
|
| 970 |
+
}
|
| 971 |
+
function renderFiltered(main, row){
|
| 972 |
+
var head = card('F0-rejected problem · ' + row.problem_id, null, {
|
| 973 |
+
badges:[badge('filtered out', 'b-bad')].concat(row.source ? [badge(row.source, 'b-plain')] : [])
|
| 974 |
+
});
|
| 975 |
+
metaRow(head.body, [['reason', row.reason || '—'],
|
| 976 |
+
['validity', row.f0 ? row.f0.validity : '—']]);
|
| 977 |
+
textBlock(head.body, row.problem, {label:'Problem statement', prose:true});
|
| 978 |
+
textBlock(head.body, row.rubric, {label:'Rubric', prose:true, hideEmpty:true});
|
| 979 |
+
main.appendChild(head.root);
|
| 980 |
+
renderF0(main, row.f0);
|
| 981 |
+
}
|
| 982 |
|
| 983 |
+
// ---------------------------------------------------------------- selection
|
| 984 |
+
function findTrajectory(uid){
|
| 985 |
+
for(var i = 0; i < DATA.trajectories.length; i++){
|
| 986 |
+
if(DATA.trajectories[i].uid === uid) return DATA.trajectories[i];
|
| 987 |
+
}
|
| 988 |
+
return null;
|
| 989 |
+
}
|
| 990 |
+
function findFiltered(uid){
|
| 991 |
+
for(var i = 0; i < DATA.filtered.length; i++){
|
| 992 |
+
if(DATA.filtered[i].uid === uid) return DATA.filtered[i];
|
| 993 |
}
|
| 994 |
+
return null;
|
| 995 |
+
}
|
| 996 |
+
function select(uid){
|
| 997 |
+
state.uid = uid;
|
| 998 |
+
blocks = [];
|
| 999 |
+
explorationIndex = {};
|
| 1000 |
+
var main = $('#main');
|
| 1001 |
+
main.textContent = '';
|
| 1002 |
+
var entry = findTrajectory(uid);
|
| 1003 |
+
if(entry){
|
| 1004 |
+
var d = entry.data;
|
| 1005 |
+
(d.layers || []).forEach(function(layer){
|
| 1006 |
+
(((layer.f4 || {}).reviews) || []).forEach(function(r){
|
| 1007 |
+
if(r.summary && r.summary.exploration_id){
|
| 1008 |
+
explorationIndex[r.summary.exploration_id] = anchorFor(layer.layer_idx, r.candidate_id);
|
| 1009 |
+
}
|
| 1010 |
+
});
|
| 1011 |
+
});
|
| 1012 |
+
renderProblem(main, d.problem, d.outcome, entry.summary, entry);
|
| 1013 |
+
renderF0(main, d.f0);
|
| 1014 |
+
var mrByLayer = {};
|
| 1015 |
+
(d.mr_targets || []).forEach(function(mr){
|
| 1016 |
+
(mrByLayer[mr.layer_idx] = mrByLayer[mr.layer_idx] || []).push(mr);
|
| 1017 |
+
});
|
| 1018 |
+
var seen = {};
|
| 1019 |
+
(d.layers || []).forEach(function(layer){
|
| 1020 |
+
seen[layer.layer_idx] = true;
|
| 1021 |
+
renderLayer(main, layer, mrByLayer);
|
| 1022 |
+
});
|
| 1023 |
+
if(!(d.layers || []).length){
|
| 1024 |
+
main.appendChild(el('div', 'empty',
|
| 1025 |
+
'This trajectory has no layers' +
|
| 1026 |
+
(d.outcome.excluded_reason ? ' (excluded_reason: ' + d.outcome.excluded_reason + ')' : '') + '.'));
|
| 1027 |
}
|
| 1028 |
+
var orphans = (d.mr_targets || []).filter(function(mr){ return !seen[mr.layer_idx]; });
|
| 1029 |
+
if(orphans.length){
|
| 1030 |
+
var oc = card('MR targets without a matching layer', 'mr', {collapsible:true, open:true});
|
| 1031 |
+
orphans.forEach(function(mr){ renderMR(oc.body, mr); });
|
| 1032 |
+
main.appendChild(oc.root);
|
| 1033 |
+
}
|
| 1034 |
+
renderAnswer(main, d.final_answer);
|
| 1035 |
+
renderJudge(main, d.final_judge);
|
| 1036 |
+
renderTermination(main, d.termination_target);
|
| 1037 |
+
} else {
|
| 1038 |
+
var f = findFiltered(uid);
|
| 1039 |
+
if(f) renderFiltered(main, f);
|
| 1040 |
}
|
| 1041 |
+
applyStageFilter();
|
| 1042 |
+
refreshAll();
|
| 1043 |
+
renderSidebar();
|
| 1044 |
+
window.scrollTo(0, 0);
|
| 1045 |
}
|
| 1046 |
|
| 1047 |
+
// ---------------------------------------------------------------- controls
|
| 1048 |
+
function applyStageFilter(){
|
| 1049 |
+
document.querySelectorAll('#main [data-stage]').forEach(function(n){
|
| 1050 |
+
n.classList.toggle('hidden', !state.stages.has(n.dataset.stage));
|
| 1051 |
+
});
|
| 1052 |
+
document.querySelectorAll('#main .cand').forEach(function(c){
|
| 1053 |
+
c.classList.toggle('hidden', !c.querySelector('[data-stage]:not(.hidden)'));
|
| 1054 |
+
});
|
| 1055 |
+
document.querySelectorAll('#main .layer').forEach(function(l){
|
| 1056 |
+
l.classList.toggle('hidden', !l.querySelector('[data-stage]:not(.hidden)'));
|
| 1057 |
+
});
|
| 1058 |
+
}
|
| 1059 |
+
function applyMatchFilter(){
|
| 1060 |
+
var on = state.filterMatches && state.query;
|
| 1061 |
+
document.querySelectorAll('#main .card').forEach(function(c){
|
| 1062 |
+
if(!on){ c.classList.remove('nomatch'); c.style.display = ''; return; }
|
| 1063 |
+
c.style.display = c.querySelector('mark') ? '' : 'none';
|
| 1064 |
+
});
|
| 1065 |
+
}
|
| 1066 |
+
function jumpMark(delta){
|
| 1067 |
+
if(!markNodes.length) return;
|
| 1068 |
+
if(markPos >= 0 && markNodes[markPos]) markNodes[markPos].classList.remove('here');
|
| 1069 |
+
markPos = (markPos + delta + markNodes.length) % markNodes.length;
|
| 1070 |
+
var m = markNodes[markPos];
|
| 1071 |
+
var d = m.closest('details');
|
| 1072 |
+
while(d){ d.open = true; d = d.parentElement ? d.parentElement.closest('details') : null; }
|
| 1073 |
+
m.classList.add('here');
|
| 1074 |
+
m.scrollIntoView({block:'center'});
|
| 1075 |
+
}
|
| 1076 |
+
function buildStageChips(){
|
| 1077 |
+
var host = $('#stage-chips');
|
| 1078 |
+
STAGES.forEach(function(s){
|
| 1079 |
+
var b = el('button', 'ctl tiny on', s[1]);
|
| 1080 |
+
b.addEventListener('click', function(){
|
| 1081 |
+
if(state.stages.has(s[0])) state.stages.delete(s[0]); else state.stages.add(s[0]);
|
| 1082 |
+
b.classList.toggle('on', state.stages.has(s[0]));
|
| 1083 |
+
applyStageFilter();
|
| 1084 |
+
});
|
| 1085 |
+
b.dataset.stage = s[0];
|
| 1086 |
+
host.appendChild(b);
|
| 1087 |
+
});
|
| 1088 |
+
}
|
| 1089 |
+
function setAllStages(on){
|
| 1090 |
+
state.stages = on ? new Set(STAGES.map(function(s){ return s[0]; })) : new Set();
|
| 1091 |
+
document.querySelectorAll('#stage-chips .ctl').forEach(function(b){ b.classList.toggle('on', on); });
|
| 1092 |
+
applyStageFilter();
|
| 1093 |
+
}
|
| 1094 |
+
function setTheme(theme){
|
| 1095 |
+
document.documentElement.setAttribute('data-theme', theme);
|
| 1096 |
+
$('#theme').textContent = theme === 'dark' ? 'Light theme' : 'Dark theme';
|
| 1097 |
+
try { localStorage.setItem('mtv4-theme', theme); } catch(e) {}
|
| 1098 |
+
}
|
| 1099 |
+
function init(){
|
| 1100 |
+
$('#run-name').textContent = DATA.run_name || DATA.run_dir;
|
| 1101 |
+
var st = DATA.stats;
|
| 1102 |
+
$('#stats').textContent =
|
| 1103 |
+
st.trajectories + ' trajectories · ' + st.terminated + ' terminated · ' + st.guided + ' guided · ' +
|
| 1104 |
+
st.minimum_waived + ' minimum waived · ' +
|
| 1105 |
+
st.excluded + ' excluded · ' + st.superseded + ' superseded · ' + st.filtered + ' F0-filtered · ' +
|
| 1106 |
+
st.parse_errors + ' parse errors · mean score ' +
|
| 1107 |
+
(st.mean_normalized === null || st.mean_normalized === undefined ? '—' : st.mean_normalized);
|
| 1108 |
+
$('#gen').textContent = DATA.run_dir + ' · generated ' + DATA.generated_at;
|
| 1109 |
+
buildStageChips();
|
| 1110 |
+
$('#stages-all').addEventListener('click', function(){ setAllStages(true); });
|
| 1111 |
+
$('#stages-none').addEventListener('click', function(){ setAllStages(false); });
|
| 1112 |
+
$('#cot').addEventListener('click', function(){
|
| 1113 |
+
state.hideCot = !state.hideCot;
|
| 1114 |
+
this.classList.toggle('on', state.hideCot);
|
| 1115 |
+
this.textContent = state.hideCot ? 'CoT hidden' : 'CoT shown';
|
| 1116 |
+
refreshAll();
|
| 1117 |
+
});
|
| 1118 |
+
$('#raw').addEventListener('click', function(){
|
| 1119 |
+
state.showRaw = !state.showRaw;
|
| 1120 |
+
this.classList.toggle('on', state.showRaw);
|
| 1121 |
+
this.textContent = state.showRaw ? 'Raw shown' : 'Raw hidden';
|
| 1122 |
+
document.querySelectorAll('#main .raw-wrap').forEach(function(d){ d.open = state.showRaw; });
|
| 1123 |
+
});
|
| 1124 |
+
$('#expand-all').addEventListener('click', function(){
|
| 1125 |
+
document.querySelectorAll('#main details').forEach(function(d){ d.open = true; });
|
| 1126 |
+
});
|
| 1127 |
+
$('#collapse-layers').addEventListener('click', function(){
|
| 1128 |
+
document.querySelectorAll('#main details.layer').forEach(function(d){ d.open = false; });
|
| 1129 |
+
});
|
| 1130 |
+
var timer = null;
|
| 1131 |
+
$('#search').addEventListener('input', function(){
|
| 1132 |
+
var value = this.value;
|
| 1133 |
+
if(timer) clearTimeout(timer);
|
| 1134 |
+
timer = setTimeout(function(){ state.query = value; refreshAll(); }, 160);
|
| 1135 |
+
});
|
| 1136 |
+
$('#next').addEventListener('click', function(){ jumpMark(1); });
|
| 1137 |
+
$('#prev').addEventListener('click', function(){ jumpMark(-1); });
|
| 1138 |
+
$('#only-matches').addEventListener('click', function(){
|
| 1139 |
+
state.filterMatches = !state.filterMatches;
|
| 1140 |
+
this.classList.toggle('on', state.filterMatches);
|
| 1141 |
+
applyMatchFilter();
|
| 1142 |
+
});
|
| 1143 |
+
$('#traj-filter').addEventListener('input', renderSidebar);
|
| 1144 |
+
$('#theme').addEventListener('click', function(){
|
| 1145 |
+
setTheme(document.documentElement.getAttribute('data-theme') === 'dark' ? 'light' : 'dark');
|
| 1146 |
+
});
|
| 1147 |
+
var saved = 'dark';
|
| 1148 |
+
try { saved = localStorage.getItem('mtv4-theme') || 'dark'; } catch(e) {}
|
| 1149 |
+
setTheme(saved);
|
| 1150 |
+
renderSidebar();
|
| 1151 |
+
var first = DATA.trajectories.length ? DATA.trajectories[0].uid
|
| 1152 |
+
: (DATA.filtered.length ? DATA.filtered[0].uid : null);
|
| 1153 |
+
if(first) select(first);
|
| 1154 |
+
else $('#main').appendChild(el('div', 'empty', 'This run directory contains no trajectories.'));
|
| 1155 |
+
}
|
| 1156 |
+
init();
|
| 1157 |
</script>
|
| 1158 |
</body>
|
| 1159 |
</html>
|