feat(785-6): 785-5 실제 길 꼴로 맞춤 — 칠 = Judge.judged · 옮기기 덮음 물음 · 목록 셈 중 다시 읽음

- M02_Hopyo_Marks.py: 블록 판정 = M02_Hopyo_Judge.judged(셈 중 None = 옛 판정)
- Hopyo_Rows.ts: [옮기기] 409(이미 옮김) = 물음 한 번 뒤 덮음
- Hopyo_SheetSk.ts: 목록 셈중 = 3 초마다 다시 읽음(판정 · 고를 것 실림)
- JudgeApi · logic/Picks: 절 몫 = 수 · 목록 셈중 · 몸 덮음
- 시험: test_642_6 Marks 부름 대역 · helper_778_5 Check 대역

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-04 23:23:26 +09:00
co-authored by Claude Opus 5.5
parent fa08640b36
commit 65bafe0050
7 changed files with 34 additions and 25 deletions
@@ -6,17 +6,25 @@
* 수량 · 단위 환산 칸(`logic/Hopyo_Unit` · 같은 단위 = 숨김) · [보기] = 엑셀 그 행 · [확인]
* · 단산 줄 = [블록 풀이] 펼침(`Hopyo_Block.solvedBody` · 절마다 기초 · 입력값 칸) + 「단가산출 통째」 칩(단산N → SK)
* · 머리 [호표 제안 모두 확인](사용자 누름 · 다 풀린 제안만) · 아래 [옮기기](`createJudgeMove` · 오른쪽 판 아래)
* · 이미 옮긴 것(409) = 물음 한 번 뒤 덮음
* · 고름 · 확인 = 캐시(`createJudgeState`) · 자동 확인 · 자동 옮김 없음 · 옮김 = 서버가 정본으로 다시 셈
* ========================================================================== */
import { createBadge, type BadgeTone } from "@ui/ui_template_badge";
import { createButton, createInputField, el, showToast } from "@ui/ui_template_elements";
import {
askConfirm,
createButton,
createInputField,
el,
showToast,
} from "@ui/ui_template_elements";
import { t as L } from "@ui/ui_template_locale";
import { createPanelHead } from "@ui/ui_template_panel_head";
import { tableRow, tableShell, type Cell, type Column } from "@ui/ui_template_table";
import { createText } from "@ui/ui_template_text";
import { createToggle } from "@ui/ui_template_toggle";
import { formatNumber } from "../common_util/common_util_money";
import { StaleError } from "./M02_MasterTemplete_Api_Fetch";
import type { HopyoScope } from "./M02_MasterTemplete_Hopyo_Api";
import { createJudgeState, solvedBody, type JudgeState } from "./M02_MasterTemplete_Hopyo_Block";
import {
@@ -300,7 +308,11 @@ export function createJudgeMove(opt: JudgeMoveOptions): { root: HTMLElement; des
}
btn.disabled = true;
try {
const r = await moveJudge(opt.target, opt.key, body);
const r = await moveJudge(opt.target, opt.key, body).catch(async (e: unknown) => {
// 이미 옮긴 호표 · 블록 — 물음 한 번 뒤 덮음(아니면 그만)
if (!(e instanceof StaleError) || !(await askConfirm({ message: e.message }))) throw e;
return moveJudge(opt.target, opt.key, { ...body, 덮음: true });
});
const stuck = new Set(r.막힘.map((x) => `${x.호표 ?? "b" + x.블록}:${x.차례 ?? ""}`));
let d = opt.state.get();
for (const [h, lines] of Object.entries(body.호표))