260725_4
This commit is contained in:
@@ -195,6 +195,8 @@ class _SectionGeometry:
|
||||
self._ground_at = ground_at
|
||||
self._rock_offset = rock_boundary_offset_m or 0.0
|
||||
self._rock_knee: dict[str, tuple[float, float] | None] = {}
|
||||
# 절토 사면·지반 최초 교차거리(측별 캐시) — 교차 후 절토 종료용(N-2-4).
|
||||
self._cut_cross: dict[str, float | None] = {}
|
||||
self.ditch_type = ditch_type
|
||||
# 횡단경사: 측구 방향으로 내려가는 단일 사면 (좌=+offset 규약).
|
||||
slope = cross_slope_pct / 100.0
|
||||
@@ -311,6 +313,41 @@ class _SectionGeometry:
|
||||
self._rock_knee[side] = result
|
||||
return result
|
||||
|
||||
def _cut_slope_z(self, side: str, dist: float) -> float:
|
||||
"""절토 사면선 표고(2단계 무릎 반영). 지반 교차 클램프는 하지 않는다."""
|
||||
start_dist, start_z = self._slope_start(side)
|
||||
knee = self.knee(side) if self.two_stage else None
|
||||
if knee is not None:
|
||||
knee_dist, knee_z = knee
|
||||
if dist <= knee_dist: # 암반 구간(경계 아래): 암 경사
|
||||
return start_z + (dist - start_dist) / self.cut_ratio
|
||||
return knee_z + (dist - knee_dist) / self.soil_cut_ratio # 토사 구간: 완만
|
||||
return start_z + (dist - start_dist) / self.cut_ratio
|
||||
|
||||
def cut_cross_dist(self, side: str) -> float | None:
|
||||
"""절토 사면이 지반선과 처음 만나는 거리(절대 오프셋). 이후는 절토 없음(N-2-4).
|
||||
|
||||
지면과 1회 교차하면 그다음 경사(2단계 전환 포함)는 의미가 없으므로 교차점에서
|
||||
절토를 종료한다. 시작(노면 끝)부터 사면이 지반 위면 교차거리=시작(절토 없음),
|
||||
끝까지 못 만나면 None.
|
||||
"""
|
||||
if side in self._cut_cross:
|
||||
return self._cut_cross[side]
|
||||
result: float | None = None
|
||||
if self._ground_at is not None:
|
||||
start_dist, _start_z = self._slope_start(side)
|
||||
step = 0.05
|
||||
dist = start_dist
|
||||
max_dist = start_dist + 500.0
|
||||
while dist <= max_dist:
|
||||
signed = dist if side == "left" else -dist
|
||||
if self._cut_slope_z(side, dist) - self._ground_at(signed) >= 0:
|
||||
result = dist
|
||||
break
|
||||
dist += step
|
||||
self._cut_cross[side] = result
|
||||
return result
|
||||
|
||||
def design_z(self, offset_m: float, ground_m: float) -> float:
|
||||
"""offset 하나의 설계 표고(사면은 지반 교차점 이후 지반 추종)."""
|
||||
side = "left" if offset_m >= 0 else "right"
|
||||
@@ -339,16 +376,11 @@ class _SectionGeometry:
|
||||
dist = abs(offset_m)
|
||||
run = dist - start_dist
|
||||
if role == "cut":
|
||||
knee = self.knee(side) if self.two_stage else None
|
||||
if knee is not None:
|
||||
knee_dist, knee_z = knee
|
||||
if dist <= knee_dist: # 암반 구간(경계 아래): 암 경사
|
||||
slope_line = start_z + (dist - start_dist) / self.cut_ratio
|
||||
else: # 토사 구간(경계 위): 무릎에서 토사 경사로 완만
|
||||
slope_line = knee_z + (dist - knee_dist) / self.soil_cut_ratio
|
||||
else:
|
||||
slope_line = start_z + run / self.cut_ratio
|
||||
return min(slope_line, ground_m)
|
||||
# 지반과 1회 교차하면 그 이후 절토는 의미 없음 → 지반 추종(N-2-4).
|
||||
cross = self.cut_cross_dist(side)
|
||||
if cross is not None and dist >= cross:
|
||||
return ground_m
|
||||
return min(self._cut_slope_z(side, dist), ground_m)
|
||||
fill_line = start_z - run / self.fill_ratio
|
||||
return max(fill_line, ground_m)
|
||||
|
||||
@@ -362,6 +394,13 @@ class _SectionGeometry:
|
||||
knee = self.knee(side) if role == "cut" else None
|
||||
if knee is not None:
|
||||
points.append(knee[0] if side == "left" else -knee[0])
|
||||
# 절토 사면·지반 교차점을 꼭짓점에 넣어 면적 절단을 정확히 한다(N-2-4).
|
||||
for side in ("left", "right"):
|
||||
role = self.left_role if side == "left" else self.right_role
|
||||
if role == "cut":
|
||||
cross = self.cut_cross_dist(side)
|
||||
if cross is not None:
|
||||
points.append(cross if side == "left" else -cross)
|
||||
return points
|
||||
|
||||
|
||||
|
||||
@@ -47,9 +47,11 @@ export function sectionModeLabel(mode: SectionMode | undefined): string {
|
||||
const key = MODE_OPTIONS.find(([value]) => value === mode)?.[1];
|
||||
return key ? ui_locales[key][currentLanguageIndex] : "-";
|
||||
}
|
||||
// 좌/우 버튼 = 노면 횡단 경사 방향(물을 모으는 쪽 = 측구가 있다면 그 위치). 양성도 측구는
|
||||
// 없지만 "생략된 측구"를 가정한 경사 방향을 여기서 정한다(N-2-3).
|
||||
const DITCH_OPTIONS: Array<[DitchSide, keyof typeof ui_locales]> = [
|
||||
["left", "B06_Design_Ditch_Left"],
|
||||
["right", "B06_Design_Ditch_Right"],
|
||||
["left", "B06_Design_SlopeDir_Left"],
|
||||
["right", "B06_Design_SlopeDir_Right"],
|
||||
];
|
||||
const DITCH_TYPE_OPTIONS: Array<[DitchType, keyof typeof ui_locales]> = [
|
||||
["standard", "B06_Design_DitchType_Standard"],
|
||||
@@ -236,8 +238,9 @@ export function buildDesignControls(
|
||||
// 컨트롤 상호작용이 카드 선택 클릭으로 전파되지 않게 한다.
|
||||
bar.addEventListener("click", (event) => event.stopPropagation());
|
||||
|
||||
// 측구 방향 선택이 필요한 경우 = 양절(both_cut). 편절은 절토측 자동, 양성은 측구 없음.
|
||||
const needsDitch = (): boolean => state.mode === "both_cut";
|
||||
// 경사 방향 선택이 필요한 경우 = 양절(both_cut)·양성(both_fill). 편절은 절토측 자동.
|
||||
// 양성은 측구가 없어도 노면 기울기 방향(생략된 측구 방향)을 여기서 지정한다(N-2-3).
|
||||
const needsDitch = (): boolean => state.mode === "both_cut" || state.mode === "both_fill";
|
||||
const emit = (): void => {
|
||||
if (!state.ground || !state.mode) return;
|
||||
// L형 측구는 암 전용 — 토사로 되돌리면 일반측구로 강등해 서버 거부를 예방한다.
|
||||
@@ -254,15 +257,10 @@ export function buildDesignControls(
|
||||
};
|
||||
|
||||
// 지반유형: 제목행 배치용으로 분리 반환(D-6). 라벨 삭제(3번) — 버튼만.
|
||||
const groundSegment = segment(
|
||||
"",
|
||||
GROUND_OPTIONS,
|
||||
state.ground,
|
||||
(value) => {
|
||||
state.ground = value;
|
||||
emit();
|
||||
},
|
||||
);
|
||||
const groundSegment = segment("", GROUND_OPTIONS, state.ground, (value) => {
|
||||
state.ground = value;
|
||||
emit();
|
||||
});
|
||||
groundSegment.classList.add("b06-design__seg--header");
|
||||
// 단면 유형은 지형에서 자동 판정되며(D-2), 제목행 pill로 표시한다(E-3, Cross_View에서 생성).
|
||||
// 아래 옵션은 상시 노출하되 선행 조건 미충족 시 비활성 처리한다(E-6).
|
||||
@@ -271,19 +269,17 @@ export function buildDesignControls(
|
||||
// 측구 생성 여부(자동 판정 or 사용자 override) — 측구형식은 측구가 있을 때만 의미 있다.
|
||||
const ditchOn = state.ditchEnabled ?? design?.ditch_enabled ?? true;
|
||||
|
||||
// 측구 방향(좌/우): 양절(both_cut)에서만 활성. 편절은 절토측 자동, 양성은 측구 없음. 라벨 삭제(E-7).
|
||||
bar.append(
|
||||
segment(
|
||||
"",
|
||||
DITCH_OPTIONS,
|
||||
state.ditch,
|
||||
(value) => {
|
||||
state.ditch = value;
|
||||
emit();
|
||||
},
|
||||
state.mode !== "both_cut",
|
||||
L("B06_Design_Disabled_BothCutOnly"),
|
||||
),
|
||||
// 경사 방향(좌/우): 양절·양성에서 활성. 항상 인라인 노출(오버플로 대상 아님). 라벨 삭제(E-7).
|
||||
const slopeDirSeg = segment(
|
||||
"",
|
||||
DITCH_OPTIONS,
|
||||
state.ditch,
|
||||
(value) => {
|
||||
state.ditch = value;
|
||||
emit();
|
||||
},
|
||||
!needsDitch(),
|
||||
L("B06_Design_Disabled_BothCutOnly"),
|
||||
);
|
||||
// 측구 생성 토글(D-1): 측구 있는 단면에서만 활성. 버튼명 "측구" 고정, 컬러로 상태 표시(E-7).
|
||||
const ditchToggle = toggle(
|
||||
@@ -298,20 +294,17 @@ export function buildDesignControls(
|
||||
!hasDitch,
|
||||
L("B06_Design_Disabled_NoDitch"),
|
||||
);
|
||||
bar.append(ditchToggle.wrap);
|
||||
// 측구형식(일반/L형): 암 지반 + 절토 단면 + 측구가 실제 있을 때만 활성.
|
||||
bar.append(
|
||||
segment(
|
||||
L("B06_Design_DitchType_Legend"),
|
||||
DITCH_TYPE_OPTIONS,
|
||||
state.ditchType,
|
||||
(value) => {
|
||||
state.ditchType = value;
|
||||
emit();
|
||||
},
|
||||
!rockCut || !ditchOn,
|
||||
!ditchOn ? L("B06_Design_Disabled_NoDitchType") : L("B06_Design_Disabled_RockCut"),
|
||||
),
|
||||
const ditchTypeSeg = segment(
|
||||
L("B06_Design_DitchType_Legend"),
|
||||
DITCH_TYPE_OPTIONS,
|
||||
state.ditchType,
|
||||
(value) => {
|
||||
state.ditchType = value;
|
||||
emit();
|
||||
},
|
||||
!rockCut || !ditchOn,
|
||||
!ditchOn ? L("B06_Design_Disabled_NoDitchType") : L("B06_Design_Disabled_RockCut"),
|
||||
);
|
||||
// 2단계 경사 토글: 암 지반 + 절토 단면에서만 활성. 활성="복합경사"/비활성="단경사"(E-7).
|
||||
const twoStage = toggle(
|
||||
@@ -326,18 +319,11 @@ export function buildDesignControls(
|
||||
!rockCut,
|
||||
L("B06_Design_Disabled_RockCut"),
|
||||
);
|
||||
bar.append(twoStage.wrap);
|
||||
// 포장 토글: 라벨 삭제, 버튼명 활성="포장"/비활성="비포장"(컬러 유지) — E-7.
|
||||
const paved = toggle(
|
||||
"",
|
||||
state.paved,
|
||||
L("B06_Design_Paved_On"),
|
||||
L("B06_Design_Paved_Off"),
|
||||
() => {
|
||||
state.paved = !state.paved;
|
||||
emit();
|
||||
},
|
||||
);
|
||||
const paved = toggle("", state.paved, L("B06_Design_Paved_On"), L("B06_Design_Paved_Off"), () => {
|
||||
state.paved = !state.paved;
|
||||
emit();
|
||||
});
|
||||
// B05 법정 경사 분석이 포장을 제안한 측점은 근거 문구를 배지·툴팁으로 표기한다.
|
||||
if (design?.pavement_suggested) {
|
||||
paved.button.title = L("B06_Design_Paved_Suggested");
|
||||
@@ -347,10 +333,42 @@ export function buildDesignControls(
|
||||
badge.title = L("B06_Design_Paved_Suggested");
|
||||
paved.wrap.append(badge);
|
||||
}
|
||||
bar.append(paved.wrap);
|
||||
|
||||
// 오버플로 드롭다운(N-2-2): 컨트롤이 카드 폭에서 한 행을 넘치면 뒤쪽부터 우측 "⋯"
|
||||
// 드롭다운(세로 배치)으로 옮겨 다음 행으로 밀리는 것을 막는다. 경사 방향은 항상 인라인,
|
||||
// 이동 우선순위(뒤에서부터): 포장 → 복합경사 → 측구형식 → 측구 토글.
|
||||
const moveable = [ditchToggle.wrap, ditchTypeSeg, twoStage.wrap, paved.wrap];
|
||||
const more = document.createElement("details");
|
||||
more.className = "b06-design__more";
|
||||
const moreSummary = document.createElement("summary");
|
||||
moreSummary.className = "b06-design__more-summary";
|
||||
moreSummary.textContent = "⋯";
|
||||
moreSummary.title = L("B06_Design_More");
|
||||
const morePanel = document.createElement("div");
|
||||
morePanel.className = "b06-design__more-panel";
|
||||
more.append(moreSummary, morePanel);
|
||||
bar.append(slopeDirSeg, ...moveable, more);
|
||||
|
||||
const reflow = (): void => {
|
||||
// 후보 전부 인라인 복귀 → more 숨김 → 넘치면 뒤에서부터 패널로 이동.
|
||||
for (const element of moveable) bar.insertBefore(element, more);
|
||||
morePanel.replaceChildren();
|
||||
more.hidden = true;
|
||||
if (bar.clientWidth <= 0) return;
|
||||
for (
|
||||
let index = moveable.length - 1;
|
||||
index >= 0 && bar.scrollWidth > bar.clientWidth + 1;
|
||||
index -= 1
|
||||
) {
|
||||
more.hidden = false;
|
||||
morePanel.insertBefore(moveable[index], morePanel.firstChild);
|
||||
}
|
||||
};
|
||||
const overflowObserver = new ResizeObserver(() => reflow());
|
||||
overflowObserver.observe(bar);
|
||||
requestAnimationFrame(reflow);
|
||||
|
||||
// 암 경계선 제어는 그래프 X축 제목 행으로 이동(E-7, Cross_View에서 배치).
|
||||
|
||||
// 절·성토 면적 readout은 그래프 중상단 오버레이로 이동(E-4, Cross_View에서 배치).
|
||||
return { bar, groundSegment };
|
||||
}
|
||||
|
||||
@@ -190,6 +190,25 @@ export async function renderB06ProfileCross(root: HTMLElement): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
/** 패널 [전체 반영](N-2-1): design 보유 전 측점을 패널 최신값으로 순차 재계산한다.
|
||||
* handleDesignChange가 standardPanel.getValues()를 실어 보내므로 표준단면 수치만
|
||||
* 갱신되고 측점별 버튼 선택값은 보존된다. 순차 await로 동시 API 호출 수를 제한한다. */
|
||||
async function applyPanelToAll(): Promise<void> {
|
||||
if (!sectionDetail) return;
|
||||
const targets = sectionDetail.cross_sections.filter((section) => section.design);
|
||||
if (!targets.length) return;
|
||||
showLoadingOverlay();
|
||||
try {
|
||||
for (const section of targets) {
|
||||
const change = changeFromDesign(section.chainage_m);
|
||||
if (change) await handleDesignChange(section.chainage_m, change);
|
||||
}
|
||||
showToast(L("B06_Std_ApplyAll_Success"), "success");
|
||||
} finally {
|
||||
hideLoadingOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
/* ── 암 경계선 오프셋(측점별) 세션 저장소 ─────────────────────────────
|
||||
* 서버 재계산 없이 프론트 세션(sessionStorage)에 보관하고, 종횡단 확정 시
|
||||
* cross_patches로 DB(data.design.rock_boundary_offset_m)에 병합한다.
|
||||
@@ -396,7 +415,7 @@ export async function renderB06ProfileCross(root: HTMLElement): Promise<void> {
|
||||
rockBoundaryStep = context.rock_boundary_step_m;
|
||||
|
||||
// 표준 횡단면 설정 패널 장착(세션값 우선, 없으면 config 기본값).
|
||||
standardPanel = createStandardPanel(projectId, context.standard_cross_section);
|
||||
standardPanel = createStandardPanel(projectId, context.standard_cross_section, applyPanelToAll);
|
||||
standardPanelSlot.append(standardPanel.root);
|
||||
|
||||
if (context.route_id === null) {
|
||||
|
||||
@@ -149,6 +149,9 @@ export function createSectionView(
|
||||
1,
|
||||
Math.floor((renderWidth + CROSS_GRID_GAP) / (CROSS_GRID_MIN_WIDTH + CROSS_GRID_GAP)),
|
||||
);
|
||||
// CSS auto-fill의 자체 열 수와 JS columnCount가 어긋나면 같은 행 높이 그룹핑이 실제
|
||||
// 렌더 행과 달라져 카드 내부가 뒤죽박죽된다(N-2-6). 열 수를 JS가 명시해 일치시킨다.
|
||||
grid.style.gridTemplateColumns = `repeat(${columnCount}, minmax(0, 1fr))`;
|
||||
cachedCardWidth = (renderWidth - (columnCount - 1) * CROSS_GRID_GAP) / columnCount;
|
||||
cachedRowHeight.clear();
|
||||
if (detail.cross_sections.length) {
|
||||
|
||||
@@ -158,6 +158,7 @@ const FIELD_SPECS: NumberFieldSpec[] = [
|
||||
export function createStandardPanel(
|
||||
projectId: string,
|
||||
defaults: StandardCrossSection,
|
||||
onApplyAll?: () => void | Promise<void>,
|
||||
): StandardPanelController {
|
||||
// 세션값 우선, 없으면 config 기본값. defaults는 복원 기준으로 보존한다.
|
||||
const sessionValue = readSession(projectId);
|
||||
@@ -247,6 +248,17 @@ export function createStandardPanel(
|
||||
});
|
||||
const actions = document.createElement("div");
|
||||
actions.className = "b06-std__actions";
|
||||
// [전체 반영](N-2-1): 패널 수치를 design 보유 전 측점에 서버 재계산으로 일괄 반영한다.
|
||||
// 측점별 버튼 선택값(지반/단면 등)은 보존하고 표준단면 수치만 갱신한다.
|
||||
if (onApplyAll) {
|
||||
actions.append(
|
||||
createButton({
|
||||
label: L("B06_Std_ApplyAll"),
|
||||
variant: "filled",
|
||||
onClick: () => void onApplyAll(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
actions.append(resetButton);
|
||||
|
||||
root.append(body, loader, actions);
|
||||
|
||||
@@ -320,10 +320,11 @@
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
|
||||
/* 측점 표준횡단 설계 지정 컨트롤 (카드 헤더 아래) — 좌측 여유 추가(2번). */
|
||||
/* 측점 표준횡단 설계 지정 컨트롤 (카드 헤더 아래) — 좌측 여유 추가(2번).
|
||||
한 행 고정(nowrap): 넘치는 컨트롤은 다음 행으로 밀지 않고 "⋯" 드롭다운으로 이동(N-2-2). */
|
||||
.b06-design {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
gap: var(--spacing-8) var(--spacing-16);
|
||||
padding: var(--spacing-8) 0 var(--spacing-8) var(--spacing-16);
|
||||
@@ -331,13 +332,60 @@
|
||||
margin-bottom: var(--spacing-8);
|
||||
}
|
||||
|
||||
/* 오버플로 드롭다운(N-2-2): 넘친 컨트롤을 담는 우측 맞춤 "⋯" 메뉴. 세로 배치. */
|
||||
.b06-design__more {
|
||||
position: relative;
|
||||
flex: 0 0 auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.b06-design__more-summary {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
height: 22px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-inputs);
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 0.9rem;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.b06-design__more-summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.b06-design__more[open] .b06-design__more-summary {
|
||||
color: var(--color-surface);
|
||||
background: var(--color-royal-amethyst);
|
||||
border-color: var(--color-royal-amethyst);
|
||||
}
|
||||
|
||||
.b06-design__more-panel {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: calc(100% + 4px);
|
||||
z-index: 3;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-8);
|
||||
padding: var(--spacing-8);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-inputs);
|
||||
background: var(--color-surface-raised);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.b06-design__seg {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-8);
|
||||
}
|
||||
|
||||
|
||||
.b06-design__seg-legend {
|
||||
font-size: 0.72rem;
|
||||
color: var(--color-text-secondary);
|
||||
|
||||
@@ -806,10 +806,10 @@ export const ui_locales = {
|
||||
B06_Design_Ground_Ripping: ["리핑암", "Ripping rock"],
|
||||
B06_Design_Ground_Blasting: ["발파암", "Blasting rock"],
|
||||
B06_Design_Mode_Legend: ["단면유형", "Section type"],
|
||||
B06_Design_Mode_LeftCut: ["좌 절토", "Left cut"],
|
||||
B06_Design_Mode_RightCut: ["우 절토", "Right cut"],
|
||||
B06_Design_Mode_BothCut: ["양절", "Both cut"],
|
||||
B06_Design_Mode_BothFill: ["양성", "Both fill"],
|
||||
B06_Design_Mode_LeftCut: ["편측 성토", "One-side fill"],
|
||||
B06_Design_Mode_RightCut: ["편측 성토", "One-side fill"],
|
||||
B06_Design_Mode_BothCut: ["양측 절토", "Both cut"],
|
||||
B06_Design_Mode_BothFill: ["양측 성토", "Both fill"],
|
||||
B06_Design_Ditch_Legend: ["측구위치", "Ditch side"],
|
||||
B06_Design_Ditch_Left: ["좌", "Left"],
|
||||
B06_Design_Ditch_Right: ["우", "Right"],
|
||||
@@ -829,9 +829,12 @@ export const ui_locales = {
|
||||
B06_Design_Ditch_On: ["측구", "Ditch"],
|
||||
B06_Design_Ditch_Off: ["측구", "Ditch"],
|
||||
B06_Design_Disabled_BothCutOnly: [
|
||||
"양절 단면에서만 선택할 수 있습니다.",
|
||||
"Available only for both-cut sections.",
|
||||
"양측 절토·양측 성토 단면에서만 경사 방향을 바꿀 수 있습니다.",
|
||||
"Slope direction is adjustable only for both-cut and both-fill sections.",
|
||||
],
|
||||
B06_Design_More: ["더보기", "More"],
|
||||
B06_Design_SlopeDir_Left: ["좌경사", "Slope left"],
|
||||
B06_Design_SlopeDir_Right: ["우경사", "Slope right"],
|
||||
B06_Design_Disabled_RockCut: [
|
||||
"암(리핑/발파) 지반의 절토 단면에서만 사용할 수 있습니다.",
|
||||
"Available only for rock ground with a cut section.",
|
||||
@@ -880,10 +883,18 @@ export const ui_locales = {
|
||||
"L-type ditch is chosen per cross-section drawing.",
|
||||
],
|
||||
B06_Std_Reset: ["기본값 복원", "Restore defaults"],
|
||||
B06_Std_ApplyAll: ["전체 측점 반영", "Apply to all stations"],
|
||||
B06_Std_ApplyAll_Success: [
|
||||
"패널 설정을 전체 측점에 반영했습니다.",
|
||||
"Applied panel settings to all stations.",
|
||||
],
|
||||
B06_Std_Load_Title: ["다른 프로젝트에서 불러오기", "Load from another project"],
|
||||
B06_Std_Load_Select: ["프로젝트 선택", "Select project"],
|
||||
B06_Std_Load_Placeholder: ["— 프로젝트 선택 —", "— Select a project —"],
|
||||
B06_Std_Load_Empty: ["같은 회사에 불러올 설계값이 없습니다.", "No saved designs in your company."],
|
||||
B06_Std_Load_Empty: [
|
||||
"같은 회사에 불러올 설계값이 없습니다.",
|
||||
"No saved designs in your company.",
|
||||
],
|
||||
B06_Std_Load_Loading: ["불러오는 중…", "Loading…"],
|
||||
B06_Std_Load_Apply: ["현재 설정에 적용", "Apply to current settings"],
|
||||
B06_Std_Load_Applied: ["적용되었습니다.", "Applied."],
|
||||
|
||||
Reference in New Issue
Block a user