forgecad 0.9.4 → 0.9.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/assets/{AdminPage-jwoEgwE_.js → AdminPage-Da6hhpJx.js} +1 -1
  2. package/dist/assets/{BlogPage-Ck7g3ue2.js → BlogPage-Bl_sKeWb.js} +1 -1
  3. package/dist/assets/{DocsPage-9WaRC14b.js → DocsPage-Blz3Tp4j.js} +1 -6
  4. package/dist/assets/EditorApp-CuiPbtn5.js +12754 -0
  5. package/dist/assets/{EmbedViewer-37_PfMwv.js → EmbedViewer-BFG6-Ufm.js} +2 -2
  6. package/dist/assets/{LandingPageProofDriven-CO8WL0CY.js → LandingPageProofDriven-DB9fQd5P.js} +1 -1
  7. package/dist/assets/{PricingPage-DADKGuOa.js → PricingPage-BMxYT_F0.js} +1 -1
  8. package/dist/assets/{SettingsPage-DKKI4W49.js → SettingsPage-VVQNrCAg.js} +1 -1
  9. package/dist/assets/{app-CwI02pTA.js → app-Dl9ymBWC.js} +355 -36
  10. package/dist/assets/cli/{render-Kw5hLEcL.js → render-CFtwKCCY.js} +203 -862
  11. package/dist/assets/{sectionPlaneMath-C8N0w8o3.js → distance-BEC2RjJi.js} +4150 -801
  12. package/dist/assets/{evalWorker-D6ub3kfS.js → evalWorker-CRvbzTXm.js} +2611 -528
  13. package/dist/assets/{manifold-CwDdMKyc.js → manifold-B9QSr-qP.js} +1 -1
  14. package/dist/assets/{manifold-DTvmxSDf.js → manifold-DpBXFS2K.js} +1 -1
  15. package/dist/assets/{manifold-lru0jwVw.js → manifold-DzZ4VRPs.js} +2 -2
  16. package/dist/assets/{renderSceneState-tvtNKNRi.js → renderSceneState-BuAXF2jh.js} +1 -1
  17. package/dist/assets/{reportWorker-DeqktDGt.js → reportWorker-BNWEnRg1.js} +2606 -525
  18. package/dist/cli/render.html +1 -1
  19. package/dist/docs/index.html +2 -2
  20. package/dist/docs-raw/AI/usage.md +0 -1
  21. package/dist/docs-raw/API/core/concepts.md +11 -1
  22. package/dist/docs-raw/CLI.md +64 -13
  23. package/dist/docs-raw/beta-operations.md +4 -0
  24. package/dist/docs-raw/deployment.md +38 -23
  25. package/dist/docs-raw/generated/assembly.md +8 -3
  26. package/dist/docs-raw/generated/concepts.md +126 -46
  27. package/dist/docs-raw/generated/core.md +97 -47
  28. package/dist/docs-raw/generated/curves.md +113 -595
  29. package/dist/docs-raw/generated/lib.md +40 -3
  30. package/dist/docs-raw/generated/output.md +6 -1
  31. package/dist/docs-raw/generated/sdf.md +50 -4
  32. package/dist/docs-raw/generated/sketch.md +9 -1
  33. package/dist/docs-raw/generated/viewport.md +1 -9
  34. package/dist/docs-raw/guides/inspection-bundles.md +40 -9
  35. package/dist/docs-raw/runbook.md +3 -3
  36. package/dist/docs-raw/skills/forgecad-blockout-model.md +1 -0
  37. package/dist/docs-raw/skills/forgecad-image-replicator.md +3 -1
  38. package/dist/docs-raw/skills/forgecad-make-a-model.md +48 -4
  39. package/dist/docs-raw/skills/forgecad-render-inspect.md +3 -1
  40. package/dist/docs-raw/skills/forgecad-visual-spec.md +2 -0
  41. package/dist/docs-raw/skills/forgecad.md +2 -1
  42. package/dist/docs-raw/skills/index.md +0 -1
  43. package/dist/index.html +1 -1
  44. package/dist/sitemap.xml +6 -6
  45. package/dist-cli/blender/render.py +43 -8
  46. package/dist-cli/forgecad.js +5729 -2015
  47. package/dist-cli/forgecad.js.map +1 -1
  48. package/dist-skill/CONTEXT.md +372 -667
  49. package/dist-skill/SKILL-dev.md +2 -1
  50. package/dist-skill/SKILL.md +2 -1
  51. package/dist-skill/docs/API/core/concepts.md +11 -1
  52. package/dist-skill/docs/CLI.md +64 -13
  53. package/dist-skill/docs/generated/assembly.md +8 -3
  54. package/dist-skill/docs/generated/core.md +97 -47
  55. package/dist-skill/docs/generated/curves.md +113 -595
  56. package/dist-skill/docs/generated/lib.md +40 -3
  57. package/dist-skill/docs/generated/output.md +6 -1
  58. package/dist-skill/docs/generated/sdf.md +50 -4
  59. package/dist-skill/docs/generated/sketch.md +9 -1
  60. package/dist-skill/docs/generated/viewport.md +1 -9
  61. package/dist-skill/docs/guides/inspection-bundles.md +40 -9
  62. package/dist-skill/docs-dev/API/core/concepts.md +11 -1
  63. package/dist-skill/docs-dev/CLI.md +64 -13
  64. package/dist-skill/docs-dev/generated/assembly.md +8 -3
  65. package/dist-skill/docs-dev/generated/core.md +97 -47
  66. package/dist-skill/docs-dev/generated/curves.md +113 -595
  67. package/dist-skill/docs-dev/generated/lib.md +40 -3
  68. package/dist-skill/docs-dev/generated/output.md +6 -1
  69. package/dist-skill/docs-dev/generated/sdf.md +50 -4
  70. package/dist-skill/docs-dev/generated/sketch.md +9 -1
  71. package/dist-skill/docs-dev/generated/viewport.md +1 -9
  72. package/dist-skill/docs-dev/guides/inspection-bundles.md +40 -9
  73. package/dist-skill/library/README.md +0 -1
  74. package/dist-skill/library/forgecad-blockout-model/SKILL.md +1 -0
  75. package/dist-skill/library/forgecad-image-replicator/SKILL.md +3 -1
  76. package/dist-skill/library/forgecad-make-a-model/SKILL.md +48 -4
  77. package/dist-skill/library/forgecad-render-inspect/SKILL.md +3 -1
  78. package/dist-skill/library/forgecad-visual-spec/SKILL.md +2 -0
  79. package/examples/api/drive-wheel-regions.forge.js +43 -0
  80. package/examples/api/guided-loft-olive-oil-bottle.forge.js +135 -0
  81. package/examples/api/sdf-circular-array-knurling.forge.js +19 -0
  82. package/examples/api/sdf-pattern2d-ceramic-ripple-set.forge.js +83 -0
  83. package/examples/api/sdf-pattern2d-grip-tread.forge.js +72 -0
  84. package/examples/api/sdf-pattern2d-orbital-jewelry.forge.js +62 -0
  85. package/examples/api/sdf-surface-basket-weave.forge.js +67 -0
  86. package/examples/api/sector-gear-body.forge.js +34 -0
  87. package/package.json +20 -2
  88. package/dist/assets/EditorApp-Dja2jMmW.js +0 -12509
  89. package/dist/docs-raw/skills/forgecad-api-dogfood.md +0 -130
  90. package/dist-skill/library/forgecad-api-dogfood/SKILL.md +0 -125
@@ -4,7 +4,7 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
5
  var _a2;
6
6
  import { c as create, r as reactExports, j as jsxRuntimeExports, a as createWithEqualityFn, R as React, T as Tb, s as schedulerExports, b as clientExports, d as reactDomExports, u as useParams, e as useSearchParams, f as useNavigate, L as Link, B as BrowserRouter, g as Routes, h as Route, N as Navigate } from "./vendor-react-Da3A2QmU.js";
7
- import { _ as __vitePreload, z as zipSync, s as strToU8, W as WebGLRenderer, R as Raycaster, O as OrthographicCamera$1, P as PerspectiveCamera$1, S as Scene, a as PCFSoftShadowMap, V as VSMShadowMap, b as PCFShadowMap, B as BasicShadowMap, C as ColorManagement, L as LinearSRGBColorSpace, c as SRGBColorSpace, N as NoToneMapping, A as ACESFilmicToneMapping, d as Layers, e as Color, f as RGBAFormat, U as UnsignedByteType, g as Vector3, h as Vector2, i as Clock, T as THREE, D as DoubleSide, j as REVISION, M as Mesh, I as IcosahedronGeometry, k as ShaderMaterial, l as Spherical, Q as Quaternion, m as MOUSE, n as TOUCH, o as Ray, p as Plane, q as DataTextureLoader, H as HalfFloatType, F as FloatType, r as DataUtils, t as LinearFilter, u as RedFormat, v as InstancedBufferGeometry, w as Float32BufferAttribute, x as InstancedInterleavedBuffer, y as InterleavedBufferAttribute, E as WireframeGeometry, G as Box3, J as Sphere, K as UniformsUtils, X as UniformsLib, Y as Vector4, Z as Line3, $ as Matrix4, a0 as MathUtils, a1 as Uniform, a2 as WebGLRenderTarget, a3 as DepthTexture, a4 as BackSide, a5 as ClampToEdgeWrapping, a6 as PlaneGeometry, a7 as UVMapping, a8 as DataTexture, a9 as Texture, aa as MeshBasicMaterial, ab as IntType, ac as ShortType, ad as ByteType, ae as UnsignedIntType, af as Loader, ag as LoadingManager, ah as LinearMipMapLinearFilter, ai as FileLoader, aj as NoBlending, ak as CubeReflectionMapping, al as EquirectangularReflectionMapping, am as CubeTextureLoader, an as WebGLCubeRenderTarget, ao as ConstraintSketch, ap as setSketchPlacement3D, aq as Sketch, ar as PROFILE_BACKEND_MARKER, as as FrozenShape, at as setShapeCompilePlan, au as hasAnyPorts, av as setShapePortsInternal, aw as markShapePortsUsed, ax as setParamOverrides, ay as DEFAULT_ACTIVE_BACKEND, az as isConstraintSketch, aA as updateConstraintValue, aB as getShapeCompilePlan, aC as resolveForgeRenderStyle, aD as publishSolverWasmRunDebug, aE as resolveForgeQualityPreset, aF as resolveImportPath, aG as BufferGeometry, aH as LineBasicMaterial, aI as Line$1, aJ as LineDashedMaterial, aK as DepthStencilFormat, aL as UnsignedInt248Type, aM as MeshNormalMaterial, aN as NearestFilter, aO as BasicDepthPacking, aP as EventDispatcher$1, aQ as NoColorSpace, aR as FrontSide, aS as Material, aT as AlwaysDepth, aU as BufferAttribute, aV as CanvasTexture, aW as Object3D, aX as FogExp2, aY as Fog, aZ as AmbientLight, a_ as HemisphereLight, a$ as SpotLight, b0 as PointLight, b1 as DirectionalLight, b2 as buildShapeFromCompilePlan, b3 as shapeToGeometry, b4 as sketchToSvg, b5 as sketchToDxf, b6 as runScript, b7 as MeshPhysicalMaterial, b8 as LineSegments, b9 as getRenderStylePreset, ba as AdditiveBlending, bb as CatmullRomCurve3, bc as TubeGeometry, bd as MeshStandardMaterial, be as compileSdfNode3, bf as buildSdfRaymarchFragmentShader, bg as SDF_RAYMARCH_PROXY_VERTEX_SHADER, bh as Shape, bi as ShapeGeometry, bj as ShaderLib, bk as CylinderGeometry, bl as parseViewportCameraState, bm as createResolvedExplodeConfig, bn as explodeBoundsCenter, bo as explodeMergeBounds, bp as resolveExplodeDirective, bq as computeExplodeMotion, br as getSketchWorldMatrix, bs as explodeAdd, bt as hasExplodeOverride, bu as resolveExplodeLocalFanDirection, bv as explodeMul, bw as explodeLeafFanStage, bx as normalizeCutPlane, by as toClippingPlane, bz as findJointAnimationClip, bA as resolveJointAnimation, bB as resolveJointViewValues, bC as getShapePorts, bD as getShapeUsedPorts, bE as DEFAULT_VIEW_CONFIG, bF as getKernelFaceNameForTriangle, bG as initKernel, bH as initSolverWasm } from "./sectionPlaneMath-C8N0w8o3.js";
7
+ import { _ as __vitePreload, z as zipSync, s as strToU8, W as WebGLRenderer, R as Raycaster, O as OrthographicCamera$1, P as PerspectiveCamera$1, S as Scene, a as PCFSoftShadowMap, V as VSMShadowMap, b as PCFShadowMap, B as BasicShadowMap, C as ColorManagement, L as LinearSRGBColorSpace, c as SRGBColorSpace, N as NoToneMapping, A as ACESFilmicToneMapping, d as Layers, e as Color, f as RGBAFormat, U as UnsignedByteType, g as Vector3, h as Vector2, i as Clock, T as THREE, D as DoubleSide, j as REVISION, M as Mesh, I as IcosahedronGeometry, k as ShaderMaterial, l as Spherical, Q as Quaternion, m as MOUSE, n as TOUCH, o as Ray, p as Plane, q as DataTextureLoader, H as HalfFloatType, F as FloatType, r as DataUtils, t as LinearFilter, u as RedFormat, v as InstancedBufferGeometry, w as Float32BufferAttribute, x as InstancedInterleavedBuffer, y as InterleavedBufferAttribute, E as WireframeGeometry, G as Box3, J as Sphere, K as UniformsUtils, X as UniformsLib, Y as Vector4, Z as Line3, $ as Matrix4, a0 as MathUtils, a1 as Uniform, a2 as WebGLRenderTarget, a3 as DepthTexture, a4 as BackSide, a5 as ClampToEdgeWrapping, a6 as PlaneGeometry, a7 as UVMapping, a8 as DataTexture, a9 as Texture, aa as MeshBasicMaterial, ab as IntType, ac as ShortType, ad as ByteType, ae as UnsignedIntType, af as Loader, ag as LoadingManager, ah as LinearMipMapLinearFilter, ai as FileLoader, aj as NoBlending, ak as CubeReflectionMapping, al as EquirectangularReflectionMapping, am as CubeTextureLoader, an as WebGLCubeRenderTarget, ao as ConstraintSketch, ap as setSketchPlacement3D, aq as Sketch, ar as PROFILE_BACKEND_MARKER, as as FrozenShape, at as setShapeCompilePlan, au as hasAnyPorts, av as setShapePortsInternal, aw as markShapePortsUsed, ax as setParamOverrides, ay as DEFAULT_ACTIVE_BACKEND, az as isConstraintSketch, aA as updateConstraintValue, aB as getShapeCompilePlan, aC as resolveForgeRenderStyle, aD as publishSolverWasmRunDebug, aE as resolveForgeQualityPreset, aF as resolveImportPath, aG as BufferGeometry, aH as LineBasicMaterial, aI as Line$1, aJ as LineDashedMaterial, aK as DepthStencilFormat, aL as UnsignedInt248Type, aM as MeshNormalMaterial, aN as NearestFilter, aO as BasicDepthPacking, aP as EventDispatcher$1, aQ as NoColorSpace, aR as FrontSide, aS as Material, aT as AlwaysDepth, aU as BufferAttribute, aV as CanvasTexture, aW as Object3D, aX as FogExp2, aY as Fog, aZ as AmbientLight, a_ as HemisphereLight, a$ as SpotLight, b0 as PointLight, b1 as DirectionalLight, b2 as analyzeCollisionIntersections, b3 as shapeToGeometry, b4 as buildShapeFromCompilePlan, b5 as sketchToSvg, b6 as sketchToDxf, b7 as runScript, b8 as MeshPhysicalMaterial, b9 as LineSegments, ba as analyzeThicknessGeometry, bb as analyzeRoughnessGeometry, bc as getRenderStylePreset, bd as AdditiveBlending, be as CatmullRomCurve3, bf as TubeGeometry, bg as MeshStandardMaterial, bh as compileSdfNode3, bi as buildSdfRaymarchFragmentShader, bj as SDF_RAYMARCH_PROXY_VERTEX_SHADER, bk as Shape, bl as ShapeGeometry, bm as ShaderLib, bn as CylinderGeometry, bo as parseViewportCameraState, bp as createResolvedExplodeConfig, bq as explodeBoundsCenter, br as explodeMergeBounds, bs as resolveExplodeDirective, bt as computeExplodeMotion, bu as getSketchWorldMatrix, bv as explodeAdd, bw as hasExplodeOverride, bx as resolveExplodeLocalFanDirection, by as explodeMul, bz as explodeLeafFanStage, bA as normalizeCutPlane, bB as toClippingPlane, bC as findJointAnimationClip, bD as resolveJointAnimation, bE as resolveJointViewValues, bF as getShapePorts, bG as getShapeUsedPorts, bH as DEFAULT_VIEW_CONFIG, bI as getKernelFaceNameForTriangle, bJ as analyzePhysicalConnectivity, bK as analyzeDistanceInspection, bL as initKernel, bM as initSolverWasm } from "./distance-BEC2RjJi.js";
8
8
  function getCsrfToken() {
9
9
  const match = document.cookie.match(/(?:^|;\s*)fc-csrf-token=([^;]+)/);
10
10
  return match == null ? void 0 : match[1];
@@ -856,7 +856,7 @@ function toRGB555(colorHex) {
856
856
  if (!rgb) return 0;
857
857
  return 32768 | rgb.r >> 3 << 10 | rgb.g >> 3 << 5 | rgb.b >> 3;
858
858
  }
859
- function rgbToHex(r2, g2, b2) {
859
+ function rgbToHex$1(r2, g2, b2) {
860
860
  const toHex = (v) => v.toString(16).padStart(2, "0").toUpperCase();
861
861
  return `#${toHex(r2)}${toHex(g2)}${toHex(b2)}`;
862
862
  }
@@ -871,7 +871,7 @@ function buildPure3mfBuffer(objects, options = {}) {
871
871
  if (obj.color) {
872
872
  const rgb = parseHexColor(obj.color);
873
873
  if (rgb) {
874
- const hex = rgbToHex(rgb.r, rgb.g, rgb.b);
874
+ const hex = rgbToHex$1(rgb.r, rgb.g, rgb.b);
875
875
  if (!colorMap.has(hex)) {
876
876
  colorMap.set(hex, colors.length);
877
877
  colors.push({ hex, objectIndices: [] });
@@ -908,7 +908,7 @@ function buildPure3mfBuffer(objects, options = {}) {
908
908
  if (obj.color && hasColors) {
909
909
  const rgb = parseHexColor(obj.color);
910
910
  if (rgb) {
911
- const hex = rgbToHex(rgb.r, rgb.g, rgb.b);
911
+ const hex = rgbToHex$1(rgb.r, rgb.g, rgb.b);
912
912
  const colorIdx = colorMap.get(hex);
913
913
  if (colorIdx !== void 0) {
914
914
  pidAttr = ` pid="${colorgroupId}" pindex="${colorIdx}"`;
@@ -15231,6 +15231,7 @@ function deserializeSceneObject(s) {
15231
15231
  sketchMeta: s.sketchMeta,
15232
15232
  groupName: s.groupName,
15233
15233
  treePath: s.treePath,
15234
+ tags: s.tags,
15234
15235
  serverShapeRef: s.serverShapeRef,
15235
15236
  exactState: s.exactState
15236
15237
  };
@@ -15787,7 +15788,7 @@ const CRASH_COOLDOWN_MS = 2e3;
15787
15788
  class EvalWorkerClient {
15788
15789
  constructor(workerFactory = () => new Worker(new URL(
15789
15790
  /* @vite-ignore */
15790
- "/assets/evalWorker-D6ub3kfS.js",
15791
+ "/assets/evalWorker-CRvbzTXm.js",
15791
15792
  import.meta.url
15792
15793
  ), { type: "module" })) {
15793
15794
  __publicField(this, "worker", null);
@@ -17198,6 +17199,7 @@ function runMetadataToRunResult(metadata) {
17198
17199
  sketchMeta: obj.sketchMeta,
17199
17200
  groupName: obj.groupName,
17200
17201
  treePath: obj.treePath,
17202
+ tags: obj.tags,
17201
17203
  mock: obj.mock,
17202
17204
  serverShapeRef: obj.serverShapeRef,
17203
17205
  exactState: obj.exactState
@@ -17359,6 +17361,18 @@ const initialActive = (() => {
17359
17361
  return fallback;
17360
17362
  })();
17361
17363
  const INITIAL_SAVED = {};
17364
+ const VIEW_INSPECT_CHANNELS = /* @__PURE__ */ new Set([
17365
+ "none",
17366
+ "mask",
17367
+ "connectivity",
17368
+ "distance",
17369
+ "collisions",
17370
+ "thickness",
17371
+ "roughness"
17372
+ ]);
17373
+ function resolveViewInspectChannel(value) {
17374
+ return typeof value === "string" && VIEW_INSPECT_CHANNELS.has(value) ? value : "none";
17375
+ }
17362
17376
  const initialViewPreferences = readViewPreferences();
17363
17377
  const initialPreviewFile = resolvePreviewFile(initialActive, INITIAL_FILES);
17364
17378
  const initialObjectSettingsByFile = (() => {
@@ -17371,6 +17385,16 @@ const initialObjectSettingsByFile = (() => {
17371
17385
  }
17372
17386
  return {};
17373
17387
  })();
17388
+ function hasSceneObjectTag(object, tag) {
17389
+ return (object.tags ?? []).includes(tag);
17390
+ }
17391
+ function defaultSettingsForObject(object) {
17392
+ return {
17393
+ visible: true,
17394
+ opacity: object.mock ? 0.3 : 1,
17395
+ color: object.color || DEFAULT_OBJECT_COLOR
17396
+ };
17397
+ }
17374
17398
  const initialParamSnapshotsByFile = sanitizeParamSnapshotsByFile(
17375
17399
  initialViewPreferences.paramSnapshotsByFile
17376
17400
  );
@@ -18107,6 +18131,12 @@ Switch to LOCAL mode or wait for the server to recover.`,
18107
18131
  writeViewPreferences({ renderMode: mode });
18108
18132
  set({ renderMode: mode });
18109
18133
  },
18134
+ inspectChannel: resolveViewInspectChannel(initialViewPreferences.inspectChannel),
18135
+ setInspectChannel: (channel) => {
18136
+ const next = resolveViewInspectChannel(channel);
18137
+ writeViewPreferences({ inspectChannel: next });
18138
+ set({ inspectChannel: next });
18139
+ },
18110
18140
  projectionMode: initialViewPreferences.projectionMode ?? "perspective",
18111
18141
  setProjectionMode: (mode) => {
18112
18142
  writeViewPreferences({ projectionMode: mode });
@@ -18180,6 +18210,50 @@ Switch to LOCAL mode or wait for the server to recover.`,
18180
18210
  objectSettingsByFile: nextObjectSettingsByFile
18181
18211
  };
18182
18212
  }),
18213
+ hideObjectsWithTag: (tag) => set((s) => {
18214
+ var _a3;
18215
+ const objects = ((_a3 = s.lastValidResult) == null ? void 0 : _a3.objects) ?? [];
18216
+ if (!objects.some((object) => hasSceneObjectTag(object, tag))) return {};
18217
+ let changed = false;
18218
+ const nextObjectSettings = { ...s.objectSettings };
18219
+ objects.forEach((object) => {
18220
+ if (!hasSceneObjectTag(object, tag)) return;
18221
+ const current = nextObjectSettings[object.id] ?? defaultSettingsForObject(object);
18222
+ if (!current.visible) return;
18223
+ nextObjectSettings[object.id] = { ...current, visible: false };
18224
+ changed = true;
18225
+ });
18226
+ if (!changed) return {};
18227
+ const nextObjectSettingsByFile = setObjectSettingsForPreviewFile(s.objectSettingsByFile, s.previewFile, nextObjectSettings);
18228
+ writeViewPreferences({ objectSettingsByFile: nextObjectSettingsByFile });
18229
+ return {
18230
+ objectSettings: nextObjectSettings,
18231
+ objectSettingsByFile: nextObjectSettingsByFile
18232
+ };
18233
+ }),
18234
+ showOnlyObjectsWithTag: (tag) => set((s) => {
18235
+ var _a3;
18236
+ const objects = ((_a3 = s.lastValidResult) == null ? void 0 : _a3.objects) ?? [];
18237
+ if (objects.length === 0) return {};
18238
+ const matchingIds = new Set(objects.filter((object) => hasSceneObjectTag(object, tag)).map((object) => object.id));
18239
+ if (matchingIds.size === 0) return {};
18240
+ let changed = false;
18241
+ const nextObjectSettings = { ...s.objectSettings };
18242
+ objects.forEach((object) => {
18243
+ const visible = matchingIds.has(object.id);
18244
+ const current = nextObjectSettings[object.id] ?? defaultSettingsForObject(object);
18245
+ if (current.visible === visible) return;
18246
+ nextObjectSettings[object.id] = { ...current, visible };
18247
+ changed = true;
18248
+ });
18249
+ if (!changed) return {};
18250
+ const nextObjectSettingsByFile = setObjectSettingsForPreviewFile(s.objectSettingsByFile, s.previewFile, nextObjectSettings);
18251
+ writeViewPreferences({ objectSettingsByFile: nextObjectSettingsByFile });
18252
+ return {
18253
+ objectSettings: nextObjectSettings,
18254
+ objectSettingsByFile: nextObjectSettingsByFile
18255
+ };
18256
+ }),
18183
18257
  setObjectOpacity: (id, opacity) => set((s) => {
18184
18258
  const current = s.objectSettings[id] ?? { visible: true, opacity: 1, color: DEFAULT_OBJECT_COLOR };
18185
18259
  const nextObjectSettings = { ...s.objectSettings, [id]: { ...current, opacity } };
@@ -18385,6 +18459,12 @@ Switch to LOCAL mode or wait for the server to recover.`,
18385
18459
  }
18386
18460
  return { focusedObjectIds: [...state2.focusedObjectIds, id], selectedObjectId: id };
18387
18461
  }),
18462
+ focusObjectsWithTag: (tag) => set((state2) => {
18463
+ var _a3;
18464
+ const ids = (((_a3 = state2.lastValidResult) == null ? void 0 : _a3.objects) ?? []).filter((object) => hasSceneObjectTag(object, tag)).map((object) => object.id);
18465
+ if (ids.length === 0) return {};
18466
+ return { focusedObjectIds: ids, selectedObjectId: ids[0] };
18467
+ }),
18388
18468
  clearFocusedObject: () => set({ focusedObjectIds: [] }),
18389
18469
  hoveredObjectId: null,
18390
18470
  setHoveredObjectId: (id) => set((state2) => state2.hoveredObjectId === id ? state2 : { hoveredObjectId: id }),
@@ -26628,6 +26708,140 @@ function ClippingManager({ active }) {
26628
26708
  }, [gl, active]);
26629
26709
  return null;
26630
26710
  }
26711
+ const COLLISION_SOURCE_OPACITY = 0.22;
26712
+ const COLLISION_SOURCE_COLOR = [180, 200, 220];
26713
+ const COLLISION_HIGHLIGHT_COLOR = [255, 68, 16];
26714
+ const COLLISION_PALETTE = [
26715
+ COLLISION_HIGHLIGHT_COLOR,
26716
+ [0, 204, 255],
26717
+ [255, 214, 0],
26718
+ [66, 220, 120],
26719
+ [255, 76, 196],
26720
+ [142, 106, 255],
26721
+ [255, 145, 48],
26722
+ [86, 232, 202],
26723
+ [210, 245, 60],
26724
+ [255, 120, 120],
26725
+ [80, 150, 255],
26726
+ [190, 110, 60]
26727
+ ];
26728
+ const MASK_PALETTE = [
26729
+ [230, 25, 75],
26730
+ [60, 180, 75],
26731
+ [255, 225, 25],
26732
+ [0, 130, 200],
26733
+ [245, 130, 48],
26734
+ [145, 30, 180],
26735
+ [70, 240, 240],
26736
+ [240, 50, 230],
26737
+ [210, 245, 60],
26738
+ [250, 190, 190],
26739
+ [0, 128, 128],
26740
+ [230, 190, 255],
26741
+ [170, 110, 40],
26742
+ [255, 250, 200],
26743
+ [128, 0, 0],
26744
+ [170, 255, 195],
26745
+ [128, 128, 0],
26746
+ [255, 215, 180],
26747
+ [0, 0, 128],
26748
+ [128, 128, 128]
26749
+ ];
26750
+ const DISTANCE_NEAR_COLOR = [66, 220, 120];
26751
+ const DISTANCE_MID_COLOR = [255, 214, 0];
26752
+ const DISTANCE_FAR_COLOR = [255, 68, 16];
26753
+ const DISTANCE_UNKNOWN_COLOR = [128, 128, 128];
26754
+ function rgbToHex(color2) {
26755
+ return `#${color2.map((value) => value.toString(16).padStart(2, "0")).join("")}`;
26756
+ }
26757
+ function maskRgbForIndex(index) {
26758
+ return MASK_PALETTE[index % MASK_PALETTE.length];
26759
+ }
26760
+ function maskColorForIndex(index) {
26761
+ return rgbToHex(maskRgbForIndex(index));
26762
+ }
26763
+ function collisionColorForIndex(index) {
26764
+ return rgbToHex(COLLISION_PALETTE[(index - 1) % COLLISION_PALETTE.length]);
26765
+ }
26766
+ function lerp$1(a2, b2, t2) {
26767
+ return a2 + (b2 - a2) * Math.max(0, Math.min(1, t2));
26768
+ }
26769
+ function lerpRgb(a2, b2, t2) {
26770
+ return [Math.round(lerp$1(a2[0], b2[0], t2)), Math.round(lerp$1(a2[1], b2[1], t2)), Math.round(lerp$1(a2[2], b2[2], t2))];
26771
+ }
26772
+ function distanceColorForRootDistance(distance, maxDistance) {
26773
+ if (!Number.isFinite(distance)) return rgbToHex(DISTANCE_UNKNOWN_COLOR);
26774
+ if (!Number.isFinite(maxDistance) || maxDistance <= 1e-9) return rgbToHex(DISTANCE_NEAR_COLOR);
26775
+ const t2 = Math.max(0, Math.min(1, distance / maxDistance));
26776
+ if (t2 <= 0.5) return rgbToHex(lerpRgb(DISTANCE_NEAR_COLOR, DISTANCE_MID_COLOR, t2 * 2));
26777
+ return rgbToHex(lerpRgb(DISTANCE_MID_COLOR, DISTANCE_FAR_COLOR, (t2 - 0.5) * 2));
26778
+ }
26779
+ function matrixToCollisionMat4(matrix) {
26780
+ if (!matrix) return void 0;
26781
+ const e2 = matrix.elements;
26782
+ return [e2[0], e2[1], e2[2], e2[3], e2[4], e2[5], e2[6], e2[7], e2[8], e2[9], e2[10], e2[11], e2[12], e2[13], e2[14], e2[15]];
26783
+ }
26784
+ function buildCollisionEntries(objects, objectSettings, objectMatrices) {
26785
+ const entries = [];
26786
+ objects.forEach((obj) => {
26787
+ var _a3;
26788
+ if (!obj.shape) return;
26789
+ if (((_a3 = objectSettings[obj.id]) == null ? void 0 : _a3.visible) === false) return;
26790
+ try {
26791
+ const bb = obj.shape.boundingBox();
26792
+ entries.push({
26793
+ id: obj.id,
26794
+ name: obj.name,
26795
+ shape: obj.shape,
26796
+ min: [bb.min[0], bb.min[1], bb.min[2]],
26797
+ max: [bb.max[0], bb.max[1], bb.max[2]],
26798
+ transform: matrixToCollisionMat4(objectMatrices[obj.id]),
26799
+ groupName: obj.groupName,
26800
+ treePath: obj.treePath,
26801
+ mock: obj.mock
26802
+ });
26803
+ } catch {
26804
+ }
26805
+ });
26806
+ return entries;
26807
+ }
26808
+ function CollisionInspectionOverlay({
26809
+ objects,
26810
+ objectSettings,
26811
+ objectMatrices
26812
+ }) {
26813
+ const collisionGeometries = reactExports.useMemo(() => {
26814
+ const report = analyzeCollisionIntersections(buildCollisionEntries(objects, objectSettings, objectMatrices));
26815
+ return report.collisions.flatMap((collision) => {
26816
+ try {
26817
+ const geometry = shapeToGeometry(collision.shape);
26818
+ return [
26819
+ {
26820
+ id: collision.id,
26821
+ color: collisionColorForIndex(collision.index),
26822
+ solid: geometry.solid,
26823
+ edges: geometry.edges
26824
+ }
26825
+ ];
26826
+ } catch {
26827
+ return [];
26828
+ }
26829
+ });
26830
+ }, [objectMatrices, objectSettings, objects]);
26831
+ reactExports.useEffect(() => {
26832
+ return () => {
26833
+ collisionGeometries.forEach((geometry) => {
26834
+ var _a3;
26835
+ geometry.solid.dispose();
26836
+ (_a3 = geometry.edges) == null ? void 0 : _a3.dispose();
26837
+ });
26838
+ };
26839
+ }, [collisionGeometries]);
26840
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("group", { children: collisionGeometries.map((geometry) => /* @__PURE__ */ jsxRuntimeExports.jsxs("group", { children: [
26841
+ /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: geometry.solid, renderOrder: 20, raycast: () => null, children: /* @__PURE__ */ jsxRuntimeExports.jsx("meshBasicMaterial", { color: geometry.color, depthTest: true, depthWrite: true, toneMapped: false }) }),
26842
+ geometry.edges && /* @__PURE__ */ jsxRuntimeExports.jsx("lineSegments", { geometry: geometry.edges, renderOrder: 21, raycast: () => null, children: /* @__PURE__ */ jsxRuntimeExports.jsx("lineBasicMaterial", { color: "#ffffff", transparent: true, opacity: 0.65, depthTest: false, toneMapped: false }) })
26843
+ ] }, geometry.id)) });
26844
+ }
26631
26845
  function ConstructionGhostOverlay({ matrix }) {
26632
26846
  const ghost = useForgeStore((s) => s.constructionGhost);
26633
26847
  const { solidGeo, edgesGeo } = reactExports.useMemo(() => {
@@ -28852,7 +29066,7 @@ function generateReportInWorker(options) {
28852
29066
  return new Promise((resolve2, reject) => {
28853
29067
  const worker = new Worker(new URL(
28854
29068
  /* @vite-ignore */
28855
- "/assets/reportWorker-DeqktDGt.js",
29069
+ "/assets/reportWorker-BNWEnRg1.js",
28856
29070
  import.meta.url
28857
29071
  ), { type: "module" });
28858
29072
  const cleanup = () => {
@@ -32130,6 +32344,8 @@ function ForgeObject({
32130
32344
  settings,
32131
32345
  renderStyle,
32132
32346
  renderMode,
32347
+ inspectChannel = "none",
32348
+ inspectColor,
32133
32349
  isInteracting,
32134
32350
  matrix,
32135
32351
  isHovered,
@@ -32166,14 +32382,30 @@ function ForgeObject({
32166
32382
  };
32167
32383
  }
32168
32384
  }, [obj.shape]);
32385
+ const inspectionGeo = reactExports.useMemo(() => {
32386
+ if (!solidGeo) return null;
32387
+ try {
32388
+ if (inspectChannel === "thickness") return analyzeThicknessGeometry(solidGeo).geometry;
32389
+ if (inspectChannel === "roughness") return analyzeRoughnessGeometry(solidGeo).geometry;
32390
+ return null;
32391
+ } catch {
32392
+ return null;
32393
+ }
32394
+ }, [inspectChannel, solidGeo]);
32169
32395
  reactExports.useEffect(() => {
32170
32396
  return () => {
32171
32397
  solidGeo == null ? void 0 : solidGeo.dispose();
32172
32398
  edgesGeo == null ? void 0 : edgesGeo.dispose();
32173
32399
  };
32174
32400
  }, [edgesGeo, solidGeo]);
32401
+ reactExports.useEffect(() => {
32402
+ return () => {
32403
+ inspectionGeo == null ? void 0 : inspectionGeo.dispose();
32404
+ };
32405
+ }, [inspectionGeo]);
32175
32406
  if (!solidGeo || !settings.visible) return null;
32176
32407
  const effectiveRenderMode = isInteracting && renderMode === "overlay" ? "solid" : renderMode;
32408
+ const isInspecting = inspectChannel !== "none";
32177
32409
  const renderStylePreset = getRenderStylePreset(renderStyle);
32178
32410
  const materialDefaults = renderStylePreset.material;
32179
32411
  const authoredMaterialOpacity = (_a3 = obj.materialProps) == null ? void 0 : _a3.opacity;
@@ -32185,9 +32417,9 @@ function ForgeObject({
32185
32417
  const materialOpacity = Math.min(meshOpacity, styleOpacity);
32186
32418
  const transmission = authoredMaterialTransmission ?? transparentDefaults.transmission;
32187
32419
  const isTransparent = materialOpacity < 1 || transmission > 0;
32188
- const showSolid = effectiveRenderMode !== "wireframe";
32189
- const showEdges = effectiveRenderMode === "overlay";
32190
- const showWire = effectiveRenderMode === "wireframe";
32420
+ const showSolid = isInspecting || effectiveRenderMode !== "wireframe";
32421
+ const showEdges = !isInspecting && effectiveRenderMode === "overlay";
32422
+ const showWire = !isInspecting && effectiveRenderMode === "wireframe";
32191
32423
  const effectiveClippingPlanes = clippingPlanes ?? [];
32192
32424
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
32193
32425
  "group",
@@ -32201,7 +32433,30 @@ function ForgeObject({
32201
32433
  onDoubleClick,
32202
32434
  onContextMenu,
32203
32435
  children: [
32204
- showSolid && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: solidGeo, userData: { forgeMesh: true }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
32436
+ showSolid && (inspectChannel === "mask" || inspectChannel === "connectivity" || inspectChannel === "distance") && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: solidGeo, userData: { forgeMesh: true }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
32437
+ "meshBasicMaterial",
32438
+ {
32439
+ color: inspectColor ?? settings.color,
32440
+ side: DoubleSide,
32441
+ toneMapped: false,
32442
+ clippingPlanes: effectiveClippingPlanes
32443
+ }
32444
+ ) }),
32445
+ showSolid && (inspectChannel === "thickness" || inspectChannel === "roughness") && inspectionGeo && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: inspectionGeo, userData: { forgeMesh: true }, children: /* @__PURE__ */ jsxRuntimeExports.jsx("meshBasicMaterial", { vertexColors: true, side: DoubleSide, toneMapped: false, clippingPlanes: effectiveClippingPlanes }) }),
32446
+ showSolid && inspectChannel === "collisions" && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: solidGeo, userData: { forgeMesh: true }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
32447
+ "meshPhysicalMaterial",
32448
+ {
32449
+ color: rgbToHex(COLLISION_SOURCE_COLOR),
32450
+ roughness: 0.75,
32451
+ metalness: 0,
32452
+ side: DoubleSide,
32453
+ transparent: true,
32454
+ opacity: COLLISION_SOURCE_OPACITY,
32455
+ depthWrite: false,
32456
+ clippingPlanes: effectiveClippingPlanes
32457
+ }
32458
+ ) }),
32459
+ showSolid && inspectChannel === "none" && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: solidGeo, userData: { forgeMesh: true }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
32205
32460
  "meshPhysicalMaterial",
32206
32461
  {
32207
32462
  color: settings.color,
@@ -32226,7 +32481,7 @@ function ForgeObject({
32226
32481
  clippingPlanes: effectiveClippingPlanes
32227
32482
  }
32228
32483
  ) }),
32229
- showSolid && hasAuthoredTransparency && renderStylePreset.glassShell.enabled && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: solidGeo, scale: renderStylePreset.glassShell.scale, raycast: () => null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
32484
+ showSolid && inspectChannel === "none" && hasAuthoredTransparency && renderStylePreset.glassShell.enabled && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: solidGeo, scale: renderStylePreset.glassShell.scale, raycast: () => null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
32230
32485
  "meshBasicMaterial",
32231
32486
  {
32232
32487
  color: renderStylePreset.glassShell.color,
@@ -37793,6 +38048,7 @@ function useViewportState() {
37793
38048
  const files = useForgeStore((s) => s.files);
37794
38049
  const renderMode = useForgeStore((s) => s.renderMode);
37795
38050
  const renderStyle = useForgeStore((s) => s.renderStyle);
38051
+ const inspectChannel = useForgeStore((s) => s.inspectChannel);
37796
38052
  const projectionMode = useForgeStore((s) => s.projectionMode);
37797
38053
  const gridEnabled = useForgeStore((s) => s.gridEnabled);
37798
38054
  const gridSize = useForgeStore((s) => s.gridSize);
@@ -38119,6 +38375,7 @@ function useViewportState() {
38119
38375
  files,
38120
38376
  renderMode,
38121
38377
  renderStyle,
38378
+ inspectChannel,
38122
38379
  projectionMode,
38123
38380
  gridEnabled,
38124
38381
  gridSize,
@@ -39448,6 +39705,58 @@ function ModelJourneyBar({
39448
39705
  }
39449
39706
  );
39450
39707
  }
39708
+ function transformedShapeBounds(obj, matrix) {
39709
+ if (!obj.shape) return null;
39710
+ try {
39711
+ const bb = obj.shape.boundingBox();
39712
+ const bounds = new Box3();
39713
+ if (!expandBoundsByTransformedAabb(bounds, bb.min, bb.max, matrix)) return null;
39714
+ return isFiniteBox3(bounds) ? bounds : null;
39715
+ } catch {
39716
+ return null;
39717
+ }
39718
+ }
39719
+ function bodyCountForShape(obj) {
39720
+ var _a3, _b2;
39721
+ try {
39722
+ const bodyCount = (_b2 = (_a3 = obj.shape) == null ? void 0 : _a3.numBodies) == null ? void 0 : _b2.call(_a3);
39723
+ return typeof bodyCount === "number" && Number.isFinite(bodyCount) ? Math.max(0, Math.round(bodyCount)) : 1;
39724
+ } catch {
39725
+ return 1;
39726
+ }
39727
+ }
39728
+ function buildPhysicalConnectivityEntries(objects, objectSettings, objectMatrices) {
39729
+ const entries = [];
39730
+ objects.forEach((obj) => {
39731
+ var _a3;
39732
+ if (!obj.shape) return;
39733
+ if (((_a3 = objectSettings[obj.id]) == null ? void 0 : _a3.visible) === false) return;
39734
+ const bounds = transformedShapeBounds(obj, objectMatrices[obj.id] ?? new Matrix4());
39735
+ if (!bounds) return;
39736
+ entries.push({
39737
+ id: obj.id,
39738
+ name: obj.name,
39739
+ shape: obj.shape,
39740
+ min: [bounds.min.x, bounds.min.y, bounds.min.z],
39741
+ max: [bounds.max.x, bounds.max.y, bounds.max.z],
39742
+ groupName: obj.groupName,
39743
+ treePath: obj.treePath,
39744
+ mock: obj.mock,
39745
+ bodyCount: bodyCountForShape(obj)
39746
+ });
39747
+ });
39748
+ return entries;
39749
+ }
39750
+ function connectivityColorByObjectId(entries) {
39751
+ const report = analyzePhysicalConnectivity(entries);
39752
+ return Object.fromEntries(report.objects.map((object) => [object.id, maskColorForIndex(object.componentIndex - 1)]));
39753
+ }
39754
+ function distanceColorByObjectId(entries) {
39755
+ const report = analyzeDistanceInspection(entries);
39756
+ return Object.fromEntries(
39757
+ report.objects.map((object) => [object.id, distanceColorForRootDistance(object.rootDistance, report.maxRootDistance)])
39758
+ );
39759
+ }
39451
39760
  const anchorTransform = {
39452
39761
  center: "translate(-50%, -50%)",
39453
39762
  top: "translate(-50%, 0)",
@@ -39615,6 +39924,7 @@ function Viewport() {
39615
39924
  evaluationPhase,
39616
39925
  renderMode,
39617
39926
  renderStyle,
39927
+ inspectChannel,
39618
39928
  projectionMode,
39619
39929
  gridEnabled,
39620
39930
  gridSize,
@@ -39698,6 +40008,7 @@ function Viewport() {
39698
40008
  const contextMenuRef = reactExports.useRef(null);
39699
40009
  const t2 = themes[themeName];
39700
40010
  const renderStylePreset = reactExports.useMemo(() => getRenderStylePreset(renderStyle), [renderStyle]);
40011
+ const inspectChannelActive = inspectChannel !== "none";
39701
40012
  const hasVisibleSdfObjects = objects.some((obj) => {
39702
40013
  var _a4;
39703
40014
  return obj.sdf && (((_a4 = objectSettings[obj.id]) == null ? void 0 : _a4.visible) ?? true);
@@ -39714,6 +40025,11 @@ function Viewport() {
39714
40025
  }
39715
40026
  return next;
39716
40027
  }, [constructionGhost, focusedObjectIdSet, objectSettings, objects]);
40028
+ const physicalInspectColorByObjectId = reactExports.useMemo(() => {
40029
+ if (inspectChannel !== "connectivity" && inspectChannel !== "distance") return {};
40030
+ const entries = buildPhysicalConnectivityEntries(objects, objectSettings, objectMatrices);
40031
+ return inspectChannel === "connectivity" ? connectivityColorByObjectId(entries) : distanceColorByObjectId(entries);
40032
+ }, [inspectChannel, objectMatrices, objectSettings, objects]);
39717
40033
  const handlers = useViewportHandlers({
39718
40034
  containerRef,
39719
40035
  contextMenuRef,
@@ -39777,7 +40093,7 @@ function Viewport() {
39777
40093
  Canvas,
39778
40094
  {
39779
40095
  style: {
39780
- background: renderStyle === "classic" ? t2.viewportBg : renderStylePreset.background,
40096
+ background: inspectChannelActive ? "#000000" : renderStyle === "classic" ? t2.viewportBg : renderStylePreset.background,
39781
40097
  cursor: measureMode ? "crosshair" : "default"
39782
40098
  },
39783
40099
  dpr: canvasDpr,
@@ -39845,8 +40161,8 @@ function Viewport() {
39845
40161
  )
39846
40162
  ] }),
39847
40163
  /* @__PURE__ */ jsxRuntimeExports.jsx(ClippingManager, { active: hasAnyObjectCutPlanes }),
39848
- sectionExplorerEnabled && /* @__PURE__ */ jsxRuntimeExports.jsx(SectionExplorerGizmo, { size: sectionGuideSize }),
39849
- sectionPlaneGuidesEnabled && activeCutPlaneDefs.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
40164
+ !inspectChannelActive && sectionExplorerEnabled && /* @__PURE__ */ jsxRuntimeExports.jsx(SectionExplorerGizmo, { size: sectionGuideSize }),
40165
+ !inspectChannelActive && sectionPlaneGuidesEnabled && activeCutPlaneDefs.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
39850
40166
  SectionPlaneGuides,
39851
40167
  {
39852
40168
  cutPlanes: scriptCutPlaneDefs,
@@ -39878,6 +40194,8 @@ function Viewport() {
39878
40194
  settings: effectiveSettings,
39879
40195
  renderStyle,
39880
40196
  renderMode,
40197
+ inspectChannel,
40198
+ inspectColor: physicalInspectColorByObjectId[obj.id] ?? maskColorForIndex(objIndex),
39881
40199
  isInteracting: isViewportInteracting,
39882
40200
  matrix,
39883
40201
  isHovered,
@@ -39942,7 +40260,8 @@ function Viewport() {
39942
40260
  }
39943
40261
  return null;
39944
40262
  }),
39945
- /* @__PURE__ */ jsxRuntimeExports.jsx(
40263
+ inspectChannel === "collisions" && /* @__PURE__ */ jsxRuntimeExports.jsx(CollisionInspectionOverlay, { objects, objectSettings, objectMatrices }),
40264
+ !inspectChannelActive && /* @__PURE__ */ jsxRuntimeExports.jsx(
39946
40265
  SectionCaps,
39947
40266
  {
39948
40267
  sceneVersion,
@@ -39954,17 +40273,17 @@ function Viewport() {
39954
40273
  isInteracting: isViewportInteracting
39955
40274
  }
39956
40275
  ),
39957
- constructionGhost && /* @__PURE__ */ jsxRuntimeExports.jsx(ConstructionGhostOverlay, { matrix: constructionGhostMatrix }),
39958
- historyMode && /* @__PURE__ */ jsxRuntimeExports.jsx(ConstructionHistoryOverlay, { objectMatrices, objectSettings }),
39959
- hoveredJointOverlay && /* @__PURE__ */ jsxRuntimeExports.jsx(HoveredJointOverlay, { state: hoveredJointOverlay, config: jointOverlayConfig }),
39960
- dimensionsVisible && dimensions.map((d) => /* @__PURE__ */ jsxRuntimeExports.jsx(DimensionAnnotation, { def: d, lengthUnit }, d.id)),
39961
- /* @__PURE__ */ jsxRuntimeExports.jsx(RenderLabelsOverlay, { labels: renderLabels }),
39962
- attachmentsVisible !== "none" && attachmentPoints.map((ap) => {
40276
+ !inspectChannelActive && constructionGhost && /* @__PURE__ */ jsxRuntimeExports.jsx(ConstructionGhostOverlay, { matrix: constructionGhostMatrix }),
40277
+ !inspectChannelActive && historyMode && /* @__PURE__ */ jsxRuntimeExports.jsx(ConstructionHistoryOverlay, { objectMatrices, objectSettings }),
40278
+ !inspectChannelActive && hoveredJointOverlay && /* @__PURE__ */ jsxRuntimeExports.jsx(HoveredJointOverlay, { state: hoveredJointOverlay, config: jointOverlayConfig }),
40279
+ !inspectChannelActive && dimensionsVisible && dimensions.map((d) => /* @__PURE__ */ jsxRuntimeExports.jsx(DimensionAnnotation, { def: d, lengthUnit }, d.id)),
40280
+ !inspectChannelActive && /* @__PURE__ */ jsxRuntimeExports.jsx(RenderLabelsOverlay, { labels: renderLabels }),
40281
+ !inspectChannelActive && attachmentsVisible !== "none" && attachmentPoints.map((ap) => {
39963
40282
  const matrix = objectMatrices[ap.objectId];
39964
40283
  return matrix ? /* @__PURE__ */ jsxRuntimeExports.jsx("group", { matrixAutoUpdate: false, matrix, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ConnectorAttachmentAnnotation, { def: ap }) }, `${ap.objectId}:${ap.name}`) : /* @__PURE__ */ jsxRuntimeExports.jsx(ConnectorAttachmentAnnotation, { def: ap }, `${ap.objectId}:${ap.name}`);
39965
40284
  }),
39966
40285
  /* @__PURE__ */ jsxRuntimeExports.jsx(MeasureTool, {}),
39967
- debugHighlights3D.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(DebugHighlightsOverlay, { highlights: debugHighlights3D }),
40286
+ !inspectChannelActive && debugHighlights3D.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(DebugHighlightsOverlay, { highlights: debugHighlights3D }),
39968
40287
  drawFlagEnabled && /* @__PURE__ */ jsxRuntimeExports.jsx(DrawCanvas, {}),
39969
40288
  /* @__PURE__ */ jsxRuntimeExports.jsx(
39970
40289
  PerformanceInfoSampler,
@@ -39977,7 +40296,7 @@ function Viewport() {
39977
40296
  }
39978
40297
  ),
39979
40298
  /* @__PURE__ */ jsxRuntimeExports.jsx(ZoomSampler, { onZoomChange: setZoomMmPerPx }),
39980
- gridEnabled && !isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(
40299
+ !inspectChannelActive && gridEnabled && !isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(
39981
40300
  Grid,
39982
40301
  {
39983
40302
  args: [500, 500],
@@ -39992,7 +40311,7 @@ function Viewport() {
39992
40311
  infiniteGrid: true
39993
40312
  }
39994
40313
  ),
39995
- !isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(
40314
+ !inspectChannelActive && !isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(
39996
40315
  SdfRaymarchLayer,
39997
40316
  {
39998
40317
  objects,
@@ -40007,11 +40326,11 @@ function Viewport() {
40007
40326
  onContextMenu: (obj, event) => handleObjectContextMenu(obj, event)
40008
40327
  }
40009
40328
  ),
40010
- !isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(LabeledAxes, {}),
40011
- isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(SketchAxes, {}),
40329
+ !inspectChannelActive && !isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(LabeledAxes, {}),
40330
+ !inspectChannelActive && isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(SketchAxes, {}),
40012
40331
  isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(CursorTracker, { onMove: (x, y) => setCursorPos({ x, y }) }),
40013
40332
  isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(SketchRulersUpdater, { hCanvasRef: hRulerRef, vCanvasRef: vRulerRef }),
40014
- gridEnabled && isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(
40333
+ !inspectChannelActive && gridEnabled && isSketchOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(
40015
40334
  Grid,
40016
40335
  {
40017
40336
  args: [500, 500],
@@ -40622,7 +40941,7 @@ function Viewport() {
40622
40941
  }
40623
40942
  );
40624
40943
  }
40625
- const EditorApp$1 = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-Dja2jMmW.js"), true ? __vite__mapDeps([0]) : void 0).then((m2) => ({ default: m2.EditorApp })));
40944
+ const EditorApp$1 = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-CuiPbtn5.js"), true ? __vite__mapDeps([0]) : void 0).then((m2) => ({ default: m2.EditorApp })));
40626
40945
  const PENDING_SHARE_COPY_KEY = "fc-pending-share-copy";
40627
40946
  function storePendingShareCopy(shareId) {
40628
40947
  sessionStorage.setItem(PENDING_SHARE_COPY_KEY, shareId);
@@ -40809,15 +41128,15 @@ const PublishedModelPage$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Objec
40809
41128
  consumePendingShareCopy,
40810
41129
  storePendingShareCopy
40811
41130
  }, Symbol.toStringTag, { value: "Module" }));
40812
- reactExports.lazy(() => __vitePreload(() => import("./LandingPageProofDriven-CO8WL0CY.js"), true ? __vite__mapDeps([1]) : void 0).then((m2) => ({ default: m2.LandingPageProofDriven })));
40813
- const DocsPage = reactExports.lazy(() => __vitePreload(() => import("./DocsPage-9WaRC14b.js"), true ? [] : void 0).then((m2) => ({ default: m2.DocsPage })));
40814
- reactExports.lazy(() => __vitePreload(() => import("./BlogPage-Ck7g3ue2.js"), true ? [] : void 0).then((m2) => ({ default: m2.BlogPage })));
40815
- reactExports.lazy(() => __vitePreload(() => import("./AdminPage-jwoEgwE_.js"), true ? [] : void 0).then((m2) => ({ default: m2.AdminPage })));
41131
+ reactExports.lazy(() => __vitePreload(() => import("./LandingPageProofDriven-DB9fQd5P.js"), true ? __vite__mapDeps([1]) : void 0).then((m2) => ({ default: m2.LandingPageProofDriven })));
41132
+ const DocsPage = reactExports.lazy(() => __vitePreload(() => import("./DocsPage-Blz3Tp4j.js"), true ? [] : void 0).then((m2) => ({ default: m2.DocsPage })));
41133
+ reactExports.lazy(() => __vitePreload(() => import("./BlogPage-Bl_sKeWb.js"), true ? [] : void 0).then((m2) => ({ default: m2.BlogPage })));
41134
+ reactExports.lazy(() => __vitePreload(() => import("./AdminPage-Da6hhpJx.js"), true ? [] : void 0).then((m2) => ({ default: m2.AdminPage })));
40816
41135
  reactExports.lazy(() => __vitePreload(() => Promise.resolve().then(() => PublishedModelPage$1), true ? void 0 : void 0).then((m2) => ({ default: m2.PublishedModelPage })));
40817
- reactExports.lazy(() => __vitePreload(() => import("./SettingsPage-DKKI4W49.js"), true ? [] : void 0).then((m2) => ({ default: m2.SettingsPage })));
40818
- reactExports.lazy(() => __vitePreload(() => import("./PricingPage-DADKGuOa.js"), true ? __vite__mapDeps([2,1]) : void 0).then((m2) => ({ default: m2.PricingPage })));
40819
- const EditorApp = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-Dja2jMmW.js"), true ? __vite__mapDeps([0]) : void 0).then((m2) => ({ default: m2.EditorApp })));
40820
- const EmbedViewer = reactExports.lazy(() => __vitePreload(() => import("./EmbedViewer-37_PfMwv.js"), true ? [] : void 0).then((m2) => ({ default: m2.EmbedViewer })));
41136
+ reactExports.lazy(() => __vitePreload(() => import("./SettingsPage-VVQNrCAg.js"), true ? [] : void 0).then((m2) => ({ default: m2.SettingsPage })));
41137
+ reactExports.lazy(() => __vitePreload(() => import("./PricingPage-BMxYT_F0.js"), true ? __vite__mapDeps([2,1]) : void 0).then((m2) => ({ default: m2.PricingPage })));
41138
+ const EditorApp = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-CuiPbtn5.js"), true ? __vite__mapDeps([0]) : void 0).then((m2) => ({ default: m2.EditorApp })));
41139
+ const EmbedViewer = reactExports.lazy(() => __vitePreload(() => import("./EmbedViewer-BFG6-Ufm.js"), true ? [] : void 0).then((m2) => ({ default: m2.EmbedViewer })));
40821
41140
  const embedMode = isEmbedMode() && !window.location.pathname.startsWith("/m/");
40822
41141
  const EDITABLE_CRASH_FILE = /\.(?:forge\.js|[cm]?[jt]sx?|json|md|txt|svg)$/i;
40823
41142
  function firstMeaningfulLine(text) {