Files
Aislo/resources/tester/helper_294_6_ford_linked_mark.cjs
T

143 lines
4.5 KiB
JavaScript

/* 294-6 물넘이 연결 표기 헬퍼 — 진짜 TS 를 Node 로 돌려 표준출력 JSON 한 벌로.
* 옆 카드(물넘이 측점 ≠ 카드 측점) · 주인 카드에 물넘이포장을 그리고 연결 꼴 · 호버 글 · 고름 표식을 잼.
*/
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.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;
};
// DOM 흉내 — 속성 · 자식 · classList · 글만
class Node {
constructor(tag) {
this.tag = tag;
this.attrs = {};
this.children = [];
this.dataset = {};
this.style = {};
this.textContent = "";
}
setAttribute(k, v) {
this.attrs[k] = String(v);
}
getAttribute(k) {
return this.attrs[k] ?? null;
}
hasAttribute(k) {
return k in this.attrs;
}
append(...kids) {
this.children.push(...kids);
}
get classList() {
const names = () => (this.attrs.class ?? "").split(" ").filter(Boolean);
const set = (list) => (this.attrs.class = list.join(" "));
return {
contains: (c) => names().includes(c),
add: (c) => names().includes(c) || set([...names(), c]),
toggle: (c, on) =>
set(on ? [...names().filter((n) => n !== c), c] : names().filter((n) => n !== c)),
};
}
querySelectorAll(selector) {
const attr = /^\[([\w-]+)\]$/.exec(selector)?.[1];
const all = this.children.flatMap((k) => [k, ...k.querySelectorAll(selector)]);
return all.filter((k) => attr && k.hasAttribute(attr));
}
}
globalThis.document = { createElementNS: (_ns, tag) => new Node(tag) };
const B06 = (f) => path.join(ROOT, "B06_Section", f);
const pave = load(B06("B06_Section_UI_Cross_Ford_Pavement.ts"));
const linked = load(B06("B06_Section_UI_Cross_Ford_Linked.ts"));
const shapePick = load(B06("B06_Section_UI_Cross_Shape_Pick.ts"));
const design = {
section_mode: "left_cut",
tilted: true,
cross_slope_pct: 5,
design_elevation_m: 100,
pavement_thickness_m: 0.2,
paved: true,
road_edges: {
left: { offset_m: 3, elevation_m: 100.15 },
right: { offset_m: -3, elevation_m: 99.85 },
},
carriageway_edges: {
left: { offset_m: 2.5, elevation_m: 100.125 },
right: { offset_m: -2.5, elevation_m: 99.875 },
},
design_line: [
{ offset_m: 6, elevation_m: 103 },
{ offset_m: 3, elevation_m: 100.15 },
{ offset_m: -3, elevation_m: 99.85 },
{ offset_m: -7, elevation_m: 97.2 },
],
};
// 검증 프로젝트 꼴 — 4+10(물넘이 · 폭 10) → 4+15 카드에도 포장 · 측점 간격 20
const spec = { chainage_m: 90, span_m: 10, depth_m: 0.4, slope_pct: 5 };
const draw = (chainage) => {
const svg = new Node("g");
const before = new Node("polyline"); // 앞서 그린 것(세월교 점선 등) — 연결 꼴 밖
before.setAttribute("class", "b06-chart__ford-deck-plan");
svg.append(before);
const from = svg.children.length;
pave.appendFordPavementOverlay(
svg,
spec,
design,
(o) => o,
(e) => e,
);
const marked = linked.markLinkedFordPavement(
svg,
from,
{ ford_pavement: spec, chainage_m: chainage },
20,
);
const shapes = svg.children
.slice(from)
.filter((k) =>
["b06-chart__ford-pavement", "b06-chart__ford-deck-plan"].some((c) =>
k.classList.contains(c),
),
);
shapePick.highlightShapes(svg, "pipe-90.00");
return {
marked,
classes: shapes.map((k) => k.attrs.class),
titles: shapes.map((k) =>
k.children.filter((c) => c.tag === "title").map((c) => c.textContent),
),
pick: shapes
.filter((k) => k.hasAttribute("data-structure-id"))
.map((k) => k.attrs["data-structure-id"]),
beforeClass: before.attrs.class,
};
};
process.stdout.write(
JSON.stringify({
neighbor: draw(95),
owner: draw(90),
noSpec: linked.markLinkedFordPavement(new Node("g"), 0, { chainage_m: 95 }, 20),
}),
);