@nice2dev/ui-3d 1.0.6 → 1.1.0

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 (79) hide show
  1. package/dist/cjs/core/i18n.js +3 -3
  2. package/dist/cjs/dance/DanceBridge.js +13 -13
  3. package/dist/cjs/dance/DanceScoreEngine.js +8 -8
  4. package/dist/cjs/dance/PoseDetector.js +20 -20
  5. package/dist/cjs/material/NiceMaterialEditor.js +19 -19
  6. package/dist/cjs/model/ModelEditorLeftPanel.js +5 -5
  7. package/dist/cjs/model/ModelEditorMenuBar.js +6 -6
  8. package/dist/cjs/model/ModelEditorRightPanel.js +19 -19
  9. package/dist/cjs/model/ModelEditorSubComponents.js +10 -10
  10. package/dist/cjs/model/ModelEditorTimeline.js +6 -6
  11. package/dist/cjs/model/ModelEditorToolbar.js +4 -4
  12. package/dist/cjs/model/ModelEditorViewport.js +2 -2
  13. package/dist/cjs/model/ModelViewer.js +14 -14
  14. package/dist/cjs/model/NiceArmatureEditor.js +18 -18
  15. package/dist/cjs/model/NiceMorphTargetEditor.js +18 -18
  16. package/dist/cjs/model/NiceOctree.js +16 -16
  17. package/dist/cjs/model/NicePhysicsSimulation.js +24 -24
  18. package/dist/cjs/model/NiceProceduralGeometry.js +8 -8
  19. package/dist/cjs/model/NiceTerrainEditor.js +19 -19
  20. package/dist/cjs/model/NiceWeightPainter.js +14 -14
  21. package/dist/cjs/model/NiceXRPreview.js +18 -18
  22. package/dist/cjs/model/useModelEditor.js +127 -127
  23. package/dist/cjs/model/useModelViewer.js +61 -61
  24. package/dist/cjs/particle/NiceParticleEditor.js +11 -11
  25. package/dist/cjs/rendering/NiceCascadedShadows.js +12 -12
  26. package/dist/cjs/rendering/NiceRenderExport.js +5 -5
  27. package/dist/cjs/rendering/NiceSSAO.js +18 -18
  28. package/dist/cjs/rendering/NiceSSR.js +14 -14
  29. package/dist/cjs/rendering/NiceWebGPURenderer.js +21 -21
  30. package/dist/cjs/ui/dist/NiceButton-D9l39Rs7.js +598 -0
  31. package/dist/cjs/ui/dist/NiceButton-D9l39Rs7.js.map +1 -0
  32. package/dist/cjs/ui/dist/NiceErrorBoundary-niMx1aSJ.js +647 -0
  33. package/dist/cjs/ui/dist/NiceErrorBoundary-niMx1aSJ.js.map +1 -0
  34. package/dist/cjs/ui/dist/NiceModuleLifecyclePanel-I_TXRiiY.js +5048 -0
  35. package/dist/cjs/ui/dist/NiceModuleLifecyclePanel-I_TXRiiY.js.map +1 -0
  36. package/dist/cjs/ui/dist/NicePinCodeInput-CrMfdxxc.js +13081 -0
  37. package/dist/cjs/ui/dist/NicePinCodeInput-CrMfdxxc.js.map +1 -0
  38. package/dist/cjs/ui/dist/NiceSavedQueryPanel-CUAsdOjJ.js +6054 -0
  39. package/dist/cjs/ui/dist/NiceSavedQueryPanel-CUAsdOjJ.js.map +1 -0
  40. package/dist/cjs/ui/dist/NiceToggle-CaY1u82g.js +280 -0
  41. package/dist/cjs/ui/dist/NiceToggle-CaY1u82g.js.map +1 -0
  42. package/dist/cjs/ui/dist/NiceWindow-SiCaREbq.js +806 -0
  43. package/dist/cjs/ui/dist/NiceWindow-SiCaREbq.js.map +1 -0
  44. package/dist/cjs/ui/dist/charts-Bx_kNBsE.js +3508 -0
  45. package/dist/cjs/ui/dist/charts-Bx_kNBsE.js.map +1 -0
  46. package/dist/cjs/ui/dist/core-BpghV7Ls.js +10249 -0
  47. package/dist/cjs/ui/dist/core-BpghV7Ls.js.map +1 -0
  48. package/dist/cjs/ui/dist/index-CIl98Vbm.js +40039 -0
  49. package/dist/cjs/ui/dist/index-CIl98Vbm.js.map +1 -0
  50. package/dist/cjs/uv/NiceUVEditor.js +24 -24
  51. package/dist/esm/model/ModelEditorLeftPanel.js +4 -4
  52. package/dist/esm/model/ModelEditorMenuBar.js +4 -4
  53. package/dist/esm/model/ModelEditorRightPanel.js +5 -5
  54. package/dist/esm/model/ModelEditorSubComponents.js +2 -2
  55. package/dist/esm/model/ModelEditorTimeline.js +5 -5
  56. package/dist/esm/model/ModelEditorToolbar.js +3 -3
  57. package/dist/esm/model/ModelEditorViewport.js +2 -2
  58. package/dist/esm/model/ModelViewer.js +2 -2
  59. package/dist/esm/ui/dist/NiceButton-D9l39Rs7.js +593 -0
  60. package/dist/esm/ui/dist/NiceButton-D9l39Rs7.js.map +1 -0
  61. package/dist/esm/ui/dist/NiceErrorBoundary-niMx1aSJ.js +637 -0
  62. package/dist/esm/ui/dist/NiceErrorBoundary-niMx1aSJ.js.map +1 -0
  63. package/dist/esm/ui/dist/NiceModuleLifecyclePanel-I_TXRiiY.js +5007 -0
  64. package/dist/esm/ui/dist/NiceModuleLifecyclePanel-I_TXRiiY.js.map +1 -0
  65. package/dist/esm/ui/dist/NicePinCodeInput-CrMfdxxc.js +13011 -0
  66. package/dist/esm/ui/dist/NicePinCodeInput-CrMfdxxc.js.map +1 -0
  67. package/dist/esm/ui/dist/NiceSavedQueryPanel-CUAsdOjJ.js +6037 -0
  68. package/dist/esm/ui/dist/NiceSavedQueryPanel-CUAsdOjJ.js.map +1 -0
  69. package/dist/esm/ui/dist/NiceToggle-CaY1u82g.js +276 -0
  70. package/dist/esm/ui/dist/NiceToggle-CaY1u82g.js.map +1 -0
  71. package/dist/esm/ui/dist/NiceWindow-SiCaREbq.js +795 -0
  72. package/dist/esm/ui/dist/NiceWindow-SiCaREbq.js.map +1 -0
  73. package/dist/esm/ui/dist/charts-Bx_kNBsE.js +3483 -0
  74. package/dist/esm/ui/dist/charts-Bx_kNBsE.js.map +1 -0
  75. package/dist/esm/ui/dist/core-BpghV7Ls.js +10071 -0
  76. package/dist/esm/ui/dist/core-BpghV7Ls.js.map +1 -0
  77. package/dist/esm/ui/dist/index-CIl98Vbm.js +39917 -0
  78. package/dist/esm/ui/dist/index-CIl98Vbm.js.map +1 -0
  79. package/package.json +1 -1
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
- var we = require('react');
4
+ var ke = require('react');
5
5
 
6
6
  const fallback = (_key, defaultValue) => defaultValue;
7
- const NiceI18nContext = we.createContext(fallback);
7
+ const NiceI18nContext = ke.createContext(fallback);
8
8
  const NiceI18nProvider = ({ t, children }) => (jsxRuntime.jsx(NiceI18nContext.Provider, { value: t, children: children }));
9
9
  function useNiceTranslation() {
10
- const t = we.useContext(NiceI18nContext);
10
+ const t = ke.useContext(NiceI18nContext);
11
11
  return { t };
12
12
  }
13
13
 
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var we = require('react');
3
+ var ke = require('react');
4
4
  var DanceScoreEngine = require('./DanceScoreEngine.js');
5
5
 
6
6
  /**
@@ -113,13 +113,13 @@ class DanceBridge {
113
113
  }
114
114
  // ── React hook: useDanceBridge ──────────────────────────────────
115
115
  function useDanceBridge(config, callbacks) {
116
- const bridgeRef = we.useRef(null);
117
- const [state, setState] = we.useState('idle');
118
- const [lastScore, setLastScore] = we.useState(null);
119
- const [result, setResult] = we.useState(null);
120
- const [combo, setCombo] = we.useState(0);
121
- const [progress, setProgress] = we.useState(0);
122
- we.useEffect(() => {
116
+ const bridgeRef = ke.useRef(null);
117
+ const [state, setState] = ke.useState('idle');
118
+ const [lastScore, setLastScore] = ke.useState(null);
119
+ const [result, setResult] = ke.useState(null);
120
+ const [combo, setCombo] = ke.useState(0);
121
+ const [progress, setProgress] = ke.useState(0);
122
+ ke.useEffect(() => {
123
123
  if (!config) {
124
124
  bridgeRef.current = null;
125
125
  return;
@@ -134,11 +134,11 @@ function useDanceBridge(config, callbacks) {
134
134
  return () => { bridgeRef.current = null; };
135
135
  // eslint-disable-next-line react-hooks/exhaustive-deps
136
136
  }, [config]);
137
- const start = we.useCallback(() => { var _a; (_a = bridgeRef.current) === null || _a === void 0 ? void 0 : _a.start(); }, []);
138
- const pause = we.useCallback(() => { var _a; (_a = bridgeRef.current) === null || _a === void 0 ? void 0 : _a.pause(); }, []);
139
- const resume = we.useCallback(() => { var _a; (_a = bridgeRef.current) === null || _a === void 0 ? void 0 : _a.resume(); }, []);
140
- const stop = we.useCallback(() => { var _a, _b; return (_b = (_a = bridgeRef.current) === null || _a === void 0 ? void 0 : _a.stop()) !== null && _b !== void 0 ? _b : null; }, []);
141
- const feedFrame = we.useCallback((frame) => {
137
+ const start = ke.useCallback(() => { var _a; (_a = bridgeRef.current) === null || _a === void 0 ? void 0 : _a.start(); }, []);
138
+ const pause = ke.useCallback(() => { var _a; (_a = bridgeRef.current) === null || _a === void 0 ? void 0 : _a.pause(); }, []);
139
+ const resume = ke.useCallback(() => { var _a; (_a = bridgeRef.current) === null || _a === void 0 ? void 0 : _a.resume(); }, []);
140
+ const stop = ke.useCallback(() => { var _a, _b; return (_b = (_a = bridgeRef.current) === null || _a === void 0 ? void 0 : _a.stop()) !== null && _b !== void 0 ? _b : null; }, []);
141
+ const feedFrame = ke.useCallback((frame) => {
142
142
  var _a, _b;
143
143
  const score = (_b = (_a = bridgeRef.current) === null || _a === void 0 ? void 0 : _a.feedFrame(frame)) !== null && _b !== void 0 ? _b : null;
144
144
  if (bridgeRef.current)
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var we = require('react');
3
+ var ke = require('react');
4
4
 
5
5
  // ── Default config ──────────────────────────────────────────────
6
6
  const DEFAULT_CONFIG = {
@@ -179,25 +179,25 @@ class DanceScoreEngine {
179
179
  }
180
180
  }
181
181
  function useDanceScore(config) {
182
- const engineRef = we.useRef(new DanceScoreEngine(config));
183
- const [lastScore, setLastScore] = we.useState(null);
184
- const [result, setResult] = we.useState(null);
185
- const loadReference = we.useCallback((seq) => {
182
+ const engineRef = ke.useRef(new DanceScoreEngine(config));
183
+ const [lastScore, setLastScore] = ke.useState(null);
184
+ const [result, setResult] = ke.useState(null);
185
+ const loadReference = ke.useCallback((seq) => {
186
186
  engineRef.current.loadReference(seq);
187
187
  setLastScore(null);
188
188
  setResult(null);
189
189
  }, []);
190
- const scoreFrame = we.useCallback((frame) => {
190
+ const scoreFrame = ke.useCallback((frame) => {
191
191
  const score = engineRef.current.scoreFrame(frame);
192
192
  setLastScore(score);
193
193
  return score;
194
194
  }, []);
195
- const finish = we.useCallback(() => {
195
+ const finish = ke.useCallback(() => {
196
196
  const r = engineRef.current.getResult();
197
197
  setResult(r);
198
198
  return r;
199
199
  }, []);
200
- const reset = we.useCallback(() => {
200
+ const reset = ke.useCallback(() => {
201
201
  engineRef.current.reset();
202
202
  setLastScore(null);
203
203
  setResult(null);
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
- var we = require('react');
4
+ var ke = require('react');
5
5
 
6
6
  // ── Standard keypoint definitions (COCO 17-keypoint model) ──────
7
7
  const COCO_KEYPOINTS = [
@@ -31,14 +31,14 @@ function createSimulatedKeypoints() {
31
31
  // ── Hook: usePoseDetection ──────────────────────────────────────
32
32
  function usePoseDetection(config = {}) {
33
33
  const { maxPersons = 1, minConfidence = 0.5, targetFps = 30, } = config;
34
- const [isDetecting, setIsDetecting] = we.useState(false);
35
- const latestFrameRef = we.useRef(null);
36
- const frameIndexRef = we.useRef(0);
37
- const rafRef = we.useRef(0);
38
- const streamRef = we.useRef(null);
39
- const videoRef = we.useRef(null);
40
- const callbackRef = we.useRef(null);
41
- const processFrame = we.useCallback(() => {
34
+ const [isDetecting, setIsDetecting] = ke.useState(false);
35
+ const latestFrameRef = ke.useRef(null);
36
+ const frameIndexRef = ke.useRef(0);
37
+ const rafRef = ke.useRef(0);
38
+ const streamRef = ke.useRef(null);
39
+ const videoRef = ke.useRef(null);
40
+ const callbackRef = ke.useRef(null);
41
+ const processFrame = ke.useCallback(() => {
42
42
  var _a;
43
43
  if (!videoRef.current || videoRef.current.readyState < 2) {
44
44
  rafRef.current = requestAnimationFrame(processFrame);
@@ -64,7 +64,7 @@ function usePoseDetection(config = {}) {
64
64
  (_a = callbackRef.current) === null || _a === void 0 ? void 0 : _a.call(callbackRef, frame);
65
65
  rafRef.current = requestAnimationFrame(processFrame);
66
66
  }, [maxPersons, minConfidence, targetFps]);
67
- const start = we.useCallback(async (video, onFrame) => {
67
+ const start = ke.useCallback(async (video, onFrame) => {
68
68
  try {
69
69
  const stream = await navigator.mediaDevices.getUserMedia({
70
70
  video: { facingMode: 'user', width: { ideal: 640 }, height: { ideal: 480 } },
@@ -82,7 +82,7 @@ function usePoseDetection(config = {}) {
82
82
  throw new Error(`Camera access failed: ${err instanceof Error ? err.message : String(err)}`);
83
83
  }
84
84
  }, [processFrame]);
85
- const stop = we.useCallback(() => {
85
+ const stop = ke.useCallback(() => {
86
86
  var _a;
87
87
  cancelAnimationFrame(rafRef.current);
88
88
  (_a = streamRef.current) === null || _a === void 0 ? void 0 : _a.getTracks().forEach(t => t.stop());
@@ -91,22 +91,22 @@ function usePoseDetection(config = {}) {
91
91
  videoRef.current.srcObject = null;
92
92
  setIsDetecting(false);
93
93
  }, []);
94
- we.useEffect(() => () => { stop(); }, [stop]);
94
+ ke.useEffect(() => () => { stop(); }, [stop]);
95
95
  return { start, stop, isDetecting, getLatestFrame: () => latestFrameRef.current };
96
96
  }
97
97
  // ── Component: PoseDetector ─────────────────────────────────────
98
- const NicePoseDetector = we.forwardRef(function NicePoseDetector(props, ref) {
98
+ const NicePoseDetector = ke.forwardRef(function NicePoseDetector(props, ref) {
99
99
  const { onFrame, onStart, onStop, onError, className, style, width = 640, height = 480, mirror = true, showSkeleton = true, showConfidence = false, ...config } = props;
100
- const videoRef = we.useRef(null);
101
- const canvasRef = we.useRef(null);
100
+ const videoRef = ke.useRef(null);
101
+ const canvasRef = ke.useRef(null);
102
102
  const detection = usePoseDetection(config);
103
- we.useImperativeHandle(ref, () => ({
103
+ ke.useImperativeHandle(ref, () => ({
104
104
  start: handleStart,
105
105
  stop: handleStop,
106
106
  getLatestFrame: detection.getLatestFrame,
107
107
  get isDetecting() { return detection.isDetecting; },
108
108
  }));
109
- const drawSkeleton = we.useCallback((frame) => {
109
+ const drawSkeleton = ke.useCallback((frame) => {
110
110
  var _a, _b, _c, _d, _e, _f;
111
111
  const ctx = (_a = canvasRef.current) === null || _a === void 0 ? void 0 : _a.getContext('2d');
112
112
  if (!ctx || !canvasRef.current)
@@ -144,11 +144,11 @@ const NicePoseDetector = we.forwardRef(function NicePoseDetector(props, ref) {
144
144
  }
145
145
  }
146
146
  }, [showSkeleton, showConfidence]);
147
- const handleFrame = we.useCallback((frame) => {
147
+ const handleFrame = ke.useCallback((frame) => {
148
148
  drawSkeleton(frame);
149
149
  onFrame === null || onFrame === void 0 ? void 0 : onFrame(frame);
150
150
  }, [drawSkeleton, onFrame]);
151
- const handleStart = we.useCallback(async () => {
151
+ const handleStart = ke.useCallback(async () => {
152
152
  try {
153
153
  if (videoRef.current) {
154
154
  await detection.start(videoRef.current, handleFrame);
@@ -159,7 +159,7 @@ const NicePoseDetector = we.forwardRef(function NicePoseDetector(props, ref) {
159
159
  onError === null || onError === void 0 ? void 0 : onError(err instanceof Error ? err : new Error(String(err)));
160
160
  }
161
161
  }, [detection, handleFrame, onStart, onError]);
162
- const handleStop = we.useCallback(() => {
162
+ const handleStop = ke.useCallback(() => {
163
163
  detection.stop();
164
164
  onStop === null || onStop === void 0 ? void 0 : onStop();
165
165
  }, [detection, onStop]);
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
- var we = require('react');
4
+ var ke = require('react');
5
5
  var materialEditorTypes = require('./materialEditorTypes.js');
6
6
  var materialNodeDefinitions = require('./materialNodeDefinitions.js');
7
7
  var materialEditorUtils = require('./materialEditorUtils.js');
@@ -338,9 +338,9 @@ function materialEditorReducer(state, action) {
338
338
  Hook: useMaterialEditor
339
339
  ═══════════════════════════════════════════════════════════════════════════ */
340
340
  function useMaterialEditor(initialGraph) {
341
- const [state, dispatch] = we.useReducer(materialEditorReducer, initialGraph, createInitialState);
341
+ const [state, dispatch] = ke.useReducer(materialEditorReducer, initialGraph, createInitialState);
342
342
  // Auto-compile when graph changes
343
- we.useEffect(() => {
343
+ ke.useEffect(() => {
344
344
  if (state.autoCompile && !state.compiling) {
345
345
  const timeout = setTimeout(() => {
346
346
  dispatch({ type: 'COMPILE' });
@@ -356,7 +356,7 @@ function NodePalette({ searchQuery, expandedCategories, onSearch, onToggleCatego
356
356
  const filteredNodes = searchQuery
357
357
  ? materialNodeDefinitions.searchNodes(searchQuery)
358
358
  : materialNodeDefinitions.MATERIAL_NODE_DEFINITIONS;
359
- const categories = we.useMemo(() => {
359
+ const categories = ke.useMemo(() => {
360
360
  const cats = new Map();
361
361
  for (const node of filteredNodes) {
362
362
  if (!cats.has(node.category)) {
@@ -369,9 +369,9 @@ function NodePalette({ searchQuery, expandedCategories, onSearch, onToggleCatego
369
369
  return (jsxRuntime.jsxs("div", { className: MaterialEditor_module.palette, children: [jsxRuntime.jsx("div", { className: MaterialEditor_module.paletteSearch, children: jsxRuntime.jsx("input", { type: "text", placeholder: "Search nodes...", value: searchQuery, onChange: e => onSearch(e.target.value), className: MaterialEditor_module.searchInput }) }), jsxRuntime.jsx("div", { className: MaterialEditor_module.paletteCategories, children: Array.from(categories.entries()).map(([category, nodes]) => (jsxRuntime.jsxs("div", { className: MaterialEditor_module.paletteCategory, children: [jsxRuntime.jsxs("button", { className: MaterialEditor_module.categoryHeader, onClick: () => onToggleCategory(category), style: { borderLeftColor: materialEditorTypes.NODE_CATEGORY_COLORS[category] }, children: [jsxRuntime.jsx("span", { className: MaterialEditor_module.categoryIcon, children: expandedCategories.includes(category) ? '▼' : '►' }), jsxRuntime.jsx("span", { children: materialEditorTypes.NODE_CATEGORY_NAMES[category] }), jsxRuntime.jsx("span", { className: MaterialEditor_module.categoryCount, children: nodes.length })] }), expandedCategories.includes(category) && (jsxRuntime.jsx("div", { className: MaterialEditor_module.categoryNodes, children: nodes.map(nodeDef => (jsxRuntime.jsxs("div", { className: MaterialEditor_module.paletteNode, draggable: true, onDragStart: e => onDragStart(nodeDef.type, e), onDoubleClick: () => onAddNode(nodeDef.type), title: nodeDef.description, children: [jsxRuntime.jsx("span", { className: MaterialEditor_module.nodeColor, style: { backgroundColor: nodeDef.color || materialEditorTypes.NODE_CATEGORY_COLORS[nodeDef.category] } }), jsxRuntime.jsx("span", { className: MaterialEditor_module.nodeName, children: nodeDef.name })] }, nodeDef.type))) }))] }, category))) })] }));
370
370
  }
371
371
  function GraphNode({ node, definition, selected, viewTransform, connections, onSelect, onMove, onStartConnection, }) {
372
- const nodeRef = we.useRef(null);
373
- const [isDragging, setIsDragging] = we.useState(false);
374
- const dragStart = we.useRef(null);
372
+ const nodeRef = ke.useRef(null);
373
+ const [isDragging, setIsDragging] = ke.useState(false);
374
+ const dragStart = ke.useRef(null);
375
375
  const handleMouseDown = (e) => {
376
376
  if (e.button !== 0)
377
377
  return;
@@ -384,7 +384,7 @@ function GraphNode({ node, definition, selected, viewTransform, connections, onS
384
384
  dragStart.current = { x: e.clientX, y: e.clientY };
385
385
  }
386
386
  };
387
- we.useEffect(() => {
387
+ ke.useEffect(() => {
388
388
  if (!isDragging)
389
389
  return;
390
390
  const handleMouseMove = (e) => {
@@ -441,10 +441,10 @@ function Toolbar({ canUndo, canRedo, canPaste, hasSelection, autoCompile, compil
441
441
  return (jsxRuntime.jsxs("div", { className: MaterialEditor_module.toolbar, children: [jsxRuntime.jsxs("div", { className: MaterialEditor_module.toolbarGroup, children: [jsxRuntime.jsx("button", { onClick: onNew, title: "New Material (Ctrl+N)", children: "\uD83D\uDCC4" }), jsxRuntime.jsx("button", { onClick: onImport, title: "Import (Ctrl+O)", children: "\uD83D\uDCC2" }), jsxRuntime.jsx("button", { onClick: onExport, title: "Export (Ctrl+S)", children: "\uD83D\uDCBE" })] }), jsxRuntime.jsx("div", { className: MaterialEditor_module.toolbarSeparator }), jsxRuntime.jsxs("div", { className: MaterialEditor_module.toolbarGroup, children: [jsxRuntime.jsx("button", { onClick: onUndo, disabled: !canUndo, title: "Undo (Ctrl+Z)", children: "\u21A9\uFE0F" }), jsxRuntime.jsx("button", { onClick: onRedo, disabled: !canRedo, title: "Redo (Ctrl+Y)", children: "\u21AA\uFE0F" })] }), jsxRuntime.jsx("div", { className: MaterialEditor_module.toolbarSeparator }), jsxRuntime.jsxs("div", { className: MaterialEditor_module.toolbarGroup, children: [jsxRuntime.jsx("button", { onClick: onCut, disabled: !hasSelection, title: "Cut (Ctrl+X)", children: "\u2702\uFE0F" }), jsxRuntime.jsx("button", { onClick: onCopy, disabled: !hasSelection, title: "Copy (Ctrl+C)", children: "\uD83D\uDCCB" }), jsxRuntime.jsx("button", { onClick: onPaste, disabled: !canPaste, title: "Paste (Ctrl+V)", children: "\uD83D\uDCE5" }), jsxRuntime.jsx("button", { onClick: onDuplicate, disabled: !hasSelection, title: "Duplicate (Ctrl+D)", children: "\uD83D\uDD04" }), jsxRuntime.jsx("button", { onClick: onDelete, disabled: !hasSelection, title: "Delete (Del)", children: "\uD83D\uDDD1\uFE0F" })] }), jsxRuntime.jsx("div", { className: MaterialEditor_module.toolbarSeparator }), jsxRuntime.jsxs("div", { className: MaterialEditor_module.toolbarGroup, children: [jsxRuntime.jsx("button", { onClick: onSelectAll, title: "Select All (Ctrl+A)", children: "\u2B1C" }), jsxRuntime.jsx("button", { onClick: onZoomToFit, title: "Zoom to Fit (F)", children: "\uD83D\uDD0D" }), jsxRuntime.jsx("button", { onClick: onToggleGrid, className: showGrid ? MaterialEditor_module.active : '', title: "Toggle Grid (G)", children: "#" }), jsxRuntime.jsx("button", { onClick: onToggleSnap, className: snapToGrid ? MaterialEditor_module.active : '', title: "Toggle Snap (S)", children: "\uD83E\uDDF2" })] }), jsxRuntime.jsx("div", { className: MaterialEditor_module.toolbarSeparator }), jsxRuntime.jsxs("div", { className: MaterialEditor_module.toolbarGroup, children: [jsxRuntime.jsx("button", { onClick: onToggleAutoCompile, className: autoCompile ? MaterialEditor_module.active : '', title: "Auto Compile", children: "\u26A1" }), jsxRuntime.jsx("button", { onClick: onCompile, disabled: compiling, title: "Compile (F5)", children: compiling ? '⏳' : '▶️' })] })] }));
442
442
  }
443
443
  function PreviewPanel({ shader, mode, compiling, onModeChange }) {
444
- const canvasRef = we.useRef(null);
444
+ const canvasRef = ke.useRef(null);
445
445
  const previewModes = ['sphere', 'cube', 'plane', 'cylinder', 'torus'];
446
446
  // Simple preview rendering (in real implementation would use Three.js)
447
- we.useEffect(() => {
447
+ ke.useEffect(() => {
448
448
  const canvas = canvasRef.current;
449
449
  if (!canvas)
450
450
  return;
@@ -475,25 +475,25 @@ function PreviewPanel({ shader, mode, compiling, onModeChange }) {
475
475
  ═══════════════════════════════════════════════════════════════════════════ */
476
476
  function NiceMaterialEditor({ graph: initialGraph, onGraphChange, onCompile, customNodes, textures, width = '100%', height = '600px', readOnly = false, showToolbar = true, showPalette = true, showProperties = true, showPreview = true, previewMode: initialPreviewMode = 'sphere', theme = 'dark', className, }) {
477
477
  const { state, dispatch } = useMaterialEditor(initialGraph);
478
- const canvasRef = we.useRef(null);
479
- const [pendingConnection, setPendingConnection] = we.useState(null);
478
+ const canvasRef = ke.useRef(null);
479
+ const [pendingConnection, setPendingConnection] = ke.useState(null);
480
480
  // Merge custom node definitions
481
- const definitions = we.useMemo(() => {
481
+ const definitions = ke.useMemo(() => {
482
482
  const map = new Map(materialNodeDefinitions.MATERIAL_NODE_MAP);
483
483
  customNodes === null || customNodes === void 0 ? void 0 : customNodes.forEach(def => map.set(def.type, def));
484
484
  return map;
485
485
  }, [customNodes]);
486
486
  // Notify parent of changes
487
- we.useEffect(() => {
487
+ ke.useEffect(() => {
488
488
  onGraphChange === null || onGraphChange === void 0 ? void 0 : onGraphChange(state.graph);
489
489
  }, [state.graph, onGraphChange]);
490
- we.useEffect(() => {
490
+ ke.useEffect(() => {
491
491
  if (state.compiledShader) {
492
492
  onCompile === null || onCompile === void 0 ? void 0 : onCompile(state.compiledShader);
493
493
  }
494
494
  }, [state.compiledShader, onCompile]);
495
495
  // Keyboard shortcuts
496
- we.useEffect(() => {
496
+ ke.useEffect(() => {
497
497
  const handleKeyDown = (e) => {
498
498
  if (readOnly)
499
499
  return;
@@ -553,7 +553,7 @@ function NiceMaterialEditor({ graph: initialGraph, onGraphChange, onCompile, cus
553
553
  return () => window.removeEventListener('keydown', handleKeyDown);
554
554
  }, [readOnly, state.selectedNodes, dispatch]);
555
555
  // Handle wheel zoom
556
- const handleWheel = we.useCallback((e) => {
556
+ const handleWheel = ke.useCallback((e) => {
557
557
  var _a;
558
558
  e.preventDefault();
559
559
  const delta = e.deltaY > 0 ? 0.9 : 1.1;
@@ -571,8 +571,8 @@ function NiceMaterialEditor({ graph: initialGraph, onGraphChange, onCompile, cus
571
571
  });
572
572
  }, [state.viewTransform, dispatch]);
573
573
  // Handle canvas pan
574
- const [isPanning, setIsPanning] = we.useState(false);
575
- const panStart = we.useRef(null);
574
+ const [isPanning, setIsPanning] = ke.useState(false);
575
+ const panStart = ke.useRef(null);
576
576
  const handleCanvasMouseDown = (e) => {
577
577
  if (e.button === 1 || (e.button === 0 && e.altKey)) {
578
578
  setIsPanning(true);
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
- var we = require('react');
4
+ var ke = require('react');
5
5
  var ModelEditor_module = require('./ModelEditor.module.css.js');
6
- var NiceButtonDmTHNHet = require('../ui/dist/NiceButton-DmTHNHet.js');
6
+ var NiceButtonD9l39Rs7 = require('../ui/dist/NiceButton-D9l39Rs7.js');
7
7
 
8
- const ModelEditorLeftPanel = we.memo(({ api }) => {
8
+ const ModelEditorLeftPanel = ke.memo(({ api }) => {
9
9
  const { sceneTree, selectedId, outlinerSearch, setOutlinerSearch, selectObject, rebuildTree, toggleNodeExpanded, toggleNodeVisibility, } = api;
10
10
  const renderTreeNode = (node, depth) => {
11
11
  // Outliner search filter
@@ -24,7 +24,7 @@ const ModelEditorLeftPanel = we.memo(({ api }) => {
24
24
  node.type === "light" ? "💡" :
25
25
  node.type === "camera" ? "📷" :
26
26
  node.type === "helper" ? "◇" : "📁";
27
- return (jsxRuntime.jsxs(we.Fragment, { children: [jsxRuntime.jsxs("div", { className: `${ModelEditor_module.treeItem} ${selectedId === node.id ? ModelEditor_module.treeItemActive : ""}`, style: { paddingLeft: depth * 16 + 4 }, onClick: () => selectObject(node), children: [hasChildren ? (jsxRuntime.jsx("span", { className: ModelEditor_module.treeToggle, onClick: (e) => {
27
+ return (jsxRuntime.jsxs(ke.Fragment, { children: [jsxRuntime.jsxs("div", { className: `${ModelEditor_module.treeItem} ${selectedId === node.id ? ModelEditor_module.treeItemActive : ""}`, style: { paddingLeft: depth * 16 + 4 }, onClick: () => selectObject(node), children: [hasChildren ? (jsxRuntime.jsx("span", { className: ModelEditor_module.treeToggle, onClick: (e) => {
28
28
  e.stopPropagation();
29
29
  toggleNodeExpanded(node);
30
30
  }, children: node.expanded ? "▼" : "▶" })) : (jsxRuntime.jsx("span", { className: ModelEditor_module.treeToggle })), jsxRuntime.jsx("span", { className: ModelEditor_module.treeIcon, children: icon }), jsxRuntime.jsx("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis" }, children: node.name }), jsxRuntime.jsx("span", { className: ModelEditor_module.treeVisibility, onClick: (e) => {
@@ -33,7 +33,7 @@ const ModelEditorLeftPanel = we.memo(({ api }) => {
33
33
  }, children: node.visible ? "👁" : "◌" })] }), node.expanded &&
34
34
  node.children.map((c) => renderTreeNode(c, depth + 1))] }, node.id));
35
35
  };
36
- return (jsxRuntime.jsx("div", { className: ModelEditor_module.leftPanel, children: jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.panelTitle, children: ["\uD83D\uDCCB Outliner", jsxRuntime.jsx(NiceButtonDmTHNHet.c, { variant: "ghost", size: "sm", onClick: rebuildTree, title: "Refresh", "aria-label": "Refresh outliner", children: "\u27F3" })] }), jsxRuntime.jsx("div", { className: ModelEditor_module.outlinerSearch, children: jsxRuntime.jsx(NiceButtonDmTHNHet.b, { className: ModelEditor_module.propInput, placeholder: "\uD83D\uDD0D Filter...", value: outlinerSearch, onChange: (val) => setOutlinerSearch(val), style: { width: "100%", marginBottom: 4 } }) }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelContent, style: { overflowY: "auto", flex: 1 }, children: [sceneTree.length === 0 && (jsxRuntime.jsx("div", { style: { color: "#666", fontSize: 10, padding: "8px 0" }, children: "Drop a 3D file to begin" })), sceneTree.map((n) => renderTreeNode(n, 0))] })] }) }));
36
+ return (jsxRuntime.jsx("div", { className: ModelEditor_module.leftPanel, children: jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.panelTitle, children: ["\uD83D\uDCCB Outliner", jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { variant: "ghost", size: "sm", onClick: rebuildTree, title: "Refresh", "aria-label": "Refresh outliner", children: "\u27F3" })] }), jsxRuntime.jsx("div", { className: ModelEditor_module.outlinerSearch, children: jsxRuntime.jsx(NiceButtonD9l39Rs7.b, { className: ModelEditor_module.propInput, placeholder: "\uD83D\uDD0D Filter...", value: outlinerSearch, onChange: (val) => setOutlinerSearch(val), style: { width: "100%", marginBottom: 4 } }) }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelContent, style: { overflowY: "auto", flex: 1 }, children: [sceneTree.length === 0 && (jsxRuntime.jsx("div", { style: { color: "#666", fontSize: 10, padding: "8px 0" }, children: "Drop a 3D file to begin" })), sceneTree.map((n) => renderTreeNode(n, 0))] })] }) }));
37
37
  });
38
38
  ModelEditorLeftPanel.displayName = "ModelEditorLeftPanel";
39
39
 
@@ -1,18 +1,18 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
- var we = require('react');
4
+ var ke = require('react');
5
5
  var ModelEditor_module = require('./ModelEditor.module.css.js');
6
- var NiceButtonDmTHNHet = require('../ui/dist/NiceButton-DmTHNHet.js');
7
- var NiceToggleC1UKGXmJ = require('../ui/dist/NiceToggle-C1UKGXmJ.js');
6
+ var NiceButtonD9l39Rs7 = require('../ui/dist/NiceButton-D9l39Rs7.js');
7
+ var NiceToggleCaY1u82g = require('../ui/dist/NiceToggle-CaY1u82g.js');
8
8
 
9
- const ModelEditorMenuBar = we.memo(({ api, hasOnSaveToLibrary }) => {
9
+ const ModelEditorMenuBar = ke.memo(({ api, hasOnSaveToLibrary }) => {
10
10
  const { editorMode, setEditorMode, fileInputRef, mergeInputRef, addMenuOpen, setAddMenuOpen, addPrimitive, addSceneLight, addCameraObject, addEmpty, selectedNode, duplicateSelected, deleteSelected, exportGLTF, exportOBJ, exportSTL, exportPLY, exportUSDZ, saveToLibrary, clearScene, showGrid, setShowGrid, showAxes, setShowAxes, wireframe, setWireframe, showSkeleton, setShowSkeleton, showLightHelpers, setShowLightHelpers, bgColor, setBgColor, } = api;
11
- return (jsxRuntime.jsxs("div", { className: ModelEditor_module.menuBar, children: [jsxRuntime.jsx(NiceButtonDmTHNHet.a, { className: ModelEditor_module.modeSelect, value: editorMode, onChange: (val) => setEditorMode(val), options: [
11
+ return (jsxRuntime.jsxs("div", { className: ModelEditor_module.menuBar, children: [jsxRuntime.jsx(NiceButtonD9l39Rs7.a, { className: ModelEditor_module.modeSelect, value: editorMode, onChange: (val) => setEditorMode(val), options: [
12
12
  { value: "object", label: "Object Mode" },
13
13
  { value: "edit", label: "Edit Mode" },
14
14
  { value: "pose", label: "Pose Mode" },
15
- ] }), jsxRuntime.jsx("div", { className: ModelEditor_module.menuSep }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, children: "\uD83D\uDCC2 Open" }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: () => { var _a; return (_a = mergeInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, title: "Merge animations from FBX/GLTF onto current model", children: "\u2795 Merge Anim" }), jsxRuntime.jsx("div", { className: ModelEditor_module.menuSep }), jsxRuntime.jsxs("div", { className: ModelEditor_module.menuDropdownWrap, children: [jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: () => setAddMenuOpen(addMenuOpen ? null : "mesh"), children: "\uFF0B Add \u25BE" }), addMenuOpen && (jsxRuntime.jsxs("div", { className: ModelEditor_module.dropdownMenu, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownTitle, children: "Mesh" }), ["cube", "sphere", "cylinder", "cone", "torus", "plane", "circle", "ring", "dodecahedron", "icosahedron", "octahedron", "tetrahedron", "torusKnot"].map((t) => (jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownItem, onClick: () => addPrimitive(t), children: t.charAt(0).toUpperCase() + t.slice(1) }, t))), jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownSep }), jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownTitle, children: "Light" }), ["point", "spot", "directional", "hemisphere"].map((t) => (jsxRuntime.jsxs("div", { className: ModelEditor_module.dropdownItem, onClick: () => addSceneLight(t), children: ["\uD83D\uDCA1 ", t.charAt(0).toUpperCase() + t.slice(1)] }, t))), jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownSep }), jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownTitle, children: "Other" }), jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownItem, onClick: addCameraObject, children: "\uD83D\uDCF7 Camera" }), jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownItem, onClick: () => addEmpty("arrows"), children: "\u22B9 Empty (Arrows)" })] }))] }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: duplicateSelected, disabled: !selectedNode, title: "Duplicate selected (Shift+D)", children: "\uD83D\uDCCB Duplicate" }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: deleteSelected, disabled: !selectedNode, title: "Delete selected (Delete)", children: "\u2715 Delete" }), jsxRuntime.jsx("div", { className: ModelEditor_module.menuSep }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: () => exportGLTF(true), children: "\uD83D\uDCBE Export GLB" }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: () => exportGLTF(false), children: "\uD83D\uDCC4 Export GLTF" }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: exportOBJ, children: "\uD83D\uDCC4 Export OBJ" }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: () => exportSTL(true), children: "\uD83D\uDCC4 Export STL" }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: () => exportPLY(true), children: "\uD83D\uDCC4 Export PLY" }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: exportUSDZ, children: "\uD83D\uDCC4 Export USDZ" }), hasOnSaveToLibrary && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: ModelEditor_module.menuSep }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: saveToLibrary, children: "\uD83D\uDCE6 Save to Library" })] })), jsxRuntime.jsx("div", { className: ModelEditor_module.menuSep }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: clearScene, children: "\uD83D\uDDD1 Clear" }), jsxRuntime.jsx("div", { className: ModelEditor_module.menuSep }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.N, { checked: showGrid, onChange: () => setShowGrid((v) => !v), label: "Grid" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.N, { checked: showAxes, onChange: () => setShowAxes((v) => !v), label: "Axes" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.N, { checked: wireframe, onChange: () => setWireframe((v) => !v), label: "Wire" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.N, { checked: showSkeleton, onChange: () => setShowSkeleton((v) => !v), label: "Skel" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.N, { checked: showLightHelpers, onChange: () => setShowLightHelpers((v) => !v), label: "Helpers" }), jsxRuntime.jsxs("div", { className: ModelEditor_module.menuRight, children: [jsxRuntime.jsx("label", { className: ModelEditor_module.menuLabel, children: "BG" }), jsxRuntime.jsx(NiceButtonDmTHNHet.N, { value: bgColor, onChange: (c) => setBgColor(c) })] })] }));
15
+ ] }), jsxRuntime.jsx("div", { className: ModelEditor_module.menuSep }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, children: "\uD83D\uDCC2 Open" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: () => { var _a; return (_a = mergeInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, title: "Merge animations from FBX/GLTF onto current model", children: "\u2795 Merge Anim" }), jsxRuntime.jsx("div", { className: ModelEditor_module.menuSep }), jsxRuntime.jsxs("div", { className: ModelEditor_module.menuDropdownWrap, children: [jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: () => setAddMenuOpen(addMenuOpen ? null : "mesh"), children: "\uFF0B Add \u25BE" }), addMenuOpen && (jsxRuntime.jsxs("div", { className: ModelEditor_module.dropdownMenu, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownTitle, children: "Mesh" }), ["cube", "sphere", "cylinder", "cone", "torus", "plane", "circle", "ring", "dodecahedron", "icosahedron", "octahedron", "tetrahedron", "torusKnot"].map((t) => (jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownItem, onClick: () => addPrimitive(t), children: t.charAt(0).toUpperCase() + t.slice(1) }, t))), jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownSep }), jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownTitle, children: "Light" }), ["point", "spot", "directional", "hemisphere"].map((t) => (jsxRuntime.jsxs("div", { className: ModelEditor_module.dropdownItem, onClick: () => addSceneLight(t), children: ["\uD83D\uDCA1 ", t.charAt(0).toUpperCase() + t.slice(1)] }, t))), jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownSep }), jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownTitle, children: "Other" }), jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownItem, onClick: addCameraObject, children: "\uD83D\uDCF7 Camera" }), jsxRuntime.jsx("div", { className: ModelEditor_module.dropdownItem, onClick: () => addEmpty("arrows"), children: "\u22B9 Empty (Arrows)" })] }))] }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: duplicateSelected, disabled: !selectedNode, title: "Duplicate selected (Shift+D)", children: "\uD83D\uDCCB Duplicate" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: deleteSelected, disabled: !selectedNode, title: "Delete selected (Delete)", children: "\u2715 Delete" }), jsxRuntime.jsx("div", { className: ModelEditor_module.menuSep }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: () => exportGLTF(true), children: "\uD83D\uDCBE Export GLB" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: () => exportGLTF(false), children: "\uD83D\uDCC4 Export GLTF" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: exportOBJ, children: "\uD83D\uDCC4 Export OBJ" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: () => exportSTL(true), children: "\uD83D\uDCC4 Export STL" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: () => exportPLY(true), children: "\uD83D\uDCC4 Export PLY" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: exportUSDZ, children: "\uD83D\uDCC4 Export USDZ" }), hasOnSaveToLibrary && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: ModelEditor_module.menuSep }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: saveToLibrary, children: "\uD83D\uDCE6 Save to Library" })] })), jsxRuntime.jsx("div", { className: ModelEditor_module.menuSep }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.menuBtn, variant: "ghost", size: "sm", onClick: clearScene, children: "\uD83D\uDDD1 Clear" }), jsxRuntime.jsx("div", { className: ModelEditor_module.menuSep }), jsxRuntime.jsx(NiceToggleCaY1u82g.N, { checked: showGrid, onChange: () => setShowGrid((v) => !v), label: "Grid" }), jsxRuntime.jsx(NiceToggleCaY1u82g.N, { checked: showAxes, onChange: () => setShowAxes((v) => !v), label: "Axes" }), jsxRuntime.jsx(NiceToggleCaY1u82g.N, { checked: wireframe, onChange: () => setWireframe((v) => !v), label: "Wire" }), jsxRuntime.jsx(NiceToggleCaY1u82g.N, { checked: showSkeleton, onChange: () => setShowSkeleton((v) => !v), label: "Skel" }), jsxRuntime.jsx(NiceToggleCaY1u82g.N, { checked: showLightHelpers, onChange: () => setShowLightHelpers((v) => !v), label: "Helpers" }), jsxRuntime.jsxs("div", { className: ModelEditor_module.menuRight, children: [jsxRuntime.jsx("label", { className: ModelEditor_module.menuLabel, children: "BG" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.N, { value: bgColor, onChange: (c) => setBgColor(c) })] })] }));
16
16
  });
17
17
  ModelEditorMenuBar.displayName = "ModelEditorMenuBar";
18
18
 
@@ -1,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
- var we = require('react');
4
+ var ke = require('react');
5
5
  var THREE = require('three');
6
6
  var ModelEditor_module = require('./ModelEditor.module.css.js');
7
7
  var modelEditorTypes = require('./modelEditorTypes.js');
8
8
  var ModelEditorSubComponents = require('./ModelEditorSubComponents.js');
9
- var NiceButtonDmTHNHet = require('../ui/dist/NiceButton-DmTHNHet.js');
10
- var NicePinCodeInput4q8yULuo = require('../ui/dist/NicePinCodeInput-4q8yULuo.js');
11
- var NiceToggleC1UKGXmJ = require('../ui/dist/NiceToggle-C1UKGXmJ.js');
9
+ var NiceButtonD9l39Rs7 = require('../ui/dist/NiceButton-D9l39Rs7.js');
10
+ var NicePinCodeInputCrMfdxxc = require('../ui/dist/NicePinCodeInput-CrMfdxxc.js');
11
+ var NiceToggleCaY1u82g = require('../ui/dist/NiceToggle-CaY1u82g.js');
12
12
 
13
13
  function _interopNamespaceDefault(e) {
14
14
  var n = Object.create(null);
@@ -29,44 +29,44 @@ function _interopNamespaceDefault(e) {
29
29
 
30
30
  var THREE__namespace = /*#__PURE__*/_interopNamespaceDefault(THREE);
31
31
 
32
- const ModelEditorRightPanel = we.memo(({ api }) => {
32
+ const ModelEditorRightPanel = ke.memo(({ api }) => {
33
33
  const { propTab, setPropTab, selectedNode, selectedMaterials, selMaterialIdx, setSelMaterialIdx, setMatRefresh, rebuildTree, aiBusy, aiStatus, rootObjectRef, videoInputRef, bgColor, setBgColor, fogEnabled, setFogEnabled, fogColor, setFogColor, fogNear, setFogNear, fogFar, setFogFar, showLightHelpers, setShowLightHelpers, showGrid, setShowGrid, showAxes, setShowAxes, showSkeleton, setShowSkeleton, snapEnabled, setSnapEnabled, snapGrid, setSnapGrid, setStatusText, } = api;
34
- return (jsxRuntime.jsxs("div", { className: ModelEditor_module.rightPanel, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.propTabs, children: ["object", "material", "world", "modifiers", "physics"].map((t) => (jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.propTabBtn, variant: propTab === t ? "primary" : "ghost", size: "sm", onClick: () => setPropTab(t), title: t.charAt(0).toUpperCase() + t.slice(1), children: t === "object" ? "🔧" : t === "material" ? "🎨" : t === "world" ? "🌍" : t === "modifiers" ? "🔩" : "⚡" }, t))) }), propTab === "object" && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83D\uDD27 Transform" }), jsxRuntime.jsx("div", { className: ModelEditor_module.panelContent, children: selectedNode ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Name" }), jsxRuntime.jsx(NiceButtonDmTHNHet.b, { className: ModelEditor_module.propInput, value: selectedNode.name, onChange: (val) => {
34
+ return (jsxRuntime.jsxs("div", { className: ModelEditor_module.rightPanel, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.propTabs, children: ["object", "material", "world", "modifiers", "physics"].map((t) => (jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.propTabBtn, variant: propTab === t ? "primary" : "ghost", size: "sm", onClick: () => setPropTab(t), title: t.charAt(0).toUpperCase() + t.slice(1), children: t === "object" ? "🔧" : t === "material" ? "🎨" : t === "world" ? "🌍" : t === "modifiers" ? "🔩" : "⚡" }, t))) }), propTab === "object" && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83D\uDD27 Transform" }), jsxRuntime.jsx("div", { className: ModelEditor_module.panelContent, children: selectedNode ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Name" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.b, { className: ModelEditor_module.propInput, value: selectedNode.name, onChange: (val) => {
35
35
  selectedNode.object.name = val;
36
36
  rebuildTree();
37
- } })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Type" }), jsxRuntime.jsx("span", { style: { fontSize: 10, color: "#888" }, children: selectedNode.type })] }), jsxRuntime.jsx(ModelEditorSubComponents.Vec3Row, { label: "Position", value: selectedNode.object.position, onChange: () => setMatRefresh((n) => n + 1) }), jsxRuntime.jsx(ModelEditorSubComponents.Vec3RowDeg, { label: "Rotation", value: selectedNode.object.rotation, onChange: () => setMatRefresh((n) => n + 1) }), jsxRuntime.jsx(ModelEditorSubComponents.Vec3Row, { label: "Scale", value: selectedNode.object.scale, onChange: () => setMatRefresh((n) => n + 1) })] })) : (jsxRuntime.jsx("div", { style: { color: "#666", fontSize: 10 }, children: "Select an object" })) })] }), selectedNode && selectedNode.object instanceof THREE__namespace.Light && (jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83D\uDCA1 Light" }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelContent, children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Color" }), jsxRuntime.jsx(NiceButtonDmTHNHet.N, { value: `#${selectedNode.object.color.getHexString()}`, onChange: (c) => {
37
+ } })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Type" }), jsxRuntime.jsx("span", { style: { fontSize: 10, color: "#888" }, children: selectedNode.type })] }), jsxRuntime.jsx(ModelEditorSubComponents.Vec3Row, { label: "Position", value: selectedNode.object.position, onChange: () => setMatRefresh((n) => n + 1) }), jsxRuntime.jsx(ModelEditorSubComponents.Vec3RowDeg, { label: "Rotation", value: selectedNode.object.rotation, onChange: () => setMatRefresh((n) => n + 1) }), jsxRuntime.jsx(ModelEditorSubComponents.Vec3Row, { label: "Scale", value: selectedNode.object.scale, onChange: () => setMatRefresh((n) => n + 1) })] })) : (jsxRuntime.jsx("div", { style: { color: "#666", fontSize: 10 }, children: "Select an object" })) })] }), selectedNode && selectedNode.object instanceof THREE__namespace.Light && (jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83D\uDCA1 Light" }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelContent, children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Color" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.N, { value: `#${selectedNode.object.color.getHexString()}`, onChange: (c) => {
38
38
  selectedNode.object.color.set(c);
39
39
  setMatRefresh((n) => n + 1);
40
- } })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Intensity" }), jsxRuntime.jsx(NicePinCodeInput4q8yULuo.U, { min: 0, max: 10, step: 0.1, value: selectedNode.object.intensity, onChange: (val) => {
40
+ } })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Intensity" }), jsxRuntime.jsx(NicePinCodeInputCrMfdxxc.U, { min: 0, max: 10, step: 0.1, value: selectedNode.object.intensity, onChange: (val) => {
41
41
  selectedNode.object.intensity = val;
42
42
  setMatRefresh((n) => n + 1);
43
- }, style: { flex: 1 } }), jsxRuntime.jsx("span", { style: { fontSize: 9, color: "#888", width: 28, textAlign: "right" }, children: selectedNode.object.intensity.toFixed(1) })] }), "castShadow" in selectedNode.object && (jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Shadow" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.N, { checked: selectedNode.object.castShadow, onChange: (checked) => {
43
+ }, style: { flex: 1 } }), jsxRuntime.jsx("span", { style: { fontSize: 9, color: "#888", width: 28, textAlign: "right" }, children: selectedNode.object.intensity.toFixed(1) })] }), "castShadow" in selectedNode.object && (jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Shadow" }), jsxRuntime.jsx(NiceToggleCaY1u82g.N, { checked: selectedNode.object.castShadow, onChange: (checked) => {
44
44
  selectedNode.object.castShadow = checked;
45
45
  setMatRefresh((n) => n + 1);
46
- } })] })), selectedNode.object instanceof THREE__namespace.SpotLight && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Angle" }), jsxRuntime.jsx(NicePinCodeInput4q8yULuo.U, { min: 0, max: 90, step: 1, value: (selectedNode.object.angle * modelEditorTypes.DEG), onChange: (val) => {
46
+ } })] })), selectedNode.object instanceof THREE__namespace.SpotLight && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Angle" }), jsxRuntime.jsx(NicePinCodeInputCrMfdxxc.U, { min: 0, max: 90, step: 1, value: (selectedNode.object.angle * modelEditorTypes.DEG), onChange: (val) => {
47
47
  selectedNode.object.angle = val / modelEditorTypes.DEG;
48
48
  setMatRefresh((n) => n + 1);
49
- }, style: { flex: 1 } }), jsxRuntime.jsxs("span", { style: { fontSize: 9, color: "#888", width: 28, textAlign: "right" }, children: [(selectedNode.object.angle * modelEditorTypes.DEG).toFixed(0), "\u00B0"] })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Penumbra" }), jsxRuntime.jsx(NicePinCodeInput4q8yULuo.U, { min: 0, max: 1, step: 0.01, value: selectedNode.object.penumbra, onChange: (val) => {
49
+ }, style: { flex: 1 } }), jsxRuntime.jsxs("span", { style: { fontSize: 9, color: "#888", width: 28, textAlign: "right" }, children: [(selectedNode.object.angle * modelEditorTypes.DEG).toFixed(0), "\u00B0"] })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Penumbra" }), jsxRuntime.jsx(NicePinCodeInputCrMfdxxc.U, { min: 0, max: 1, step: 0.01, value: selectedNode.object.penumbra, onChange: (val) => {
50
50
  selectedNode.object.penumbra = val;
51
51
  setMatRefresh((n) => n + 1);
52
- }, style: { flex: 1 } })] })] }))] })] })), selectedNode && selectedNode.object instanceof THREE__namespace.PerspectiveCamera && (jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83D\uDCF7 Camera" }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelContent, children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "FOV" }), jsxRuntime.jsx(NicePinCodeInput4q8yULuo.U, { min: 10, max: 120, step: 1, value: selectedNode.object.fov, onChange: (val) => {
52
+ }, style: { flex: 1 } })] })] }))] })] })), selectedNode && selectedNode.object instanceof THREE__namespace.PerspectiveCamera && (jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83D\uDCF7 Camera" }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelContent, children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "FOV" }), jsxRuntime.jsx(NicePinCodeInputCrMfdxxc.U, { min: 10, max: 120, step: 1, value: selectedNode.object.fov, onChange: (val) => {
53
53
  const cam = selectedNode.object;
54
54
  cam.fov = val;
55
55
  cam.updateProjectionMatrix();
56
56
  setMatRefresh((n) => n + 1);
57
- }, style: { flex: 1 } }), jsxRuntime.jsxs("span", { style: { fontSize: 9, color: "#888", width: 28, textAlign: "right" }, children: [selectedNode.object.fov.toFixed(0), "\u00B0"] })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Near" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.a, { className: ModelEditor_module.propInput, step: 0.01, value: selectedNode.object.near, onChange: (val) => {
57
+ }, style: { flex: 1 } }), jsxRuntime.jsxs("span", { style: { fontSize: 9, color: "#888", width: 28, textAlign: "right" }, children: [selectedNode.object.fov.toFixed(0), "\u00B0"] })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Near" }), jsxRuntime.jsx(NiceToggleCaY1u82g.a, { className: ModelEditor_module.propInput, step: 0.01, value: selectedNode.object.near, onChange: (val) => {
58
58
  const cam = selectedNode.object;
59
59
  cam.near = val !== null && val !== void 0 ? val : 0.1;
60
60
  cam.updateProjectionMatrix();
61
61
  setMatRefresh((n) => n + 1);
62
- }, style: { width: 60 } })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Far" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.a, { className: ModelEditor_module.propInput, step: 1, value: selectedNode.object.far, onChange: (val) => {
62
+ }, style: { width: 60 } })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Far" }), jsxRuntime.jsx(NiceToggleCaY1u82g.a, { className: ModelEditor_module.propInput, step: 1, value: selectedNode.object.far, onChange: (val) => {
63
63
  const cam = selectedNode.object;
64
64
  cam.far = val !== null && val !== void 0 ? val : 1000;
65
65
  cam.updateProjectionMatrix();
66
66
  setMatRefresh((n) => n + 1);
67
- }, style: { width: 80 } })] })] })] })), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83E\uDD16 AI Animation" }), jsxRuntime.jsx("div", { className: ModelEditor_module.panelContent, children: jsxRuntime.jsxs("div", { className: ModelEditor_module.aiPanel, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.aiHeader, children: "\u2728 Generate animation from video" }), jsxRuntime.jsx("p", { style: { fontSize: 10, color: "#888", margin: "0 0 6px" }, children: "Upload a video and AI will extract 3D pose data to create an animation clip for the current model." }), jsxRuntime.jsx("div", { className: ModelEditor_module.aiBtnRow, children: jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.aiBtn, variant: "ghost", size: "sm", disabled: aiBusy || !rootObjectRef.current, onClick: () => { var _a; return (_a = videoInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, children: aiBusy ? "Processing..." : "Upload Video" }) }), aiStatus && (jsxRuntime.jsx("div", { className: ModelEditor_module.aiStatus, children: aiStatus }))] }) })] })] })), propTab === "material" && (jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83C\uDFA8 Materials" }), jsxRuntime.jsx("div", { className: ModelEditor_module.panelContent, children: selectedMaterials.length > 0 ? (selectedMaterials.map((mat, i) => (jsxRuntime.jsx(ModelEditorSubComponents.MaterialCard, { material: mat, active: i === selMaterialIdx, onClick: () => setSelMaterialIdx(i), onUpdate: () => setMatRefresh((n) => n + 1) }, i)))) : (jsxRuntime.jsx("div", { style: { color: "#666", fontSize: 10 }, children: selectedNode
67
+ }, style: { width: 80 } })] })] })] })), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83E\uDD16 AI Animation" }), jsxRuntime.jsx("div", { className: ModelEditor_module.panelContent, children: jsxRuntime.jsxs("div", { className: ModelEditor_module.aiPanel, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.aiHeader, children: "\u2728 Generate animation from video" }), jsxRuntime.jsx("p", { style: { fontSize: 10, color: "#888", margin: "0 0 6px" }, children: "Upload a video and AI will extract 3D pose data to create an animation clip for the current model." }), jsxRuntime.jsx("div", { className: ModelEditor_module.aiBtnRow, children: jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.aiBtn, variant: "ghost", size: "sm", disabled: aiBusy || !rootObjectRef.current, onClick: () => { var _a; return (_a = videoInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, children: aiBusy ? "Processing..." : "Upload Video" }) }), aiStatus && (jsxRuntime.jsx("div", { className: ModelEditor_module.aiStatus, children: aiStatus }))] }) })] })] })), propTab === "material" && (jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83C\uDFA8 Materials" }), jsxRuntime.jsx("div", { className: ModelEditor_module.panelContent, children: selectedMaterials.length > 0 ? (selectedMaterials.map((mat, i) => (jsxRuntime.jsx(ModelEditorSubComponents.MaterialCard, { material: mat, active: i === selMaterialIdx, onClick: () => setSelMaterialIdx(i), onUpdate: () => setMatRefresh((n) => n + 1) }, i)))) : (jsxRuntime.jsx("div", { style: { color: "#666", fontSize: 10 }, children: selectedNode
68
68
  ? "No materials on this object"
69
- : "Select a mesh to inspect" })) })] })), propTab === "world" && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83C\uDF0D Environment" }), jsxRuntime.jsx("div", { className: ModelEditor_module.panelContent, children: jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Background" }), jsxRuntime.jsx(NiceButtonDmTHNHet.N, { value: bgColor, onChange: (c) => setBgColor(c) }), jsxRuntime.jsx("span", { style: { fontSize: 9, color: "#888" }, children: bgColor })] }) })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83C\uDF2B Fog" }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelContent, children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Enable" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.N, { checked: fogEnabled, onChange: () => setFogEnabled((v) => !v) })] }), fogEnabled && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Color" }), jsxRuntime.jsx(NiceButtonDmTHNHet.N, { value: fogColor, onChange: (c) => setFogColor(c) })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Near" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.a, { className: ModelEditor_module.propInput, value: fogNear, onChange: (val) => setFogNear(val !== null && val !== void 0 ? val : 1), style: { width: 60 } })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Far" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.a, { className: ModelEditor_module.propInput, value: fogFar, onChange: (val) => setFogFar(val !== null && val !== void 0 ? val : 100), style: { width: 60 } })] })] }))] })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83D\uDD06 Scene Lights" }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelContent, children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Show Helpers" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.N, { checked: showLightHelpers, onChange: () => setShowLightHelpers((v) => !v) })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Grid" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.N, { checked: showGrid, onChange: () => setShowGrid((v) => !v) })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Axes" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.N, { checked: showAxes, onChange: () => setShowAxes((v) => !v) })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Skeleton" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.N, { checked: showSkeleton, onChange: () => setShowSkeleton((v) => !v) })] })] })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83E\uDDF2 Snapping" }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelContent, children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Snap" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.N, { checked: snapEnabled, onChange: () => setSnapEnabled((v) => !v) })] }), snapEnabled && (jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Grid Size" }), jsxRuntime.jsx(NiceToggleC1UKGXmJ.a, { className: ModelEditor_module.propInput, step: 0.25, min: 0.1, value: snapGrid, onChange: (val) => setSnapGrid(val !== null && val !== void 0 ? val : 1), style: { width: 60 } })] }))] })] })] })), propTab === "modifiers" && (jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83D\uDD29 Modifiers" }), jsxRuntime.jsx("div", { className: ModelEditor_module.panelContent, children: selectedNode && selectedNode.object instanceof THREE__namespace.Mesh ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.btnSecondary, variant: "ghost", size: "sm", style: { width: "100%", marginBottom: 4 }, onClick: () => {
69
+ : "Select a mesh to inspect" })) })] })), propTab === "world" && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83C\uDF0D Environment" }), jsxRuntime.jsx("div", { className: ModelEditor_module.panelContent, children: jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Background" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.N, { value: bgColor, onChange: (c) => setBgColor(c) }), jsxRuntime.jsx("span", { style: { fontSize: 9, color: "#888" }, children: bgColor })] }) })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83C\uDF2B Fog" }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelContent, children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Enable" }), jsxRuntime.jsx(NiceToggleCaY1u82g.N, { checked: fogEnabled, onChange: () => setFogEnabled((v) => !v) })] }), fogEnabled && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Color" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.N, { value: fogColor, onChange: (c) => setFogColor(c) })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Near" }), jsxRuntime.jsx(NiceToggleCaY1u82g.a, { className: ModelEditor_module.propInput, value: fogNear, onChange: (val) => setFogNear(val !== null && val !== void 0 ? val : 1), style: { width: 60 } })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Far" }), jsxRuntime.jsx(NiceToggleCaY1u82g.a, { className: ModelEditor_module.propInput, value: fogFar, onChange: (val) => setFogFar(val !== null && val !== void 0 ? val : 100), style: { width: 60 } })] })] }))] })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83D\uDD06 Scene Lights" }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelContent, children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Show Helpers" }), jsxRuntime.jsx(NiceToggleCaY1u82g.N, { checked: showLightHelpers, onChange: () => setShowLightHelpers((v) => !v) })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Grid" }), jsxRuntime.jsx(NiceToggleCaY1u82g.N, { checked: showGrid, onChange: () => setShowGrid((v) => !v) })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Axes" }), jsxRuntime.jsx(NiceToggleCaY1u82g.N, { checked: showAxes, onChange: () => setShowAxes((v) => !v) })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Skeleton" }), jsxRuntime.jsx(NiceToggleCaY1u82g.N, { checked: showSkeleton, onChange: () => setShowSkeleton((v) => !v) })] })] })] }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83E\uDDF2 Snapping" }), jsxRuntime.jsxs("div", { className: ModelEditor_module.panelContent, children: [jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Snap" }), jsxRuntime.jsx(NiceToggleCaY1u82g.N, { checked: snapEnabled, onChange: () => setSnapEnabled((v) => !v) })] }), snapEnabled && (jsxRuntime.jsxs("div", { className: ModelEditor_module.propRow, children: [jsxRuntime.jsx("span", { className: ModelEditor_module.propLabel, children: "Grid Size" }), jsxRuntime.jsx(NiceToggleCaY1u82g.a, { className: ModelEditor_module.propInput, step: 0.25, min: 0.1, value: snapGrid, onChange: (val) => setSnapGrid(val !== null && val !== void 0 ? val : 1), style: { width: 60 } })] }))] })] })] })), propTab === "modifiers" && (jsxRuntime.jsxs("div", { className: ModelEditor_module.panelSection, children: [jsxRuntime.jsx("div", { className: ModelEditor_module.panelTitle, children: "\uD83D\uDD29 Modifiers" }), jsxRuntime.jsx("div", { className: ModelEditor_module.panelContent, children: selectedNode && selectedNode.object instanceof THREE__namespace.Mesh ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.btnSecondary, variant: "ghost", size: "sm", style: { width: "100%", marginBottom: 4 }, onClick: () => {
70
70
  const mesh = selectedNode.object;
71
71
  const geo = mesh.geometry;
72
72
  const pos = geo.attributes.position;
@@ -76,17 +76,17 @@ const ModelEditorRightPanel = we.memo(({ api }) => {
76
76
  setStatusText("Applied Wireframe modifier");
77
77
  rebuildTree();
78
78
  }
79
- }, children: "+ Wireframe Modifier" }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.btnSecondary, variant: "ghost", size: "sm", style: { width: "100%", marginBottom: 4 }, onClick: () => {
79
+ }, children: "+ Wireframe Modifier" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.btnSecondary, variant: "ghost", size: "sm", style: { width: "100%", marginBottom: 4 }, onClick: () => {
80
80
  const mesh = selectedNode.object;
81
81
  mesh.geometry.computeVertexNormals();
82
82
  setStatusText("Recomputed normals");
83
- }, children: "Recompute Normals" }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.btnSecondary, variant: "ghost", size: "sm", style: { width: "100%", marginBottom: 4 }, onClick: () => {
83
+ }, children: "Recompute Normals" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.btnSecondary, variant: "ghost", size: "sm", style: { width: "100%", marginBottom: 4 }, onClick: () => {
84
84
  const mesh = selectedNode.object;
85
85
  const geo = mesh.geometry;
86
86
  geo.center();
87
87
  setStatusText("Centered geometry");
88
88
  setMatRefresh((n) => n + 1);
89
- }, children: "Center Geometry" }), jsxRuntime.jsx(NiceButtonDmTHNHet.c, { className: ModelEditor_module.btnSecondary, variant: "ghost", size: "sm", style: { width: "100%", marginBottom: 4 }, onClick: () => {
89
+ }, children: "Center Geometry" }), jsxRuntime.jsx(NiceButtonD9l39Rs7.c, { className: ModelEditor_module.btnSecondary, variant: "ghost", size: "sm", style: { width: "100%", marginBottom: 4 }, onClick: () => {
90
90
  const mesh = selectedNode.object;
91
91
  const geo = mesh.geometry;
92
92
  const idx = geo.index;