/* 371-2 관 글 기울기 헬퍼 — 짝 = `test_371_2_pipe_slope_text.py`. * B07 픽스처 배관 측점에 `appendCulvertOverlay` 를 가짜 SVG 로 그려 관 글 · 툴팁을 읽음. */ const fs = require("fs"); const path = require("path"); const { makeLoader } = require("./helper_ts_stub_loader.cjs"); const ROOT = path.join(__dirname, "..", ".."); const noop = new Proxy({}, { get: () => () => "" }); /** 아주 작은 SVG 가짜 — 글 자리 판정에 쓰는 것만(class 고르기 · 속성 · 부모). */ class El { constructor(tag) { this.tag = tag; this.attrs = {}; this.children = []; this.parentNode = null; this.ownerSVGElement = null; this.textContent = ""; } setAttribute(k, v) { this.attrs[k] = String(v); } getAttribute(k) { return this.attrs[k] ?? null; } appendChild(c) { c.parentNode = this; c.ownerSVGElement = this.tag === "svg" ? this : this.ownerSVGElement; this.children.push(c); return c; } append(...cs) { cs.forEach((c) => this.appendChild(c)); } addEventListener() {} all() { return this.children.flatMap((c) => [c, ...c.all()]); } querySelectorAll(sel) { return this.all().filter((e) => (e.attrs.class ?? "").split(" ").includes(sel.slice(1))); } querySelector(sel) { return this.querySelectorAll(sel)[0] ?? null; } } globalThis.document = { addEventListener: () => undefined, createElementNS: (_ns, t) => new El(t) }; const { loadTs } = makeLoader({ root: ROOT, requireFor: (full) => { const resolve = (base) => fs.existsSync(base) && fs.statSync(base).isFile() ? base : `${base}.ts`; const req = (r) => { if (r.startsWith("@ui/") || r.startsWith("@config/")) return noop; if (r.startsWith("@util/")) return loadTs(resolve(path.join(ROOT, "common_util", r.slice(6)))); return loadTs(resolve(path.join(path.dirname(full), r))); }; return req; }, }); const { computeCulvertLayout } = loadTs( path.join(ROOT, "B06_Section", "logic/B06_Section_Cross_Culvert_Geom.ts"), ); const { appendCulvertOverlay } = loadTs( path.join(ROOT, "B06_Section", "B06_Section_UI_Cross_Culvert.ts"), ); const sections = JSON.parse( fs.readFileSync(path.join(__dirname, "fixtures", "b07_cross_overlay_sections.json"), "utf8"), ).cross_sections; const section = sections.find((s) => s.culvert && !s.culvert.hidden_pipe); /** 노폭 라벨이 있는 B06 카드 꼴 svg 에 그려 관 글 · 관 툴팁을 돌려줌. */ function draw(layout, hidePipe) { const svg = new El("svg"); const road = new El("text"); road.setAttribute("class", "b06-chart__carriageway-label"); road.setAttribute("x", 200); road.setAttribute("y", 180); svg.appendChild(road); const plot = new El("g"); svg.appendChild(plot); appendCulvertOverlay( plot, layout, (o) => o, (z) => z, undefined, hidePipe, false, ); const titles = svg .all() .filter((e) => e.tag === "title") .map((e) => e.textContent); return { infos: svg.querySelectorAll(".b06-chart__pipe-info").map((e) => e.textContent), pipeTips: titles.filter((t) => t.startsWith("관매설")), }; } const layout = computeCulvertLayout(section, section.samples); const reverse = { ...layout, pipe: { ...layout.pipe, slopePct: -0.43 } }; process.stdout.write( JSON.stringify({ slopePct: layout.pipe.slopePct, lengthM: layout.pipe.lengthM, pipe: draw(layout, false), reverse: draw(reverse, false), hidden: draw(layout, true), }), );