- Cross_Refresh refreshLocally — 세션 고름(단추 · 노견 확장 · 소단 깊이 · 암 경계 · 암 경사) ?? 저장 정본(savedDesigns) · 정본에 없는 측점만 메모리 설계 · 소단 깊이 · 소단 제원은 이번 원천 그대로(↶ 뒤 앞 값이 안 남음) - Design_Sync handleDesignChange — target.design 덮기 셋 뺌(세션만 · 카드는 다시 셈 알림이 그림) - 새 시험 test_272_choice_undo(옛 코드 = 넷 다 ↶ 뒤 앞 고름에 머묾) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
135 lines
4.3 KiB
JavaScript
135 lines
4.3 KiB
JavaScript
/* 467 덧 헬퍼 — 횡단 고름(단추 · 노견 확장 · 소단 깊이 · 암 경계)을 세션에 쓰고 다시 셈 → 세션 칸을 지움(↶) →
|
|
* 다시 셈 = 고르기 전(정본) 설계와 같은가 · 다시 씀(↷) = 고른 값과 같은가.
|
|
* node helper_272_choice_undo.mjs <묶음.mjs> <job.json>
|
|
* job = { standard, rockDefault, ground } · 짝 = `test_272_choice_undo.py` · 표준출력 JSON 한 벌.
|
|
*/
|
|
import { readFileSync } from "node:fs";
|
|
import { pathToFileURL } from "node:url";
|
|
|
|
const memory = () => {
|
|
const m = new Map();
|
|
return {
|
|
getItem: (k) => (m.has(k) ? m.get(k) : null),
|
|
setItem: (k, v) => m.set(k, String(v)),
|
|
removeItem: (k) => m.delete(k),
|
|
key: (i) => [...m.keys()][i] ?? null,
|
|
get length() {
|
|
return m.size;
|
|
},
|
|
clear: () => m.clear(),
|
|
};
|
|
};
|
|
globalThis.window = globalThis;
|
|
globalThis.sessionStorage = memory();
|
|
globalThis.localStorage = memory();
|
|
const any = new Proxy(function () {}, {
|
|
get: (_t, k) => (k === Symbol.toPrimitive ? () => 0 : any),
|
|
apply: () => any,
|
|
construct: () => any,
|
|
});
|
|
globalThis.document = any;
|
|
globalThis.requestAnimationFrame = (run) => setTimeout(run, 0);
|
|
globalThis.fetch = async () => new Response("{}", { status: 404 });
|
|
|
|
const m = await import(pathToFileURL(process.argv[2]).href);
|
|
const job = JSON.parse(readFileSync(process.argv[3], "utf8"));
|
|
const P = "p272undo";
|
|
const R = 6;
|
|
const AT = 40;
|
|
m.writeState("std-cross", job.standard, P);
|
|
m.rememberRockBoundaryDefault(P, job.rockDefault);
|
|
// 소단 사본 = 측점을 덮는 구간(소단 깊이가 먹게)
|
|
m.writeState(
|
|
"berm",
|
|
[{ start_m: 0, end_m: 100, width_m: 1, interval_m: 3, slope_deg: 0, depth_m: 1 }],
|
|
P,
|
|
R,
|
|
);
|
|
const canonDetail = () => ({
|
|
longitudinal: { length_m: 100, stations: [], profile_alignment: { policy: {} } },
|
|
cross_sections: [
|
|
{
|
|
station_id: "station_000000040000",
|
|
chainage_m: AT,
|
|
label: "",
|
|
kind: "regular",
|
|
center_z: 100,
|
|
azimuth_deg: 90,
|
|
center_x: AT,
|
|
center_y: 0,
|
|
frame: { left_xy: [0, 1] },
|
|
uphill_side: "left",
|
|
samples: job.ground,
|
|
design: {
|
|
design_elevation_m: 100,
|
|
ground_type: "soil",
|
|
section_mode: "left_cut",
|
|
ditch_type: "standard",
|
|
ditch_side: "left",
|
|
ditch_choice: null,
|
|
two_stage_slope: false,
|
|
},
|
|
},
|
|
],
|
|
});
|
|
m.writeState("section-detail", canonDetail(), P, R); // 저장 정본(세션 상세)
|
|
const alignment = {
|
|
stations: [{ chainage_m: AT, plan_elevation_m: 100.4 }],
|
|
samples: [
|
|
{ chainage_m: 0, elevation_m: 100.4 },
|
|
{ chainage_m: 100000, elevation_m: 100.4 },
|
|
],
|
|
balance: { cut_area_m2: 0, fill_area_m2: 0, net_area_m2: 0 },
|
|
};
|
|
const detail = canonDetail(); // 메모리 상세(가게가 쥔 객체)
|
|
const refresh = async (target = detail) => {
|
|
await m.refreshCrossDesigns({
|
|
projectId: P,
|
|
routeId: R,
|
|
detail: target,
|
|
edits: { station_offsets: {}, curve_radii: {} },
|
|
alignment,
|
|
});
|
|
return JSON.stringify(target.cross_sections[0].design);
|
|
};
|
|
const clear = (name) => sessionStorage.removeItem(m.stateKey(name, P, R));
|
|
|
|
const pristine = await refresh(canonDetail()); // 고르기 전 = 정본으로 셈
|
|
await refresh(); // 메모리 상세 한 번(측점 열쇠 세움)
|
|
const out = { pristineSame: (await refresh()) === pristine, cases: {} };
|
|
const CASES = {
|
|
choice: [
|
|
() =>
|
|
m.writeCrossDesignChoice(P, R, AT, {
|
|
ground_type: "blasting_rock",
|
|
section_mode: "right_cut",
|
|
ditch_side: "right",
|
|
ditch_type: "standard",
|
|
paved: false,
|
|
two_stage_slope: true,
|
|
ditch_choice: false,
|
|
}),
|
|
"crossdesign",
|
|
],
|
|
shoulder: [() => m.writeShoulderExtend(P, R, AT, "left", 1.2), "shoulderext"],
|
|
bermDepth: [() => m.writeBermDepth(P, R, AT, "left", 2.5), "bermdepth"],
|
|
rock: [() => m.writeKeyed("rockb", P, R, new Map([["40.00", 3.5]]), ["40.00"]), "rockb"],
|
|
};
|
|
for (const [name, [write, state]] of Object.entries(CASES)) {
|
|
write();
|
|
const picked = await refresh();
|
|
clear(state); // ↶ = 세션 칸 지움
|
|
const undone = await refresh();
|
|
write(); // ↷ = 다시 고름
|
|
const redone = await refresh();
|
|
clear(state);
|
|
const again = await refresh();
|
|
out.cases[name] = {
|
|
changed: picked !== pristine,
|
|
undoIsCanon: undone === pristine,
|
|
redoIsPicked: redone === picked,
|
|
undoAgain: again === pristine,
|
|
};
|
|
}
|
|
process.stdout.write(JSON.stringify(out));
|