/* ============================================================================= * M02_CF_Sample.ts * 단가산출 다이어그램 견본 — 처음 열었을 때 바로 보고 따라 만들 견본 셋(`_sample/*.json` · 손으로 짬) * ① 돌쌓기 메쌓기(인력) — 변수 · 품표 · 증가율표 · 인력 → 함수(표 찾기 · 높이 할증 · 직렬 · 병렬) → 출력 노무비 * ② 공구손료(비율) — 노무비 × 율 → 출력 재료비 * ③ 덤프트럭 시간당 작업량(값) — 변수 넷 → 함수 하나 → 출력 값 * 견본은 읽기만 — `sampleLoad` 는 「복사해서 열기」 사본(key 없음 · 저장하면 `_data` 에 새 번호). * 입력 값(노임 · 표)은 견본에 안 들고 열 때 · 저장 때 마스터에서 받음(정함 「계산」). * 모양 = `M02_CF_Model` CfLogic · 알약 이름 규칙(입력 = 요소 이름 · 「표」 · 변수 이름 / 함수 = inputs[].port · * output.name / 출력 = 「값」) — 정함 `docs/raw/M01_쉬운단가/원가다이어그램_정함.md` 11. 이 폴더째 지워도 됨. * ========================================================================== */ import { currentLanguageIndex } from "@ui/ui_template_locale"; import type { CfLogic } from "./M02_CF_Model"; const FILES = import.meta.glob("./_sample/*.json", { eager: true, import: "default" }); /** 견본마다 한 줄 설명 — [한, 영] */ const NOTE: Record = { masonry: [ "변수 · 품표 · 증가율표 · 인력 → 표 찾기 · 높이 할증 → 품 × 노임 → 노무비", "Variables, tables and labor → lookup, height surcharge → crew × wage → labor cost", ], rate: ["노무비 × 공구손료율 → 재료비", "Labor cost × small-tools rate → material cost"], value: [ "q · f · E · Cm → 60 × q × f × E ÷ Cm → 값(시간당 작업량)", "q, f, E, Cm → 60 × q × f × E ÷ Cm → value (output per hour)", ], }; /** 보여 줄 차례 */ const ORDER = ["masonry", "rate", "value"]; export interface CfSampleItem { /** 파일 이름(확장자 뺌) */ id: string; name: string; resultUnit: string; /** 쉬운 말 한 줄 */ note: string; } const idOf = (path: string): string => path.replace(/^.*\//, "").replace(/\.json$/, ""); const byId = (): Map => new Map(Object.entries(FILES).map(([path, lg]) => [idOf(path), lg])); /** 견본 목록 — 정한 차례 먼저 · 나머지는 이름 차례 */ export function sampleList(): CfSampleItem[] { const all = byId(); const rank = (id: string): number => (ORDER.includes(id) ? ORDER.indexOf(id) : ORDER.length); return [...all.entries()] .sort(([a, x], [b, y]) => rank(a) - rank(b) || x.name.localeCompare(y.name)) .map(([id, lg]) => ({ id, name: lg.name, resultUnit: lg.resultUnit, note: NOTE[id]?.[currentLanguageIndex === 1 ? 1 : 0] ?? "", })); } /** 견본 하나 「복사해서 열기」 — 깊은 사본 · key 없음(저장하면 서버가 새 번호) · 없으면 null */ export function sampleLoad(id: string): CfLogic | null { const lg = byId().get(id); return lg ? { ...(JSON.parse(JSON.stringify(lg)) as CfLogic), key: null } : null; }