@babylonjs/inspector 8.54.1 → 8.54.3

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.
@@ -37,7 +37,7 @@ import { PerformanceViewerCollector } from '@babylonjs/core/Misc/PerformanceView
37
37
  import { AbstractEngine } from '@babylonjs/core/Engines/abstractEngine.js';
38
38
  import { Bone } from '@babylonjs/core/Bones/bone.js';
39
39
  import { Camera } from '@babylonjs/core/Cameras/camera.js';
40
- import { FrameGraphUtils, FindMainObjectRenderer, FindMainCamera } from '@babylonjs/core/FrameGraph/frameGraphUtils.js';
40
+ import { FrameGraphUtils, FindMainCamera } from '@babylonjs/core/FrameGraph/frameGraphUtils.js';
41
41
  import { CameraGizmo } from '@babylonjs/core/Gizmos/cameraGizmo.js';
42
42
  import { GizmoManager } from '@babylonjs/core/Gizmos/gizmoManager.js';
43
43
  import { LightGizmo } from '@babylonjs/core/Gizmos/lightGizmo.js';
@@ -143,7 +143,8 @@ import { SceneSerializer } from '@babylonjs/core/Misc/sceneSerializer.js';
143
143
  import { EnvironmentTextureTools } from '@babylonjs/core/Misc/environmentTextureTools.js';
144
144
  import { ImportAnimationsAsync, SceneLoader } from '@babylonjs/core/Loading/sceneLoader.js';
145
145
  import { FilesInput } from '@babylonjs/core/Misc/filesInput.js';
146
- import { GLTFLoaderAnimationStartMode, GLTFLoaderCoordinateSystemMode, GLTFLoaderDefaultOptions } from '@babylonjs/loaders/glTF/glTFFileLoader.js';
146
+ import { registeredGLTFExtensions } from '@babylonjs/loaders/glTF/2.0/glTFLoaderExtensionRegistry.js';
147
+ import { GLTFLoaderDefaultOptions, GLTFLoaderAnimationStartMode, GLTFLoaderCoordinateSystemMode } from '@babylonjs/loaders/glTF/glTFFileLoader.js';
147
148
  import { GLTFValidation } from '@babylonjs/loaders/glTF/glTFValidation.js';
148
149
  import { EngineStore } from '@babylonjs/core/Engines/engineStore.js';
149
150
  import { DebugLayer } from '@babylonjs/core/Debug/debugLayer.js';
@@ -168,7 +169,7 @@ const TokenMap = {
168
169
  px40: tokens.lineHeightHero800,
169
170
  };
170
171
  const CustomTokens = {
171
- inputWidth: "150px",
172
+ valueWidth: "150px",
172
173
  lineHeight: TokenMap.px36,
173
174
  lineHeightSmall: TokenMap.px28,
174
175
  dividerGap: TokenMap.px10,
@@ -176,9 +177,8 @@ const CustomTokens = {
176
177
  labelMinWidth: "50px",
177
178
  rightAlignOffset: `-${TokenMap.px8}`,
178
179
  };
179
- const UniformWidthStyling = { width: CustomTokens.inputWidth, boxSizing: "border-box" };
180
+ const UniformWidthStyling = { width: CustomTokens.valueWidth, boxSizing: "border-box" };
180
181
  const useInputStyles$1 = makeStyles({
181
- input: UniformWidthStyling,
182
182
  inputSlot: { textAlign: "right" },
183
183
  invalid: { backgroundColor: tokens.colorPaletteRedBackground2 },
184
184
  container: {
@@ -187,6 +187,10 @@ const useInputStyles$1 = makeStyles({
187
187
  justifyContent: "center", // align items vertically
188
188
  minWidth: 0, // Allow shrinking
189
189
  },
190
+ inputFill: {
191
+ width: "100%",
192
+ minWidth: 0,
193
+ },
190
194
  });
191
195
  function HandleOnBlur(event) {
192
196
  event.stopPropagation();
@@ -276,7 +280,7 @@ const Button = forwardRef((props, ref) => {
276
280
  });
277
281
  Button.displayName = "Button";
278
282
 
279
- const useStyles$V = makeStyles({
283
+ const useStyles$Y = makeStyles({
280
284
  root: {
281
285
  display: "flex",
282
286
  flexDirection: "column",
@@ -357,7 +361,7 @@ class ErrorBoundary extends Component {
357
361
  }
358
362
  }
359
363
  function ErrorFallback({ error, onRetry }) {
360
- const styles = useStyles$V();
364
+ const styles = useStyles$Y();
361
365
  return (jsxs("div", { className: styles.root, children: [jsx(ErrorCircleRegular, { className: styles.icon }), jsx("div", { className: styles.title, children: "Something went wrong" }), jsx("div", { className: styles.message, children: "An error occurred in this component. You can try again or continue using other parts of the tool." }), jsx(Button, { label: "Try Again", appearance: "primary", onClick: onRetry }), error && jsx("div", { className: styles.details, children: error.message })] }));
362
366
  }
363
367
 
@@ -1361,7 +1365,7 @@ function useIsSectionEmpty(sectionId) {
1361
1365
  return hasItems;
1362
1366
  }
1363
1367
 
1364
- const useStyles$U = makeStyles({
1368
+ const useStyles$X = makeStyles({
1365
1369
  accordion: {
1366
1370
  display: "flex",
1367
1371
  flexDirection: "column",
@@ -1442,6 +1446,9 @@ const useStyles$U = makeStyles({
1442
1446
  width: "100%",
1443
1447
  maxWidth: "none",
1444
1448
  },
1449
+ sectionBlockEmpty: {
1450
+ display: "none",
1451
+ },
1445
1452
  });
1446
1453
  /**
1447
1454
  * Renders the menu bar and control buttons.
@@ -1450,7 +1457,7 @@ const useStyles$U = makeStyles({
1450
1457
  */
1451
1458
  const AccordionMenuBar = () => {
1452
1459
  AccordionMenuBar.displayName = "AccordionMenuBar";
1453
- const classes = useStyles$U();
1460
+ const classes = useStyles$X();
1454
1461
  const accordionCtx = useContext(AccordionContext);
1455
1462
  if (!accordionCtx) {
1456
1463
  return null;
@@ -1474,10 +1481,11 @@ const AccordionMenuBar = () => {
1474
1481
  const AccordionSectionBlock = (props) => {
1475
1482
  AccordionSectionBlock.displayName = "AccordionSectionBlock";
1476
1483
  const { children, sectionId } = props;
1484
+ const classes = useStyles$X();
1477
1485
  const accordionCtx = useContext(AccordionContext);
1478
1486
  const { context: sectionContext, isEmpty } = useAccordionSectionBlockContext(props);
1479
1487
  if (accordionCtx) {
1480
- return (jsx(AccordionSectionBlockContext.Provider, { value: sectionContext, children: !isEmpty && jsx(AccordionItem, { value: sectionId, children: children }) }));
1488
+ return (jsx(AccordionSectionBlockContext.Provider, { value: sectionContext, children: jsx(AccordionItem, { value: sectionId, className: isEmpty ? classes.sectionBlockEmpty : undefined, children: children }) }));
1481
1489
  }
1482
1490
  return jsx(AccordionItem, { value: sectionId, children: children });
1483
1491
  };
@@ -1493,7 +1501,7 @@ const AccordionSectionBlock = (props) => {
1493
1501
  const AccordionSectionItem = (props) => {
1494
1502
  AccordionSectionItem.displayName = "AccordionSectionItem";
1495
1503
  const { children, staticItem } = props;
1496
- const classes = useStyles$U();
1504
+ const classes = useStyles$X();
1497
1505
  const accordionCtx = useContext(AccordionContext);
1498
1506
  const itemState = useAccordionSectionItemState(props);
1499
1507
  const [ctrlMode, setCtrlMode] = useState(false);
@@ -1533,7 +1541,7 @@ const AccordionSectionItem = (props) => {
1533
1541
  */
1534
1542
  const AccordionPinnedContainer = () => {
1535
1543
  AccordionPinnedContainer.displayName = "AccordionPinnedContainer";
1536
- const classes = useStyles$U();
1544
+ const classes = useStyles$X();
1537
1545
  const accordionCtx = useContext(AccordionContext);
1538
1546
  return (jsx("div", { ref: accordionCtx?.pinnedContainerRef, className: classes.pinnedContainer, children: jsx(MessageBar$1, { className: classes.pinnedContainerEmpty, children: jsx(MessageBarBody, { children: "No pinned items" }) }) }));
1539
1547
  };
@@ -1544,7 +1552,7 @@ const AccordionPinnedContainer = () => {
1544
1552
  */
1545
1553
  const AccordionSearchBox = () => {
1546
1554
  AccordionSearchBox.displayName = "AccordionSearchBox";
1547
- const classes = useStyles$U();
1555
+ const classes = useStyles$X();
1548
1556
  const accordionCtx = useContext(AccordionContext);
1549
1557
  if (!accordionCtx?.features.search) {
1550
1558
  return null;
@@ -1560,7 +1568,7 @@ const AccordionSearchBox = () => {
1560
1568
  */
1561
1569
  const AccordionSection = (props) => {
1562
1570
  AccordionSection.displayName = "AccordionSection";
1563
- const classes = useStyles$U();
1571
+ const classes = useStyles$X();
1564
1572
  return jsx("div", { className: classes.panelDiv, children: props.children });
1565
1573
  };
1566
1574
  const StringAccordion = Accordion$1;
@@ -1568,7 +1576,7 @@ const Accordion = forwardRef((props, ref) => {
1568
1576
  Accordion.displayName = "Accordion";
1569
1577
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
1570
1578
  const { children, highlightSections, uniqueId, enablePinnedItems, enableHiddenItems, enableSearchItems, ...rest } = props;
1571
- const classes = useStyles$U();
1579
+ const classes = useStyles$X();
1572
1580
  const { size } = useContext(ToolContext);
1573
1581
  const accordionCtx = useAccordionContext(props);
1574
1582
  const hasPinning = accordionCtx?.features.pinning ?? false;
@@ -1665,7 +1673,7 @@ const Collapse = (props) => {
1665
1673
  return (jsx(Collapse$1, { visible: props.visible, orientation: props.orientation, unmountOnExit: true, children: jsx("div", { className: `${classes.collapseContent} ${props.orientation === "horizontal" ? classes.horizontal : classes.vertical}`, children: props.children }) }));
1666
1674
  };
1667
1675
 
1668
- const useStyles$T = makeStyles({
1676
+ const useStyles$W = makeStyles({
1669
1677
  button: {
1670
1678
  display: "flex",
1671
1679
  alignItems: "center",
@@ -1683,7 +1691,7 @@ const ToggleButton = (props) => {
1683
1691
  ToggleButton.displayName = "ToggleButton";
1684
1692
  const { value, onChange, title, appearance = "subtle" } = props;
1685
1693
  const { size } = useContext(ToolContext);
1686
- const classes = useStyles$T();
1694
+ const classes = useStyles$W();
1687
1695
  const [checked, setChecked] = useState(value);
1688
1696
  const toggle = useCallback(() => {
1689
1697
  setChecked((prevChecked) => {
@@ -1733,7 +1741,7 @@ const InfoLabel = (props) => {
1733
1741
  props.onContextMenu(e);
1734
1742
  }
1735
1743
  }, [props.onContextMenu]);
1736
- return infoContent ? (jsx(InfoLabel$1, { htmlFor: props.htmlFor, info: infoContent, className: mergeClasses(props.className, showCopyCursor ? classes.copyable : undefined), label: props.flexLabel ? { className: classes.labelSlot } : undefined, onContextMenu: props.onContextMenu, onClick: handleClick, children: jsx(Body1Strong, { className: classes.labelText, children: props.label }) })) : (jsx(Body1Strong, { className: mergeClasses(props.className, showCopyCursor ? classes.copyable : undefined), onContextMenu: props.onContextMenu, onClick: handleClick, children: props.label }));
1744
+ return infoContent ? (jsx(InfoLabel$1, { htmlFor: props.htmlFor, info: infoContent, className: mergeClasses(props.className, showCopyCursor ? classes.copyable : undefined), label: props.flexLabel ? { className: classes.labelSlot } : undefined, onContextMenu: props.onContextMenu, onClick: handleClick, children: jsx(Body1Strong, { className: classes.labelText, children: props.label }) })) : (jsx("div", { className: mergeClasses(props.className, showCopyCursor ? classes.copyable : undefined), onContextMenu: props.onContextMenu, onClick: handleClick, children: jsx(Body1Strong, { className: classes.labelText, children: props.label }) }));
1737
1745
  };
1738
1746
 
1739
1747
  const ToastContext = createContext({ showToast: () => { } });
@@ -1765,6 +1773,7 @@ const usePropertyLineStyles = makeStyles({
1765
1773
  display: "flex",
1766
1774
  flex: "1 1 0", // grow=1, shrink =1, basis = 0 initial size before
1767
1775
  minWidth: CustomTokens.labelMinWidth,
1776
+ overflow: "hidden",
1768
1777
  textAlign: "left",
1769
1778
  },
1770
1779
  rightContent: {
@@ -2027,7 +2036,7 @@ const UXContextProvider = (props) => {
2027
2036
  function AsReadonlyArray(array) {
2028
2037
  return array;
2029
2038
  }
2030
- const useStyles$S = makeStyles({
2039
+ const useStyles$V = makeStyles({
2031
2040
  rootDiv: {
2032
2041
  flex: 1,
2033
2042
  overflow: "hidden",
@@ -2042,7 +2051,7 @@ const useStyles$S = makeStyles({
2042
2051
  * @returns The extensible accordion component.
2043
2052
  */
2044
2053
  function ExtensibleAccordion(props) {
2045
- const classes = useStyles$S();
2054
+ const classes = useStyles$V();
2046
2055
  const { children, sections, sectionContent, context, sectionsRef, ...rest } = props;
2047
2056
  const defaultSections = useMemo(() => {
2048
2057
  const defaultSections = [];
@@ -2167,7 +2176,7 @@ function ExtensibleAccordion(props) {
2167
2176
  })] }) })) }));
2168
2177
  }
2169
2178
 
2170
- const useStyles$R = makeStyles({
2179
+ const useStyles$U = makeStyles({
2171
2180
  paneRootDiv: {
2172
2181
  display: "flex",
2173
2182
  flex: 1,
@@ -2180,7 +2189,7 @@ const useStyles$R = makeStyles({
2180
2189
  */
2181
2190
  const SidePaneContainer = forwardRef((props, ref) => {
2182
2191
  const { className, ...rest } = props;
2183
- const classes = useStyles$R();
2192
+ const classes = useStyles$U();
2184
2193
  return (jsx("div", { className: mergeClasses(classes.paneRootDiv, className), ref: ref, ...rest, children: props.children }));
2185
2194
  });
2186
2195
 
@@ -2451,7 +2460,7 @@ function useTheme(invert = false) {
2451
2460
  }
2452
2461
 
2453
2462
  // Fluent doesn't apply styling to scrollbars by default, so provide our own reasonable default.
2454
- const useStyles$Q = makeStyles({
2463
+ const useStyles$T = makeStyles({
2455
2464
  root: {
2456
2465
  scrollbarColor: `${tokens.colorNeutralForeground3} ${tokens.colorTransparentBackground}`,
2457
2466
  },
@@ -2467,11 +2476,11 @@ const Theme = (props) => {
2467
2476
  // break any UI within the portal. Therefore, default to false.
2468
2477
  const { invert = false, applyStylesToPortals = false, className, ...rest } = props;
2469
2478
  const theme = useTheme(invert);
2470
- const classes = useStyles$Q();
2479
+ const classes = useStyles$T();
2471
2480
  return (jsx(FluentProvider, { theme: theme, className: mergeClasses(classes.root, className), applyStylesToPortals: applyStylesToPortals, ...rest, children: props.children }));
2472
2481
  };
2473
2482
 
2474
- const useStyles$P = makeStyles({
2483
+ const useStyles$S = makeStyles({
2475
2484
  extensionTeachingPopover: {
2476
2485
  maxWidth: "320px",
2477
2486
  },
@@ -2482,7 +2491,7 @@ const useStyles$P = makeStyles({
2482
2491
  * @returns The teaching moment popover.
2483
2492
  */
2484
2493
  const TeachingMoment = ({ shouldDisplay, positioningRef, onOpenChange, title, description }) => {
2485
- const classes = useStyles$P();
2494
+ const classes = useStyles$S();
2486
2495
  return (jsx(TeachingPopover, { appearance: "brand", open: shouldDisplay, positioning: { positioningRef }, onOpenChange: onOpenChange, children: jsxs(TeachingPopoverSurface, { className: classes.extensionTeachingPopover, children: [jsx(TeachingPopoverHeader, { children: title }), jsx(TeachingPopoverBody, { children: description })] }) }));
2487
2496
  };
2488
2497
 
@@ -2685,13 +2694,13 @@ function useImpulse() {
2685
2694
  return [value, pulse];
2686
2695
  }
2687
2696
 
2688
- const useStyles$O = makeStyles({
2697
+ const useStyles$R = makeStyles({
2689
2698
  placeholderDiv: {
2690
2699
  padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalM}`,
2691
2700
  },
2692
2701
  });
2693
2702
  const PropertiesPane = (props) => {
2694
- const classes = useStyles$O();
2703
+ const classes = useStyles$R();
2695
2704
  const entity = props.context;
2696
2705
  return entity != null ? (jsx(ExtensibleAccordion, { ...props })) : (jsx("div", { className: classes.placeholderDiv, children: jsx(Body1Strong, { italic: true, children: "No entity selected." }) }));
2697
2706
  };
@@ -3017,7 +3026,7 @@ const RootComponentServiceIdentity = Symbol("RootComponent");
3017
3026
  * The unique identity symbol for the shell service.
3018
3027
  */
3019
3028
  const ShellServiceIdentity = Symbol("ShellService");
3020
- const useStyles$N = makeStyles({
3029
+ const useStyles$Q = makeStyles({
3021
3030
  mainView: {
3022
3031
  flex: 1,
3023
3032
  display: "flex",
@@ -3230,14 +3239,14 @@ const DockMenu = (props) => {
3230
3239
  };
3231
3240
  const PaneHeader = (props) => {
3232
3241
  const { id, title, dockOptions } = props;
3233
- const classes = useStyles$N();
3242
+ const classes = useStyles$Q();
3234
3243
  return (jsxs("div", { className: classes.paneHeaderDiv, children: [props.icon && (jsx("div", { className: classes.paneHeaderIcon, children: jsx(props.icon, {}) })), jsx(Subtitle2Stronger, { className: mergeClasses(classes.paneHeaderText, !props.icon && classes.paneHeaderTextNoIcon), children: title }), jsx(DockMenu, { sidePaneId: id, dockOptions: dockOptions, children: jsx(Button$1, { className: classes.paneHeaderButton, appearance: "transparent", icon: jsx(MoreHorizontalRegular, {}) }) })] }));
3235
3244
  };
3236
3245
  // This is a wrapper for an item in a toolbar that simply adds a teaching moment, which is useful for dynamically added items, possibly from extensions.
3237
3246
  const ToolbarItem = (props) => {
3238
3247
  // eslint-disable-next-line @typescript-eslint/naming-convention
3239
3248
  const { verticalLocation, horizontalLocation, id, component: Component, displayName } = props;
3240
- const classes = useStyles$N();
3249
+ const classes = useStyles$Q();
3241
3250
  const useTeachingMoment = useMemo(() => MakePopoverTeachingMoment(`Bar/${verticalLocation}/${horizontalLocation}/${displayName ?? id}`), [displayName, id]);
3242
3251
  const teachingMoment = useTeachingMoment(props.teachingMoment === false);
3243
3252
  const title = typeof props.teachingMoment === "object" ? props.teachingMoment.title : (displayName ?? id);
@@ -3247,7 +3256,7 @@ const ToolbarItem = (props) => {
3247
3256
  // TODO: Handle overflow, possibly via https://react.fluentui.dev/?path=/docs/components-overflow--docs with priority.
3248
3257
  // This component just renders a toolbar with left aligned toolbar items on the left and right aligned toolbar items on the right.
3249
3258
  const Toolbar = ({ location, components }) => {
3250
- const classes = useStyles$N();
3259
+ const classes = useStyles$Q();
3251
3260
  const leftComponents = useMemo(() => components.filter((entry) => entry.horizontalLocation === "left"), [components]);
3252
3261
  const rightComponents = useMemo(() => components.filter((entry) => entry.horizontalLocation === "right"), [components]);
3253
3262
  return (jsx(Fragment, { children: components.length > 0 && (jsxs("div", { className: `${classes.bar} ${location === "top" ? classes.barTop : classes.barBottom}`, children: [jsx("div", { className: classes.barLeft, children: leftComponents.map((entry) => (jsx(ToolbarItem, { verticalLocation: location, horizontalLocation: entry.horizontalLocation, id: entry.key, component: entry.component, displayName: entry.displayName, teachingMoment: entry.teachingMoment }, entry.key))) }), jsx("div", { className: classes.barRight, children: rightComponents.map((entry) => (jsx(ToolbarItem, { verticalLocation: location, horizontalLocation: entry.horizontalLocation, id: entry.key, component: entry.component, displayName: entry.displayName, teachingMoment: entry.teachingMoment }, entry.key))) })] })) }));
@@ -3257,7 +3266,7 @@ const SidePaneTab = (props) => {
3257
3266
  const { location, id, isSelected, isFirst, isLast, dockOptions,
3258
3267
  // eslint-disable-next-line @typescript-eslint/naming-convention
3259
3268
  icon: Icon, title, } = props;
3260
- const classes = useStyles$N();
3269
+ const classes = useStyles$Q();
3261
3270
  const useTeachingMoment = useMemo(() => MakePopoverTeachingMoment(`Pane/${location}/${title ?? id}`), [title, id]);
3262
3271
  const teachingMoment = useTeachingMoment(props.teachingMoment === false);
3263
3272
  const tabClass = mergeClasses(classes.tab, isSelected ? classes.selectedTab : classes.unselectedTab, isFirst ? classes.firstTab : undefined, isLast ? classes.lastTab : undefined);
@@ -3269,7 +3278,7 @@ const SidePaneTab = (props) => {
3269
3278
  // In "compact" mode, the tab list is integrated into the pane itself.
3270
3279
  // In "full" mode, the returned tab list is later injected into the toolbar.
3271
3280
  function usePane(location, defaultWidth, minWidth, sidePanes, onSelectSidePane, dockOperations, toolbarMode, topBarItems, bottomBarItems, initialCollapsed) {
3272
- const classes = useStyles$N();
3281
+ const classes = useStyles$Q();
3273
3282
  const [topSelectedTab, setTopSelectedTab] = useState();
3274
3283
  const [bottomSelectedTab, setBottomSelectedTab] = useState();
3275
3284
  const [collapsed, setCollapsed] = useState(initialCollapsed);
@@ -3466,7 +3475,7 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
3466
3475
  expand: () => onCollapseChanged.notifyObservers({ location: "right", collapsed: false }),
3467
3476
  };
3468
3477
  const rootComponent = () => {
3469
- const classes = useStyles$N();
3478
+ const classes = useStyles$Q();
3470
3479
  const [sidePaneDockOverrides, setSidePaneDockOverrides] = useSetting(SidePaneDockOverridesSettingDescriptor);
3471
3480
  // This function returns a promise that resolves after the dock change takes effect so that
3472
3481
  // we can then select the re-docked pane.
@@ -4230,7 +4239,7 @@ function CoerceEntityArray(entities, sort) {
4230
4239
  }
4231
4240
  return entities;
4232
4241
  }
4233
- const useStyles$M = makeStyles({
4242
+ const useStyles$P = makeStyles({
4234
4243
  rootDiv: {
4235
4244
  flex: 1,
4236
4245
  overflow: "hidden",
@@ -4339,14 +4348,14 @@ function MakeInlineCommandElement(command, isPlaceholder) {
4339
4348
  }
4340
4349
  const SceneTreeItem = (props) => {
4341
4350
  const { isSelected, select } = props;
4342
- const classes = useStyles$M();
4351
+ const classes = useStyles$P();
4343
4352
  const [compactMode] = useSetting(CompactModeSettingDescriptor);
4344
4353
  const treeItemLayoutClass = mergeClasses(classes.sceneTreeItemLayout, compactMode ? classes.treeItemLayoutCompact : undefined);
4345
4354
  return (jsx(FlatTreeItem, { className: classes.treeItem, value: "scene", itemType: "leaf", parentValue: undefined, "aria-level": 1, "aria-setsize": 1, "aria-posinset": 1, onClick: select, children: jsx(TreeItemLayout, { iconBefore: jsx(GlobeRegular, {}), className: treeItemLayoutClass, style: isSelected ? { backgroundColor: tokens.colorNeutralBackground1Selected } : undefined, children: jsx(Body1Strong, { wrap: false, truncate: true, children: "Scene" }) }) }, "scene"));
4346
4355
  };
4347
4356
  const SectionTreeItem = (props) => {
4348
4357
  const { section, isFiltering, commandProviders, expandAll, collapseAll, isDropTarget, ...dropProps } = props;
4349
- const classes = useStyles$M();
4358
+ const classes = useStyles$P();
4350
4359
  const [compactMode] = useSetting(CompactModeSettingDescriptor);
4351
4360
  // Get the commands that apply to this section.
4352
4361
  const commands = useResource(useCallback(() => {
@@ -4363,7 +4372,7 @@ const SectionTreeItem = (props) => {
4363
4372
  };
4364
4373
  const EntityTreeItem = (props) => {
4365
4374
  const { entityItem, isSelected, select, isFiltering, commandProviders, expandAll, collapseAll, isDragging, isDropTarget, ...dragProps } = props;
4366
- const classes = useStyles$M();
4375
+ const classes = useStyles$P();
4367
4376
  const [compactMode] = useSetting(CompactModeSettingDescriptor);
4368
4377
  const hasChildren = !!entityItem.children?.length;
4369
4378
  const displayInfo = useResource(useCallback(() => {
@@ -4479,7 +4488,7 @@ const EntityTreeItem = (props) => {
4479
4488
  }, children: jsx(Body1, { wrap: false, truncate: true, children: name }) }) }, GetEntityId(entityItem.entity)) }), jsx(MenuPopover, { hidden: !hasChildren && contextMenuCommands.length === 0, children: jsxs(MenuList, { children: [hasChildren && (jsxs(Fragment, { children: [jsx(MenuItem, { icon: jsx(ArrowExpandAllRegular, {}), onClick: expandAll, children: jsx(Body1, { children: "Expand All" }) }), jsx(MenuItem, { icon: jsx(ArrowCollapseAllRegular, {}), onClick: collapseAll, children: jsx(Body1, { children: "Collapse All" }) })] })), hasChildren && contextMenuCommands.length > 0 && jsx(MenuDivider, {}), contextMenuItems] }) })] }));
4480
4489
  };
4481
4490
  const SceneExplorer = (props) => {
4482
- const classes = useStyles$M();
4491
+ const classes = useStyles$P();
4483
4492
  const { sections, entityCommandProviders, sectionCommandProviders, scene, selectedEntity = null } = props;
4484
4493
  const [openItems, setOpenItems] = useState(new Set());
4485
4494
  const [sceneVersion, setSceneVersion] = useState(0);
@@ -5524,13 +5533,9 @@ class CanvasGraphService {
5524
5533
  ctx.font = GraphAddonFont;
5525
5534
  ctx.textBaseline = "middle";
5526
5535
  ctx.textAlign = "left";
5527
- let width;
5528
5536
  // if the lengths are the same the estimate should be good enough given the padding.
5529
- if (this._tickerTextCache.text.length === longestText.length) {
5530
- width = this._tickerTextCache.width;
5531
- }
5532
- else {
5533
- width = ctx.measureText(longestText).width + 2 * TickerHorizontalPadding;
5537
+ if (this._tickerTextCache.text.length !== longestText.length) {
5538
+ const width = ctx.measureText(longestText).width + 2 * TickerHorizontalPadding;
5534
5539
  this._tickerTextCache.text = longestText;
5535
5540
  this._tickerTextCache.width = width;
5536
5541
  }
@@ -5812,10 +5817,10 @@ class CanvasGraphService {
5812
5817
  return Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2));
5813
5818
  }
5814
5819
  // next we want to handle the case where our point is beyond the y position of our line
5815
- let topX = 0;
5816
- let topY = 0;
5817
- let bottomX = 0;
5818
- let bottomY = 0;
5820
+ let topX;
5821
+ let topY;
5822
+ let bottomX;
5823
+ let bottomY;
5819
5824
  if (y1 >= y2) {
5820
5825
  topX = x1;
5821
5826
  topY = y1;
@@ -6108,7 +6113,7 @@ class CanvasGraphService {
6108
6113
  }
6109
6114
  }
6110
6115
 
6111
- const useStyles$L = makeStyles({
6116
+ const useStyles$O = makeStyles({
6112
6117
  canvas: {
6113
6118
  flexGrow: 1,
6114
6119
  width: "100%",
@@ -6117,7 +6122,7 @@ const useStyles$L = makeStyles({
6117
6122
  });
6118
6123
  const CanvasGraph = (props) => {
6119
6124
  const { collector, scene, layoutObservable, returnToPlayheadObservable, onVisibleRangeChangedObservable, initialGraphSize } = props;
6120
- const classes = useStyles$L();
6125
+ const classes = useStyles$O();
6121
6126
  const canvasRef = useRef(null);
6122
6127
  useEffect(() => {
6123
6128
  if (!canvasRef.current) {
@@ -6194,7 +6199,7 @@ function EvaluateExpression(rawValue) {
6194
6199
  return NaN;
6195
6200
  }
6196
6201
  }
6197
- const useStyles$K = makeStyles({
6202
+ const useStyles$N = makeStyles({
6198
6203
  icon: {
6199
6204
  "&:hover": {
6200
6205
  color: tokens.colorBrandForeground1,
@@ -6208,7 +6213,7 @@ const useStyles$K = makeStyles({
6208
6213
  const SpinButton = forwardRef((props, ref) => {
6209
6214
  SpinButton.displayName = "SpinButton2";
6210
6215
  const inputClasses = useInputStyles$1();
6211
- const classes = useStyles$K();
6216
+ const classes = useStyles$N();
6212
6217
  const { size } = useContext(ToolContext);
6213
6218
  const { min, max } = props;
6214
6219
  const baseStep = props.step ?? 1;
@@ -6350,7 +6355,7 @@ const SpinButton = forwardRef((props, ref) => {
6350
6355
  // Real-time validation: when editing, validate the expression; otherwise validate the committed value.
6351
6356
  // (validateValue already handles NaN, so no separate isNaN check needed.)
6352
6357
  const isInputInvalid = !validateValue(isEditing ? EvaluateExpression(editText) : value);
6353
- const mergedClassName = mergeClasses(inputClasses.input, isInputInvalid ? inputClasses.invalid : "", props.className);
6358
+ const mergedClassName = mergeClasses(inputClasses.inputFill, isInputInvalid ? inputClasses.invalid : "");
6354
6359
  const inputSlotClassName = mergeClasses(inputClasses.inputSlot, props.inputClassName);
6355
6360
  const formattedValue = formatValue(value);
6356
6361
  const handleFocus = useCallback(() => {
@@ -6366,13 +6371,13 @@ const SpinButton = forwardRef((props, ref) => {
6366
6371
  setIsEditing(false);
6367
6372
  HandleOnBlur(event);
6368
6373
  }, [commitEditText, isDragging]);
6369
- const contentBefore = !props.disableDragButton && (isHovered || isDragging) && !isInputInvalid ? (jsx(ArrowBidirectionalUpDownFilled, { className: classes.icon, style: { cursor: isDragging ? "ns-resize" : "pointer" }, onPointerDown: handleIconPointerDown, onPointerMove: handleIconPointerMove, onPointerUp: handleIconPointerUp })) : undefined;
6370
- const input = (jsx("div", { onMouseEnter: () => setIsHovered(true), onMouseLeave: () => {
6374
+ const contentBefore = !props.disableDragButton && !props.disabled && (isHovered || isDragging) && !isInputInvalid ? (jsx(ArrowBidirectionalUpDownFilled, { className: classes.icon, style: { cursor: isDragging ? "ns-resize" : "pointer" }, onPointerDown: handleIconPointerDown, onPointerMove: handleIconPointerMove, onPointerUp: handleIconPointerUp })) : undefined;
6375
+ const input = (jsx("div", { className: props.infoLabel ? undefined : props.className, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => {
6371
6376
  if (!isDragging) {
6372
6377
  setIsHovered(false);
6373
6378
  }
6374
- }, children: jsx(Input, { ref: mergedRef, id: id, appearance: "outline", size: size, className: mergedClassName, input: { className: inputSlotClassName }, value: isEditing ? editText : formattedValue, onChange: handleInputChange, onFocus: handleFocus, onKeyDown: handleKeyDown, onBlur: handleBlur, contentBefore: contentBefore, contentAfter: props.unit }) }));
6375
- return props.infoLabel ? (jsxs("div", { className: inputClasses.container, children: [jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), input] })) : (input);
6379
+ }, children: jsx(Input, { ref: mergedRef, id: id, appearance: "outline", size: size, className: mergedClassName, input: { className: inputSlotClassName }, value: isEditing ? editText : formattedValue, disabled: props.disabled, onChange: handleInputChange, onFocus: handleFocus, onKeyDown: handleKeyDown, onBlur: handleBlur, contentBefore: contentBefore, contentAfter: props.unit }) }));
6380
+ return props.infoLabel ? (jsxs("div", { className: mergeClasses(inputClasses.container, props.className), children: [jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), input] })) : (input);
6376
6381
  });
6377
6382
 
6378
6383
  const TextInput = (props) => {
@@ -6417,9 +6422,9 @@ const TextInput = (props) => {
6417
6422
  tryCommitValue(event.currentTarget.value);
6418
6423
  }
6419
6424
  };
6420
- const mergedClassName = mergeClasses(classes.input, !validateValue(value) ? classes.invalid : "", props.className);
6425
+ const mergedClassName = mergeClasses(classes.inputFill, !validateValue(value) ? classes.invalid : "");
6421
6426
  const id = useId("input-button");
6422
- return (jsxs("div", { className: classes.container, children: [props.infoLabel && jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), jsx(Input, { ...props, input: { className: classes.inputSlot }, id: id, size: size, value: value, onChange: handleChange, onKeyUp: handleKeyUp, onKeyDown: HandleKeyDown, onBlur: handleBlur, className: mergedClassName })] }));
6427
+ return (jsxs("div", { className: mergeClasses(classes.container, props.className), children: [props.infoLabel && jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), jsx(Input, { ...props, input: { className: classes.inputSlot }, id: id, size: size, value: value, onChange: handleChange, onKeyUp: handleKeyUp, onKeyDown: HandleKeyDown, onBlur: handleBlur, className: mergedClassName })] }));
6423
6428
  };
6424
6429
 
6425
6430
  const useDropdownStyles = makeStyles({
@@ -6463,7 +6468,7 @@ const Dropdown = (props) => {
6463
6468
  const NumberDropdown = Dropdown;
6464
6469
  const StringDropdown = Dropdown;
6465
6470
 
6466
- const useStyles$J = makeStyles({
6471
+ const useStyles$M = makeStyles({
6467
6472
  surface: {
6468
6473
  maxWidth: "400px",
6469
6474
  },
@@ -6478,7 +6483,7 @@ const useStyles$J = makeStyles({
6478
6483
  const Popover = forwardRef((props, ref) => {
6479
6484
  const { children, open: controlledOpen, onOpenChange, positioning, surfaceClassName } = props;
6480
6485
  const [internalOpen, setInternalOpen] = useState(false);
6481
- const classes = useStyles$J();
6486
+ const classes = useStyles$M();
6482
6487
  const isControlled = controlledOpen !== undefined;
6483
6488
  const popoverOpen = isControlled ? controlledOpen : internalOpen;
6484
6489
  const handleOpenChange = (_, data) => {
@@ -6667,7 +6672,7 @@ const InputAlphaField = (props) => {
6667
6672
  } }));
6668
6673
  };
6669
6674
 
6670
- const useStyles$I = makeStyles({
6675
+ const useStyles$L = makeStyles({
6671
6676
  sidebar: {
6672
6677
  display: "flex",
6673
6678
  flexDirection: "column",
@@ -6731,7 +6736,7 @@ const useStyles$I = makeStyles({
6731
6736
  });
6732
6737
  const PerformanceSidebar = (props) => {
6733
6738
  const { collector, onVisibleRangeChangedObservable } = props;
6734
- const classes = useStyles$I();
6739
+ const classes = useStyles$L();
6735
6740
  // Map from id to IPerfMetadata information
6736
6741
  const [metadataMap, setMetadataMap] = useState();
6737
6742
  // Map from category to all the ids belonging to that category
@@ -6804,7 +6809,7 @@ const PerformanceSidebar = (props) => {
6804
6809
  })] }, `category-${category || "version"}`))) }));
6805
6810
  };
6806
6811
 
6807
- const useStyles$H = makeStyles({
6812
+ const useStyles$K = makeStyles({
6808
6813
  container: {
6809
6814
  display: "flex",
6810
6815
  flexDirection: "row",
@@ -6833,7 +6838,7 @@ const useStyles$H = makeStyles({
6833
6838
  });
6834
6839
  const PerformanceViewer = (props) => {
6835
6840
  const { scene, layoutObservable, returnToLiveObservable, performanceCollector, initialGraphSize } = props;
6836
- const classes = useStyles$H();
6841
+ const classes = useStyles$K();
6837
6842
  const [onVisibleRangeChangedObservable] = useState(() => new Observable());
6838
6843
  const onReturnToPlayheadClick = () => {
6839
6844
  returnToLiveObservable.notifyObservers();
@@ -7002,14 +7007,14 @@ const TextPropertyLine = (props) => {
7002
7007
  return (jsx(PropertyLine, { ...props, children: jsx(Body1, { title: title, children: value ?? "" }) }));
7003
7008
  };
7004
7009
 
7005
- const useStyles$G = makeStyles({
7010
+ const useStyles$J = makeStyles({
7006
7011
  pinnedStatsPane: {
7007
7012
  flex: "0 1 auto",
7008
7013
  paddingBottom: tokens.spacingHorizontalM,
7009
7014
  },
7010
7015
  });
7011
7016
  const StatsPane = (props) => {
7012
- const classes = useStyles$G();
7017
+ const classes = useStyles$J();
7013
7018
  const scene = props.context;
7014
7019
  const engine = scene.getEngine();
7015
7020
  const pollingObservable = usePollingObservable(250);
@@ -7167,7 +7172,7 @@ const ToolsServiceDefinition = {
7167
7172
  },
7168
7173
  };
7169
7174
 
7170
- const useStyles$F = makeStyles({
7175
+ const useStyles$I = makeStyles({
7171
7176
  dropdown: {
7172
7177
  ...UniformWidthStyling,
7173
7178
  },
@@ -7179,7 +7184,7 @@ const useStyles$F = makeStyles({
7179
7184
  */
7180
7185
  const DropdownPropertyLine = forwardRef((props, ref) => {
7181
7186
  DropdownPropertyLine.displayName = "DropdownPropertyLine";
7182
- const classes = useStyles$F();
7187
+ const classes = useStyles$I();
7183
7188
  return (jsx(PropertyLine, { ...props, ref: ref, children: jsx(Dropdown, { ...props, className: classes.dropdown }) }));
7184
7189
  });
7185
7190
  /**
@@ -7252,20 +7257,27 @@ const useSyncedSliderStyles = makeStyles({
7252
7257
  alignItems: "center",
7253
7258
  minWidth: 0,
7254
7259
  },
7260
+ // Default: 50/50 split between slider and spinbutton
7255
7261
  slider: {
7256
- flex: "1 1 auto",
7257
- minWidth: "75px",
7258
- maxWidth: "75px",
7262
+ flex: "1 1 0",
7263
+ minWidth: 0,
7264
+ },
7265
+ spinButton: {
7266
+ flex: "1 1 0",
7267
+ minWidth: 0,
7268
+ },
7269
+ spinButtonInput: {
7270
+ minWidth: "0",
7259
7271
  },
7272
+ // compact/growSlider overrides for standalone (non-PropertyLine) usage
7260
7273
  compactSlider: {
7261
7274
  flex: "1 1 auto",
7262
- minWidth: "50px", // Allow shrinking for compact mode
7275
+ minWidth: "50px",
7263
7276
  maxWidth: "75px",
7264
7277
  },
7265
7278
  growSlider: {
7266
7279
  flex: "1 1 auto",
7267
7280
  minWidth: "50px",
7268
- // No maxWidth - slider grows to fill available space
7269
7281
  },
7270
7282
  compactSpinButton: {
7271
7283
  width: "65px",
@@ -7317,7 +7329,7 @@ const SyncedSliderInput = (props) => {
7317
7329
  props.onChange(value); // Input always updates immediately
7318
7330
  };
7319
7331
  const hasSlider = props.min !== undefined && props.max !== undefined;
7320
- // Determine Slider className based on props
7332
+ const useCompactSizing = props.compact || props.growSlider;
7321
7333
  const getSliderClassName = () => {
7322
7334
  if (props.growSlider) {
7323
7335
  return classes.growSlider;
@@ -7327,9 +7339,14 @@ const SyncedSliderInput = (props) => {
7327
7339
  }
7328
7340
  return classes.slider;
7329
7341
  };
7330
- return (jsxs("div", { className: classes.container, children: [infoLabel && jsx(InfoLabel, { ...infoLabel, htmlFor: "syncedSlider" }), jsxs("div", { id: "syncedSlider", className: classes.syncedSlider, children: [hasSlider && (jsx(Slider, { className: getSliderClassName(), value: value, onChange: handleSliderChange, min: props.min, max: props.max, step: props.step, disabled: props.disabled, onPointerDown: handleSliderPointerDown, onPointerUp: handleSliderPointerUp })), jsx(SpinButton, { ...passthroughProps, className: hasSlider || props.compact ? classes.compactSpinButton : undefined, inputClassName: hasSlider || props.compact ? classes.compactSpinButtonInput : undefined, value: value, onChange: handleInputChange, step: props.step, disableDragButton: true })] })] }));
7342
+ return (jsxs("div", { className: mergeClasses(classes.container, props.className), children: [infoLabel && jsx(InfoLabel, { ...infoLabel, htmlFor: "syncedSlider" }), jsxs("div", { id: "syncedSlider", className: classes.syncedSlider, children: [hasSlider && (jsx(Slider, { className: getSliderClassName(), value: value, onChange: handleSliderChange, min: props.min, max: props.max, step: props.step, disabled: props.disabled, onPointerDown: handleSliderPointerDown, onPointerUp: handleSliderPointerUp })), jsx(SpinButton, { ...passthroughProps, className: useCompactSizing ? classes.compactSpinButton : classes.spinButton, inputClassName: useCompactSizing ? classes.compactSpinButtonInput : classes.spinButtonInput, value: value, onChange: handleInputChange, step: props.step, disabled: props.disabled, disableDragButton: true })] })] }));
7331
7343
  };
7332
7344
 
7345
+ const useStyles$H = makeStyles({
7346
+ uniformWidth: {
7347
+ ...UniformWidthStyling,
7348
+ },
7349
+ });
7333
7350
  /**
7334
7351
  * Renders a simple wrapper around the SyncedSliderInput
7335
7352
  * @param props
@@ -7337,8 +7354,9 @@ const SyncedSliderInput = (props) => {
7337
7354
  */
7338
7355
  const SyncedSliderPropertyLine = forwardRef((props, ref) => {
7339
7356
  SyncedSliderPropertyLine.displayName = "SyncedSliderPropertyLine";
7357
+ const classes = useStyles$H();
7340
7358
  const { label, description, ...sliderProps } = props;
7341
- return (jsx(PropertyLine, { ref: ref, ...props, children: jsx(SyncedSliderInput, { ...sliderProps }) }));
7359
+ return (jsx(PropertyLine, { ref: ref, ...props, children: jsx(SyncedSliderInput, { ...sliderProps, className: mergeClasses(classes.uniformWidth, props.className) }) }));
7342
7360
  });
7343
7361
 
7344
7362
  const WatcherSettingDescriptor = {
@@ -7779,7 +7797,7 @@ const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
7779
7797
  keywords: ["creation", "tools"],
7780
7798
  ...BabylonWebResources,
7781
7799
  author: { name: "Babylon.js", forumUserName: "" },
7782
- getExtensionModuleAsync: async () => await import('./quickCreateToolsService-DnszM-9c.js'),
7800
+ getExtensionModuleAsync: async () => await import('./quickCreateToolsService-D-cyDKNQ.js'),
7783
7801
  },
7784
7802
  {
7785
7803
  name: "Reflector",
@@ -7787,7 +7805,7 @@ const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
7787
7805
  keywords: ["reflector", "bridge", "sync", "sandbox", "tools"],
7788
7806
  ...BabylonWebResources,
7789
7807
  author: { name: "Babylon.js", forumUserName: "" },
7790
- getExtensionModuleAsync: async () => await import('./reflectorService-Dis4AcAP.js'),
7808
+ getExtensionModuleAsync: async () => await import('./reflectorService-DNf_o1rS.js'),
7791
7809
  },
7792
7810
  ]);
7793
7811
 
@@ -7825,6 +7843,11 @@ const ColorSliders = ({ color, onSliderChange }) => (jsxs(Fragment, { children:
7825
7843
  const Color3PropertyLine = ColorPropertyLine;
7826
7844
  const Color4PropertyLine = ColorPropertyLine;
7827
7845
 
7846
+ const useStyles$G = makeStyles({
7847
+ uniformWidth: {
7848
+ ...UniformWidthStyling,
7849
+ },
7850
+ });
7828
7851
  /**
7829
7852
  * Wraps a text input in a property line
7830
7853
  * @param props - PropertyLineProps and InputProps
@@ -7832,7 +7855,8 @@ const Color4PropertyLine = ColorPropertyLine;
7832
7855
  */
7833
7856
  const TextInputPropertyLine = (props) => {
7834
7857
  TextInputPropertyLine.displayName = "TextInputPropertyLine";
7835
- return (jsx(PropertyLine, { ...props, children: jsx(TextInput, { ...props }) }));
7858
+ const classes = useStyles$G();
7859
+ return (jsx(PropertyLine, { ...props, children: jsx(TextInput, { ...props, className: mergeClasses(classes.uniformWidth, props.className) }) }));
7836
7860
  };
7837
7861
  /**
7838
7862
  * Wraps a number input in a property line
@@ -7842,7 +7866,8 @@ const TextInputPropertyLine = (props) => {
7842
7866
  */
7843
7867
  const NumberInputPropertyLine = (props) => {
7844
7868
  NumberInputPropertyLine.displayName = "NumberInputPropertyLine";
7845
- return (jsx(PropertyLine, { ...props, children: jsx(SpinButton, { ...props }) }));
7869
+ const classes = useStyles$G();
7870
+ return (jsx(PropertyLine, { ...props, children: jsx(SpinButton, { ...props, className: mergeClasses(classes.uniformWidth, props.className) }) }));
7846
7871
  };
7847
7872
 
7848
7873
  const HasZ = (vector) => !(vector instanceof Vector2);
@@ -8397,7 +8422,7 @@ class ServiceContainer {
8397
8422
  }
8398
8423
  }
8399
8424
 
8400
- const useStyles$E = makeStyles({
8425
+ const useStyles$F = makeStyles({
8401
8426
  themeButton: {
8402
8427
  margin: 0,
8403
8428
  },
@@ -8416,7 +8441,7 @@ const ThemeSelectorServiceDefinition = {
8416
8441
  teachingMoment: false,
8417
8442
  order: -300,
8418
8443
  component: () => {
8419
- const classes = useStyles$E();
8444
+ const classes = useStyles$F();
8420
8445
  const { isDarkMode, themeMode, setThemeMode } = useThemeMode();
8421
8446
  const onSelectedThemeChange = useCallback((e, data) => {
8422
8447
  setThemeMode(data.checkedItems.includes("System") ? "system" : data.checkedItems[0].toLocaleLowerCase());
@@ -8433,7 +8458,7 @@ const ThemeSelectorServiceDefinition = {
8433
8458
  },
8434
8459
  };
8435
8460
 
8436
- const useStyles$D = makeStyles({
8461
+ const useStyles$E = makeStyles({
8437
8462
  app: {
8438
8463
  colorScheme: "light dark",
8439
8464
  flexGrow: 1,
@@ -8473,7 +8498,7 @@ function MakeModularTool(options) {
8473
8498
  settingsStore.writeSetting(ThemeModeSettingDescriptor, themeMode);
8474
8499
  }
8475
8500
  const modularToolRootComponent = () => {
8476
- const classes = useStyles$D();
8501
+ const classes = useStyles$E();
8477
8502
  const [extensionManagerContext, setExtensionManagerContext] = useState();
8478
8503
  const [requiredExtensions, setRequiredExtensions] = useState();
8479
8504
  const [requiredExtensionsDeferred, setRequiredExtensionsDeferred] = useState();
@@ -8516,7 +8541,7 @@ function MakeModularTool(options) {
8516
8541
  }
8517
8542
  // Register the extension list service (for browsing/installing extensions) if extension feeds are provided.
8518
8543
  if (extensionFeeds.length > 0) {
8519
- const { ExtensionListServiceDefinition } = await import('./extensionsListService-ClgMe11V.js');
8544
+ const { ExtensionListServiceDefinition } = await import('./extensionsListService--XzVqzeM.js');
8520
8545
  await serviceContainer.addServiceAsync(ExtensionListServiceDefinition);
8521
8546
  }
8522
8547
  // Register all external services (that make up a unique tool).
@@ -8623,7 +8648,7 @@ const BreakTangentIcon = createFluentIcon("BreakTangent", "20", '<g transform="s
8623
8648
  const UnifyTangentIcon = createFluentIcon("UnifyTangent", "20", '<g transform="scale(0.5)"><path d="M27.94,18.28a1.49,1.49,0,0,0-1.41,1h-5l-1.62-1.63-1.62,1.63h-5a1.5,1.5,0,1,0,0,1h5l1.62,1.62,1.62-1.62h5a1.5,1.5,0,1,0,1.41-2Z"/></g>');
8624
8649
  const StepTangentIcon = createFluentIcon("StepTangent", "20", '<g transform="scale(0.5)"><path d="M29,16.71a1.5,1.5,0,1,0-2,1.41v5.67H11v1H28V18.12A1.51,1.51,0,0,0,29,16.71Z"/></g>');
8625
8650
 
8626
- const useStyles$C = makeStyles({
8651
+ const useStyles$D = makeStyles({
8627
8652
  coordinatesModeButton: {
8628
8653
  margin: `0 0 0 ${tokens.spacingHorizontalXS}`,
8629
8654
  },
@@ -8639,7 +8664,7 @@ const useStyles$C = makeStyles({
8639
8664
  });
8640
8665
  const GizmoToolbar = (props) => {
8641
8666
  const { gizmoService, sceneContext } = props;
8642
- const classes = useStyles$C();
8667
+ const classes = useStyles$D();
8643
8668
  const gizmoMode = useObservableState(() => gizmoService.gizmoMode, gizmoService.onGizmoModeChanged);
8644
8669
  const coordinatesMode = useObservableState(() => gizmoService.coordinatesMode, gizmoService.onCoordinatesModeChanged);
8645
8670
  const cameraGizmo = useObservableState(() => gizmoService.gizmoCamera, gizmoService.onCameraGizmoChanged);
@@ -8768,7 +8793,7 @@ const HighlightServiceDefinition = {
8768
8793
  },
8769
8794
  };
8770
8795
 
8771
- const useStyles$B = makeStyles({
8796
+ const useStyles$C = makeStyles({
8772
8797
  badge: {
8773
8798
  margin: tokens.spacingHorizontalXXS,
8774
8799
  fontFamily: "monospace",
@@ -8785,7 +8810,7 @@ const MiniStatsServiceDefinition = {
8785
8810
  order: 300 /* DefaultToolbarItemOrder.FrameRate */,
8786
8811
  teachingMoment: false,
8787
8812
  component: () => {
8788
- const classes = useStyles$B();
8813
+ const classes = useStyles$C();
8789
8814
  const scene = useObservableState(useCallback(() => sceneContext.currentScene, [sceneContext.currentScene]), sceneContext.currentSceneObservable);
8790
8815
  const engine = scene?.getEngine();
8791
8816
  const pollingObservable = usePollingObservable(250);
@@ -9114,7 +9139,7 @@ function useCurveEditor() {
9114
9139
  return context;
9115
9140
  }
9116
9141
 
9117
- const useStyles$A = makeStyles({
9142
+ const useStyles$B = makeStyles({
9118
9143
  root: {
9119
9144
  display: "flex",
9120
9145
  flexDirection: "row",
@@ -9158,7 +9183,7 @@ const useStyles$A = makeStyles({
9158
9183
  * @returns The top bar component
9159
9184
  */
9160
9185
  const TopBar = () => {
9161
- const styles = useStyles$A();
9186
+ const styles = useStyles$B();
9162
9187
  const { state, observables } = useCurveEditor();
9163
9188
  const [keyFrameValue, setKeyFrameValue] = useState(null);
9164
9189
  const [keyValue, setKeyValue] = useState(null);
@@ -9251,7 +9276,7 @@ const ColorChannelColors = {
9251
9276
  */
9252
9277
  const DefaultCurveColor = "#ffffff";
9253
9278
 
9254
- const useStyles$z = makeStyles({
9279
+ const useStyles$A = makeStyles({
9255
9280
  root: {
9256
9281
  display: "flex",
9257
9282
  flexDirection: "column",
@@ -9293,7 +9318,7 @@ const LOOP_MODES$1 = [
9293
9318
  * @returns The edit animation panel component
9294
9319
  */
9295
9320
  const EditAnimationPanel = ({ animation, onClose }) => {
9296
- const styles = useStyles$z();
9321
+ const styles = useStyles$A();
9297
9322
  const { observables } = useCurveEditor();
9298
9323
  const [name, setName] = useState(animation.name);
9299
9324
  const [property, setProperty] = useState(animation.targetProperty);
@@ -9324,7 +9349,7 @@ const EditAnimationPanel = ({ animation, onClose }) => {
9324
9349
  return (jsxs("div", { className: styles.root, children: [jsxs("div", { className: styles.form, children: [jsxs("div", { className: styles.row, children: [jsx(Label, { children: "Display Name" }), jsx(Input, { value: name, onChange: (_, data) => setName(data.value), placeholder: "Animation name" })] }), jsxs("div", { className: styles.row, children: [jsx(Label, { children: "Property" }), jsx(Input, { value: property, onChange: (_, data) => setProperty(data.value), placeholder: "e.g., position, rotation, scaling" })] }), jsxs("div", { className: styles.row, children: [jsx(Label, { children: "Loop Mode" }), jsx(Dropdown$1, { value: getLoopModeLabel(loopMode), selectedOptions: [loopMode.toString()], onOptionSelect: (_, data) => setLoopMode(Number(data.optionValue)), positioning: "below", inlinePopup: true, children: LOOP_MODES$1.map((mode) => (jsx(Option, { value: mode.value.toString(), children: mode.label }, mode.value))) })] })] }), jsxs("div", { className: styles.buttons, children: [jsx(Button, { appearance: "primary", onClick: saveChanges, label: "Save", disabled: !isValid }), jsx(Button, { appearance: "subtle", onClick: onClose, label: "Cancel" })] })] }));
9325
9350
  };
9326
9351
 
9327
- const useStyles$y = makeStyles({
9352
+ const useStyles$z = makeStyles({
9328
9353
  root: {
9329
9354
  display: "flex",
9330
9355
  flexDirection: "column",
@@ -9390,7 +9415,7 @@ const useStyles$y = makeStyles({
9390
9415
  * @returns Animation entry component
9391
9416
  */
9392
9417
  const AnimationEntry = ({ animation }) => {
9393
- const styles = useStyles$y();
9418
+ const styles = useStyles$z();
9394
9419
  const { state, actions, observables } = useCurveEditor();
9395
9420
  const [isExpanded, setIsExpanded] = useState(false);
9396
9421
  const [isHovered, setIsHovered] = useState(false);
@@ -9469,7 +9494,7 @@ const AnimationEntry = ({ animation }) => {
9469
9494
  * @returns Animation sub-entry component
9470
9495
  */
9471
9496
  const AnimationSubEntry = ({ animation, subName, color }) => {
9472
- const styles = useStyles$y();
9497
+ const styles = useStyles$z();
9473
9498
  const { actions, observables } = useCurveEditor();
9474
9499
  const activeChannel = actions.getActiveChannel(animation);
9475
9500
  const isThisChannelActive = activeChannel === color;
@@ -9492,7 +9517,7 @@ const AnimationSubEntry = ({ animation, subName, color }) => {
9492
9517
  * @returns Animation list component
9493
9518
  */
9494
9519
  const AnimationList = () => {
9495
- const styles = useStyles$y();
9520
+ const styles = useStyles$z();
9496
9521
  const { state, observables } = useCurveEditor();
9497
9522
  // Re-render when animations are loaded or changed (e.g. animation deleted)
9498
9523
  // useCallback stabilizes the accessor to prevent infinite re-render loops
@@ -9505,7 +9530,7 @@ const AnimationList = () => {
9505
9530
  }) }));
9506
9531
  };
9507
9532
 
9508
- const useStyles$x = makeStyles({
9533
+ const useStyles$y = makeStyles({
9509
9534
  root: {
9510
9535
  display: "flex",
9511
9536
  flexDirection: "column",
@@ -9554,7 +9579,7 @@ const LoopModeOptions = LOOP_MODES.map((lm) => ({ label: lm, value: lm }));
9554
9579
  * @returns The add animation panel component
9555
9580
  */
9556
9581
  const AddAnimationPanel = ({ onClose }) => {
9557
- const styles = useStyles$x();
9582
+ const styles = useStyles$y();
9558
9583
  const { state, actions, observables } = useCurveEditor();
9559
9584
  const [name, setName] = useState("");
9560
9585
  const [mode, setMode] = useState("List");
@@ -9771,7 +9796,7 @@ const AddAnimationPanel = ({ onClose }) => {
9771
9796
  return (jsxs("div", { className: styles.root, children: [jsx("div", { className: styles.header, children: jsx("div", { className: styles.title, children: "Add Animation" }) }), jsxs("div", { className: styles.form, children: [jsxs("div", { className: styles.row, children: [jsx(Label, { children: "Display Name" }), jsx(TextInput, { value: name, onChange: setName })] }), jsx("div", { className: styles.row, children: jsx(StringDropdown, { value: mode, onChange: (val) => setMode(val), options: ModeOptions, disabled: properties.length === 0, infoLabel: { label: "Mode" } }) }), jsxs("div", { className: styles.row, children: [jsx(Label, { children: "Property" }), isCustomMode ? (jsx(TextInput, { value: customProperty, onChange: setCustomProperty })) : (jsx(StringDropdown, { value: selectedProperty, onChange: (val) => setSelectedProperty(val), options: properties.map((p) => ({ label: p, value: p })) }))] }), jsxs("div", { className: styles.row, children: [jsx(Label, { children: "Type" }), isCustomMode ? (jsx(StringDropdown, { value: animationType, onChange: (val) => setAnimationType(val), options: AnimationTypeOptions })) : (jsx("div", { className: styles.typeDisplay, children: inferredType }))] }), jsx("div", { className: styles.row, children: jsx(StringDropdown, { value: loopMode, onChange: (val) => setLoopMode(val), options: LoopModeOptions, infoLabel: { label: "Loop Mode" } }) })] }), jsxs("div", { className: styles.buttons, children: [jsx(Button, { appearance: "primary", onClick: createAnimation, disabled: !isValid, label: "Create" }), jsx(Button, { appearance: "subtle", onClick: onClose, label: "Cancel" })] })] }));
9772
9797
  };
9773
9798
 
9774
- const useStyles$w = makeStyles({
9799
+ const useStyles$x = makeStyles({
9775
9800
  root: {
9776
9801
  display: "flex",
9777
9802
  flexDirection: "column",
@@ -9814,7 +9839,7 @@ const useStyles$w = makeStyles({
9814
9839
  * @returns The load animation panel component
9815
9840
  */
9816
9841
  const LoadAnimationPanel = ({ onClose }) => {
9817
- const styles = useStyles$w();
9842
+ const styles = useStyles$x();
9818
9843
  const { state, actions, observables } = useCurveEditor();
9819
9844
  const [snippetIdInput, setSnippetIdInput] = useState("");
9820
9845
  const [loadedSnippetId, setLoadedSnippetId] = useState(null);
@@ -9953,7 +9978,7 @@ class StringTools {
9953
9978
  }
9954
9979
  }
9955
9980
 
9956
- const useStyles$v = makeStyles({
9981
+ const useStyles$w = makeStyles({
9957
9982
  root: {
9958
9983
  display: "flex",
9959
9984
  flexDirection: "column",
@@ -9998,7 +10023,7 @@ const useStyles$v = makeStyles({
9998
10023
  * @returns The save animation panel component
9999
10024
  */
10000
10025
  const SaveAnimationPanel = ({ onClose: _onClose }) => {
10001
- const styles = useStyles$v();
10026
+ const styles = useStyles$w();
10002
10027
  const { state } = useCurveEditor();
10003
10028
  const [selectedAnimations, setSelectedAnimations] = useState(() => {
10004
10029
  if (!state.animations) {
@@ -10071,7 +10096,7 @@ const SaveAnimationPanel = ({ onClose: _onClose }) => {
10071
10096
  }) }), jsxs("div", { className: styles.buttons, children: [jsx(Button, { appearance: "primary", onClick: saveToSnippetServer, disabled: selectedAnimations.length === 0 || isSaving, label: isSaving ? "Saving..." : "Save to Snippet Server" }), jsx(Button, { appearance: "secondary", onClick: saveToFile, disabled: selectedAnimations.length === 0, label: "Save to File" })] }), saveError && jsx("div", { className: styles.errorText, children: saveError }), snippetId && jsxs("div", { className: styles.snippetId, children: ["Saved! Snippet ID: ", snippetId] })] }));
10072
10097
  };
10073
10098
 
10074
- const useStyles$u = makeStyles({
10099
+ const useStyles$v = makeStyles({
10075
10100
  root: {
10076
10101
  display: "flex",
10077
10102
  flexDirection: "column",
@@ -10125,7 +10150,7 @@ const useStyles$u = makeStyles({
10125
10150
  * @returns The sidebar component
10126
10151
  */
10127
10152
  const SideBar = () => {
10128
- const styles = useStyles$u();
10153
+ const styles = useStyles$v();
10129
10154
  const { state, actions, observables } = useCurveEditor();
10130
10155
  const [openPopover, setOpenPopover] = useState(null);
10131
10156
  const [fps, setFps] = useState(60);
@@ -11113,7 +11138,7 @@ const KeyPointComponent = (props) => {
11113
11138
  } })] }))] }))] }));
11114
11139
  };
11115
11140
 
11116
- const useStyles$t = makeStyles({
11141
+ const useStyles$u = makeStyles({
11117
11142
  root: {
11118
11143
  position: "absolute",
11119
11144
  top: 0,
@@ -11297,7 +11322,7 @@ function ExtractValuesFromKeys(keys, curves) {
11297
11322
  * @returns The graph component
11298
11323
  */
11299
11324
  const Graph = ({ width, height }) => {
11300
- const styles = useStyles$t();
11325
+ const styles = useStyles$u();
11301
11326
  const { state, actions, observables } = useCurveEditor();
11302
11327
  const svgRef = useRef(null);
11303
11328
  const [scale, setScale] = useState(1);
@@ -11660,7 +11685,7 @@ const Graph = ({ width, height }) => {
11660
11685
  }), renderValueAxis()] })] }));
11661
11686
  };
11662
11687
 
11663
- const useStyles$s = makeStyles({
11688
+ const useStyles$t = makeStyles({
11664
11689
  root: {
11665
11690
  position: "absolute",
11666
11691
  top: 0,
@@ -11703,7 +11728,7 @@ const useStyles$s = makeStyles({
11703
11728
  * @returns The playhead component
11704
11729
  */
11705
11730
  const PlayHead = ({ width, height: _height }) => {
11706
- const styles = useStyles$s();
11731
+ const styles = useStyles$t();
11707
11732
  const { state, actions, observables } = useCurveEditor();
11708
11733
  const [isDragging, setIsDragging] = useState(false);
11709
11734
  // Use refs for all mutable values to avoid render cycles
@@ -11854,7 +11879,7 @@ const PlayHead = ({ width, height: _height }) => {
11854
11879
  return (jsxs("div", { className: styles.root, children: [jsx("div", { ref: lineRef, className: styles.line, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp }), jsx("div", { ref: handleRef, className: styles.handle, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp })] }));
11855
11880
  };
11856
11881
 
11857
- const useStyles$r = makeStyles({
11882
+ const useStyles$s = makeStyles({
11858
11883
  root: {
11859
11884
  display: "flex",
11860
11885
  flexDirection: "row",
@@ -11886,7 +11911,7 @@ const useStyles$r = makeStyles({
11886
11911
  * @returns The frame bar component
11887
11912
  */
11888
11913
  const FrameBar = ({ width }) => {
11889
- const styles = useStyles$r();
11914
+ const styles = useStyles$s();
11890
11915
  const { state, observables } = useCurveEditor();
11891
11916
  const containerRef = useRef(null);
11892
11917
  const [scale, setScale] = useState(1);
@@ -11915,7 +11940,7 @@ const FrameBar = ({ width }) => {
11915
11940
  return ticks;
11916
11941
  }
11917
11942
  // Determine tick spacing based on zoom level
11918
- let tickSpacing = 10;
11943
+ let tickSpacing;
11919
11944
  if (range > 500) {
11920
11945
  tickSpacing = 100;
11921
11946
  }
@@ -11944,7 +11969,7 @@ const FrameBar = ({ width }) => {
11944
11969
  return (jsx("div", { className: styles.root, ref: containerRef, children: renderTicks() }));
11945
11970
  };
11946
11971
 
11947
- const useStyles$q = makeStyles({
11972
+ const useStyles$r = makeStyles({
11948
11973
  root: {
11949
11974
  display: "flex",
11950
11975
  flexDirection: "column",
@@ -11985,7 +12010,7 @@ const OFFSET_X = 10;
11985
12010
  * @returns The range frame bar component
11986
12011
  */
11987
12012
  const RangeFrameBar = ({ width }) => {
11988
- const styles = useStyles$q();
12013
+ const styles = useStyles$r();
11989
12014
  const { state, actions, observables } = useCurveEditor();
11990
12015
  const svgRef = useRef(null);
11991
12016
  const [viewWidth, setViewWidth] = useState(width);
@@ -12096,7 +12121,7 @@ const RangeFrameBar = ({ width }) => {
12096
12121
  }), renderKeyframes, renderActiveFrame] }) }));
12097
12122
  };
12098
12123
 
12099
- const useStyles$p = makeStyles({
12124
+ const useStyles$q = makeStyles({
12100
12125
  root: {
12101
12126
  display: "flex",
12102
12127
  flexDirection: "column",
@@ -12128,7 +12153,7 @@ const useStyles$p = makeStyles({
12128
12153
  * @returns The canvas component
12129
12154
  */
12130
12155
  const Canvas = () => {
12131
- const styles = useStyles$p();
12156
+ const styles = useStyles$q();
12132
12157
  const { observables } = useCurveEditor();
12133
12158
  const containerRef = useRef(null);
12134
12159
  const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
@@ -12158,7 +12183,7 @@ const Canvas = () => {
12158
12183
  return (jsxs("div", { className: styles.root, ref: containerRef, children: [jsx("div", { className: styles.frameBar, children: jsx(FrameBar, { width: dimensions.width }) }), jsxs("div", { className: styles.canvasArea, children: [jsx(Graph, { width: dimensions.width, height: dimensions.height - 70 }), jsx(PlayHead, { width: dimensions.width, height: dimensions.height - 70 })] }), jsx("div", { className: styles.rangeFrameBar, children: jsx(RangeFrameBar, { width: dimensions.width }) })] }));
12159
12184
  };
12160
12185
 
12161
- const useStyles$o = makeStyles({
12186
+ const useStyles$p = makeStyles({
12162
12187
  root: {
12163
12188
  flex: 1,
12164
12189
  height: "25px",
@@ -12220,7 +12245,7 @@ const useStyles$o = makeStyles({
12220
12245
  * @returns The range selector component
12221
12246
  */
12222
12247
  const RangeSelector = () => {
12223
- const styles = useStyles$o();
12248
+ const styles = useStyles$p();
12224
12249
  const { state, actions, observables } = useCurveEditor();
12225
12250
  const containerRef = useRef(null);
12226
12251
  const scrollbarRef = useRef(null);
@@ -12365,7 +12390,7 @@ function GetKeyAtAnyFrameIndex(animations, frame) {
12365
12390
  }
12366
12391
  return false;
12367
12392
  }
12368
- const useStyles$n = makeStyles({
12393
+ const useStyles$o = makeStyles({
12369
12394
  root: {
12370
12395
  display: "flex",
12371
12396
  flexDirection: "row",
@@ -12422,7 +12447,7 @@ MediaControls.displayName = "MediaControls";
12422
12447
  * @returns The BottomBar component.
12423
12448
  */
12424
12449
  const BottomBar = () => {
12425
- const styles = useStyles$n();
12450
+ const styles = useStyles$o();
12426
12451
  const { state, actions, observables } = useCurveEditor();
12427
12452
  // Track display frame separately for smooth updates during playback
12428
12453
  const [displayFrame, setDisplayFrame] = useState(state.activeFrame);
@@ -12537,7 +12562,7 @@ const BottomBar = () => {
12537
12562
  return (jsxs("div", { className: styles.root, children: [jsx("div", { className: styles.mediaControls, children: jsx(MediaControls, { hasActiveAnimations: hasActiveAnimations, isPlaying: state.isPlaying, forwardAnimation: state.forwardAnimation, onPlayForward: handlePlayForward, onPlayBackward: handlePlayBackward, onStop: handleStop, onPrevKey: handlePrevKey, onNextKey: handleNextKey, onFirstFrame: handleFirstFrame, onLastFrame: handleLastFrame }) }), jsxs("div", { className: styles.frameDisplay, children: [jsx("div", { className: styles.frameLabel, children: "Frame:" }), jsx(SpinButton, { className: styles.spinButton, value: displayFrame, onChange: handleFrameChange, min: state.fromKey, max: state.toKey, disabled: !hasActiveAnimations })] }), jsx(RangeSelector, {}), jsxs("div", { className: styles.clipLengthSection, children: [jsx("div", { className: styles.frameLabel, children: "Clip Length:" }), jsx(SpinButton, { className: styles.spinButton, value: clipLength, onChange: handleClipLengthChange, min: 1, disabled: !hasActiveAnimations })] })] }));
12538
12563
  };
12539
12564
 
12540
- const useStyles$m = makeStyles({
12565
+ const useStyles$n = makeStyles({
12541
12566
  root: {
12542
12567
  display: "flex",
12543
12568
  flexDirection: "column",
@@ -12586,7 +12611,7 @@ const useStyles$m = makeStyles({
12586
12611
  * @returns The curve editor content
12587
12612
  */
12588
12613
  const CurveEditorContent = () => {
12589
- const styles = useStyles$m();
12614
+ const styles = useStyles$n();
12590
12615
  const { state, actions, observables } = useCurveEditor();
12591
12616
  const rootRef = useRef(null);
12592
12617
  const prepareRef = useRef(() => actions.prepare());
@@ -13973,7 +13998,7 @@ async function EditNodeMaterial(material) {
13973
13998
  await material.edit({ nodeEditorConfig: { backgroundColor: material.getScene().clearColor } });
13974
13999
  }
13975
14000
 
13976
- const useStyles$l = makeStyles({
14001
+ const useStyles$m = makeStyles({
13977
14002
  subsection: {
13978
14003
  marginTop: tokens.spacingVerticalM,
13979
14004
  },
@@ -14047,7 +14072,7 @@ const GradientBlockPropertyLine = (props) => {
14047
14072
  };
14048
14073
  const NodeMaterialInputProperties = (props) => {
14049
14074
  const { material } = props;
14050
- const classes = useStyles$l();
14075
+ const classes = useStyles$m();
14051
14076
  const inputBlocks = useObservableState(useCallback(() => {
14052
14077
  const inspectorVisibleInputBlocks = material
14053
14078
  .getInputBlocks()
@@ -14269,7 +14294,7 @@ const OpenPBRMaterialGeometryProperties = (props) => {
14269
14294
  } })] }));
14270
14295
  };
14271
14296
 
14272
- const useStyles$k = makeStyles({
14297
+ const useStyles$l = makeStyles({
14273
14298
  root: {
14274
14299
  display: "grid",
14275
14300
  gridTemplateRows: "repeat(1fr)",
@@ -14278,8 +14303,8 @@ const useStyles$k = makeStyles({
14278
14303
  maxWidth: "400px",
14279
14304
  },
14280
14305
  comboBox: {
14281
- width: CustomTokens.inputWidth,
14282
- minWidth: CustomTokens.inputWidth,
14306
+ width: CustomTokens.valueWidth,
14307
+ minWidth: CustomTokens.valueWidth,
14283
14308
  boxSizing: "border-box",
14284
14309
  },
14285
14310
  input: {
@@ -14299,7 +14324,7 @@ const useStyles$k = makeStyles({
14299
14324
  const ComboBox = forwardRef((props, ref) => {
14300
14325
  ComboBox.displayName = "ComboBox";
14301
14326
  const comboId = useId();
14302
- const styles = useStyles$k();
14327
+ const styles = useStyles$l();
14303
14328
  const { size } = useContext(ToolContext);
14304
14329
  // Find the label for the current value
14305
14330
  const getLabel = (value) => props.options.find((opt) => opt.value === value)?.label ?? "";
@@ -14322,7 +14347,7 @@ const ComboBox = forwardRef((props, ref) => {
14322
14347
  return (jsxs("div", { className: styles.root, children: [jsx("label", { id: comboId, children: props.label }), jsx(Combobox, { ref: ref, defaultOpen: props.defaultOpen, size: size, root: { className: styles.comboBox }, input: { className: styles.input }, listbox: { className: styles.listbox }, onOptionSelect: onOptionSelect, "aria-labelledby": comboId, placeholder: "Search..", onChange: (ev) => setQuery(ev.target.value), value: query, children: children })] }));
14323
14348
  });
14324
14349
 
14325
- const useStyles$j = makeStyles({
14350
+ const useStyles$k = makeStyles({
14326
14351
  linkDiv: {
14327
14352
  display: "flex",
14328
14353
  flexDirection: "row",
@@ -14347,7 +14372,7 @@ const useStyles$j = makeStyles({
14347
14372
  function EntitySelector(props) {
14348
14373
  const { value, onLink, getEntities, getName, filter, defaultValue } = props;
14349
14374
  const onChange = props.onChange;
14350
- const classes = useStyles$j();
14375
+ const classes = useStyles$k();
14351
14376
  const comboBoxRef = useRef(null);
14352
14377
  // Build options with uniqueId as key
14353
14378
  const options = useMemo(() => {
@@ -14479,7 +14504,7 @@ const TextureUpload = (props) => {
14479
14504
  return jsx(UploadButton, { onUpload: handleUpload, accept: accept, title: "Upload Texture", label: label });
14480
14505
  };
14481
14506
 
14482
- const useStyles$i = makeStyles({
14507
+ const useStyles$j = makeStyles({
14483
14508
  container: {
14484
14509
  display: "flex",
14485
14510
  flexDirection: "row",
@@ -14496,7 +14521,7 @@ const useStyles$i = makeStyles({
14496
14521
  const TextureSelector = (props) => {
14497
14522
  TextureSelector.displayName = "TextureSelector";
14498
14523
  const { scene, cubeOnly, value, onChange, onLink, defaultValue } = props;
14499
- const classes = useStyles$i();
14524
+ const classes = useStyles$j();
14500
14525
  const getTextures = useCallback(() => scene.textures, [scene.textures]);
14501
14526
  const getName = useCallback((texture) => texture.displayName || texture.name || `${texture.getClassName() || "Unnamed Texture"} (${texture.uniqueId})`, []);
14502
14527
  const filter = useCallback((texture) => !cubeOnly || texture.isCube, [cubeOnly]);
@@ -15087,7 +15112,7 @@ function SaveMetadata(entity, metadata) {
15087
15112
  entity.metadata = metadata;
15088
15113
  }
15089
15114
  }
15090
- const useStyles$h = makeStyles({
15115
+ const useStyles$i = makeStyles({
15091
15116
  mainDiv: {
15092
15117
  display: "flex",
15093
15118
  flexDirection: "column",
@@ -15107,7 +15132,7 @@ const useStyles$h = makeStyles({
15107
15132
  */
15108
15133
  const MetadataProperties = (props) => {
15109
15134
  const { entity } = props;
15110
- const classes = useStyles$h();
15135
+ const classes = useStyles$i();
15111
15136
  const { size } = useContext(ToolContext);
15112
15137
  const metadata = useProperty(entity, "metadata");
15113
15138
  const stringifiedMetadata = useMemo(() => StringifyMetadata(metadata, false) ?? "", [metadata]);
@@ -15653,7 +15678,7 @@ async function SaveToSnippetServer(config) {
15653
15678
  catch (e) {
15654
15679
  const errorMsg = `Unable to save your ${entityName ?? "content"}: ${e}`;
15655
15680
  alert(errorMsg);
15656
- throw new Error(errorMsg);
15681
+ throw new Error(errorMsg, { cause: e });
15657
15682
  }
15658
15683
  if (!response.ok) {
15659
15684
  const errorMsg = `Unable to save your ${entityName ?? "content"}`;
@@ -16051,7 +16076,7 @@ function useObservableArray(target, getItems, addFn, removeFn, changeFn) {
16051
16076
  }, [getItems]), useInterceptObservable("function", target, addFn), useInterceptObservable("function", target, removeFn), changeFn ? useInterceptObservable("function", target, changeFn) : undefined);
16052
16077
  }
16053
16078
 
16054
- const useStyles$g = makeStyles({
16079
+ const useStyles$h = makeStyles({
16055
16080
  subsection: {
16056
16081
  marginTop: tokens.spacingVerticalM,
16057
16082
  },
@@ -16071,7 +16096,7 @@ const ParticleSystemSizeProperties = (props) => {
16071
16096
  const sizeGradientGetter = useCallback(() => system.getSizeGradients(), [system]);
16072
16097
  const sizeGradient = useObservableArray(system, sizeGradientGetter, "addSizeGradient", "removeSizeGradient", "forceRefreshGradients");
16073
16098
  const useSizeGradients = (sizeGradient?.length ?? 0) > 0;
16074
- const classes = useStyles$g();
16099
+ const classes = useStyles$h();
16075
16100
  return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Min size", target: system, propertyKey: "minSize", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Max size", target: system, propertyKey: "maxSize", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Min scale x", target: system, propertyKey: "minScaleX", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Max scale x", target: system, propertyKey: "maxScaleX", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Min scale y", target: system, propertyKey: "minScaleY", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Max scale y", target: system, propertyKey: "maxScaleY", min: 0, step: 0.1 }), isCpuParticleSystem && !useStartSizeGradients && (jsx(ButtonLine, { label: "Use Start Size gradients", onClick: () => {
16076
16101
  system.addStartSizeGradient(0, system.minSize, system.maxSize);
16077
16102
  system.forceRefreshGradients();
@@ -16107,7 +16132,7 @@ const ParticleSystemSizeProperties = (props) => {
16107
16132
  } })] }))] }));
16108
16133
  };
16109
16134
 
16110
- const useStyles$f = makeStyles({
16135
+ const useStyles$g = makeStyles({
16111
16136
  subsection: {
16112
16137
  marginTop: tokens.spacingVerticalM,
16113
16138
  },
@@ -16133,7 +16158,7 @@ const ParticleSystemEmissionProperties = (props) => {
16133
16158
  const useVelocityGradients = (velocityGradients?.length ?? 0) > 0;
16134
16159
  const useLimitVelocityGradients = (limitVelocityGradients?.length ?? 0) > 0;
16135
16160
  const useDragGradients = (dragGradients?.length ?? 0) > 0;
16136
- const classes = useStyles$f();
16161
+ const classes = useStyles$g();
16137
16162
  return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Emit rate", target: system, propertyKey: "emitRate", min: 0, step: 1 }), isCpuParticleSystem && !useEmitRateGradients && (jsx(ButtonLine, { label: "Use Emit rate gradients", onClick: () => {
16138
16163
  system.addEmitRateGradient(0, system.emitRate, system.emitRate);
16139
16164
  system.forceRefreshGradients();
@@ -16201,7 +16226,7 @@ const ParticleSystemEmissionProperties = (props) => {
16201
16226
  } })] }))] }));
16202
16227
  };
16203
16228
 
16204
- const useStyles$e = makeStyles({
16229
+ const useStyles$f = makeStyles({
16205
16230
  subsection: {
16206
16231
  marginTop: tokens.spacingVerticalM,
16207
16232
  },
@@ -16218,7 +16243,7 @@ const ParticleSystemLifetimeProperties = (props) => {
16218
16243
  const lifeTimeGradientsGetter = useCallback(() => system.getLifeTimeGradients(), [system]);
16219
16244
  const lifeTimeGradients = useObservableArray(system, lifeTimeGradientsGetter, "addLifeTimeGradient", "removeLifeTimeGradient", "forceRefreshGradients");
16220
16245
  const useLifeTimeGradients = (lifeTimeGradients?.length ?? 0) > 0;
16221
- const classes = useStyles$e();
16246
+ const classes = useStyles$f();
16222
16247
  return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Min lifetime", target: system, propertyKey: "minLifeTime", min: 0, step: 0.1 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Max lifetime", target: system, propertyKey: "maxLifeTime", min: 0, step: 0.1 }), isCpuParticleSystem && !useLifeTimeGradients && (jsx(ButtonLine, { label: "Use Lifetime gradients", onClick: () => {
16223
16248
  system.addLifeTimeGradient(0, system.minLifeTime, system.maxLifeTime);
16224
16249
  system.forceRefreshGradients();
@@ -16238,7 +16263,7 @@ const ParticleSystemLifetimeProperties = (props) => {
16238
16263
  } })] })), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Target stop duration", target: system, propertyKey: "targetStopDuration", min: 0, step: 0.1 })] }));
16239
16264
  };
16240
16265
 
16241
- const useStyles$d = makeStyles({
16266
+ const useStyles$e = makeStyles({
16242
16267
  subsection: {
16243
16268
  marginTop: tokens.spacingVerticalM,
16244
16269
  },
@@ -16265,7 +16290,7 @@ const ParticleSystemColorProperties = (props) => {
16265
16290
  const hasRampGradients = (rampGradients?.length ?? 0) > 0;
16266
16291
  const hasColorRemapGradients = (colorRemapGradients?.length ?? 0) > 0;
16267
16292
  const hasAlphaRemapGradients = (alphaRemapGradients?.length ?? 0) > 0;
16268
- const classes = useStyles$d();
16293
+ const classes = useStyles$e();
16269
16294
  return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: Color4PropertyLine, label: "Color 1", target: system, propertyKey: "color1" }), jsx(BoundProperty, { component: Color4PropertyLine, label: "Color 2", target: system, propertyKey: "color2" }), jsx(BoundProperty, { component: Color4PropertyLine, label: "Color dead", target: system, propertyKey: "colorDead" }), !hasColorGradients && (jsx(ButtonLine, { label: "Use Color gradients", onClick: () => {
16270
16295
  system.addColorGradient(0, system.color1, system.color1);
16271
16296
  system.addColorGradient(1, system.color2, system.color2);
@@ -16337,7 +16362,7 @@ const ParticleSystemColorProperties = (props) => {
16337
16362
  } })] }))] }))] }));
16338
16363
  };
16339
16364
 
16340
- const useStyles$c = makeStyles({
16365
+ const useStyles$d = makeStyles({
16341
16366
  subsection: {
16342
16367
  marginTop: tokens.spacingVerticalM,
16343
16368
  },
@@ -16352,7 +16377,7 @@ const ParticleSystemRotationProperties = (props) => {
16352
16377
  const angularSpeedGradientsGetter = useCallback(() => system.getAngularSpeedGradients(), [system]);
16353
16378
  const angularSpeedGradients = useObservableArray(system, angularSpeedGradientsGetter, "addAngularSpeedGradient", "removeAngularSpeedGradient", "forceRefreshGradients");
16354
16379
  const useAngularSpeedGradients = (angularSpeedGradients?.length ?? 0) > 0;
16355
- const classes = useStyles$c();
16380
+ const classes = useStyles$d();
16356
16381
  return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Min Angular speed", target: system, propertyKey: "minAngularSpeed", step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Max Angular speed", target: system, propertyKey: "maxAngularSpeed", step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Min initial rotation", target: system, propertyKey: "minInitialRotation", step: 0.01 }), jsx(BoundProperty, { component: NumberInputPropertyLine, label: "Max initial rotation", target: system, propertyKey: "maxInitialRotation", step: 0.01 }), !useAngularSpeedGradients && (jsx(ButtonLine, { label: "Use Angular speed gradients", onClick: () => {
16357
16382
  system.addAngularSpeedGradient(0, system.minAngularSpeed, system.maxAngularSpeed);
16358
16383
  system.forceRefreshGradients();
@@ -16458,7 +16483,7 @@ const AttractorComponent = (props) => {
16458
16483
  } }), !attractorData.isReadOnly && (jsx(ToggleButton, { title: "Add / remove position gizmo from particle attractor", checkedIcon: ArrowMoveFilled, value: isControlled(impostor), onChange: (control) => onControl(control ? impostor : undefined) }))] }));
16459
16484
  };
16460
16485
 
16461
- const useStyles$b = makeStyles({
16486
+ const useStyles$c = makeStyles({
16462
16487
  subsection: {
16463
16488
  marginTop: tokens.spacingVerticalM,
16464
16489
  },
@@ -16515,7 +16540,7 @@ const AttractorList = (props) => {
16515
16540
  gizmoManager.attachToMesh(attached);
16516
16541
  setControlledImpostor(attached);
16517
16542
  };
16518
- const classes = useStyles$b();
16543
+ const classes = useStyles$c();
16519
16544
  return (jsxs(Fragment, { children: [items.length > 0 && (jsxs(Fragment, { children: [jsx(Color3PropertyLine, { label: "Attractor Debug Color", value: impostorColor, onChange: setImpostorColor }), jsx(SyncedSliderPropertyLine, { label: "Attractor Debug Size", value: impostorScale, onChange: setImpostorScale, min: 0, max: 10, step: 0.1 }), jsx(Subtitle2, { className: classes.subsection, children: "Attractors list" })] })), jsx(List, { addButtonLabel: `Add New Attractor`, items: items, onDelete: attractorSource.removeAttractor
16520
16545
  ? (item, _index) => {
16521
16546
  // Only CPU attractors (Attractor instances) can be removed
@@ -16625,7 +16650,7 @@ const ParticleSystemAttractorProperties = (props) => {
16625
16650
  return (jsx(Fragment, { children: scene ? (jsx(AttractorList, { attractorSource: attractorSource, scene: scene })) : (jsx(MessageBar, { intent: "info", title: "No Scene Available", message: "Cannot display attractors without a scene" })) }));
16626
16651
  };
16627
16652
 
16628
- const useStyles$a = makeStyles({
16653
+ const useStyles$b = makeStyles({
16629
16654
  subsection: {
16630
16655
  marginTop: tokens.spacingVerticalM,
16631
16656
  },
@@ -16679,7 +16704,7 @@ const InputBlockPropertyLine = (props) => {
16679
16704
  */
16680
16705
  const ParticleSystemNodeEditorProperties = (props) => {
16681
16706
  const { particleSystem: system } = props;
16682
- const classes = useStyles$a();
16707
+ const classes = useStyles$b();
16683
16708
  const source = system.source;
16684
16709
  const inputBlocks = useObservableState(useCallback(() => {
16685
16710
  if (!source) {
@@ -17576,9 +17601,15 @@ const SkeletonPropertiesServiceDefinition = {
17576
17601
  },
17577
17602
  };
17578
17603
 
17604
+ const useStyles$a = makeStyles({
17605
+ uniformWidth: {
17606
+ ...UniformWidthStyling,
17607
+ },
17608
+ });
17579
17609
  const SpinButtonPropertyLine = (props) => {
17580
17610
  SpinButtonPropertyLine.displayName = "SpinButtonPropertyLine";
17581
- return (jsx(PropertyLine, { ...props, children: jsx(SpinButton, { ...props }) }));
17611
+ const classes = useStyles$a();
17612
+ return (jsx(PropertyLine, { ...props, children: jsx(SpinButton, { ...props, className: mergeClasses(classes.uniformWidth, props.className) }) }));
17582
17613
  };
17583
17614
 
17584
17615
  const SnippetDashboardStorageKey = "Babylon/InspectorV2/SnippetDashboard/SpriteManagers";
@@ -17862,7 +17893,7 @@ function useMaxCellCount(sprite) {
17862
17893
  const manager = sprite.manager;
17863
17894
  const texture = useProperty(manager, "texture");
17864
17895
  const textureSize = texture.getSize();
17865
- let maxCellCount = 0;
17896
+ let maxCellCount;
17866
17897
  if (!textureSize.width || !textureSize.height) {
17867
17898
  maxCellCount = Math.max(sprite.fromIndex, sprite.toIndex);
17868
17899
  }
@@ -19984,7 +20015,7 @@ const AnimationGroupExplorerServiceDefinition = {
19984
20015
  const nameHookToken = watcherService.watchProperty(namedEntity, "name", () => onChangeObservable.notifyObservers());
19985
20016
  return {
19986
20017
  get name() {
19987
- return namedEntity.name;
20018
+ return namedEntity.name || "Unnamed AnimationGroup";
19988
20019
  },
19989
20020
  onChange: onChangeObservable,
19990
20021
  dispose: () => {
@@ -20062,7 +20093,7 @@ const AtmosphereExplorerServiceDefinition = {
20062
20093
  const nameHookToken = watcherService.watchProperty(atmosphere, "name", () => onChangeObservable.notifyObservers());
20063
20094
  return {
20064
20095
  get name() {
20065
- return atmosphere.name;
20096
+ return atmosphere.name || `Unnamed ${atmosphere.getClassName()}`;
20066
20097
  },
20067
20098
  onChange: onChangeObservable,
20068
20099
  dispose: () => {
@@ -20133,7 +20164,7 @@ const EffectLayerExplorerServiceDefinition = {
20133
20164
  const nameHookToken = watcherService.watchProperty(effectLayer, "name", () => onChangeObservable.notifyObservers());
20134
20165
  return {
20135
20166
  get name() {
20136
- return effectLayer.name;
20167
+ return effectLayer.name || `Unnamed ${effectLayer.getClassName()}`;
20137
20168
  },
20138
20169
  onChange: onChangeObservable,
20139
20170
  dispose: () => {
@@ -20171,7 +20202,7 @@ const FrameGraphExplorerServiceDefinition = {
20171
20202
  const nameHookToken = watcherService.watchProperty(frameGraph, "name", () => onChangeObservable.notifyObservers());
20172
20203
  return {
20173
20204
  get name() {
20174
- return frameGraph.name;
20205
+ return frameGraph.name || `Unnamed ${frameGraph.getClassName()}`;
20175
20206
  },
20176
20207
  onChange: onChangeObservable,
20177
20208
  dispose: () => {
@@ -20300,10 +20331,10 @@ const GuiExplorerServiceDefinition = {
20300
20331
  return {
20301
20332
  get name() {
20302
20333
  if (IsAdvancedDynamicTexture(entity)) {
20303
- return entity.name;
20334
+ return entity.name || `Unnamed ${entity.getClassName()}`;
20304
20335
  }
20305
20336
  else {
20306
- return `${entity.name ?? "No name"} [${entity.getClassName()}]`;
20337
+ return `${entity.name || "Unnamed"} [${entity.getClassName()}]`;
20307
20338
  }
20308
20339
  },
20309
20340
  onChange: onChangeObservable,
@@ -20408,7 +20439,7 @@ const MaterialExplorerServiceDefinition = {
20408
20439
  const nameHookToken = watcherService.watchProperty(material, "name", () => onChangeObservable.notifyObservers());
20409
20440
  return {
20410
20441
  get name() {
20411
- return material.name;
20442
+ return material.name || `Unnamed ${material.getClassName()}`;
20412
20443
  },
20413
20444
  onChange: onChangeObservable,
20414
20445
  dispose: () => {
@@ -20443,6 +20474,9 @@ const MaterialExplorerServiceDefinition = {
20443
20474
  },
20444
20475
  };
20445
20476
 
20477
+ function IsCameraFrameGraphTask(task) {
20478
+ return task.camera instanceof Camera;
20479
+ }
20446
20480
  const NodeExplorerServiceDefinition = {
20447
20481
  friendlyName: "Node Explorer",
20448
20482
  consumes: [SceneExplorerServiceIdentity, SceneContextIdentity, GizmoServiceIdentity, WatcherServiceIdentity],
@@ -20489,7 +20523,7 @@ const NodeExplorerServiceDefinition = {
20489
20523
  const parentHookToken = watcherService.watchProperty(node, "parent", () => nodeMovedObservable.notifyObservers(node));
20490
20524
  return {
20491
20525
  get name() {
20492
- return node.name;
20526
+ return node.name || `Unnamed ${node.getClassName()}`;
20493
20527
  },
20494
20528
  onChange: onChangeObservable,
20495
20529
  dispose: () => {
@@ -20622,16 +20656,30 @@ const NodeExplorerServiceDefinition = {
20622
20656
  set isEnabled(enabled) {
20623
20657
  const activeCamera = getActiveCamera();
20624
20658
  if (enabled && activeCamera !== camera) {
20625
- activeCamera?.detachControl();
20626
20659
  if (scene.frameGraph) {
20627
- const objectRenderer = FindMainObjectRenderer(scene.frameGraph);
20628
- if (objectRenderer) {
20629
- objectRenderer.camera = camera;
20630
- onChangeObservable.notifyObservers(); // manual trigger, because scene.onActiveCameraChanged won't be triggered by the line above
20631
- camera.attachControl(true);
20632
- }
20660
+ void (async (frameGraph) => {
20661
+ let updated = false;
20662
+ const nrg = frameGraph.getLinkedNodeRenderGraph();
20663
+ if (nrg) {
20664
+ updated = await nrg.replaceCameraAsync(activeCamera, camera);
20665
+ }
20666
+ else {
20667
+ for (const task of frameGraph.tasks) {
20668
+ if (IsCameraFrameGraphTask(task)) {
20669
+ task.camera = camera;
20670
+ updated = true;
20671
+ }
20672
+ }
20673
+ }
20674
+ if (updated) {
20675
+ activeCamera?.detachControl();
20676
+ camera.attachControl(true);
20677
+ onChangeObservable.notifyObservers();
20678
+ }
20679
+ })(scene.frameGraph);
20633
20680
  }
20634
20681
  else {
20682
+ activeCamera?.detachControl();
20635
20683
  scene.activeCamera = camera;
20636
20684
  camera.attachControl(true);
20637
20685
  }
@@ -20756,7 +20804,7 @@ const ParticleSystemExplorerServiceDefinition = {
20756
20804
  const nameHookToken = watcherService.watchProperty(particleSystem, "name", () => onChangeObservable.notifyObservers());
20757
20805
  return {
20758
20806
  get name() {
20759
- return particleSystem.name;
20807
+ return particleSystem.name || `Unnamed ${particleSystem.getClassName()}`;
20760
20808
  },
20761
20809
  onChange: onChangeObservable,
20762
20810
  dispose: () => {
@@ -20808,7 +20856,7 @@ const PostProcessExplorerServiceDefinition = {
20808
20856
  const nameHookToken = watcherService.watchProperty(postProcess, "name", () => onChangeObservable.notifyObservers());
20809
20857
  return {
20810
20858
  get name() {
20811
- return postProcess.name;
20859
+ return postProcess.name || `Unnamed ${postProcess.getClassName()}`;
20812
20860
  },
20813
20861
  onChange: onChangeObservable,
20814
20862
  dispose: () => {
@@ -20844,8 +20892,7 @@ const RenderingPipelineExplorerServiceDefinition = {
20844
20892
  getEntityDisplayInfo: (pipeline) => {
20845
20893
  return {
20846
20894
  get name() {
20847
- const typeName = pipeline.getClassName();
20848
- return `${pipeline.name} (${typeName})`;
20895
+ return `${pipeline.name || "Unnamed"} [${pipeline.getClassName()}]`;
20849
20896
  },
20850
20897
  };
20851
20898
  },
@@ -20881,7 +20928,7 @@ const SkeletonExplorerServiceDefinition = {
20881
20928
  const parentHookToken = skeletonOrBone instanceof Skeleton ? null : watcherService.watchProperty(skeletonOrBone, "parent", () => boneMovedObservable.notifyObservers(skeletonOrBone));
20882
20929
  return {
20883
20930
  get name() {
20884
- return skeletonOrBone.name;
20931
+ return skeletonOrBone.name || `Unnamed ${skeletonOrBone.getClassName()}`;
20885
20932
  },
20886
20933
  onChange: onChangeObservable,
20887
20934
  dispose: () => {
@@ -20943,7 +20990,7 @@ const SoundExplorerServiceDefinition = {
20943
20990
  const nameHookToken = watcherService.watchProperty(sound, "name", () => onChangeObservable.notifyObservers());
20944
20991
  return {
20945
20992
  get name() {
20946
- return sound.name;
20993
+ return sound.name || `Unnamed ${sound.getClassName()}`;
20947
20994
  },
20948
20995
  onChange: onChangeObservable,
20949
20996
  dispose: () => {
@@ -20987,7 +21034,7 @@ const SpriteManagerExplorerServiceDefinition = {
20987
21034
  const nameHookToken = watcherService.watchProperty(spriteEntity, "name", () => onChangeObservable.notifyObservers());
20988
21035
  return {
20989
21036
  get name() {
20990
- return spriteEntity.name;
21037
+ return spriteEntity.name || `Unnamed ${spriteEntity instanceof Sprite ? spriteEntity.getClassName() : "SpriteManager"}`;
20991
21038
  },
20992
21039
  onChange: onChangeObservable,
20993
21040
  dispose: () => {
@@ -21472,6 +21519,19 @@ const GLTFAnimationImportServiceDefinition = {
21472
21519
  },
21473
21520
  };
21474
21521
 
21522
+ // Options exposed in Inspector includes all the properties from the default loader options (GLTFLoaderDefaultOptions)
21523
+ // plus some options that only exist directly on the GLTFFileLoader class itself.
21524
+ // These are the non-null defaults, used as defaultValue for the nullable property lines.
21525
+ const LoaderOptionDefaults = Object.assign({
21526
+ capturePerformanceCounters: false,
21527
+ loggingEnabled: false,
21528
+ }, { ...GLTFLoaderDefaultOptions });
21529
+ // Non-null defaults for extension options that have properties beyond just 'enabled'.
21530
+ const ExtensionOptionDefaults = {
21531
+ /* eslint-disable @typescript-eslint/naming-convention */
21532
+ MSFT_lod: { maxLODsToLoad: 10 },
21533
+ };
21534
+
21475
21535
  const AnimationStartModeOptions = [
21476
21536
  { label: "None", value: GLTFLoaderAnimationStartMode.NONE },
21477
21537
  { label: "First", value: GLTFLoaderAnimationStartMode.FIRST },
@@ -21482,70 +21542,45 @@ const CoordinateSystemModeOptions = [
21482
21542
  { label: "Right Handed", value: GLTFLoaderCoordinateSystemMode.FORCE_RIGHT_HANDED },
21483
21543
  ];
21484
21544
  const GLTFLoaderOptionsTool = ({ loaderOptions }) => {
21485
- return (jsx(PropertyLine, { label: "Loader Options", expandByDefault: false, expandedContent: jsxs(Fragment, { children: [jsx(BoundProperty, { component: SwitchPropertyLine, label: "Always compute bounding box", target: loaderOptions, propertyKey: "alwaysComputeBoundingBox" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Always compute skeleton root node", target: loaderOptions, propertyKey: "alwaysComputeSkeletonRootNode" }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Animation start mode", options: AnimationStartModeOptions, target: loaderOptions, propertyKey: "animationStartMode" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Capture performance counters", target: loaderOptions, propertyKey: "capturePerformanceCounters" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Compile materials", target: loaderOptions, propertyKey: "compileMaterials" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Compile shadow generators", target: loaderOptions, propertyKey: "compileShadowGenerators" }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Coordinate system", options: CoordinateSystemModeOptions, target: loaderOptions, propertyKey: "coordinateSystemMode" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Create instances", target: loaderOptions, propertyKey: "createInstances" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Enable logging", target: loaderOptions, propertyKey: "loggingEnabled" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Load all materials", target: loaderOptions, propertyKey: "loadAllMaterials" }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Target FPS", target: loaderOptions, propertyKey: "targetFps", min: 1, max: 120, step: 1 }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Transparency as coverage", target: loaderOptions, propertyKey: "transparencyAsCoverage" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use clip plane", target: loaderOptions, propertyKey: "useClipPlane" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use sRGB buffers", target: loaderOptions, propertyKey: "useSRGBBuffers" })] }) }));
21545
+ return (jsx(PropertyLine, { label: "Loader Options", expandByDefault: false, expandedContent: jsxs(Fragment, { children: [jsx(BoundProperty, { component: SwitchPropertyLine, label: "Always compute bounding box", target: loaderOptions, propertyKey: "alwaysComputeBoundingBox", nullable: true, defaultValue: LoaderOptionDefaults.alwaysComputeBoundingBox }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Always compute skeleton root node", target: loaderOptions, propertyKey: "alwaysComputeSkeletonRootNode", nullable: true, defaultValue: LoaderOptionDefaults.alwaysComputeSkeletonRootNode }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Animation start mode", options: AnimationStartModeOptions, target: loaderOptions, propertyKey: "animationStartMode", nullable: true, defaultValue: LoaderOptionDefaults.animationStartMode }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Capture performance counters", target: loaderOptions, propertyKey: "capturePerformanceCounters", nullable: true, defaultValue: LoaderOptionDefaults.capturePerformanceCounters }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Compile materials", target: loaderOptions, propertyKey: "compileMaterials", nullable: true, defaultValue: LoaderOptionDefaults.compileMaterials }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Compile shadow generators", target: loaderOptions, propertyKey: "compileShadowGenerators", nullable: true, defaultValue: LoaderOptionDefaults.compileShadowGenerators }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Coordinate system", options: CoordinateSystemModeOptions, target: loaderOptions, propertyKey: "coordinateSystemMode", nullable: true, defaultValue: LoaderOptionDefaults.coordinateSystemMode }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Create instances", target: loaderOptions, propertyKey: "createInstances", nullable: true, defaultValue: LoaderOptionDefaults.createInstances }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Enable logging", target: loaderOptions, propertyKey: "loggingEnabled", nullable: true, defaultValue: LoaderOptionDefaults.loggingEnabled }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Load all materials", target: loaderOptions, propertyKey: "loadAllMaterials", nullable: true, defaultValue: LoaderOptionDefaults.loadAllMaterials }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Target FPS", target: loaderOptions, propertyKey: "targetFps", min: 1, max: 120, step: 1, nullable: true, defaultValue: LoaderOptionDefaults.targetFps }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Transparency as coverage", target: loaderOptions, propertyKey: "transparencyAsCoverage", nullable: true, defaultValue: LoaderOptionDefaults.transparencyAsCoverage }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use clip plane", target: loaderOptions, propertyKey: "useClipPlane", nullable: true, defaultValue: LoaderOptionDefaults.useClipPlane }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use sRGB buffers", target: loaderOptions, propertyKey: "useSRGBBuffers", nullable: true, defaultValue: LoaderOptionDefaults.useSRGBBuffers })] }) }));
21486
21546
  };
21487
21547
  const GLTFExtensionOptionsTool = ({ extensionOptions }) => {
21488
- return (jsx(PropertyLine, { label: "Extension Options", expandByDefault: false, expandedContent: jsx(Fragment, { children: Object.entries(extensionOptions).map(([extensionName, options]) => {
21489
- return (jsx(BoundProperty, { component: SwitchPropertyLine, label: extensionName, target: options, propertyKey: "enabled", expandedContent: (extensionName === "MSFT_lod" && (jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Maximum LODs", target: extensionOptions[extensionName], propertyKey: "maxLODsToLoad", min: 1, max: 10, step: 1 }, extensionName + "_maxLODsToLoad"))) ||
21548
+ return (jsx(PropertyLine, { label: "Extension Options", expandByDefault: false, expandedContent: jsx(Fragment, { children: Object.entries(extensionOptions)
21549
+ .sort(([a], [b]) => a.localeCompare(b))
21550
+ .map(([extensionName, options]) => {
21551
+ return (jsx(BoundProperty, { component: SwitchPropertyLine, label: extensionName, target: options, propertyKey: "enabled", nullable: true, defaultValue: true, expandedContent: (extensionName === "MSFT_lod" && (jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Maximum LODs", target: extensionOptions[extensionName], propertyKey: "maxLODsToLoad", min: 1, max: 10, step: 1, nullable: true, defaultValue: ExtensionOptionDefaults.MSFT_lod.maxLODsToLoad }, extensionName + "_maxLODsToLoad"))) ||
21490
21552
  undefined }, extensionName));
21491
21553
  }) }) }));
21492
21554
  };
21493
21555
 
21494
- // Options exposed in Inspector includes all the properties from the default loader options (GLTFLoaderDefaultOptions)
21495
- // plus some options that only exist directly on the GLTFFileLoader class itself.
21496
- const CurrentLoaderOptions = Object.assign({
21497
- capturePerformanceCounters: false,
21498
- loggingEnabled: false,
21499
- }, GLTFLoaderDefaultOptions);
21500
- const CurrentExtensionOptions = {
21501
- /* eslint-disable @typescript-eslint/naming-convention */
21502
- EXT_lights_image_based: { enabled: true },
21503
- EXT_mesh_gpu_instancing: { enabled: true },
21504
- EXT_texture_webp: { enabled: true },
21505
- EXT_texture_avif: { enabled: true },
21506
- KHR_draco_mesh_compression: { enabled: true },
21507
- KHR_materials_pbrSpecularGlossiness: { enabled: true },
21508
- KHR_materials_clearcoat: { enabled: true },
21509
- KHR_materials_iridescence: { enabled: true },
21510
- KHR_materials_anisotropy: { enabled: true },
21511
- KHR_materials_emissive_strength: { enabled: true },
21512
- KHR_materials_ior: { enabled: true },
21513
- KHR_materials_sheen: { enabled: true },
21514
- KHR_materials_specular: { enabled: true },
21515
- KHR_materials_unlit: { enabled: true },
21516
- KHR_materials_variants: { enabled: true },
21517
- KHR_materials_transmission: { enabled: true },
21518
- KHR_materials_diffuse_transmission: { enabled: true },
21519
- KHR_materials_volume: { enabled: true },
21520
- KHR_materials_dispersion: { enabled: true },
21521
- KHR_materials_diffuse_roughness: { enabled: true },
21522
- KHR_mesh_quantization: { enabled: true },
21523
- KHR_lights_punctual: { enabled: true },
21524
- EXT_lights_area: { enabled: true },
21525
- KHR_texture_basisu: { enabled: true },
21526
- KHR_texture_transform: { enabled: true },
21527
- KHR_xmp_json_ld: { enabled: true },
21528
- MSFT_lod: { enabled: true, maxLODsToLoad: 10 },
21529
- MSFT_minecraftMesh: { enabled: true },
21530
- MSFT_sRGBFactors: { enabled: true },
21531
- MSFT_audio_emitter: { enabled: true },
21532
- };
21533
21556
  const GLTFLoaderOptionsServiceDefinition = {
21534
21557
  friendlyName: "GLTF Loader Options",
21535
21558
  consumes: [ToolsServiceIdentity],
21536
21559
  factory: (toolsService) => {
21560
+ // Current loader options with nullable properties (null means "don't override the options coming in with load calls")
21561
+ const currentLoaderOptions = Object.fromEntries(Object.keys(LoaderOptionDefaults).map((key) => [key, null]));
21562
+ // Build extension options dynamically from the registered extensions.
21563
+ // Every extension gets an 'enabled' toggle; extensions in ExtensionOptionDefaults also get their extra properties.
21564
+ const currentExtensionOptions = {};
21565
+ for (const extName of registeredGLTFExtensions.keys()) {
21566
+ const defaults = ExtensionOptionDefaults[extName];
21567
+ const extraNulls = defaults ? Object.fromEntries(Object.keys(defaults).map((key) => [key, null])) : {};
21568
+ currentExtensionOptions[extName] = { enabled: null, ...extraNulls };
21569
+ }
21537
21570
  // Subscribe to plugin activation
21538
21571
  const pluginObserver = SceneLoader.OnPluginActivatedObservable.add((plugin) => {
21539
21572
  if (plugin.name === "gltf") {
21540
21573
  const loader = plugin;
21541
- // Apply loader settings
21542
- Object.assign(loader, CurrentLoaderOptions);
21574
+ // Apply loader settings (filter out null values to not override options coming in with load calls)
21575
+ const nonNullLoaderOptions = Object.fromEntries(Object.entries(currentLoaderOptions).filter(([_, v]) => v !== null));
21576
+ Object.assign(loader, nonNullLoaderOptions);
21543
21577
  // Subscribe to extension loading
21544
21578
  loader.onExtensionLoadedObservable.add((extension) => {
21545
- const extensionOptions = CurrentExtensionOptions[extension.name];
21579
+ const extensionOptions = currentExtensionOptions[extension.name];
21546
21580
  if (extensionOptions) {
21547
- // Apply extension settings
21548
- Object.assign(extension, extensionOptions);
21581
+ // Apply extension settings (filter out null values to not override options coming in with load calls)
21582
+ const nonNullExtOptions = Object.fromEntries(Object.entries(extensionOptions).filter(([_, v]) => v !== null));
21583
+ Object.assign(extension, nonNullExtOptions);
21549
21584
  }
21550
21585
  });
21551
21586
  }
@@ -21555,7 +21590,7 @@ const GLTFLoaderOptionsServiceDefinition = {
21555
21590
  section: "GLTF Loader",
21556
21591
  order: 50,
21557
21592
  component: () => {
21558
- return (jsxs(Fragment, { children: [jsx(MessageBar, { intent: "info", message: "Reload the file for changes to take effect" }), jsx(GLTFLoaderOptionsTool, { loaderOptions: CurrentLoaderOptions }), jsx(GLTFExtensionOptionsTool, { extensionOptions: CurrentExtensionOptions })] }));
21593
+ return (jsxs(Fragment, { children: [jsx(MessageBar, { intent: "info", message: "Reload the file for changes to take effect" }), jsx(GLTFLoaderOptionsTool, { loaderOptions: currentLoaderOptions }), jsx(GLTFExtensionOptionsTool, { extensionOptions: currentExtensionOptions })] }));
21559
21594
  },
21560
21595
  });
21561
21596
  return {
@@ -21658,10 +21693,9 @@ const PickingToolbar = (props) => {
21658
21693
  }
21659
21694
  const p0p1 = TmpVectors.Vector3[0];
21660
21695
  const p1p2 = TmpVectors.Vector3[1];
21661
- let normal = TmpVectors.Vector3[2];
21662
21696
  p1.subtractToRef(p0, p0p1);
21663
21697
  p2.subtractToRef(p1, p1p2);
21664
- normal = Vector3.Cross(p0p1, p1p2);
21698
+ const normal = Vector3.Cross(p0p1, p1p2);
21665
21699
  return Vector3.Dot(normal, ray.direction) < 0;
21666
21700
  });
21667
21701
  pickedEntity = pickingInfo.pickedMesh;
@@ -22825,4 +22859,4 @@ const TextAreaPropertyLine = (props) => {
22825
22859
  AttachDebugLayer();
22826
22860
 
22827
22861
  export { HexPropertyLine as $, Accordion as A, Button as B, CheckboxPropertyLine as C, ColorStepGradientComponent as D, ComboBox as E, ComboBoxPropertyLine as F, ConstructorFactory as G, ConvertOptions as H, DebugServiceIdentity as I, DetachDebugLayer as J, DraggableLine as K, LinkToEntity as L, MessageBar as M, NumberInputPropertyLine as N, Dropdown as O, Popover as P, EntitySelector as Q, ErrorBoundary as R, SpinButtonPropertyLine as S, TextInputPropertyLine as T, ExtensibleAccordion as U, Vector3PropertyLine as V, FactorGradientComponent as W, FactorGradientList as X, FileUploadLine as Y, GetPropertyDescriptor as Z, GizmoServiceIdentity as _, useProperty as a, Vector2PropertyLine as a$, InfoLabel as a0, InputHexField as a1, InputHsvField as a2, Inspector as a3, InterceptFunction as a4, InterceptProperty as a5, IsPropertyReadonly as a6, LineContainer as a7, LinkPropertyLine as a8, LinkToEntityPropertyLine as a9, SettingsStoreIdentity as aA, ShowInspector as aB, SidePaneContainer as aC, SkeletonSelector as aD, Slider as aE, SpinButton as aF, StatsServiceIdentity as aG, StringDropdown as aH, StringDropdownPropertyLine as aI, StringifiedPropertyLine as aJ, Switch as aK, SwitchPropertyLine as aL, SyncedSliderInput as aM, SyncedSliderPropertyLine as aN, TeachingMoment as aO, TextAreaPropertyLine as aP, TextInput as aQ, TextPropertyLine as aR, Textarea as aS, TextureSelector as aT, TextureUpload as aU, Theme as aV, ThemeServiceIdentity as aW, ToastProvider as aX, ToggleButton as aY, Tooltip as aZ, UploadButton as a_, List as aa, MakeDialogTeachingMoment as ab, MakeLazyComponent as ac, MakePopoverTeachingMoment as ad, MakePropertyHook as ae, MakeTeachingMoment as af, MaterialSelector as ag, NodeSelector as ah, NumberDropdown as ai, NumberDropdownPropertyLine as aj, ObservableCollection as ak, Pane as al, PlaceholderPropertyLine as am, PositionedPopover as an, PropertiesServiceIdentity as ao, Property as ap, PropertyContext as aq, PropertyLine as ar, QuaternionPropertyLine as as, RotationVectorPropertyLine as at, SceneExplorerServiceIdentity as au, SearchBar as av, SearchBox as aw, SelectionServiceDefinition as ax, SettingsServiceIdentity as ay, SettingsStore as az, ShellServiceIdentity as b, Vector4PropertyLine as b0, WatcherServiceIdentity as b1, useAngleConverters as b2, useAsyncResource as b3, useColor3Property as b4, useColor4Property as b5, useEventListener as b6, useEventfulState as b7, useInterceptObservable as b8, useKeyListener as b9, useKeyState as ba, useObservableCollection as bb, useOrderedObservableCollection as bc, usePollingObservable as bd, usePropertyChangedNotifier as be, useQuaternionProperty as bf, useResource as bg, useSetting as bh, useTheme as bi, useThemeMode as bj, useVector3Property as bk, SceneContextIdentity as c, SelectionServiceIdentity as d, useObservableState as e, AccordionSection as f, ButtonLine as g, ToolsServiceIdentity as h, useExtensionManager as i, Link as j, AccordionSectionItem as k, AttachDebugLayer as l, BooleanBadgePropertyLine as m, BoundProperty as n, BuiltInsExtensionFeed as o, Checkbox as p, ChildWindow as q, Collapse as r, Color3GradientComponent as s, Color3GradientList as t, useToast as u, Color3PropertyLine as v, Color4GradientComponent as w, Color4GradientList as x, Color4PropertyLine as y, ColorPickerPopup as z };
22828
- //# sourceMappingURL=index-DBHYgAua.js.map
22862
+ //# sourceMappingURL=index-CIc0CbG8.js.map