/* 307 B06 고름 강조 헬퍼 — 진짜 TS 를 Node 로 돌려 표준출력 JSON 한 벌로. * ① 「관」 setter 가름(splitPipePick) ② 측점 길 형상 강조(highlightShapes) ③ 벽 고름 콘크리트 표식(Station_Controls). */ const fs = require("fs"); const path = require("path"); const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript")); const ROOT = path.join(__dirname, "..", ".."); const cache = new Map(); const load = (file) => { if (cache.has(file)) return cache.get(file); const js = ts.transpileModule(fs.readFileSync(file, "utf8"), { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, }).outputText; const box = { exports: {} }; cache.set(file, box.exports); const near = (m) => { if (m.startsWith("@config/")) return load(path.join(ROOT, "config", `${m.slice(8)}.ts`)); if (m.endsWith(".json")) return require(path.join(path.dirname(file), m)); if (m.startsWith(".")) return load(path.join(path.dirname(file), `${m}.ts`)); return new Proxy({}, { get: () => () => {} }); }; new Function("exports", "module", "require", js)(box.exports, box, near); return box.exports; }; const memory = new Map(); globalThis.sessionStorage = { getItem: (k) => (memory.has(k) ? memory.get(k) : null), setItem: (k, v) => memory.set(k, String(v)), removeItem: (k) => memory.delete(k), }; globalThis.window = { setTimeout, clearTimeout, sessionStorage: globalThis.sessionStorage }; const B = (f) => path.join(ROOT, "B06_Section", f); const shapePick = load(B("B06_Section_UI_Cross_Shape_Pick.ts")); // ① 「관」 setter — 콘크리트 고름 = 콘크리트만 · 관 고름 = 관만 · 다른 벽 = 그대로 const split = (concrete, key) => { const calls = { base: [], shape: [] }; const setter = shapePick.splitPipePick( (k) => calls.base.push(k), (on) => calls.shape.push(on), () => concrete, ); setter(key); return calls; }; // ② 측점 길 형상 강조 — 맹암거는 id 대로 · 물넘이 콘크리트(pipe-…)는 안 건드림 class Node { constructor(id, cls = "") { this.attrs = { "data-structure-id": id, class: cls }; } getAttribute(k) { return this.attrs[k] ?? null; } get classList() { const names = () => (this.attrs.class ?? "").split(" ").filter(Boolean); return { contains: (c) => names().includes(c), toggle: (c, on) => { const rest = names().filter((n) => n !== c); this.attrs.class = (on ? [...rest, c] : rest).join(" "); }, }; } } const drain = new Node("ud-1"); const concreteLit = new Node("pipe-90.00", "is-active"); // 형상 누름 「관」이 켠 콘크리트 const concreteOff = new Node("pipe-90.00"); const root = { querySelectorAll: () => [drain, concreteLit, concreteOff] }; shapePick.highlightShapes(root, "pipe-90.00"); // 물넘이포장 측점 길(알약 · 목록 · 측점선) = 알약 id const byStationPath = { concreteOff: concreteOff.classList.contains("is-active"), concreteLitKept: concreteLit.classList.contains("is-active"), }; shapePick.highlightShapes(root, "ud-1"); const drainLit = drain.classList.contains("is-active"); shapePick.highlightShapes(root, null); // 풂(Esc · 다른 것) — 콘크리트는 「관」 고름 풂이 끔 const afterRelease = { drain: drain.classList.contains("is-active"), concreteLit: concreteLit.classList.contains("is-active"), }; // ③ 벽 고름 콘크리트 표식 — 관 카드(80) · 물넘이 제 카드(90 · 관 없음) const stations = load(B("B06_Section_UI_Page_Station_Controls.ts")); const sections = [ { station_id: "s80", chainage_m: 80, culvert: { inlet: {}, outlet: {} }, samples: [] }, { station_id: "s90", chainage_m: 90, ford_pavement: { chainage_m: 90 }, samples: [] }, ]; let changes = 0; const controls = stations.createStationControls({ sessionKey: () => null, refreshCard: () => {}, detail: () => ({ cross_sections: sections }), crossHalfWidth: () => undefined, sampledHalfWidth: () => 20, ensureSampledWidth: async () => true, projectId: () => null, }); const revet = controls.revetOffset; revet.onSelectionChange = () => (changes += 1); const flag = (chainageM, key, ownerM) => { revet.select(chainageM, key, ownerM); return { shape: revet.shapePicked(), selected: revet.selectedFor(sections[chainageM === 80 ? 0 : 1]), }; }; const revetCases = { pipeOnPipeCard: flag(80, "pipe"), // 관 그림 누름 = 관 concreteOnPipeCard: flag(80, "pipe", 90), // 연동 관 카드 콘크리트 누름 = 콘크리트 concreteOnOwnCard: flag(90, "pipe", 90), // 물넘이 제 카드 콘크리트 누름 handoffOnOwnCard: flag(90, "pipe"), // 3D 넘김 「관」(관 없는 카드) = 콘크리트 wall: flag(80, "inlet"), released: flag(80, null), changes: 0, }; revetCases.changes = changes; process.stdout.write( JSON.stringify({ split: { concretePipe: split(true, "pipe"), pipePipe: split(false, "pipe"), concreteWall: split(true, "inlet"), none: split(false, null), }, byStationPath, drainLit, afterRelease, revetCases, }), );