From 1cc805dfba1efe82e4127a7b8c0c536e59a99905 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 21 Sep 2026 23:33:33 +0900 Subject: [PATCH 1/2] =?UTF-8?q?knowledge(master):=20=EC=A7=80=EC=97=AD?= =?UTF-8?q?=C2=B7=EA=B3=84=EC=95=BD=EC=A2=85=EB=B3=84=2017=EC=A4=84=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC=20=E2=80=94=20=EC=A7=80=EC=97=AD=20=EA=B0=88?= =?UTF-8?q?=EB=A6=BC=20=EC=9E=AC=EB=A3=8C=20=ED=91=9C=20=C2=B7=20=EC=A0=84?= =?UTF-8?q?=EB=A0=A5=20=EC=9B=90=EB=AC=B8=20=EB=8C=80=EC=A1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 지역 자리 = 로직 입력 자재지역 · 전력 계약종별(17줄 모두 있음) — 대표로 굳히지 않는 것이 맞음. 품셈재료 모래·자갈 비고에 뜻을 적음. ref/_지역_갈림_재료.md — 지역이 이름 글자로만 있는 품목 여덟의 지역 수·울진 값(울진은 레미콘·아스콘만 있고 모래·자갈 없음) · 전력 두 줄은 한전 요금표와 맞음. 값은 안 지어 넣음. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01JgUhN55Z3BCYhUJTjwTNfj --- resources/master_data/ref/_남은_옛재료줄.md | 1 + resources/master_data/ref/_지역_갈림_재료.md | 61 ++++++++++++++++++++ resources/master_data/재료_품셈재료.json | 4 +- 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 resources/master_data/ref/_지역_갈림_재료.md diff --git a/resources/master_data/ref/_남은_옛재료줄.md b/resources/master_data/ref/_남은_옛재료줄.md index 52f3d590..47db77ea 100644 --- a/resources/master_data/ref/_남은_옛재료줄.md +++ b/resources/master_data/ref/_남은_옛재료줄.md @@ -28,6 +28,7 @@ - `MP000006` 자갈 1줄(GF000183) 연결이 `{이름, 지역=입력}`·`{이름, 계약종별=입력}` 이라 **줄마다 값이 입력(자재지역·전력 계약종별)에 따라 달라짐** — 대표 줄 하나로 굳히면 지역이 바뀔 때 틀린 값이 나옴. +→ **정리 끝(2026-09-21)**: 지역 자리 = 로직 입력 `자재지역` · 전력 = 입력 `전력 계약종별` — 17줄 모두 그 입력이 있음 · 대표로 굳히지 않는 것이 맞음 · 품목별 표 `ref/_지역_갈림_재료.md`. 모래·자갈은 산림 12장에서 쓴 방식(고르기 조건 + 단위중량 환산)을 건설품셈 줄에도 그대로 옮기면 되지만, 원문 단위가 ㎥ 와 ㎏ 로 갈려 **사용자 확정이 한 번 더 필요**해 이번엔 손대지 않음. ### ③ 이름에 `{변수}` 가 든 참조 — 22줄 diff --git a/resources/master_data/ref/_지역_갈림_재료.md b/resources/master_data/ref/_지역_갈림_재료.md new file mode 100644 index 00000000..80ed14dd --- /dev/null +++ b/resources/master_data/ref/_지역_갈림_재료.md @@ -0,0 +1,61 @@ +# 지역으로 값이 갈리는 재료 (2026-09-21) + +자재품목 30,592줄 훑기. **지역 칸은 없음** — 지역은 품명(이름) 글자에만 있음. 값은 지어내지 않음(세기만 함). + +## 지역이 이름에 적히는 꼴 (셋) + +| 꼴 | 보기 | +|---|---| +| 괄호 꼴 | `레미콘(관급)-경상북도(울진군)` · `아스콘(관급)-경상북도(청송군,영양군,울진군)` | +| 쉼표 꼴 | `모 래, 서울, 도착도` · `시멘트, 서울` · `쇄석골재, 포항, …` | +| 앞괄호 꼴 | `레미콘(서울)-사급` | + +엔진은 로직 입력 `자재지역`(시·군 이름)이 이름에 든 줄만 후보로 잡음(빈칸 없앰 · 지역 이름 그대로 맞댐) — 꼴을 가리지 않음. + +## 품목별 (줄 = 그 품목 이름 줄 전체 · 지역 수 · 울진) + +| 품목 | 구분 › 상세구분 | 줄 | 지역 수 | 울진 줄 | 울진 값 | +|---|---|---|---|---|---| +| 레미콘 | 레미콘 › 레미콘 | 3,203 | 87 | 19 | 19 | +| 아스콘(관급) | 아스콘·포장 › 아스콘 | 1,479 | 38 | 23 | 23 (「청송군·영양군·울진군」 묶음) | +| 쇄석골재 | 시멘트·골재 › 골재 | 124 | 56 | 0 | — | +| 혼합골재 | 시멘트·골재 › 골재 | 119 | 52 | 0 | — | +| 모래 | 시멘트·골재 › 골재 | 36 | 27 | 0 | — (포항 · 삼척 있음) | +| 시멘트 | 시멘트·골재 › 시멘트 | 71 | 21 | 0 | — | +| 자연자갈 | 시멘트·골재 › 골재 | 6 | 4 | 0 | — (서울·광주·대전·전주) | +| 쇄석자갈 | 시멘트·골재 › 골재 | 8 | 3 | 0 | — (금산·문경·원주) | + +- 지역 수는 이름에서 뽑은 지역어 어휘(99)로 센 값 — 「전국」 · 「제주(관급)」 같은 묶음 이름은 하나로 셈. +- 이름에 「울진」 이 든 줄 = 레미콘 19 · 아스콘 23 뿐 — 모래 · 자갈 · 골재 · 시멘트에는 없음. +- 철근 · 형강 · 합판 · 각재 · 철선 등도 이름에 지역어가 있으나 **물가지 원문의 판매처·규격 글**이라 지역 선택 대상 아님(울진 0). + +## 로직에서 어떻게 풀리는가 + +- 지역 자리 = 로직 입력 **`자재지역`**(자유 글 · 「시·군 이름」). 고르기 조건 칸(구분·상세구분·규격·대표)에는 지역 칸이 **없음** — 조건은 넓게 두고 이 입력이 이름 글자로 후보를 좁힘. 별도 자리를 더 만들지 않음. +- 지역 값은 마스터에 굳히지 않음 — 프로젝트가 고름. 시험 계산용 `시험입력` 만 있음(건설품셈 줄 「포항」 · 12-17-1-2 「울진」). +- 품셈재료 모래·자갈 줄(`MP000004` · `MP000006`) 비고에 「대표 줄로 굳히지 않음」 을 적음. + +## 막힘이 나는 곳 (지역 값이 없거나 갈림) + +| 시험 입력 | 결과 | +|---|---| +| `자재지역 = 울진` 으로 모래 줄을 부르는 로직 8줄(GC000211 · 677 · 685 · 933 · 934 · 938 · GF000176 · 183) | 「모래 지역 값 없음 — 울진」 — 울진 모래 줄이 없음 | +| `GF000183` (시험입력 울진) | 모래 뒤에 자갈도 울진 없음 — 두 줄 다 막힘 | +| `자재지역 = 삼척` | 「후보 여럿 — 규격 선택 필요 (4줄)」 — 삼척 모래는 강모래·해사·육상모래 규격이 섞임 | +| `자재지역 = 포항` | 모래 통과 · `GF000183` 은 자갈 줄이 없어 막힘 | + +→ 울진 현장은 **가까운 지역(삼척 등)을 고르거나 울진 값을 새로 받아야** 모래·자갈 줄이 풀림. 이 창은 값을 지어 넣지 않음. +→ 12-17-1-2(`GF000183`) 시험입력이 울진이라 시험 계산이 멈춤 — 현장이 울진이면 데이터 대기 목록에 넣을 것. + +## 전력 (계약종별) 원문 대조 + +원문 = `resources/knowledge/original/원가계산/전기요금_한국전력/20250101/별표1_월간전기요금표(C)_20250101.md`. + +| 유가전력 줄 | 값 | 원문 | 판정 | +|---|---|---|---| +| `MO000058` 주택용 저압 전력량요금 | 120.0 | 1-가(2) 처음 200kWh까지 120.0 | 맞음 | +| `MO000073` 일반용(갑)Ⅰ 저압 전력량요금 | 114.4 | 2-가(1) 여름 132.4 · 봄가을 91.9 · 겨울 119.0 → 단순평균 114.43 | 맞음 | + +- 두 줄만 남긴 것은 사용자 확정(2026-09-20) — 원문에 계약종별 지정은 없음(전력비 = 실비). +- 주택용은 **첫 구간 값만** 담음(다음 200kWh 214.6 · 초과 307.3 은 안 담음) — 시험 계산용 낮은 값이라는 뜻. +- 전력 로직 8줄(GC000893∼897 · 933 · 934 · 938)은 입력 `전력 계약종별`(고르기 둘)로 이 두 줄 가운데 하나를 고름 — 대표로 굳히지 않음. diff --git a/resources/master_data/재료_품셈재료.json b/resources/master_data/재료_품셈재료.json index c6bb3271..b406bdd8 100644 --- a/resources/master_data/재료_품셈재료.json +++ b/resources/master_data/재료_품셈재료.json @@ -12,9 +12,9 @@ { "키": "MP000001", "원문번호": "레미콘", "이름": "레디믹스트콘크리트", "규격": "", "단위": "㎥", "요구절": ["산림품셈 12-9-1", "산림품셈 12-11-1", "산림품셈 12-11-2-1", "산림품셈 12-12", "산림품셈 12-13", "산림품셈 12-15", "산림품셈 12-16", "산림품셈 12-17-2", "산림품셈 12-17-3", "산림품셈 13-4-4 주①", "산림품셈 13-4-5", "산림품셈 13-5-1 주⑤", "산림품셈 13-5-2", "건설품셈 공통 7-3-1 주⑥ 채움콘크리트"], "연결": {"이름": "레미콘", "규격": "", "지역": "입력"}, "고르기": null, "비고": "규격(강도·골재·슬럼프)별 값이 다르면 관리자가 줄을 나눔 · 후보 조건: 지역 입력" }, { "키": "MP000002", "원문번호": "시멘트", "이름": "시멘트", "규격": "", "단위": "kg", "요구절": ["산림품셈 12-1-3 주⑤⑥", "산림품셈 12-17-1-2 주③", "건설품셈 공통 6-3-1 주⑤", "건설품셈 건축 5-4-9", "건설품셈 건축 9-1-1", "건설품셈 건축 9-2-3", "건설품셈 건축 9-3-1"], "연결": "MT004176", "고르기": null, "비고": "연결: 자재품목 시멘트 전국 kg 줄" }, { "키": "MP000003", "원문번호": "모래(중량)", "이름": "모래", "규격": "건조상태", "단위": "kg", "요구절": ["산림품셈 12-1-3 주⑤"], "연결": null, "고르기": null, "비고": "자재품목 모래는 ㎥ — kg 환산 안 함 · 고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, - { "키": "MP000004", "원문번호": "모래", "이름": "모래", "규격": "", "단위": "㎥", "요구절": ["산림품셈 12-11-3", "산림품셈 12-17-1-2 주③", "건설품셈 공통 6-3-1 주⑤", "건설품셈 건축 9-1-1", "건설품셈 건축 9-3-1", "건설품셈 기계설비 13-6-3", "건설품셈 기계설비 13-6-6"], "연결": {"이름": "모래", "규격": "", "지역": "입력"}, "고르기": null, "비고": "후보 조건: 지역 입력" }, + { "키": "MP000004", "원문번호": "모래", "이름": "모래", "규격": "", "단위": "㎥", "요구절": ["산림품셈 12-11-3", "산림품셈 12-17-1-2 주③", "건설품셈 공통 6-3-1 주⑤", "건설품셈 건축 9-1-1", "건설품셈 건축 9-3-1", "건설품셈 기계설비 13-6-3", "건설품셈 기계설비 13-6-6"], "연결": {"이름": "모래", "규격": "", "지역": "입력"}, "고르기": null, "비고": "후보 조건: 지역 입력 · 대표 줄로 굳히지 않음 — 지역은 프로젝트가 정하는 로직 입력 「자재지역」 · 후보 = 이름에 그 지역이 든 줄(울진 모래 줄 없음 · ref/_지역_갈림_재료.md)" }, { "키": "MP000005", "원문번호": "자갈(중량)", "이름": "자갈 또는 부순돌", "규격": "", "단위": "kg", "요구절": ["산림품셈 12-1-3 주⑤"], "연결": null, "고르기": null, "비고": "품명 둘(자갈·부순돌) · 자갈 값은 ㎥ · 고르기 없음(자재품목 그 묶음에 같은 단위·이름 줄이 없음)" }, - { "키": "MP000006", "원문번호": "자갈", "이름": "자갈", "규격": "", "단위": "㎥", "요구절": ["산림품셈 12-17-1-2 주③"], "연결": {"이름": "자갈", "규격": "", "지역": "입력"}, "고르기": null, "비고": "후보 조건: 지역 입력" }, + { "키": "MP000006", "원문번호": "자갈", "이름": "자갈", "규격": "", "단위": "㎥", "요구절": ["산림품셈 12-17-1-2 주③"], "연결": {"이름": "자갈", "규격": "", "지역": "입력"}, "고르기": null, "비고": "후보 조건: 지역 입력 · 대표 줄로 굳히지 않음 — 지역은 프로젝트가 정하는 로직 입력 「자재지역」 · 후보 = 이름에 그 지역이 든 줄(울진 자갈 줄 없음 · ref/_지역_갈림_재료.md)" }, { "키": "MP000007", "원문번호": "철근", "이름": "철근", "규격": "", "단위": "ton", "요구절": ["산림품셈 12-15", "산림품셈 12-16"], "연결": null, "고르기": {"구분": "철근·강재", "상세구분": "철근"}, "비고": "SD300·400·500 갈림 — 원문 강도 없음" }, { "키": "MP000008", "원문번호": "이형철근 SD300 D16", "이름": "이형철근", "규격": "SD300, D16", "단위": "ton", "요구절": ["산림품셈 12-9-1"], "연결": "MT014464", "고르기": null, "비고": "연결: 이형철근(SD300) D16 전국 줄" }, { "키": "MP000009", "원문번호": "이형철근 SD300 D13", "이름": "이형철근", "규격": "SD300, D13", "단위": "ton", "요구절": ["산림품셈 12-12"], "연결": "MT014463", "고르기": null, "비고": "연결: 이형철근(SD300) D13 전국 줄" }, From cd2e8df39aecb1ad4a9f64371f2e54c8a1e560dc Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 21 Sep 2026 23:34:17 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat(M01):=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=20=EC=8B=9C=ED=97=98=20=EC=A4=84=20=EB=AA=A8=EB=8B=AC?= =?UTF-8?q?=20=E2=80=94=20=ED=95=9C=20=EC=A4=84=20=ED=92=80=EC=9D=B4?= =?UTF-8?q?=EC=99=80=20=EC=95=8C=EC=95=BD=20=EB=8B=A8=EC=B6=94(=EB=88=84?= =?UTF-8?q?=EB=A5=B8=20=EC=9E=90=EB=A3=8C=20=ED=95=98=EB=82=98=EB=A7=8C=20?= =?UTF-8?q?=ED=8E=BC=EC=B9=A8=C2=B7=EC=A0=91=ED=9E=98)=20(PLAN=205-3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01PAdA5ThqmtVSsbzjusk1cJ --- .../M01_MasterData_UI_LogicLab_Modal.ts | 81 ++++++++++++------- .../M01_MasterData_UI_LogicLab_Pill.css | 35 ++++++++ .../M01_MasterData_UI_LogicLab_Pill.ts | 44 ++++++++++ .../M01_MasterData_UI_LogicLab_Text.ts | 5 ++ 4 files changed, 138 insertions(+), 27 deletions(-) create mode 100644 M01_MasterData/M01_MasterData_UI_LogicLab_Pill.css create mode 100644 M01_MasterData/M01_MasterData_UI_LogicLab_Pill.ts diff --git a/M01_MasterData/M01_MasterData_UI_LogicLab_Modal.ts b/M01_MasterData/M01_MasterData_UI_LogicLab_Modal.ts index f6cd210a..0fbfa52f 100644 --- a/M01_MasterData/M01_MasterData_UI_LogicLab_Modal.ts +++ b/M01_MasterData/M01_MasterData_UI_LogicLab_Modal.ts @@ -9,13 +9,16 @@ import { createButton, el } from "@ui/ui_template_elements"; import type { ElementBrief, NamedFormula } from "./M01_MasterData_UI_Logic_Api"; import { formatNumber } from "./M01_MasterData_UI_Logic_Edit"; import { + explain, loadTable, matchRow, relatedFinds, type RelatedFind, type TableRow, } from "./M01_MasterData_UI_Logic_Note"; +import { pillBar, type Pill } from "./M01_MasterData_UI_LogicLab_Pill"; import { tl } from "./M01_MasterData_UI_LogicLab_Text"; +import "./M01_MasterData_UI_LogicLab_Pill.css"; export interface ModalTarget { title: string; @@ -87,6 +90,9 @@ function tableView( }); } +const groupOf = (ref: string): string => + ref.startsWith("LB") ? "인력" : ref.startsWith("M") ? "재료" : ref.startsWith("EQ") ? "기계" : ""; + function priceView(ref: string, brief: ElementBrief): HTMLElement { const cols = Object.entries(brief.값칸 ?? {}); return el("div", { @@ -134,38 +140,59 @@ export function openMaterialModal(target: ModalTarget): void { backdrop.addEventListener("click", (ev) => ev.target === backdrop && close()); backdrop.addEventListener("keydown", (ev) => ev.key === "Escape" && close()); - const parts: HTMLElement[] = [ - el("p", { className: "m01-logic__muted", text: tl("Modal_Qty") }), - el("pre", { className: "m01lab__expr", text: target.expr }), - ]; const finds = relatedFinds(target.expr, target.middles); - const price = target.element ? target.prices[target.element] : undefined; - if (target.element?.startsWith("로직(")) { - parts.push(el("p", { text: `${tl("Modal_Logic")} · ${target.element}` })); - } else if (price) { - parts.push( - el("p", { className: "m01-logic__muted", text: tl("Modal_Price") }), - priceView(target.element as string, price), - ); + const base = target.element?.split(".")[0] ?? ""; + const price = target.element ? (target.prices[target.element] ?? target.prices[base]) : undefined; + const logicRef = target.element?.startsWith("로직(") ? target.element : ""; + const pills: Pill[] = []; + if (price && target.element) { + pills.push({ + label: `${groupOf(base)} ${price.이름 ?? base}`.trim(), + view: () => priceView(target.element as string, price), + }); + } else if (target.element && !logicRef) { + pills.push({ + label: `${groupOf(base)} ${target.title}`.trim(), + view: () => el("p", { text: target.element }), + }); } - const tables = el("div", { className: "m01lab__tables" }); - parts.push(tables); - if (!finds.length && !price && !target.element?.startsWith("로직(")) { - parts.push(el("p", { className: "m01-logic__muted", text: tl("Modal_NoData") })); + if (logicRef) { + pills.push({ + label: `${tl("Pill_Logic")} ${logicRef.slice(3).split(",")[0].replace(/\)$/, "")}`, + view: () => el("p", { text: `${tl("Modal_Logic")} · ${logicRef}` }), + }); } + for (const f of finds) { + pills.push({ + label: `${tl("Pill_Table")} ${f.find.table}`, + view: async () => { + const table = await loadTable(f.find.table); + return table + ? tableView(f, table, target.values) + : el("p", { className: "m01-logic__bad", text: `${f.find.table} ?` }); + }, + }); + } + const unit = price ? `${tl("Modal_UnitPrice")} ${formatNumber(price.값)} × ` : ""; + const parts: HTMLElement[] = [ + el("p", { className: "m01-logic__muted", text: tl("Modal_Sum") }), + el("p", { + className: "m01lab__sum", + text: `${target.title} = ${unit}${explain(target.expr)}`, + }), + ...(pills.length + ? [el("p", { className: "m01-logic__muted", text: tl("Pill_Hint") }), pillBar(pills)] + : [el("p", { className: "m01-logic__muted", text: tl("Modal_NoData") })]), + el("details", { + className: "m01lab__raw", + children: [ + el("summary", { text: tl("Modal_Qty") }), + el("pre", { className: "m01lab__expr", text: target.expr }), + ], + }), + ]; body.replaceChildren(...parts); document.body.append(backdrop); dialog.tabIndex = -1; dialog.focus(); - - void Promise.all(finds.map(async (f) => ({ f, table: await loadTable(f.find.table) }))).then( - (got) => - tables.replaceChildren( - ...got.map(({ f, table }) => - table - ? tableView(f, table, target.values) - : el("p", { className: "m01-logic__bad", text: `${f.find.table} ?` }), - ), - ), - ); } diff --git a/M01_MasterData/M01_MasterData_UI_LogicLab_Pill.css b/M01_MasterData/M01_MasterData_UI_LogicLab_Pill.css new file mode 100644 index 00000000..91d90601 --- /dev/null +++ b/M01_MasterData/M01_MasterData_UI_LogicLab_Pill.css @@ -0,0 +1,35 @@ +/* M01 로직 개선 시험 — 줄 모달의 알약 단추 */ +.m01lab__pills { + display: flex; + flex-direction: column; + gap: var(--spacing-8); + min-width: 0; +} + +.m01lab__pill-row { + display: flex; + flex-wrap: wrap; + gap: var(--spacing-8); +} + +.m01lab__pill { + padding: var(--spacing-4) var(--spacing-12); + border: 1px solid var(--color-border); + border-radius: 999px; + background: var(--color-bg); + color: var(--color-text); + font: inherit; + cursor: pointer; + max-width: 100%; + overflow-wrap: anywhere; +} + +.m01lab__pill.is-open { + background: var(--color-accent); + border-color: var(--color-accent); + color: var(--color-bg); +} + +.m01lab__pill-stage { + min-width: 0; +} diff --git a/M01_MasterData/M01_MasterData_UI_LogicLab_Pill.ts b/M01_MasterData/M01_MasterData_UI_LogicLab_Pill.ts new file mode 100644 index 00000000..7282dd4c --- /dev/null +++ b/M01_MasterData/M01_MasterData_UI_LogicLab_Pill.ts @@ -0,0 +1,44 @@ +/* ============================================================================= + * M01_MasterData_UI_LogicLab_Pill.ts + * 줄 모달의 알약 단추 — 쓰인 자료를 알약으로만 늘어놓고, 누른 것 하나만 펼침(다시 누르면 접힘) + * ========================================================================== */ + +import { el } from "@ui/ui_template_elements"; + +export interface Pill { + /** 알약 글 — 보기 「표 QF000421」 · 「인력 석공」 */ + label: string; + /** 펼칠 때 그림 — 표처럼 읽어 와야 하면 Promise */ + view: () => HTMLElement | Promise; +} + +export function pillBar(pills: Pill[]): HTMLElement { + const stage = el("div", { className: "m01lab__pill-stage" }); + const buttons: HTMLButtonElement[] = []; + let open = -1; + let turn = 0; + const show = async (i: number): Promise => { + const mine = ++turn; + open = open === i ? -1 : i; + buttons.forEach((b, k) => { + b.setAttribute("aria-expanded", String(k === open)); + b.classList.toggle("is-open", k === open); + }); + if (open < 0) return stage.replaceChildren(); + const view = await pills[open].view(); + if (mine === turn) stage.replaceChildren(view); // 빨리 눌러도 마지막 것만 + }; + pills.forEach((p, i) => { + const b = el("button", { + className: "m01lab__pill", + text: p.label, + attrs: { type: "button", "aria-expanded": "false", "data-pill": p.label }, + }); + b.addEventListener("click", () => void show(i)); + buttons.push(b); + }); + return el("div", { + className: "m01lab__pills", + children: [el("div", { className: "m01lab__pill-row", children: buttons }), stage], + }); +} diff --git a/M01_MasterData/M01_MasterData_UI_LogicLab_Text.ts b/M01_MasterData/M01_MasterData_UI_LogicLab_Text.ts index c73c5063..c4992680 100644 --- a/M01_MasterData/M01_MasterData_UI_LogicLab_Text.ts +++ b/M01_MasterData/M01_MasterData_UI_LogicLab_Text.ts @@ -45,6 +45,11 @@ const TEXT = { ], Click_Hint: ["줄을 누르면 그 줄이 쓰는 자료가 뜸", "Click a line to see the data it uses"], Modal_Close: ["닫기", "Close"], + Modal_Sum: ["한 줄 풀이", "In one line"], + Pill_Hint: ["쓰인 자료 — 누르면 펼침", "Data used — tap to open"], + Modal_UnitPrice: ["단가", "Unit price"], + Pill_Table: ["표", "Table"], + Pill_Logic: ["로직", "Logic"], Modal_Qty: ["수량 식", "Quantity formula"], Modal_Price: ["단가 자료", "Price source"], Modal_Value: ["값", "Value"],