@things-factory/figure-ui 10.1.73 → 10.1.75
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/v3-editor.ts +105 -10
- package/client/modeller/v3-refusals.ts +62 -13
- package/dist-client/modeller/v3-clips.d.ts +1 -1
- package/dist-client/modeller/v3-editor.d.ts +14 -0
- package/dist-client/modeller/v3-editor.js +107 -9
- package/dist-client/modeller/v3-editor.js.map +1 -1
- package/dist-client/modeller/v3-product-session.d.ts +31 -0
- package/dist-client/modeller/v3-refusals.d.ts +37 -5
- package/dist-client/modeller/v3-refusals.js +59 -16
- package/dist-client/modeller/v3-refusals.js.map +1 -1
- package/dist-client/tsconfig.fui.tsbuildinfo +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/test/browser/modeller-page.js +14 -0
- package/test/browser/modeller.check.mjs +40 -2
- package/test/v3-parts-wiring.test.ts +6 -2
- package/test/v3-recipes.test.ts +1 -1
- package/test/v3-refusals.test.ts +35 -5
- package/translations/en.json +19 -5
- package/translations/ja.json +19 -5
- package/translations/ko.json +19 -5
- package/translations/ms.json +19 -5
- package/translations/zh.json +19 -5
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.75",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"@things-factory:registry": "https://registry.npmjs.org"
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"clean": "npm run clean:server && npm run clean:client"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@hatiolab/figure-model": "^0.1.
|
|
31
|
-
"@hatiolab/things-scene": "^10.1.
|
|
30
|
+
"@hatiolab/figure-model": "^0.1.92",
|
|
31
|
+
"@hatiolab/things-scene": "^10.1.60",
|
|
32
32
|
"@material/web": "^2.0.0",
|
|
33
33
|
"@operato/data-grist": "^10.0.0",
|
|
34
34
|
"@operato/graphql": "^10.0.0",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"@operato/styles": "^10.0.0",
|
|
42
42
|
"@operato/utils": "^10.0.0",
|
|
43
43
|
"@things-factory/ai-assistant": "^10.1.58",
|
|
44
|
-
"@things-factory/figure-service": "^10.1.
|
|
44
|
+
"@things-factory/figure-service": "^10.1.75",
|
|
45
45
|
"three": "^0.185.1"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "931154ec5ab1b4d3bd2530a9a689363157f21f5f"
|
|
48
48
|
}
|
|
@@ -154,6 +154,20 @@ window.probe = {
|
|
|
154
154
|
const l = Math.hypot(b.x - a.x, b.y - a.y) || 1
|
|
155
155
|
return { x: (b.x - a.x) / l, y: (b.y - a.y) / l }
|
|
156
156
|
},
|
|
157
|
+
/** The page point of an input or checkbox by its aria-label. */
|
|
158
|
+
labelled(label) {
|
|
159
|
+
const input = deep('input').find(i => i.getAttribute('aria-label') === label)
|
|
160
|
+
return input ? centreOf(input) : null
|
|
161
|
+
},
|
|
162
|
+
/** The page point of a button by an attribute it carries. */
|
|
163
|
+
button(attribute) {
|
|
164
|
+
const b = deep(`button[${attribute}]`)[0]
|
|
165
|
+
return b ? { ...centreOf(b), disabled: b.disabled } : null
|
|
166
|
+
},
|
|
167
|
+
/** The figure as the session holds it. */
|
|
168
|
+
source() {
|
|
169
|
+
return JSON.parse(editor().session.source())
|
|
170
|
+
},
|
|
157
171
|
/** The ids of every body drawn. */
|
|
158
172
|
ids() {
|
|
159
173
|
return editor().session.read().geometry.map(g => g.id)
|
|
@@ -743,7 +743,7 @@ describe('the recipe catalog: a template chosen, filled in, put onto the chosen
|
|
|
743
743
|
assert.equal(await at('figure-v3-recipe-catalog'), null, 'the catalog closes')
|
|
744
744
|
})
|
|
745
745
|
|
|
746
|
-
test('a door the room cannot take is refused in the catalog,
|
|
746
|
+
test('a door the room cannot take is refused in the catalog, with the step it stopped at, and nothing is added', async () => {
|
|
747
747
|
await click(await read(() => probe.row('room')))
|
|
748
748
|
await click(await at('button[recipe-catalog]'))
|
|
749
749
|
await click(await at('button[card="sliding-door"]'))
|
|
@@ -754,11 +754,49 @@ describe('the recipe catalog: a template chosen, filled in, put onto the chosen
|
|
|
754
754
|
assert.equal((await state()).revision, start.revision, 'no step')
|
|
755
755
|
assert.deepEqual(await parts(), before, 'nothing added')
|
|
756
756
|
const said = await at('section[detail] p[role="alert"]')
|
|
757
|
-
|
|
757
|
+
/* The step it stopped at and the kernel's code -- not the kernel's English (2026-09-27). */
|
|
758
|
+
assert.ok(said && /recipe-step-refused|단계|step/i.test(said.text) && /\([A-Z_]+\)/.test(said.text) && !/steps\[/.test(said.text), `the step and the code, in words: ${said?.text}`)
|
|
758
759
|
await click(await at('button[close]'))
|
|
759
760
|
})
|
|
760
761
|
})
|
|
761
762
|
|
|
763
|
+
describe('a row\'s pitch made a board\'s to set (ADR-0096)', () => {
|
|
764
|
+
const typeInto = async (label, text) => {
|
|
765
|
+
const at = await read(l => probe.labelled(l), label)
|
|
766
|
+
assert.ok(at, `the field ${label}`)
|
|
767
|
+
await page().mouse.click(at.x, at.y, { clickCount: 3 })
|
|
768
|
+
await page().keyboard.type(text)
|
|
769
|
+
await page().keyboard.press('Tab')
|
|
770
|
+
await sleep(400)
|
|
771
|
+
}
|
|
772
|
+
test('published in one step with a name and a range; the pitch then sets the input; withdrawn, the pitch stays as it is', async () => {
|
|
773
|
+
await mount('rollers')
|
|
774
|
+
await click(await read(() => probe.row('roller')))
|
|
775
|
+
const before = (await read(() => probe.ids())).filter(id => id.includes('"roller.placed"')).length
|
|
776
|
+
await click(await read(() => probe.labelled('figure.label.board-sets')))
|
|
777
|
+
await typeInto('figure.label.board-name', '롤러 간격')
|
|
778
|
+
await typeInto('figure.label.least', '100')
|
|
779
|
+
await typeInto('figure.label.most', '400')
|
|
780
|
+
const start = await state()
|
|
781
|
+
await click(await read(() => probe.button('publish-pitch')))
|
|
782
|
+
assert.equal((await state()).revision, start.revision + 1, 'one step')
|
|
783
|
+
let source = await read(() => probe.source())
|
|
784
|
+
assert.deepEqual(source.publicInputs, [{ input: 'roller.pitch', label: '롤러 간격' }])
|
|
785
|
+
const input = source.document.model.inputs.find(i => i.id === 'roller.pitch')
|
|
786
|
+
assert.deepEqual([input.min, input.max, source.designInputs['roller.pitch']], [100, 400, 200])
|
|
787
|
+
assert.deepEqual(source.joints.find(j => j.body1.part === 'roller').repeat.pitch, { from: { of: 'input', input: 'roller.pitch' } })
|
|
788
|
+
assert.equal((await read(() => probe.ids())).filter(id => id.includes('"roller.placed"')).length, before, 'the row as it was')
|
|
789
|
+
await typeInto('roller.repeat.pitch', '400')
|
|
790
|
+
source = await read(() => probe.source())
|
|
791
|
+
assert.equal(source.designInputs['roller.pitch'], 400, 'the pitch field sets the input')
|
|
792
|
+
assert.ok((await read(() => probe.ids())).filter(id => id.includes('"roller.placed"')).length < before, 'fewer rollers at a wider pitch')
|
|
793
|
+
await click(await read(() => probe.labelled('figure.label.board-sets')))
|
|
794
|
+
source = await read(() => probe.source())
|
|
795
|
+
assert.equal(source.publicInputs, undefined, 'withdrawn')
|
|
796
|
+
assert.equal(source.joints.find(j => j.body1.part === 'roller').repeat.pitch, 400, 'the pitch stays as it is')
|
|
797
|
+
})
|
|
798
|
+
})
|
|
799
|
+
|
|
762
800
|
describe('a row that carries a part (ADR-0093, 2026-09-26)', () => {
|
|
763
801
|
test('the list has the roller and its mark, each once; a click on a mark on the canvas picks the mark, and only the roller offers the row', async () => {
|
|
764
802
|
await mount('rollers')
|
|
@@ -36,13 +36,17 @@ test('작업대에서 가린 부품은 캔버스에서 빠지고, 다른 도형
|
|
|
36
36
|
assert.match(reset, /this\.hiddenParts = new Set\(\)/)
|
|
37
37
|
})
|
|
38
38
|
|
|
39
|
-
test('지울 수 없는 부품은 사람의 말로
|
|
39
|
+
test('지울 수 없는 부품은 사람의 말로 거절하고, 지우며 풀어 준 것은 사람의 말로 알린다 — 다섯 말 모두', () => {
|
|
40
40
|
/* Since 2026-09-25 the reason is told apart (partRefusalOf, tested in v3-refusals); the editor hands the refusal to it. */
|
|
41
41
|
assert.match(editor, /private removePart[\s\S]*?partRefusalOf\(error, id,/)
|
|
42
|
+
assert.match(editor, /private removePart[\s\S]*?this\.notice = removalNoticeOf\(view\.removal,/, '지운 뒤 풀어 준 것을 알린다')
|
|
42
43
|
for (const lang of ['ko', 'en', 'ja', 'zh', 'ms']) {
|
|
43
44
|
const table = JSON.parse(read(`../translations/${lang}.json`))
|
|
44
|
-
for (const key of ['part-is-referenced', 'part-
|
|
45
|
+
for (const key of ['part-is-referenced', 'part-in-declared-space', 'part-row-along', 'part-row-carries'])
|
|
45
46
|
assert.ok(table[`figure.text.${key}`]?.includes('{part}'), `${lang} ${key}`)
|
|
47
|
+
/* What a removal let go of, in every language, with the names it carries. */
|
|
48
|
+
for (const [key, word] of [['removal-released', '{parts}'], ['removal-released-motion', '{control}'], ['removal-own-control', '{max}'], ['removal-fixed', '{parts}'], ['removal-bindings', '{places}'], ['edit-refused', '{code}'], ['edit-refused-node-limit', '{max}']])
|
|
49
|
+
assert.ok(table[`figure.text.${key}`]?.includes(word), `${lang} ${key}`)
|
|
46
50
|
}
|
|
47
51
|
})
|
|
48
52
|
|
package/test/v3-recipes.test.ts
CHANGED
|
@@ -67,7 +67,7 @@ test('모델러 — 부품 칸의 단추가 카탈로그를 열고, 넣으면
|
|
|
67
67
|
const editor = read('../client/modeller/v3-editor.ts')
|
|
68
68
|
const insert = editor.slice(editor.indexOf(' private insertRecipe('), editor.indexOf(' /** The design values of the asset being edited. */'))
|
|
69
69
|
assert.ok(insert.includes('v3RecipeIdFor(asset, checked)') && insert.includes('this.session!.applyRecipe(steps)') && insert.includes('this.catalogOpen = false'))
|
|
70
|
-
assert.ok(insert.includes('this.recipeError = error
|
|
70
|
+
assert.ok(insert.includes('this.recipeError = recipeRefusalOf(error, (key, params) => i18next.t(key, params)) ?? this.said(error)'), '거절은 사람의 말로, 막힌 단계와 함께 — 커널의 영어가 아니라 (2026-09-27)')
|
|
71
71
|
const page = read('../client/pages/figure-v3-modeller-page.ts')
|
|
72
72
|
assert.ok(page.includes("availableRecipes(i18next.language || 'en')") && page.includes('.templates=${this.templates}'))
|
|
73
73
|
const catalog = read('../client/modeller/figure-v3-recipe-catalog.ts')
|
package/test/v3-refusals.test.ts
CHANGED
|
@@ -48,8 +48,8 @@ test('범위가 받을 수 없는 연결은 같은 연결을 범위를 좁혀
|
|
|
48
48
|
assert.equal(narrowingRetryOf({ kind: 'attach' }, error, say), null, '연결이 아닌 명령에는 권하지 않는다')
|
|
49
49
|
})
|
|
50
50
|
|
|
51
|
-
test('
|
|
52
|
-
const { partRefusalOf } = await import('../client/modeller/v3-refusals.ts')
|
|
51
|
+
test('지우기는 매단 것 · 따라 움직이는 것을 풀어 남기고 그 이름을 한 줄로 말한다; 남는 거절은 공간 선언과 줄 (아키텍트 판정 2026-09-27)', async () => {
|
|
52
|
+
const { partRefusalOf, removalNoticeOf, editRefusalOf } = await import('../client/modeller/v3-refusals.ts')
|
|
53
53
|
const fm = await import('@hatiolab/figure-model')
|
|
54
54
|
const say = (key: string, p: Record<string, string>) => `${key} ${JSON.stringify(p)}`
|
|
55
55
|
let a = fm.createV3Asset('Bench')
|
|
@@ -64,6 +64,16 @@ test('부품을 못 지우는 까닭을 넷으로 가려 말한다 — 매단
|
|
|
64
64
|
const turn = (asset: typeof a, part: string, extra: object) => fm.applyV3Authoring(asset, { kind: 'set-joint', joint: { ...asset.joints!.find(j => j.body1.part === part)!, type: 'revolute', axis: 'Y', ...extra } as never })
|
|
65
65
|
a = turn(a, 'lamp', { state: { id: 'lamp-turn' } })
|
|
66
66
|
a = turn(a, 'shade', { mimic: { joint: 'lamp', multiplier: 1 } })
|
|
67
|
+
|
|
68
|
+
const top = fm.removePart(a, { kind: 'remove-part', target: 'top' })
|
|
69
|
+
const told = removalNoticeOf(top.notice, say)!
|
|
70
|
+
assert.match(told, /removal-released-motion .*"part":"lamp".*"control":"lamp-turn"/, '움직이던 것은 조작값 이름까지')
|
|
71
|
+
assert.match(told, /removal-released .*"parts":"shade"/)
|
|
72
|
+
const lamp = removalNoticeOf(fm.removePart(a, { kind: 'remove-part', target: 'lamp' }).notice, say)!
|
|
73
|
+
assert.match(lamp, /removal-own-control .*"part":"shade".*"control":"shade".*"min":"-180".*"max":"180"/, '따르던 것은 제 조작값을 받는다')
|
|
74
|
+
assert.equal(removalNoticeOf(fm.removePart(a, { kind: 'remove-part', target: 'shade' }).notice, say), null, '아무것도 풀지 않았으면 말하지 않는다')
|
|
75
|
+
|
|
76
|
+
const declared = fm.applyV3Authoring(a, { kind: 'declare-occupancy', proposal: fm.proposeV3Occupancy(a), placement: 'floor' })
|
|
67
77
|
const why = (asset: typeof a, part: string) => {
|
|
68
78
|
try {
|
|
69
79
|
fm.editV3Part(asset, { kind: 'remove-part', target: part })
|
|
@@ -72,10 +82,20 @@ test('부품을 못 지우는 까닭을 넷으로 가려 말한다 — 매단
|
|
|
72
82
|
return partRefusalOf(e, part, say)
|
|
73
83
|
}
|
|
74
84
|
}
|
|
75
|
-
assert.match(why(a, 'top')!, /part-holds-others .*"others":"lamp, shade"/)
|
|
76
|
-
assert.match(why(a, 'lamp')!, /part-is-led .*"others":"shade"/)
|
|
77
|
-
const declared = fm.applyV3Authoring(a, { kind: 'declare-occupancy', proposal: fm.proposeV3Occupancy(a), placement: 'floor' })
|
|
78
85
|
assert.match(why(declared, 'shade')!, /part-in-declared-space .*"part":"shade"/, '잎인데 공간 선언에 들어 있다')
|
|
86
|
+
|
|
87
|
+
let row = fm.createV3Asset('Conveyor')
|
|
88
|
+
row = fm.addV3Box(row, { id: 'frame', size: { x: 2000, y: 100, z: 600 }, position: { x: 0, y: 0, z: 0 } })
|
|
89
|
+
row = fm.addV3Box(row, { id: 'roller', size: { x: 60, y: 60, z: 560 }, position: { x: 0, y: 0, z: 0 } })
|
|
90
|
+
row = fm.applyV3Authoring(row, { kind: 'attach', part: 'frame', face: 'bottom', to: { plane: 'mounting-plane' } })
|
|
91
|
+
row = fm.applyV3Authoring(row, { kind: 'attach', part: 'roller', face: 'bottom', to: { part: 'frame', face: 'top' } })
|
|
92
|
+
row = fm.applyV3Authoring(row, { kind: 'make-repeat', part: 'roller', axis: 'x', pitch: 200 })
|
|
93
|
+
assert.match(why(row, 'frame')!, /part-row-along .*"part":"frame".*"rows":"roller"/, '줄이 따라 놓인 부품')
|
|
94
|
+
|
|
95
|
+
/* A refusal no sentence knows is still said as a refusal, with its code -- never the kernel's English. */
|
|
96
|
+
const unknown = editRefusalOf(Object.assign(new Error('EDIT_TARGET: x: something in English'), { code: 'EDIT_TARGET' }), say)
|
|
97
|
+
assert.match(unknown, /^figure\.text\.edit-refused .*"code":"EDIT_TARGET"/)
|
|
98
|
+
assert.doesNotMatch(unknown, /something in English/)
|
|
79
99
|
})
|
|
80
100
|
|
|
81
101
|
test('공간 선언에 든 부품 — 지우고 공간을 남은 부품에 맞추는 길을 한 번에 권한다(차단기의 떠도는 상자, 09-25)', async () => {
|
|
@@ -134,3 +154,13 @@ test('범위 밖 값은 받을 수 있는 범위를 숫자로 말한다 — 커
|
|
|
134
154
|
assert.equal(inputRangeRefusalOf(range('INPUT_RANGE: steps: at the length it is authored (100 mm) a pitch under 1 mm makes more than 50 copies'), say), null)
|
|
135
155
|
assert.equal(inputRangeRefusalOf(Object.assign(new Error('x'), { code: 'EDIT_TARGET' }), say), null)
|
|
136
156
|
})
|
|
157
|
+
|
|
158
|
+
test('레시피가 막히면 몇 번째 단계에서 왜 막혔는지 사람의 말로 — 커널의 영어가 아니라 (2026-09-27)', async () => {
|
|
159
|
+
const { recipeRefusalOf } = await import('../client/modeller/v3-refusals.ts')
|
|
160
|
+
const say = (key: string, p: Record<string, string>) => `${key} ${JSON.stringify(p)}`
|
|
161
|
+
const refusal = Object.assign(new Error('EDIT_TARGET: steps[2]: attach: door is wider than the opening'), { code: 'EDIT_TARGET', path: 'steps[2]' })
|
|
162
|
+
const told = recipeRefusalOf(refusal, say)!
|
|
163
|
+
assert.match(told, /^figure\.text\.recipe-step-refused .*"step":"3".*"code":"EDIT_TARGET"/, '셋째 단계, 코드와 함께')
|
|
164
|
+
assert.doesNotMatch(told, /wider than/)
|
|
165
|
+
assert.equal(recipeRefusalOf(Object.assign(new Error('x'), { code: 'SCHEMA', path: 'steps' }), say), null, '단계가 아닌 거절은 다른 말이 맡는다')
|
|
166
|
+
})
|
package/translations/en.json
CHANGED
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"figure.text.input-range-size": "figure size {axis} can only be set between {min} and {max} mm. value given: {value} mm",
|
|
74
74
|
"figure.text.input-range": "this value can only be set between {min} and {max}. value given: {value}",
|
|
75
75
|
"figure.text.mounting-face-needs-space": "declare the space first to choose one.",
|
|
76
|
-
"figure.text.part-is-referenced": "'{part}' cannot be deleted: another part
|
|
76
|
+
"figure.text.part-is-referenced": "'{part}' cannot be deleted: another part uses its values as they are.",
|
|
77
77
|
"figure.text.part-name-invalid": "'{name}' cannot be a part name. Start with a letter and use letters, digits, - and _.",
|
|
78
78
|
"figure.text.part-name-taken": "'{name}' is already used in this figure.",
|
|
79
79
|
"figure.text.placement-redeclares": "changing it declares the space again from the parts as they are now.",
|
|
@@ -632,10 +632,7 @@
|
|
|
632
632
|
"figure.button.narrow-range-from": "narrow {axis} to {mm} mm and up, and link",
|
|
633
633
|
"figure.text.link-needs-larger-range": "with this link the figure cannot be drawn when its {axis} is over {mm} mm, and the declared sizes go above that.",
|
|
634
634
|
"figure.button.narrow-range-to": "narrow {axis} to {mm} mm and under, and link",
|
|
635
|
-
"figure.text.part-holds-others": "'{part}' holds {others}; take them off first.",
|
|
636
635
|
"figure.text.part-in-declared-space": "'{part}' is in the declared space, so it cannot simply be deleted. it can be deleted with the space fitted to the parts left.",
|
|
637
|
-
"figure.text.part-is-followed": "{others} follow the size or place of '{part}'; make them their own numbers first.",
|
|
638
|
-
"figure.text.part-is-led": "{others} move with '{part}'; give them their own control first.",
|
|
639
636
|
"figure.button.change-motion": "change the motion",
|
|
640
637
|
"figure.button.apply-motion-change": "apply the change",
|
|
641
638
|
"figure.button.cancel-motion-change": "leave it",
|
|
@@ -649,5 +646,22 @@
|
|
|
649
646
|
"figure.text.placement-plane-refused": "{parts} cannot go on a {placement} by the face fastened to the mounting plane. detach it or fasten it by its {faces} first.",
|
|
650
647
|
"figure.label.face-centre": "centre",
|
|
651
648
|
"figure.label.budget-moving": "parts recomputed every frame",
|
|
652
|
-
"figure.label.performance-cost": "performance cost"
|
|
649
|
+
"figure.label.performance-cost": "performance cost",
|
|
650
|
+
"figure.label.board-sets": "a board may change it",
|
|
651
|
+
"figure.label.board-name": "name on the board",
|
|
652
|
+
"figure.label.least": "least",
|
|
653
|
+
"figure.label.most": "most",
|
|
654
|
+
"figure.button.publish-input": "publish to boards",
|
|
655
|
+
"figure.button.apply": "apply",
|
|
656
|
+
"figure.text.part-row-along": "The row {rows} is laid along '{part}', so '{part}' cannot be deleted. Fasten the row to another part, or undo the repeat, first.",
|
|
657
|
+
"figure.text.part-row-carries": "{others} hangs on every copy of the row '{part}'; take it off first.",
|
|
658
|
+
"figure.text.removal-released": "{parts} stay where they were, no longer fastened.",
|
|
659
|
+
"figure.text.removal-released-motion": "{part} stays where it was; its fastening and motion (control {control}) are gone.",
|
|
660
|
+
"figure.text.removal-own-control": "{part} now moves on its own control {control} ({min} to {max}).",
|
|
661
|
+
"figure.text.removal-fixed": "The values {parts} followed are now fixed numbers.",
|
|
662
|
+
"figure.text.removal-bindings": "{places} went with it.",
|
|
663
|
+
"figure.text.removal-mounting-face": "The mounting face is released.",
|
|
664
|
+
"figure.text.edit-refused": "This edit cannot be made. ({code})",
|
|
665
|
+
"figure.text.edit-refused-node-limit": "The figure is too large to add more. It holds up to {max} nodes.",
|
|
666
|
+
"figure.text.recipe-step-refused": "Stopped at step {step} of the recipe. {why} ({code})"
|
|
653
667
|
}
|
package/translations/ja.json
CHANGED
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"figure.text.input-range-size": "図形サイズ {axis} は {min} ~ {max} mm の間でのみ設定できます。入力値: {value} mm",
|
|
74
74
|
"figure.text.input-range": "この値は {min} ~ {max} の間でのみ設定できます。入力値: {value}",
|
|
75
75
|
"figure.text.mounting-face-needs-space": "先に空間を宣言すると選べます。",
|
|
76
|
-
"figure.text.part-is-referenced": "'{part}'
|
|
76
|
+
"figure.text.part-is-referenced": "他の部品が '{part}' の値をそのまま使っているため削除できません。",
|
|
77
77
|
"figure.text.part-name-invalid": "'{name}' は部品名に使えません。英字で始め、英字・数字・-・_ のみ使えます。",
|
|
78
78
|
"figure.text.part-name-taken": "'{name}' はこの図形ですでに使われている名前です。",
|
|
79
79
|
"figure.text.placement-redeclares": "変更すると、今の部品で空間を宣言し直します。",
|
|
@@ -632,10 +632,7 @@
|
|
|
632
632
|
"figure.button.narrow-range-from": "{axis} を {mm} mm からに絞って連結",
|
|
633
633
|
"figure.text.link-needs-larger-range": "この連結で図形の {axis} が {mm} mm を超えると描けません。宣言された置けるサイズはそれより大きくまで開いています。",
|
|
634
634
|
"figure.button.narrow-range-to": "{axis} を {mm} mm までに絞って連結",
|
|
635
|
-
"figure.text.part-holds-others": "'{part}' に {others} が付いているため削除できません。先に外してください。",
|
|
636
635
|
"figure.text.part-in-declared-space": "'{part}' は宣言された空間に含まれるため、そのままでは削除できません。削除と同時に空間を残りの部品に合わせ直せます。",
|
|
637
|
-
"figure.text.part-is-followed": "{others} が '{part}' のサイズか位置に従っているため削除できません。先に自分の数値に変えてください。",
|
|
638
|
-
"figure.text.part-is-led": "{others} が '{part}' に連動しているため削除できません。先に自分の操作値に変えてください。",
|
|
639
636
|
"figure.button.change-motion": "動きを直す",
|
|
640
637
|
"figure.button.apply-motion-change": "動きを変える",
|
|
641
638
|
"figure.button.cancel-motion-change": "直さない",
|
|
@@ -649,5 +646,22 @@
|
|
|
649
646
|
"figure.text.placement-plane-refused": "{parts} は取付平面に付いている面では {placement} に付けられません。外すか {faces} 面で付け直してから変更してください。",
|
|
650
647
|
"figure.label.face-centre": "中心",
|
|
651
648
|
"figure.label.budget-moving": "毎フレーム再計算する部品",
|
|
652
|
-
"figure.label.performance-cost": "性能コスト"
|
|
649
|
+
"figure.label.performance-cost": "性能コスト",
|
|
650
|
+
"figure.label.board-sets": "ボードで変更可能",
|
|
651
|
+
"figure.label.board-name": "ボードでの名前",
|
|
652
|
+
"figure.label.least": "最小",
|
|
653
|
+
"figure.label.most": "最大",
|
|
654
|
+
"figure.button.publish-input": "ボードに公開",
|
|
655
|
+
"figure.button.apply": "適用",
|
|
656
|
+
"figure.text.part-row-along": "列 {rows} が '{part}' に沿って並んでいるため '{part}' を削除できません。列を他の部品に取り付けるか、繰り返しを解除してから削除してください。",
|
|
657
|
+
"figure.text.part-row-carries": "{others} が列 '{part}' の各コピーに付いているため削除できません。先に外してください。",
|
|
658
|
+
"figure.text.removal-released": "{parts} はその場に残り、取り付けが外れました。",
|
|
659
|
+
"figure.text.removal-released-motion": "{part} はその場に残り、取り付けと動き(操作値 {control})が外れました。",
|
|
660
|
+
"figure.text.removal-own-control": "{part} は自分の操作値 {control}({min}~{max})で動くようになりました。",
|
|
661
|
+
"figure.text.removal-fixed": "{parts} が従っていた値は現在の数値に固定されました。",
|
|
662
|
+
"figure.text.removal-bindings": "{places} も一緒に削除しました。",
|
|
663
|
+
"figure.text.removal-mounting-face": "取付面が外れました。",
|
|
664
|
+
"figure.text.edit-refused": "この編集はできません。({code})",
|
|
665
|
+
"figure.text.edit-refused-node-limit": "図形が大きいためこれ以上追加できません。ノードは {max} 個までです。",
|
|
666
|
+
"figure.text.recipe-step-refused": "レシピの {step} 番目の手順で止まりました。{why} ({code})"
|
|
653
667
|
}
|
package/translations/ko.json
CHANGED
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"figure.text.input-range-size": "도형 크기 {axis} 는 {min} ~ {max} mm 사이에서만 정할 수 있습니다. 넣은 값: {value} mm",
|
|
74
74
|
"figure.text.input-range": "이 값은 {min} ~ {max} 사이에서만 정할 수 있습니다. 넣은 값: {value}",
|
|
75
75
|
"figure.text.mounting-face-needs-space": "공간을 먼저 선언해야 고를 수 있습니다.",
|
|
76
|
-
"figure.text.part-is-referenced": "'{part}'
|
|
76
|
+
"figure.text.part-is-referenced": "다른 부품이 '{part}' 의 값을 그대로 쓰고 있어 지울 수 없습니다.",
|
|
77
77
|
"figure.text.part-name-invalid": "'{name}' 은 부품 이름으로 쓸 수 없습니다. 영문자로 시작하고 영문자·숫자·-·_ 만 씁니다.",
|
|
78
78
|
"figure.text.part-name-taken": "'{name}' 은 이 도형에서 이미 쓰는 이름입니다.",
|
|
79
79
|
"figure.text.placement-redeclares": "바꾸면 지금 부품으로 공간을 다시 선언합니다.",
|
|
@@ -632,10 +632,7 @@
|
|
|
632
632
|
"figure.button.narrow-range-from": "{axis} 를 {mm} mm 부터로 좁히고 연결",
|
|
633
633
|
"figure.text.link-needs-larger-range": "이 연결로 도형 {axis} 가 {mm} mm 보다 크면 그릴 수 없습니다. 지금 선언된 놓일 수 있는 크기는 그보다 큰 데까지 열려 있습니다.",
|
|
634
634
|
"figure.button.narrow-range-to": "{axis} 를 {mm} mm 까지로 좁히고 연결",
|
|
635
|
-
"figure.text.part-holds-others": "'{part}' 에 {others} 이 매달려 있어 지울 수 없습니다. 먼저 떼어 주세요.",
|
|
636
635
|
"figure.text.part-in-declared-space": "'{part}' 는 선언된 공간에 들어 있어 그냥 지울 수 없습니다. 지우면서 공간을 남은 부품에 다시 맞출 수 있습니다.",
|
|
637
|
-
"figure.text.part-is-followed": "{others} 이 '{part}' 의 크기나 자리를 따르고 있어 지울 수 없습니다. 먼저 그 부품을 제 숫자로 바꾸세요.",
|
|
638
|
-
"figure.text.part-is-led": "{others} 이 '{part}' 를 따라 움직여 지울 수 없습니다. 먼저 제 조작값으로 바꾸세요.",
|
|
639
636
|
"figure.button.change-motion": "움직임 고치기",
|
|
640
637
|
"figure.button.apply-motion-change": "움직임 바꾸기",
|
|
641
638
|
"figure.button.cancel-motion-change": "고치지 않음",
|
|
@@ -649,5 +646,22 @@
|
|
|
649
646
|
"figure.text.placement-plane-refused": "{parts} 가 장착 평면에 붙은 면으로는 {placement} 에 붙일 수 없습니다. 떼거나 {faces} 면으로 다시 붙인 뒤 바꾸세요.",
|
|
650
647
|
"figure.label.face-centre": "가운데",
|
|
651
648
|
"figure.label.budget-moving": "매 프레임 다시 계산하는 부품",
|
|
652
|
-
"figure.label.performance-cost": "성능 비용"
|
|
649
|
+
"figure.label.performance-cost": "성능 비용",
|
|
650
|
+
"figure.label.board-sets": "보드에서 바꿀 수 있음",
|
|
651
|
+
"figure.label.board-name": "보드에 보이는 이름",
|
|
652
|
+
"figure.label.least": "최소",
|
|
653
|
+
"figure.label.most": "최대",
|
|
654
|
+
"figure.button.publish-input": "보드에 공개",
|
|
655
|
+
"figure.button.apply": "적용",
|
|
656
|
+
"figure.text.part-row-along": "{rows} 줄이 '{part}' 를 따라 놓여 있어 '{part}' 를 지울 수 없습니다. 줄을 다른 부품에 붙이거나 되풀이를 없앤 뒤 지우세요.",
|
|
657
|
+
"figure.text.part-row-carries": "{others} 이 줄 '{part}' 의 복제마다 붙어 있어 지울 수 없습니다. 먼저 떼어 주세요.",
|
|
658
|
+
"figure.text.removal-released": "{parts} 는 그 자리에 남고 붙임이 풀렸습니다.",
|
|
659
|
+
"figure.text.removal-released-motion": "{part} 는 그 자리에 남고, 붙임과 움직임(조작값 {control})이 풀렸습니다.",
|
|
660
|
+
"figure.text.removal-own-control": "{part} 는 이제 제 조작값 {control}({min}~{max})로 움직입니다.",
|
|
661
|
+
"figure.text.removal-fixed": "{parts} 가 따르던 값은 지금 수로 고정되었습니다.",
|
|
662
|
+
"figure.text.removal-bindings": "{places} 도 함께 지웠습니다.",
|
|
663
|
+
"figure.text.removal-mounting-face": "장착면이 풀렸습니다.",
|
|
664
|
+
"figure.text.edit-refused": "이 편집은 할 수 없습니다. ({code})",
|
|
665
|
+
"figure.text.edit-refused-node-limit": "도형이 커서 더 넣을 수 없습니다. 노드는 {max} 개까지입니다.",
|
|
666
|
+
"figure.text.recipe-step-refused": "레시피의 {step} 번째 단계에서 막혔습니다. {why} ({code})"
|
|
653
667
|
}
|
package/translations/ms.json
CHANGED
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"figure.text.input-range-size": "saiz rajah {axis} hanya boleh ditetapkan antara {min} dan {max} mm. nilai diberi: {value} mm",
|
|
74
74
|
"figure.text.input-range": "nilai ini hanya boleh ditetapkan antara {min} dan {max}. nilai diberi: {value}",
|
|
75
75
|
"figure.text.mounting-face-needs-space": "isytiharkan ruang dahulu untuk memilih.",
|
|
76
|
-
"figure.text.part-is-referenced": "'{part}' tidak boleh dipadam: bahagian lain
|
|
76
|
+
"figure.text.part-is-referenced": "'{part}' tidak boleh dipadam: bahagian lain menggunakan nilainya seperti sedia ada.",
|
|
77
77
|
"figure.text.part-name-invalid": "'{name}' tidak boleh menjadi nama bahagian. Mulakan dengan huruf dan gunakan huruf, digit, - dan _.",
|
|
78
78
|
"figure.text.part-name-taken": "'{name}' sudah digunakan dalam bentuk ini.",
|
|
79
79
|
"figure.text.placement-redeclares": "menukarnya mengisytiharkan semula ruang daripada bahagian semasa.",
|
|
@@ -632,10 +632,7 @@
|
|
|
632
632
|
"figure.button.narrow-range-from": "sempitkan {axis} dari {mm} mm dan pautkan",
|
|
633
633
|
"figure.text.link-needs-larger-range": "dengan pautan ini rajah tidak boleh dilukis apabila {axis} melebihi {mm} mm, dan saiz yang diisytihar pergi lebih tinggi.",
|
|
634
634
|
"figure.button.narrow-range-to": "sempitkan {axis} hingga {mm} mm dan pautkan",
|
|
635
|
-
"figure.text.part-holds-others": "'{part}' memegang {others}; tanggalkan dahulu.",
|
|
636
635
|
"figure.text.part-in-declared-space": "'{part}' berada dalam ruang yang diisytihar, jadi ia tidak boleh dipadam begitu sahaja. ia boleh dipadam dengan ruang dimuatkan semula pada bahagian yang tinggal.",
|
|
637
|
-
"figure.text.part-is-followed": "{others} mengikut saiz atau tempat '{part}'; jadikan nombor sendiri dahulu.",
|
|
638
|
-
"figure.text.part-is-led": "{others} bergerak bersama '{part}'; beri kawalan sendiri dahulu.",
|
|
639
636
|
"figure.button.change-motion": "ubah gerakan",
|
|
640
637
|
"figure.button.apply-motion-change": "guna perubahan",
|
|
641
638
|
"figure.button.cancel-motion-change": "biarkan",
|
|
@@ -649,5 +646,22 @@
|
|
|
649
646
|
"figure.text.placement-plane-refused": "{parts} tidak boleh dipasang pada {placement} dengan muka yang dipasang pada satah pemasangan. tanggalkan atau pasang semula dengan muka {faces} dahulu.",
|
|
650
647
|
"figure.label.face-centre": "tengah",
|
|
651
648
|
"figure.label.budget-moving": "bahagian dikira semula setiap bingkai",
|
|
652
|
-
"figure.label.performance-cost": "kos prestasi"
|
|
649
|
+
"figure.label.performance-cost": "kos prestasi",
|
|
650
|
+
"figure.label.board-sets": "papan boleh mengubahnya",
|
|
651
|
+
"figure.label.board-name": "nama pada papan",
|
|
652
|
+
"figure.label.least": "terkecil",
|
|
653
|
+
"figure.label.most": "terbesar",
|
|
654
|
+
"figure.button.publish-input": "terbitkan ke papan",
|
|
655
|
+
"figure.button.apply": "guna",
|
|
656
|
+
"figure.text.part-row-along": "Barisan {rows} disusun sepanjang '{part}', jadi '{part}' tidak boleh dipadam. Pasangkan barisan pada bahagian lain, atau batalkan ulangan, dahulu.",
|
|
657
|
+
"figure.text.part-row-carries": "{others} tergantung pada setiap salinan barisan '{part}'; tanggalkan dahulu.",
|
|
658
|
+
"figure.text.removal-released": "{parts} kekal di tempatnya, tidak lagi dipasang.",
|
|
659
|
+
"figure.text.removal-released-motion": "{part} kekal di tempatnya; pemasangan dan gerakannya (kawalan {control}) telah hilang.",
|
|
660
|
+
"figure.text.removal-own-control": "{part} kini bergerak dengan kawalannya sendiri {control} ({min} hingga {max}).",
|
|
661
|
+
"figure.text.removal-fixed": "Nilai yang diikuti oleh {parts} kini nombor tetap.",
|
|
662
|
+
"figure.text.removal-bindings": "{places} turut dipadam.",
|
|
663
|
+
"figure.text.removal-mounting-face": "Muka pemasangan dilepaskan.",
|
|
664
|
+
"figure.text.edit-refused": "Suntingan ini tidak boleh dibuat. ({code})",
|
|
665
|
+
"figure.text.edit-refused-node-limit": "Rajah terlalu besar untuk ditambah. Ia memuatkan sehingga {max} nod.",
|
|
666
|
+
"figure.text.recipe-step-refused": "Terhenti pada langkah {step} resipi. {why} ({code})"
|
|
653
667
|
}
|
package/translations/zh.json
CHANGED
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"figure.text.input-range-size": "图形尺寸 {axis} 只能设置在 {min} 到 {max} mm 之间。输入值:{value} mm",
|
|
74
74
|
"figure.text.input-range": "此值只能设置在 {min} 到 {max} 之间。输入值:{value}",
|
|
75
75
|
"figure.text.mounting-face-needs-space": "请先声明空间,然后才能选择。",
|
|
76
|
-
"figure.text.part-is-referenced": "
|
|
76
|
+
"figure.text.part-is-referenced": "其他部件直接使用 '{part}' 的值,无法删除。",
|
|
77
77
|
"figure.text.part-name-invalid": "'{name}' 不能作为部件名称。请以字母开头,只使用字母、数字、- 和 _。",
|
|
78
78
|
"figure.text.part-name-taken": "'{name}' 在此图形中已被使用。",
|
|
79
79
|
"figure.text.placement-redeclares": "更改后将按当前部件重新声明空间。",
|
|
@@ -632,10 +632,7 @@
|
|
|
632
632
|
"figure.button.narrow-range-from": "将 {axis} 收窄为 {mm} mm 起并连接",
|
|
633
633
|
"figure.text.link-needs-larger-range": "此连接下,图形 {axis} 大于 {mm} mm 时无法绘制,而声明的可放置尺寸高于此值。",
|
|
634
634
|
"figure.button.narrow-range-to": "将 {axis} 收窄为 {mm} mm 以内并连接",
|
|
635
|
-
"figure.text.part-holds-others": "'{part}' 上挂着 {others},无法删除。请先卸下。",
|
|
636
635
|
"figure.text.part-in-declared-space": "'{part}' 在已声明的空间内,不能直接删除。可以在删除的同时让空间重新适配剩余部件。",
|
|
637
|
-
"figure.text.part-is-followed": "{others} 跟随 '{part}' 的尺寸或位置,无法删除。请先改为自身数值。",
|
|
638
|
-
"figure.text.part-is-led": "{others} 跟随 '{part}' 运动,无法删除。请先改为自身控制值。",
|
|
639
636
|
"figure.button.change-motion": "修改运动",
|
|
640
637
|
"figure.button.apply-motion-change": "应用修改",
|
|
641
638
|
"figure.button.cancel-motion-change": "不修改",
|
|
@@ -649,5 +646,22 @@
|
|
|
649
646
|
"figure.text.placement-plane-refused": "{parts} 贴在安装平面上的面不能用于 {placement}。请先拆下或改用 {faces} 面贴合后再更改。",
|
|
650
647
|
"figure.label.face-centre": "中心",
|
|
651
648
|
"figure.label.budget-moving": "每帧重新计算的部件",
|
|
652
|
-
"figure.label.performance-cost": "性能成本"
|
|
649
|
+
"figure.label.performance-cost": "性能成本",
|
|
650
|
+
"figure.label.board-sets": "可在看板中修改",
|
|
651
|
+
"figure.label.board-name": "看板中显示的名称",
|
|
652
|
+
"figure.label.least": "最小",
|
|
653
|
+
"figure.label.most": "最大",
|
|
654
|
+
"figure.button.publish-input": "公开到看板",
|
|
655
|
+
"figure.button.apply": "应用",
|
|
656
|
+
"figure.text.part-row-along": "阵列 {rows} 沿 '{part}' 排列,无法删除 '{part}'。请先将阵列固定到其他部件或取消重复。",
|
|
657
|
+
"figure.text.part-row-carries": "{others} 挂在阵列 '{part}' 的每个副本上,无法删除。请先卸下。",
|
|
658
|
+
"figure.text.removal-released": "{parts} 留在原处,已解除固定。",
|
|
659
|
+
"figure.text.removal-released-motion": "{part} 留在原处,固定和运动(控制值 {control})已解除。",
|
|
660
|
+
"figure.text.removal-own-control": "{part} 现在由自己的控制值 {control}({min}~{max})驱动。",
|
|
661
|
+
"figure.text.removal-fixed": "{parts} 跟随的值已固定为当前数值。",
|
|
662
|
+
"figure.text.removal-bindings": "{places} 也一并删除。",
|
|
663
|
+
"figure.text.removal-mounting-face": "安装面已解除。",
|
|
664
|
+
"figure.text.edit-refused": "无法进行此编辑。({code})",
|
|
665
|
+
"figure.text.edit-refused-node-limit": "图形过大,无法再添加。节点上限为 {max} 个。",
|
|
666
|
+
"figure.text.recipe-step-refused": "配方在第 {step} 步停止。{why} ({code})"
|
|
653
667
|
}
|