/* 444 헬퍼 — 관 구간값 예약(culvertopt)이 관 옮김을 따라가고 · 못 맞춘 값은 버리고 · 두 번째 [저장]이 안 덮음. * node helper_444_culvertopt.mjs <묶음.mjs> * 묶음 = 444 진입점(`helper_444_entry.ts` · 346-2 묶음 + 내보내기 · vite ssr 진짜 모듈) · 표준출력 JSON 한 벌. * 짝 = test_444_culvertopt_single_draft.py · 틀 = helper_415_swap.mjs(415-3). */ 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(); 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.__toasts = []; /* 관 정본(서버) — GET 은 지금 관 · PUT 은 받은 몸통으로 바꿈 */ let saved = []; const puts = []; globalThis.fetch = async (url, init = {}) => { if (String(url).includes("/drainage/pipe-points") && init.method === "PUT") { const points = JSON.parse(init.body).points; puts.push(points); saved = points.map((point) => ({ ...point, lonlat: [0, 0] })); } return { ok: true, status: 200, json: async () => ({ pipe_points: saved, basins: [] }) }; }; const m = await import(pathToFileURL(process.argv[2]).href); const P = "p444"; const R = 3; const out = {}; const section = (chainage_m, kind, extra = {}) => ({ station_id: `station_${String(Math.round(chainage_m * 1000)).padStart(12, "0")}`, chainage_m, label: "", kind, center_z: 100, azimuth_deg: 90, center_x: chainage_m, center_y: 0, frame: { left_xy: [0, 1] }, samples: [{ offset_m: 0, elevation_m: 100, valid: true }], design: { design_elevation_m: 101 }, ...extra, }); const detail = () => ({ longitudinal: { length_m: 100, stations: [], profile_alignment: { policy: { station_interval_m: 20 } }, }, cross_sections: [ section(0, "bp"), section(20, "regular"), section(40, "regular"), section(45.054, "irregular", { structure: "세월교", culvert: {} }), section(60, "regular"), section(80, "regular"), section(100, "ep"), ], }); const station = (key, chainageM, kind, id = null) => ({ key, chainageM, x: chainageM, y: 0, azimuthDeg: 90, left: [0, 1], kind, id, ground: { centerZ: 99, left: [{ offsetM: 0.5, z: 99.1 }], right: [{ offsetM: 0.5, z: 98.9 }] }, planRadiusM: null, curveOuterSide: null, curveWideningM: null, }); const list = (pipeAt) => [ station("end:BP", 0, "end"), station("grid:1", 20, "grid"), station("grid:2", 40, "grid"), station("pipe:pipe-s1", pipeAt, "pipe", "pipe-s1"), station("grid:3", 60, "grid"), station("grid:4", 80, "grid"), station("end:EP", 100, "end"), ].sort((a, b) => a.chainageM - b.chainageM); const key = `aislo:draft:culvertopt:${P}:${R}`; /* 1. 관 5 m 옮김 — 옛 세션 구간값 예약도 관 새 자리로(조정창 맵 없이 · 415-3 과 같은 길) */ m.writeState("section-detail", detail(), P, R); m.writeState("pipe-ids", { next: 2, ids: [{ id: "pipe-s1", at: 45.054 }] }, P); await m.loadSectionDetail(P, R); m.writeState("culvertopt", { 45.05: { ford_width_m: 4 } }, P, R); const stop = m.followSwaps( P, () => R, { visible: () => true }, async () => undefined, ); m.writeState("pipe-ids", { next: 2, ids: [{ id: "pipe-s1", at: 50 }] }, P); m.useDesignStore(P, null).set("stations", list(50)); await new Promise((resolve) => setTimeout(resolve, 30)); out.moved = m.readState("culvertopt", P, R); stop(); /* 2. [저장] 두 번 — 첫 번째는 관 새 자리에 얹고 세션 비움 · 두 번째는 안 보냄(값 그대로) */ saved = [ { id: "p5000", chainage_m: 50, source: "stream", facility: "ford", options: { ford_width_m: 3 } }, ]; await m.flushCulvertOptions(P, key); out.firstSave = { puts: puts.length, width: saved[0].options.ford_width_m, left: sessionStorage.getItem(key), }; await m.flushCulvertOptions(P, key); out.secondSave = { puts: puts.length, width: saved[0].options.ford_width_m }; /* 3. 못 맞춘 값(지운 · 옮긴 관 옛 자리) — 다른 관에 안 얹고 버림 */ m.writeState("culvertopt", { "30.00": { ford_width_m: 9 } }, P, R); await m.flushCulvertOptions(P, key); out.unmatched = { puts: puts.length, width: saved[0].options.ford_width_m, left: sessionStorage.getItem(key), }; process.stdout.write(JSON.stringify(out));