@things-factory/figure-service 10.1.183 → 10.1.188
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/dist-server/service/figure/figure-format.js +47 -0
- package/dist-server/service/figure/figure-format.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/server/service/figure/figure-format.test.ts +44 -0
- package/server/service/figure/figure-format.ts +55 -1
- package/translations/en.json +16 -0
- package/translations/es.json +16 -0
- package/translations/ja.json +16 -0
- package/translations/ko.json +16 -0
- package/translations/ms.json +16 -0
- package/translations/zh.json +16 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/figure-service",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.188",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"@things-factory:registry": "https://registry.npmjs.org"
|
|
@@ -25,18 +25,18 @@
|
|
|
25
25
|
"test:templates": "node --test scripts/templates.test.mts"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@hatiolab/figure-model": "^0.7.
|
|
28
|
+
"@hatiolab/figure-model": "^0.7.3",
|
|
29
29
|
"@operato/typeorm-history": "^10.0.0",
|
|
30
|
-
"@things-factory/ai-client-base": "^10.1.
|
|
31
|
-
"@things-factory/attachment-base": "^10.1.
|
|
32
|
-
"@things-factory/auth-base": "^10.1.
|
|
30
|
+
"@things-factory/ai-client-base": "^10.1.188",
|
|
31
|
+
"@things-factory/attachment-base": "^10.1.188",
|
|
32
|
+
"@things-factory/auth-base": "^10.1.188",
|
|
33
33
|
"@things-factory/env": "^10.1.149",
|
|
34
|
-
"@things-factory/setting-base": "^10.1.
|
|
35
|
-
"@things-factory/shell": "^10.1.
|
|
34
|
+
"@things-factory/setting-base": "^10.1.188",
|
|
35
|
+
"@things-factory/shell": "^10.1.188",
|
|
36
36
|
"graphql-scalars": "^1.22.4",
|
|
37
37
|
"graphql-upload": "^15.0.2",
|
|
38
38
|
"jszip": "^3.10.1",
|
|
39
39
|
"koa-router": "^7.4.0"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "c5e75e2e0b565e0666472bc835f5f1538fb18f48"
|
|
42
42
|
}
|
|
@@ -388,6 +388,50 @@ describe('figure-format — 판을 알아보는 문', () => {
|
|
|
388
388
|
})
|
|
389
389
|
})
|
|
390
390
|
|
|
391
|
+
/* The walk of 2026-10-18: a figure off its mounting plane passed release with no word. Said now, never refused. */
|
|
392
|
+
describe('a figure off the plane it is mounted on', () => {
|
|
393
|
+
const conveyor = (legBottom: number, placement: 'floor' | 'ceiling' | 'wall' | 'center' = 'floor') => {
|
|
394
|
+
let a = applyFigureAuthoring(createFigureAsset('Conveyor'), { kind: 'set-placement', placement })
|
|
395
|
+
a = addFigureBox(a, { id: 'bed', size: { x: 3000, y: 100, z: 800 }, position: { x: 0, y: legBottom + 750, z: 0 } })
|
|
396
|
+
a = addFigureBox(a, { id: 'leg', size: { x: 60, y: 700, z: 60 }, position: { x: 0, y: legBottom + 350, z: 0 } })
|
|
397
|
+
return applyFigureAuthoring(a, { kind: 'attach', part: 'leg', face: 'top', to: { part: 'bed', face: 'bottom' } })
|
|
398
|
+
}
|
|
399
|
+
const offPlane = (asset: ReturnType<typeof conveyor>) =>
|
|
400
|
+
inspectSource(serializeFigureAsset(asset), null, undefined, 'CONVEYOR').findings.filter(f => f.code === 'off-mounting-plane')
|
|
401
|
+
|
|
402
|
+
it('100 mm in the air: named by its lowest part, and the release goes on', () => {
|
|
403
|
+
const [found, ...more] = offPlane(conveyor(100))
|
|
404
|
+
expect(more).toEqual([])
|
|
405
|
+
expect(found.blocking).toBe(false)
|
|
406
|
+
expect(found.at).toBe('leg')
|
|
407
|
+
expect(found.message).toBe("'leg' is 100 mm above the floor.")
|
|
408
|
+
})
|
|
409
|
+
it('standing on the floor says nothing; nor does a centred figure', () => {
|
|
410
|
+
expect(offPlane(conveyor(0))).toEqual([])
|
|
411
|
+
expect(offPlane(conveyor(100, 'center'))).toEqual([])
|
|
412
|
+
})
|
|
413
|
+
it('every part below the floor asks whether it hangs from the ceiling', () => {
|
|
414
|
+
const [found] = offPlane(conveyor(-2000))
|
|
415
|
+
expect(found.message).toBe('Every part is below the floor.')
|
|
416
|
+
expect(found.how).toBe('If it hangs from the ceiling, set where it stands to the ceiling.')
|
|
417
|
+
})
|
|
418
|
+
it('a figure that names its mounting face is checked on that face, not told twice', () => {
|
|
419
|
+
let a = conveyor(100)
|
|
420
|
+
a = applyFigureAuthoring(a, { kind: 'declare-occupancy', proposal: proposeFigureOccupancy(a) })
|
|
421
|
+
a = applyFigureAuthoring(a, { kind: 'set-mounting-face', part: 'leg', face: 'bottom' })
|
|
422
|
+
const found = inspectSource(serializeFigureAsset(a), null, undefined, 'CONVEYOR').findings
|
|
423
|
+
expect(found.map(f => f.code)).not.toContain('off-mounting-plane')
|
|
424
|
+
expect(found.map(f => f.code)).toContain('parts-off-placement-face')
|
|
425
|
+
})
|
|
426
|
+
it('its sentences are in all six languages', () => {
|
|
427
|
+
const keys = ['floor', 'ceiling', 'wall'].flatMap(p => [...['clear', 'through', 'beyond'].map(k => `${p}.${k}.message`), `${p}.why`, `${p}.beyond.how`]).concat('how')
|
|
428
|
+
for (const lang of ['ko', 'en', 'ja', 'zh', 'es', 'ms']) {
|
|
429
|
+
const dict = require(`../../../translations/${lang}.json`) as Record<string, string>
|
|
430
|
+
for (const key of keys) expect([lang, key, !!dict[`figure.gate.off-mounting-plane.${key}`]]).toEqual([lang, key, true])
|
|
431
|
+
}
|
|
432
|
+
})
|
|
433
|
+
})
|
|
434
|
+
|
|
391
435
|
/* ADR-0104 decision 4: off the middle of its room is said at release, never refused. */
|
|
392
436
|
it('an origin off the middle of the room is a warning, and the release goes on', () => {
|
|
393
437
|
let asset = createFigureAsset('Door')
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* board (`consumablePayloadOf`). The format is `figure-asset-1`, and the asset says so in its `version`; a source
|
|
4
4
|
* that does not is refused by name, because a source the server cannot identify is one it must not save.
|
|
5
5
|
*/
|
|
6
|
-
import { FIGURE_KERNEL_VERSION, compileFigureAsset, inspectFigureAsset, isPlaceholderType, parseFigureAsset, serializeFigureAsset, figureContractChanges, figureCostOf, figureOriginCentredOf, figureReleaseMetricsOf, figureScoreOf, figureTopViewOf } from '@hatiolab/figure-model'
|
|
6
|
+
import { FIGURE_KERNEL_VERSION, compileFigureAsset, inspectFigureAsset, isPlaceholderType, parseFigureAsset, serializeFigureAsset, figureContractChanges, figureCostOf, figureOriginCentredOf, figurePlaneGapOf, figureReleaseMetricsOf, figureScoreOf, figureTopViewOf } from '@hatiolab/figure-model'
|
|
7
7
|
import type { FigureAsset, FigureContractChange, FigureContractError, FigureReleaseMetrics, FigureTopView, FigureViolation } from '@hatiolab/figure-model'
|
|
8
8
|
|
|
9
9
|
import type { FigureFinding } from './figure-type.js'
|
|
@@ -336,11 +336,65 @@ export function inspectSource(
|
|
|
336
336
|
blocking: false
|
|
337
337
|
})
|
|
338
338
|
}
|
|
339
|
+
findings.push(...planeGapFindings(asset!, say))
|
|
339
340
|
if (releasedJson) findings.push(...figureContractFindings(asset!, releasedJson, say))
|
|
340
341
|
findings.push(...appFindings({ asset: asset!, type: rowType, category: rowCategory, t }))
|
|
341
342
|
return { blocked: findings.some(finding => finding.blocking), findings }
|
|
342
343
|
}
|
|
343
344
|
|
|
345
|
+
/*
|
|
346
|
+
Said, never refused: a figure off the plane it is mounted on stands off it on every board -- a conveyor in the air, a
|
|
347
|
+
hoist hung below a floor figure (the walk of 2026-10-18 found each passing release with no word). A gap can be meant,
|
|
348
|
+
and so can a part through the plane, so it does not block. A figure that names its mounting face is checked on that
|
|
349
|
+
face by the gate already; this is for the one that names none.
|
|
350
|
+
*/
|
|
351
|
+
type Gap = { part: string; mm: number }
|
|
352
|
+
const PLANE_ENGLISH = {
|
|
353
|
+
floor: {
|
|
354
|
+
clear: (g: Gap) => `'${g.part}' is ${g.mm} mm above the floor.`,
|
|
355
|
+
through: (g: Gap) => `'${g.part}' goes ${g.mm} mm below the floor.`,
|
|
356
|
+
beyond: 'Every part is below the floor.',
|
|
357
|
+
why: 'A board stands this figure on the floor, so it stands so on every board.',
|
|
358
|
+
beyondHow: 'If it hangs from the ceiling, set where it stands to the ceiling.'
|
|
359
|
+
},
|
|
360
|
+
ceiling: {
|
|
361
|
+
clear: (g: Gap) => `'${g.part}' is ${g.mm} mm below the ceiling.`,
|
|
362
|
+
through: (g: Gap) => `'${g.part}' goes ${g.mm} mm above the ceiling.`,
|
|
363
|
+
beyond: 'Every part is above the ceiling.',
|
|
364
|
+
why: 'A board hangs this figure from the ceiling, so it hangs so on every board.',
|
|
365
|
+
beyondHow: 'If it stands on the floor, set where it stands to the floor.'
|
|
366
|
+
},
|
|
367
|
+
wall: {
|
|
368
|
+
clear: (g: Gap) => `'${g.part}' is ${g.mm} mm out from the wall.`,
|
|
369
|
+
through: (g: Gap) => `'${g.part}' goes ${g.mm} mm into the wall.`,
|
|
370
|
+
beyond: 'Every part is behind the wall.',
|
|
371
|
+
why: 'A board puts this figure on the wall, so it sits so on every board.',
|
|
372
|
+
beyondHow: 'Bring the parts out in front of the wall, or choose again where it stands.'
|
|
373
|
+
}
|
|
374
|
+
} as const
|
|
375
|
+
function planeGapFindings(asset: FigureAsset, say: Say): GateFinding[] {
|
|
376
|
+
if (asset.occupancy?.contact) return []
|
|
377
|
+
const gap = figurePlaneGapOf(asset)
|
|
378
|
+
if (!gap || gap.touches) return []
|
|
379
|
+
const english = PLANE_ENGLISH[gap.placement]
|
|
380
|
+
const key = `figure.gate.off-mounting-plane.${gap.placement}`
|
|
381
|
+
const kind = gap.beyond ? 'beyond' : gap.mm > 0 ? 'clear' : 'through'
|
|
382
|
+
const said = { part: gap.part, mm: Math.round(Math.abs(gap.mm)) }
|
|
383
|
+
return [
|
|
384
|
+
{
|
|
385
|
+
code: 'off-mounting-plane',
|
|
386
|
+
message: say(`${key}.${kind}.message`, said, kind === 'beyond' ? english.beyond : english[kind](said)),
|
|
387
|
+
why: say(`${key}.why`, {}, english.why),
|
|
388
|
+
how:
|
|
389
|
+
kind === 'beyond'
|
|
390
|
+
? say(`${key}.beyond.how`, {}, english.beyondHow)
|
|
391
|
+
: say('figure.gate.off-mounting-plane.how', {}, 'Keep it if it is meant. Otherwise fasten that part to the mounting plane, or move it until it meets the plane.'),
|
|
392
|
+
at: gap.part,
|
|
393
|
+
blocking: false
|
|
394
|
+
}
|
|
395
|
+
]
|
|
396
|
+
}
|
|
397
|
+
|
|
344
398
|
/**
|
|
345
399
|
* The last release against this one — what the drawings that already hold this type lean on (ADR-0063 decision 3).
|
|
346
400
|
*
|
package/translations/en.json
CHANGED
|
@@ -97,6 +97,22 @@
|
|
|
97
97
|
"figure.gate.origin-off-centre.message": "The origin is off the middle of the declared room: {off}.",
|
|
98
98
|
"figure.gate.origin-off-centre.why": "A drawing that places figures by the middle of their room puts this one that far from where it is drawn.",
|
|
99
99
|
"figure.gate.origin-off-centre.how": "Keep it when the figure is fastened there, as a door at its hinge. Move the origin to the middle to place it by its room.",
|
|
100
|
+
"figure.gate.off-mounting-plane.floor.clear.message": "'{part}' is {mm} mm above the floor.",
|
|
101
|
+
"figure.gate.off-mounting-plane.floor.through.message": "'{part}' goes {mm} mm below the floor.",
|
|
102
|
+
"figure.gate.off-mounting-plane.floor.beyond.message": "Every part is below the floor.",
|
|
103
|
+
"figure.gate.off-mounting-plane.floor.why": "A board stands this figure on the floor, so it stands so on every board.",
|
|
104
|
+
"figure.gate.off-mounting-plane.floor.beyond.how": "If it hangs from the ceiling, set where it stands to the ceiling.",
|
|
105
|
+
"figure.gate.off-mounting-plane.ceiling.clear.message": "'{part}' is {mm} mm below the ceiling.",
|
|
106
|
+
"figure.gate.off-mounting-plane.ceiling.through.message": "'{part}' goes {mm} mm above the ceiling.",
|
|
107
|
+
"figure.gate.off-mounting-plane.ceiling.beyond.message": "Every part is above the ceiling.",
|
|
108
|
+
"figure.gate.off-mounting-plane.ceiling.why": "A board hangs this figure from the ceiling, so it hangs so on every board.",
|
|
109
|
+
"figure.gate.off-mounting-plane.ceiling.beyond.how": "If it stands on the floor, set where it stands to the floor.",
|
|
110
|
+
"figure.gate.off-mounting-plane.wall.clear.message": "'{part}' is {mm} mm out from the wall.",
|
|
111
|
+
"figure.gate.off-mounting-plane.wall.through.message": "'{part}' goes {mm} mm into the wall.",
|
|
112
|
+
"figure.gate.off-mounting-plane.wall.beyond.message": "Every part is behind the wall.",
|
|
113
|
+
"figure.gate.off-mounting-plane.wall.why": "A board puts this figure on the wall, so it sits so on every board.",
|
|
114
|
+
"figure.gate.off-mounting-plane.wall.beyond.how": "Bring the parts out in front of the wall, or choose again where it stands.",
|
|
115
|
+
"figure.gate.off-mounting-plane.how": "Keep it if it is meant. Otherwise fasten that part to the mounting plane, or move it until it meets the plane.",
|
|
100
116
|
"error.figure-namespace-missing": "this domain has no default figure namespace. add one first.",
|
|
101
117
|
"error.figure-namespace-invalid": "{value} is not a figure namespace. use lower-case letters, digits, dots and hyphens, for example hatiolab.com.",
|
|
102
118
|
"error.figure-type-malformed": "{type} is not a figure type. use lower-case letters, digits and single hyphens, {min} to {max} characters, starting with a letter.",
|
package/translations/es.json
CHANGED
|
@@ -97,6 +97,22 @@
|
|
|
97
97
|
"figure.gate.origin-off-centre.message": "El origen está desplazado del centro del espacio declarado: {off}.",
|
|
98
98
|
"figure.gate.origin-off-centre.why": "Un plano que coloca las figuras por el centro de su espacio sitúa esta a esa distancia de donde está dibujada.",
|
|
99
99
|
"figure.gate.origin-off-centre.how": "Manténgalo si la figura se fija en ese punto, como una puerta por su bisagra. Mueva el origen al centro para colocarla por su espacio.",
|
|
100
|
+
"figure.gate.off-mounting-plane.floor.clear.message": "'{part}' está {mm} mm por encima del suelo.",
|
|
101
|
+
"figure.gate.off-mounting-plane.floor.through.message": "'{part}' baja {mm} mm por debajo del suelo.",
|
|
102
|
+
"figure.gate.off-mounting-plane.floor.beyond.message": "Todas las piezas están por debajo del suelo.",
|
|
103
|
+
"figure.gate.off-mounting-plane.floor.why": "Un plano coloca esta figura de pie sobre el suelo, así que queda así en todos los planos.",
|
|
104
|
+
"figure.gate.off-mounting-plane.floor.beyond.how": "Si cuelga del techo, cambie dónde se coloca a techo.",
|
|
105
|
+
"figure.gate.off-mounting-plane.ceiling.clear.message": "'{part}' está {mm} mm por debajo del techo.",
|
|
106
|
+
"figure.gate.off-mounting-plane.ceiling.through.message": "'{part}' sube {mm} mm por encima del techo.",
|
|
107
|
+
"figure.gate.off-mounting-plane.ceiling.beyond.message": "Todas las piezas están por encima del techo.",
|
|
108
|
+
"figure.gate.off-mounting-plane.ceiling.why": "Un plano cuelga esta figura del techo, así que queda así en todos los planos.",
|
|
109
|
+
"figure.gate.off-mounting-plane.ceiling.beyond.how": "Si se apoya en el suelo, cambie dónde se coloca a suelo.",
|
|
110
|
+
"figure.gate.off-mounting-plane.wall.clear.message": "'{part}' está a {mm} mm de la pared.",
|
|
111
|
+
"figure.gate.off-mounting-plane.wall.through.message": "'{part}' entra {mm} mm en la pared.",
|
|
112
|
+
"figure.gate.off-mounting-plane.wall.beyond.message": "Todas las piezas están detrás de la pared.",
|
|
113
|
+
"figure.gate.off-mounting-plane.wall.why": "Un plano coloca esta figura en la pared, así que queda así en todos los planos.",
|
|
114
|
+
"figure.gate.off-mounting-plane.wall.beyond.how": "Lleve las piezas delante de la pared o vuelva a elegir dónde se coloca.",
|
|
115
|
+
"figure.gate.off-mounting-plane.how": "Manténgalo si es intencionado. Si no, fije esa pieza al plano de montaje o muévala hasta que toque el plano.",
|
|
100
116
|
"error.figure-namespace-missing": "este dominio no tiene un namespace de figura predeterminado. agregue uno primero.",
|
|
101
117
|
"error.figure-namespace-invalid": "{value} no es un namespace de Figure. Use minúsculas, dígitos, puntos y guiones, por ejemplo hatiolab.com.",
|
|
102
118
|
"error.figure-type-malformed": "{type} no es un tipo de figura. Use letras minúsculas, dígitos y guiones simples, de {min} a {max} caracteres, empezando por una letra.",
|
package/translations/ja.json
CHANGED
|
@@ -97,6 +97,22 @@
|
|
|
97
97
|
"figure.gate.origin-off-centre.message": "原点が宣言された空間の中央からずれています: {off}。",
|
|
98
98
|
"figure.gate.origin-off-centre.why": "空間の中央で Figure を配置する図面では、描画した位置からその分だけ離れて配置されます。",
|
|
99
99
|
"figure.gate.origin-off-centre.how": "ドアの蝶番のように、Figure をそこで取り付ける場合はそのままにしてください。空間の中央で配置するには、原点を中央に移動してください。",
|
|
100
|
+
"figure.gate.off-mounting-plane.floor.clear.message": "'{part}' が床から {mm} mm 浮いています。",
|
|
101
|
+
"figure.gate.off-mounting-plane.floor.through.message": "'{part}' が床の下に {mm} mm 入り込んでいます。",
|
|
102
|
+
"figure.gate.off-mounting-plane.floor.beyond.message": "すべての部品が床の下にあります。",
|
|
103
|
+
"figure.gate.off-mounting-plane.floor.why": "ボードはこの Figure を床に立てます。どのボードでも今の姿のまま置かれます。",
|
|
104
|
+
"figure.gate.off-mounting-plane.floor.beyond.how": "天井から吊るす設備なら、置く場所を天井に変更してください。",
|
|
105
|
+
"figure.gate.off-mounting-plane.ceiling.clear.message": "'{part}' が天井から {mm} mm 下にあります。",
|
|
106
|
+
"figure.gate.off-mounting-plane.ceiling.through.message": "'{part}' が天井の上に {mm} mm 出ています。",
|
|
107
|
+
"figure.gate.off-mounting-plane.ceiling.beyond.message": "すべての部品が天井の上にあります。",
|
|
108
|
+
"figure.gate.off-mounting-plane.ceiling.why": "ボードはこの Figure を天井から吊るします。どのボードでも今の姿のまま置かれます。",
|
|
109
|
+
"figure.gate.off-mounting-plane.ceiling.beyond.how": "床に立てる設備なら、置く場所を床に変更してください。",
|
|
110
|
+
"figure.gate.off-mounting-plane.wall.clear.message": "'{part}' が壁から {mm} mm 離れています。",
|
|
111
|
+
"figure.gate.off-mounting-plane.wall.through.message": "'{part}' が壁の中に {mm} mm 入り込んでいます。",
|
|
112
|
+
"figure.gate.off-mounting-plane.wall.beyond.message": "すべての部品が壁の裏にあります。",
|
|
113
|
+
"figure.gate.off-mounting-plane.wall.why": "ボードはこの Figure を壁に取り付けます。どのボードでも今の姿のまま置かれます。",
|
|
114
|
+
"figure.gate.off-mounting-plane.wall.beyond.how": "部品を壁の前に移すか、置く場所を選び直してください。",
|
|
115
|
+
"figure.gate.off-mounting-plane.how": "意図したものならそのままにしてください。そうでなければ、その部品を取付平面に取り付けるか、平面に接するまで移動してください。",
|
|
100
116
|
"error.figure-namespace-missing": "このドメインには既定の Figure namespace がありません。先に namespace を追加してください。",
|
|
101
117
|
"error.figure-namespace-invalid": "Figure namespace の形式ではありません({value})。英小文字・数字・ドット・ハイフンで入力してください。例: hatiolab.com",
|
|
102
118
|
"error.figure-type-malformed": "{type} は Figure type ではありません。英小文字で始め、英小文字・数字・単一のハイフンのみを使って {min}〜{max} 文字で指定してください。",
|
package/translations/ko.json
CHANGED
|
@@ -97,6 +97,22 @@
|
|
|
97
97
|
"figure.gate.origin-off-centre.message": "원점이 차지 공간 가운데에서 비켜 있습니다: {off}.",
|
|
98
98
|
"figure.gate.origin-off-centre.why": "공간 가운데로 도형을 놓는 도면에서는 그린 자리에서 그만큼 떨어져 놓입니다.",
|
|
99
99
|
"figure.gate.origin-off-centre.how": "문의 경첩처럼 붙이는 자리라면 그대로 둡니다. 공간 가운데로 놓이게 하려면 원점을 가운데로 옮깁니다.",
|
|
100
|
+
"figure.gate.off-mounting-plane.floor.clear.message": "'{part}' 부품이 바닥에서 {mm}mm 떠 있습니다.",
|
|
101
|
+
"figure.gate.off-mounting-plane.floor.through.message": "'{part}' 부품이 바닥 아래로 {mm}mm 내려가 있습니다.",
|
|
102
|
+
"figure.gate.off-mounting-plane.floor.beyond.message": "모든 부품이 바닥 아래에 있습니다.",
|
|
103
|
+
"figure.gate.off-mounting-plane.floor.why": "보드는 이 도형을 바닥에 세웁니다. 어느 보드에서나 지금 모습 그대로 놓입니다.",
|
|
104
|
+
"figure.gate.off-mounting-plane.floor.beyond.how": "천장에 매다는 설비라면 놓이는 곳을 천장으로 바꿉니다.",
|
|
105
|
+
"figure.gate.off-mounting-plane.ceiling.clear.message": "'{part}' 부품이 천장에서 {mm}mm 아래에 있습니다.",
|
|
106
|
+
"figure.gate.off-mounting-plane.ceiling.through.message": "'{part}' 부품이 천장 위로 {mm}mm 올라가 있습니다.",
|
|
107
|
+
"figure.gate.off-mounting-plane.ceiling.beyond.message": "모든 부품이 천장 위에 있습니다.",
|
|
108
|
+
"figure.gate.off-mounting-plane.ceiling.why": "보드는 이 도형을 천장에 매답니다. 어느 보드에서나 지금 모습 그대로 놓입니다.",
|
|
109
|
+
"figure.gate.off-mounting-plane.ceiling.beyond.how": "바닥에 세우는 설비라면 놓이는 곳을 바닥으로 바꿉니다.",
|
|
110
|
+
"figure.gate.off-mounting-plane.wall.clear.message": "'{part}' 부품이 벽에서 {mm}mm 떨어져 있습니다.",
|
|
111
|
+
"figure.gate.off-mounting-plane.wall.through.message": "'{part}' 부품이 벽 안으로 {mm}mm 들어가 있습니다.",
|
|
112
|
+
"figure.gate.off-mounting-plane.wall.beyond.message": "모든 부품이 벽 뒤에 있습니다.",
|
|
113
|
+
"figure.gate.off-mounting-plane.wall.why": "보드는 이 도형을 벽에 붙입니다. 어느 보드에서나 지금 모습 그대로 놓입니다.",
|
|
114
|
+
"figure.gate.off-mounting-plane.wall.beyond.how": "부품을 벽 앞으로 옮기거나 놓이는 곳을 다시 고릅니다.",
|
|
115
|
+
"figure.gate.off-mounting-plane.how": "의도한 것이면 그대로 둡니다. 아니면 그 부품을 장착 평면에 붙이거나, 평면에 닿도록 옮깁니다.",
|
|
100
116
|
"error.figure-namespace-missing": "이 도메인에는 기본 Figure namespace 가 없습니다. 먼저 namespace 를 추가해 주세요.",
|
|
101
117
|
"error.figure-namespace-invalid": "Figure namespace 형식이 아닙니다({value}). 영문 소문자·숫자·점·하이픈으로 입력해 주세요. 예: hatiolab.com",
|
|
102
118
|
"error.figure-type-malformed": "{type} 은 Figure type 이 아닙니다. 소문자로 시작하고 소문자·숫자·하이픈 하나씩만 써서 {min}~{max}자로 정해 주세요.",
|
package/translations/ms.json
CHANGED
|
@@ -97,6 +97,22 @@
|
|
|
97
97
|
"figure.gate.origin-off-centre.message": "Titik asal tidak berada di tengah ruang yang diisytiharkan: {off}.",
|
|
98
98
|
"figure.gate.origin-off-centre.why": "Lukisan yang meletakkan figure mengikut tengah ruangnya meletakkan figure ini sejauh itu dari tempat ia dilukis.",
|
|
99
99
|
"figure.gate.origin-off-centre.how": "Kekalkan jika figure dilekatkan di situ, seperti pintu pada engselnya. Alihkan titik asal ke tengah untuk meletakkannya mengikut ruangnya.",
|
|
100
|
+
"figure.gate.off-mounting-plane.floor.clear.message": "'{part}' berada {mm} mm di atas lantai.",
|
|
101
|
+
"figure.gate.off-mounting-plane.floor.through.message": "'{part}' turun {mm} mm di bawah lantai.",
|
|
102
|
+
"figure.gate.off-mounting-plane.floor.beyond.message": "Semua bahagian berada di bawah lantai.",
|
|
103
|
+
"figure.gate.off-mounting-plane.floor.why": "Papan meletakkan figure ini berdiri di atas lantai, jadi ia kekal begitu pada setiap papan.",
|
|
104
|
+
"figure.gate.off-mounting-plane.floor.beyond.how": "Jika ia digantung dari siling, tukar tempat ia diletakkan kepada siling.",
|
|
105
|
+
"figure.gate.off-mounting-plane.ceiling.clear.message": "'{part}' berada {mm} mm di bawah siling.",
|
|
106
|
+
"figure.gate.off-mounting-plane.ceiling.through.message": "'{part}' naik {mm} mm di atas siling.",
|
|
107
|
+
"figure.gate.off-mounting-plane.ceiling.beyond.message": "Semua bahagian berada di atas siling.",
|
|
108
|
+
"figure.gate.off-mounting-plane.ceiling.why": "Papan menggantung figure ini dari siling, jadi ia kekal begitu pada setiap papan.",
|
|
109
|
+
"figure.gate.off-mounting-plane.ceiling.beyond.how": "Jika ia berdiri di atas lantai, tukar tempat ia diletakkan kepada lantai.",
|
|
110
|
+
"figure.gate.off-mounting-plane.wall.clear.message": "'{part}' berada {mm} mm dari dinding.",
|
|
111
|
+
"figure.gate.off-mounting-plane.wall.through.message": "'{part}' masuk {mm} mm ke dalam dinding.",
|
|
112
|
+
"figure.gate.off-mounting-plane.wall.beyond.message": "Semua bahagian berada di belakang dinding.",
|
|
113
|
+
"figure.gate.off-mounting-plane.wall.why": "Papan meletakkan figure ini pada dinding, jadi ia kekal begitu pada setiap papan.",
|
|
114
|
+
"figure.gate.off-mounting-plane.wall.beyond.how": "Bawa bahagian ke hadapan dinding, atau pilih semula tempat ia diletakkan.",
|
|
115
|
+
"figure.gate.off-mounting-plane.how": "Kekalkan jika ia disengajakan. Jika tidak, lekatkan bahagian itu pada satah pemasangan, atau alihkannya sehingga menyentuh satah.",
|
|
100
116
|
"error.figure-namespace-missing": "domain ini tiada namespace figure lalai. tambah satu dahulu.",
|
|
101
117
|
"error.figure-namespace-invalid": "{value} bukan namespace Figure. Gunakan huruf kecil, digit, titik dan sempang, contohnya hatiolab.com.",
|
|
102
118
|
"error.figure-type-malformed": "{type} bukan jenis figure. gunakan huruf kecil, digit dan tanda sempang tunggal, {min} hingga {max} aksara, bermula dengan huruf.",
|
package/translations/zh.json
CHANGED
|
@@ -97,6 +97,22 @@
|
|
|
97
97
|
"figure.gate.origin-off-centre.message": "原点偏离声明空间的中心:{off}。",
|
|
98
98
|
"figure.gate.origin-off-centre.why": "在按空间中心放置图形的图纸中,此图形会偏离绘制位置相应距离。",
|
|
99
99
|
"figure.gate.origin-off-centre.how": "如果图形固定在该处(如门的铰链),请保持不变。若要按空间放置,请将原点移到中心。",
|
|
100
|
+
"figure.gate.off-mounting-plane.floor.clear.message": "'{part}' 离地面 {mm} mm,悬在空中。",
|
|
101
|
+
"figure.gate.off-mounting-plane.floor.through.message": "'{part}' 低于地面 {mm} mm。",
|
|
102
|
+
"figure.gate.off-mounting-plane.floor.beyond.message": "所有部件都在地面以下。",
|
|
103
|
+
"figure.gate.off-mounting-plane.floor.why": "看板把此图形立在地面上,在任何看板上都会按现在的样子放置。",
|
|
104
|
+
"figure.gate.off-mounting-plane.floor.beyond.how": "如果是吊在天花板上的设备,请把放置位置改为天花板。",
|
|
105
|
+
"figure.gate.off-mounting-plane.ceiling.clear.message": "'{part}' 在天花板下方 {mm} mm。",
|
|
106
|
+
"figure.gate.off-mounting-plane.ceiling.through.message": "'{part}' 高出天花板 {mm} mm。",
|
|
107
|
+
"figure.gate.off-mounting-plane.ceiling.beyond.message": "所有部件都在天花板以上。",
|
|
108
|
+
"figure.gate.off-mounting-plane.ceiling.why": "看板把此图形吊在天花板上,在任何看板上都会按现在的样子放置。",
|
|
109
|
+
"figure.gate.off-mounting-plane.ceiling.beyond.how": "如果是立在地面上的设备,请把放置位置改为地面。",
|
|
110
|
+
"figure.gate.off-mounting-plane.wall.clear.message": "'{part}' 离墙 {mm} mm。",
|
|
111
|
+
"figure.gate.off-mounting-plane.wall.through.message": "'{part}' 嵌入墙内 {mm} mm。",
|
|
112
|
+
"figure.gate.off-mounting-plane.wall.beyond.message": "所有部件都在墙后。",
|
|
113
|
+
"figure.gate.off-mounting-plane.wall.why": "看板把此图形贴在墙上,在任何看板上都会按现在的样子放置。",
|
|
114
|
+
"figure.gate.off-mounting-plane.wall.beyond.how": "请把部件移到墙前,或重新选择放置位置。",
|
|
115
|
+
"figure.gate.off-mounting-plane.how": "如果是有意为之,请保持不变。否则请把该部件固定到安装平面,或移动它直到贴合平面。",
|
|
100
116
|
"error.figure-namespace-missing": "此域没有默认的图形 namespace。请先添加一个。",
|
|
101
117
|
"error.figure-namespace-invalid": "不是 Figure namespace 的格式({value})。请使用小写字母、数字、点和连字符,例如 hatiolab.com。",
|
|
102
118
|
"error.figure-type-malformed": "{type} 不是图形类型。请使用小写字母、数字和单个连字符,长度 {min} 到 {max} 个字符,并以字母开头。",
|