@nice2dev/ui-3d 1.3.15 → 1.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/collaborative/collaborativeScene.js +160 -206
  3. package/dist/cjs/core/editorAsk.js +51 -41
  4. package/dist/cjs/core/i18n.js +13 -14
  5. package/dist/cjs/core/threeCompat.js +29 -42
  6. package/dist/cjs/dance/DanceBridge.js +148 -177
  7. package/dist/cjs/dance/DanceScoreEngine.js +209 -221
  8. package/dist/cjs/dance/PoseDetector.js +302 -275
  9. package/dist/cjs/index.js +110 -113
  10. package/dist/cjs/material/MaterialEditor.module.css.js +242 -5
  11. package/dist/cjs/material/NiceMaterialEditor.js +1213 -757
  12. package/dist/cjs/material/materialEditorTypes.js +35 -49
  13. package/dist/cjs/material/materialEditorUtils.js +684 -747
  14. package/dist/cjs/material/materialNodeDefinitions.js +1411 -1459
  15. package/dist/cjs/model/ModelEditor.js +90 -40
  16. package/dist/cjs/model/ModelEditor.module.css.js +257 -5
  17. package/dist/cjs/model/ModelEditorLeftPanel.js +126 -47
  18. package/dist/cjs/model/ModelEditorMenuBar.js +359 -32
  19. package/dist/cjs/model/ModelEditorRightPanel.js +647 -131
  20. package/dist/cjs/model/ModelEditorSubComponents.js +277 -112
  21. package/dist/cjs/model/ModelEditorTimeline.js +232 -34
  22. package/dist/cjs/model/ModelEditorToolbar.js +170 -14
  23. package/dist/cjs/model/ModelEditorViewport.js +231 -39
  24. package/dist/cjs/model/ModelViewer.js +388 -63
  25. package/dist/cjs/model/ModelViewer.module.css.js +77 -5
  26. package/dist/cjs/model/NiceArmatureEditor.js +473 -274
  27. package/dist/cjs/model/NiceMorphTargetEditor.js +333 -227
  28. package/dist/cjs/model/NiceOctree.js +372 -320
  29. package/dist/cjs/model/NicePhysicsSimulation.js +528 -298
  30. package/dist/cjs/model/NiceProceduralGeometry.js +673 -300
  31. package/dist/cjs/model/NiceTerrainEditor.js +595 -385
  32. package/dist/cjs/model/NiceWeightPainter.js +384 -261
  33. package/dist/cjs/model/NiceXRPreview.js +385 -308
  34. package/dist/cjs/model/cadModeUtils.js +103 -106
  35. package/dist/cjs/model/editorShortcuts.js +171 -194
  36. package/dist/cjs/model/modelEditorTypes.js +100 -118
  37. package/dist/cjs/model/modelEditorUtils.js +1061 -1146
  38. package/dist/cjs/model/simsModeUtils.js +1023 -1053
  39. package/dist/cjs/model/useModelEditor.js +1977 -1933
  40. package/dist/cjs/model/useModelViewer.js +633 -665
  41. package/dist/cjs/nice2dev-ui-3d.css +1 -1
  42. package/dist/cjs/particle/NiceParticleEditor.js +1186 -571
  43. package/dist/cjs/particle/ParticleEditor.module.css.js +122 -5
  44. package/dist/cjs/particle/particleEditorTypes.js +62 -70
  45. package/dist/cjs/particle/particleEditorUtils.js +998 -1013
  46. package/dist/cjs/rendering/NiceCascadedShadows.js +381 -259
  47. package/dist/cjs/rendering/NiceRenderExport.js +424 -337
  48. package/dist/cjs/rendering/NiceSSAO.js +454 -337
  49. package/dist/cjs/rendering/NiceSSR.js +387 -261
  50. package/dist/cjs/rendering/NiceWebGPURenderer.js +359 -230
  51. package/dist/cjs/uv/NiceUVEditor.js +787 -550
  52. package/dist/cjs/uv/UVEditor.module.css.js +53 -5
  53. package/dist/cjs/uv/uvEditorTypes.js +59 -76
  54. package/dist/cjs/uv/uvEditorUtils.js +501 -575
  55. package/dist/esm/collaborative/collaborativeScene.js +163 -205
  56. package/dist/esm/core/editorAsk.js +53 -40
  57. package/dist/esm/core/i18n.js +15 -13
  58. package/dist/esm/core/threeCompat.js +18 -26
  59. package/dist/esm/dance/DanceBridge.js +151 -176
  60. package/dist/esm/dance/DanceScoreEngine.js +211 -220
  61. package/dist/esm/dance/PoseDetector.js +304 -274
  62. package/dist/esm/index.js +258 -36
  63. package/dist/esm/material/MaterialEditor.module.css.js +242 -3
  64. package/dist/esm/material/NiceMaterialEditor.js +1215 -756
  65. package/dist/esm/material/materialEditorTypes.js +45 -48
  66. package/dist/esm/material/materialEditorUtils.js +713 -746
  67. package/dist/esm/material/materialNodeDefinitions.js +1415 -1458
  68. package/dist/esm/model/ModelEditor.js +91 -39
  69. package/dist/esm/model/ModelEditor.module.css.js +257 -3
  70. package/dist/esm/model/ModelEditorLeftPanel.js +126 -45
  71. package/dist/esm/model/ModelEditorMenuBar.js +359 -30
  72. package/dist/esm/model/ModelEditorRightPanel.js +634 -114
  73. package/dist/esm/model/ModelEditorSubComponents.js +265 -94
  74. package/dist/esm/model/ModelEditorTimeline.js +232 -32
  75. package/dist/esm/model/ModelEditorToolbar.js +170 -12
  76. package/dist/esm/model/ModelEditorViewport.js +231 -37
  77. package/dist/esm/model/ModelViewer.js +389 -62
  78. package/dist/esm/model/ModelViewer.module.css.js +77 -3
  79. package/dist/esm/model/NiceArmatureEditor.js +462 -258
  80. package/dist/esm/model/NiceMorphTargetEditor.js +322 -211
  81. package/dist/esm/model/NiceOctree.js +361 -304
  82. package/dist/esm/model/NicePhysicsSimulation.js +517 -282
  83. package/dist/esm/model/NiceProceduralGeometry.js +667 -284
  84. package/dist/esm/model/NiceTerrainEditor.js +584 -369
  85. package/dist/esm/model/NiceWeightPainter.js +373 -245
  86. package/dist/esm/model/NiceXRPreview.js +374 -292
  87. package/dist/esm/model/cadModeUtils.js +95 -88
  88. package/dist/esm/model/editorShortcuts.js +172 -193
  89. package/dist/esm/model/modelEditorTypes.js +90 -100
  90. package/dist/esm/model/modelEditorUtils.js +1056 -1128
  91. package/dist/esm/model/simsModeUtils.js +1021 -1035
  92. package/dist/esm/model/useModelEditor.js +1946 -1920
  93. package/dist/esm/model/useModelViewer.js +619 -647
  94. package/dist/esm/nice2dev-ui-3d.css +1 -1
  95. package/dist/esm/particle/NiceParticleEditor.js +1188 -570
  96. package/dist/esm/particle/ParticleEditor.module.css.js +122 -3
  97. package/dist/esm/particle/particleEditorTypes.js +69 -69
  98. package/dist/esm/particle/particleEditorUtils.js +1027 -1012
  99. package/dist/esm/rendering/NiceCascadedShadows.js +370 -243
  100. package/dist/esm/rendering/NiceRenderExport.js +413 -321
  101. package/dist/esm/rendering/NiceSSAO.js +450 -328
  102. package/dist/esm/rendering/NiceSSR.js +383 -252
  103. package/dist/esm/rendering/NiceWebGPURenderer.js +326 -214
  104. package/dist/esm/uv/NiceUVEditor.js +788 -549
  105. package/dist/esm/uv/UVEditor.module.css.js +53 -3
  106. package/dist/esm/uv/uvEditorTypes.js +68 -75
  107. package/dist/esm/uv/uvEditorUtils.js +515 -557
  108. package/package.json +7 -12
@@ -1,125 +1,122 @@
1
- 'use strict';
2
-
3
- var THREE = require('three');
4
-
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const THREE = require("three");
5
4
  function _interopNamespaceDefault(e) {
6
- var n = Object.create(null);
7
- if (e) {
8
- Object.keys(e).forEach(function (k) {
9
- if (k !== 'default') {
10
- var d = Object.getOwnPropertyDescriptor(e, k);
11
- Object.defineProperty(n, k, d.get ? d : {
12
- enumerable: true,
13
- get: function () { return e[k]; }
14
- });
15
- }
16
- });
17
- }
18
- n.default = e;
19
- return Object.freeze(n);
5
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
6
+ if (e) {
7
+ for (const k in e) {
8
+ if (k !== "default") {
9
+ const d = Object.getOwnPropertyDescriptor(e, k);
10
+ Object.defineProperty(n, k, d.get ? d : {
11
+ enumerable: true,
12
+ get: () => e[k]
13
+ });
14
+ }
15
+ }
16
+ }
17
+ n.default = e;
18
+ return Object.freeze(n);
20
19
  }
21
-
22
- var THREE__namespace = /*#__PURE__*/_interopNamespaceDefault(THREE);
23
-
24
- /**
25
- * cadModeUtils.ts — CAD-style design utilities for ModelEditor.
26
- *
27
- * Provides: wall/floor/room drawing, dimension annotations,
28
- * snap-to-grid, measurement overlay, DXF import/export,
29
- * floor plan tools — inspired by AutoCAD & ArchiCAD.
30
- */
31
- /* ════════════════════════════════════════════════════════════════
32
- CONSTANTS
33
- ════════════════════════════════════════════════════════════════ */
20
+ const THREE__namespace = /* @__PURE__ */ _interopNamespaceDefault(THREE);
34
21
  const DEFAULT_CAD_SETTINGS = {
35
- grid: {
36
- enabled: true,
37
- spacing: 1,
38
- subdivisions: 10,
39
- unit: 'm',
40
- showLabels: true,
41
- color: '#444466',
42
- subColor: '#333344',
43
- },
44
- snapModes: ['grid', 'endpoint', 'midpoint', 'intersection'],
45
- snapRadius: 0.15,
46
- defaultWallHeight: 2.8,
47
- defaultWallThickness: 0.2,
48
- defaultDoorWidth: 0.9,
49
- defaultDoorHeight: 2.1,
50
- defaultWindowWidth: 1.2,
51
- defaultWindowHeight: 1.4,
52
- defaultWindowSill: 0.9,
53
- unit: 'm',
54
- precision: 2,
55
- orthogonalLock: false,
56
- showDimensions: true,
57
- currentFloor: 0,
22
+ grid: {
23
+ enabled: true,
24
+ spacing: 1,
25
+ subdivisions: 10,
26
+ unit: "m",
27
+ showLabels: true,
28
+ color: "#444466",
29
+ subColor: "#333344"
30
+ },
31
+ snapModes: ["grid", "endpoint", "midpoint", "intersection"],
32
+ snapRadius: 0.15,
33
+ defaultWallHeight: 2.8,
34
+ defaultWallThickness: 0.2,
35
+ defaultDoorWidth: 0.9,
36
+ defaultDoorHeight: 2.1,
37
+ defaultWindowWidth: 1.2,
38
+ defaultWindowHeight: 1.4,
39
+ defaultWindowSill: 0.9,
40
+ unit: "m",
41
+ precision: 2,
42
+ orthogonalLock: false,
43
+ showDimensions: true,
44
+ currentFloor: 0
58
45
  };
59
46
  const UNIT_SCALES = {
60
- mm: 0.001,
61
- cm: 0.01,
62
- m: 1,
63
- in: 0.0254,
64
- ft: 0.3048,
47
+ mm: 1e-3,
48
+ cm: 0.01,
49
+ m: 1,
50
+ in: 0.0254,
51
+ ft: 0.3048
65
52
  };
66
53
  const ROOM_COLORS = {
67
- living: '#e8d5b0',
68
- bedroom: '#c5d8e8',
69
- bathroom: '#b0dde8',
70
- kitchen: '#e8d0b5',
71
- dining: '#d8c8a8',
72
- office: '#c8d5c0',
73
- garage: '#c0c0c0',
74
- hallway: '#d5d0c8',
75
- closet: '#d8cbe8',
76
- laundry: '#b8d8d0',
77
- balcony: '#c0e0c0',
78
- stairwell: '#d0c8b8',
79
- custom: '#d0d0d0',
54
+ living: "#e8d5b0",
55
+ bedroom: "#c5d8e8",
56
+ bathroom: "#b0dde8",
57
+ kitchen: "#e8d0b5",
58
+ dining: "#d8c8a8",
59
+ office: "#c8d5c0",
60
+ garage: "#c0c0c0",
61
+ hallway: "#d5d0c8",
62
+ closet: "#d8cbe8",
63
+ laundry: "#b8d8d0",
64
+ balcony: "#c0e0c0",
65
+ stairwell: "#d0c8b8",
66
+ custom: "#d0d0d0"
80
67
  };
81
68
  const WALL_MATERIALS = [
82
- { id: 'concrete', name: 'Concrete', color: '#b8b8b8' },
83
- { id: 'brick', name: 'Brick', color: '#c07050' },
84
- { id: 'drywall', name: 'Drywall', color: '#f0e8d8' },
85
- { id: 'glass', name: 'Glass', color: '#c8e0f0' },
86
- { id: 'wood', name: 'Wood Panel', color: '#c8a060' },
87
- { id: 'stone', name: 'Stone', color: '#a0a098' },
88
- { id: 'metal', name: 'Metal Panel', color: '#b0b0b8' },
69
+ { id: "concrete", name: "Concrete", color: "#b8b8b8" },
70
+ { id: "brick", name: "Brick", color: "#c07050" },
71
+ { id: "drywall", name: "Drywall", color: "#f0e8d8" },
72
+ { id: "glass", name: "Glass", color: "#c8e0f0" },
73
+ { id: "wood", name: "Wood Panel", color: "#c8a060" },
74
+ { id: "stone", name: "Stone", color: "#a0a098" },
75
+ { id: "metal", name: "Metal Panel", color: "#b0b0b8" }
89
76
  ];
90
77
  const FLOOR_MATERIALS = [
91
- { id: 'hardwood', name: 'Hardwood', color: '#c09050' },
92
- { id: 'tile-white', name: 'White Tile', color: '#f0f0f0' },
93
- { id: 'tile-grey', name: 'Grey Tile', color: '#b0b0b0' },
94
- { id: 'carpet', name: 'Carpet', color: '#908070' },
95
- { id: 'marble', name: 'Marble', color: '#e8e0d8' },
96
- { id: 'concrete', name: 'Polished Concrete', color: '#c0c0c0' },
97
- { id: 'laminate', name: 'Laminate', color: '#d0b080' },
98
- { id: 'vinyl', name: 'Vinyl', color: '#d0d0c8' },
78
+ { id: "hardwood", name: "Hardwood", color: "#c09050" },
79
+ { id: "tile-white", name: "White Tile", color: "#f0f0f0" },
80
+ { id: "tile-grey", name: "Grey Tile", color: "#b0b0b0" },
81
+ { id: "carpet", name: "Carpet", color: "#908070" },
82
+ { id: "marble", name: "Marble", color: "#e8e0d8" },
83
+ { id: "concrete", name: "Polished Concrete", color: "#c0c0c0" },
84
+ { id: "laminate", name: "Laminate", color: "#d0b080" },
85
+ { id: "vinyl", name: "Vinyl", color: "#d0d0c8" }
99
86
  ];
100
- /* ════════════════════════════════════════════════════════════════
101
- GRID & SNAP
102
- ════════════════════════════════════════════════════════════════ */
103
87
  function createCADGrid(settings) {
104
- const group = new THREE__namespace.Group();
105
- group.name = '__cadGrid';
106
- const size = settings.spacing * 50;
107
- const mainGrid = new THREE__namespace.GridHelper(size * 2, Math.floor((size * 2) / settings.spacing), settings.color, settings.subColor);
108
- mainGrid.position.y = 0.001;
109
- group.add(mainGrid);
110
- if (settings.subdivisions > 1) {
111
- const subSize = settings.spacing / settings.subdivisions;
112
- const subGrid = new THREE__namespace.GridHelper(size * 2, Math.floor((size * 2) / subSize), settings.subColor, `${settings.subColor}44`);
113
- subGrid.position.y = 0;
114
- group.add(subGrid);
115
- }
116
- return group;
88
+ const group = new THREE__namespace.Group();
89
+ group.name = "__cadGrid";
90
+ const size = settings.spacing * 50;
91
+ const mainGrid = new THREE__namespace.GridHelper(
92
+ size * 2,
93
+ Math.floor(size * 2 / settings.spacing),
94
+ settings.color,
95
+ settings.subColor
96
+ );
97
+ mainGrid.position.y = 1e-3;
98
+ group.add(mainGrid);
99
+ if (settings.subdivisions > 1) {
100
+ const subSize = settings.spacing / settings.subdivisions;
101
+ const subGrid = new THREE__namespace.GridHelper(
102
+ size * 2,
103
+ Math.floor(size * 2 / subSize),
104
+ settings.subColor,
105
+ `${settings.subColor}44`
106
+ );
107
+ subGrid.position.y = 0;
108
+ group.add(subGrid);
109
+ }
110
+ return group;
117
111
  }
118
112
  function snapToCADGrid(point, settings) {
119
- const snap = settings.grid.spacing / settings.grid.subdivisions;
120
- return new THREE__namespace.Vector3(Math.round(point.x / snap) * snap, Math.round(point.y / snap) * snap, Math.round(point.z / snap) * snap);
113
+ const snap = settings.grid.spacing / settings.grid.subdivisions;
114
+ return new THREE__namespace.Vector3(
115
+ Math.round(point.x / snap) * snap,
116
+ Math.round(point.y / snap) * snap,
117
+ Math.round(point.z / snap) * snap
118
+ );
121
119
  }
122
-
123
120
  exports.DEFAULT_CAD_SETTINGS = DEFAULT_CAD_SETTINGS;
124
121
  exports.FLOOR_MATERIALS = FLOOR_MATERIALS;
125
122
  exports.ROOM_COLORS = ROOM_COLORS;
@@ -1,220 +1,197 @@
1
- 'use strict';
2
-
3
- /**
4
- * editorShortcuts.ts — Customizable keyboard shortcuts for the 3D ModelEditor.
5
- *
6
- * Features:
7
- * - Pre-configured default shortcuts matching current ModelEditor
8
- * - Rebindable keys with persistence support
9
- * - Shortcut categories for organized display
10
- * - Conflict detection
11
- */
12
- /* ═══════════════════════════════════════════
13
- Helpers
14
- ═══════════════════════════════════════════ */
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
15
3
  function normalizeKey(key) {
16
- return key.length === 1 ? key.toLowerCase() : key;
4
+ return key.length === 1 ? key.toLowerCase() : key;
17
5
  }
18
6
  function bindingEquals(a, b) {
19
- return (normalizeKey(a.key) === normalizeKey(b.key) &&
20
- !!a.ctrl === !!b.ctrl &&
21
- !!a.shift === !!b.shift &&
22
- !!a.alt === !!b.alt &&
23
- !!a.meta === !!b.meta);
7
+ return normalizeKey(a.key) === normalizeKey(b.key) && !!a.ctrl === !!b.ctrl && !!a.shift === !!b.shift && !!a.alt === !!b.alt && !!a.meta === !!b.meta;
24
8
  }
25
9
  function eventToBinding(e) {
26
- return {
27
- key: e.key,
28
- ctrl: e.ctrlKey || e.metaKey,
29
- shift: e.shiftKey,
30
- alt: e.altKey,
31
- };
10
+ return {
11
+ key: e.key,
12
+ ctrl: e.ctrlKey || e.metaKey,
13
+ shift: e.shiftKey,
14
+ alt: e.altKey
15
+ };
32
16
  }
33
- /* ═══════════════════════════════════════════
34
- Default Shortcuts
35
- ═══════════════════════════════════════════ */
36
17
  const DEFAULT_SHORTCUTS = [
37
- // Transform
38
- {
39
- id: 'transform.translate',
40
- label: 'Move (Translate)',
41
- category: 'Transform',
42
- binding: { key: 'g' },
43
- },
44
- { id: 'transform.rotate', label: 'Rotate', category: 'Transform', binding: { key: 'r' } },
45
- { id: 'transform.scale', label: 'Scale', category: 'Transform', binding: { key: 's' } },
46
- {
47
- id: 'transform.delete',
48
- label: 'Delete Selected',
49
- category: 'Transform',
50
- binding: { key: 'Delete' },
51
- },
52
- {
53
- id: 'transform.deleteAlt',
54
- label: 'Delete (Ctrl+X)',
55
- category: 'Transform',
56
- binding: { key: 'x', ctrl: true },
57
- },
58
- {
59
- id: 'transform.duplicate',
60
- label: 'Duplicate',
61
- category: 'Transform',
62
- binding: { key: 'd', shift: true },
63
- },
64
- // Camera
65
- { id: 'camera.focus', label: 'Focus on Object', category: 'Camera', binding: { key: 'f' } },
66
- { id: 'camera.front', label: 'Front View', category: 'Camera', binding: { key: '1' } },
67
- { id: 'camera.right', label: 'Right View', category: 'Camera', binding: { key: '3' } },
68
- { id: 'camera.top', label: 'Top View', category: 'Camera', binding: { key: '7' } },
69
- { id: 'camera.left', label: 'Left View', category: 'Camera', binding: { key: '4' } },
70
- { id: 'camera.back', label: 'Back View', category: 'Camera', binding: { key: '9' } },
71
- { id: 'camera.bottom', label: 'Bottom View', category: 'Camera', binding: { key: '2' } },
72
- // Animation
73
- { id: 'anim.playPause', label: 'Play / Pause', category: 'Animation', binding: { key: ' ' } },
74
- // Edit
75
- { id: 'edit.undo', label: 'Undo', category: 'Edit', binding: { key: 'z', ctrl: true } },
76
- { id: 'edit.redo', label: 'Redo', category: 'Edit', binding: { key: 'y', ctrl: true } },
77
- {
78
- id: 'edit.redoAlt',
79
- label: 'Redo (Ctrl+Shift+Z)',
80
- category: 'Edit',
81
- binding: { key: 'z', ctrl: true, shift: true },
82
- },
83
- // Mode
84
- { id: 'mode.cycle', label: 'Cycle Editor Mode', category: 'Mode', binding: { key: 'Tab' } },
85
- { id: 'mode.escape', label: 'Close/Cancel', category: 'Mode', binding: { key: 'Escape' } },
18
+ // Transform
19
+ {
20
+ id: "transform.translate",
21
+ label: "Move (Translate)",
22
+ category: "Transform",
23
+ binding: { key: "g" }
24
+ },
25
+ { id: "transform.rotate", label: "Rotate", category: "Transform", binding: { key: "r" } },
26
+ { id: "transform.scale", label: "Scale", category: "Transform", binding: { key: "s" } },
27
+ {
28
+ id: "transform.delete",
29
+ label: "Delete Selected",
30
+ category: "Transform",
31
+ binding: { key: "Delete" }
32
+ },
33
+ {
34
+ id: "transform.deleteAlt",
35
+ label: "Delete (Ctrl+X)",
36
+ category: "Transform",
37
+ binding: { key: "x", ctrl: true }
38
+ },
39
+ {
40
+ id: "transform.duplicate",
41
+ label: "Duplicate",
42
+ category: "Transform",
43
+ binding: { key: "d", shift: true }
44
+ },
45
+ // Camera
46
+ { id: "camera.focus", label: "Focus on Object", category: "Camera", binding: { key: "f" } },
47
+ { id: "camera.front", label: "Front View", category: "Camera", binding: { key: "1" } },
48
+ { id: "camera.right", label: "Right View", category: "Camera", binding: { key: "3" } },
49
+ { id: "camera.top", label: "Top View", category: "Camera", binding: { key: "7" } },
50
+ { id: "camera.left", label: "Left View", category: "Camera", binding: { key: "4" } },
51
+ { id: "camera.back", label: "Back View", category: "Camera", binding: { key: "9" } },
52
+ { id: "camera.bottom", label: "Bottom View", category: "Camera", binding: { key: "2" } },
53
+ // Animation
54
+ { id: "anim.playPause", label: "Play / Pause", category: "Animation", binding: { key: " " } },
55
+ // Edit
56
+ { id: "edit.undo", label: "Undo", category: "Edit", binding: { key: "z", ctrl: true } },
57
+ { id: "edit.redo", label: "Redo", category: "Edit", binding: { key: "y", ctrl: true } },
58
+ {
59
+ id: "edit.redoAlt",
60
+ label: "Redo (Ctrl+Shift+Z)",
61
+ category: "Edit",
62
+ binding: { key: "z", ctrl: true, shift: true }
63
+ },
64
+ // Mode
65
+ { id: "mode.cycle", label: "Cycle Editor Mode", category: "Mode", binding: { key: "Tab" } },
66
+ { id: "mode.escape", label: "Close/Cancel", category: "Mode", binding: { key: "Escape" } }
86
67
  ];
87
- /* ═══════════════════════════════════════════
88
- EditorShortcutManager
89
- ═══════════════════════════════════════════ */
90
68
  class EditorShortcutManager {
91
- constructor() {
92
- this.shortcuts = new Map();
93
- this.callbacks = new Map();
94
- for (const def of DEFAULT_SHORTCUTS) {
95
- this.shortcuts.set(def.id, { ...def, enabled: true });
96
- }
69
+ constructor() {
70
+ this.shortcuts = /* @__PURE__ */ new Map();
71
+ this.callbacks = /* @__PURE__ */ new Map();
72
+ for (const def of DEFAULT_SHORTCUTS) {
73
+ this.shortcuts.set(def.id, { ...def, enabled: true });
97
74
  }
98
- /** Register a callback for a shortcut ID. */
99
- on(id, callback) {
100
- this.callbacks.set(id, callback);
75
+ }
76
+ /** Register a callback for a shortcut ID. */
77
+ on(id, callback) {
78
+ this.callbacks.set(id, callback);
79
+ }
80
+ /** Unregister a callback. */
81
+ off(id) {
82
+ this.callbacks.delete(id);
83
+ }
84
+ /** Rebind a shortcut to a new key combination. */
85
+ rebind(id, binding) {
86
+ const shortcut = this.shortcuts.get(id);
87
+ if (shortcut) {
88
+ shortcut.binding = binding;
101
89
  }
102
- /** Unregister a callback. */
103
- off(id) {
104
- this.callbacks.delete(id);
90
+ }
91
+ /** Enable/disable a shortcut. */
92
+ setEnabled(id, enabled) {
93
+ const shortcut = this.shortcuts.get(id);
94
+ if (shortcut) {
95
+ shortcut.enabled = enabled;
105
96
  }
106
- /** Rebind a shortcut to a new key combination. */
107
- rebind(id, binding) {
108
- const shortcut = this.shortcuts.get(id);
109
- if (shortcut) {
110
- shortcut.binding = binding;
111
- }
97
+ }
98
+ /** Reset all bindings to defaults. */
99
+ resetAll() {
100
+ this.shortcuts.clear();
101
+ for (const def of DEFAULT_SHORTCUTS) {
102
+ this.shortcuts.set(def.id, { ...def, enabled: true });
112
103
  }
113
- /** Enable/disable a shortcut. */
114
- setEnabled(id, enabled) {
115
- const shortcut = this.shortcuts.get(id);
116
- if (shortcut) {
117
- shortcut.enabled = enabled;
118
- }
104
+ }
105
+ /** Get all shortcuts grouped by category. */
106
+ getGrouped() {
107
+ const groups = {};
108
+ for (const s of this.shortcuts.values()) {
109
+ if (!groups[s.category]) {
110
+ groups[s.category] = [];
111
+ }
112
+ groups[s.category].push(s);
119
113
  }
120
- /** Reset all bindings to defaults. */
121
- resetAll() {
122
- this.shortcuts.clear();
123
- for (const def of DEFAULT_SHORTCUTS) {
124
- this.shortcuts.set(def.id, { ...def, enabled: true });
114
+ return groups;
115
+ }
116
+ /** Get all shortcuts as a flat array. */
117
+ getAll() {
118
+ return [...this.shortcuts.values()];
119
+ }
120
+ /** Find conflicts (two shortcuts with the same binding). */
121
+ findConflicts() {
122
+ const conflicts = [];
123
+ const entries = [...this.shortcuts.values()];
124
+ for (let i = 0; i < entries.length; i++) {
125
+ for (let j = i + 1; j < entries.length; j++) {
126
+ if (bindingEquals(entries[i].binding, entries[j].binding)) {
127
+ conflicts.push([entries[i], entries[j]]);
125
128
  }
129
+ }
126
130
  }
127
- /** Get all shortcuts grouped by category. */
128
- getGrouped() {
129
- const groups = {};
130
- for (const s of this.shortcuts.values()) {
131
- if (!groups[s.category]) {
132
- groups[s.category] = [];
133
- }
134
- groups[s.category].push(s);
135
- }
136
- return groups;
131
+ return conflicts;
132
+ }
133
+ /** Export bindings for persistence. */
134
+ exportConfig() {
135
+ return [...this.shortcuts.values()].map((s) => ({
136
+ id: s.id,
137
+ binding: s.binding
138
+ }));
139
+ }
140
+ /** Import bindings from saved config. */
141
+ importConfig(configs) {
142
+ for (const config of configs) {
143
+ this.rebind(config.id, config.binding);
137
144
  }
138
- /** Get all shortcuts as a flat array. */
139
- getAll() {
140
- return [...this.shortcuts.values()];
145
+ }
146
+ /** Match a keyboard event to a shortcut and return its ID (or null). */
147
+ match(e) {
148
+ const evtBinding = eventToBinding(e);
149
+ for (const [id, shortcut] of this.shortcuts) {
150
+ if (!shortcut.enabled) {
151
+ continue;
152
+ }
153
+ if (bindingEquals(evtBinding, shortcut.binding)) {
154
+ return id;
155
+ }
141
156
  }
142
- /** Find conflicts (two shortcuts with the same binding). */
143
- findConflicts() {
144
- const conflicts = [];
145
- const entries = [...this.shortcuts.values()];
146
- for (let i = 0; i < entries.length; i++) {
147
- for (let j = i + 1; j < entries.length; j++) {
148
- if (bindingEquals(entries[i].binding, entries[j].binding)) {
149
- conflicts.push([entries[i], entries[j]]);
150
- }
151
- }
152
- }
153
- return conflicts;
157
+ return null;
158
+ }
159
+ /** Handle a keyboard event — fires callback if matched. Returns true if handled. */
160
+ handleKeyDown(e) {
161
+ const id = this.match(e);
162
+ if (!id) {
163
+ return false;
154
164
  }
155
- /** Export bindings for persistence. */
156
- exportConfig() {
157
- return [...this.shortcuts.values()].map((s) => ({
158
- id: s.id,
159
- binding: s.binding,
160
- }));
165
+ const cb = this.callbacks.get(id);
166
+ if (cb) {
167
+ e.preventDefault();
168
+ cb();
169
+ return true;
161
170
  }
162
- /** Import bindings from saved config. */
163
- importConfig(configs) {
164
- for (const config of configs) {
165
- this.rebind(config.id, config.binding);
166
- }
171
+ return false;
172
+ }
173
+ /** Format a binding for UI display. */
174
+ formatBinding(id) {
175
+ const shortcut = this.shortcuts.get(id);
176
+ if (!shortcut) {
177
+ return "";
167
178
  }
168
- /** Match a keyboard event to a shortcut and return its ID (or null). */
169
- match(e) {
170
- const evtBinding = eventToBinding(e);
171
- for (const [id, shortcut] of this.shortcuts) {
172
- if (!shortcut.enabled) {
173
- continue;
174
- }
175
- if (bindingEquals(evtBinding, shortcut.binding)) {
176
- return id;
177
- }
178
- }
179
- return null;
179
+ const b = shortcut.binding;
180
+ const parts = [];
181
+ if (b.ctrl) {
182
+ parts.push("Ctrl");
180
183
  }
181
- /** Handle a keyboard event — fires callback if matched. Returns true if handled. */
182
- handleKeyDown(e) {
183
- const id = this.match(e);
184
- if (!id) {
185
- return false;
186
- }
187
- const cb = this.callbacks.get(id);
188
- if (cb) {
189
- e.preventDefault();
190
- cb();
191
- return true;
192
- }
193
- return false;
184
+ if (b.shift) {
185
+ parts.push("Shift");
194
186
  }
195
- /** Format a binding for UI display. */
196
- formatBinding(id) {
197
- const shortcut = this.shortcuts.get(id);
198
- if (!shortcut) {
199
- return '';
200
- }
201
- const b = shortcut.binding;
202
- const parts = [];
203
- if (b.ctrl) {
204
- parts.push('Ctrl');
205
- }
206
- if (b.shift) {
207
- parts.push('Shift');
208
- }
209
- if (b.alt) {
210
- parts.push('Alt');
211
- }
212
- if (b.meta) {
213
- parts.push('Meta');
214
- }
215
- parts.push(b.key === ' ' ? 'Space' : b.key.length === 1 ? b.key.toUpperCase() : b.key);
216
- return parts.join('+');
187
+ if (b.alt) {
188
+ parts.push("Alt");
189
+ }
190
+ if (b.meta) {
191
+ parts.push("Meta");
217
192
  }
193
+ parts.push(b.key === " " ? "Space" : b.key.length === 1 ? b.key.toUpperCase() : b.key);
194
+ return parts.join("+");
195
+ }
218
196
  }
219
-
220
197
  exports.EditorShortcutManager = EditorShortcutManager;