/* 421-2 추천 창 「못 지킨 구간」 · 원지반 기울기(참고) · 시종점 알림 헬퍼 — `_Initial_Model` 을 * 그 자리에서 트랜스파일해 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(); function memoryStorage() { const map = new Map(); return { getItem: (key) => (map.has(key) ? map.get(key) : null), setItem: (key, value) => map.set(key, String(value)), removeItem: (key) => map.delete(key), key: (index) => [...map.keys()][index] ?? null, get length() { return map.size; }, _map: map, }; } const session = memoryStorage(); globalThis.window = { localStorage: memoryStorage(), sessionStorage: session }; globalThis.fetch = () => Promise.resolve({ ok: false }); const STUBS = { "@ui/ui_template_palette": { themeColor: (_name, fallback) => fallback } }; function loadTs(file) { const full = path.resolve(file); if (cache.has(full)) return cache.get(full); const js = ts.transpileModule(fs.readFileSync(full, "utf8"), { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, }).outputText; const box = { exports: {} }; cache.set(full, box.exports); const localRequire = (request) => { if (STUBS[request]) return STUBS[request]; if (request.endsWith(".css")) return {}; if (request.startsWith("@ui/")) return loadTs(path.join(ROOT, "ui_template", `${request.slice(4)}.ts`)); if (request.startsWith(".")) return loadTs(path.join(path.dirname(full), `${request}.ts`)); return require(request); }; new Function("exports", "module", "require", js)(box.exports, box, localRequire); cache.set(full, box.exports); return box.exports; } const model = loadTs(path.join(ROOT, "B05_Profile", "B05_Profile_UI_RouteEdit_Initial_Model.ts")); const nodes = [ { x: 0, y: 0 }, { x: 10, y: 5 }, ]; const item = (kind, station, value, limit, reason) => ({ kind, station, value, limit, reason }); const now = model.normalizeRouteInitial( { nodes, curves: [], metrics: { max_grade_pct: 35.8, over_limit: { grade: 2, radius: 1, station: 1, stream: 0, total: 4 }, violations: [ item("grade", "No.1", 28.8, 14, "원지반 기울기 — 참고"), item("radius", "No.3", 10, 12, "지형상 불가능 — 곡선"), item("grade", "No.4", 18.9, 14, "원지반 기울기"), item("station", "No.5+3.0", 3, 0, "측점 밖"), ], }, ends_grade_pct: 16.24, ends_over_limit: true, }, "earthwork", null, ); const clean = model.normalizeRouteInitial( { nodes, curves: [], metrics: { max_grade_pct: 12, over_limit: { total: 1, grade: 1 }, violations: [item("grade", "No.2", 15, 14, "")], }, ends_grade_pct: 3, ends_over_limit: false, }, "follow", null, ); const old = model.normalizeRouteInitial( { nodes, curves: [], metrics: { max_grade_pct: 9, over_limit: { total: 3 } } }, "gentle", null, ); const lines = (choice) => ({ violations: model.violationsLine(choice.metrics), ground: model.groundGradeLine(choice.metrics), groundTitle: model.groundGradeTitle(choice.metrics), ends: model.endsLine(choice), over: choice.metrics.overLimitCount, route: model.metricsLines(choice.metrics).route, }); process.stdout.write(JSON.stringify({ now: lines(now), clean: lines(clean), old: lines(old) }));