feat(rebar): 상면 주철근(C1–C6) 이음 무시/반영, 위치 기둥 중심/단부
- 기본 '이음 무시' (사양 결정). '반영'이면 정척(12000) 초과 철근을 l_s 겹침 2조각으로 나눔 - 위치: 기둥 중심 = 전체의 절반, 단부 = 정척 안에서 가장 끝 쪽 (짧은 조각 = 전체 + l_s − 12000, 긴 조각 = 12000) - 철근표 조각 목록과 비고, 3D 두 조각(l_s 겹침)에 반영 - STANDARD_BAR를 common.ts로 옮겨 순환 import 방지 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
72053be420
commit
496e0ea4e5
10 files changed
+130
-16
No files matched your search
+2
-1
@@ -23,7 +23,7 @@ export const EDITABLE_FIELDS = [
|
||||
] as const;
|
||||
|
||||
/** Inputs tracked for overrides and pending changes: the numeric cards plus 열별 본수 (an array, compared by value). */
|
||||
export const TRACKED_KEYS = [...EDITABLE_FIELDS.map((f) => f.key), 'pileRows', 'groundPosition', 'groundWaterOn', 'groundWaterEl', 'floodLevelEl', 'scourDepthM', 'highWaterEl', 'lowWaterEl', 'strataRows', 'bearingType', 'bearingLayout', 'blockRebar', 'copingRebar'] as const;
|
||||
export const TRACKED_KEYS = [...EDITABLE_FIELDS.map((f) => f.key), 'pileRows', 'groundPosition', 'groundWaterOn', 'groundWaterEl', 'floodLevelEl', 'scourDepthM', 'highWaterEl', 'lowWaterEl', 'strataRows', 'bearingType', 'bearingLayout', 'blockRebar', 'copingRebar', 'topSplice'] as const;
|
||||
|
||||
export type EditableKey = (typeof TRACKED_KEYS)[number];
|
||||
|
||||
@@ -55,6 +55,7 @@ export const FIELD_LABELS: Record<EditableKey, string> = {
|
||||
bearingLayout: '받침 배치',
|
||||
blockRebar: '받침블럭 철근 설정',
|
||||
copingRebar: '코핑 배근 입력',
|
||||
topSplice: '상면 주철근 이음',
|
||||
strataRows: '지층 행',
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { buildAxis, copingSpan, fromAxis, kinkArc, nearKink, toAxis } from './axis';
|
||||
import { buildIntegratedBlocks, type IntegratedBlock } from './integrated-block';
|
||||
import { type BlockRebarSettings, DEFAULT_BLOCK_REBAR } from './rebar/bearing-block';
|
||||
import { type CopingRebarSettings, DEFAULT_COPING_REBAR } from './rebar/coping-settings';
|
||||
import { type CopingRebarSettings, DEFAULT_COPING_REBAR, DEFAULT_TOP_SPLICE, type TopSpliceSettings } from './rebar/coping-settings';
|
||||
import { layoutText, resolveRowCounts, rowLayout, type PileGeometry } from './piles';
|
||||
import type { PierInput, Row } from './types';
|
||||
import { type CopingGeom, P1_COPING_GEOM } from './coping-geom';
|
||||
@@ -179,6 +179,8 @@ export interface PierModel {
|
||||
blockRebar: BlockRebarSettings;
|
||||
/** 코핑 배근 입력 used by the coping rebar (승인 2026-10-26). */
|
||||
copingRebar: CopingRebarSettings;
|
||||
/** 상면 주철근 이음 used by the coping rebar (승인 2026-10-26). */
|
||||
topSplice: TopSpliceSettings;
|
||||
columns: ColumnModel[];
|
||||
footings: FootingModel[];
|
||||
blindings: BlindingModel[];
|
||||
@@ -468,6 +470,7 @@ export function buildPier(input: PierInput): PierModel {
|
||||
integratedBlocks: buildIntegratedBlocks(blocks, input.bearingLayout === '일체'),
|
||||
blockRebar: { ...DEFAULT_BLOCK_REBAR, ...input.blockRebar },
|
||||
copingRebar: { ...DEFAULT_COPING_REBAR, ...input.copingRebar },
|
||||
topSplice: { ...DEFAULT_TOP_SPLICE, ...input.topSplice },
|
||||
columns,
|
||||
footings,
|
||||
blindings,
|
||||
|
||||
@@ -117,6 +117,9 @@ export function developmentLength(db: number, fy: number, fck: number, lambda =
|
||||
return (0.6 * db * fy) / (lambda * Math.sqrt(fck));
|
||||
}
|
||||
|
||||
/** 정척 L_bar (mm) from 확대기초철근.md §1.2. Bars longer than this need a splice. */
|
||||
export const STANDARD_BAR = 12000;
|
||||
|
||||
/** Lap splice length l_s = 1.3·l_d (spec §4 공통 설계 규약). */
|
||||
export function spliceLength(db: number, fy: number, fck: number, lambda = MATERIAL_DEFAULTS.lambda): number {
|
||||
return 1.3 * developmentLength(db, fy, fck, lambda);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { DEFAULT_MATERIAL, fyOf, hookLength, Material, NOMINAL_DIAMETER, spliceLength } from './common';
|
||||
import { type CopingRebarSettings, DEFAULT_COPING_REBAR } from './coping-settings';
|
||||
import { DEFAULT_MATERIAL, fyOf, hookLength, Material, NOMINAL_DIAMETER, spliceLength, STANDARD_BAR } from './common';
|
||||
import { type CopingRebarSettings, DEFAULT_COPING_REBAR, type TopSpliceAt } from './coping-settings';
|
||||
|
||||
/**
|
||||
* C1–C8 상·하면 주철근 (plan C3 continued). Source: RAG/코핑철근.md §5, 2026-10-22 최종 정리.
|
||||
@@ -71,6 +71,19 @@ export function topBarLength(L: number, k: number): number {
|
||||
return path + 2 * MAIN.hook;
|
||||
}
|
||||
|
||||
/**
|
||||
* Top bar C1–C6 when its 이음 is applied (승인 2026-10-26). Only a bar longer than the standard length is split (2 pieces, l_s lap).
|
||||
* splitFromLeft is measured from the bar's left end (mm). 기둥 중심: the centre. 단부: the split closest to the end that keeps
|
||||
* both pieces within the standard length, so the short piece is total + l_s − standard and the long piece is the standard length.
|
||||
*/
|
||||
export function topSplicePieces(L: number, k: number, at: TopSpliceAt, m: Material = DEFAULT_MATERIAL): { pieces: [number, number]; splitFromLeft: number; lap: number } | null {
|
||||
const total = topBarLength(L, k);
|
||||
if (total <= STANDARD_BAR) return null;
|
||||
const lap = spliceLength(NOMINAL_DIAMETER.H29, fyOf(m, 'H29'), m.fck);
|
||||
const splitFromLeft = at === 'center' ? total / 2 : total + lap / 2 - STANDARD_BAR;
|
||||
return { pieces: [splitFromLeft + lap / 2, total - splitFromLeft + lap / 2], splitFromLeft, lap };
|
||||
}
|
||||
|
||||
/**
|
||||
* Bottom bar C7·C8 (spliced at the column centre, 하면 겹침이음). Each piece:
|
||||
* path/2 + l_s/2 + l_h, with path = 2·slope + Level and l_s = 1.3·l_d for H29 (nominal 28.6, with the material inputs).
|
||||
|
||||
@@ -60,6 +60,18 @@ export const COPING_REBAR_RANGES: Record<keyof CopingRebarSettings, [number, num
|
||||
c14LowerSpacing: [1500, 2500],
|
||||
};
|
||||
|
||||
/** 상면 주철근(C1–C6) 이음 (승인 2026-10-26): ignore = 이음 무시 (사양 기본), apply = 정척 초과 시 2조각 겹침. */
|
||||
export type TopSpliceMode = 'ignore' | 'apply';
|
||||
/** 이음 위치: center = 기둥 중심, end = 단부 (정척 안에서 가장 끝 쪽). */
|
||||
export type TopSpliceAt = 'center' | 'end';
|
||||
|
||||
export interface TopSpliceSettings {
|
||||
mode: TopSpliceMode;
|
||||
at: TopSpliceAt;
|
||||
}
|
||||
|
||||
export const DEFAULT_TOP_SPLICE: TopSpliceSettings = { mode: 'ignore', at: 'center' };
|
||||
|
||||
export interface CopingSettingsIssue {
|
||||
code: 'CP01' | 'CP02';
|
||||
key: keyof CopingRebarSettings;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type { PierModel } from '../geometry';
|
||||
import { barLength, bearingBlockRebar, DEFAULT_BLOCK_REBAR, totals } from './bearing-block';
|
||||
import { DEFAULT_COPING_REBAR } from './coping-settings';
|
||||
import { bottomPiece, topBarLength, widthLayout } from './coping-main';
|
||||
import { bottomPiece, topBarLength, widthLayout, topSplicePieces } from './coping-main';
|
||||
import { shearBars, shearBarsMulti, copingSideBars, SIDE_HOOK_LEG, c14Bars, c14Length, stairBars, stepDevLength, undersideAt, shearULength, capLength, PIECES_PER_POSITION } from './coping';
|
||||
import { sideRowLevels } from '../coping-geom';
|
||||
import { columnRebar, columnInputFor } from './column';
|
||||
import { bottomBars, crossBars, sideBars, assemblyBars, shearB9 } from './footing';
|
||||
import { DEFAULT_MATERIAL, FckByMember, fyOf, isAssumedMaterial, Material, materialFor, splitPieces } from './common';
|
||||
import { DEFAULT_MATERIAL, FckByMember, fyOf, isAssumedMaterial, Material, materialFor, splitPieces, STANDARD_BAR } from './common';
|
||||
|
||||
/** 근거 badge (spec §6.1): where the value comes from. */
|
||||
export type Basis = 'input' | 'default' | 'calc' | 'assumed';
|
||||
@@ -89,8 +89,7 @@ const FALLBACK: Pick<RebarRow, 'spacing' | 'actual' | 'position' | 'direction' |
|
||||
spacing: '—', actual: '—', position: '—', direction: '—', shape: '—', basis: 'calc',
|
||||
};
|
||||
|
||||
/** 정척 L_bar (mm) from 확대기초철근.md §1.2. Bars longer than this need a splice. */
|
||||
export const STANDARD_BAR = 12000;
|
||||
export { STANDARD_BAR };
|
||||
|
||||
/**
|
||||
* 철근표 for one pier (③ screen v1): bearing blocks, coping, column, footing. Built from the generated model.
|
||||
@@ -195,8 +194,14 @@ export function rebarSummary(
|
||||
warnings.push({ code: 'CP04', message: `주철근 개수 ${width.count}(n+3)은 홀수라 cycle-1·cycle-2를 나눌 수 없습니다 (기본간격 ${width.spacing}, 끝단 여유 ${model.copingRebar.mainEndGap}). 기본간격을 확인하세요.`, target: 'coping' });
|
||||
}
|
||||
// C1–C3 and C4–C6 are the same three top rows (row 1, 2, 3), one set per cycle.
|
||||
const AT_LABEL = { center: '기둥 중심', end: '단부' } as const;
|
||||
for (const [name, k] of [['C1', 1], ['C2', 2], ['C3', 3], ['C4', 1], ['C5', 2], ['C6', 3]] as const) {
|
||||
rows.push({ member: 'coping', name, size: 'H29', count: perRow, length: topBarLength(L, k), note: '상면, 이음 무시' });
|
||||
const sp = model.topSplice.mode === 'apply' ? topSplicePieces(L, k, model.topSplice.at, mCoping) : null;
|
||||
if (sp) {
|
||||
rows.push({ member: 'coping', name, size: 'H29', count: perRow, length: null, pieces: [{ length: sp.pieces[0], count: perRow }, { length: sp.pieces[1], count: perRow }], note: `상면, 2조각 겹침이음 (${AT_LABEL[model.topSplice.at]}, l_s ${Math.round(sp.lap)})` });
|
||||
} else {
|
||||
rows.push({ member: 'coping', name, size: 'H29', count: perRow, length: topBarLength(L, k), note: '상면, 이음 무시' });
|
||||
}
|
||||
}
|
||||
const bottom = bottomPiece(mCoping);
|
||||
rows.push({ member: 'coping', name: 'C7', size: 'H29', count: perRow, length: bottom.piece, note: '하면, 2조각 겹침이음' });
|
||||
|
||||
+3
-1
@@ -1,4 +1,4 @@
|
||||
import type { CopingRebarSettings } from './rebar/coping-settings';
|
||||
import type { CopingRebarSettings, TopSpliceSettings } from './rebar/coping-settings';
|
||||
|
||||
export type PierType = 'T형' | '2주형' | '3주형';
|
||||
export type FoundationType = '말뚝기초' | '직접기초' | '현장타설말뚝';
|
||||
@@ -78,6 +78,8 @@ export interface PierInput {
|
||||
bearingLayout?: '분리' | '일체';
|
||||
/** 코핑 배근 입력 (승인 2026-10-26): the 12 numbers of ③ 코핑 배근. Absent = the 코핑철근.md defaults. */
|
||||
copingRebar?: Partial<CopingRebarSettings>;
|
||||
/** 상면 주철근(C1–C6) 이음 (승인 2026-10-26). Absent = 이음 무시, 기둥 중심. */
|
||||
topSplice?: Partial<TopSpliceSettings>;
|
||||
strataRows?: StrataRow[];
|
||||
}
|
||||
|
||||
|
||||
+34
-4
@@ -27,7 +27,7 @@ import { blockRebarPlanSvg } from './view/block-rebar-plan-svg';
|
||||
import { copingEndStation, copingFrontSvg, copingSectionSvg } from './view/coping-rebar-svg';
|
||||
import { BLOCK_REBAR_RANGES } from './core/rebar/block-check';
|
||||
import { DEFAULT_BLOCK_REBAR, type BlockRebarSettings } from './core/rebar/bearing-block';
|
||||
import { COPING_REBAR_RANGES, copingSettingsIssues, type CopingRebarSettings, DEFAULT_COPING_REBAR } from './core/rebar/coping-settings';
|
||||
import { COPING_REBAR_RANGES, copingSettingsIssues, type CopingRebarSettings, DEFAULT_COPING_REBAR, DEFAULT_TOP_SPLICE, type TopSpliceSettings } from './core/rebar/coping-settings';
|
||||
import { groundSectionSvg } from './view/ground-svg';
|
||||
import { parseBearingElevationTable, parseSolplateTable, readDxfTexts } from './core/dxf-table';
|
||||
import { columnDiameterIssues } from './core/column-check';
|
||||
@@ -1091,13 +1091,26 @@ const COPING_REBAR_FIELDS: { key: keyof CopingRebarSettings; label: string }[] =
|
||||
];
|
||||
|
||||
/** 적용: the values go to the draft and the model is rebuilt only when every check passes (CP01·CP02). */
|
||||
function applyCopingRebar(name: string, next: CopingRebarSettings): void {
|
||||
function applyCopingRebar(name: string, next: CopingRebarSettings, splice: TopSpliceSettings): void {
|
||||
const p = state.piers.find((q) => q.input.name === name);
|
||||
if (!p) return;
|
||||
p.draft = { ...p.draft, copingRebar: next };
|
||||
p.draft = { ...p.draft, copingRebar: next, topSplice: splice };
|
||||
regenerateOne(name);
|
||||
}
|
||||
|
||||
/** A row of toggle buttons (aria-pressed), as on the 배치 chips of ②. */
|
||||
function toggleRow<T extends string>(options: [T, string][], current: T, onPick: (v: T) => void): HTMLDivElement {
|
||||
const row = el('div', undefined, 'opts');
|
||||
for (const [v, label] of options) {
|
||||
const b = el('button', label, 'btn small');
|
||||
b.type = 'button';
|
||||
b.setAttribute('aria-pressed', String(v === current));
|
||||
b.addEventListener('click', () => onPick(v));
|
||||
row.appendChild(b);
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
function renderCopingSettings(box: HTMLDivElement, pier: Pier): void {
|
||||
if (!pier.model) return;
|
||||
const wrap = el('div', undefined, 'bearing-ref');
|
||||
@@ -1135,6 +1148,23 @@ function renderCopingSettings(box: HTMLDivElement, pier: Pier): void {
|
||||
grid.appendChild(row);
|
||||
}
|
||||
wrap.appendChild(grid);
|
||||
// 상면 주철근(C1–C6) 이음 (승인 2026-10-26): 무시 (사양 기본) / 반영, and the 위치 when 반영.
|
||||
let splice: TopSpliceSettings = { ...DEFAULT_TOP_SPLICE, ...pier.draft.topSplice };
|
||||
const spliceBox = el('div', undefined, 'bearing-ref');
|
||||
const drawSplice = (): void => {
|
||||
spliceBox.replaceChildren(el('p', '상면 주철근(C1–C6) 이음', 'muted small'), toggleRow([['ignore', '이음 무시'], ['apply', '반영']] as const, splice.mode, (v) => {
|
||||
splice = { ...splice, mode: v };
|
||||
drawSplice();
|
||||
}));
|
||||
if (splice.mode === 'apply') {
|
||||
spliceBox.appendChild(toggleRow([['center', '기둥 중심'], ['end', '단부']] as const, splice.at, (v) => {
|
||||
splice = { ...splice, at: v };
|
||||
drawSplice();
|
||||
}));
|
||||
}
|
||||
};
|
||||
drawSplice();
|
||||
wrap.appendChild(spliceBox);
|
||||
const msg = el('p', undefined, 'muted small');
|
||||
const apply = el('button', '적용', 'btn small');
|
||||
apply.type = 'button';
|
||||
@@ -1147,7 +1177,7 @@ function renderCopingSettings(box: HTMLDivElement, pier: Pier): void {
|
||||
setError('코핑 배근 입력을 확인하세요. 값은 반영되지 않았습니다.');
|
||||
return;
|
||||
}
|
||||
applyCopingRebar(pier.input.name, next);
|
||||
applyCopingRebar(pier.input.name, next, splice);
|
||||
});
|
||||
wrap.append(msg, apply);
|
||||
box.appendChild(wrap);
|
||||
|
||||
+10
-1
@@ -1,7 +1,7 @@
|
||||
import * as THREE from 'three';
|
||||
import type { PierModel } from '../core/geometry';
|
||||
import { assemblyEndOffset, assemblyJs, b10Levels, b9Bars, FOOTING_DEFAULTS, gridPositions, grid, layers, legLength, legOffsets, sideDepth } from '../core/rebar/footing';
|
||||
import { bottomPiece, MAIN, widthLayout } from '../core/rebar/coping-main';
|
||||
import { bottomPiece, MAIN, topSplicePieces, widthLayout } from '../core/rebar/coping-main';
|
||||
import { C14_INSET, c14Bars, CAP, COPING_REBAR, SHEAR_LOOP_STEP, shearBars, shearBarsMulti, shearUHeight, copingSideBars, SIDE_HOOK_LEG, stairBars, undersideAt } from '../core/rebar/coping';
|
||||
import { sideRowLevels } from '../core/coping-geom';
|
||||
import { columnRebar, columnInputFor, COLUMN_P1 } from '../core/rebar/column';
|
||||
@@ -152,8 +152,17 @@ export function buildRebar3D(m: PierModel, common: Material = DEFAULT_MATERIAL,
|
||||
for (let k = 1; k <= 3; k++) {
|
||||
const z = topEl - 0.127 - (k - 1) * (m.copingRebar.mainLayerGap / 1000);
|
||||
const xk = cover + ((k - 1) * MAIN.layHorizontal) / 1000;
|
||||
// 상면 이음 (승인 2026-10-26): when applied and longer than the standard, the bar is two pieces overlapping by l_s at the split.
|
||||
const sp = m.topSplice.mode === 'apply' ? topSplicePieces(L * 1000, k, m.topSplice.at, mCoping) : null;
|
||||
const splitX = sp ? xk + (sp.splitFromLeft - MAIN.hook) / 1000 : 0;
|
||||
const half = sp ? sp.lap / 2000 : 0;
|
||||
xs.forEach((n, j) => {
|
||||
const name = `C${k + (j % 2 === 1 ? 0 : 3)}`;
|
||||
if (sp) {
|
||||
addPath(name, 0, [[xk, z - hookTop, n], [xk, z, n], [splitX + half, z, n]], NOMINAL_DIAMETER.H29, COLOR.coping);
|
||||
addPath(name, 0, [[splitX - half, z, n], [L - xk, z, n], [L - xk, z - hookTop, n]], NOMINAL_DIAMETER.H29, COLOR.coping);
|
||||
return;
|
||||
}
|
||||
const pts: [number, number, number][] = [
|
||||
[xk, z - hookTop, n],
|
||||
[xk, z, n],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { developmentLength, hookLength, NOMINAL_DIAMETER, spliceLength } from '../src/core/rebar/common';
|
||||
import { bottomPiece, topBarLength, topRowEl, widthLayout } from '../src/core/rebar/coping-main';
|
||||
import { bottomPiece, topBarLength, topRowEl, topSplicePieces, widthLayout } from '../src/core/rebar/coping-main';
|
||||
import { buildPier } from '../src/core/geometry';
|
||||
import { rebarSummary } from '../src/core/rebar/summary';
|
||||
import { DEFAULT_COPING_REBAR } from '../src/core/rebar/coping-settings';
|
||||
@@ -54,6 +54,42 @@ describe('C1–C8 상·하면 주철근 (코핑철근.md §5, plan C3)', () => {
|
||||
expect([s1.spacing, s1.actual, s1.basis]).toEqual(['130', '130', 'input']);
|
||||
});
|
||||
|
||||
it('상면 이음 (승인 2026-10-26): 기둥 중심 → total/2 + l_s/2 each; 단부 → total + l_s − 12000 and 12000', () => {
|
||||
const center = topSplicePieces(12000, 1, 'center')!;
|
||||
expect(center.lap).toBeGreaterThan(1700);
|
||||
expect(center.pieces[0]).toBeCloseTo(12744 / 2 + center.lap / 2, 3);
|
||||
expect(center.pieces[1]).toBeCloseTo(center.pieces[0], 3);
|
||||
expect(center.pieces[0] + center.pieces[1]).toBeCloseTo(12744 + center.lap, 3);
|
||||
|
||||
const end = topSplicePieces(12000, 1, 'end')!;
|
||||
expect(end.pieces[0]).toBeCloseTo(12744 + end.lap - 12000, 3);
|
||||
expect(end.pieces[1]).toBeCloseTo(12000, 3);
|
||||
});
|
||||
|
||||
it('상면 이음: a bar within the standard length is not split', () => {
|
||||
expect(topSplicePieces(10000, 1, 'center')).toBeNull();
|
||||
});
|
||||
|
||||
it('철근표: 이음 무시 → 단일 길이 12744 · 반영(기둥 중심) → 2조각, 각 조각 개수 = 행 개수', () => {
|
||||
const ignore = rebarSummary(buildPier(loadP1())).rows.find((r) => r.name === 'C1')!;
|
||||
expect(ignore.length).toBeCloseTo(12744, 0);
|
||||
expect(ignore.pieces).toBeUndefined();
|
||||
|
||||
const applied = rebarSummary(buildPier({ ...loadP1(), topSplice: { mode: 'apply', at: 'center' } })).rows;
|
||||
const c1 = applied.find((r) => r.name === 'C1')!;
|
||||
const lap = topSplicePieces(12000, 1, 'center')!.lap;
|
||||
expect(c1.length).toBeNull();
|
||||
expect(c1.pieces).toHaveLength(2);
|
||||
expect(c1.pieces![0].count).toBe(c1.count);
|
||||
expect(c1.pieces![0].length).toBeCloseTo(12744 / 2 + lap / 2, 3);
|
||||
expect(c1.pieces![1].length).toBeCloseTo(12744 / 2 + lap / 2, 3);
|
||||
expect(c1.note).toContain('기둥 중심');
|
||||
|
||||
const end = rebarSummary(buildPier({ ...loadP1(), topSplice: { mode: 'apply', at: 'end' } })).rows.find((r) => r.name === 'C1')!;
|
||||
expect(end.pieces![1].length).toBeCloseTo(12000, 3);
|
||||
expect(end.note).toContain('단부');
|
||||
});
|
||||
|
||||
it('CP04: the default P1 has an even count (no warning); 기본간격 120 gives an odd count and a CP04 warning', () => {
|
||||
const base = rebarSummary(buildPier(loadP1())).warnings.filter((w) => w.code === 'CP04');
|
||||
expect(base).toEqual([]);
|
||||
|
||||
Reference in new issue
Block a user