/* 386-3 헬퍼 — 묶음 planline 저장 기준 = 저장 상세 + 지금 입력(관 · 구조물)이 심는 측점. * node helper_384_3_planted.mjs <묶음.mjs> * vite ssr 로 묶은 진짜 모듈(helper_384_3_entry.ts) · 표준출력 JSON 한 벌. 짝 = test_384_3_planted_base.py. */ 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(); const any = new Proxy(function () {}, { get: (_t, k) => (k === Symbol.toPrimitive ? () => 0 : any), apply: () => any, construct: () => any, }); globalThis.document = any; const m = await import(pathToFileURL(process.argv[2]).href); const P = "p386"; localStorage.setItem("frd_current_project_id", P); m.usePipeIds(P); const st = (chainage_m, kind = "regular") => ({ station_id: `station_${String(Math.round(chainage_m * 1000)).padStart(12, "0")}`, chainage_m, kind, }); const server = [st(0, "bp"), st(20), st(40), st(60, "ep")]; const detail = { longitudinal: { stations: server, length_m: 60, samples: [ { chainage_m: 0, elevation_m: 100 }, { chainage_m: 60, elevation_m: 106 }, ], profile_alignment: { policy: { default_curve_radius_m: 100, station_interval_m: 20 }, base_pvi: [ { chainage_m: 0, elevation_m: 100 }, { chainage_m: 60, elevation_m: 106 }, ], samples: [ { chainage_m: 0, ground_elevation_m: 100 }, { chainage_m: 60, ground_elevation_m: 106 }, ], stations: server, segments: [], curves: [], }, }, cross_sections: [], }; // 구조물 표 = 실제 정의(마스터 읽기만) · 측점을 심는 구조물 — 켜진 점형 하나 · 꺼진 것 하나(보기와 같이 둘 다 심음) const definition = JSON.parse( readFileSync(new URL("../master_template/구조물정의.json", import.meta.url), "utf8"), ); m.useCatalogDefinition(definition); const planting = (item) => { const row = m.catalogRow(item.type_id); return row && row.owner === "structures" && row.station !== "none"; }; const on = definition.types.find( (item) => item.enabled !== false && item.placement === "point" && planting(item), ); const off = definition.types.find((item) => item.enabled === false && planting(item)); const types = [on, off].map(({ type_id, group, placement, enabled }) => ({ type_id, group, placement, enabled, })); const at = (id, type_id, chainage_m) => ({ structure_id: id, type_id, chainage_m, start_m: chainage_m - 3, end_m: chainage_m + 3, options: {}, }); const ids = (base) => base.stations.map((s) => [s.station_id.split(":")[0], s.chainage_m]); const viewBase = { stations: [{ station_id: "view", chainage_m: 1 }] }; const none = m.plantedBase({ base: viewBase, detail }, { pipes: [], structures: [] }, types); const pipe = m.plantedBase( { base: viewBase, detail }, { pipes: [], structures: [at("b1", on.type_id, 33)] }, types, ); const both = m.plantedBase( { base: viewBase, detail }, { pipes: [], structures: [at("b1", on.type_id, 33), at("d1", off.type_id, 47)], }, types, ); const noDetail = m.plantedBase( { base: viewBase, detail: null }, { pipes: [], structures: [] }, types, ); process.stdout.write( JSON.stringify({ none: ids(none), pipe: ids(pipe), both: ids(both), noDetail: noDetail === viewBase, pvi: both.basePvi.length, kinds: [on.type_id, off.type_id], }), );