brepjs 18.134.0 → 18.136.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/2d/lib/svgPath.d.ts +0 -11
  2. package/dist/2d.cjs +6 -6
  3. package/dist/2d.js +6 -6
  4. package/dist/{adjacencyFns-CwcdjOsT.js → adjacencyFns-BMgFDWFO.js} +3 -3
  5. package/dist/{adjacencyFns-BhdfZany.cjs → adjacencyFns-Clu4DbkI.cjs} +3 -3
  6. package/dist/{blueprint-DRvc1LOz.js → blueprint-BzDq9Rfb.js} +40 -15
  7. package/dist/{blueprint-BgbVmx4L.cjs → blueprint-CdOcvuG4.cjs} +40 -15
  8. package/dist/{blueprintFns-COSD5yZH.js → blueprintFns-B0wbS9PN.js} +2 -2
  9. package/dist/{blueprintFns-oatmkSjh.cjs → blueprintFns-B6zG47o1.cjs} +2 -2
  10. package/dist/{blueprintSketcher-yZiAeqft.js → blueprintSketcher-DI_qQhBg.js} +3 -3
  11. package/dist/{blueprintSketcher-B5UqD0FO.cjs → blueprintSketcher-DeQYScWX.cjs} +3 -3
  12. package/dist/{boolean2D-p7RMNFtG.cjs → boolean2D-C-Azd06V.cjs} +4 -4
  13. package/dist/{boolean2D-BuM5xJSa.js → boolean2D-CdDn7AFp.js} +4 -4
  14. package/dist/brepjs.cjs +200 -37
  15. package/dist/brepjs.js +201 -38
  16. package/dist/{cameraFns-VVI0cWLa.js → cameraFns-BqSTuHN2.js} +3 -3
  17. package/dist/{cameraFns-i1otOZ0V.cjs → cameraFns-CdPdw2Ma.cjs} +3 -3
  18. package/dist/core.cjs +2 -2
  19. package/dist/core.js +2 -2
  20. package/dist/{cornerFinder-CiHpo7kU.js → cornerFinder-CBNgUcWy.js} +1 -1
  21. package/dist/{cornerFinder-DIe6pMPU.cjs → cornerFinder-WICP_RPb.cjs} +1 -1
  22. package/dist/csg/builders.d.ts +8 -2
  23. package/dist/csg/evaluators/shell.d.ts +5 -0
  24. package/dist/csg/index.d.ts +2 -2
  25. package/dist/csg/serialize.d.ts +1 -1
  26. package/dist/csg/types.d.ts +10 -2
  27. package/dist/{curveFns-jmKL1KZp.cjs → curveFns-BYcLLDAB.cjs} +1 -1
  28. package/dist/{curveFns-Bh_PHl9N.js → curveFns-BtXR6kJ7.js} +1 -1
  29. package/dist/{drawFns-BFktlDIi.js → drawFns-BAwR4uoC.js} +12 -12
  30. package/dist/{drawFns-CP82Xdma.cjs → drawFns-CYW65QTr.cjs} +12 -12
  31. package/dist/{faceFns-C0A8O-2a.cjs → faceFns-B5UiJH4H.cjs} +2 -2
  32. package/dist/{faceFns-CaBQNffu.js → faceFns-BfTHYEiw.js} +2 -2
  33. package/dist/{healingFns-BqmIvfPm.cjs → healingFns-ChcvzVB8.cjs} +4 -4
  34. package/dist/{healingFns-BrrTpxjI.js → healingFns-DAVYFXVB.js} +4 -4
  35. package/dist/{helpers-DLZUxawd.cjs → helpers-C9PIppuU.cjs} +12 -6
  36. package/dist/{helpers-BiqV-wPK.js → helpers-CvwerZfP.js} +7 -7
  37. package/dist/{importFns-ncp_0vEl.cjs → importFns-Bt9YEImO.cjs} +2 -2
  38. package/dist/{importFns-BId6d2pt.js → importFns-DSY1pI70.js} +2 -2
  39. package/dist/io.cjs +2 -2
  40. package/dist/io.js +2 -2
  41. package/dist/kernel/occtWasm/occtWasmAdapter.cjs +1 -1
  42. package/dist/kernel/occtWasm/occtWasmAdapter.js +1 -1
  43. package/dist/{loftFns-m7LoJWE2.js → loftFns-Bl8reWqk.js} +1 -1
  44. package/dist/{loftFns-u-yPHpJ9.cjs → loftFns-CdwKSxw1.cjs} +1 -1
  45. package/dist/{measureFns-CaEuNAZO.cjs → measureFns-B-UbL3Rw.cjs} +3 -3
  46. package/dist/{measureFns-9-1Ng0wR.js → measureFns-DtiZvj_X.js} +3 -3
  47. package/dist/measurement.cjs +1 -1
  48. package/dist/measurement.js +1 -1
  49. package/dist/{meshFns-CB7HsxzB.cjs → meshFns-B461Ku2S.cjs} +3 -3
  50. package/dist/{meshFns-CpfeEN1b.js → meshFns-CqJScqWa.js} +3 -3
  51. package/dist/{occtWasmAdapter-BEe---7w.js → occtWasmAdapter-Bzx2d8zN.js} +39 -10
  52. package/dist/{occtWasmAdapter-DEpy64ji.cjs → occtWasmAdapter-G8mkVxgw.cjs} +39 -10
  53. package/dist/operations.cjs +2 -2
  54. package/dist/operations.js +2 -2
  55. package/dist/{originTrackingFns-JxAlPJXX.js → originTrackingFns-BWA8gv5V.js} +2 -2
  56. package/dist/{originTrackingFns-CKKmLIUH.cjs → originTrackingFns-rh_FbN6R.cjs} +2 -2
  57. package/dist/{primitiveFns-C6Trlz8m.cjs → primitiveFns-BTxppy_Y.cjs} +4 -4
  58. package/dist/{primitiveFns-BSMbMRf1.js → primitiveFns-C-p7jKZt.js} +4 -4
  59. package/dist/projection.cjs +1 -1
  60. package/dist/projection.js +1 -1
  61. package/dist/query.cjs +2 -2
  62. package/dist/query.js +2 -2
  63. package/dist/{refResolveFns-DcyIQSDi.js → refResolveFns-BPnjuRUW.js} +6 -6
  64. package/dist/{refResolveFns-c7RWIsZy.cjs → refResolveFns-DEU2yvJU.cjs} +6 -6
  65. package/dist/{shapeFns-DyDRpo6K.js → shapeFns-s6VgcNkU.js} +2 -2
  66. package/dist/{shapeFns-DDTLk0mJ.cjs → shapeFns-xApQafn6.cjs} +2 -2
  67. package/dist/shapeRef.cjs +1 -1
  68. package/dist/shapeRef.js +1 -1
  69. package/dist/{shapeTypes-pxoxsXIo.js → shapeTypes-D3bntzog.js} +1 -1
  70. package/dist/{shapeTypes-DVExh1xP.cjs → shapeTypes-Dz5JzlYx.cjs} +1 -1
  71. package/dist/sketching.cjs +3 -3
  72. package/dist/sketching.js +3 -3
  73. package/dist/{solidBuilders-CgW7Ge_s.cjs → solidBuilders-B3EZcVNw.cjs} +5 -5
  74. package/dist/{solidBuilders-Devga1Vk.js → solidBuilders-FOfRGZq0.js} +5 -5
  75. package/dist/{surfaceBuilders-DUTDN2Ay.cjs → surfaceBuilders-CVLhWPtB.cjs} +3 -3
  76. package/dist/{surfaceBuilders-B7WlmoVr.js → surfaceBuilders-Dcf7LRqM.js} +3 -3
  77. package/dist/text.cjs +2 -2
  78. package/dist/text.js +2 -2
  79. package/dist/{textBlueprints-BMvBJ79v.cjs → textBlueprints-hV1kO8tW.cjs} +7 -7
  80. package/dist/{textBlueprints-myJW6Fzl.js → textBlueprints-kwXeudLb.js} +7 -7
  81. package/dist/{textMetrics-CPFqh2a1.js → textMetrics-BlhkYGHT.js} +1 -1
  82. package/dist/{textMetrics-Byfb_37y.cjs → textMetrics-BmN3SBkI.cjs} +1 -1
  83. package/dist/{threadFns-B6-3UeCZ.js → threadFns-CQErpnNd.js} +7 -7
  84. package/dist/{threadFns-BQIE5dO9.cjs → threadFns-Dd0C7WLp.cjs} +7 -7
  85. package/dist/topology.cjs +9 -9
  86. package/dist/topology.js +9 -9
  87. package/dist/{topologyQueryFns-BtLGfXgL.cjs → topologyQueryFns-DzYSYw51.cjs} +1 -1
  88. package/dist/{topologyQueryFns-CwYkfE3v.js → topologyQueryFns-qvptbhqO.js} +1 -1
  89. package/dist/{validityTypes-C2nklkrH.cjs → validityTypes-Beci6AC-.cjs} +1 -1
  90. package/dist/{validityTypes-Bl3adWZb.js → validityTypes-DF2h0WJo.js} +1 -1
  91. package/package.json +1 -1
package/dist/brepjs.js CHANGED
@@ -1,39 +1,39 @@
1
- import { $ as prewarm, A as is2D, B as withArenaCheckpoint, C as isSolid, E as getShapeKind, F as getDisposalStats, G as getActiveKernelId, H as withScopeResult, I as isLive, J as getKernelCapabilities, K as getKernel, M as DisposalScope, N as createHandle, O as as2D, P as createKernelHandle, Q as initFromOC, R as resetDisposalStats, S as isShell, T as isWire, U as withScopeResultAsync, V as withScope, W as _usingCtx, X as init, Y as getKernelTier, Z as initFromManifold, _ as isCompound, a as castShape3D, at as BrepkitAdapter, b as isShape1D, c as createEdge, ct as currentQuality, d as createSolid, et as registerKernel, f as createVertex, h as disposeResultShape, i as castShape, it as withTier, j as is3D, k as as3D, l as createFace, lt as qualityDeflection, n as castResultShape, nt as withKernel, ot as getPerformanceStats, p as createWire, q as getKernel2D, rt as withQuality, s as createCompound, st as resetPerformanceStats, tt as registerKernelTier, u as createShell, v as isEdge, w as isVertex, x as isShape3D, y as isFace } from "./shapeTypes-pxoxsXIo.js";
2
- import { A as EXACT_BREP_CAPABILITIES, k as DEFAULT_CAPABILITIES, t as OcctWasmAdapter } from "./occtWasmAdapter-BEe---7w.js";
1
+ import { $ as prewarm, A as is2D, B as withArenaCheckpoint, C as isSolid, E as getShapeKind, F as getDisposalStats, G as getActiveKernelId, H as withScopeResult, I as isLive, J as getKernelCapabilities, K as getKernel, M as DisposalScope, N as createHandle, O as as2D, P as createKernelHandle, Q as initFromOC, R as resetDisposalStats, S as isShell, T as isWire, U as withScopeResultAsync, V as withScope, W as _usingCtx, X as init, Y as getKernelTier, Z as initFromManifold, _ as isCompound, a as castShape3D, at as BrepkitAdapter, b as isShape1D, c as createEdge, ct as currentQuality, d as createSolid, et as registerKernel, f as createVertex, h as disposeResultShape, i as castShape, it as withTier, j as is3D, k as as3D, l as createFace, lt as qualityDeflection, n as castResultShape, nt as withKernel, ot as getPerformanceStats, p as createWire, q as getKernel2D, rt as withQuality, s as createCompound, st as resetPerformanceStats, tt as registerKernelTier, u as createShell, v as isEdge, w as isVertex, x as isShape3D, y as isFace } from "./shapeTypes-D3bntzog.js";
2
+ import { A as EXACT_BREP_CAPABILITIES, k as DEFAULT_CAPABILITIES, t as OcctWasmAdapter } from "./occtWasmAdapter-Bzx2d8zN.js";
3
3
  import { i as wasmIndex, n as bug, t as BrepBugError } from "./bug-BdOHwn_e.js";
4
4
  import { A as tap, C as mapBoth, D as or, E as ok, F as unwrapErr, I as unwrapOr, L as unwrapOrElse, M as tryCatch, N as tryCatchAsync, O as orElse, P as unwrap, R as zip, S as map, T as match, _ as flatMap, a as moduleInitError, b as isErr, c as sketcherStateError, d as validationError, f as OK, g as err, h as collect, i as kernelError, j as tapErr, k as pipeline, l as typeCastError, m as andThen, n as computationError, o as queryError, p as all, r as ioError, t as BrepErrorCode, u as unsupportedError, v as flatten, w as mapErr, x as isOk, y as fromNullable } from "./errors-MHLiNE-C.js";
5
- import { C as vertexPosition, E as kernelCallScoped, T as kernelCallRaw, _ as iterFaces, a as getCachedSurfaceType, b as iterVertices, c as getFaces, d as getSolids, f as getVertices, g as iterEdges, h as iterCompSolids, m as invalidateShapeCache, n as getBounds, o as getCompSolids, p as getWires, s as getEdges, t as describe$1, u as getShells, v as iterShells, w as kernelCall, x as iterWires, y as iterSolids } from "./topologyQueryFns-CwYkfE3v.js";
6
- import { a as isPlanarFace, c as manifoldShell, d as planarWire, f as validSolid, i as isOrientedFace, l as orientedFace, n as isClosedWire, o as isPlanarWire, r as isManifoldShell, s as isValidSolid, t as closedWire, u as planarFace } from "./validityTypes-Bl3adWZb.js";
5
+ import { C as vertexPosition, E as kernelCallScoped, T as kernelCallRaw, _ as iterFaces, a as getCachedSurfaceType, b as iterVertices, c as getFaces, d as getSolids, f as getVertices, g as iterEdges, h as iterCompSolids, m as invalidateShapeCache, n as getBounds, o as getCompSolids, p as getWires, s as getEdges, t as describe$1, u as getShells, v as iterShells, w as kernelCall, x as iterWires, y as iterSolids } from "./topologyQueryFns-qvptbhqO.js";
6
+ import { a as isPlanarFace, c as manifoldShell, d as planarWire, f as validSolid, i as isOrientedFace, l as orientedFace, n as isClosedWire, o as isPlanarWire, r as isManifoldShell, s as isValidSolid, t as closedWire, u as planarFace } from "./validityTypes-DF2h0WJo.js";
7
7
  import { n as HASH_CODE_MAX, r as RAD2DEG, t as DEG2RAD } from "./constants-ITRzCnCp.js";
8
8
  import { n as toVec2, r as toVec3, t as resolveDirection } from "./types-D24Y27N0.js";
9
9
  import { a as vecDot, c as vecLength, d as vecNormalize, f as vecProjectToPlane, g as vecSub, h as vecScale, i as vecDistance, l as vecLengthSq, m as vecRotate, n as vecAngle, o as vecEquals, p as vecRepr, r as vecCross, s as vecIsZero, t as vecAdd, u as vecNegate } from "./vecOps-SKPRvPH-.js";
10
10
  import { i as pivotPlane, n as createPlane, o as resolvePlane, r as makePlane, s as translatePlane, t as createNamedPlane } from "./planeOps-CQahLrCx.js";
11
- import { C as shapeType, S as iterTopo, _ as cast, a as faceOrientation, b as fromBREP, c as innerWires, d as pointOnSurface, f as projectPointOnFace, g as asTopo, h as uvCoordinates, i as faceGeomType, l as normalAt, m as uvBounds, n as faceAxis, o as flipFaceOrientation, p as removeHolesFromFace, r as faceCenter, s as getSurfaceType, t as classifyPointOnFace, u as outerWire, x as isCompSolid, y as downcast } from "./faceFns-CaBQNffu.js";
12
- import { i as setShapeOrigin, t as getFaceOrigins } from "./originTrackingFns-JxAlPJXX.js";
13
- import { A as parseColor, D as colorShape, E as colorFaces, F as tagFaces, M as getFaceTags, N as getTagMetadata, O as getFaceColor, P as setTagMetadata, S as hasAnyMetadata, T as propagateMetadataThroughRelocation, _ as section$1, b as split$1, d as booleanPipeline, f as cut$2, g as intersect$2, h as fuseAll$2, j as findFacesByTag, k as getShapeColor, m as fuse$2, p as cutAll$2, r as makeCylinder, t as makeCompound, v as sectionToFace$1, y as slice$1 } from "./solidBuilders-Devga1Vk.js";
14
- import { A as locate$1, C as threePointArc, D as wireLoop, E as wire, F as transformCopy$1, I as translate$2, M as resize, N as rotate$2, O as applyMatrix$1, P as scale$3, S as tangentArc, T as vertex, _ as polygon, a as circle, b as sphere$1, c as cylinder, d as ellipsoid, f as face, g as offsetFace, h as line, i as bsplineApprox, j as mirror$2, k as composeTransforms, l as ellipse, m as helix, n as bezier, o as compound, p as filledFace, r as box, s as cone, t as addHoles, u as ellipseArc, v as sewShells, w as torus$1, x as subFace, y as solid } from "./primitiveFns-BSMbMRf1.js";
15
- import { a as isSameShape, i as isEqualShape, n as getHashCode, o as simplify$1, r as isEmpty$2, s as toBREP$1, t as clone$1 } from "./shapeFns-DyDRpo6K.js";
16
- import { a as curveIsPeriodic, c as curvePointAt, d as flipOrientation, f as getCurveType, h as offsetWire2D, i as curveIsClosed, l as curveStartPoint, m as interpolateCurve, n as curveAxis, o as curveLength, p as getOrientation, r as curveEndPoint, s as curvePeriod, t as approximateCurve, u as curveTangentAt } from "./curveFns-Bh_PHl9N.js";
17
- import { a as meshEdges$1, c as meshMultiLOD, d as createMeshCache, i as mesh$1, l as buildMeshCacheKey, n as exportSTEP, o as meshLODs, r as exportSTL, s as meshLODsProgressive, t as exportIGES, u as clearMeshCache } from "./meshFns-CpfeEN1b.js";
11
+ import { C as shapeType, S as iterTopo, _ as cast, a as faceOrientation, b as fromBREP, c as innerWires, d as pointOnSurface, f as projectPointOnFace, g as asTopo, h as uvCoordinates, i as faceGeomType, l as normalAt, m as uvBounds, n as faceAxis, o as flipFaceOrientation, p as removeHolesFromFace, r as faceCenter, s as getSurfaceType, t as classifyPointOnFace, u as outerWire, x as isCompSolid, y as downcast } from "./faceFns-BfTHYEiw.js";
12
+ import { i as setShapeOrigin, t as getFaceOrigins } from "./originTrackingFns-BWA8gv5V.js";
13
+ import { A as parseColor, D as colorShape, E as colorFaces, F as tagFaces, M as getFaceTags, N as getTagMetadata, O as getFaceColor, P as setTagMetadata, S as hasAnyMetadata, T as propagateMetadataThroughRelocation, _ as section$1, b as split$1, d as booleanPipeline, f as cut$2, g as intersect$2, h as fuseAll$2, j as findFacesByTag, k as getShapeColor, m as fuse$2, p as cutAll$2, r as makeCylinder, t as makeCompound, v as sectionToFace$1, y as slice$1 } from "./solidBuilders-FOfRGZq0.js";
14
+ import { A as locate$1, C as threePointArc, D as wireLoop, E as wire, F as transformCopy$1, I as translate$2, M as resize, N as rotate$2, O as applyMatrix$1, P as scale$3, S as tangentArc, T as vertex, _ as polygon, a as circle, b as sphere$1, c as cylinder, d as ellipsoid, f as face, g as offsetFace, h as line, i as bsplineApprox, j as mirror$2, k as composeTransforms, l as ellipse, m as helix, n as bezier, o as compound, p as filledFace, r as box, s as cone, t as addHoles, u as ellipseArc, v as sewShells, w as torus$1, x as subFace, y as solid } from "./primitiveFns-C-p7jKZt.js";
15
+ import { a as isSameShape, i as isEqualShape, n as getHashCode, o as simplify$1, r as isEmpty$2, s as toBREP$1, t as clone$1 } from "./shapeFns-s6VgcNkU.js";
16
+ import { a as curveIsPeriodic, c as curvePointAt, d as flipOrientation, f as getCurveType, h as offsetWire2D, i as curveIsClosed, l as curveStartPoint, m as interpolateCurve, n as curveAxis, o as curveLength, p as getOrientation, r as curveEndPoint, s as curvePeriod, t as approximateCurve, u as curveTangentAt } from "./curveFns-BtXR6kJ7.js";
17
+ import { a as meshEdges$1, c as meshMultiLOD, d as createMeshCache, i as mesh$1, l as buildMeshCacheKey, n as exportSTEP, o as meshLODs, r as exportSTL, s as meshLODsProgressive, t as exportIGES, u as clearMeshCache } from "./meshFns-CqJScqWa.js";
18
18
  import { n as getAtOrThrow, r as lastOrThrow, t as firstOrThrow } from "./arrayAccess-DrUGPADn.js";
19
- import { _ as makeThreePointArc, d as makeCircle, h as makeLine, l as makeBSplineInterpolation, n as fill, p as makeEllipseArc, r as makeFace, s as assembleWire, u as makeBezierCurve } from "./surfaceBuilders-B7WlmoVr.js";
20
- import { A as toBufferGeometryData, C as chamfer$2, D as shell$1, E as offset$1, M as toLODGeometryData, N as toLODGeometryLevels, O as thicken$1, P as toLineGeometryData, S as chamferDistAngle, T as fillet$2, _ as checkBoolean, a as healFace, b as getNurbsCurveData, c as isValid$1, d as chamferWithEvolution, f as cutWithEvolution, g as shellWithEvolution, h as intersectWithEvolution, i as heal$1, j as toGroupedBufferGeometryData, k as variableFillet, l as solidFromShell, m as fuseWithEvolution, n as fixSelfIntersection, o as healSolid, p as filletWithEvolution, r as fixShape, s as healWire, t as autoHeal, u as positionOnCurve, v as cutAllBisect, w as draft$1, x as getNurbsSurfaceData, y as fuseAllBisect } from "./healingFns-BrrTpxjI.js";
21
- import { A as setJointValue, B as walkAssembly, C as cylindricalJoint, D as planarJoint, E as mechanismDOF, F as countNodes, G as quatFromAxisAngle, H as circularPattern, I as createAssemblyNode, J as quatRotate, K as quatFromTo, L as findNode, M as sphericalJoint, N as addChild, O as prismaticJoint, P as collectShapes, R as removeChild, S as addJoint, T as jointTransform, U as gridPattern, V as exportAssemblySTEP, W as linearPattern, Y as createAssembly, _ as exportURDF, a as deserializeHistory, b as inverseKinematics, c as modifyStep, d as replayFrom, f as replayHistory, g as undoLast, h as stepsFrom, i as createRegistry, j as setJointValues, k as revoluteJoint, l as registerOperation, m as stepCount, n as addStep, o as findStep, p as serializeHistory, q as quatMultiply, r as createHistory, s as getShape, t as thread, u as registerShape, v as importURDF, w as forwardKinematics, x as jointTrajectory, y as jointsFromDH, z as updateNode } from "./threadFns-B6-3UeCZ.js";
22
- import { n as BaseSketcher2d, r as organiseBlueprints, t as BlueprintSketcher } from "./blueprintSketcher-yZiAeqft.js";
23
- import { a as createTypedFinder, i as wireFinder, n as edgeFinder, r as faceFinder, t as getSingleFace } from "./helpers-BiqV-wPK.js";
24
- import { g as approximateAsSvgCompatibleCurve } from "./blueprint-DRvc1LOz.js";
25
- import { A as sketchEllipse, D as makeBaseBox, E as deserializeDrawing, F as sketchRectangle, I as sketchRoundedRectangle, L as FaceSketcher, M as sketchHelix, N as sketchParametricFunction, O as polysideInnerRadius, P as sketchPolysides, R as Sketcher, S as drawText, _ as drawPolysides, a as drawingIntersect, b as drawSingleCircle, c as rotateDrawing, d as drawFaceOutline, f as drawProjection, g as drawPointsInterpolation, h as drawParametricFunction, i as drawingFuse, j as sketchFaceOffset, k as sketchCircle, l as scaleDrawing, m as drawEllipse, n as drawingCut, o as drawingToSketchOnPlane, p as drawCircle, r as drawingFillet, s as mirrorDrawing, t as drawingChamfer, u as translateDrawing, v as drawRectangle, w as draw, x as drawSingleEllipse, y as drawRoundedRectangle } from "./drawFns-BFktlDIi.js";
26
- import { a as measureDistance, c as measureLinearProps, d as measureVolumeProps, i as measureCurvatureAtMid, l as measureSurfaceProps, n as measureArea, o as measureDistanceProps, r as measureCurvatureAt, s as measureLength, t as createDistanceQuery, u as measureVolume } from "./measureFns-9-1Ng0wR.js";
27
- import { t as cornerFinder } from "./cornerFinder-CiHpo7kU.js";
28
- import { a as fuseBlueprints, c as roundedRectangleBlueprint, i as cutBlueprints, n as fuse2D, o as intersectBlueprints, r as intersect2D, s as polysidesBlueprint, t as cut2D } from "./boolean2D-BuM5xJSa.js";
29
- import { S as reverseCurve, _ as curve2dIsOnCurve, a as isInside2D, b as curve2dSplitAt, c as scale2D, d as stretch2D, f as toSVGPathD, g as curve2dFirstPoint, h as curve2dDistanceFrom, i as getOrientation2D, l as sketchOnFace2D, m as curve2dBoundingBox, n as createCompoundBlueprint, o as mirror2D, p as translate2D, r as getBounds2D, s as rotate2D, t as createBlueprint, u as sketchOnPlane2D, v as curve2dLastPoint, x as curve2dTangentAt, y as curve2dParameter } from "./blueprintFns-COSD5yZH.js";
30
- import { a as importSVG, c as blueprintToDXF, d as exportGltf, f as exportOBJ, i as exportSTEPConfigured, l as exportDXF, n as importSTEP, o as importSVGPathD, r as importSTL, s as exportThreeMF, t as importIGES, u as exportGlb } from "./importFns-BId6d2pt.js";
31
- import { a as multiSectionSweep, c as twistExtrude, i as guidedSweep, n as loftAll, o as supportExtrude, r as complexExtrude, s as sweep$1, t as loft$2 } from "./loftFns-m7LoJWE2.js";
32
- import { a as Sketch, b as extrudeAll, c as compoundSketchLoft, d as sketchFace, f as sketchLoft, h as sketchWires, i as Sketches, l as compoundSketchRevolve, m as sketchSweep, n as getFont, o as compoundSketchExtrude, p as sketchRevolve, r as loadFont, s as compoundSketchFace, t as textBlueprints, u as sketchExtrude, v as CompoundSketch, x as revolve$2, y as extrude$2 } from "./textBlueprints-myJW6Fzl.js";
33
- import { _ as createRef, a as isVertexRef, b as defaultScorer, c as resolveRefParams, d as createVertexRef, f as resolveVertexRef, g as captureHint, h as assignRoles, i as isLineageRef, l as createDerivedFaceRef, m as resolveEdgeRef, n as isEdgeRef, o as resolveLineageRef, p as createEdgeRef, r as isFaceRef, s as resolveRefIn, t as isDerivedFaceRef, u as resolveDerivedFaceRef, v as resolveRef, y as updateRoles } from "./refResolveFns-DcyIQSDi.js";
34
- import { a as facesOfVertex, c as verticesOfFace, i as facesOfEdge, l as wiresOfFace, n as adjacentFaces, o as sharedEdges, r as edgesOfFace, s as verticesOfEdge } from "./adjacencyFns-CwcdjOsT.js";
35
- import { a as makeProjectedEdges, i as projectEdges, n as cameraLookAt, r as createCamera, s as isProjectionPlane, t as cameraFromPlane } from "./cameraFns-VVI0cWLa.js";
36
- import { n as textMetrics, r as sketchText, t as fontMetrics } from "./textMetrics-CPFqh2a1.js";
19
+ import { _ as makeThreePointArc, d as makeCircle, h as makeLine, l as makeBSplineInterpolation, n as fill, p as makeEllipseArc, r as makeFace, s as assembleWire, u as makeBezierCurve } from "./surfaceBuilders-Dcf7LRqM.js";
20
+ import { A as toBufferGeometryData, C as chamfer$2, D as shell$2, E as offset$1, M as toLODGeometryData, N as toLODGeometryLevels, O as thicken$1, P as toLineGeometryData, S as chamferDistAngle, T as fillet$2, _ as checkBoolean, a as healFace, b as getNurbsCurveData, c as isValid$1, d as chamferWithEvolution, f as cutWithEvolution, g as shellWithEvolution, h as intersectWithEvolution, i as heal$1, j as toGroupedBufferGeometryData, k as variableFillet, l as solidFromShell, m as fuseWithEvolution, n as fixSelfIntersection, o as healSolid, p as filletWithEvolution, r as fixShape, s as healWire, t as autoHeal, u as positionOnCurve, v as cutAllBisect, w as draft$1, x as getNurbsSurfaceData, y as fuseAllBisect } from "./healingFns-DAVYFXVB.js";
21
+ import { A as setJointValue, B as walkAssembly, C as cylindricalJoint, D as planarJoint, E as mechanismDOF, F as countNodes, G as quatFromAxisAngle, H as circularPattern, I as createAssemblyNode, J as quatRotate, K as quatFromTo, L as findNode, M as sphericalJoint, N as addChild, O as prismaticJoint, P as collectShapes, R as removeChild, S as addJoint, T as jointTransform, U as gridPattern, V as exportAssemblySTEP, W as linearPattern, Y as createAssembly, _ as exportURDF, a as deserializeHistory, b as inverseKinematics, c as modifyStep, d as replayFrom, f as replayHistory, g as undoLast, h as stepsFrom, i as createRegistry, j as setJointValues, k as revoluteJoint, l as registerOperation, m as stepCount, n as addStep, o as findStep, p as serializeHistory, q as quatMultiply, r as createHistory, s as getShape, t as thread, u as registerShape, v as importURDF, w as forwardKinematics, x as jointTrajectory, y as jointsFromDH, z as updateNode } from "./threadFns-CQErpnNd.js";
22
+ import { n as BaseSketcher2d, r as organiseBlueprints, t as BlueprintSketcher } from "./blueprintSketcher-DI_qQhBg.js";
23
+ import { a as createTypedFinder, i as wireFinder, n as edgeFinder, r as faceFinder, t as getSingleFace } from "./helpers-CvwerZfP.js";
24
+ import { g as approximateAsSvgCompatibleCurve } from "./blueprint-BzDq9Rfb.js";
25
+ import { A as sketchEllipse, D as makeBaseBox, E as deserializeDrawing, F as sketchRectangle, I as sketchRoundedRectangle, L as FaceSketcher, M as sketchHelix, N as sketchParametricFunction, O as polysideInnerRadius, P as sketchPolysides, R as Sketcher, S as drawText, _ as drawPolysides, a as drawingIntersect, b as drawSingleCircle, c as rotateDrawing, d as drawFaceOutline, f as drawProjection, g as drawPointsInterpolation, h as drawParametricFunction, i as drawingFuse, j as sketchFaceOffset, k as sketchCircle, l as scaleDrawing, m as drawEllipse, n as drawingCut, o as drawingToSketchOnPlane, p as drawCircle, r as drawingFillet, s as mirrorDrawing, t as drawingChamfer, u as translateDrawing, v as drawRectangle, w as draw, x as drawSingleEllipse, y as drawRoundedRectangle } from "./drawFns-BAwR4uoC.js";
26
+ import { a as measureDistance, c as measureLinearProps, d as measureVolumeProps, i as measureCurvatureAtMid, l as measureSurfaceProps, n as measureArea, o as measureDistanceProps, r as measureCurvatureAt, s as measureLength, t as createDistanceQuery, u as measureVolume } from "./measureFns-DtiZvj_X.js";
27
+ import { t as cornerFinder } from "./cornerFinder-CBNgUcWy.js";
28
+ import { a as fuseBlueprints, c as roundedRectangleBlueprint, i as cutBlueprints, n as fuse2D, o as intersectBlueprints, r as intersect2D, s as polysidesBlueprint, t as cut2D } from "./boolean2D-CdDn7AFp.js";
29
+ import { S as reverseCurve, _ as curve2dIsOnCurve, a as isInside2D, b as curve2dSplitAt, c as scale2D, d as stretch2D, f as toSVGPathD, g as curve2dFirstPoint, h as curve2dDistanceFrom, i as getOrientation2D, l as sketchOnFace2D, m as curve2dBoundingBox, n as createCompoundBlueprint, o as mirror2D, p as translate2D, r as getBounds2D, s as rotate2D, t as createBlueprint, u as sketchOnPlane2D, v as curve2dLastPoint, x as curve2dTangentAt, y as curve2dParameter } from "./blueprintFns-B0wbS9PN.js";
30
+ import { a as importSVG, c as blueprintToDXF, d as exportGltf, f as exportOBJ, i as exportSTEPConfigured, l as exportDXF, n as importSTEP, o as importSVGPathD, r as importSTL, s as exportThreeMF, t as importIGES, u as exportGlb } from "./importFns-DSY1pI70.js";
31
+ import { a as multiSectionSweep, c as twistExtrude, i as guidedSweep, n as loftAll, o as supportExtrude, r as complexExtrude, s as sweep$1, t as loft$2 } from "./loftFns-Bl8reWqk.js";
32
+ import { a as Sketch, b as extrudeAll, c as compoundSketchLoft, d as sketchFace, f as sketchLoft, h as sketchWires, i as Sketches, l as compoundSketchRevolve, m as sketchSweep, n as getFont, o as compoundSketchExtrude, p as sketchRevolve, r as loadFont, s as compoundSketchFace, t as textBlueprints, u as sketchExtrude, v as CompoundSketch, x as revolve$2, y as extrude$2 } from "./textBlueprints-kwXeudLb.js";
33
+ import { _ as createRef, a as isVertexRef, b as defaultScorer, c as resolveRefParams, d as createVertexRef, f as resolveVertexRef, g as captureHint, h as assignRoles, i as isLineageRef, l as createDerivedFaceRef, m as resolveEdgeRef, n as isEdgeRef, o as resolveLineageRef, p as createEdgeRef, r as isFaceRef, s as resolveRefIn, t as isDerivedFaceRef, u as resolveDerivedFaceRef, v as resolveRef, y as updateRoles } from "./refResolveFns-BPnjuRUW.js";
34
+ import { a as facesOfVertex, c as verticesOfFace, i as facesOfEdge, l as wiresOfFace, n as adjacentFaces, o as sharedEdges, r as edgesOfFace, s as verticesOfEdge } from "./adjacencyFns-BMgFDWFO.js";
35
+ import { a as makeProjectedEdges, i as projectEdges, n as cameraLookAt, r as createCamera, s as isProjectionPlane, t as cameraFromPlane } from "./cameraFns-BqSTuHN2.js";
36
+ import { n as textMetrics, r as sketchText, t as fontMetrics } from "./textMetrics-BlhkYGHT.js";
37
37
  import { _ as isSuccessResponse, a as createWorkerClient, c as enqueueTask, d as rejectAll, f as isBatchRequest, g as isOperationRequest, h as isInitRequest, i as registerHandler, l as isEmpty$1, m as isErrorResponse, n as createOperationRegistry, o as createTaskQueue, p as isDisposeRequest, r as createWorkerHandler, s as dequeueTask, t as createWorkerPool, u as pendingCount } from "./workerPool-XcYX2UZ0.js";
38
38
  //#region \0rolldown/runtime.js
39
39
  var __defProp = Object.defineProperty;
@@ -1862,6 +1862,55 @@ function chamfer$1(target, ref, distance) {
1862
1862
  freeParams: depsOf(target, de)
1863
1863
  };
1864
1864
  }
1865
+ function hashShapeRef(h0, ref) {
1866
+ let h = fnvMixString(h0, ref.origin);
1867
+ h = fnvMixString(h, ref.role);
1868
+ const hint = ref.hint;
1869
+ h = fnvMixBool(h, hint.surfaceType !== void 0);
1870
+ if (hint.surfaceType !== void 0) h = fnvMixString(h, hint.surfaceType);
1871
+ h = fnvMixBool(h, hint.normal !== void 0);
1872
+ if (hint.normal) for (const c of hint.normal) h = fnvMixNumber(h, c);
1873
+ h = fnvMixBool(h, hint.centroid !== void 0);
1874
+ if (hint.centroid) for (const c of hint.centroid) h = fnvMixNumber(h, c);
1875
+ h = fnvMixBool(h, hint.area !== void 0);
1876
+ if (hint.area !== void 0) h = fnvMixNumber(h, hint.area);
1877
+ return h;
1878
+ }
1879
+ function copyShapeRef(ref) {
1880
+ const hint = ref.hint;
1881
+ return {
1882
+ origin: ref.origin,
1883
+ role: ref.role,
1884
+ hint: {
1885
+ entityType: "face",
1886
+ ...hint.surfaceType !== void 0 ? { surfaceType: hint.surfaceType } : {},
1887
+ ...hint.normal ? { normal: [...hint.normal] } : {},
1888
+ ...hint.centroid ? { centroid: [...hint.centroid] } : {},
1889
+ ...hint.area !== void 0 ? { area: hint.area } : {}
1890
+ }
1891
+ };
1892
+ }
1893
+ /** Hollow the evaluated target to walls of `thickness`, leaving the faces
1894
+ * named by `refs` open. Refs are serializable node data (the cache key stays
1895
+ * purely structural); they resolve against the materialized target at
1896
+ * evaluation, so an upstream parameter edit re-targets the same faces by
1897
+ * role. Ref order is content-significant. */
1898
+ function shell$1(target, refs, thickness) {
1899
+ const copied = refs.map(copyShapeRef);
1900
+ const te = asScalarExpr(thickness);
1901
+ let h = fnvMixInt32(startHash("Shell"), copied.length);
1902
+ h = mix(h, target);
1903
+ for (const ref of copied) h = hashShapeRef(h, ref);
1904
+ h = mix(h, te);
1905
+ return {
1906
+ kind: "Shell",
1907
+ target,
1908
+ refs: copied,
1909
+ thickness: te,
1910
+ structuralHash: h,
1911
+ freeParams: depsOf(target, te)
1912
+ };
1913
+ }
1865
1914
  /** Attach a color (hex string or RGB/RGBA tuple, canonicalized to RGBA) to
1866
1915
  * the evaluated result of `target`. Metadata rides beside the geometry: the
1867
1916
  * evaluator re-tags the shared target materialization with an independent
@@ -2015,7 +2064,8 @@ function outputKindOf(node) {
2015
2064
  case "Loft":
2016
2065
  case "Sweep":
2017
2066
  case "Fillet":
2018
- case "Chamfer": return "Solid";
2067
+ case "Chamfer":
2068
+ case "Shell": return "Solid";
2019
2069
  case "Profile": return "Face";
2020
2070
  case "Path": return "Wire";
2021
2071
  case "Compound": return "Compound";
@@ -3054,6 +3104,27 @@ function evalChamfer(node, ctx) {
3054
3104
  return chamfer$2(solid.value, [resolved.entity], distance.value);
3055
3105
  }
3056
3106
  //#endregion
3107
+ //#region src/csg/evaluators/shell.ts
3108
+ function evalShell(node, ctx) {
3109
+ const thickness = evalScalar(node.thickness, ctx.env, "Shell.thickness");
3110
+ if (!thickness.ok) return thickness;
3111
+ if (!Number.isFinite(thickness.value) || thickness.value <= 0) return err(validationError("CSG_SHELL_THICKNESS", `Shell.thickness must be positive, got ${thickness.value}`));
3112
+ if (node.refs.length === 0) return err(validationError("CSG_SHELL_REFS", "Shell needs at least one face ref"));
3113
+ const t = ctx.evalNode(node.target);
3114
+ if (!t.ok) return t;
3115
+ if (!isSolid(t.value)) return err(validationError("CSG_SHELL_TARGET", "Shell.target did not produce a Solid"));
3116
+ const solid = validSolid(t.value);
3117
+ if (!solid.ok) return err(validationError("CSG_SHELL_TARGET", solid.error));
3118
+ const faces = [];
3119
+ for (const ref of node.refs) {
3120
+ const resolved = resolveRefIn(ref, t.value);
3121
+ if (!resolved.ok) return err(validationError("CSG_SHELL_REF", `Shell ref '${ref.role}' did not resolve: ${resolved.reason}`));
3122
+ if (!isFace(resolved.entity)) return err(validationError("CSG_SHELL_REF", `Shell ref '${ref.role}' resolved to a non-face`));
3123
+ faces.push(resolved.entity);
3124
+ }
3125
+ return shell$2(solid.value, faces, thickness.value);
3126
+ }
3127
+ //#endregion
3057
3128
  //#region src/csg/evaluate.ts
3058
3129
  function dispatch(node, ctx) {
3059
3130
  switch (node.kind) {
@@ -3086,7 +3157,8 @@ function dispatch(node, ctx) {
3086
3157
  case "Profile":
3087
3158
  case "Color":
3088
3159
  case "Fillet":
3089
- case "Chamfer": return dispatchFeature(node, ctx);
3160
+ case "Chamfer":
3161
+ case "Shell": return dispatchFeature(node, ctx);
3090
3162
  }
3091
3163
  }
3092
3164
  function dispatchFeature(node, ctx) {
@@ -3100,6 +3172,7 @@ function dispatchFeature(node, ctx) {
3100
3172
  case "Color": return evalColor(node, ctx);
3101
3173
  case "Fillet": return evalFillet(node, ctx);
3102
3174
  case "Chamfer": return evalChamfer(node, ctx);
3175
+ case "Shell": return evalShell(node, ctx);
3103
3176
  }
3104
3177
  }
3105
3178
  function hashExprValue(h, v) {
@@ -3509,7 +3582,7 @@ function withEvaluator(options, fn) {
3509
3582
  var MIN_CSG_VERSION = 1;
3510
3583
  function toJSON(node) {
3511
3584
  return {
3512
- csgVersion: 6,
3585
+ csgVersion: 7,
3513
3586
  root: nodeToJson(node)
3514
3587
  };
3515
3588
  }
@@ -3676,6 +3749,19 @@ function edgeRefToJson(ref) {
3676
3749
  }
3677
3750
  };
3678
3751
  }
3752
+ function shapeRefToJson(ref) {
3753
+ return {
3754
+ origin: ref.origin,
3755
+ role: ref.role,
3756
+ hint: {
3757
+ entityType: "face",
3758
+ surfaceType: ref.hint.surfaceType,
3759
+ normal: ref.hint.normal ? [...ref.hint.normal] : void 0,
3760
+ centroid: ref.hint.centroid ? [...ref.hint.centroid] : void 0,
3761
+ area: ref.hint.area
3762
+ }
3763
+ };
3764
+ }
3679
3765
  function contourToJson(c) {
3680
3766
  return {
3681
3767
  start: exprToJson(c.start),
@@ -3762,6 +3848,12 @@ function nodeToJson(n) {
3762
3848
  ref: edgeRefToJson(n.ref),
3763
3849
  distance: exprToJson(n.distance)
3764
3850
  };
3851
+ if (n.kind === "Shell") return {
3852
+ kind: "Shell",
3853
+ target: nodeToJson(n.target),
3854
+ refs: n.refs.map(shapeRefToJson),
3855
+ thickness: exprToJson(n.thickness)
3856
+ };
3765
3857
  if (n.kind === "Compound") return {
3766
3858
  kind: "Compound",
3767
3859
  children: n.children.map(nodeToJson)
@@ -3805,7 +3897,7 @@ function readVec2(v, where) {
3805
3897
  function fromJSON(envelope) {
3806
3898
  if (!isObj(envelope)) return bad("input is not an object");
3807
3899
  const v = envelope["csgVersion"];
3808
- if (typeof v !== "number" || !Number.isInteger(v) || v < MIN_CSG_VERSION || v > 6) return bad(`unsupported csgVersion ${String(v)} (expected ${MIN_CSG_VERSION}..6)`);
3900
+ if (typeof v !== "number" || !Number.isInteger(v) || v < MIN_CSG_VERSION || v > 7) return bad(`unsupported csgVersion ${String(v)} (expected ${MIN_CSG_VERSION}..7)`);
3809
3901
  const root = envelope["root"];
3810
3902
  return readNode(root);
3811
3903
  }
@@ -3922,6 +4014,7 @@ function readNode(j) {
3922
4014
  case "Color": return readColor(j);
3923
4015
  case "Fillet": return readFillet(j);
3924
4016
  case "Chamfer": return readChamfer(j);
4017
+ case "Shell": return readShell(j);
3925
4018
  default: return bad(`unknown node kind: ${String(kind)}`);
3926
4019
  }
3927
4020
  }
@@ -4197,6 +4290,70 @@ function readEdgeRef(j, where) {
4197
4290
  }
4198
4291
  });
4199
4292
  }
4293
+ var SURFACE_TYPES = /* @__PURE__ */ new Set([
4294
+ "PLANE",
4295
+ "CYLINDRE",
4296
+ "CONE",
4297
+ "SPHERE",
4298
+ "TORUS",
4299
+ "BEZIER_SURFACE",
4300
+ "BSPLINE_SURFACE",
4301
+ "REVOLUTION_SURFACE",
4302
+ "EXTRUSION_SURFACE",
4303
+ "OFFSET_SURFACE",
4304
+ "OTHER_SURFACE"
4305
+ ]);
4306
+ function readShapeRef(j, where) {
4307
+ if (!isObj(j)) return bad(`${where}: not an object`);
4308
+ const origin = j["origin"];
4309
+ if (!isString(origin)) return bad(`${where}.origin: not a string`);
4310
+ const role = j["role"];
4311
+ if (!isString(role)) return bad(`${where}.role: not a string`);
4312
+ const hintRaw = j["hint"];
4313
+ if (!isObj(hintRaw)) return bad(`${where}.hint: not an object`);
4314
+ const surfaceType = hintRaw["surfaceType"];
4315
+ if (surfaceType !== void 0 && (!isString(surfaceType) || !SURFACE_TYPES.has(surfaceType))) return bad(`${where}.hint.surfaceType`);
4316
+ const area = hintRaw["area"];
4317
+ if (area !== void 0 && !isNumber$1(area)) return bad(`${where}.hint.area`);
4318
+ let normal;
4319
+ if (hintRaw["normal"] !== void 0) {
4320
+ const n = readVec3(hintRaw["normal"], `${where}.hint.normal`);
4321
+ if (!n.ok) return n;
4322
+ normal = n.value;
4323
+ }
4324
+ let centroid;
4325
+ if (hintRaw["centroid"] !== void 0) {
4326
+ const c = readVec3(hintRaw["centroid"], `${where}.hint.centroid`);
4327
+ if (!c.ok) return c;
4328
+ centroid = c.value;
4329
+ }
4330
+ return ok({
4331
+ origin,
4332
+ role,
4333
+ hint: {
4334
+ entityType: "face",
4335
+ ...surfaceType !== void 0 ? { surfaceType } : {},
4336
+ ...normal ? { normal } : {},
4337
+ ...centroid ? { centroid } : {},
4338
+ ...area !== void 0 ? { area } : {}
4339
+ }
4340
+ });
4341
+ }
4342
+ function readShell(j) {
4343
+ const target = readNode(j["target"]);
4344
+ if (!target.ok) return target;
4345
+ const thickness = readExpr(j["thickness"]);
4346
+ if (!thickness.ok) return thickness;
4347
+ const rawRefs = j["refs"];
4348
+ if (!Array.isArray(rawRefs) || rawRefs.length === 0) return bad("Shell.refs: expected a non-empty array");
4349
+ const refs = [];
4350
+ for (const [i, raw] of rawRefs.entries()) {
4351
+ const ref = readShapeRef(raw, `Shell.refs[${i}]`);
4352
+ if (!ref.ok) return ref;
4353
+ refs.push(ref.value);
4354
+ }
4355
+ return ok(shell$1(target.value, refs, thickness.value));
4356
+ }
4200
4357
  function readFillet(j) {
4201
4358
  const target = readNode(j["target"]);
4202
4359
  if (!target.ok) return target;
@@ -4375,7 +4532,8 @@ function optimizeNode(n) {
4375
4532
  case "Path":
4376
4533
  case "Color":
4377
4534
  case "Fillet":
4378
- case "Chamfer": return optimizeFeature(n);
4535
+ case "Chamfer":
4536
+ case "Shell": return optimizeFeature(n);
4379
4537
  }
4380
4538
  }
4381
4539
  function optimizeFeature(n) {
@@ -4392,6 +4550,7 @@ function optimizeFeature(n) {
4392
4550
  case "Color": return color(optimizeNode(n.target), [...n.color]);
4393
4551
  case "Fillet": return fillet$1(optimizeNode(n.target), n.ref, foldExpr(n.radius));
4394
4552
  case "Chamfer": return chamfer$1(optimizeNode(n.target), n.ref, foldExpr(n.distance));
4553
+ case "Shell": return shell$1(optimizeNode(n.target), n.refs, foldExpr(n.thickness));
4395
4554
  }
4396
4555
  }
4397
4556
  function optimizeTransform(n) {
@@ -4503,7 +4662,8 @@ function rebuildChildren(n, pred, repl) {
4503
4662
  case "Sweep":
4504
4663
  case "Color":
4505
4664
  case "Fillet":
4506
- case "Chamfer": return rebuildFeature(n, pred, repl);
4665
+ case "Chamfer":
4666
+ case "Shell": return rebuildFeature(n, pred, repl);
4507
4667
  }
4508
4668
  }
4509
4669
  function rebuildFeature(n, pred, repl) {
@@ -4518,6 +4678,7 @@ function rebuildFeature(n, pred, repl) {
4518
4678
  case "Color": return color(walk(n.target, pred, repl), [...n.color]);
4519
4679
  case "Fillet": return fillet$1(walk(n.target, pred, repl), n.ref, n.radius);
4520
4680
  case "Chamfer": return chamfer$1(walk(n.target, pred, repl), n.ref, n.distance);
4681
+ case "Shell": return shell$1(walk(n.target, pred, repl), n.refs, n.thickness);
4521
4682
  }
4522
4683
  }
4523
4684
  function forEachNode(root, fn) {
@@ -4549,7 +4710,8 @@ function childrenOf(n) {
4549
4710
  case "Mirror":
4550
4711
  case "Color":
4551
4712
  case "Fillet":
4552
- case "Chamfer": return [n.target];
4713
+ case "Chamfer":
4714
+ case "Shell": return [n.target];
4553
4715
  case "Compound": return n.children;
4554
4716
  case "Instance": return [n.source];
4555
4717
  case "Extrude":
@@ -7160,7 +7322,7 @@ function chamfer(shape, edgesOrDistance, maybeDistance) {
7160
7322
  function shell(shape, faces, thickness, options) {
7161
7323
  const s = resolve(shape);
7162
7324
  const resolvedFaces = resolveFaces(faces, s);
7163
- return shell$1(s, resolvedFaces, thickness, options?.tolerance);
7325
+ return shell$2(s, resolvedFaces, thickness, options?.tolerance);
7164
7326
  }
7165
7327
  /** Offset all faces of a valid solid by a given distance. */
7166
7328
  function offset(shape, distance, options) {
@@ -8559,7 +8721,7 @@ var patterns_exports = /* @__PURE__ */ __exportAll({
8559
8721
  //#endregion
8560
8722
  //#region src/ns/csg.ts
8561
8723
  var csg_exports = /* @__PURE__ */ __exportAll({
8562
- CSG_VERSION: () => 6,
8724
+ CSG_VERSION: () => 7,
8563
8725
  Evaluator: () => Evaluator,
8564
8726
  add: () => add$1,
8565
8727
  arbitraryClosedProfile: () => arbitraryClosedProfile,
@@ -8621,6 +8783,7 @@ var csg_exports = /* @__PURE__ */ __exportAll({
8621
8783
  revolve: () => revolve$1,
8622
8784
  rotate: () => rotate$1,
8623
8785
  scale: () => scale$2,
8786
+ shell: () => shell$1,
8624
8787
  sphere: () => sphere$2,
8625
8788
  sweep: () => sweep$2,
8626
8789
  tShapeProfile: () => tShapeProfile,
@@ -1,8 +1,8 @@
1
- import { K as getKernel, W as _usingCtx, n as castResultShape } from "./shapeTypes-pxoxsXIo.js";
1
+ import { K as getKernel, W as _usingCtx, n as castResultShape } from "./shapeTypes-D3bntzog.js";
2
2
  import { E as ok, P as unwrap, d as validationError, g as err } from "./errors-MHLiNE-C.js";
3
- import { s as getEdges } from "./topologyQueryFns-CwYkfE3v.js";
3
+ import { s as getEdges } from "./topologyQueryFns-qvptbhqO.js";
4
4
  import { c as vecLength, d as vecNormalize, g as vecSub, r as vecCross } from "./vecOps-SKPRvPH-.js";
5
- import { t as clone } from "./shapeFns-DyDRpo6K.js";
5
+ import { t as clone } from "./shapeFns-s6VgcNkU.js";
6
6
  //#region src/projection/projectionPlanes.ts
7
7
  /** Lookup table mapping each {@link ProjectionPlane} to its camera configuration. */
8
8
  var PROJECTION_PLANES = {
@@ -1,8 +1,8 @@
1
- const require_shapeTypes = require("./shapeTypes-DVExh1xP.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-Dz5JzlYx.cjs");
2
2
  const require_errors = require("./errors-RHkKO5bZ.cjs");
3
- const require_topologyQueryFns = require("./topologyQueryFns-BtLGfXgL.cjs");
3
+ const require_topologyQueryFns = require("./topologyQueryFns-DzYSYw51.cjs");
4
4
  const require_vecOps = require("./vecOps-CCnJt-yH.cjs");
5
- const require_shapeFns = require("./shapeFns-DDTLk0mJ.cjs");
5
+ const require_shapeFns = require("./shapeFns-xApQafn6.cjs");
6
6
  //#region src/projection/projectionPlanes.ts
7
7
  /** Lookup table mapping each {@link ProjectionPlane} to its camera configuration. */
8
8
  var PROJECTION_PLANES = {
package/dist/core.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_shapeTypes = require("./shapeTypes-DVExh1xP.cjs");
2
+ const require_shapeTypes = require("./shapeTypes-Dz5JzlYx.cjs");
3
3
  const require_bug = require("./bug-O02CsAmt.cjs");
4
4
  const require_errors = require("./errors-RHkKO5bZ.cjs");
5
- const require_validityTypes = require("./validityTypes-C2nklkrH.cjs");
5
+ const require_validityTypes = require("./validityTypes-Beci6AC-.cjs");
6
6
  const require_constants = require("./constants-BOVyEYGH.cjs");
7
7
  const require_types = require("./types-KjA8tY4Y.cjs");
8
8
  const require_vecOps = require("./vecOps-CCnJt-yH.cjs");
package/dist/core.js CHANGED
@@ -1,7 +1,7 @@
1
- import { A as is2D, C as isSolid, E as getShapeKind, H as withScopeResult, I as isLive, M as DisposalScope, N as createHandle, P as createKernelHandle, S as isShell, T as isWire, U as withScopeResultAsync, V as withScope, _ as isCompound, b as isShape1D, i as castShape, j as is3D, v as isEdge, w as isVertex, x as isShape3D, y as isFace } from "./shapeTypes-pxoxsXIo.js";
1
+ import { A as is2D, C as isSolid, E as getShapeKind, H as withScopeResult, I as isLive, M as DisposalScope, N as createHandle, P as createKernelHandle, S as isShell, T as isWire, U as withScopeResultAsync, V as withScope, _ as isCompound, b as isShape1D, i as castShape, j as is3D, v as isEdge, w as isVertex, x as isShape3D, y as isFace } from "./shapeTypes-D3bntzog.js";
2
2
  import { n as bug, t as BrepBugError } from "./bug-BdOHwn_e.js";
3
3
  import { E as ok, F as unwrapErr, I as unwrapOr, L as unwrapOrElse, M as tryCatch, N as tryCatchAsync, P as unwrap, S as map, T as match, _ as flatMap, a as moduleInitError, b as isErr, c as sketcherStateError, d as validationError, f as OK, g as err, h as collect, i as kernelError, l as typeCastError, m as andThen, n as computationError, o as queryError, r as ioError, u as unsupportedError, w as mapErr, x as isOk } from "./errors-MHLiNE-C.js";
4
- import { c as manifoldShell, f as validSolid, i as isOrientedFace, l as orientedFace, n as isClosedWire, r as isManifoldShell, s as isValidSolid, t as closedWire } from "./validityTypes-Bl3adWZb.js";
4
+ import { c as manifoldShell, f as validSolid, i as isOrientedFace, l as orientedFace, n as isClosedWire, r as isManifoldShell, s as isValidSolid, t as closedWire } from "./validityTypes-DF2h0WJo.js";
5
5
  import { n as HASH_CODE_MAX, r as RAD2DEG, t as DEG2RAD } from "./constants-ITRzCnCp.js";
6
6
  import { n as toVec2, r as toVec3, t as resolveDirection } from "./types-D24Y27N0.js";
7
7
  import { a as vecDot, c as vecLength, d as vecNormalize, f as vecProjectToPlane, g as vecSub, h as vecScale, i as vecDistance, l as vecLengthSq, m as vecRotate, n as vecAngle, o as vecEquals, p as vecRepr, r as vecCross, s as vecIsZero, t as vecAdd, u as vecNegate } from "./vecOps-SKPRvPH-.js";
@@ -1,6 +1,6 @@
1
1
  import { t as DEG2RAD } from "./constants-ITRzCnCp.js";
2
2
  import { n as getAtOrThrow } from "./arrayAccess-DrUGPADn.js";
3
- import { _ as samePoint, f as distance2d, l as angle2d } from "./helpers-BiqV-wPK.js";
3
+ import { p as distance2d, u as angle2d, v as samePoint } from "./helpers-CvwerZfP.js";
4
4
  //#region src/query/cornerFinder.ts
5
5
  var PI_2 = 2 * Math.PI;
6
6
  function positiveHalfAngle(angle) {
@@ -1,6 +1,6 @@
1
1
  const require_constants = require("./constants-BOVyEYGH.cjs");
2
2
  const require_arrayAccess = require("./arrayAccess-e4H9cBfh.cjs");
3
- const require_helpers = require("./helpers-DLZUxawd.cjs");
3
+ const require_helpers = require("./helpers-C9PIppuU.cjs");
4
4
  //#region src/query/cornerFinder.ts
5
5
  var PI_2 = 2 * Math.PI;
6
6
  function positiveHalfAngle(angle) {
@@ -2,8 +2,8 @@ import { ScalarInput, Vec2Input, Vec3Input } from './expressions.js';
2
2
  import { Contour, Segment2D } from './segments.js';
3
3
  import { Matrix4x4 } from '../core/types.js';
4
4
  import { ColorInput } from '../topology/metadata/colorFns.js';
5
- import { EdgeRef } from '../topology/shapeRef/shapeRefTypes.js';
6
- import { BoxNode, SphereNode, CylinderNode, ConeNode, TorusNode, PolygonNode, CircleNode, LineNode, VertexLitNode, EmptyNode, FuseNode, CutNode, IntersectNode, FuseAllNode, CutAllNode, TranslateNode, RotateNode, ScaleNode, MirrorNode, ExtrudeNode, RevolveNode, LoftNode, SweepNode, ProfileNode, PathNode, ColorNode, FilletNode, ChamferNode, CompoundNode, InstanceNode, IRNode, SolidNode, FaceNode, EdgeNode, VertexNode } from './types.js';
5
+ import { EdgeRef, ShapeRef } from '../topology/shapeRef/shapeRefTypes.js';
6
+ import { BoxNode, SphereNode, CylinderNode, ConeNode, TorusNode, PolygonNode, CircleNode, LineNode, VertexLitNode, EmptyNode, FuseNode, CutNode, IntersectNode, FuseAllNode, CutAllNode, TranslateNode, RotateNode, ScaleNode, MirrorNode, ExtrudeNode, RevolveNode, LoftNode, SweepNode, ProfileNode, PathNode, ColorNode, ShellNode, FilletNode, ChamferNode, CompoundNode, InstanceNode, IRNode, SolidNode, FaceNode, EdgeNode, VertexNode } from './types.js';
7
7
  export declare function box(x: ScalarInput, y: ScalarInput, z: ScalarInput): BoxNode;
8
8
  export declare function sphere(radius: ScalarInput): SphereNode;
9
9
  export declare function cylinder(radius: ScalarInput, height: ScalarInput): CylinderNode;
@@ -41,6 +41,12 @@ export declare function fillet(target: IRNode, ref: EdgeRef, radius: ScalarInput
41
41
  /** Chamfer the edge named by a lineage ref on the evaluated target. Same
42
42
  * contract as `fillet`: the ref is deep-copied, serializable node data. */
43
43
  export declare function chamfer(target: IRNode, ref: EdgeRef, distance: ScalarInput): ChamferNode;
44
+ /** Hollow the evaluated target to walls of `thickness`, leaving the faces
45
+ * named by `refs` open. Refs are serializable node data (the cache key stays
46
+ * purely structural); they resolve against the materialized target at
47
+ * evaluation, so an upstream parameter edit re-targets the same faces by
48
+ * role. Ref order is content-significant. */
49
+ export declare function shell(target: IRNode, refs: ReadonlyArray<ShapeRef>, thickness: ScalarInput): ShellNode;
44
50
  /** Attach a color (hex string or RGB/RGBA tuple, canonicalized to RGBA) to
45
51
  * the evaluated result of `target`. Metadata rides beside the geometry: the
46
52
  * evaluator re-tags the shared target materialization with an independent
@@ -0,0 +1,5 @@
1
+ import { Result } from '../../core/result.js';
2
+ import { AnyShape, Dimension } from '../../core/shapeTypes.js';
3
+ import { ShellNode } from '../types.js';
4
+ import { EvalContext } from './context.js';
5
+ export declare function evalShell(node: ShellNode, ctx: EvalContext): Result<AnyShape<Dimension>>;
@@ -5,9 +5,9 @@
5
5
  * parameterize via named expression bindings; evaluate against the active
6
6
  * kernel with subtree-level cache reuse for incremental parametric edits.
7
7
  */
8
- export { box, sphere, cylinder, cone, torus, polygon, circle, line, vertex, emptySolid, emptyFace, emptyWire, fuse, cut, intersect, fuseAll, cutAll, translate, rotate, scale, mirror, extrude, revolve, loft, sweep, profile, path, color, fillet, chamfer, compound, instance, type RevolveOptions, type LoftOptions, type SweepNodeOptions, type RotateOptions, type ScaleOptions, type MirrorOptions, } from './builders.js';
8
+ export { box, sphere, cylinder, cone, torus, polygon, circle, line, vertex, emptySolid, emptyFace, emptyWire, fuse, cut, intersect, fuseAll, cutAll, translate, rotate, scale, mirror, extrude, revolve, loft, sweep, profile, path, color, fillet, chamfer, shell, compound, instance, type RevolveOptions, type LoftOptions, type SweepNodeOptions, type RotateOptions, type ScaleOptions, type MirrorOptions, } from './builders.js';
9
9
  export { numLit, vec3Lit, vec2Lit, param, binOp, unaryOp, component, buildVec, add, mul, asScalarExpr, asVec3Expr, asVec2Expr, type Expr, type ExprValue, type Env, type ScalarInput, type Vec3Input, type Vec2Input, type BinaryOp, type UnaryOp, } from './expressions.js';
10
- export type { IRNode, NodeKind, OutputKind, PrimitiveNode, BooleanNode, TransformIRNode, ExtrudeNode, RevolveNode, LoftNode, SweepNode, ProfileNode, PathNode, ColorNode, FilletNode, ChamferNode, InstanceNode, SolidNode, FaceNode, EdgeNode, VertexNode, AnyNode, } from './types.js';
10
+ export type { IRNode, NodeKind, OutputKind, PrimitiveNode, BooleanNode, TransformIRNode, ExtrudeNode, RevolveNode, LoftNode, SweepNode, ProfileNode, PathNode, ColorNode, FilletNode, ChamferNode, ShellNode, InstanceNode, SolidNode, FaceNode, EdgeNode, VertexNode, AnyNode, } from './types.js';
11
11
  export { outputKindOf } from './types.js';
12
12
  export { lineTo, arcTo, bezierTo, ellipseArcTo, contour, type Contour, type Segment2D, type SegmentOptions, type EllipseArcOptions, } from './segments.js';
13
13
  export { rectangularProfile, circularProfile, iBeamProfile, asymmetricIProfile, lShapeProfile, tShapeProfile, uShapeProfile, zShapeProfile, cShapeProfile, ellipseProfile, trapeziumProfile, rectangleHollowProfile, circleHollowProfile, arbitraryClosedProfile, arbitraryProfileWithVoids, type IBeamParams, type AsymmetricIParams, type LShapeParams, type TShapeParams, type UShapeParams, type ZShapeParams, type CShapeParams, type TrapeziumParams, type RectangleHollowParams, type CircleHollowParams, } from './profiles.js';
@@ -1,6 +1,6 @@
1
1
  import { Result } from '../core/result.js';
2
2
  import { IRNode } from './types.js';
3
- export declare const CSG_VERSION = 6;
3
+ export declare const CSG_VERSION = 7;
4
4
  export interface CsgEnvelope {
5
5
  readonly csgVersion: number;
6
6
  readonly root: unknown;
@@ -1,6 +1,6 @@
1
1
  import { Expr } from './expressions.js';
2
2
  import { Contour, Segment2D } from './segments.js';
3
- import { EdgeRef } from '../topology/shapeRef/shapeRefTypes.js';
3
+ import { EdgeRef, ShapeRef } from '../topology/shapeRef/shapeRefTypes.js';
4
4
  import { Matrix4x4 } from '../core/types.js';
5
5
  export type OutputKind = 'Solid' | 'Face' | 'Wire' | 'Edge' | 'Vertex' | 'Compound';
6
6
  /** Output kinds that have a corresponding empty-shape builder + serializer. */
@@ -141,6 +141,14 @@ export interface ChamferNode extends IRNodeBase {
141
141
  readonly ref: EdgeRef;
142
142
  readonly distance: Expr;
143
143
  }
144
+ export interface ShellNode extends IRNodeBase {
145
+ readonly kind: 'Shell';
146
+ readonly target: IRNode;
147
+ /** Faces left open, named by serializable role refs. Order is
148
+ * content-significant (it enters the structural hash). */
149
+ readonly refs: readonly ShapeRef[];
150
+ readonly thickness: Expr;
151
+ }
144
152
  export interface ColorNode extends IRNodeBase {
145
153
  readonly kind: 'Color';
146
154
  readonly target: IRNode;
@@ -193,7 +201,7 @@ export interface InstanceNode extends IRNodeBase {
193
201
  export type PrimitiveNode = BoxNode | SphereNode | CylinderNode | ConeNode | TorusNode | PolygonNode | CircleNode | LineNode | VertexLitNode | EmptyNode;
194
202
  export type BooleanNode = FuseNode | CutNode | IntersectNode | FuseAllNode | CutAllNode;
195
203
  export type TransformIRNode = TranslateNode | RotateNode | ScaleNode | MirrorNode;
196
- export type IRNode = PrimitiveNode | BooleanNode | TransformIRNode | ExtrudeNode | RevolveNode | LoftNode | SweepNode | ProfileNode | PathNode | ColorNode | FilletNode | ChamferNode | CompoundNode | InstanceNode;
204
+ export type IRNode = PrimitiveNode | BooleanNode | TransformIRNode | ExtrudeNode | RevolveNode | LoftNode | SweepNode | ProfileNode | PathNode | ColorNode | FilletNode | ChamferNode | ShellNode | CompoundNode | InstanceNode;
197
205
  export type NodeKind = IRNode['kind'];
198
206
  export type AnyNode = IRNode;
199
207
  /** Nodes that produce a 3D solid. */
@@ -1,4 +1,4 @@
1
- const require_shapeTypes = require("./shapeTypes-DVExh1xP.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-Dz5JzlYx.cjs");
2
2
  const require_errors = require("./errors-RHkKO5bZ.cjs");
3
3
  //#region src/topology/curveFns.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { K as getKernel, T as isWire, h as disposeResultShape, n as castResultShape, v as isEdge } from "./shapeTypes-pxoxsXIo.js";
1
+ import { K as getKernel, T as isWire, h as disposeResultShape, n as castResultShape, v as isEdge } from "./shapeTypes-D3bntzog.js";
2
2
  import { E as ok, g as err, l as typeCastError } from "./errors-MHLiNE-C.js";
3
3
  //#region src/topology/curveFns.ts
4
4
  /**
@@ -1,22 +1,22 @@
1
- import { K as getKernel, M as DisposalScope, W as _usingCtx, c as createEdge, l as createFace, p as createWire } from "./shapeTypes-pxoxsXIo.js";
1
+ import { K as getKernel, M as DisposalScope, W as _usingCtx, c as createEdge, l as createFace, p as createWire } from "./shapeTypes-D3bntzog.js";
2
2
  import { i as wasmIndex, n as bug } from "./bug-BdOHwn_e.js";
3
3
  import { P as unwrap, s as safeIndex } from "./errors-MHLiNE-C.js";
4
- import { s as getEdges } from "./topologyQueryFns-CwYkfE3v.js";
4
+ import { s as getEdges } from "./topologyQueryFns-qvptbhqO.js";
5
5
  import { t as DEG2RAD } from "./constants-ITRzCnCp.js";
6
6
  import { r as toVec3 } from "./types-D24Y27N0.js";
7
7
  import { d as vecNormalize, g as vecSub, h as vecScale, m as vecRotate, r as vecCross } from "./vecOps-SKPRvPH-.js";
8
8
  import { a as planeToWorld, o as resolvePlane } from "./planeOps-CQahLrCx.js";
9
- import { d as pointOnSurface, l as normalAt, m as uvBounds, r as faceCenter, u as outerWire, v as copyShape, y as downcast } from "./faceFns-CaBQNffu.js";
10
- import { h as offsetWire2D, i as curveIsClosed, l as curveStartPoint } from "./curveFns-Bh_PHl9N.js";
9
+ import { d as pointOnSurface, l as normalAt, m as uvBounds, r as faceCenter, u as outerWire, v as copyShape, y as downcast } from "./faceFns-BfTHYEiw.js";
10
+ import { h as offsetWire2D, i as curveIsClosed, l as curveStartPoint } from "./curveFns-BtXR6kJ7.js";
11
11
  import { n as getAtOrThrow, r as lastOrThrow, t as firstOrThrow } from "./arrayAccess-DrUGPADn.js";
12
- import { c as makeBSplineApproximation, d as makeCircle, f as makeEllipse, m as makeHelix, r as makeFace, s as assembleWire } from "./surfaceBuilders-B7WlmoVr.js";
13
- import { a as Blueprints, c as make2dOffset, i as CompoundBlueprint, l as intersectCurves, n as BaseSketcher2d, o as chamferCurves, s as filletCurves, u as Flatbush } from "./blueprintSketcher-yZiAeqft.js";
14
- import { _ as samePoint$1, b as subtract2d, c as add2d, s as PRECISION_OFFSET, y as squareDistance2d } from "./helpers-BiqV-wPK.js";
15
- import { _ as Curve2D, a as edgeToCurve, b as BoundingBox2d, c as make2dCircle, d as make2dInerpolatedBSplineCurve, f as make2dSegmentCurve, g as approximateAsSvgCompatibleCurve, i as curvesAsEdgesOnPlane, l as make2dEllipse, o as make2dArcFromCenter, t as Blueprint, v as deserializeCurve2D } from "./blueprint-DRvc1LOz.js";
16
- import { t as cornerFinder } from "./cornerFinder-CiHpo7kU.js";
17
- import { c as roundedRectangleBlueprint, n as fuse2D, r as intersect2D, s as polysidesBlueprint, t as cut2D } from "./boolean2D-BuM5xJSa.js";
18
- import { _ as wrapSketchDataArray, a as Sketch, g as wrapSketchData, i as Sketches, t as textBlueprints } from "./textBlueprints-myJW6Fzl.js";
19
- import { i as projectEdges, t as cameraFromPlane } from "./cameraFns-VVI0cWLa.js";
12
+ import { c as makeBSplineApproximation, d as makeCircle, f as makeEllipse, m as makeHelix, r as makeFace, s as assembleWire } from "./surfaceBuilders-Dcf7LRqM.js";
13
+ import { a as Blueprints, c as make2dOffset, i as CompoundBlueprint, l as intersectCurves, n as BaseSketcher2d, o as chamferCurves, s as filletCurves, u as Flatbush } from "./blueprintSketcher-DI_qQhBg.js";
14
+ import { b as squareDistance2d, l as add2d, s as PRECISION_OFFSET, v as samePoint$1, x as subtract2d } from "./helpers-CvwerZfP.js";
15
+ import { _ as Curve2D, a as edgeToCurve, b as BoundingBox2d, c as make2dCircle, d as make2dInerpolatedBSplineCurve, f as make2dSegmentCurve, g as approximateAsSvgCompatibleCurve, i as curvesAsEdgesOnPlane, l as make2dEllipse, o as make2dArcFromCenter, t as Blueprint, v as deserializeCurve2D } from "./blueprint-BzDq9Rfb.js";
16
+ import { t as cornerFinder } from "./cornerFinder-CBNgUcWy.js";
17
+ import { c as roundedRectangleBlueprint, n as fuse2D, r as intersect2D, s as polysidesBlueprint, t as cut2D } from "./boolean2D-CdDn7AFp.js";
18
+ import { _ as wrapSketchDataArray, a as Sketch, g as wrapSketchData, i as Sketches, t as textBlueprints } from "./textBlueprints-kwXeudLb.js";
19
+ import { i as projectEdges, t as cameraFromPlane } from "./cameraFns-BqSTuHN2.js";
20
20
  //#region src/2d/lib/stitching.ts
21
21
  /**
22
22
  * Group a flat list of curves into connected chains by matching endpoints.