@things-factory/figure-ui 10.1.84 → 10.1.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/modeller/editor.ts +9 -0
- package/client/modeller/figure-parts.ts +4 -4
- package/client/modeller/figure-section-panel.ts +204 -75
- package/client/modeller/live.ts +8 -4
- package/client/modeller/section-controls.ts +89 -8
- package/dist-client/modeller/editor.d.ts +2 -0
- package/dist-client/modeller/editor.js +8 -0
- package/dist-client/modeller/editor.js.map +1 -1
- package/dist-client/modeller/figure-parts.js +1 -3
- package/dist-client/modeller/figure-parts.js.map +1 -1
- package/dist-client/modeller/figure-section-panel.d.ts +26 -12
- package/dist-client/modeller/figure-section-panel.js +186 -69
- package/dist-client/modeller/figure-section-panel.js.map +1 -1
- package/dist-client/modeller/live.d.ts +3 -1
- package/dist-client/modeller/live.js +6 -3
- package/dist-client/modeller/live.js.map +1 -1
- package/dist-client/modeller/section-controls.d.ts +33 -0
- package/dist-client/modeller/section-controls.js +71 -7
- package/dist-client/modeller/section-controls.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/test/palette-icons.test.ts +1 -1
- package/test/parts-wiring.test.ts +6 -2
- package/test/section-panel.test.ts +103 -4
- package/translations/en.json +13 -2
- package/translations/ja.json +13 -2
- package/translations/ko.json +13 -2
- package/translations/ms.json +13 -2
- package/translations/zh.json +13 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/figure-ui",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.85",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"@things-factory:registry": "https://registry.npmjs.org"
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"@things-factory/figure-service": "^10.1.84",
|
|
45
45
|
"three": "^0.185.1"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "cbca21a8021b950f558f5547d5df4d12c199a3ef"
|
|
48
48
|
}
|
|
@@ -17,6 +17,6 @@ test('every shape in the palette has an icon the font draws', () => {
|
|
|
17
17
|
const parts = readFileSync(fileURLToPath(new URL('../client/modeller/figure-parts.ts', import.meta.url)), 'utf8')
|
|
18
18
|
const recipes = parts.slice(parts.indexOf('const RECIPES'), parts.indexOf(']', parts.indexOf('const RECIPES')))
|
|
19
19
|
const icons = [...recipes.matchAll(/icon: '([a-z_]+)'/g)].map(m => m[1]!)
|
|
20
|
-
assert.ok(icons.length >=
|
|
20
|
+
assert.ok(icons.length >= 8, 'the eight starting shapes (ADR-0100 §2.1)')
|
|
21
21
|
assert.deepEqual(icons.filter(icon => !RENDERS.has(icon)), [])
|
|
22
22
|
})
|
|
@@ -57,8 +57,12 @@ test('좁은 칸에서도 고른 줄의 이름과 조작이 다 보인다 —
|
|
|
57
57
|
assert.match(narrow, /li\[selected\] div\[ops\] \{\s*flex-basis: 100%;/)
|
|
58
58
|
})
|
|
59
59
|
|
|
60
|
-
test('둥근
|
|
61
|
-
|
|
60
|
+
test('팔레트는 시작 모양만 낸다 — 둥근 상자와 통은 상자의 모서리·속 공간으로 만든다 (ADR-0100 §2.1·§3.3)', () => {
|
|
61
|
+
const recipes = panel.slice(panel.indexOf('const RECIPES'), panel.indexOf(']', panel.indexOf('const RECIPES')))
|
|
62
|
+
const kinds = [...recipes.matchAll(/kind: '([\w-]+)'/g)].map(m => m[1])
|
|
63
|
+
assert.deepEqual(kinds, ['box', 'cylinder', 'sphere', 'frustum', 'polygon', 'plate', 'wall', 'portal'])
|
|
64
|
+
/* A part made so is still called by what it is: its icon in the parts list, its name over the properties (links.ts). */
|
|
65
|
+
assert.match(panel, /'rounded-box': 'crop_square'/)
|
|
62
66
|
for (const lang of ['ko', 'en', 'ja', 'zh', 'ms'])
|
|
63
67
|
assert.ok(JSON.parse(read(`../translations/${lang}.json`))['figure.label.primitive-rounded-box'], lang)
|
|
64
68
|
})
|
|
@@ -12,7 +12,17 @@ import { fileURLToPath } from 'node:url'
|
|
|
12
12
|
import { addFigureBox, applyFigureAuthoring, compileFigureAsset, createFigureAsset } from '@hatiolab/figure-model'
|
|
13
13
|
import type { FigureAsset, FigureEvaluatedShape } from '@hatiolab/figure-model'
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
cavityDepthOf,
|
|
17
|
+
cavityRefusalOf,
|
|
18
|
+
cavityRequestOf,
|
|
19
|
+
cavityResultOf,
|
|
20
|
+
cornerLimitOf,
|
|
21
|
+
cornerRefusalOf,
|
|
22
|
+
defaultWallOf,
|
|
23
|
+
wallLimitOf
|
|
24
|
+
} from '../client/modeller/section-controls.ts'
|
|
25
|
+
import { livePartsOf } from '../client/modeller/live.ts'
|
|
16
26
|
import { editRefusalOf } from '../client/modeller/refusals.ts'
|
|
17
27
|
|
|
18
28
|
const read = (path: string) => readFileSync(fileURLToPath(new URL(path, import.meta.url)), 'utf8')
|
|
@@ -73,17 +83,73 @@ test('벽이 단면을 다 채우거나 모서리가 변의 절반을 넘으면,
|
|
|
73
83
|
assert.equal(refusal(() => applyFigureAuthoring(probe(), { kind: 'set-section-corner', part: 'body', corner: 160 })), ko['figure.text.section-corner-too-large'])
|
|
74
84
|
})
|
|
75
85
|
|
|
76
|
-
test('편집기는 단면 칸의 명령을 세션의 이력 하나로 돌리고,
|
|
86
|
+
test('편집기는 단면 칸의 명령을 세션의 이력 하나로 돌리고, 치는 동안의 값은 그리기만 한다', () => {
|
|
77
87
|
assert.match(editor, /<figure-section-panel[\s\S]*?@command=\$\{\(e: CustomEvent\) => this\.linkCommand\(e\.detail\.action\)\}/)
|
|
78
|
-
assert.match(
|
|
88
|
+
assert.match(editor, /@command-live=\$\{\(e: CustomEvent\) => this\.holdAction\(e\.detail\.action\)\}/)
|
|
89
|
+
assert.match(editor, /private linkCommand\(action: FigureAuthoringAction\) \{\s*\/\*[^*]*\*\/\s*this\.holdAction\(null\)/, 'a command sent lets go of the one in hand')
|
|
79
90
|
for (const lang of ['ko', 'en', 'ja', 'zh', 'ms']) {
|
|
80
91
|
const words = JSON.parse(read(`../translations/${lang}.json`)) as Record<string, string>
|
|
81
92
|
const used = [...new Set([...panel.matchAll(/'(figure\.(?:label|text)\.section-[\w-]+|figure\.label\.group-section)'/g)].map(m => m[1]!))]
|
|
82
|
-
|
|
93
|
+
/* The keys the panel builds: each result, and the wall's and the ends' over-limit words. */
|
|
94
|
+
used.push(...['pipe', 'container', 'sealed'].map(r => `figure.label.section-result-${r}`), 'figure.text.section-wall-over', 'figure.text.section-ends-over')
|
|
95
|
+
assert.ok(used.length >= 16)
|
|
83
96
|
for (const key of used) assert.ok(words[key], `${lang} has ${key}`)
|
|
84
97
|
}
|
|
85
98
|
})
|
|
86
99
|
|
|
100
|
+
test('화면에 커널 말을 쓰지 않는다 — 「속 비우기」·「중공」·「공동」이 아니라 「속 공간」 (ADR-0100 §2.1)', () => {
|
|
101
|
+
const words = Object.entries(ko).filter(([k]) => k.startsWith('figure.label.section-') || k.startsWith('figure.text.section-'))
|
|
102
|
+
for (const [key, text] of words) assert.doesNotMatch(text, /속\s*비우|속을 비움|중공|공동/, key)
|
|
103
|
+
assert.equal(ko['figure.label.section-cavity'], '속 공간 만들기')
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
test('모서리 반지름의 허용값은 커널이 정한 그대로다 — 짧은 변의 절반까지', () => {
|
|
107
|
+
const shape = shapeOf(probe())
|
|
108
|
+
assert.equal(cornerLimitOf(shape), 150)
|
|
109
|
+
assert.equal(cornerRefusalOf(shape, 150), null)
|
|
110
|
+
assert.deepEqual(cornerRefusalOf(shape, 151), { max: 150 })
|
|
111
|
+
/* The screen's limit is the kernel's: the command takes 150 and refuses 151. */
|
|
112
|
+
assert.doesNotThrow(() => shapeOf(applyFigureAuthoring(probe(), { kind: 'set-section-corner', part: 'body', corner: 150 })))
|
|
113
|
+
assert.throws(() => applyFigureAuthoring(probe(), { kind: 'set-section-corner', part: 'body', corner: 151 }))
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
test('벽과 막힌 끝의 허용값도 커널이 정한 그대로다 — 칸은 고칠 값을 말하고 보내지 않는다', () => {
|
|
117
|
+
const tray = applyFigureAuthoring(probe(), { kind: 'set-cavity', part: 'body', cavity: cavityRequestOf(shapeOf(probe())) })
|
|
118
|
+
const shape = shapeOf(tray)
|
|
119
|
+
assert.equal(wallLimitOf(shape), 150)
|
|
120
|
+
assert.deepEqual(cavityRefusalOf(shape, cavityRequestOf(shape, { wall: 150 })), { code: 'wall-too-thick', max: 150 })
|
|
121
|
+
assert.equal(cavityRefusalOf(shape, cavityRequestOf(shape, { wall: 149 })), null)
|
|
122
|
+
assert.doesNotThrow(() => applyFigureAuthoring(tray, { kind: 'set-cavity', part: 'body', cavity: cavityRequestOf(shape, { wall: 149 }) }))
|
|
123
|
+
assert.throws(() => applyFigureAuthoring(tray, { kind: 'set-cavity', part: 'body', cavity: cavityRequestOf(shape, { wall: 150 }) }))
|
|
124
|
+
assert.deepEqual(cavityRefusalOf(shape, cavityRequestOf(shape, { start: { closed: 120 }, end: { closed: 80 } })), { code: 'ends-too-thick', max: 200 })
|
|
125
|
+
/* One side thicker than the rest: the kernel still says whether the inside has room. */
|
|
126
|
+
assert.equal(cavityRefusalOf(shape, cavityRequestOf(shape, { wall: { 'x-': 396, 'x+': 5, 'z-': 5, 'z+': 5 } })).code, 'wall-too-thick')
|
|
127
|
+
assert.equal(cavityRefusalOf(shape, cavityRequestOf(shape, { wall: { 'x-': 100, 'x+': 5, 'z-': 5, 'z+': 5 } })), null)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
test('속 공간은 무엇이 되었는지와 깊이로 보인다 — 한쪽이 열리면 용기, 양쪽이면 관, 양쪽이 막히면 닫힌 속 공간', () => {
|
|
131
|
+
const tray = shapeOf(applyFigureAuthoring(probe(), { kind: 'set-cavity', part: 'body', cavity: cavityRequestOf(shapeOf(probe())) }))
|
|
132
|
+
assert.equal(cavityResultOf(tray.cavity!), 'container')
|
|
133
|
+
assert.equal(cavityDepthOf(tray), 170, 'the 200 mm push less its 30 mm floor')
|
|
134
|
+
assert.equal(cavityResultOf({ ...tray.cavity!, start: 'open' }), 'pipe')
|
|
135
|
+
assert.equal(cavityResultOf({ ...tray.cavity!, end: { closed: 5 } }), 'sealed')
|
|
136
|
+
assert.match(panel, /figure\.text\.section-depth/)
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
test('치는 동안의 값은 사본에 그려지고 원본은 그대로다 — 받을 수 없는 값은 그리지 않는다', () => {
|
|
140
|
+
const asset = probe()
|
|
141
|
+
const drawn = livePartsOf(asset, { values: {}, action: { kind: 'set-section-corner', part: 'body', corner: 40 } })!
|
|
142
|
+
const body = drawn.find(p => p.id === 'body')! as unknown as { shape: FigureEvaluatedShape }
|
|
143
|
+
assert.deepEqual(body.shape.extrusion!.section, { kind: 'rectangle', size: { x: 400, z: 300 }, corner: { x: 40, z: 40 } })
|
|
144
|
+
assert.equal('corner' in shapeOf(asset).extrusion!.section, false, 'the asset itself is not changed')
|
|
145
|
+
assert.equal(livePartsOf(asset, { values: {}, action: { kind: 'set-section-corner', part: 'body', corner: 999 } }), null)
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
test('다각 단면에는 속 공간을 만들 수 없다고 그 자리에서 말한다', () => {
|
|
149
|
+
assert.match(panel, /kind === 'rectangle' \|\| kind === 'ellipse'\s*\? this\.renderCavity\(body, e\.axis\)\s*: html`[\s\S]*?figure\.text\.section-cavity-unavailable/)
|
|
150
|
+
assert.match(ko['figure.text.section-cavity-unavailable']!, /이 윤곽에는 속 공간을 만들 수 없습니다/)
|
|
151
|
+
})
|
|
152
|
+
|
|
87
153
|
test('붙어 있는 것이 기대는 면을 없애는 편집은 거절되고, 그 면을 사람의 말로 부른다', () => {
|
|
88
154
|
let asset = applyFigureAuthoring(probe(), { kind: 'set-cavity', part: 'body', cavity: { wall: 10, start: { closed: 15 }, end: 'open' } })
|
|
89
155
|
asset = addFigureBox(asset, { id: 'divider', size: { x: 10, y: 100, z: 200 }, position: { x: 0, y: 0, z: 0 } })
|
|
@@ -91,3 +157,36 @@ test('붙어 있는 것이 기대는 면을 없애는 편집은 거절되고,
|
|
|
91
157
|
const said = refusal(() => applyFigureAuthoring(asset, { kind: 'set-cavity', part: 'body', cavity: { wall: 10, start: 'open', end: 'open' } }))
|
|
92
158
|
assert.equal(said, say('figure.text.section-face-in-use', { faces: ko['figure.label.face-inside-bottom']! }))
|
|
93
159
|
})
|
|
160
|
+
|
|
161
|
+
test('치는 동안 그려진 도형이 칸의 글자를 덮어쓰지 않는다 — 친 것은 보낼 때까지 칸이 든다', () => {
|
|
162
|
+
assert.match(panel, /\.value=\$\{live\(this\.typed\[key\] \?\? shown\)\}/)
|
|
163
|
+
assert.match(panel, /this\.typed = \{ \.\.\.this\.typed, \[key\]: \(ev\.target as HTMLInputElement\)\.value \}/)
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
test('면마다 벽 두께를 치는 동안에도 그려진다 — 명령이 없앤 입력(한 벽 두께)의 지금 값은 미리보기를 막지 않는다', async () => {
|
|
167
|
+
const { liveOverSession } = await import('../client/modeller/live.ts')
|
|
168
|
+
const tray = applyFigureAuthoring(probe(), { kind: 'set-cavity', part: 'body', cavity: { wall: 30, start: { closed: 30 }, end: 'open' } })
|
|
169
|
+
/* The editor draws over every value as it stands: the one wall is among them. */
|
|
170
|
+
const current = { ...tray.designInputs }
|
|
171
|
+
assert.ok('body.dimension.wall' in current)
|
|
172
|
+
const drawn = liveOverSession(tray, current, {
|
|
173
|
+
values: {},
|
|
174
|
+
action: { kind: 'set-cavity', part: 'body', cavity: { wall: { 'x-': 100, 'x+': 30, 'z-': 30, 'z+': 30 }, start: { closed: 30 }, end: 'open' } }
|
|
175
|
+
})
|
|
176
|
+
assert.ok(drawn, 'the preview is drawn')
|
|
177
|
+
const body = drawn!.find(p => p.id === 'body') as unknown as { shape: FigureEvaluatedShape }
|
|
178
|
+
assert.equal(body.shape.cavity!.wall['x-'], 100)
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
test('한 면의 벽 한도는 그 방향의 너비에서 맞은편 벽을 뺀 값이다 — 네 면이 같을 때의 한도가 아니다', async () => {
|
|
182
|
+
const { sideWallLimitOf } = await import('../client/modeller/section-controls.ts')
|
|
183
|
+
const tray = applyFigureAuthoring(probe(), { kind: 'set-cavity', part: 'body', cavity: { wall: 30, start: { closed: 30 }, end: 'open' } })
|
|
184
|
+
const shape = shapeOf(tray)
|
|
185
|
+
const walls = { 'x-': 30, 'x+': 40, 'z-': 30, 'z+': 30 }
|
|
186
|
+
assert.equal(sideWallLimitOf(shape, walls, 'x-'), 360, 'the 400 mm width less the 40 mm wall opposite')
|
|
187
|
+
assert.equal(sideWallLimitOf(shape, walls, 'z+'), 270)
|
|
188
|
+
/* The kernel agrees: just under takes, the limit refuses. */
|
|
189
|
+
assert.equal(cavityRefusalOf(shape, cavityRequestOf(shape, { wall: { ...walls, 'x-': 359 } })), null)
|
|
190
|
+
assert.equal(cavityRefusalOf(shape, cavityRequestOf(shape, { wall: { ...walls, 'x-': 360 } }))!.code, 'wall-too-thick')
|
|
191
|
+
assert.match(panel, /sideWallLimitOf\(body\.shape, cavity\.wall, side\)/)
|
|
192
|
+
})
|
package/translations/en.json
CHANGED
|
@@ -188,12 +188,23 @@
|
|
|
188
188
|
"figure.label.palette-token": "palette token",
|
|
189
189
|
"figure.label.part": "part",
|
|
190
190
|
"figure.label.part-material": "material",
|
|
191
|
+
"figure.text.section-cavity-unavailable": "This outline cannot have an inside. An inside is made in a rectangle or circle section.",
|
|
192
|
+
"figure.text.section-corner-over": "The corner radius can be at most {max} mm.",
|
|
193
|
+
"figure.text.section-at-most": "at most {max} mm",
|
|
194
|
+
"figure.text.section-not-positive": "The thickness must be more than 0.",
|
|
195
|
+
"figure.text.section-wall-over": "The wall must be thinner than {max} mm.",
|
|
196
|
+
"figure.text.section-ends-over": "The two closed ends together must be thinner than {max} mm.",
|
|
197
|
+
"figure.text.section-depth": "{result} · {depth} mm deep",
|
|
198
|
+
"figure.label.section-result-pipe": "pipe",
|
|
199
|
+
"figure.label.section-result-container": "container",
|
|
200
|
+
"figure.label.section-result-sealed": "closed inside",
|
|
201
|
+
"figure.text.section-wall-at-most": "thinner than {max} mm",
|
|
202
|
+
"figure.label.section-wall-per-side": "per side",
|
|
191
203
|
"figure.label.group-section": "section",
|
|
192
204
|
"figure.label.section-corner": "corner radius",
|
|
193
205
|
"figure.text.section-corner-differs": "differs by axis",
|
|
194
|
-
"figure.label.section-cavity": "
|
|
206
|
+
"figure.label.section-cavity": "make an inside",
|
|
195
207
|
"figure.label.section-wall": "wall thickness",
|
|
196
|
-
"figure.text.section-wall-differs": "differs by side",
|
|
197
208
|
"figure.label.section-end-closed": "closed",
|
|
198
209
|
"figure.label.section-end-open": "open",
|
|
199
210
|
"figure.text.section-face-in-use": "Not changed: something is attached to {faces}. Detach it first.",
|
package/translations/ja.json
CHANGED
|
@@ -188,12 +188,23 @@
|
|
|
188
188
|
"figure.label.palette-token": "palette token",
|
|
189
189
|
"figure.label.part": "part",
|
|
190
190
|
"figure.label.part-material": "material",
|
|
191
|
+
"figure.text.section-cavity-unavailable": "この輪郭には内部の空間をつくれません。内部の空間は四角形と円の断面につくります。",
|
|
192
|
+
"figure.text.section-corner-over": "角の半径は {max} mm までです。",
|
|
193
|
+
"figure.text.section-at-most": "最大 {max} mm",
|
|
194
|
+
"figure.text.section-not-positive": "厚さは 0 より大きくしてください。",
|
|
195
|
+
"figure.text.section-wall-over": "壁の厚さは {max} mm より薄くしてください。",
|
|
196
|
+
"figure.text.section-ends-over": "閉じた両端の厚さの合計は {max} mm より薄くしてください。",
|
|
197
|
+
"figure.text.section-depth": "{result} · 深さ {depth} mm",
|
|
198
|
+
"figure.label.section-result-pipe": "管",
|
|
199
|
+
"figure.label.section-result-container": "容器",
|
|
200
|
+
"figure.label.section-result-sealed": "閉じた内部",
|
|
201
|
+
"figure.text.section-wall-at-most": "{max} mm より薄く",
|
|
202
|
+
"figure.label.section-wall-per-side": "面ごとに",
|
|
191
203
|
"figure.label.group-section": "断面",
|
|
192
204
|
"figure.label.section-corner": "角の半径",
|
|
193
205
|
"figure.text.section-corner-differs": "軸ごとに異なる",
|
|
194
|
-
"figure.label.section-cavity": "
|
|
206
|
+
"figure.label.section-cavity": "内部の空間をつくる",
|
|
195
207
|
"figure.label.section-wall": "壁の厚さ",
|
|
196
|
-
"figure.text.section-wall-differs": "面ごとに異なる",
|
|
197
208
|
"figure.label.section-end-closed": "閉じる",
|
|
198
209
|
"figure.label.section-end-open": "開く",
|
|
199
210
|
"figure.text.section-face-in-use": "変更しませんでした: {faces} に取り付けられたものがあります。先に外してください。",
|
package/translations/ko.json
CHANGED
|
@@ -188,12 +188,23 @@
|
|
|
188
188
|
"figure.label.palette-token": "팔레트 토큰",
|
|
189
189
|
"figure.label.part": "부품",
|
|
190
190
|
"figure.label.part-material": "재질",
|
|
191
|
+
"figure.text.section-cavity-unavailable": "이 윤곽에는 속 공간을 만들 수 없습니다. 속 공간은 사각형과 원 단면에 만듭니다.",
|
|
192
|
+
"figure.text.section-corner-over": "모서리 반지름은 {max} mm 까지입니다.",
|
|
193
|
+
"figure.text.section-at-most": "최대 {max} mm",
|
|
194
|
+
"figure.text.section-not-positive": "두께는 0 보다 커야 합니다.",
|
|
195
|
+
"figure.text.section-wall-over": "벽 두께는 {max} mm 보다 얇아야 합니다.",
|
|
196
|
+
"figure.text.section-ends-over": "막힌 두 끝의 두께를 더해 {max} mm 보다 얇아야 합니다.",
|
|
197
|
+
"figure.text.section-depth": "{result} · 깊이 {depth} mm",
|
|
198
|
+
"figure.label.section-result-pipe": "관",
|
|
199
|
+
"figure.label.section-result-container": "용기",
|
|
200
|
+
"figure.label.section-result-sealed": "닫힌 속 공간",
|
|
201
|
+
"figure.text.section-wall-at-most": "{max} mm 보다 얇게",
|
|
202
|
+
"figure.label.section-wall-per-side": "면마다 따로",
|
|
191
203
|
"figure.label.group-section": "단면",
|
|
192
204
|
"figure.label.section-corner": "모서리 반지름",
|
|
193
205
|
"figure.text.section-corner-differs": "축마다 다름",
|
|
194
|
-
"figure.label.section-cavity": "
|
|
206
|
+
"figure.label.section-cavity": "속 공간 만들기",
|
|
195
207
|
"figure.label.section-wall": "벽 두께",
|
|
196
|
-
"figure.text.section-wall-differs": "면마다 다름",
|
|
197
208
|
"figure.label.section-end-closed": "막힘",
|
|
198
209
|
"figure.label.section-end-open": "열림",
|
|
199
210
|
"figure.text.section-face-in-use": "이 면에 붙어 있는 것이 있어 바꾸지 않았습니다: {faces}. 먼저 떼어 냅니다.",
|
package/translations/ms.json
CHANGED
|
@@ -188,12 +188,23 @@
|
|
|
188
188
|
"figure.label.palette-token": "palette token",
|
|
189
189
|
"figure.label.part": "part",
|
|
190
190
|
"figure.label.part-material": "material",
|
|
191
|
+
"figure.text.section-cavity-unavailable": "Garis luar ini tidak boleh mempunyai ruang dalam. Ruang dalam dibuat dalam keratan segi empat atau bulatan.",
|
|
192
|
+
"figure.text.section-corner-over": "Jejari sudut paling banyak {max} mm.",
|
|
193
|
+
"figure.text.section-at-most": "paling banyak {max} mm",
|
|
194
|
+
"figure.text.section-not-positive": "Ketebalan mesti lebih daripada 0.",
|
|
195
|
+
"figure.text.section-wall-over": "Dinding mesti lebih nipis daripada {max} mm.",
|
|
196
|
+
"figure.text.section-ends-over": "Jumlah ketebalan dua hujung tertutup mesti kurang daripada {max} mm.",
|
|
197
|
+
"figure.text.section-depth": "{result} · dalam {depth} mm",
|
|
198
|
+
"figure.label.section-result-pipe": "paip",
|
|
199
|
+
"figure.label.section-result-container": "bekas",
|
|
200
|
+
"figure.label.section-result-sealed": "ruang dalam tertutup",
|
|
201
|
+
"figure.text.section-wall-at-most": "lebih nipis daripada {max} mm",
|
|
202
|
+
"figure.label.section-wall-per-side": "setiap sisi",
|
|
191
203
|
"figure.label.group-section": "keratan",
|
|
192
204
|
"figure.label.section-corner": "jejari sudut",
|
|
193
205
|
"figure.text.section-corner-differs": "berbeza mengikut paksi",
|
|
194
|
-
"figure.label.section-cavity": "
|
|
206
|
+
"figure.label.section-cavity": "buat ruang dalam",
|
|
195
207
|
"figure.label.section-wall": "ketebalan dinding",
|
|
196
|
-
"figure.text.section-wall-differs": "berbeza mengikut sisi",
|
|
197
208
|
"figure.label.section-end-closed": "tertutup",
|
|
198
209
|
"figure.label.section-end-open": "terbuka",
|
|
199
210
|
"figure.text.section-face-in-use": "Tidak diubah: ada sesuatu dipasang pada {faces}. Tanggalkannya dahulu.",
|
package/translations/zh.json
CHANGED
|
@@ -188,12 +188,23 @@
|
|
|
188
188
|
"figure.label.palette-token": "palette token",
|
|
189
189
|
"figure.label.part": "part",
|
|
190
190
|
"figure.label.part-material": "material",
|
|
191
|
+
"figure.text.section-cavity-unavailable": "此轮廓不能创建内部空间。内部空间只能在矩形和圆形截面中创建。",
|
|
192
|
+
"figure.text.section-corner-over": "圆角半径最大为 {max} mm。",
|
|
193
|
+
"figure.text.section-at-most": "最大 {max} mm",
|
|
194
|
+
"figure.text.section-not-positive": "厚度必须大于 0。",
|
|
195
|
+
"figure.text.section-wall-over": "壁厚必须小于 {max} mm。",
|
|
196
|
+
"figure.text.section-ends-over": "两个封闭端的厚度之和必须小于 {max} mm。",
|
|
197
|
+
"figure.text.section-depth": "{result} · 深 {depth} mm",
|
|
198
|
+
"figure.label.section-result-pipe": "管",
|
|
199
|
+
"figure.label.section-result-container": "容器",
|
|
200
|
+
"figure.label.section-result-sealed": "封闭内部",
|
|
201
|
+
"figure.text.section-wall-at-most": "小于 {max} mm",
|
|
202
|
+
"figure.label.section-wall-per-side": "逐面设置",
|
|
191
203
|
"figure.label.group-section": "截面",
|
|
192
204
|
"figure.label.section-corner": "圆角半径",
|
|
193
205
|
"figure.text.section-corner-differs": "各轴不同",
|
|
194
|
-
"figure.label.section-cavity": "
|
|
206
|
+
"figure.label.section-cavity": "创建内部空间",
|
|
195
207
|
"figure.label.section-wall": "壁厚",
|
|
196
|
-
"figure.text.section-wall-differs": "各面不同",
|
|
197
208
|
"figure.label.section-end-closed": "封闭",
|
|
198
209
|
"figure.label.section-end-open": "开口",
|
|
199
210
|
"figure.text.section-face-in-use": "未更改:{faces} 上附着有其他部件。请先拆下。",
|