commit b38dcad7db508bd5a1cce5293c4a1ce3750ec692
Author: Eiichi Shimazu <studio@adaptdesign.jp>
Date:   Sat Nov 14 23:13:32 2026 +0900

    判定の画面で確定済みの回を開いたら記録した pick / place のボタンを塗る (依頼 190). index.html だけ. 回を開いたら人の確定の行 (なければ確定の行) の pick / place を button.on で塗る (AI だけの回は塗らない・書けたか分からない操作の回はその入力を戻す). 押して変えたら押したものが塗られ, 回を移ると記録の値に戻る. 今の判定の札を 1 回にし, 札・人が確定済み・日時・pick / place を 1 行目にまとめる. 書き込み・キー・数え方・見た目の決まりは変えない. テスト test_verdicts 39 OK
    
    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---
 pi05/verdict_viewer/index.html | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/pi05/verdict_viewer/index.html b/pi05/verdict_viewer/index.html
index b8a1443..044143c 100644
--- a/pi05/verdict_viewer/index.html
+++ b/pi05/verdict_viewer/index.html
@@ -238,6 +238,10 @@ async function select(stem) {
   catch (e) { if (seq === selSeq) { $("#title").textContent = stem; status("この回を読めませんでした: " + e.message + " ・ 一覧でもう一度選んでください", "err"); } return false; }
   if (seq !== selSeq || d.run_stem !== cur) return false;
   detail = d; loading = false;
+  if (!po) {  // 記録した pick / place を塗る (人の確定があればそれ, なければ確定の行. 依頼 190)
+    const r = recordedRow();
+    if (r) { pp = {pick: r.pick || null, place: r.place || null}; markPP(); }
+  }
   $("#title").textContent = stem;
   $("#meta").textContent = `送ったチャンク ${detail.executed_chunks} ・ 終わり方 ${detail.end_reason || "記録なし"} ・ ${detail.model || ""}`;
   renderMedia(); renderInfo(); renderChart();
@@ -272,8 +276,8 @@ function renderInfo() {
   const a = detail.ai, l = detail.latest;
   $("#ai").innerHTML = a ? `<div class="big">${OC_JA[a.outcome]}</div><div>pick ${a.pick} / place ${a.place} ・ 素材 ${a.evidence || "なし"}</div><div class="muted">${esc(a.ai_reason)}</div>` : `<span class="muted">AI の判定はありません</span>`;
   const h = detail.history.filter(r => HUMAN.includes(r.labeler)).pop();  // 人が確定した行 (依頼 187)
-  const hl = h ? `<div><b>人が確定済み</b> ${tag(h.outcome, false)} ・ ${esc(h.labeled_at.slice(0, 10))} ${hm(h.labeled_at)}</div>` : "";
-  $("#cur").innerHTML = l ? `<div class="big">${tag(l.outcome, l.labeler === "ai")} <span class="muted" style="font-size:12px">${LB_JA[l.labeler]}</span></div>${hl}<div>pick ${l.pick} / place ${l.place} ・ ${esc(l.labeled_at)}</div>${l.note ? `<div class="muted">${esc(l.note)}</div>` : ""}` : `<span class="muted">まだ判定がありません</span>`;
+  const c = h || l;  // 札は 1 回だけ. 札・人が確定・時刻・pick / place を 1 行目に (依頼 190)
+  $("#cur").innerHTML = c ? `<div>${tag(c.outcome, c.labeler === "ai")} ${h ? "<b>人が確定済み</b>" : `<span class="muted">${LB_JA[c.labeler]}</span>`} ・ ${esc(c.labeled_at.slice(0, 10))} ${hm(c.labeled_at)} ・ pick ${c.pick} / place ${c.place}</div>${c.note ? `<div class="muted">${esc(c.note)}</div>` : ""}` : `<span class="muted">まだ判定がありません</span>`;
   markOC();
   $("#hist").innerHTML = detail.history.length ? `<table class="hist"><tr><th>時刻</th><th>判定</th><th>pick/place</th><th>付けた</th></tr>${detail.history.map(r => `<tr><td>${esc(r.labeled_at)}</td><td>${tag(r.outcome, r.labeler === "ai")}</td><td>${r.pick}/${r.place}</td><td>${LB_JA[r.labeler]}</td></tr>`).join("")}</table>` : `<span class="muted">なし</span>`;
 }
@@ -338,6 +342,13 @@ function cursor(vt) {
 }
 
 // 判定するのボタン: 指定がなければ開いている回の人の確定を塗る (依頼 189)
+// 開いた回の記録した行: 人の確定があればそれ, なければ確定の行 (AI だけの回は null. 依頼 190)
+function recordedRow() {
+  if (!detail) return null;
+  const h = detail.history.filter(r => HUMAN.includes(r.labeler)).pop();
+  const l = detail.latest;
+  return h || (l && l.labeler !== "ai" ? l : null);
+}
 function humanOc() { const h = detail ? detail.history.filter(r => HUMAN.includes(r.labeler)).pop() : null; return h ? h.outcome : null; }
 function markOC(oc = humanOc()) { document.querySelectorAll("[data-oc]").forEach(b => b.classList.toggle("on", b.dataset.oc === oc)); }
 function markPP() {
