/* ============================================================================= * design_structure_guard.ts * 흙막이 공통 양식 — 배관(표 01) · 박스암거(표 02) · 세월교(표 04)가 같은 칸을 씀(PLAN 65-2). * * · 흙막이 = 형태 6 · 길이 · 높이 · 기준측점 전 · 후(길이 = 전 + 후 맞물림) * · 필수 보호공(유입 · 유출)은 구조 갈래마다 저장 키(`{side}_revet_*` 옛 키) · 선택 흙막이 · 도수로/돌붙임은 * 인스턴스 키(`soil_add_{n}_*` · `chute_add_{n}_*`) * import = 꼴만 — 시험이 이 폴더 파일만 옮겨 돌림. * ========================================================================== */ import type { SpecChoice, SpecContainer, SpecItem } from "./design_structure_spec"; export const SOIL_FORMS: SpecChoice[] = [ { value: "돌쌓기(찰)", label: "돌 쌓기(찰)" }, { value: "돌쌓기(메)", label: "돌 쌓기(메)" }, { value: "콘크리트", label: "콘크리트" }, { value: "돌망태", label: "돌망태" }, { value: "통나무·목재틀", label: "통나무/목재틀" }, { value: "바자", label: "바자" }, ]; /** 흙막이 기본값(54-36 · 사면안정 흙막이 정의 기본값과 같음). */ const SOIL_DEFAULTS: Record = { form: "돌쌓기(찰)", length: "10", height: "1.5", before: "5", after: "5", }; /** 형태 · 길이 · 높이 · 전 · 후 — 필수 보호공은 구조 갈래마다 옛 키(`keys`) · 선택 흙막이는 인스턴스 키. * `forms` = 갈래별 형태 선택지(배관 집수정 등) · `defaults` = 새 상자 · 흙막이를 고를 때 칸에 실제 값. */ export function guardItems( keys?: Record>, forms?: Record, defaults = !keys, ): SpecItem[] { const by = (field: string, choices?: Record) => keys ? { item: "structure", map: Object.fromEntries( // 키 없는 갈래 = 그 구조에 없는 칸(집수정 길이 · 전 · 후) — 가림 Object.entries(keys) .filter(([, k]) => k[field]) .map(([structure, k]) => [ structure, { key: k[field], choices: choices?.[structure] }, ]), ), } : undefined; const items: SpecItem[] = [ { id: "form", label: "형태", kind: "select", choices: SOIL_FORMS, by: by("form", forms) }, { id: "length", label: "길이 (m)", kind: "number", split: "length", step: 1, by: by("length") }, { id: "height", label: "높이 (m)", kind: "number", step: 0.1, by: by("height") }, { id: "before", label: "기준측점 전 (m)", kind: "number", split: "before", step: 0.5, by: by("before"), }, { id: "after", label: "기준측점 후 (m)", kind: "number", split: "after", step: 0.5, by: by("after"), }, ]; return defaults ? items.map((item) => ({ ...item, default: SOIL_DEFAULTS[item.id] })) : items; } export const revetKeys = (side: "inlet" | "outlet"): Record => ({ form: `${side}_revet_form`, length: `${side}_revet_length_m`, height: `${side}_revet_height_m`, before: `${side}_revet_before_m`, after: `${side}_revet_after_m`, }); /** 세월교 · 박스 유입 · 유출 흙막이 칸(79-7) — 높이 빈 칸 = 자동(`heightHint` · 횡단도가 셈) · * 유입만 절토부 앞 수평공간 칸(`inlet_revet_berm_m` · 유출은 없음 · 89-4)을 더함 · `wingBerm` = 세월교 * 유입 날개벽에도 같은 칸(수평 여유 · 107-3). */ export function bodyGuardItems( side: "inlet" | "outlet", heightHint: string, wingBerm = false, ): SpecItem[] { const items = guardItems({ 흙막이: revetKeys(side) }, undefined, true).map((item) => item.id === "height" ? { ...item, default: undefined, hint: heightHint } : item, ); if (side === "outlet") return items; const branch = { key: `${side}_revet_berm_m` }; const berm: SpecItem = { id: "berm", label: "수평공간 (m)", kind: "number", step: 0.1, default: "1", // 세월교 유입 날개벽 = 같은 칸 · 같은 키(끝이 묻히면 수평 여유 뒤 절토 · 면적 밖) by: { item: "structure", map: wingBerm ? { 흙막이: branch, 날개벽: branch } : { 흙막이: branch }, }, }; return [...items, berm]; } /** 추가 흙막이(선택 · 여러 개) — 사면안정 흙막이(표 09 · 54-26)와 같은 칸 · 구조 고르기 없음(54-30). */ export const SOIL_ADD: SpecContainer = { id: "soil_add", title: "흙막이", required: false, prefix: "soil_add", link: "gsoiladd", items: guardItems(), }; /** 도수로/돌붙임 칸 — 구조 · 두께(cm · 새 상자 30 · 90-2 사용자 확정) · 붙임 형식 · 면적(98-3) · 물넘이 포장(`ford_chute`)도 같은 칸. */ export const CHUTE_ITEMS: SpecItem[] = [ { id: "structure", label: "구조", kind: "select", choices: [ { value: "도수로", label: "도수로" }, { value: "돌붙임", label: "돌붙임" }, ], }, { id: "thickness", label: "두께 (cm)", kind: "number", step: 1, default: "30" }, // 붙임 형식 · 면적(98-3) — 빈칸이면 B08 구조물 집계표에 안 셈(설계자가 넣음) { id: "bond", label: "붙임 형식", kind: "select", choices: [ { value: "찰붙임", label: "찰붙임" }, { value: "메붙임", label: "메붙임" }, ], }, { id: "area", label: "면적 (㎡)", kind: "number", step: 0.1 }, ]; /** 도수로/돌붙임(선택 · 하나만 · 54-48) — 옛 둘 이상은 보이되 [추가]만 숨김. */ export const CHUTE_ADD: SpecContainer = { id: "chute_add", title: "도수로/돌붙임", required: false, prefix: "chute_add", link: "gchuteadd", max: 1, items: CHUTE_ITEMS, };