@things-factory/figure-ui 10.1.151 → 10.1.153

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.
Files changed (86) hide show
  1. package/client/modeller/ai-proposal.ts +14 -13
  2. package/client/modeller/command-preview-controller.ts +210 -0
  3. package/client/modeller/editor-styles.ts +307 -0
  4. package/client/modeller/editor.ts +65 -634
  5. package/client/modeller/fasten-geometry.ts +32 -0
  6. package/client/modeller/figure-first-save.ts +9 -1
  7. package/client/modeller/figure-links.ts +32 -14
  8. package/client/modeller/mesh-import.ts +0 -10
  9. package/client/modeller/modeller-keys.ts +60 -0
  10. package/client/modeller/pane-fold.ts +61 -0
  11. package/client/modeller/panel-memory.ts +53 -0
  12. package/client/modeller/refusal-teller.ts +93 -0
  13. package/client/modeller/refusals.ts +32 -2
  14. package/dist-client/modeller/ai-proposal.d.ts +6 -5
  15. package/dist-client/modeller/ai-proposal.js +9 -9
  16. package/dist-client/modeller/ai-proposal.js.map +1 -1
  17. package/dist-client/modeller/clips.d.ts +1 -1
  18. package/dist-client/modeller/command-preview-controller.d.ts +75 -0
  19. package/dist-client/modeller/command-preview-controller.js +178 -0
  20. package/dist-client/modeller/command-preview-controller.js.map +1 -0
  21. package/dist-client/modeller/editor-styles.d.ts +2 -0
  22. package/dist-client/modeller/editor-styles.js +307 -0
  23. package/dist-client/modeller/editor-styles.js.map +1 -0
  24. package/dist-client/modeller/editor.d.ts +5 -56
  25. package/dist-client/modeller/editor.js +76 -656
  26. package/dist-client/modeller/editor.js.map +1 -1
  27. package/dist-client/modeller/fasten-geometry.d.ts +13 -0
  28. package/dist-client/modeller/fasten-geometry.js +29 -0
  29. package/dist-client/modeller/fasten-geometry.js.map +1 -1
  30. package/dist-client/modeller/figure-first-save.d.ts +1 -0
  31. package/dist-client/modeller/figure-first-save.js +8 -1
  32. package/dist-client/modeller/figure-first-save.js.map +1 -1
  33. package/dist-client/modeller/figure-links.d.ts +9 -2
  34. package/dist-client/modeller/figure-links.js +35 -14
  35. package/dist-client/modeller/figure-links.js.map +1 -1
  36. package/dist-client/modeller/mesh-import.d.ts +0 -2
  37. package/dist-client/modeller/mesh-import.js +0 -11
  38. package/dist-client/modeller/mesh-import.js.map +1 -1
  39. package/dist-client/modeller/modeller-keys.d.ts +22 -0
  40. package/dist-client/modeller/modeller-keys.js +43 -0
  41. package/dist-client/modeller/modeller-keys.js.map +1 -0
  42. package/dist-client/modeller/pane-fold.d.ts +15 -0
  43. package/dist-client/modeller/pane-fold.js +60 -0
  44. package/dist-client/modeller/pane-fold.js.map +1 -0
  45. package/dist-client/modeller/panel-memory.d.ts +15 -0
  46. package/dist-client/modeller/panel-memory.js +54 -0
  47. package/dist-client/modeller/panel-memory.js.map +1 -0
  48. package/dist-client/modeller/product-session.d.ts +4 -28
  49. package/dist-client/modeller/refusal-teller.d.ts +36 -0
  50. package/dist-client/modeller/refusal-teller.js +81 -0
  51. package/dist-client/modeller/refusal-teller.js.map +1 -0
  52. package/dist-client/modeller/refusals.d.ts +12 -1
  53. package/dist-client/modeller/refusals.js +26 -1
  54. package/dist-client/modeller/refusals.js.map +1 -1
  55. package/dist-client/tsconfig.tsbuildinfo +1 -1
  56. package/package.json +5 -5
  57. package/test/browser/build.mjs +7 -2
  58. package/test/browser/editing.check.mjs +14 -0
  59. package/test/browser/fix-alignment.check.mjs +112 -0
  60. package/test/browser/links.check.mjs +69 -13
  61. package/test/browser/mesh-select.check.mjs +91 -0
  62. package/test/browser/modeller-page.js +36 -0
  63. package/test/browser/modeller-revision.check.mjs +18 -6
  64. package/test/browser/modeller.check.mjs +25 -0
  65. package/test/browser/part-ids.check.mjs +24 -6
  66. package/test/browser/parts-page.js +9 -1
  67. package/test/browser/parts.check.mjs +61 -2
  68. package/test/browser/places-mesh.check.mjs +25 -9
  69. package/test/browser/product-page.check.mjs +42 -2
  70. package/test/browser/row-preview.check.mjs +81 -0
  71. package/test/browser/screen.check.mjs +35 -1
  72. package/test/clip-ai-proposal.test.ts +4 -1
  73. package/test/clip-consent.test.ts +9 -2
  74. package/test/fields.test.ts +5 -9
  75. package/test/fix-alignment.test.ts +32 -0
  76. package/test/layout.test.ts +3 -1
  77. package/test/mesh-import.test.ts +1 -8
  78. package/test/parts-wiring.test.ts +1 -5
  79. package/test/refusals.test.ts +46 -10
  80. package/test/theme.test.ts +5 -15
  81. package/translations/en.json +8 -0
  82. package/translations/es.json +8 -0
  83. package/translations/ja.json +8 -0
  84. package/translations/ko.json +8 -0
  85. package/translations/ms.json +8 -0
  86. package/translations/zh.json +8 -0
@@ -14,6 +14,7 @@ import { DEFAULT_VIEW, WORKBENCH } from '../client/modeller/figure-view.ts'
14
14
 
15
15
  const read = (path: string) => readFileSync(fileURLToPath(new URL(path, import.meta.url)), 'utf8')
16
16
  const editor = read('../client/modeller/editor.ts')
17
+ const styles = read('../client/modeller/editor-styles.ts')
17
18
 
18
19
  /** Hex colours that are not a `var(--token, #fallback)` fallback. */
19
20
  const fixed = (text: string) =>
@@ -23,6 +24,7 @@ const fixed = (text: string) =>
23
24
 
24
25
  test('편집기에 박힌 색이 없다 — 토큰의 대체값만 남는다', () => {
25
26
  assert.deepEqual(fixed(editor), [], 'editor.ts')
27
+ assert.deepEqual(fixed(styles), [], 'editor-styles.ts')
26
28
  })
27
29
 
28
30
  test('캔버스 바탕은 작업대 회색 — 판의 하늘색이라 환경 탭에서 바꾼다', () => {
@@ -30,23 +32,11 @@ test('캔버스 바탕은 작업대 회색 — 판의 하늘색이라 환경 탭
30
32
  assert.equal(DEFAULT_VIEW.skyColor, WORKBENCH, '3D 바탕의 처음 값도 작업대 회색')
31
33
  })
32
34
 
33
- test('눌린 단추는 셸이 두 테마 대비를 맞춘 칸을 쓴다 — 오류는 앱의 알림이 그린다 (2026-09-27)', () => {
34
- const pressed = editor.slice(editor.indexOf("button[aria-pressed='true']"), editor.indexOf('}', editor.indexOf("button[aria-pressed='true']")))
35
- assert.match(pressed, /--md-sys-color-secondary-container\)/)
36
- assert.match(pressed, /--md-sys-color-on-secondary-container\)/)
37
- assert.match(pressed, /border-color: var\(--md-sys-color-primary\)/)
38
- })
39
-
40
35
  test('편집기는 창이 아니라 자기 폭으로 접는다 — 레일이 폭을 먼저 가져간다', () => {
41
36
  /* The widths - 200 | 1fr | 340, 160 | 300 under 860px, one column with the canvas first under 560px - are
42
37
  ox-three-pane's, measured in @operato/layout's own test. The editor must not write the grid again. */
43
- assert.doesNotMatch(editor, /@media \(max-width/, '창 폭 기준이 남아 있다 — 레일을 펼치면 편집기가 넘친다')
44
- assert.doesNotMatch(editor, /grid-template-columns/, '편집기가 격자를 다시 쓰지 않는다')
38
+ assert.doesNotMatch(editor + styles, /@media \(max-width/, '창 폭 기준이 남아 있다 — 레일을 펼치면 편집기가 넘친다')
39
+ assert.doesNotMatch(editor + styles, /grid-template-columns/, '편집기가 격자를 다시 쓰지 않는다')
45
40
  })
46
41
 
47
- test('양쪽 칸은 띠에서 접는다 — 접으면 캔버스가 그 폭을 갖고, 오른쪽 칸은 무엇도 가리지 않는다', () => {
48
- /* The bar folding the editor's own frame, and the canvas taking the width, are the browser check's (test/browser/screen.check.mjs). */
49
- const aside = editor.slice(editor.indexOf(' aside {'), editor.indexOf('}', editor.indexOf(' aside {')))
50
- assert.doesNotMatch(aside, /z-index/)
51
- assert.doesNotMatch(aside, /border-left/, '칸 경계선은 틀이 긋는다 — 두 줄이 되지 않게')
52
- })
42
+ /* A pressed button drawn in the shell's containers, and the side drawing no edge and stacking over nothing, are the browser check's (test/browser/screen.check.mjs). */
@@ -59,6 +59,12 @@
59
59
  "figure.text.row-copies-over-limit": "At this pitch the row has {count} copies. A row takes up to {limit}. Widen the pitch.",
60
60
  "figure.text.row-geometry-over-limit": "Laid out, the row would draw {count} bodies. A figure draws up to {limit}.",
61
61
  "figure.text.row-copies-out-of-range": "A row has {min} to {max} copies. Given: {count}",
62
+ "figure.text.row-does-not-fit": "{count} do not fit in {length} mm: each is {extent} mm. Make fewer, or make the part smaller.",
63
+ "figure.text.row-same-axis": "{outer}'s row already runs along {axis}. A row of {part} inside it runs along another axis.",
64
+ "figure.text.row-face-held-slot-layout": "The slot layout stands on a face of {part}, so it cannot be made a row. Move that anchor of the slot layout first.",
65
+ "figure.text.row-face-held-place": "A place is on a face of {part}, so it cannot be made a row. Remove that place first.",
66
+ "figure.text.row-face-held-footprint": "The figure's room is measured from a face of {part}, so it cannot be made a row. Change the room first.",
67
+ "figure.text.row-face-held-other": "A face of {part} is used elsewhere, so it cannot be made a row.",
62
68
  "figure.text.gizmo-joint-places": "a joint places {part}. move it with its control in the motion tab.",
63
69
  "figure.label.motion-continuous": "turn without end",
64
70
  "figure.text.fasten-before-moving": "fasten it to another part or the floor first; then it can move.",
@@ -549,6 +555,8 @@
549
555
  "figure.text.overhang-side-low": "{axis} low side {mm} mm",
550
556
  "figure.text.overhang-side-high": "{axis} high side {mm} mm",
551
557
  "figure.button.fix-alignment": "change alignment and gap",
558
+ "figure.text.fix-alignment-inside": "{part} is inside the face. What is out is a part fastened on {part}: pick that part to fix it.",
559
+ "figure.text.fix-alignment-unmeasured": "The face of {on} cannot be measured, so it cannot be lined up for you. Drag the part in the drawing below.",
552
560
  "figure.text.detach-moves": "Detached, it moves:",
553
561
  "figure.text.detach-keeps-children": "Parts fastened to it ({parts}) stay fastened to it.",
554
562
  "figure.text.detach-clips": "Detaching removes clips: {clips}. You will be asked when you detach.",
@@ -59,6 +59,12 @@
59
59
  "figure.text.row-copies-over-limit": "Con este paso la fila tiene {count} copias. Una fila admite hasta {limit}. Amplíe el paso.",
60
60
  "figure.text.row-geometry-over-limit": "Desplegada, la fila dibujaría {count} cuerpos. Una figura dibuja hasta {limit}.",
61
61
  "figure.text.row-copies-out-of-range": "Una fila tiene de {min} a {max} copias. Valor dado: {count}",
62
+ "figure.text.row-does-not-fit": "{count} no caben en {length} mm: cada una mide {extent} mm. Ponga menos o haga la pieza más pequeña.",
63
+ "figure.text.row-same-axis": "La fila de {outer} ya va a lo largo de {axis}. Una fila de {part} dentro de ella va por otro eje.",
64
+ "figure.text.row-face-held-slot-layout": "La disposición de huecos se apoya en una cara de {part}, así que no puede convertirse en fila. Cambie antes esa referencia de la disposición.",
65
+ "figure.text.row-face-held-place": "Hay un lugar en una cara de {part}, así que no puede convertirse en fila. Quite antes ese lugar.",
66
+ "figure.text.row-face-held-footprint": "El espacio de la figura se mide desde una cara de {part}, así que no puede convertirse en fila. Cambie antes ese espacio.",
67
+ "figure.text.row-face-held-other": "Una cara de {part} se usa en otro lugar, así que no puede convertirse en fila.",
62
68
  "figure.text.gizmo-joint-places": "una articulación coloca {part}. muévala con su control en la pestaña de movimiento.",
63
69
  "figure.label.motion-continuous": "girar sin fin",
64
70
  "figure.text.fasten-before-moving": "primero sujétela a otra pieza o al suelo; después podrá moverse.",
@@ -549,6 +555,8 @@
549
555
  "figure.text.overhang-side-low": "{axis} lado inferior {mm} mm",
550
556
  "figure.text.overhang-side-high": "{axis} lado superior {mm} mm",
551
557
  "figure.button.fix-alignment": "cambiar alineación y separación",
558
+ "figure.text.fix-alignment-inside": "{part} está dentro de la cara. Lo que sobresale es una pieza sujeta a {part}: selecciónela para corregirla.",
559
+ "figure.text.fix-alignment-unmeasured": "No se puede medir la cara de {on}, así que no se puede alinear automáticamente. Arrastre la pieza en el dibujo de abajo.",
552
560
  "figure.text.detach-moves": "Al separarla, se mueve:",
553
561
  "figure.text.detach-keeps-children": "Las piezas sujetas a ella ({parts}) siguen sujetas a ella.",
554
562
  "figure.text.detach-clips": "Al separarla se eliminan clips: {clips}. Se le preguntará al separarla.",
@@ -59,6 +59,12 @@
59
59
  "figure.text.row-copies-over-limit": "この間隔では列が {count} 個になります。1 列は {limit} 個までです。間隔を広げてください。",
60
60
  "figure.text.row-geometry-over-limit": "列を展開すると形状が {count} 個になります。図形は {limit} 個まで描きます。",
61
61
  "figure.text.row-copies-out-of-range": "列の個数は {min}~{max} 個です。入力値: {count}",
62
+ "figure.text.row-does-not-fit": "{count} 個は {length} mm に収まりません。1 個が {extent} mm です。個数を減らすか部品を小さくしてください。",
63
+ "figure.text.row-same-axis": "{outer} の列はすでに {axis} 方向です。{part} の列は別の方向に並べてください。",
64
+ "figure.text.row-face-held-slot-layout": "{part} の面を場所の配置が基準面として使っているため、列にできません。先に場所の配置の基準面を変えてください。",
65
+ "figure.text.row-face-held-place": "{part} の面に場所があるため、列にできません。先にその場所を削除してください。",
66
+ "figure.text.row-face-held-footprint": "{part} の面が占有空間の基準のため、列にできません。先に占有空間を変えてください。",
67
+ "figure.text.row-face-held-other": "{part} の面がほかで使われているため、列にできません。",
62
68
  "figure.text.gizmo-joint-places": "{part} は関節に付いていて、関節が位置を決めます。動きタブの操作値で動かしてください。",
63
69
  "figure.label.motion-continuous": "無限回転",
64
70
  "figure.text.fasten-before-moving": "先に他の部品か床に取り付けると、動きを付けられます。",
@@ -549,6 +555,8 @@
549
555
  "figure.text.overhang-side-low": "{axis} 低い側 {mm} mm",
550
556
  "figure.text.overhang-side-high": "{axis} 高い側 {mm} mm",
551
557
  "figure.button.fix-alignment": "位置合わせ・間隔を直す",
558
+ "figure.text.fix-alignment-inside": "{part} は面の内側にあります。はみ出しているのは {part} に付いた部品です。その部品を選んで直してください。",
559
+ "figure.text.fix-alignment-unmeasured": "{on} の面の大きさを測れないため、自動では合わせられません。下の図で部品をドラッグして動かしてください。",
552
560
  "figure.text.detach-moves": "外すと位置が変わります:",
553
561
  "figure.text.detach-keeps-children": "この部品に取り付いた部品({parts})はそのまま取り付いています。",
554
562
  "figure.text.detach-clips": "外すとクリップが削除されます: {clips}。外すときにもう一度確認します。",
@@ -59,6 +59,12 @@
59
59
  "figure.text.row-copies-over-limit": "간격이 좁아 줄이 {count}개가 됩니다. 한 줄은 {limit}개까지입니다. 간격을 넓혀 주세요.",
60
60
  "figure.text.row-geometry-over-limit": "줄을 펼치면 형상이 {count}개가 됩니다. 도형은 {limit}개까지 그립니다.",
61
61
  "figure.text.row-copies-out-of-range": "줄의 개수는 {min}~{max}개입니다. 넣은 값: {count}",
62
+ "figure.text.row-does-not-fit": "{count}개가 {length} mm 안에 들어가지 않습니다. 하나가 {extent} mm입니다. 개수를 줄이거나 부품을 줄여 주세요.",
63
+ "figure.text.row-same-axis": "{outer}의 줄이 이미 {axis} 방향입니다. {part}의 줄은 다른 방향으로 늘어나야 합니다.",
64
+ "figure.text.row-face-held-slot-layout": "{part}의 면을 자리 배치가 기준면으로 쓰고 있어 줄로 바꿀 수 없습니다. 자리 배치의 기준면을 먼저 바꿔 주세요.",
65
+ "figure.text.row-face-held-place": "{part}의 면에 자리가 있어 줄로 바꿀 수 없습니다. 그 자리를 먼저 지워 주세요.",
66
+ "figure.text.row-face-held-footprint": "{part}의 면이 점유 공간의 기준이라 줄로 바꿀 수 없습니다. 점유 공간을 먼저 바꿔 주세요.",
67
+ "figure.text.row-face-held-other": "{part}의 면을 다른 곳에서 쓰고 있어 줄로 바꿀 수 없습니다.",
62
68
  "figure.text.gizmo-joint-places": "{part} 부품은 관절에 달려 있어 관절이 자리를 정합니다. 움직임 탭의 조작값으로 움직이세요.",
63
69
  "figure.label.motion-continuous": "끝없이 회전",
64
70
  "figure.text.fasten-before-moving": "먼저 다른 부품이나 바닥에 붙여야 움직임을 줄 수 있습니다.",
@@ -549,6 +555,8 @@
549
555
  "figure.text.overhang-side-low": "{axis} 낮은 쪽 {mm} mm",
550
556
  "figure.text.overhang-side-high": "{axis} 높은 쪽 {mm} mm",
551
557
  "figure.button.fix-alignment": "정렬·간격 고치기",
558
+ "figure.text.fix-alignment-inside": "{part}은(는) 면 안에 있습니다. 밖으로 나온 것은 {part}에 붙은 부품이니, 그 부품을 골라 고쳐 주세요.",
559
+ "figure.text.fix-alignment-unmeasured": "{on}의 면 크기를 잴 수 없어 자동으로 맞출 수 없습니다. 아래 그림에서 끌어 옮겨 주세요.",
552
560
  "figure.text.detach-moves": "떼면 자리가 바뀝니다:",
553
561
  "figure.text.detach-keeps-children": "이 부품에 붙은 부품({parts})은 그대로 이 부품에 붙어 있습니다.",
554
562
  "figure.text.detach-clips": "떼면 클립이 지워집니다: {clips}. 뗄 때 다시 묻습니다.",
@@ -59,6 +59,12 @@
59
59
  "figure.text.row-copies-over-limit": "Pada jarak ini barisan mempunyai {count} salinan. Satu barisan mengambil sehingga {limit}. Lebarkan jarak.",
60
60
  "figure.text.row-geometry-over-limit": "Apabila dibentangkan, barisan akan melukis {count} jasad. Rajah melukis sehingga {limit}.",
61
61
  "figure.text.row-copies-out-of-range": "Satu barisan mempunyai {min} hingga {max} salinan. Diberi: {count}",
62
+ "figure.text.row-does-not-fit": "{count} tidak muat dalam {length} mm: setiap satu {extent} mm. Kurangkan bilangan atau kecilkan bahagian.",
63
+ "figure.text.row-same-axis": "Baris {outer} sudah berjalan sepanjang {axis}. Baris {part} di dalamnya mesti berjalan pada paksi lain.",
64
+ "figure.text.row-face-held-slot-layout": "Susun atur slot berdiri pada permukaan {part}, jadi ia tidak boleh dijadikan baris. Tukar sauh susun atur slot itu dahulu.",
65
+ "figure.text.row-face-held-place": "Ada tempat pada permukaan {part}, jadi ia tidak boleh dijadikan baris. Buang tempat itu dahulu.",
66
+ "figure.text.row-face-held-footprint": "Ruang rajah diukur dari permukaan {part}, jadi ia tidak boleh dijadikan baris. Tukar ruang rajah dahulu.",
67
+ "figure.text.row-face-held-other": "Permukaan {part} digunakan di tempat lain, jadi ia tidak boleh dijadikan baris.",
62
68
  "figure.text.gizmo-joint-places": "sendi menentukan kedudukan {part}. gerakkannya dengan kawalannya di tab gerakan.",
63
69
  "figure.label.motion-continuous": "putaran tanpa henti",
64
70
  "figure.text.fasten-before-moving": "lekatkan pada bahagian lain atau lantai dahulu; kemudian ia boleh bergerak.",
@@ -549,6 +555,8 @@
549
555
  "figure.text.overhang-side-low": "{axis} sisi bawah {mm} mm",
550
556
  "figure.text.overhang-side-high": "{axis} sisi atas {mm} mm",
551
557
  "figure.button.fix-alignment": "ubah penjajaran dan jarak",
558
+ "figure.text.fix-alignment-inside": "{part} berada di dalam permukaan. Yang terkeluar ialah bahagian yang diikat pada {part}: pilih bahagian itu untuk membetulkannya.",
559
+ "figure.text.fix-alignment-unmeasured": "Permukaan {on} tidak dapat diukur, jadi ia tidak dapat dijajarkan secara automatik. Seret bahagian dalam lukisan di bawah.",
552
560
  "figure.text.detach-moves": "Apabila ditanggalkan, ia bergerak:",
553
561
  "figure.text.detach-keeps-children": "Bahagian yang dilekatkan padanya ({parts}) kekal dilekatkan.",
554
562
  "figure.text.detach-clips": "Menanggalkan membuang klip: {clips}. Anda akan ditanya semasa menanggalkan.",
@@ -59,6 +59,12 @@
59
59
  "figure.text.row-copies-over-limit": "此间距下一排有 {count} 个。一排最多 {limit} 个。请加大间距。",
60
60
  "figure.text.row-geometry-over-limit": "展开后这一排有 {count} 个形体。图形最多绘制 {limit} 个。",
61
61
  "figure.text.row-copies-out-of-range": "一排的数量为 {min}~{max} 个。输入值: {count}",
62
+ "figure.text.row-does-not-fit": "{length} mm 内放不下 {count} 个:每个 {extent} mm。请减少个数或缩小部件。",
63
+ "figure.text.row-same-axis": "{outer} 的排列已沿 {axis} 方向。{part} 的排列须沿另一个方向。",
64
+ "figure.text.row-face-held-slot-layout": "位置布局以 {part} 的面为基准面,因此不能改为排列。请先更改位置布局的基准面。",
65
+ "figure.text.row-face-held-place": "{part} 的面上有位置,因此不能改为排列。请先删除该位置。",
66
+ "figure.text.row-face-held-footprint": "占用空间以 {part} 的面为基准,因此不能改为排列。请先更改占用空间。",
67
+ "figure.text.row-face-held-other": "{part} 的面在别处被使用,因此不能改为排列。",
62
68
  "figure.text.gizmo-joint-places": "{part} 由关节决定位置。请用运动标签中的控制值移动它。",
63
69
  "figure.label.motion-continuous": "无限旋转",
64
70
  "figure.text.fasten-before-moving": "请先将其固定到其他部件或地面上,然后才能添加运动。",
@@ -549,6 +555,8 @@
549
555
  "figure.text.overhang-side-low": "{axis} 低侧 {mm} mm",
550
556
  "figure.text.overhang-side-high": "{axis} 高侧 {mm} mm",
551
557
  "figure.button.fix-alignment": "修改对齐和间距",
558
+ "figure.text.fix-alignment-inside": "{part} 在面内。超出的是固定在 {part} 上的部件,请选中该部件进行修正。",
559
+ "figure.text.fix-alignment-unmeasured": "无法测量 {on} 的面,因此无法自动对齐。请在下方图中拖动部件。",
552
560
  "figure.text.detach-moves": "拆下后位置会改变:",
553
561
  "figure.text.detach-keeps-children": "附着在此部件上的部件({parts})仍附着在它上面。",
554
562
  "figure.text.detach-clips": "拆下会删除片段:{clips}。拆下时会再次确认。",