/* 463 B05 · B06 한 페이지 페이지 설정 한 칸(요구 271-5 · 분석 4장 (B)) — 진짜 `applyPageSettings` · 페이지 설정 초안 · * 기준표 · 세션 칸. 종단도는 가짜(받은 것 기록). 노선 캐시 · 초안 갈래마다 종단도가 받는 기준을 JSON 한 줄로. * node helper_271_profile_settings.cjs (짝 = `test_271_profile_settings.py`) */ const fs = require("fs"); const path = require("path"); const ROOT = path.join(__dirname, "..", ".."); const ts = require(path.join(ROOT, "config", "node_modules", "typescript")); function memoryStorage() { const map = new Map(); return { getItem: (k) => (map.has(k) ? map.get(k) : null), setItem: (k, v) => map.set(k, String(v)), removeItem: (k) => map.delete(k), key: (i) => [...map.keys()][i] ?? null, get length() { return map.size; }, }; } globalThis.window = { sessionStorage: memoryStorage(), localStorage: memoryStorage() }; const REAL = new Set( [ "A00_Common/b_page_state.ts", "A00_Common/design/design_store.ts", // 페이지 설정 값 주인 = 가게 칸(472-5) "B05_Profile/B05_Profile_Api_Fetch.ts", "B05_Profile/B05_Profile_Api_PageSettings.ts", "B05_Profile/B05_Profile_UI_Page_Latest.ts", "B05_Profile/B05_Profile_UI_Panel_Fields.ts", "B05_Profile/logic/B05_Profile_Grade_Criteria.ts", // 법정 기준표(511-B B-3 · 화면에서 옮김) ].map((rel) => path.join(ROOT, rel)), ); const anything = () => new Proxy({}, { get: (_target, key) => (key === "__esModule" ? false : () => undefined) }); const cache = new Map(); function load(file) { if (cache.has(file)) return cache.get(file); const box = { exports: {} }; cache.set(file, box.exports); const js = ts.transpileModule(fs.readFileSync(file, "utf8"), { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, }).outputText; const req = (request) => { if (request === "@ui/ui_template_locale") return { ui_locales: {}, currentLanguageIndex: 0 }; if (!request.startsWith(".")) return anything(); const target = path.resolve(path.dirname(file), request); const full = fs.existsSync(`${target}.ts`) ? `${target}.ts` : target; return REAL.has(full) ? load(full) : anything(); }; new Function("exports", "module", "require", js)(box.exports, box, req); return box.exports; } const latestApi = load(path.join(ROOT, "B05_Profile", "B05_Profile_UI_Page_Latest.ts")); const settings = load(path.join(ROOT, "B05_Profile", "B05_Profile_Api_PageSettings.ts")); const state = load(path.join(ROOT, "A00_Common", "b_page_state.ts")); const P = "P463"; /** 가짜 종단도 — 받은 기준을 적음. 최소고 강제는 편집 가드가 페이지 설정 한 칸을 바로 읽음(472-5) — * 화면은 늘 캐시에 둔 노선을 넘기므로(`writeRouteLatestCache` 뒤) 받은 노선을 캐시에 두고 읽음. */ function apply(latest) { const got = {}; if (latest) state.writeState("latest", latest, P); latestApi.applyPageSettings( { setGradeLimit: (pct) => (got.grade = pct), setStationDisplay: (next) => (got.display = next), }, P, latest, ); if (Object.keys(got).length) got.enforce = settings.enforceMinCoverOf(P); return got; } const latestOf = (params) => ({ project_id: P, surface_params: {}, route_params: params }); const out = {}; window.sessionStorage = memoryStorage(); out.nothing = apply(undefined); // 노선 캐시 · 초안 없음 = 종단도 그대로 state.writeState( "latest", latestOf({ options: { grade_class: "trunk", design_speed_kph: 30, terrain_type: "normal" }, max_grade_pct: null, enforce_pipe_clearance: true, station_display: { station: 3, cumulative: 60 }, }), P, ); out.saved = apply(undefined); // 캐시 읽음 settings.writePageSettings(P, { design_speed_kph: 30, terrain_type: "normal", max_grade_pct: 12, min_vertical_radius_m: null, min_tangent_length_m: null, enforce_pipe_clearance: false, station_display: { station: 5, cumulative: 100 }, }); out.draft = apply(undefined); // 초안이 이김 out.work = apply( latestOf({ options: { grade_class: "work", design_speed_kph: 30, terrain_type: "normal" } }), ); // 받은 노선 · 초안 그대로 이김(작업임도 30 → 20 · 넣은 12 그대로) state.clearState("pagesettings", P); out.workSaved = apply( latestOf({ options: { grade_class: "work", design_speed_kph: 30, terrain_type: "normal" } }), ); out.defaults = apply(latestOf({})); // 빈 설정 = 좌측 패널 기본(20 · 특수 · 강제 해제 · 0) state.clearState("latest", P); settings.writePageSettings(P, { design_speed_kph: 40, terrain_type: "special", max_grade_pct: null, min_vertical_radius_m: null, min_tangent_length_m: null, enforce_pipe_clearance: true, station_display: { station: 0, cumulative: 0 }, }); out.draftOnly = apply(undefined); state.clearState("pagesettings", P); // 463 덧 — surface_params 없는 노선(옛 · 시험 · 막 만든 프로젝트) = 안 죽고 저장 설정대로 · 등고선 칸은 패널 값 그대로 const bare = { project_id: P, route_params: { enforce_pipe_clearance: true } }; out.noSurface = apply(bare); out.noSurfacePanel = latestApi.panelValuesOf(bare).contourInterval ?? null; console.log(JSON.stringify(out));