@things-factory/figure-ui 10.1.15 → 10.1.17
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/figure-animations.ts +12 -12
- package/client/modeller/figure-canvas.ts +32 -48
- package/client/modeller/figure-capabilities.ts +10 -10
- package/client/modeller/figure-inspector.ts +39 -28
- package/client/modeller/figure-parts.ts +1 -1
- package/client/modeller/figure-preview.ts +122 -25
- package/client/modeller/figure-report.ts +24 -6
- package/client/modeller/figure-settings.ts +45 -2
- package/client/modeller/figure-side.ts +6 -6
- package/client/modeller/figure-source.ts +84 -38
- package/client/modeller/figure-thumbnail.ts +5 -5
- package/client/modeller/figure-view.ts +53 -0
- package/client/modeller/part-edits.ts +36 -36
- package/client/modeller/proposal.ts +25 -4
- package/client/pages/figure-modeller-page.ts +142 -98
- package/dist-client/modeller/figure-animations.d.ts +4 -4
- package/dist-client/modeller/figure-animations.js +10 -10
- package/dist-client/modeller/figure-animations.js.map +1 -1
- package/dist-client/modeller/figure-canvas.d.ts +7 -7
- package/dist-client/modeller/figure-canvas.js +27 -40
- package/dist-client/modeller/figure-canvas.js.map +1 -1
- package/dist-client/modeller/figure-capabilities.d.ts +2 -2
- package/dist-client/modeller/figure-capabilities.js +9 -9
- package/dist-client/modeller/figure-capabilities.js.map +1 -1
- package/dist-client/modeller/figure-inspector.d.ts +16 -5
- package/dist-client/modeller/figure-inspector.js +38 -27
- package/dist-client/modeller/figure-inspector.js.map +1 -1
- package/dist-client/modeller/figure-parts.d.ts +1 -1
- package/dist-client/modeller/figure-parts.js +1 -1
- package/dist-client/modeller/figure-parts.js.map +1 -1
- package/dist-client/modeller/figure-preview.d.ts +39 -0
- package/dist-client/modeller/figure-preview.js +112 -23
- package/dist-client/modeller/figure-preview.js.map +1 -1
- package/dist-client/modeller/figure-report.d.ts +9 -0
- package/dist-client/modeller/figure-report.js +23 -5
- package/dist-client/modeller/figure-report.js.map +1 -1
- package/dist-client/modeller/figure-settings.js +42 -2
- package/dist-client/modeller/figure-settings.js.map +1 -1
- package/dist-client/modeller/figure-side.d.ts +2 -2
- package/dist-client/modeller/figure-side.js +5 -5
- package/dist-client/modeller/figure-side.js.map +1 -1
- package/dist-client/modeller/figure-source.d.ts +38 -23
- package/dist-client/modeller/figure-source.js +40 -21
- package/dist-client/modeller/figure-source.js.map +1 -1
- package/dist-client/modeller/figure-thumbnail.d.ts +2 -2
- package/dist-client/modeller/figure-thumbnail.js +3 -3
- package/dist-client/modeller/figure-thumbnail.js.map +1 -1
- package/dist-client/modeller/figure-view.d.ts +45 -0
- package/dist-client/modeller/figure-view.js +27 -0
- package/dist-client/modeller/figure-view.js.map +1 -1
- package/dist-client/modeller/part-edits.d.ts +16 -16
- package/dist-client/modeller/part-edits.js +35 -35
- package/dist-client/modeller/part-edits.js.map +1 -1
- package/dist-client/modeller/proposal.d.ts +1 -1
- package/dist-client/modeller/proposal.js +15 -3
- package/dist-client/modeller/proposal.js.map +1 -1
- package/dist-client/pages/figure-modeller-page.d.ts +44 -9
- package/dist-client/pages/figure-modeller-page.js +134 -92
- package/dist-client/pages/figure-modeller-page.js.map +1 -1
- package/dist-client/route.d.ts +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/test/ai-proposal-contract.test.ts +393 -12
- package/test/expect.ts +55 -0
- package/test/figure-source.test.ts +562 -0
- package/test/i18n-prefix-guard.test.ts +1 -1
- package/{client/modeller → test}/part-edits.test.ts +50 -45
- package/translations/en.json +31 -28
- package/translations/ja.json +16 -21
- package/translations/ko.json +41 -38
- package/translations/ms.json +16 -21
- package/translations/zh.json +16 -21
- package/client/modeller/figure-ask.ts +0 -265
- package/client/modeller/figure-source.test.ts +0 -352
- package/dist-client/modeller/figure-ask.d.ts +0 -40
- package/dist-client/modeller/figure-ask.js +0 -282
- package/dist-client/modeller/figure-ask.js.map +0 -1
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import assert from 'node:assert/strict'
|
|
2
|
+
import { describe, it, test } from 'node:test'
|
|
3
|
+
|
|
4
|
+
import { expect } from './expect.ts'
|
|
5
|
+
|
|
1
6
|
import {
|
|
2
7
|
addPart,
|
|
3
8
|
alignPartToEnd,
|
|
@@ -14,9 +19,9 @@ import {
|
|
|
14
19
|
removePart,
|
|
15
20
|
snapPart,
|
|
16
21
|
updatePart
|
|
17
|
-
} from '
|
|
18
|
-
import { toFigureSource } from '
|
|
19
|
-
import type {
|
|
22
|
+
} from '../client/modeller/part-edits.ts'
|
|
23
|
+
import { toFigureSource } from '../dist-client/modeller/figure-source.js'
|
|
24
|
+
import type { FigureDraft, PartModel } from '../dist-client/modeller/figure-source.js'
|
|
20
25
|
import { validate } from '@hatiolab/figure-model'
|
|
21
26
|
|
|
22
27
|
/**
|
|
@@ -28,8 +33,8 @@ import { validate } from '@hatiolab/figure-model'
|
|
|
28
33
|
* 상황이 생긴다.
|
|
29
34
|
*/
|
|
30
35
|
|
|
31
|
-
/**
|
|
32
|
-
const
|
|
36
|
+
/** 기준 상자 3000 x 2000 x 800 — 세 축이 모두 달라야 축을 바꿔 써도 테스트가 잡아낸다. */
|
|
37
|
+
const DRAFT: FigureDraft = {
|
|
33
38
|
width: 3000,
|
|
34
39
|
height: 2000,
|
|
35
40
|
depth: 800,
|
|
@@ -51,8 +56,8 @@ const DECK: PartModel = {
|
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
describe('부품 생성', () => {
|
|
54
|
-
it('
|
|
55
|
-
const part = newPart(
|
|
59
|
+
it('기준 상자의 3분의 1 크기로 생성된다 — 추가하자마자 보여야 한다', () => {
|
|
60
|
+
const part = newPart(DRAFT, [], 'cube')
|
|
56
61
|
|
|
57
62
|
expect(part.width).toBe(1000)
|
|
58
63
|
expect(part.height).toBe(667)
|
|
@@ -60,37 +65,37 @@ describe('부품 생성', () => {
|
|
|
60
65
|
})
|
|
61
66
|
|
|
62
67
|
it('바닥 가운데에 놓인다', () => {
|
|
63
|
-
const part = newPart(
|
|
68
|
+
const part = newPart(DRAFT, [], 'cube')
|
|
64
69
|
|
|
65
70
|
expect(part.zPos).toBe(0)
|
|
66
71
|
// 위치도 크기도 정수로 맞추므로 0.5 까지는 어긋난다
|
|
67
|
-
expect(Math.abs(part.left + part.width / 2 -
|
|
68
|
-
expect(Math.abs(part.top + part.height / 2 -
|
|
72
|
+
expect(Math.abs(part.left + part.width / 2 - DRAFT.width / 2)).toBeLessThanOrEqual(0.5)
|
|
73
|
+
expect(Math.abs(part.top + part.height / 2 - DRAFT.height / 2)).toBeLessThanOrEqual(0.5)
|
|
69
74
|
})
|
|
70
75
|
|
|
71
|
-
it('
|
|
72
|
-
expect(newPart(
|
|
76
|
+
it('편집 캔버스에 그대로 놓을 수 있는 씬 컴포넌트 타입을 갖는다', () => {
|
|
77
|
+
expect(newPart(DRAFT, [], 'cube').type).toBe('figure-part')
|
|
73
78
|
})
|
|
74
79
|
|
|
75
80
|
it('이름이 중복되지 않는다 — 저장되는 식별자다', () => {
|
|
76
81
|
let parts: PartModel[] = []
|
|
77
|
-
for (let i = 0; i < 3; i++) parts = addPart(
|
|
82
|
+
for (let i = 0; i < 3; i++) parts = addPart(DRAFT, parts, 'cube')
|
|
78
83
|
|
|
79
84
|
expect(parts.map(part => part.name)).toEqual(['cube', 'cube-2', 'cube-3'])
|
|
80
85
|
})
|
|
81
86
|
|
|
82
87
|
it('팔레트 토큰을 기존 부품에서 물려받는다 — 토큰이 늘면 재질 그룹이 하나씩 는다', () => {
|
|
83
|
-
const parts = addPart(
|
|
88
|
+
const parts = addPart(DRAFT, [{ ...DECK, token: 'palette.dark' }], 'sphere')
|
|
84
89
|
expect(parts[1].token).toBe('palette.dark')
|
|
85
90
|
})
|
|
86
91
|
|
|
87
92
|
it('곡면 도형은 분할 수를 갖고 생성된다', () => {
|
|
88
|
-
expect(newPart(
|
|
89
|
-
expect(newPart(
|
|
93
|
+
expect(newPart(DRAFT, [], 'cylinder').segments).toBe(12)
|
|
94
|
+
expect(newPart(DRAFT, [], 'cube').segments).toBeUndefined()
|
|
90
95
|
})
|
|
91
96
|
|
|
92
97
|
it('polygon 은 삼각형으로 생성된다 — 점이 3개보다 적으면 검증에서 막힌다', () => {
|
|
93
|
-
expect(newPart(
|
|
98
|
+
expect(newPart(DRAFT, [], 'polygon').path).toHaveLength(3)
|
|
94
99
|
})
|
|
95
100
|
|
|
96
101
|
/*
|
|
@@ -99,7 +104,7 @@ describe('부품 생성', () => {
|
|
|
99
104
|
*/
|
|
100
105
|
it('새로 만든 부품만으로도 검증을 통과한다', () => {
|
|
101
106
|
for (const kind of ['cube', 'wall', 'cylinder', 'sphere', 'rect', 'polygon'] as const) {
|
|
102
|
-
const source = toFigureSource(
|
|
107
|
+
const source = toFigureSource(DRAFT, [newPart(DRAFT, [], kind)])
|
|
103
108
|
expect(validate(source).errors).toEqual([])
|
|
104
109
|
}
|
|
105
110
|
})
|
|
@@ -143,7 +148,7 @@ describe('목록 편집', () => {
|
|
|
143
148
|
})
|
|
144
149
|
|
|
145
150
|
it('부품 수 한도는 디테일 등급이 결정한다', () => {
|
|
146
|
-
expect(partLimit({ ...
|
|
151
|
+
expect(partLimit({ ...DRAFT, detailLevel: 'S' })).toBeLessThan(partLimit({ ...DRAFT, detailLevel: 'L' }))
|
|
147
152
|
})
|
|
148
153
|
})
|
|
149
154
|
|
|
@@ -156,40 +161,40 @@ describe('목록 편집', () => {
|
|
|
156
161
|
*/
|
|
157
162
|
describe('정밀 배치 도구', () => {
|
|
158
163
|
it('가운데로 옮기면 변환했을 때 원점에 온다', () => {
|
|
159
|
-
const moved = centerPart(
|
|
164
|
+
const moved = centerPart(DRAFT, [{ ...DECK, left: 0 }], 0, 'x')
|
|
160
165
|
|
|
161
166
|
expect(moved[0].left).toBe(1100)
|
|
162
|
-
expect(toFigureSource(
|
|
167
|
+
expect(toFigureSource(DRAFT, moved).parts[0].transform.position.x).toBe(0)
|
|
163
168
|
})
|
|
164
169
|
|
|
165
170
|
it('축마다 다른 속성을 바꾼다 — z 는 top 이고 y 는 zPos 다', () => {
|
|
166
|
-
expect(centerPart(
|
|
167
|
-
expect(centerPart(
|
|
171
|
+
expect(centerPart(DRAFT, [DECK], 0, 'z')[0].top).toBe(700)
|
|
172
|
+
expect(centerPart(DRAFT, [DECK], 0, 'y')[0].zPos).toBe(300)
|
|
168
173
|
})
|
|
169
174
|
|
|
170
|
-
it('바닥에 붙이면 zPos 가 0 이다 — 밑면이 곧
|
|
175
|
+
it('바닥에 붙이면 zPos 가 0 이다 — 밑면이 곧 상자 바닥이다', () => {
|
|
171
176
|
expect(alignPartToStart([DECK], 0, 'y')[0].zPos).toBe(0)
|
|
172
177
|
})
|
|
173
178
|
|
|
174
|
-
it('끝에 붙이면 부품의 끝이
|
|
175
|
-
const moved = alignPartToEnd(
|
|
176
|
-
expect(moved[0].left + moved[0].width).toBe(
|
|
179
|
+
it('끝에 붙이면 부품의 끝이 상자의 끝과 만난다', () => {
|
|
180
|
+
const moved = alignPartToEnd(DRAFT, [DECK], 0, 'x')
|
|
181
|
+
expect(moved[0].left + moved[0].width).toBe(DRAFT.width)
|
|
177
182
|
})
|
|
178
183
|
|
|
179
|
-
it('대칭 복제가
|
|
180
|
-
const parts = mirrorPart(
|
|
184
|
+
it('대칭 복제가 상자 안에서 반대쪽으로 간다', () => {
|
|
185
|
+
const parts = mirrorPart(DRAFT, [{ ...DECK, left: 200 }], 0, 'x')
|
|
181
186
|
|
|
182
187
|
expect(parts).toHaveLength(2)
|
|
183
188
|
// 왼쪽 여백 200 → 오른쪽 여백도 200 이어야 한다
|
|
184
|
-
expect(parts[1].left).toBe(
|
|
189
|
+
expect(parts[1].left).toBe(DRAFT.width - 200 - DECK.width)
|
|
185
190
|
})
|
|
186
191
|
|
|
187
192
|
it('대칭 복제본이 어느 쪽인지 이름에 드러난다', () => {
|
|
188
|
-
expect(mirrorPart(
|
|
193
|
+
expect(mirrorPart(DRAFT, [{ ...DECK, left: 200 }], 0, 'x')[1].name).toBe('deck-x')
|
|
189
194
|
})
|
|
190
195
|
|
|
191
196
|
it('대칭 복제가 원본을 건드리지 않는다', () => {
|
|
192
|
-
const parts = mirrorPart(
|
|
197
|
+
const parts = mirrorPart(DRAFT, [{ ...DECK, left: 200 }], 0, 'x')
|
|
193
198
|
expect(parts[0].left).toBe(200)
|
|
194
199
|
})
|
|
195
200
|
|
|
@@ -198,26 +203,26 @@ describe('정밀 배치 도구', () => {
|
|
|
198
203
|
늘고 겹친 면에서 z-fighting 이 일어난다.
|
|
199
204
|
*/
|
|
200
205
|
it('이미 가운데면 대칭 복제를 막는다', () => {
|
|
201
|
-
const centered = centerPart(
|
|
206
|
+
const centered = centerPart(DRAFT, [DECK], 0, 'x')
|
|
202
207
|
|
|
203
|
-
expect(canMirror(
|
|
204
|
-
expect(mirrorPart(
|
|
208
|
+
expect(canMirror(DRAFT, centered, 0, 'x')).toBe(false)
|
|
209
|
+
expect(mirrorPart(DRAFT, centered, 0, 'x')).toHaveLength(1)
|
|
205
210
|
})
|
|
206
211
|
|
|
207
212
|
it('가운데가 아니면 대칭 복제할 수 있다', () => {
|
|
208
|
-
expect(canMirror(
|
|
213
|
+
expect(canMirror(DRAFT, [{ ...DECK, left: 200 }], 0, 'x')).toBe(true)
|
|
209
214
|
})
|
|
210
215
|
|
|
211
216
|
it('격자에 맞추면 위치와 크기가 격자 배수가 된다', () => {
|
|
212
|
-
const step = gridStep(
|
|
213
|
-
const snapped = snapPart(
|
|
217
|
+
const step = gridStep(DRAFT)
|
|
218
|
+
const snapped = snapPart(DRAFT, [{ ...DECK, left: 1213, width: 787 }], 0)
|
|
214
219
|
|
|
215
220
|
expect(snapped[0].left % step).toBe(0)
|
|
216
221
|
expect(snapped[0].width % step).toBe(0)
|
|
217
222
|
})
|
|
218
223
|
|
|
219
224
|
it('격자에 맞춰도 크기가 0 이 되지 않는다 — 사라진 것처럼 보인다', () => {
|
|
220
|
-
const snapped = snapPart(
|
|
225
|
+
const snapped = snapPart(DRAFT, [{ ...DECK, width: 1, height: 1, depth: 1 }], 0)
|
|
221
226
|
|
|
222
227
|
expect(snapped[0].width).toBeGreaterThan(0)
|
|
223
228
|
expect(snapped[0].height).toBeGreaterThan(0)
|
|
@@ -226,10 +231,10 @@ describe('정밀 배치 도구', () => {
|
|
|
226
231
|
|
|
227
232
|
it('없는 인덱스를 주면 목록을 그대로 반환한다', () => {
|
|
228
233
|
const parts = [DECK]
|
|
229
|
-
expect(centerPart(
|
|
230
|
-
expect(snapPart(
|
|
231
|
-
expect(mirrorPart(
|
|
232
|
-
expect(canMirror(
|
|
234
|
+
expect(centerPart(DRAFT, parts, 7, 'x')).toBe(parts)
|
|
235
|
+
expect(snapPart(DRAFT, parts, 7)).toBe(parts)
|
|
236
|
+
expect(mirrorPart(DRAFT, parts, 7, 'x')).toBe(parts)
|
|
237
|
+
expect(canMirror(DRAFT, parts, 7, 'x')).toBe(false)
|
|
233
238
|
})
|
|
234
239
|
})
|
|
235
240
|
|
|
@@ -246,7 +251,7 @@ describe('격자 간격', () => {
|
|
|
246
251
|
expect(niceStep(-100)).toBeGreaterThan(0)
|
|
247
252
|
})
|
|
248
253
|
|
|
249
|
-
it('
|
|
250
|
-
expect(gridStep(
|
|
254
|
+
it('기준 상자의 긴 쪽을 기준으로 잡는다 — 3D 바닥 격자와 같아야 한다', () => {
|
|
255
|
+
expect(gridStep(DRAFT)).toBe(niceStep(3000))
|
|
251
256
|
})
|
|
252
257
|
})
|
package/translations/en.json
CHANGED
|
@@ -3,12 +3,7 @@
|
|
|
3
3
|
"figure.button.add-clip": "add clip",
|
|
4
4
|
"figure.button.add-key": "add key",
|
|
5
5
|
"figure.button.ask": "ask",
|
|
6
|
-
"figure.
|
|
7
|
-
"figure.text.proposal-feedback-note": "Optional note for the next suggestion (this session only)",
|
|
8
|
-
"figure.text.proposal-feedback-placeholder": "e.g. keep the silhouette, but make the port easier to read",
|
|
9
|
-
"figure.text.tools-explained": "Use alignment after setting position, size, and rotation. From left: centre X, centre Z, put on floor, mirror X, mirror Z, and snap to grid. Hover an icon to confirm its action.",
|
|
10
|
-
"figure.text.palette-purpose-explained": "Choose the visual role this part plays, not an implementation color name.",
|
|
11
|
-
"figure.button.attach-a-picture": "image",
|
|
6
|
+
"figure.button.cancel": "cancel",
|
|
12
7
|
"figure.button.center-x": "centre X",
|
|
13
8
|
"figure.button.center-z": "centre Z",
|
|
14
9
|
"figure.button.close": "close",
|
|
@@ -22,29 +17,30 @@
|
|
|
22
17
|
"figure.button.new-figure": "new figure",
|
|
23
18
|
"figure.button.pivot-clear": "part centre",
|
|
24
19
|
"figure.button.pivot-set": "set",
|
|
20
|
+
"figure.button.redo": "redo",
|
|
25
21
|
"figure.button.release-figure": "release",
|
|
26
22
|
"figure.button.remove": "remove",
|
|
27
23
|
"figure.button.remove-part": "delete",
|
|
28
24
|
"figure.button.reset-view": "reset",
|
|
29
25
|
"figure.button.revert": "revert",
|
|
30
26
|
"figure.button.save": "save",
|
|
31
|
-
"figure.button.undo": "undo",
|
|
32
|
-
"figure.button.redo": "redo",
|
|
33
27
|
"figure.button.see-the-trend-chart": "see the trend chart",
|
|
34
28
|
"figure.button.snap": "snap",
|
|
35
29
|
"figure.button.take-n-changes": "apply {n}",
|
|
36
30
|
"figure.button.to-floor": "to floor",
|
|
31
|
+
"figure.button.undo": "undo",
|
|
37
32
|
"figure.label.accepts": "accepts",
|
|
38
33
|
"figure.label.anchor": "holds which face",
|
|
34
|
+
"figure.label.anchor-advanced": "advanced proportional sizing",
|
|
39
35
|
"figure.label.anchor-aspect-x": "grows only as much as x does (keeps ratio)",
|
|
40
36
|
"figure.label.anchor-aspect-y": "grows only as much as y does (keeps ratio)",
|
|
41
37
|
"figure.label.anchor-aspect-z": "grows only as much as z does (keeps ratio)",
|
|
42
38
|
"figure.label.anchor-auto": "automatic ({rule})",
|
|
43
|
-
"figure.label.anchor-
|
|
44
|
-
"figure.label.anchor-choice-auto": "automatic",
|
|
39
|
+
"figure.label.anchor-center": "stays centred, keeps its size",
|
|
45
40
|
"figure.label.anchor-choice-aspect-x": "keep X ratio",
|
|
46
41
|
"figure.label.anchor-choice-aspect-y": "keep Y ratio",
|
|
47
42
|
"figure.label.anchor-choice-aspect-z": "keep Z ratio",
|
|
43
|
+
"figure.label.anchor-choice-auto": "automatic",
|
|
48
44
|
"figure.label.anchor-choice-center": "stay centred",
|
|
49
45
|
"figure.label.anchor-choice-max-x": "right face",
|
|
50
46
|
"figure.label.anchor-choice-max-y": "upper face",
|
|
@@ -54,7 +50,6 @@
|
|
|
54
50
|
"figure.label.anchor-choice-min-z": "back face",
|
|
55
51
|
"figure.label.anchor-choice-scale": "grow together",
|
|
56
52
|
"figure.label.anchor-choice-span": "fill both faces",
|
|
57
|
-
"figure.label.anchor-center": "stays centred, keeps its size",
|
|
58
53
|
"figure.label.anchor-max": "stays on the upper face",
|
|
59
54
|
"figure.label.anchor-max-x": "stays on the right face",
|
|
60
55
|
"figure.label.anchor-max-y": "stays on the top face",
|
|
@@ -66,6 +61,7 @@
|
|
|
66
61
|
"figure.label.anchor-scale": "grows with the box",
|
|
67
62
|
"figure.label.anchor-span": "touches both faces, fills between",
|
|
68
63
|
"figure.label.animation": "animation",
|
|
64
|
+
"figure.label.assumed-board": "the board it goes on",
|
|
69
65
|
"figure.label.axis-consistency": "visual consistency",
|
|
70
66
|
"figure.label.axis-consistency-short": "consistency",
|
|
71
67
|
"figure.label.axis-depth": "depth",
|
|
@@ -89,8 +85,10 @@
|
|
|
89
85
|
"figure.label.budget-transparent": "transparent materials",
|
|
90
86
|
"figure.label.budgets": "budgets",
|
|
91
87
|
"figure.label.by-axis": "maturity by axis",
|
|
88
|
+
"figure.label.candidate-review": "candidate review",
|
|
92
89
|
"figure.label.cast-shadow": "cast shadow",
|
|
93
90
|
"figure.label.category": "category",
|
|
91
|
+
"figure.label.ceiling-height": "ceiling height (mm)",
|
|
94
92
|
"figure.label.channel-path": "moves",
|
|
95
93
|
"figure.label.channel-pivot": "pivot",
|
|
96
94
|
"figure.label.channel-target": "part",
|
|
@@ -121,10 +119,7 @@
|
|
|
121
119
|
"figure.label.environment-sunny": "sunny",
|
|
122
120
|
"figure.label.environment-warehouse": "warehouse",
|
|
123
121
|
"figure.label.figure": "figure",
|
|
124
|
-
"figure.label.figure-placement": "
|
|
125
|
-
"figure.label.placement-floor": "floor-based (floor)",
|
|
126
|
-
"figure.label.placement-ceiling": "ceiling-based (ceiling)",
|
|
127
|
-
"figure.label.placement-center": "center-based (center)",
|
|
122
|
+
"figure.label.figure-placement": "placement",
|
|
128
123
|
"figure.label.figure-released": "released",
|
|
129
124
|
"figure.label.figure-type": "type",
|
|
130
125
|
"figure.label.findings": "findings",
|
|
@@ -150,8 +145,6 @@
|
|
|
150
145
|
"figure.label.none": "none",
|
|
151
146
|
"figure.label.now": "current",
|
|
152
147
|
"figure.label.on-by-default": "on by default",
|
|
153
|
-
"figure.label.palette-token": "palette token",
|
|
154
|
-
"figure.label.palette-role": "color role",
|
|
155
148
|
"figure.label.palette-purpose-accent": "accent part · handles and covers that must stand out",
|
|
156
149
|
"figure.label.palette-purpose-danger": "danger signal · an error or stop indicator",
|
|
157
150
|
"figure.label.palette-purpose-dark": "frame and shadow · dark structure and edges",
|
|
@@ -163,6 +156,8 @@
|
|
|
163
156
|
"figure.label.palette-purpose-success": "normal signal · a normal-operation indicator",
|
|
164
157
|
"figure.label.palette-purpose-surface": "surface and background · broad background faces",
|
|
165
158
|
"figure.label.palette-purpose-warning": "warning signal · an attention-needed indicator",
|
|
159
|
+
"figure.label.palette-role": "color role",
|
|
160
|
+
"figure.label.palette-token": "palette token",
|
|
166
161
|
"figure.label.part": "part",
|
|
167
162
|
"figure.label.part-material": "material",
|
|
168
163
|
"figure.label.part-position": "position (centre)",
|
|
@@ -172,6 +167,9 @@
|
|
|
172
167
|
"figure.label.path-scale": "scale",
|
|
173
168
|
"figure.label.path-translation": "offset",
|
|
174
169
|
"figure.label.placement": "position and size",
|
|
170
|
+
"figure.label.placement-ceiling": "ceiling-based (ceiling)",
|
|
171
|
+
"figure.label.placement-center": "center-based (center)",
|
|
172
|
+
"figure.label.placement-floor": "floor-based (floor)",
|
|
175
173
|
"figure.label.placement-limit": "placement limit",
|
|
176
174
|
"figure.label.preset": "preset",
|
|
177
175
|
"figure.label.preset-ceramic": "ceramic",
|
|
@@ -205,6 +203,10 @@
|
|
|
205
203
|
"figure.label.rung-none": "draws only",
|
|
206
204
|
"figure.label.same-as-off": "same as unlit",
|
|
207
205
|
"figure.label.scene-floor": "floor",
|
|
206
|
+
"figure.label.scene-reference": "scene reference",
|
|
207
|
+
"figure.label.scene-reference-floor": "floor",
|
|
208
|
+
"figure.label.scene-reference-inverted": "inverted (ceiling)",
|
|
209
|
+
"figure.label.scene-reference-space": "space",
|
|
208
210
|
"figure.label.segments": "segments",
|
|
209
211
|
"figure.label.shape": "shape",
|
|
210
212
|
"figure.label.shape-detail": "shape detail",
|
|
@@ -242,11 +244,6 @@
|
|
|
242
244
|
"figure.text.animation-empty-what-it-is": "This figure does not move yet. A clip is one set of motion across several parts — a door opening is the two leaves sliding apart, not two separate things.",
|
|
243
245
|
"figure.text.animation-is-driven-by-a-fact": "One clip moves several parts together. On a board a fact sets its value — “this door is 40% open”.",
|
|
244
246
|
"figure.text.animation-needs-a-named-part": "Add a part first. A channel names the part it moves.",
|
|
245
|
-
"figure.text.ask-create-example": "e.g. a three-tier conveyor sorter",
|
|
246
|
-
"figure.text.ask-revise-example": "e.g. bring it down to two material groups",
|
|
247
|
-
"figure.text.ask-to-create": "create",
|
|
248
|
-
"figure.text.ask-to-revise": "revise",
|
|
249
|
-
"figure.text.asking": "working…",
|
|
250
247
|
"figure.text.assistant-proposed-a-figure": "here is a proposal — the result is on the right.",
|
|
251
248
|
"figure.text.axes-not-measurable-yet": "axes that cannot be measured yet are left off the chart — {axes}. the reason is listed below.",
|
|
252
249
|
"figure.text.bound-by-drawCalls": "draw calls reach the limit first — {per} per instance, against {budget} for a board.",
|
|
@@ -258,13 +255,16 @@
|
|
|
258
255
|
"figure.text.capacity-from-repeat": "capacity comes from the repeat setting and the instance size",
|
|
259
256
|
"figure.text.category-explained": "how the palette groups figures. one per figure — a figure in two groups meets the author twice.",
|
|
260
257
|
"figure.text.category-placeholder": "e.g. conveyor",
|
|
258
|
+
"figure.text.ceiling-height-explained": "where a ceiling figure hangs from in the preview. A figure does not know how tall the room it goes in is.",
|
|
261
259
|
"figure.text.center-on-x": "move to the centre of the base box on X.",
|
|
262
260
|
"figure.text.center-on-z": "move to the centre of the base box on Z.",
|
|
263
261
|
"figure.text.change-added": "a new part",
|
|
264
|
-
"figure.text.change-
|
|
262
|
+
"figure.text.change-animations": "animations",
|
|
265
263
|
"figure.text.change-base": "the base size",
|
|
264
|
+
"figure.text.change-capabilities": "capabilities",
|
|
266
265
|
"figure.text.change-changed": "a changed part",
|
|
267
266
|
"figure.text.change-detail": "the detail level",
|
|
267
|
+
"figure.text.change-placement": "placement",
|
|
268
268
|
"figure.text.change-removed": "a part being removed",
|
|
269
269
|
"figure.text.change-styleKit": "the style kit",
|
|
270
270
|
"figure.text.channel-target-is-gone": "No such part. If you renamed the part, pick it again here.",
|
|
@@ -288,6 +288,7 @@
|
|
|
288
288
|
"figure.text.expand-parts-pane": "expand the part list",
|
|
289
289
|
"figure.text.expand-properties-pane": "expand the property pane",
|
|
290
290
|
"figure.text.figure-display-name": "display name",
|
|
291
|
+
"figure.text.figure-type-placeholder": "Figure type identifier (e.g. OHT)",
|
|
291
292
|
"figure.text.find-by-this-tag": "find by this tag",
|
|
292
293
|
"figure.text.fits-n-instances": "up to {n}",
|
|
293
294
|
"figure.text.floor-explained": "overlaps the coordinate ground, so usually off",
|
|
@@ -321,6 +322,7 @@
|
|
|
321
322
|
"figure.text.mirror-would-overlap": "already centred — a mirror would land in the same place and overlap.",
|
|
322
323
|
"figure.text.mode-edit-explained": "place and edit parts. always at the base size.",
|
|
323
324
|
"figure.text.mode-preview-explained": "how it looks placed on a board. base size next to the enlarged ones.",
|
|
325
|
+
"figure.text.more-segment-options": "advanced segment counts",
|
|
324
326
|
"figure.text.must-fix-to-release": "fix these first",
|
|
325
327
|
"figure.text.n-of-limit": "{used} / {limit}",
|
|
326
328
|
"figure.text.n-parts-at-most": "up to {limit} parts",
|
|
@@ -332,7 +334,7 @@
|
|
|
332
334
|
"figure.text.nothing-released-yet": "nothing released yet. releasing keeps the figure as it is now, as a version.",
|
|
333
335
|
"figure.text.on-by-default-explained": "the starting state when placed on a board. an instance switching it wins.",
|
|
334
336
|
"figure.text.other-segment-count": "enter a value",
|
|
335
|
-
"figure.text.
|
|
337
|
+
"figure.text.palette-purpose-explained": "Choose the visual role this part plays, not an implementation color name.",
|
|
336
338
|
"figure.text.part-limit-reached": "the detail level allows no more parts — raise the level or remove a part.",
|
|
337
339
|
"figure.text.part-limit-reached-short": "level {level} allows {limit} parts. Raise the level or remove a part.",
|
|
338
340
|
"figure.text.path-rotation-unit": "Euler degrees — the same convention as the part's own rotation.",
|
|
@@ -340,11 +342,12 @@
|
|
|
340
342
|
"figure.text.path-translation-unit": "Offset from where the part sits. 0 leaves it in place.",
|
|
341
343
|
"figure.text.pick-a-shape-above-to-start": "pick a shape above to add the first part.",
|
|
342
344
|
"figure.text.picked-changes-do-not-validate": "the selected changes do not make a valid figure",
|
|
343
|
-
"figure.text.picture-is-for-proportions": "used for proportions and form, not for surface detail.",
|
|
344
345
|
"figure.text.pivot-defaults-to-the-part-centre": "Left unset, the part turns about its own centre. Coordinates are local to the part.",
|
|
345
346
|
"figure.text.placement-explained": "sets the anchor plane in 3D scene (floor: AGV/conveyor, ceiling: OHT/hoist, center: sensor/drone).",
|
|
346
347
|
"figure.text.preview-blocked-by-errors": "cannot build — the figure breaks the format. the maturity tab has the reason.",
|
|
347
348
|
"figure.text.preview-needs-a-part": "shows how it looks placed on a board. appears once you make a part.",
|
|
349
|
+
"figure.text.proposal-feedback-note": "Optional note for the next suggestion (this session only)",
|
|
350
|
+
"figure.text.proposal-feedback-placeholder": "e.g. keep the silhouette, but make the port easier to read",
|
|
348
351
|
"figure.text.put-on-floor": "drop it to the floor (Z=0).",
|
|
349
352
|
"figure.text.release-needs-a-save-first": "there are unsaved changes. a release publishes what was saved, so save first.",
|
|
350
353
|
"figure.text.releasing": "releasing…",
|
|
@@ -362,8 +365,10 @@
|
|
|
362
365
|
"figure.text.rung-flow-note": "holds, and takes in and sends out through ports. conveyors, chutes, sorters",
|
|
363
366
|
"figure.text.rung-hold-note": "has places to put things. racks, pallets, benches",
|
|
364
367
|
"figure.text.rung-none-note": "takes nothing. most figures belong here",
|
|
368
|
+
"figure.text.save-new-figure-desc": "Set the unique type code and display name for this figure.",
|
|
365
369
|
"figure.text.save-the-figure-before-releasing": "this figure has not been saved yet. save it and you can release it.",
|
|
366
370
|
"figure.text.saving-figure": "saving",
|
|
371
|
+
"figure.text.scene-reference-explained": "which kind of board you are looking at this on. Not the same as the figure's own placement — put a ceiling figure on a floor-based board and the board stays put while the figure hangs at ceiling height.",
|
|
367
372
|
"figure.text.search-figure": "search by name, type, description, category or tag",
|
|
368
373
|
"figure.text.select-a-part-to-edit": "select a part to edit it here.",
|
|
369
374
|
"figure.text.show-all-parts": "show all",
|
|
@@ -378,6 +383,7 @@
|
|
|
378
383
|
"figure.text.tags-explained": "for the finding a single category cannot do. a figure may carry several — a conveyor that is also outbound. separate them with commas.",
|
|
379
384
|
"figure.text.tags-placeholder": "e.g. outbound, automatic, level 2",
|
|
380
385
|
"figure.text.thumbnail-not-made-yet": "no thumbnail yet",
|
|
386
|
+
"figure.text.tools-explained": "Use alignment after setting position, size, and rotation. From left: centre X, centre Z, put on floor, mirror X, mirror Z, and snap to grid. Hover an icon to confirm its action.",
|
|
381
387
|
"figure.text.triangle-count": "{count} triangles",
|
|
382
388
|
"figure.text.two-keys-at-least": "A channel needs two keys. With one it is not motion, it is a single pose.",
|
|
383
389
|
"figure.text.type-name-already-taken": "the type name {type} is already in use. pick another one — it cannot be changed later.",
|
|
@@ -387,9 +393,6 @@
|
|
|
387
393
|
"figure.text.view-settings-are-not-saved": "these settings are not saved. they make the view comfortable to work in and do not travel with the asset.",
|
|
388
394
|
"figure.text.what-a-figure-is": "a Figure is a 3D component you author. Compose it from simple shapes and it becomes a component you can place on a board, sharing shape and material across every instance.",
|
|
389
395
|
"figure.text.what-changed-in-this-release": "what changed in this release",
|
|
390
|
-
"figure.button.cancel": "cancel",
|
|
391
|
-
"figure.text.figure-type-placeholder": "Figure type identifier (e.g. OHT)",
|
|
392
|
-
"figure.text.save-new-figure-desc": "Set the unique type code and display name for this figure.",
|
|
393
396
|
"figure.title.figures": "figures",
|
|
394
397
|
"figure.title.new-figure": "new figure",
|
|
395
398
|
"figure.title.save-new-figure": "save figure draft"
|
package/translations/ja.json
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"figure.button.ask": "ask",
|
|
3
|
-
"figure.label.candidate-review": "candidate review",
|
|
4
|
-
"figure.text.proposal-feedback-note": "Optional note for the next suggestion (this session only)",
|
|
5
|
-
"figure.text.proposal-feedback-placeholder": "e.g. keep the silhouette, but make the port easier to read",
|
|
6
|
-
"figure.text.tools-explained": "Use alignment after setting position, size, and rotation. From left: centre X, centre Z, put on floor, mirror X, mirror Z, and snap to grid. Hover an icon to confirm its action.",
|
|
7
|
-
"figure.text.palette-purpose-explained": "Choose the visual role this part plays, not an implementation color name.",
|
|
8
|
-
"figure.button.attach-a-picture": "image",
|
|
9
3
|
"figure.button.center-x": "centre X",
|
|
10
4
|
"figure.button.center-z": "centre Z",
|
|
11
5
|
"figure.button.close": "close",
|
|
@@ -17,27 +11,28 @@
|
|
|
17
11
|
"figure.button.move-part-down": "move down",
|
|
18
12
|
"figure.button.move-part-up": "move up",
|
|
19
13
|
"figure.button.new-figure": "new figure",
|
|
14
|
+
"figure.button.redo": "やり直す",
|
|
20
15
|
"figure.button.release-figure": "公開する",
|
|
21
16
|
"figure.button.remove-part": "delete",
|
|
22
17
|
"figure.button.reset-view": "reset",
|
|
23
18
|
"figure.button.revert": "戻す",
|
|
24
19
|
"figure.button.save": "save",
|
|
25
|
-
"figure.button.undo": "元に戻す",
|
|
26
|
-
"figure.button.redo": "やり直す",
|
|
27
20
|
"figure.button.see-the-trend-chart": "see the trend chart",
|
|
28
21
|
"figure.button.snap": "snap",
|
|
29
22
|
"figure.button.take-n-changes": "apply {n}",
|
|
30
23
|
"figure.button.to-floor": "to floor",
|
|
24
|
+
"figure.button.undo": "元に戻す",
|
|
31
25
|
"figure.label.anchor": "つかむ面",
|
|
26
|
+
"figure.label.anchor-advanced": "advanced proportional sizing",
|
|
32
27
|
"figure.label.anchor-aspect-x": "x 軸が大きくなる分だけ大きくなる (比率維持)",
|
|
33
28
|
"figure.label.anchor-aspect-y": "y 軸が大きくなる分だけ大きくなる (比率維持)",
|
|
34
29
|
"figure.label.anchor-aspect-z": "z 軸が大きくなる分だけ大きくなる (比率維持)",
|
|
35
30
|
"figure.label.anchor-auto": "自動 ({rule})",
|
|
36
|
-
"figure.label.anchor-
|
|
37
|
-
"figure.label.anchor-choice-auto": "automatic",
|
|
31
|
+
"figure.label.anchor-center": "中央に残り大きさはそのまま",
|
|
38
32
|
"figure.label.anchor-choice-aspect-x": "keep X ratio",
|
|
39
33
|
"figure.label.anchor-choice-aspect-y": "keep Y ratio",
|
|
40
34
|
"figure.label.anchor-choice-aspect-z": "keep Z ratio",
|
|
35
|
+
"figure.label.anchor-choice-auto": "automatic",
|
|
41
36
|
"figure.label.anchor-choice-center": "stay centred",
|
|
42
37
|
"figure.label.anchor-choice-max-x": "right face",
|
|
43
38
|
"figure.label.anchor-choice-max-y": "upper face",
|
|
@@ -47,7 +42,6 @@
|
|
|
47
42
|
"figure.label.anchor-choice-min-z": "back face",
|
|
48
43
|
"figure.label.anchor-choice-scale": "grow together",
|
|
49
44
|
"figure.label.anchor-choice-span": "fill both faces",
|
|
50
|
-
"figure.label.anchor-center": "中央に残り大きさはそのまま",
|
|
51
45
|
"figure.label.anchor-max": "大きい側の面にくっついている",
|
|
52
46
|
"figure.label.anchor-max-x": "右の面にくっついている",
|
|
53
47
|
"figure.label.anchor-max-y": "上の面にくっついている",
|
|
@@ -81,6 +75,7 @@
|
|
|
81
75
|
"figure.label.budget-transparent": "transparent materials",
|
|
82
76
|
"figure.label.budgets": "budgets",
|
|
83
77
|
"figure.label.by-axis": "maturity by axis",
|
|
78
|
+
"figure.label.candidate-review": "candidate review",
|
|
84
79
|
"figure.label.cast-shadow": "cast shadow",
|
|
85
80
|
"figure.label.coordinate-ground": "coordinate ground",
|
|
86
81
|
"figure.label.corner-round": "corner round",
|
|
@@ -127,8 +122,6 @@
|
|
|
127
122
|
"figure.label.none": "none",
|
|
128
123
|
"figure.label.now": "current",
|
|
129
124
|
"figure.label.on-by-default": "on by default",
|
|
130
|
-
"figure.label.palette-token": "palette token",
|
|
131
|
-
"figure.label.palette-role": "color role",
|
|
132
125
|
"figure.label.palette-purpose-accent": "accent part · handles and covers that must stand out",
|
|
133
126
|
"figure.label.palette-purpose-danger": "danger signal · an error or stop indicator",
|
|
134
127
|
"figure.label.palette-purpose-dark": "frame and shadow · dark structure and edges",
|
|
@@ -140,6 +133,8 @@
|
|
|
140
133
|
"figure.label.palette-purpose-success": "normal signal · a normal-operation indicator",
|
|
141
134
|
"figure.label.palette-purpose-surface": "surface and background · broad background faces",
|
|
142
135
|
"figure.label.palette-purpose-warning": "warning signal · an attention-needed indicator",
|
|
136
|
+
"figure.label.palette-role": "color role",
|
|
137
|
+
"figure.label.palette-token": "palette token",
|
|
143
138
|
"figure.label.part": "part",
|
|
144
139
|
"figure.label.part-material": "material",
|
|
145
140
|
"figure.label.part-position": "position (centre)",
|
|
@@ -194,11 +189,6 @@
|
|
|
194
189
|
"figure.text.all-lights-off": "both lights are off. only self-lit surfaces show; everything else goes black — this is how you check whether a lamp is lit.",
|
|
195
190
|
"figure.text.already-released-edit-to-release-again": "すでに公開済みです。修正して保存すると下書きに戻り、そこで再び公開できます。",
|
|
196
191
|
"figure.text.anchor-explained": "箱が大きくなるとき、この部品がどこにくっついているかです。接している部品と違う面にくっついていると、大きくなるにつれて離れます。",
|
|
197
|
-
"figure.text.ask-create-example": "e.g. a three-tier conveyor sorter",
|
|
198
|
-
"figure.text.ask-revise-example": "e.g. bring it down to two material groups",
|
|
199
|
-
"figure.text.ask-to-create": "create",
|
|
200
|
-
"figure.text.ask-to-revise": "revise",
|
|
201
|
-
"figure.text.asking": "working…",
|
|
202
192
|
"figure.text.assistant-proposed-a-figure": "here is a proposal — the result is on the right.",
|
|
203
193
|
"figure.text.axes-not-measurable-yet": "axes that cannot be measured yet are left off the chart — {axes}. the reason is listed below.",
|
|
204
194
|
"figure.text.bound-by-drawCalls": "draw calls reach the limit first — {per} per instance, against {budget} for a board.",
|
|
@@ -209,10 +199,12 @@
|
|
|
209
199
|
"figure.text.center-on-x": "move to the centre of the base box on X.",
|
|
210
200
|
"figure.text.center-on-z": "move to the centre of the base box on Z.",
|
|
211
201
|
"figure.text.change-added": "a new part",
|
|
212
|
-
"figure.text.change-
|
|
202
|
+
"figure.text.change-animations": "アニメーション",
|
|
213
203
|
"figure.text.change-base": "the base size",
|
|
204
|
+
"figure.text.change-capabilities": "能力",
|
|
214
205
|
"figure.text.change-changed": "a changed part",
|
|
215
206
|
"figure.text.change-detail": "the detail level",
|
|
207
|
+
"figure.text.change-placement": "配置基準",
|
|
216
208
|
"figure.text.change-removed": "a part being removed",
|
|
217
209
|
"figure.text.change-styleKit": "the style kit",
|
|
218
210
|
"figure.text.collapse-parts-pane": "collapse the part list",
|
|
@@ -258,6 +250,7 @@
|
|
|
258
250
|
"figure.text.mirror-would-overlap": "already centred — a mirror would land in the same place and overlap.",
|
|
259
251
|
"figure.text.mode-edit-explained": "place and edit parts. always at the base size.",
|
|
260
252
|
"figure.text.mode-preview-explained": "how it looks placed on a board. base size next to the enlarged ones.",
|
|
253
|
+
"figure.text.more-segment-options": "advanced segment counts",
|
|
261
254
|
"figure.text.must-fix-to-release": "直すべきもの",
|
|
262
255
|
"figure.text.n-of-limit": "{used} / {limit}",
|
|
263
256
|
"figure.text.n-parts-at-most": "up to {limit} parts",
|
|
@@ -269,14 +262,15 @@
|
|
|
269
262
|
"figure.text.nothing-released-yet": "まだ公開した版がありません。公開すると、その時点のフィギュアが版として残ります。",
|
|
270
263
|
"figure.text.on-by-default-explained": "the starting state when placed on a board. an instance switching it wins.",
|
|
271
264
|
"figure.text.other-segment-count": "enter a value",
|
|
272
|
-
"figure.text.
|
|
265
|
+
"figure.text.palette-purpose-explained": "Choose the visual role this part plays, not an implementation color name.",
|
|
273
266
|
"figure.text.part-limit-reached": "the detail level allows no more parts — raise the level or remove a part.",
|
|
274
267
|
"figure.text.part-limit-reached-short": "level {level} allows {limit} parts. Raise the level or remove a part.",
|
|
275
268
|
"figure.text.pick-a-shape-above-to-start": "pick a shape above to add the first part.",
|
|
276
269
|
"figure.text.picked-changes-do-not-validate": "the selected changes do not make a valid figure",
|
|
277
|
-
"figure.text.picture-is-for-proportions": "used for proportions and form, not for surface detail.",
|
|
278
270
|
"figure.text.preview-blocked-by-errors": "cannot build — the figure breaks the format. the maturity tab has the reason.",
|
|
279
271
|
"figure.text.preview-needs-a-part": "add a part and the board view appears here.",
|
|
272
|
+
"figure.text.proposal-feedback-note": "Optional note for the next suggestion (this session only)",
|
|
273
|
+
"figure.text.proposal-feedback-placeholder": "e.g. keep the silhouette, but make the port easier to read",
|
|
280
274
|
"figure.text.put-on-floor": "drop it to the floor (Z=0).",
|
|
281
275
|
"figure.text.release-needs-a-save-first": "保存していない変更があります。公開は保存されたものを出すので、先に保存してください。",
|
|
282
276
|
"figure.text.releasing": "公開しています…",
|
|
@@ -299,6 +293,7 @@
|
|
|
299
293
|
"figure.text.sizing-stretch-explained": "only one axis stretches — like a frame, a belt or a rail.",
|
|
300
294
|
"figure.text.snap-explained": "rounds position and size to the grid — the same spacing you see on the canvas.",
|
|
301
295
|
"figure.text.thumbnail-not-made-yet": "no thumbnail yet",
|
|
296
|
+
"figure.text.tools-explained": "Use alignment after setting position, size, and rotation. From left: centre X, centre Z, put on floor, mirror X, mirror Z, and snap to grid. Hover an icon to confirm its action.",
|
|
302
297
|
"figure.text.triangle-count": "{count} triangles",
|
|
303
298
|
"figure.text.type-name-already-taken": "the type name {type} is already in use. pick another one — it cannot be changed later.",
|
|
304
299
|
"figure.text.type-name-cannot-change": "the type name is a stored identifier and cannot be changed after creation.",
|