@things-factory/figure-ui 10.1.271 → 10.1.273

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 (112) hide show
  1. package/client/modeller/canvas.ts +4 -2
  2. package/client/modeller/clips.ts +74 -4
  3. package/client/modeller/data-interface.ts +30 -18
  4. package/client/modeller/editor-styles.ts +17 -6
  5. package/client/modeller/editor.ts +2 -0
  6. package/client/modeller/fasten-form.ts +81 -6
  7. package/client/modeller/fasten-geometry.ts +5 -3
  8. package/client/modeller/figure-cavity-drawing.ts +1 -3
  9. package/client/modeller/figure-clips.ts +101 -8
  10. package/client/modeller/figure-data-panel.ts +384 -200
  11. package/client/modeller/figure-fasten-dialog.ts +41 -30
  12. package/client/modeller/figure-fasten-drawing.ts +24 -14
  13. package/client/modeller/figure-first-save.ts +4 -3
  14. package/client/modeller/figure-links.ts +109 -37
  15. package/client/modeller/figure-parts.ts +7 -11
  16. package/client/modeller/figure-preview.ts +299 -79
  17. package/client/modeller/figure-size-editor.ts +7 -2
  18. package/client/modeller/first-save.ts +8 -0
  19. package/client/modeller/focus-on-render.ts +4 -0
  20. package/client/modeller/pivot.ts +76 -0
  21. package/client/modeller/size-response.ts +14 -0
  22. package/client/modeller/stage-model.ts +50 -6
  23. package/dist-client/modeller/canvas.d.ts +1 -0
  24. package/dist-client/modeller/canvas.js +3 -2
  25. package/dist-client/modeller/canvas.js.map +1 -1
  26. package/dist-client/modeller/clips.d.ts +17 -3
  27. package/dist-client/modeller/clips.js +69 -4
  28. package/dist-client/modeller/clips.js.map +1 -1
  29. package/dist-client/modeller/data-interface.d.ts +11 -8
  30. package/dist-client/modeller/data-interface.js +27 -17
  31. package/dist-client/modeller/data-interface.js.map +1 -1
  32. package/dist-client/modeller/editor-styles.js +17 -6
  33. package/dist-client/modeller/editor-styles.js.map +1 -1
  34. package/dist-client/modeller/editor.js +2 -0
  35. package/dist-client/modeller/editor.js.map +1 -1
  36. package/dist-client/modeller/fasten-form.d.ts +13 -0
  37. package/dist-client/modeller/fasten-form.js +72 -7
  38. package/dist-client/modeller/fasten-form.js.map +1 -1
  39. package/dist-client/modeller/fasten-geometry.d.ts +3 -2
  40. package/dist-client/modeller/fasten-geometry.js +5 -3
  41. package/dist-client/modeller/fasten-geometry.js.map +1 -1
  42. package/dist-client/modeller/figure-cavity-drawing.js +1 -3
  43. package/dist-client/modeller/figure-cavity-drawing.js.map +1 -1
  44. package/dist-client/modeller/figure-clips.d.ts +9 -0
  45. package/dist-client/modeller/figure-clips.js +104 -8
  46. package/dist-client/modeller/figure-clips.js.map +1 -1
  47. package/dist-client/modeller/figure-data-panel.d.ts +10 -19
  48. package/dist-client/modeller/figure-data-panel.js +382 -190
  49. package/dist-client/modeller/figure-data-panel.js.map +1 -1
  50. package/dist-client/modeller/figure-fasten-dialog.js +39 -24
  51. package/dist-client/modeller/figure-fasten-dialog.js.map +1 -1
  52. package/dist-client/modeller/figure-fasten-drawing.js +24 -14
  53. package/dist-client/modeller/figure-fasten-drawing.js.map +1 -1
  54. package/dist-client/modeller/figure-first-save.js +4 -3
  55. package/dist-client/modeller/figure-first-save.js.map +1 -1
  56. package/dist-client/modeller/figure-links.d.ts +9 -0
  57. package/dist-client/modeller/figure-links.js +120 -51
  58. package/dist-client/modeller/figure-links.js.map +1 -1
  59. package/dist-client/modeller/figure-parts.js +7 -11
  60. package/dist-client/modeller/figure-parts.js.map +1 -1
  61. package/dist-client/modeller/figure-preview.d.ts +13 -0
  62. package/dist-client/modeller/figure-preview.js +296 -80
  63. package/dist-client/modeller/figure-preview.js.map +1 -1
  64. package/dist-client/modeller/figure-size-editor.js +7 -3
  65. package/dist-client/modeller/figure-size-editor.js.map +1 -1
  66. package/dist-client/modeller/first-save.d.ts +5 -0
  67. package/dist-client/modeller/first-save.js +7 -0
  68. package/dist-client/modeller/first-save.js.map +1 -1
  69. package/dist-client/modeller/focus-on-render.d.ts +2 -0
  70. package/dist-client/modeller/focus-on-render.js +4 -0
  71. package/dist-client/modeller/focus-on-render.js.map +1 -0
  72. package/dist-client/modeller/pivot.d.ts +12 -0
  73. package/dist-client/modeller/pivot.js +59 -0
  74. package/dist-client/modeller/pivot.js.map +1 -0
  75. package/dist-client/modeller/size-response.d.ts +6 -0
  76. package/dist-client/modeller/size-response.js +14 -0
  77. package/dist-client/modeller/size-response.js.map +1 -1
  78. package/dist-client/modeller/stage-model.d.ts +17 -3
  79. package/dist-client/modeller/stage-model.js +44 -6
  80. package/dist-client/modeller/stage-model.js.map +1 -1
  81. package/dist-client/tsconfig.tsbuildinfo +1 -1
  82. package/package.json +8 -7
  83. package/test/browser/editing-page.js +1 -1
  84. package/test/browser/editing.check.mjs +6 -5
  85. package/test/browser/links.check.mjs +30 -0
  86. package/test/browser/modeller.check.mjs +2 -2
  87. package/test/browser/parts-page.js +4 -0
  88. package/test/browser/parts.check.mjs +16 -10
  89. package/test/browser/screen-page.js +12 -1
  90. package/test/browser/screen.check.mjs +142 -11
  91. package/test/browser/section.check.mjs +21 -0
  92. package/test/browser/serve-response.mjs +5 -2
  93. package/test/browser/side-panel-sweep.check.mjs +171 -10
  94. package/test/clips.test.ts +49 -4
  95. package/test/data-motion.test.ts +39 -8
  96. package/test/fasten-form.test.ts +69 -0
  97. package/test/fasten-geometry.test.ts +13 -0
  98. package/test/first-save.test.ts +11 -1
  99. package/test/pivot.test.ts +57 -0
  100. package/test/size-response.test.ts +10 -2
  101. package/test/stage-model.test.ts +23 -1
  102. package/translations/en.json +31 -11
  103. package/translations/es.json +30 -10
  104. package/translations/ja.json +30 -10
  105. package/translations/ko.json +32 -12
  106. package/translations/ms.json +30 -10
  107. package/translations/zh.json +30 -10
  108. package/tutorial/humanoid/README.md +22 -0
  109. package/tutorial/humanoid/chapters.mjs +247 -0
  110. package/tutorial/humanoid/encode.mjs +26 -0
  111. package/tutorial/humanoid/lib.mjs +197 -0
  112. package/tutorial/humanoid/record.mjs +65 -0
@@ -1,7 +1,8 @@
1
1
  import { test } from 'node:test'
2
2
  import assert from 'node:assert/strict'
3
- import { applyFigureAuthoring, compileFigureAsset, figureRowOf, figureFollowOf } from '@hatiolab/figure-model'
4
- import { sizeRelationSteps, sizeRelationOf, sizeInputOf } from '../client/modeller/size-response.ts'
3
+ import { addFigureBox, addFigurePrimitive, applyFigureAuthoring, compileFigureAsset, createFigureAsset, figureRowOf, figureFollowOf } from '@hatiolab/figure-model'
4
+ import { sizeAxisWord, sizeRelationSteps, sizeRelationOf, sizeInputOf } from '../client/modeller/size-response.ts'
5
+ import { followableAxes } from '../client/modeller/links.ts'
5
6
  import type { FigureRevision } from '../client/modeller/revision.ts'
6
7
  import { multipartResponseFixture } from './multipart-response-fixture.js'
7
8
  const revision = (asset: ReturnType<typeof multipartResponseFixture>) => ({ asset, inputs: asset.designInputs } as FigureRevision)
@@ -47,3 +48,10 @@ test('repeat settings can change count, direction and mode without losing the at
47
48
  assert.deepEqual(a.joints!.find(j=>j.body1.part==='legLeft')!.body0,initial.body0)
48
49
  assert.deepEqual(figureFollowOf(a,'brace','x'),{of:'part',part:'tabletop',axis:'x',plus:-200})
49
50
  })
51
+
52
+ test('a round body names the diameter that sets the axis it has no row for: X·Z across, Y up (tutorial 2026-11-12)', () => {
53
+ const ball = addFigurePrimitive(createFigureAsset('Ball'), { id: 'ball', kind: 'sphere', dimensions: { radius: 100, radiusY: 120 }, position: { x: 0, y: 0, z: 0 } } as never)
54
+ assert.deepEqual(followableAxes(ball, 'ball').map(a => sizeAxisWord(ball, 'ball', a, '지름')), ['X·Z · 지름', 'Y · 지름'])
55
+ const block = addFigureBox(createFigureAsset('Block'), { id: 'block', size: { x: 10, y: 20, z: 30 }, position: { x: 0, y: 0, z: 0 } })
56
+ assert.deepEqual(followableAxes(block, 'block').map(a => sizeAxisWord(block, 'block', a, '지름')), ['X', 'Y', 'Z'])
57
+ })
@@ -9,7 +9,7 @@ import assert from 'node:assert/strict'
9
9
  import { addFigureBox, compileFigureAsset, createFigureAsset } from '@hatiolab/figure-model'
10
10
 
11
11
  import { drawableFigureParts } from '../client/modeller/renderer.ts'
12
- import { boardFor, needsRefit } from '../client/modeller/stage-model.ts'
12
+ import { boardFor, drawnSpanOf, needsRefit, outgrowsFit } from '../client/modeller/stage-model.ts'
13
13
 
14
14
  const partsOf = (height: number) =>
15
15
  drawableFigureParts(
@@ -33,3 +33,25 @@ test('a size typed far from the view brings the camera to it; a nudge does not (
33
33
  assert.equal(needsRefit(boardFor(parts(3000, 800, 600)), boardFor(parts(100, 100, 100))), true, 'shrunk far: fitted again')
34
34
  assert.equal(needsRefit(undefined, boardFor(parts(3000, 800, 600))), false, 'never fitted: the first standing fits it')
35
35
  })
36
+
37
+ test('the view follows a figure that grows past the fit, or stands higher off the floor (review 2026-11-11)', () => {
38
+ const at = (height: number, y: number) =>
39
+ drawableFigureParts(compileFigureAsset(addFigureBox(createFigureAsset('P'), { id: 'p', size: { x: 300, y: height, z: 200 }, position: { x: 0, y, z: 0 } })).evaluate().geometry)
40
+ /* A pelvis 180 mm tall put 880 mm up: as tall as it stands from the floor, not as its own height. */
41
+ const onFloor = boardFor(at(180, 90))
42
+ const raised = boardFor(at(180, 970))
43
+ assert.ok(raised.depth >= 1060, `reached from the floor: ${raised.depth}`)
44
+ assert.equal(needsRefit(onFloor, raised), true, 'raised far: the view follows it up')
45
+ /* A head added on a 1.56 m body: 1.8 m runs past the fit's margin. */
46
+ assert.equal(needsRefit(boardFor(at(680, 1220)), boardFor(at(920, 1340))), true)
47
+ /* A nudge inside the fit's margin leaves the camera where the author put it. */
48
+ assert.equal(needsRefit(boardFor(at(680, 1220)), boardFor(at(700, 1230))), false)
49
+ })
50
+
51
+ test('the view follows a part hung below what it was fitted round (review 2026-11-11)', () => {
52
+ const body = drawnSpanOf(partsOf(500))
53
+ const longer = drawnSpanOf(partsOf(800))
54
+ assert.equal(outgrowsFit(body, longer), true, 'reaching 300 mm past the top')
55
+ assert.equal(outgrowsFit(body, drawnSpanOf(partsOf(520))), false, 'a little taller stays in view')
56
+ assert.equal(outgrowsFit(undefined, longer), false)
57
+ })
@@ -484,6 +484,8 @@
484
484
  "figure.text.pick-a-shape-above-to-start": "pick a shape above to add the first part.",
485
485
  "figure.text.placement-explained": "sets the anchor plane in 3D scene (floor: AGV/conveyor, ceiling: OHT/hoist, center: sensor/drone).",
486
486
  "figure.text.pose-as-default-explained": "Writes the pose you have set as the parameters’ defaults, so the figure stands like this when nobody gives it a value.",
487
+ "figure.text.control-played": "Playing",
488
+ "figure.text.control-played-explained": "The {clip} clip is moving this control. Stop the clip to give it a value.",
487
489
  "figure.text.clear-tried-explained": "clears the control values tried here. the saved default pose is unchanged, and the clips move the figure again.",
488
490
  "figure.text.preview-blocked-by-errors": "cannot show the preview because of format errors. see the check tab for the reason.",
489
491
  "figure.text.put-on-floor": "Moves the part once so its bottom is on the floor (Y=0). It does not stay there when the size changes; for that, use “Follow size, attached to the floor”.",
@@ -715,6 +717,10 @@
715
717
  "figure.label.motion-own-control": "its own control",
716
718
  "figure.label.motion-multiplier": "multiplier",
717
719
  "figure.label.motion-offset": "offset",
720
+ "figure.label.pivot-at": "turn about",
721
+ "figure.label.pivot-top": "top end",
722
+ "figure.label.pivot-middle": "middle",
723
+ "figure.label.pivot-bottom": "bottom end",
718
724
  "figure.label.motion-through": "axis passes through",
719
725
  "figure.label.motion-follows": "moves with {joint} × {multiplier} + {offset}",
720
726
  "figure.label.face-opening-left": "opening left",
@@ -1020,6 +1026,7 @@
1020
1026
  "figure.text.slot-id-taken": "{slot} is already the name of a place in this figure.",
1021
1027
  "figure.label.placement": "fastening",
1022
1028
  "figure.label.motion-groups": "motion groups",
1029
+ "figure.label.motion-group-named": "motion",
1023
1030
  "figure.label.motion-group": "motion group",
1024
1031
  "figure.label.no-motion-group": "no group",
1025
1032
  "figure.label.motion-group-name": "name",
@@ -1045,12 +1052,12 @@
1045
1052
  "figure.label.data-scale": "scale",
1046
1053
  "figure.label.data-offset": "offset",
1047
1054
  "figure.label.data-sample": "sample data",
1048
- "figure.text.data-sample-explained": "Enter one record as JSON to see what it moves. It is read the way a figure on a board reads its data, and not saved.",
1049
- "figure.text.data-sample-moves-all": "A position in the data moves every figure in the preview to it; on a board, figures given the same value stand in the same place too.",
1055
+ "figure.text.data-sample-explained": "Enter one record as JSON or JSON5 to see what it moves. It is read the way a figure on a board reads its data, and not saved.",
1050
1056
  "figure.label.data-sample-in-preview": "apply to the preview",
1057
+ "figure.text.data-sample-shown-in-preview": "The sample shows in the preview; the edit view keeps the figure as made.",
1058
+ "figure.button.data-sample-show-preview": "Show the preview",
1051
1059
  "figure.label.data-schema": "data shape",
1052
1060
  "figure.text.data-schema-explained": "The shape of the data a site sends this figure. Name each field as the site's data names it; group fields in objects and lists.",
1053
- "figure.label.data-bound": "{count} bound",
1054
1061
  "figure.text.data-no-fields": "Add a field to the data shape first.",
1055
1062
  "figure.label.data-name": "field name",
1056
1063
  "figure.label.data-label": "display name",
@@ -1061,17 +1068,18 @@
1061
1068
  "figure.button.remove-data-field": "remove the field",
1062
1069
  "figure.label.data-from-sample": "make from a sample",
1063
1070
  "figure.text.data-from-sample-explained": "Paste one record of the site's data to guess its fields. Units, ranges and value lists are not guessed; set them after.",
1064
- "figure.text.data-not-json": "This is not JSON.",
1071
+ "figure.text.data-not-json": "This is not JSON or JSON5.",
1065
1072
  "figure.text.data-guessed": "{count} fields found.",
1066
1073
  "figure.text.data-guessed-replaces": "{count} fields found. Using them replaces the current data shape.",
1067
1074
  "figure.button.data-use-guessed": "use this shape",
1068
- "figure.text.data-bindings-explained": "Connects data values to the figure. A number shows as it is, scaled, or by a range table; a text or true/false by a code table. A table sets, per value, parts' colour and effect, controls and a motion group at once. Select a row to edit it.",
1069
- "figure.label.data-field": "data value",
1075
+ "figure.text.data-bindings-explained": "Connects data values to the figure. A number applies unchanged, scaled, or by a range table; a text or true/false by a code table. A table sets, per value, parts' colour and effect, controls and a motion group at once. Select a row to edit it.",
1070
1076
  "figure.label.data-behavior": "behaviour",
1071
1077
  "figure.label.data-seconds": "travel time (s)",
1072
1078
  "figure.label.data-paused": "paused",
1073
1079
  "figure.label.data-playing": "playing",
1074
1080
  "figure.label.data-otherwise": "any other value",
1081
+ "figure.label.data-keep": "keep as is",
1082
+ "figure.text.data-keep": "A value with no row of its own leaves the look this table last showed.",
1075
1083
  "figure.label.data-range-from": "from",
1076
1084
  "figure.label.data-range-to": "below",
1077
1085
  "figure.button.add-data-range": "add an interval",
@@ -1094,7 +1102,6 @@
1094
1102
  "figure.button.data-add-rotation": "make the rotation",
1095
1103
  "figure.label.data-none": "none",
1096
1104
  "figure.button.remove-data-binding": "remove the binding",
1097
- "figure.label.data-items-count": "{count} items",
1098
1105
  "figure.text.data-value-not-a-list": "{path}: not a list.",
1099
1106
  "figure.text.data-value-value-unknown": "{path}: not one of its values.",
1100
1107
  "figure.text.data-value-json-unreadable": "{path}: the JSON text cannot be read.",
@@ -1232,10 +1239,7 @@
1232
1239
  "figure.label.data-legend-role": "Legend role",
1233
1240
  "figure.label.data-legend-swappable": "A board may swap it for a legend",
1234
1241
  "figure.label.data-method": "Method",
1235
- "figure.label.data-new-field": "New field",
1236
1242
  "figure.label.data-sample-legend": "Sample legend",
1237
- "figure.label.data-table-legend": "legend {name}",
1238
- "figure.label.data-table-own": "figure's table",
1239
1243
  "figure.label.data-target-group": "Motion group",
1240
1244
  "figure.label.data-target-inputs": "Controls",
1241
1245
  "figure.label.data-target-parts": "Parts",
@@ -1322,6 +1326,7 @@
1322
1326
  "figure.button.shift-track": "shift",
1323
1327
  "figure.button.copy-track-apply": "copy",
1324
1328
  "figure.text.copy-clip-needs-group": "A copy plays the same controls, so only a clip in a motion group can be copied.",
1329
+ "figure.text.copy-clip-makes-group": "Copies every track into a clip with a new name. The copy moves the same controls, so both go into a new motion group named after this clip (one plays at a time).",
1325
1330
  "figure.label.primitive-pipe": "pipe",
1326
1331
  "figure.label.primitive-duct": "duct",
1327
1332
  "figure.label.primitive-tapered-box": "tapered box",
@@ -1402,5 +1407,20 @@
1402
1407
  "figure.label.clip-interpolation-smooth": "Ease in and out",
1403
1408
  "figure.label.clip-interpolation-step": "Jump",
1404
1409
  "figure.text.copy-track-off-key": "A smooth track can be shifted only so that it starts at one of its keys. Possible values: {seconds} s",
1405
- "figure.text.mirror-copies-clips": "The motion in {clips} is copied to the copy too."
1410
+ "figure.text.mirror-copies-clips": "The motion in {clips} is copied to the copy too.",
1411
+ "figure.label.data-bindings-title": "Data bindings",
1412
+ "figure.label.data-column-field": "Field",
1413
+ "figure.label.data-column-kind": "Kind",
1414
+ "figure.label.data-column-moves": "Drives",
1415
+ "figure.text.data-method-does-value": "Applies the data value unchanged.",
1416
+ "figure.text.data-method-does-scale": "Applies the data value multiplied by a scale.",
1417
+ "figure.text.data-method-does-code": "Applies what the table sets for each data value.",
1418
+ "figure.text.data-method-does-ranges": "Applies what the table sets for the range the data value falls in.",
1419
+ "figure.label.data-bindings-without-field": "Bindings without a field",
1420
+ "figure.button.add": "Add",
1421
+ "figure.label.data-targets": "Targets",
1422
+ "figure.label.data-target-add": "Add target",
1423
+ "figure.label.data-target-choose": "Choose a part or control",
1424
+ "figure.text.data-no-targets": "No target chosen.",
1425
+ "figure.button.data-remove-target": "Remove target"
1406
1426
  }
@@ -484,6 +484,8 @@
484
484
  "figure.text.pick-a-shape-above-to-start": "elija una forma arriba para añadir la primera pieza.",
485
485
  "figure.text.placement-explained": "define el plano de anclaje en la escena 3D (suelo: AGV/transportador, techo: OHT/polipasto, centro: sensor/dron).",
486
486
  "figure.text.pose-as-default-explained": "Escribe la postura que ha definido como valores predeterminados de los parámetros, para que la figura quede así cuando nadie le dé un valor.",
487
+ "figure.text.control-played": "En reproducción",
488
+ "figure.text.control-played-explained": "El clip {clip} está moviendo este control. Detén el clip para darle un valor.",
487
489
  "figure.text.clear-tried-explained": "borra los valores de control probados aquí. la pose por defecto guardada no cambia y los clips vuelven a moverla.",
488
490
  "figure.text.preview-blocked-by-errors": "no se puede mostrar la vista previa por errores de formato. consulte el motivo en la pestaña de madurez.",
489
491
  "figure.text.put-on-floor": "Mueve la pieza una vez para que su base quede en el suelo (Y=0). No se mantiene ahí cuando cambia el tamaño; para ello, use “Seguir el tamaño, unida al suelo”.",
@@ -715,6 +717,10 @@
715
717
  "figure.label.motion-own-control": "su propio control",
716
718
  "figure.label.motion-multiplier": "multiplicador",
717
719
  "figure.label.motion-offset": "desplazamiento",
720
+ "figure.label.pivot-at": "girar en",
721
+ "figure.label.pivot-top": "extremo superior",
722
+ "figure.label.pivot-middle": "centro",
723
+ "figure.label.pivot-bottom": "extremo inferior",
718
724
  "figure.label.motion-through": "el eje pasa por",
719
725
  "figure.label.motion-follows": "se mueve con {joint} × {multiplier} + {offset}",
720
726
  "figure.label.face-opening-left": "abertura izquierda",
@@ -1020,6 +1026,7 @@
1020
1026
  "figure.text.slot-id-taken": "{slot} ya es el nombre de un lugar en esta figura.",
1021
1027
  "figure.label.placement": "sujeción",
1022
1028
  "figure.label.motion-groups": "grupos de movimiento",
1029
+ "figure.label.motion-group-named": "movimiento",
1023
1030
  "figure.label.motion-group": "grupo de movimiento",
1024
1031
  "figure.label.no-motion-group": "sin grupo",
1025
1032
  "figure.label.motion-group-name": "nombre",
@@ -1045,12 +1052,12 @@
1045
1052
  "figure.label.data-scale": "escala",
1046
1053
  "figure.label.data-offset": "desplazamiento",
1047
1054
  "figure.label.data-sample": "datos de ejemplo",
1048
- "figure.text.data-sample-explained": "Introduzca un registro en JSON para ver qué mueve. Se lee como una figura en un tablero lee sus datos, y no se guarda.",
1049
- "figure.text.data-sample-moves-all": "Una posición en los datos lleva todas las figuras de la vista previa a ella; en un tablero, las figuras con el mismo valor también quedan en el mismo lugar.",
1055
+ "figure.text.data-sample-explained": "Introduzca un registro en JSON o JSON5 para ver qué mueve. Se lee como una figura en un tablero lee sus datos, y no se guarda.",
1050
1056
  "figure.label.data-sample-in-preview": "aplicar a la vista previa",
1057
+ "figure.text.data-sample-shown-in-preview": "Los datos de muestra se ven en la vista previa; la edición muestra la figura tal como se hizo.",
1058
+ "figure.button.data-sample-show-preview": "Ver la vista previa",
1051
1059
  "figure.label.data-schema": "forma de los datos",
1052
1060
  "figure.text.data-schema-explained": "La forma de los datos que un sitio envía a esta figura. Nombre cada campo como lo nombran los datos del sitio; agrupe campos en objetos y listas.",
1053
- "figure.label.data-bound": "{count} vinculados",
1054
1061
  "figure.text.data-no-fields": "Primero añada un campo a la forma de los datos.",
1055
1062
  "figure.label.data-name": "nombre del campo",
1056
1063
  "figure.label.data-label": "nombre visible",
@@ -1061,17 +1068,18 @@
1061
1068
  "figure.button.remove-data-field": "quitar el campo",
1062
1069
  "figure.label.data-from-sample": "crear desde una muestra",
1063
1070
  "figure.text.data-from-sample-explained": "Pegue un registro de los datos del sitio para deducir sus campos. Unidades, rangos y listas de valores no se deducen; fíjelos después.",
1064
- "figure.text.data-not-json": "No es JSON.",
1071
+ "figure.text.data-not-json": "No es JSON ni JSON5.",
1065
1072
  "figure.text.data-guessed": "Se encontraron {count} campos.",
1066
1073
  "figure.text.data-guessed-replaces": "Se encontraron {count} campos. Usarlos reemplaza la forma de datos actual.",
1067
1074
  "figure.button.data-use-guessed": "usar esta forma",
1068
1075
  "figure.text.data-bindings-explained": "Conecta valores de datos con la figura. Un número se muestra tal cual, escalado o con una tabla de rangos; un texto o verdadero/falso, con una tabla de códigos. Una tabla fija por valor el color y efecto de las piezas, los controles y un grupo de movimiento. Seleccione una fila para editarla.",
1069
- "figure.label.data-field": "valor de datos",
1070
1076
  "figure.label.data-behavior": "comportamiento",
1071
1077
  "figure.label.data-seconds": "tiempo de desplazamiento (s)",
1072
1078
  "figure.label.data-paused": "en pausa",
1073
1079
  "figure.label.data-playing": "en marcha",
1074
1080
  "figure.label.data-otherwise": "cualquier otro valor",
1081
+ "figure.label.data-keep": "mantener",
1082
+ "figure.text.data-keep": "Un valor sin fila propia deja el aspecto que esta tabla mostró por última vez.",
1075
1083
  "figure.label.data-range-from": "desde",
1076
1084
  "figure.label.data-range-to": "hasta (sin incluir)",
1077
1085
  "figure.button.add-data-range": "añadir intervalo",
@@ -1094,7 +1102,6 @@
1094
1102
  "figure.button.data-add-rotation": "crear la rotación",
1095
1103
  "figure.label.data-none": "ninguno",
1096
1104
  "figure.button.remove-data-binding": "quitar el vínculo",
1097
- "figure.label.data-items-count": "{count} artículos",
1098
1105
  "figure.text.data-value-not-a-list": "{path}: no es una lista.",
1099
1106
  "figure.text.data-value-value-unknown": "{path}: no es uno de sus valores.",
1100
1107
  "figure.text.data-value-json-unreadable": "{path}: no se puede leer el texto JSON.",
@@ -1232,10 +1239,7 @@
1232
1239
  "figure.label.data-legend-role": "Rol de leyenda",
1233
1240
  "figure.label.data-legend-swappable": "Quien lo usa puede cambiarla por una leyenda",
1234
1241
  "figure.label.data-method": "Método",
1235
- "figure.label.data-new-field": "Campo nuevo",
1236
1242
  "figure.label.data-sample-legend": "Leyenda de ejemplo",
1237
- "figure.label.data-table-legend": "leyenda {name}",
1238
- "figure.label.data-table-own": "tabla de la figura",
1239
1243
  "figure.label.data-target-group": "Grupo de movimiento",
1240
1244
  "figure.label.data-target-inputs": "Controles",
1241
1245
  "figure.label.data-target-parts": "Piezas",
@@ -1322,6 +1326,7 @@
1322
1326
  "figure.button.shift-track": "desplazar",
1323
1327
  "figure.button.copy-track-apply": "copiar",
1324
1328
  "figure.text.copy-clip-needs-group": "Una copia mueve los mismos controles, así que solo se copia un clip que está en un grupo de movimiento.",
1329
+ "figure.text.copy-clip-makes-group": "Copia todas las pistas en un clip con un nombre nuevo. La copia mueve los mismos controles, así que ambos van a un grupo de movimiento nuevo con el nombre de este clip (se reproduce uno a la vez).",
1325
1330
  "figure.label.primitive-pipe": "tubo",
1326
1331
  "figure.label.primitive-duct": "conducto",
1327
1332
  "figure.label.primitive-tapered-box": "caja ahusada",
@@ -1402,5 +1407,20 @@
1402
1407
  "figure.label.clip-interpolation-smooth": "Arranque y parada suaves",
1403
1408
  "figure.label.clip-interpolation-step": "Salto",
1404
1409
  "figure.text.copy-track-off-key": "Una pista suave solo puede desplazarse para que empiece en una de sus claves. Valores posibles: {seconds} s",
1405
- "figure.text.mirror-copies-clips": "El movimiento de {clips} también se copia en la copia."
1410
+ "figure.text.mirror-copies-clips": "El movimiento de {clips} también se copia en la copia.",
1411
+ "figure.label.data-bindings-title": "Vínculos de datos",
1412
+ "figure.label.data-column-field": "Campo",
1413
+ "figure.label.data-column-kind": "Tipo",
1414
+ "figure.label.data-column-moves": "Mueve",
1415
+ "figure.text.data-method-does-value": "Aplica el valor del dato sin convertirlo.",
1416
+ "figure.text.data-method-does-scale": "Aplica el valor del dato multiplicado por una escala.",
1417
+ "figure.text.data-method-does-code": "Aplica lo que la tabla fija para cada valor del dato.",
1418
+ "figure.text.data-method-does-ranges": "Aplica lo que la tabla fija para el intervalo en que cae el valor.",
1419
+ "figure.label.data-bindings-without-field": "Vínculos sin campo",
1420
+ "figure.button.add": "Añadir",
1421
+ "figure.label.data-targets": "Destinos",
1422
+ "figure.label.data-target-add": "Añadir destino",
1423
+ "figure.label.data-target-choose": "Elija una pieza o un control",
1424
+ "figure.text.data-no-targets": "No hay destinos elegidos.",
1425
+ "figure.button.data-remove-target": "Quitar destino"
1406
1426
  }
@@ -484,6 +484,8 @@
484
484
  "figure.text.pick-a-shape-above-to-start": "pick a shape above to add the first part.",
485
485
  "figure.text.placement-explained": "3D シーンでの基準面を決めます (床: AGV/コンベヤ、天井: OHT/ホイスト、中心: センサー/ドローン)。",
486
486
  "figure.text.pose-as-default-explained": "今の姿勢をパラメータの既定値として書き込みます。値が与えられないとき、この姿勢で立ちます。",
487
+ "figure.text.control-played": "再生中",
488
+ "figure.text.control-played-explained": "{clip} クリップがこの操作値を動かしています。クリップを止めると値を与えられます。",
487
489
  "figure.text.clear-tried-explained": "プレビューで変えた操作値を消します。保存された既定の姿勢は変わらず、クリップが再び動かします。",
488
490
  "figure.text.preview-blocked-by-errors": "形式エラーのためプレビューを表示できません。成熟度タブで理由を確認してください。",
489
491
  "figure.text.put-on-floor": "今の位置だけ底面を床(Y=0)に合わせます。サイズが変わると追従しません。付けたままにするには「床に付けてサイズに追従」を使ってください。",
@@ -715,6 +717,10 @@
715
717
  "figure.label.motion-own-control": "自分の操作値",
716
718
  "figure.label.motion-multiplier": "倍率",
717
719
  "figure.label.motion-offset": "オフセット",
720
+ "figure.label.pivot-at": "回転の中心",
721
+ "figure.label.pivot-top": "上端",
722
+ "figure.label.pivot-middle": "中央",
723
+ "figure.label.pivot-bottom": "下端",
718
724
  "figure.label.motion-through": "軸が通る点",
719
725
  "figure.label.motion-follows": "{joint} に連動 × {multiplier} + {offset}",
720
726
  "figure.label.face-opening-left": "開口部 左",
@@ -1020,6 +1026,7 @@
1020
1026
  "figure.text.slot-id-taken": "{slot} はこの図形ですでに使われている場所の名前です。",
1021
1027
  "figure.label.placement": "取り付け",
1022
1028
  "figure.label.motion-groups": "モーショングループ",
1029
+ "figure.label.motion-group-named": "動作",
1023
1030
  "figure.label.motion-group": "モーショングループ",
1024
1031
  "figure.label.no-motion-group": "グループなし",
1025
1032
  "figure.label.motion-group-name": "名前",
@@ -1045,12 +1052,12 @@
1045
1052
  "figure.label.data-scale": "倍率",
1046
1053
  "figure.label.data-offset": "加算",
1047
1054
  "figure.label.data-sample": "サンプルデータ",
1048
- "figure.text.data-sample-explained": "データを1件JSONで入れて何が動くかを確認します。ボードに置いたFigureと同じ方法で読み、保存しません。",
1049
- "figure.text.data-sample-moves-all": "位置を決める値はプレビューのFigureをすべてその位置に移します。ボードでも同じ値を受けたFigureは同じ位置に立ちます。",
1055
+ "figure.text.data-sample-explained": "データを1件JSONまたはJSON5で入れて何が動くかを確認します。ボードに置いたFigureと同じ方法で読み、保存しません。",
1050
1056
  "figure.label.data-sample-in-preview": "プレビューに適用",
1057
+ "figure.text.data-sample-shown-in-preview": "サンプルデータはプレビューに表示されます。編集画面は作ったままです。",
1058
+ "figure.button.data-sample-show-preview": "プレビューで見る",
1051
1059
  "figure.label.data-schema": "データ形式",
1052
1060
  "figure.text.data-schema-explained": "現場がこのFigureに送るデータの形です。フィールド名は現場データの名前どおりに書き、オブジェクトとリストでまとめられます。",
1053
- "figure.label.data-bound": "動作 {count}件",
1054
1061
  "figure.text.data-no-fields": "先にデータ形式にフィールドを追加します。",
1055
1062
  "figure.label.data-name": "フィールド名",
1056
1063
  "figure.label.data-label": "表示名",
@@ -1061,17 +1068,18 @@
1061
1068
  "figure.button.remove-data-field": "フィールドを削除",
1062
1069
  "figure.label.data-from-sample": "サンプルから作る",
1063
1070
  "figure.text.data-from-sample-explained": "現場データを1件貼り付けるとフィールドを推定します。単位・範囲・値の一覧は推定しないので、置き換えた後に決めます。",
1064
- "figure.text.data-not-json": "JSON形式ではありません。",
1071
+ "figure.text.data-not-json": "JSONまたはJSON5形式ではありません。",
1065
1072
  "figure.text.data-guessed": "フィールドが {count} 件見つかりました。",
1066
1073
  "figure.text.data-guessed-replaces": "フィールドが {count} 件見つかりました。置き換えると今のデータ形式に代わります。",
1067
1074
  "figure.button.data-use-guessed": "この形式に置き換える",
1068
1075
  "figure.text.data-bindings-explained": "データの値をフィギュアにつなぎます。数値はそのまま・倍率・区間表で、文字と真偽はコード表で表示します。表は値ごとに部品の色と効果、操作値、動作グループをまとめて決めます。行を選ぶと編集できます。",
1069
- "figure.label.data-field": "データ値",
1070
1076
  "figure.label.data-behavior": "動作",
1071
1077
  "figure.label.data-seconds": "移動時間 (秒)",
1072
1078
  "figure.label.data-paused": "一時停止",
1073
1079
  "figure.label.data-playing": "再生",
1074
1080
  "figure.label.data-otherwise": "その他の値",
1081
+ "figure.label.data-keep": "そのまま",
1082
+ "figure.text.data-keep": "表にない値が来ると、この表が最後に示した見た目をそのまま保ちます。",
1075
1083
  "figure.label.data-range-from": "以上",
1076
1084
  "figure.label.data-range-to": "未満",
1077
1085
  "figure.button.add-data-range": "区間を追加",
@@ -1094,7 +1102,6 @@
1094
1102
  "figure.button.data-add-rotation": "回転を作る",
1095
1103
  "figure.label.data-none": "なし",
1096
1104
  "figure.button.remove-data-binding": "連結を削除",
1097
- "figure.label.data-items-count": "アイテム {count}件",
1098
1105
  "figure.text.data-value-not-a-list": "{path}: リストではありません。",
1099
1106
  "figure.text.data-value-value-unknown": "{path}: 値の一覧にない値です。",
1100
1107
  "figure.text.data-value-json-unreadable": "{path}: JSON文字列を読めません。",
@@ -1232,10 +1239,7 @@
1232
1239
  "figure.label.data-legend-role": "凡例の役割",
1233
1240
  "figure.label.data-legend-swappable": "使う側が凡例に置き換えられる",
1234
1241
  "figure.label.data-method": "方法",
1235
- "figure.label.data-new-field": "新しいフィールド",
1236
1242
  "figure.label.data-sample-legend": "サンプル凡例",
1237
- "figure.label.data-table-legend": "凡例 {name}",
1238
- "figure.label.data-table-own": "フィギュアの表",
1239
1243
  "figure.label.data-target-group": "動作グループ",
1240
1244
  "figure.label.data-target-inputs": "操作値",
1241
1245
  "figure.label.data-target-parts": "部品",
@@ -1322,6 +1326,7 @@
1322
1326
  "figure.button.shift-track": "ずらす",
1323
1327
  "figure.button.copy-track-apply": "複製",
1324
1328
  "figure.text.copy-clip-needs-group": "複製は同じ操作値を動かすため、動作グループに入れたクリップだけ複製できます。",
1329
+ "figure.text.copy-clip-makes-group": "すべてのトラックを新しい名前のクリップへ複製します。複製は同じ操作値を動かすため、このクリップの名前で動作グループを作り、両方を入れます(同時に再生されるのは一つ)。",
1325
1330
  "figure.label.primitive-pipe": "パイプ",
1326
1331
  "figure.label.primitive-duct": "ダクト",
1327
1332
  "figure.label.primitive-tapered-box": "先細りの箱",
@@ -1402,5 +1407,20 @@
1402
1407
  "figure.label.clip-interpolation-smooth": "滑らかに発進・停止",
1403
1408
  "figure.label.clip-interpolation-step": "即時切り替え",
1404
1409
  "figure.text.copy-track-off-key": "滑らかに動くトラックは、キーのある時点に合わせてのみ時間をずらせます。可能な値: {seconds}秒",
1405
- "figure.text.mirror-copies-clips": "「{clips}」クリップの動きもコピーに一緒に複製されます。"
1410
+ "figure.text.mirror-copies-clips": "「{clips}」クリップの動きもコピーに一緒に複製されます。",
1411
+ "figure.label.data-bindings-title": "データ連結",
1412
+ "figure.label.data-column-field": "フィールド",
1413
+ "figure.label.data-column-kind": "種類",
1414
+ "figure.label.data-column-moves": "連結先",
1415
+ "figure.text.data-method-does-value": "データ値を変換せずに適用します。",
1416
+ "figure.text.data-method-does-scale": "データ値に倍率を掛けて適用します。",
1417
+ "figure.text.data-method-does-code": "データ値ごとに表で指定した設定を適用します。",
1418
+ "figure.text.data-method-does-ranges": "データ値が属する区間ごとに表で指定した設定を適用します。",
1419
+ "figure.label.data-bindings-without-field": "フィールドのない連結",
1420
+ "figure.button.add": "追加",
1421
+ "figure.label.data-targets": "対象",
1422
+ "figure.label.data-target-add": "対象を追加",
1423
+ "figure.label.data-target-choose": "部品または操作値を選択",
1424
+ "figure.text.data-no-targets": "選択した対象がありません。",
1425
+ "figure.button.data-remove-target": "対象を削除"
1406
1426
  }
@@ -484,6 +484,8 @@
484
484
  "figure.text.pick-a-shape-above-to-start": "위에서 하나를 골라 첫 부품을 놓으세요.",
485
485
  "figure.text.placement-explained": "3D 씬에서 객체의 기준면을 정합니다 (바닥: AGV/컨베이어, 천장: OHT/호이스트, 중심: 센서/드론).",
486
486
  "figure.text.pose-as-default-explained": "현재 자세를 파라미터의 기본값으로 저장합니다. 값이 지정되지 않으면 피규어에 이 자세가 적용됩니다.",
487
+ "figure.text.control-played": "재생 중",
488
+ "figure.text.control-played-explained": "{clip} 클립이 이 조작값을 움직이고 있습니다. 클립을 멈추면 값을 줄 수 있습니다.",
487
489
  "figure.text.clear-tried-explained": "미리 보기에서 바꾼 조작값을 지웁니다. 저장된 기본 자세는 바뀌지 않고, 클립이 다시 움직입니다.",
488
490
  "figure.text.preview-blocked-by-errors": "형식 오류로 미리보기를 표시할 수 없습니다. 검사 탭에서 사유를 확인하세요.",
489
491
  "figure.text.put-on-floor": "지금 위치만 바닥(Y=0)에 맞춥니다. 크기가 바뀌면 따라가지 않습니다. 계속 붙어 있게 하려면 ‘바닥에 붙여 크기 따라가기’를 쓰세요.",
@@ -715,6 +717,10 @@
715
717
  "figure.label.motion-own-control": "제 조작값으로",
716
718
  "figure.label.motion-multiplier": "배율",
717
719
  "figure.label.motion-offset": "더하기",
720
+ "figure.label.pivot-at": "회전 중심",
721
+ "figure.label.pivot-top": "위 끝",
722
+ "figure.label.pivot-middle": "가운데",
723
+ "figure.label.pivot-bottom": "아래 끝",
718
724
  "figure.label.motion-through": "축이 지나는 점",
719
725
  "figure.label.motion-follows": "따라 움직임: {joint} × {multiplier} + {offset}",
720
726
  "figure.label.face-opening-left": "개구부 왼쪽",
@@ -1020,6 +1026,7 @@
1020
1026
  "figure.text.slot-id-taken": "이 피규어에서 이미 쓰는 자리 이름입니다: {slot}.",
1021
1027
  "figure.label.placement": "붙이기",
1022
1028
  "figure.label.motion-groups": "동작 그룹",
1029
+ "figure.label.motion-group-named": "동작",
1023
1030
  "figure.label.motion-group": "동작 그룹",
1024
1031
  "figure.label.no-motion-group": "그룹 없음",
1025
1032
  "figure.label.motion-group-name": "이름",
@@ -1045,12 +1052,12 @@
1045
1052
  "figure.label.data-scale": "배율",
1046
1053
  "figure.label.data-offset": "더하기",
1047
1054
  "figure.label.data-sample": "샘플 데이터",
1048
- "figure.text.data-sample-explained": "JSON 형식의 샘플 데이터 한 건을 입력하여 동작을 확인합니다. 보드에 배치된 피규어와 같은 방식으로 데이터를 해석하며 샘플 데이터는 저장되지 않습니다.",
1049
- "figure.text.data-sample-moves-all": "위치 데이터는 미리보기의 모든 피규어에 동일하게 적용됩니다. 보드에서도 같은 위치 데이터를 수신한 피규어는 같은 위치에 배치됩니다.",
1055
+ "figure.text.data-sample-explained": "JSON 또는 JSON5 형식의 샘플 데이터 한 건을 입력하여 동작을 확인합니다. 보드에 배치된 피규어와 같은 방식으로 데이터를 해석하며 샘플 데이터는 저장되지 않습니다.",
1050
1056
  "figure.label.data-sample-in-preview": "미리보기에 적용",
1057
+ "figure.text.data-sample-shown-in-preview": "견본 데이터는 미리보기에서 보입니다. 편집 화면은 만든 그대로입니다.",
1058
+ "figure.button.data-sample-show-preview": "미리보기로 보기",
1051
1059
  "figure.label.data-schema": "데이터 형식",
1052
1060
  "figure.text.data-schema-explained": "현장이 이 피규어에 보내는 데이터의 모양입니다. 필드 이름은 현장 데이터의 이름 그대로 적고, 객체와 목록으로 묶을 수 있습니다.",
1053
- "figure.label.data-bound": "작동 {count}개",
1054
1061
  "figure.text.data-no-fields": "데이터 형식에 필드를 먼저 추가합니다.",
1055
1062
  "figure.label.data-name": "필드 이름",
1056
1063
  "figure.label.data-label": "표시 이름",
@@ -1061,17 +1068,18 @@
1061
1068
  "figure.button.remove-data-field": "필드 삭제",
1062
1069
  "figure.label.data-from-sample": "샘플에서 만들기",
1063
1070
  "figure.text.data-from-sample-explained": "현장 데이터 한 건을 붙여 넣으면 필드를 추정합니다. 단위, 범위, 값 목록은 자동으로 추정하지 않으므로 필드 변환 후 직접 설정해 주세요.",
1064
- "figure.text.data-not-json": "JSON 형식이 아닙니다.",
1071
+ "figure.text.data-not-json": "JSON 또는 JSON5 형식이 아닙니다.",
1065
1072
  "figure.text.data-guessed": "필드 {count}개를 찾았습니다.",
1066
1073
  "figure.text.data-guessed-replaces": "필드 {count}개를 찾았습니다. 바꾸면 지금 데이터 형식을 대신합니다.",
1067
1074
  "figure.button.data-use-guessed": "이 형식으로 바꾸기",
1068
- "figure.text.data-bindings-explained": "데이터 값을 피규어에 연결합니다. 숫자는 그대로, 배율, 구간 표로, 글자와 참/거짓은 코드 표로 보입니다. 표는 값마다 부품의 색과 효과, 조작값, 동작 그룹을 함께 정합니다. 행을 선택하면 수정할 수 있습니다.",
1069
- "figure.label.data-field": "데이터 값",
1075
+ "figure.text.data-bindings-explained": "데이터 값을 피규어에 연결합니다. 숫자는 변환 없이, 배율, 구간 표로, 글자와 참/거짓은 코드 표로 보입니다. 표는 값마다 부품의 색과 효과, 조작값, 동작 그룹을 함께 정합니다. 행을 선택하면 수정할 수 있습니다.",
1070
1076
  "figure.label.data-behavior": "작동",
1071
1077
  "figure.label.data-seconds": "이동 시간 (초)",
1072
1078
  "figure.label.data-paused": "멈춤",
1073
1079
  "figure.label.data-playing": "재생",
1074
1080
  "figure.label.data-otherwise": "그 밖의 값",
1081
+ "figure.label.data-keep": "그대로 둠",
1082
+ "figure.text.data-keep": "표에 없는 값이 오면 이 표가 마지막으로 보인 모양을 그대로 둡니다.",
1075
1083
  "figure.label.data-range-from": "이상",
1076
1084
  "figure.label.data-range-to": "미만",
1077
1085
  "figure.button.add-data-range": "구간 추가",
@@ -1094,7 +1102,6 @@
1094
1102
  "figure.button.data-add-rotation": "회전 만들기",
1095
1103
  "figure.label.data-none": "없음",
1096
1104
  "figure.button.remove-data-binding": "연결 삭제",
1097
- "figure.label.data-items-count": "아이템 {count}개",
1098
1105
  "figure.text.data-value-not-a-list": "{path}: 목록이 아닙니다.",
1099
1106
  "figure.text.data-value-value-unknown": "{path}: 값 목록에 없는 값입니다.",
1100
1107
  "figure.text.data-value-json-unreadable": "{path}: JSON 글자를 읽을 수 없습니다.",
@@ -1232,10 +1239,7 @@
1232
1239
  "figure.label.data-legend-role": "범례 역할",
1233
1240
  "figure.label.data-legend-swappable": "보드 범례로 바꿀 수 있음",
1234
1241
  "figure.label.data-method": "방법",
1235
- "figure.label.data-new-field": "새 필드",
1236
1242
  "figure.label.data-sample-legend": "샘플 범례",
1237
- "figure.label.data-table-legend": "범례 {name}",
1238
- "figure.label.data-table-own": "피규어 표",
1239
1243
  "figure.label.data-target-group": "동작 그룹",
1240
1244
  "figure.label.data-target-inputs": "조작값",
1241
1245
  "figure.label.data-target-parts": "부품",
@@ -1258,7 +1262,7 @@
1258
1262
  "figure.text.data-table-entry-paused": "{key} 줄: 멈춤은 참이나 거짓입니다.",
1259
1263
  "figure.text.data-table-entry-speed": "{key} 줄: 배속은 0에서 3까지입니다.",
1260
1264
  "figure.text.data-table-entry-values": "{key} 줄: {id} 값 {value}는 받을 수 없습니다.",
1261
- "figure.text.data-table-needs-target": "표가 바꿀 부품 · 조작값 · 동작 그룹을 하나 이상 고릅니다.",
1265
+ "figure.text.data-table-needs-target": "표가 바꿀 부품, 조작값, 동작 그룹을 하나 이상 선택하세요.",
1262
1266
  "figure.text.data-table-target-group": "{id} 동작 그룹이 없습니다.",
1263
1267
  "figure.text.data-table-target-input": "{id} 조작값이 없거나 두 번 골랐습니다.",
1264
1268
  "figure.text.data-table-target-none": "표가 보일 대상을 하나 이상 고릅니다.",
@@ -1322,6 +1326,7 @@
1322
1326
  "figure.button.shift-track": "시간 밀기",
1323
1327
  "figure.button.copy-track-apply": "복사",
1324
1328
  "figure.text.copy-clip-needs-group": "복사본은 같은 조작값을 움직이므로 동작 묶음에 넣은 클립만 복사할 수 있습니다.",
1329
+ "figure.text.copy-clip-makes-group": "모든 트랙을 새 이름의 클립으로 복사합니다. 복사본은 같은 조작값을 움직이므로, 이 클립의 이름으로 동작 묶음을 만들어 둘을 함께 넣습니다(한 번에 하나만 재생).",
1325
1330
  "figure.label.primitive-pipe": "관",
1326
1331
  "figure.label.primitive-duct": "덕트",
1327
1332
  "figure.label.primitive-tapered-box": "가늘어지는 상자",
@@ -1402,5 +1407,20 @@
1402
1407
  "figure.label.clip-interpolation-smooth": "부드럽게 출발·정지",
1403
1408
  "figure.label.clip-interpolation-step": "즉시 전환",
1404
1409
  "figure.text.copy-track-off-key": "부드럽게 움직이는 트랙은 키가 있는 시점에 맞춰서만 시간을 밀 수 있습니다. 가능한 값: {seconds}초",
1405
- "figure.text.mirror-copies-clips": "「{clips}」 클립의 동작도 복사본에 함께 복사됩니다."
1410
+ "figure.text.mirror-copies-clips": "「{clips}」 클립의 동작도 복사본에 함께 복사됩니다.",
1411
+ "figure.label.data-bindings-title": "데이터 연결",
1412
+ "figure.label.data-column-field": "필드",
1413
+ "figure.label.data-column-kind": "종류",
1414
+ "figure.label.data-column-moves": "연결 대상",
1415
+ "figure.text.data-method-does-value": "데이터 값을 변환 없이 적용합니다.",
1416
+ "figure.text.data-method-does-scale": "데이터 값에 배율을 곱해 적용합니다.",
1417
+ "figure.text.data-method-does-code": "데이터 값마다 표에 지정한 설정을 적용합니다.",
1418
+ "figure.text.data-method-does-ranges": "데이터 값이 속한 구간에 따라 표에 지정한 설정을 적용합니다.",
1419
+ "figure.label.data-bindings-without-field": "필드가 없는 연결",
1420
+ "figure.button.add": "추가",
1421
+ "figure.label.data-targets": "대상",
1422
+ "figure.label.data-target-add": "대상 추가",
1423
+ "figure.label.data-target-choose": "부품 또는 조작값 선택",
1424
+ "figure.text.data-no-targets": "선택한 대상이 없습니다.",
1425
+ "figure.button.data-remove-target": "대상 삭제"
1406
1426
  }