284 lines
20 KiB
JavaScript
284 lines
20 KiB
JavaScript
/* -*- coding: utf-8 -*- */
|
||
/**
|
||
* STMATE 시뮬레이터: 내역서(BOQ), 제잡비(Calc_Kanjub), 변경설계(Revision) 렌더러 (app_views_cost.js)
|
||
*/
|
||
const StmateCostViews = (() => {
|
||
const esc = (s) =>
|
||
String(s ?? "").replace(
|
||
/[&<>"']/g,
|
||
(c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c],
|
||
);
|
||
const fmt = (n, maxDec = 2) =>
|
||
new Intl.NumberFormat("ko-KR", { maximumFractionDigits: maxDec }).format(Number(n) || 0);
|
||
|
||
function renderBoqTab(state, res) {
|
||
const sys = state.sysConfig,
|
||
boq = res.boqOrig;
|
||
const unitChoices = [
|
||
...state.ilwiItems.map((b) => [b.id, `[일위 B] ${b.code} ${b.name}`]),
|
||
...state.sanItems.map((d) => [d.id, `[단산 D] ${d.code} ${d.name}`]),
|
||
...state.machines.map((m) => [m.id, `[중기 X] ${m.code} ${m.name}`]),
|
||
...state.resources.map((r) => [r.id, `[단독 ${r.code[0]}] ${r.code} ${r.name}`]),
|
||
];
|
||
|
||
const rowsHtml = boq.rows
|
||
.map(
|
||
(r, i) => `
|
||
<tr class="${r.rowType !== "normal" ? "excl-row" : ""}">
|
||
<td><input type="text" data-sec="boqItems" data-idx="${i}" data-field="code" value="${esc(r.code)}" class="code-input"></td>
|
||
<td><input type="text" data-sec="boqItems" data-idx="${i}" data-field="name" value="${esc(r.name)}"></td>
|
||
<td><select data-sec="boqItems" data-idx="${i}" data-field="refId">${unitChoices.map(([v, l]) => `<option value="${esc(v)}" ${r.refId === v ? "selected" : ""}>${esc(l)}</option>`).join("")}</select></td>
|
||
<td>
|
||
<select data-sec="boqItems" data-idx="${i}" data-field="rowType">
|
||
<option value="normal" ${r.rowType === "normal" ? "selected" : ""}>일반 말단행(직접비)</option>
|
||
<option value="gov_mat" ${r.rowType === "gov_mat" ? "selected" : ""}>C* 제외구역(관급원자재)</option>
|
||
<option value="gov_fee" ${r.rowType === "gov_fee" ? "selected" : ""}>C* 제외구역(조달수수료)</option>
|
||
</select>
|
||
</td>
|
||
<td class="num-col"><input type="number" data-sec="boqItems" data-idx="${i}" data-field="qty" value="${r.qty}" step="any"></td>
|
||
<td class="money-col">${fmt(r.unitInfo.T, 0)}</td>
|
||
<td class="money-col">${fmt(r.M, 0)}</td>
|
||
<td class="money-col">${fmt(r.L, 0)}</td>
|
||
<td class="money-col">${fmt(r.S, 0)}</td>
|
||
<td class="money-col highlight-col"><strong>${fmt(r.T, 0)}</strong>${r.optimizTarget ? `<div class="diff-warn">OPTIMIZ: ${esc(r.optimizTarget)}</div>` : ""}</td>
|
||
<td class="money-col">${fmt(r.aggT, 0)}</td>
|
||
<td class="center-col"><button type="button" class="btn-del" data-action="del-boq" data-idx="${i}">삭제</button></td>
|
||
</tr>`,
|
||
)
|
||
.join("");
|
||
|
||
return `
|
||
<div class="panel-card">
|
||
<div class="card-header">
|
||
<div>
|
||
<h2>내역서 계산 방식 및 <code>ST_Func_C.CPM :: OPTIMIZ</code> 차액 보정 제어</h2>
|
||
<p>14·15단계 REA 분석에서 확인된 <code>CHNNM</code>(비목별 금액 우선 vs 총액 우선) 및 <code>OPTNM</code>(<code>SML</code> 차액 보정 순서) 동작을 검증합니다. 또한 <code>C*</code> 제외금액 구역(관급자재대)은 직접공사비 합산에서 분리됩니다(16번 문서 §4.2).</p>
|
||
</div>
|
||
<button type="button" class="btn primary" data-action="add-boq">+ 내역 행 추가</button>
|
||
</div>
|
||
<div class="control-grid">
|
||
<label class="ctrl-item">
|
||
<span>내역서 계산 방식 (<code>CHNNM</code> · <code>+0x7c5</code>)</span>
|
||
<select data-sec="sysConfig" data-field="chnMode">
|
||
<option value="bimok" ${sys.chnMode === "bimok" ? "selected" : ""}>0: 비목별 금액 먼저 (각 비목 절사 후 합산)</option>
|
||
<option value="total" ${sys.chnMode === "total" ? "selected" : ""}>1: 총액 먼저 (OPTIMIZ로 단수 차액 성분 배분)</option>
|
||
</select>
|
||
</label>
|
||
<label class="ctrl-item">
|
||
<span>차액 보정 우선순위 (<code>OPTNM</code> · <code>+0x7dc</code>)</span>
|
||
<select data-sec="sysConfig" data-field="optOrder">
|
||
<option value="SML" ${sys.optOrder === "SML" ? "selected" : ""}>SML (경비 → 재료비 → 노무비)</option>
|
||
<option value="MLS" ${sys.optOrder === "MLS" ? "selected" : ""}>MLS (재료비 → 노무비 → 경비)</option>
|
||
<option value="LMS" ${sys.optOrder === "LMS" ? "selected" : ""}>LMS (노무비 → 재료비 → 경비)</option>
|
||
</select>
|
||
</label>
|
||
</div>
|
||
<div class="table-scroll">
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr><th>코드(<code>BDCODE1</code>)</th><th>공종명</th><th>연결 단가</th><th>구역 구분</th><th>설계수량(<code>QTY1</code>)</th><th>합계단가</th><th>재료비(<code>M_AMT1</code>)</th><th>노무비(<code>L_AMT1</code>)</th><th>경비(<code>S_AMT1</code>)</th><th>내역 합계(<code>T_AMT1</code>)</th><th>집계표(사사오입)</th><th>관리</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
${rowsHtml}
|
||
<tr class="total-row">
|
||
<td colspan="6">직접공사비 소계 (<code>C*</code> 제외금액 구역 불포함)</td>
|
||
<td class="money-col">${fmt(boq.directM, 0)}</td>
|
||
<td class="money-col">${fmt(boq.directL, 0)}</td>
|
||
<td class="money-col">${fmt(boq.directS, 0)}</td>
|
||
<td class="money-col">${fmt(boq.directTotal, 0)}</td>
|
||
<td colspan="2">관급원자재: ${fmt(boq.govRawTotal, 0)} / 수수료: ${fmt(boq.govFeeTotal, 0)}</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>`;
|
||
}
|
||
|
||
function renderKanjubTab(state, res) {
|
||
const cfg = state.kanjubConfig,
|
||
k = res.kanjubOrig;
|
||
const itemRows = k.items
|
||
.map(
|
||
(it) => `
|
||
<tr>
|
||
<td><code>${esc(it.code)}</code></td>
|
||
<td><strong>${esc(it.label)}</strong></td>
|
||
<td><span class="formula-tag">${esc(it.baseDesc)}</span></td>
|
||
<td class="money-col">${fmt(it.baseAmt, 0)}</td>
|
||
<td class="num-col"><input type="number" data-sec="kanjubRates" data-field="${esc(it.code)}" value="${it.ratePct}" step="any"></td>
|
||
<td class="money-col highlight-col"><strong>${fmt(it.amount, 0)}</strong></td>
|
||
</tr>`,
|
||
)
|
||
.join("");
|
||
|
||
return `
|
||
<div class="panel-card">
|
||
<div class="card-header">
|
||
<div>
|
||
<h2>원가계산 4형식 및 제잡비·끝전조정 제어 (<code>ST_KanJub.CPM :: Calc_Kanjub</code>)</h2>
|
||
<p>원가계산 형식(<code>T/S/TA/SA</code>)을 바꾸면 기타경비·환경보전비·일반관리비·이윤의 <strong>밑수 공식 자체가 전환</strong>됩니다(12번 문서 §7). 또한 도급공사비 절사 차액을 세전 환산(<code>ROUND(차액/1.1)</code>)하여 이윤에서 빼는 끝전조정을 검증합니다(16번 문서 §4.4).</p>
|
||
</div>
|
||
</div>
|
||
<div class="control-grid">
|
||
<label class="ctrl-item">
|
||
<span>원가계산 형식 (<code>TWM_KANJUB</code> 4탭)</span>
|
||
<select data-sec="kanjubConfig" data-field="scheme">
|
||
<option value="T" ${cfg.scheme === "T" ? "selected" : ""}>T: 일반형식 (표준 제비율)</option>
|
||
<option value="S" ${cfg.scheme === "S" ? "selected" : ""}>S: 수공형식 (세부경비 8종 분리)</option>
|
||
<option value="TA" ${cfg.scheme === "TA" ? "selected" : ""}>TA: 실적일반 (환경·보증 밑수=직공비, 이윤에 재료비 포함)</option>
|
||
<option value="SA" ${cfg.scheme === "SA" ? "selected" : ""}>SA: 실적수공 (일반관리비 밑수=직공비+간노)</option>
|
||
</select>
|
||
</label>
|
||
<label class="ctrl-item">
|
||
<span>부가가치세 기준 (<code>I_BUGA</code> · 태그 59)</span>
|
||
<select data-sec="kanjubConfig" data-field="vatMode">
|
||
<option value="supply_10" ${cfg.vatMode === "supply_10" ? "selected" : ""}>(1) 공급가액의 10%</option>
|
||
<option value="mat_10" ${cfg.vatMode === "mat_10" ? "selected" : ""}>(2) 재료비의 10% (면세·임협식 변형)</option>
|
||
<option value="mat_exp_10" ${cfg.vatMode === "mat_exp_10" ? "selected" : ""}>(3) (재료비+산출경비)의 10%</option>
|
||
<option value="zero" ${cfg.vatMode === "zero" ? "selected" : ""}>(0) 영세율 / 부가세 0원</option>
|
||
</select>
|
||
</label>
|
||
<label class="ctrl-item">
|
||
<span>도급액 절사 자리 (<code>I_TOT_JEOL</code> · <code>+0x204</code>)</span>
|
||
<select data-sec="kanjubConfig" data-field="totJeolDigits">
|
||
<option value="-3" ${Number(cfg.totJeolDigits) === -3 ? "selected" : ""}>1,000원 미만 절사 (-3)</option>
|
||
<option value="-4" ${Number(cfg.totJeolDigits) === -4 ? "selected" : ""}>10,000원 미만 절사 (-4)</option>
|
||
<option value="-2" ${Number(cfg.totJeolDigits) === -2 ? "selected" : ""}>100원 미만 절사 (-2)</option>
|
||
<option value="0" ${Number(cfg.totJeolDigits) === 0 ? "selected" : ""}>절사 없음 (0)</option>
|
||
</select>
|
||
</label>
|
||
<label class="ctrl-item">
|
||
<span>산업안전보건관리비 기초액 (원)</span>
|
||
<input type="number" data-sec="kanjubConfig" data-field="anjunBaseAdd" value="${cfg.anjunBaseAdd}" step="1000">
|
||
</label>
|
||
<label class="ctrl-item">
|
||
<span>관급자재대 끝전 처리 (기본: 천원 올림)</span>
|
||
<select data-sec="kanjubConfig" data-field="govRoundMode">
|
||
<option value="up" ${cfg.govRoundMode === "up" ? "selected" : ""}>천원 단위 올림 (ROUNDUP -3)</option>
|
||
<option value="half" ${cfg.govRoundMode === "half" ? "selected" : ""}>천원 단위 반올림 (ROUND -3)</option>
|
||
<option value="down" ${cfg.govRoundMode === "down" ? "selected" : ""}>천원 단위 절사 (ROUNDDOWN -3)</option>
|
||
</select>
|
||
</label>
|
||
<label class="ctrl-item checkbox-row">
|
||
<input type="checkbox" data-sec="kanjubConfig" data-field="enableProfitEndAdj" ${cfg.enableProfitEndAdj !== false ? "checked" : ""}>
|
||
<span>끝전 차액을 이윤(<code>C_IYUN_M</code>)에서 세전 차감 보정 (<code>0x4724f0</code>)</span>
|
||
</label>
|
||
</div>
|
||
<div class="table-scroll">
|
||
<table class="data-table">
|
||
<thead><tr><th>저장키</th><th>원가계산 항목</th><th>산정기초 (밑수 공식)</th><th>밑수 금액 (D_)</th><th>적용 요율 (R_ %)</th><th>산출 확정액 (S_)</th></tr></thead>
|
||
<tbody>
|
||
<tr class="sub-row"><td><code>DAMT_M/L/S</code></td><td><strong>직접공사비 합계</strong></td><td>직접재료비 ${fmt(k.dM, 0)} + 직접노무비 ${fmt(k.dL, 0)} + 산출경비 ${fmt(k.dS, 0)}</td><td class="money-col">${fmt(k.dT, 0)}</td><td class="center-col">—</td><td class="money-col"><strong>${fmt(k.dT, 0)}</strong></td></tr>
|
||
${itemRows}
|
||
<tr class="sub-row"><td><code>PURE_COST</code></td><td><strong>순공사원가</strong></td><td>재료비 + 노무비(직노+간노) + 경비(산출+제경비)</td><td class="money-col">${fmt(k.pureConstructionCost, 0)}</td><td class="center-col">—</td><td class="money-col"><strong>${fmt(k.pureConstructionCost, 0)}</strong></td></tr>
|
||
<tr><td><code>ILBAN</code></td><td><strong>일반관리비</strong></td><td><span class="formula-tag">${esc(k.ilbanDesc)}</span></td><td class="money-col">${fmt(k.ilbanBase, 0)}</td><td class="num-col"><input type="number" data-sec="kanjubRates" data-field="ILBAN" value="${cfg.rates.ILBAN}" step="any"></td><td class="money-col highlight-col"><strong>${fmt(k.ilbanAmt, 0)}</strong></td></tr>
|
||
<tr><td><code>IYUN</code></td><td><strong>이윤 (끝전보정 후)</strong></td><td><span class="formula-tag">${esc(k.iyunDesc)}</span><div class="tiny-tag">보정전 산식이윤 ${fmt(k.iyunRaw, 0)} − 세전끝전조정 ${fmt(k.pretaxProfitAdj, 0)} (차액 ${fmt(k.diffTotal, 0)}/1.1 반올림)</div></td><td class="money-col">${fmt(k.iyunBase, 0)}</td><td class="num-col"><input type="number" data-sec="kanjubRates" data-field="IYUN" value="${cfg.rates.IYUN}" step="any"></td><td class="money-col highlight-col"><strong>${fmt(k.iyunFinal, 0)}</strong></td></tr>
|
||
<tr class="sub-row"><td><code>SUPPLY</code></td><td><strong>총원가 (공급가액)</strong></td><td>순공사원가 + 일반관리비 + 최종이윤 (보정전: ${fmt(k.supplyBeforeAdj, 0)})</td><td class="money-col">${fmt(k.supplyFinal, 0)}</td><td class="center-col">—</td><td class="money-col"><strong>${fmt(k.supplyFinal, 0)}</strong></td></tr>
|
||
<tr><td><code>BUGA</code></td><td><strong>부가가치세</strong></td><td>과세표준 × 세율 (보정전 도급액: ${fmt(k.contractBeforeAdj, 0)})</td><td class="money-col">${fmt(k.supplyFinal, 0)}</td><td class="center-col">10%</td><td class="money-col highlight-col"><strong>${fmt(k.vatFinal, 0)}</strong></td></tr>
|
||
<tr class="total-row"><td><code>CONTRACT</code></td><td><strong>도급공사비</strong></td><td>공급가액 + 부가가치세 (끝전 절사 완료)</td><td class="money-col">${fmt(k.contractBeforeAdj, 0)}</td><td class="center-col">—</td><td class="money-col"><strong>${fmt(k.contractFinal, 0)}</strong></td></tr>
|
||
<tr><td><code>KWANGUP</code></td><td><strong>관급자재대</strong></td><td>관급원자재(${fmt(k.govRawTotal, 0)}) + 조달수수료(${fmt(k.govFeeTotal, 0)}) 끝전 처리</td><td class="money-col">${fmt(k.govRawTotal + k.govFeeTotal, 0)}</td><td class="center-col">—</td><td class="money-col"><strong>${fmt(k.govFinal, 0)}</strong></td></tr>
|
||
<tr class="total-row"><td><code>GRAND_TOT</code></td><td><strong>총공사비</strong></td><td>도급공사비 + 관급자재대</td><td class="money-col">—</td><td class="center-col">—</td><td class="money-col"><strong>${fmt(k.grandTotal, 0)} 원</strong></td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>`;
|
||
}
|
||
|
||
function renderRevisionTab(state, res) {
|
||
const boqOrig = res.boqOrig,
|
||
boqRev = res.boqRev,
|
||
kOrig = res.kanjubOrig,
|
||
kRev = res.kanjubRev;
|
||
const kSim = state.sysConfig.kOrdSim || { pclass: 7, regMode: 7, flag: 0, currentK: 2 };
|
||
const kSimOut = StmateCalc.evalKOrdTransition(
|
||
kSim.pclass,
|
||
kSim.regMode,
|
||
kSim.flag,
|
||
kSim.currentK,
|
||
);
|
||
|
||
const boqCompareRows = state.boqItems
|
||
.map(
|
||
(b, i) => `
|
||
<tr>
|
||
<td><code>${esc(b.code)}</code></td><td>${esc(b.name)}</td>
|
||
<td class="money-col">${fmt(b.qty, 2)}</td>
|
||
<td class="num-col"><input type="number" data-sec="boqItems" data-idx="${i}" data-field="changedQty" value="${b.changedQty ?? b.qty}" step="any"></td>
|
||
<td class="money-col">${fmt(boqOrig.rows[i].T, 0)}</td>
|
||
<td class="money-col">${fmt(boqRev.rows[i].T, 0)}</td>
|
||
<td class="money-col highlight-col"><strong>${boqRev.rows[i].T - boqOrig.rows[i].T >= 0 ? "+" : ""}${fmt(boqRev.rows[i].T - boqOrig.rows[i].T, 0)}</strong></td>
|
||
</tr>`,
|
||
)
|
||
.join("");
|
||
|
||
const revModeChoices = [
|
||
["recalculated", "recalculated (변경 밑수로 재계산)"],
|
||
["carry_original", "carry_original (당초액 유지 · 사후정산)"],
|
||
["proportional", "방법 A (당초액 × 직접비 증감비율)"],
|
||
["delta_rate", "방법 B (당초액 + 밑수증감 × 요율)"],
|
||
];
|
||
|
||
const kanjubCompareRows = kRev.items
|
||
.map((it) => {
|
||
const curMode = state.kanjubConfig.revModes[it.code] || "recalculated";
|
||
return `
|
||
<tr>
|
||
<td><code>${esc(it.code)}</code></td><td><strong>${esc(it.label)}</strong></td>
|
||
<td><select data-sec="revModes" data-field="${esc(it.code)}">${revModeChoices.map(([v, l]) => `<option value="${v}" ${curMode === v ? "selected" : ""}>${l}</option>`).join("")}</select></td>
|
||
<td class="money-col">${fmt(it.origAmt, 0)}</td>
|
||
<td class="money-col">${fmt(it.amount, 0)}</td>
|
||
<td class="money-col highlight-col"><strong>${it.deltaAmt >= 0 ? "+" : ""}${fmt(it.deltaAmt, 0)}</strong></td>
|
||
</tr>`;
|
||
})
|
||
.join("");
|
||
|
||
return `
|
||
<div class="panel-card">
|
||
<div class="card-header">
|
||
<div>
|
||
<h2>설계변경 수량 및 간접비 변경 계산모드 (<code>cBx_CH_BO</code> · 08번 문서 §2 · 18단계 REA)</h2>
|
||
<p>실무 변경설계에서는 직접노무비가 늘어나도 건강·장기요양·연금보험료 등 사후정산 항목은 <strong>당초액을 그대로 유지(<code>carry_original</code>)</strong>하고, 나머지는 재계산하거나 방법 A/B 공식을 적용합니다.</p>
|
||
</div>
|
||
</div>
|
||
<div class="table-scroll">
|
||
<table class="data-table">
|
||
<thead><tr><th>코드</th><th>내역 공종명</th><th>당초 수량</th><th>변경 수량 (조작)</th><th>당초 금액</th><th>변경 금액</th><th>증감 차액</th></tr></thead>
|
||
<tbody>
|
||
${boqCompareRows}
|
||
<tr class="total-row"><td colspan="4">직접공사비 당초 / 변경 / 증감 합계</td><td class="money-col">${fmt(boqOrig.directTotal, 0)}</td><td class="money-col">${fmt(boqRev.directTotal, 0)}</td><td class="money-col">${boqRev.directTotal - boqOrig.directTotal >= 0 ? "+" : ""}${fmt(boqRev.directTotal - boqOrig.directTotal, 0)}</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<div class="table-scroll" style="margin-top:16px;">
|
||
<table class="data-table">
|
||
<thead><tr><th>키</th><th>제잡비 항목</th><th>변경설계 계산 모드 선택</th><th>당초 금액 (<code>C_AMT_B</code>)</th><th>변경 금액</th><th>증감 차액</th></tr></thead>
|
||
<tbody>
|
||
${kanjubCompareRows}
|
||
<tr class="total-row"><td colspan="3">총공사비 (도급 + 관급) 당초 / 변경 / 증감</td><td class="money-col">${fmt(kOrig.grandTotal, 0)}</td><td class="money-col">${fmt(kRev.grandTotal, 0)}</td><td class="money-col">${kRev.grandTotal - kOrig.grandTotal >= 0 ? "+" : ""}${fmt(kRev.grandTotal - kOrig.grandTotal, 0)}</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="panel-card">
|
||
<div class="card-header">
|
||
<div>
|
||
<h2><code>K_ORD</code> 등록·차수내리기 전이 규칙 시뮬레이터 (<code>STMATE_REA_최종보고서</code> §4.1)</h2>
|
||
<p>Main <code>0x559228</code>(NewProject) 및 <code>0x55a640</code>(MkBoq)에서 관측된 <code>PCLASS</code> · 등록모드 · 플래그 조합에 따른 <code>K_ORD</code> 저장식과 차수내리기(<code>K - (K>5 ? K-4 : 1)</code>) 동작을 확인합니다.</p>
|
||
</div>
|
||
</div>
|
||
<div class="control-grid">
|
||
<label class="ctrl-item"><span>원본 <code>PCLASS</code></span><select data-sec="kOrdSim" data-field="pclass"><option value="4" ${Number(kSim.pclass) === 4 ? "selected" : ""}>4</option><option value="6" ${Number(kSim.pclass) === 6 ? "selected" : ""}>6</option><option value="7" ${Number(kSim.pclass) === 7 ? "selected" : ""}>7</option></select></label>
|
||
<label class="ctrl-item"><span>등록 모드 (6 또는 7)</span><select data-sec="kOrdSim" data-field="regMode"><option value="6" ${Number(kSim.regMode) === 6 ? "selected" : ""}>모드 6</option><option value="7" ${Number(kSim.regMode) === 7 ? "selected" : ""}>모드 7</option></select></label>
|
||
<label class="ctrl-item"><span>플래그 (0 또는 1)</span><select data-sec="kOrdSim" data-field="flag"><option value="0" ${Number(kSim.flag) === 0 ? "selected" : ""}>0</option><option value="1" ${Number(kSim.flag) === 1 ? "selected" : ""}>1</option></select></label>
|
||
<label class="ctrl-item"><span>현재 <code>K_ORD</code> (K)</span><input type="number" data-sec="kOrdSim" data-field="currentK" value="${kSim.currentK}" min="1" max="20"></label>
|
||
</div>
|
||
<div class="sub-toolbar">
|
||
<span>등록 시 새 <code>K_ORD</code>: <strong>${kSimOut.nextK}</strong> · 차수내리기 실행 시 <code>K - (K>5 ? K-4 : 1)</code>: <strong>${kSimOut.downK}</strong></span>
|
||
<span>REA 확인: <code>Calq_San</code> 행 selector(<code>+0x430</code>) 0 초기화 지배 · 공유 <code>tb_Ref(+0x58) → MmComRec+8</code></span>
|
||
</div>
|
||
</div>`;
|
||
}
|
||
|
||
return { renderBoqTab, renderKanjubTab, renderRevisionTab };
|
||
})();
|