- 「제약 못 지킨 구간」 · 「기준 초과」 = 같은 목록에서 원지반 기울기 뺀 수(엔진 419 짝) - 「원지반 기울기(참고) 최대 … % · 상한 넘는 곳 N」 줄 따로 · 넘는 곳은 풍선 - ends_over_limit 이면 「시종점 높이 차가 상한을 넘음(평균 … %) — 종단으로 못 맞춤 · 노선을 늘려야 함」 - 도움말 글(종단기울기 상한 · 못 지킨 구간 · 원지반 기울기 · 시종점) · 시험 test_421_2 · 옛 시험 단언 고침 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ji4nuyLVHcxrXWHTdb5nRD
108 lines
3.5 KiB
JavaScript
108 lines
3.5 KiB
JavaScript
/* 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) }));
|