/* 364-6 헬퍼 — vite ssr 로 묶은 진짜 모듈(helper_364_6_entry.ts)로 표준 횡단 칸 열기 전후 다시 셈을 잼. * node helper_364_6_std_panel.mjs <묶음.mjs> <고정 자료.json> * 고정 자료 = 검증_sub7 노선 304(모두 리핑암)의 서버 상세 4 측점 + config 표준 횡단. */ import { readFileSync } from "node:fs"; import { pathToFileURL } from "node:url"; const store = () => { 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 = store(); globalThis.localStorage = store(); // 패널 DOM — 무엇을 불러도 받아 주는 빈 객체 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); const [bundlePath, fixturePath] = process.argv.slice(2); const m = await import(pathToFileURL(bundlePath).href); const fixture = JSON.parse(readFileSync(fixturePath, "utf8")); const raw = JSON.stringify(fixture.detail); const standard = fixture.standard_cross_section; const RID = fixture.route_id; const KEYS = ["cut_area_m2", "fill_area_m2", "ditch_area_m2"]; const areas = (sections) => sections.map((s) => Object.fromEntries(KEYS.map((k) => [k, s.design?.[k] ?? null]))); const saved = fixture.detail.longitudinal.profile_alignment?.edits ?? {}; const edits = { station_offsets: saved.station_offsets ?? {}, curve_radii: saved.curve_radii ?? {}, }; const recompute = async (pid) => { const detail = JSON.parse(raw); await m.refreshCrossDesigns({ projectId: pid, routeId: RID, detail, edits }); return areas(detail.cross_sections); }; /** B05 = 칸 없음(config 기본값) → B06 = 칸 열림. seed = 저장 표준 횡단을 세션에 먼저 채운 경우. */ async function scenario(pid, seed) { m.rememberStandardDefaults(pid, standard); if (seed) m.writeState("std-cross", seed, pid); const b05 = await recompute(pid); m.createStandardPanel(pid, standard, () => {}); const b06 = await recompute(pid); return { b05, b06, session: m.readState("std-cross", pid) }; } /** 공통 칸 끝 글(364-6 덧) — 고치기 전 · 공통 칸을 고친 뒤(토사 값을 다른 그룹에 펼침 = spread). */ const LABELS = [ "B06_Std_Field_DitchTop", "B06_Std_Field_CrossSlopeMin", "B06_Std_Field_CrossSlopeMax", "B06_Std_Field_CutSlope", ]; const notesOf = (state) => Object.fromEntries(LABELS.map((l) => [l, m.commonGroupNote(state, l)])); const edited = JSON.parse(JSON.stringify(standard)); edited.rock.ditch.top_width_m = edited.soil.ditch.top_width_m; edited.paved.ditch.top_width_m = edited.soil.ditch.top_width_m; edited.rock.cross_slope_pct.max = edited.soil.cross_slope_pct.max; const out = { notes: { before: notesOf(standard), after: notesOf(edited) }, server: areas(fixture.detail.cross_sections), standard, config: await scenario("p364a", null), stored: await scenario("p364b", standard), }; process.stdout.write(JSON.stringify(out));