@realsee/dnalogel 4.0.0-webgpu.3 → 4.0.0-webgpu.4

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 (147) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/floorplan.js +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +270 -35
  5. package/dist/index.js.map +1 -0
  6. package/dist/internal/{BasePlugin-CT5K8m36.js → BasePlugin-DC5m72La.js} +3 -3
  7. package/dist/internal/{BasePlugin-CT5K8m36.js.map → BasePlugin-DC5m72La.js.map} +1 -1
  8. package/dist/internal/BasePluginWithData-D_0W46_q.js +7 -0
  9. package/dist/internal/{BasePluginWithData-9z4tpAT4.js.map → BasePluginWithData-D_0W46_q.js.map} +1 -1
  10. package/dist/internal/{BetterTween-BX0aTvP1.js → BetterTween-DmptqE8m.js} +2 -2
  11. package/dist/internal/{BetterTween-BX0aTvP1.js.map → BetterTween-DmptqE8m.js.map} +1 -1
  12. package/dist/internal/{CSS3DRenderPlugin-ccSpcvwd.js → CSS3DRenderPlugin-CEatgl0m.js} +3 -3
  13. package/dist/internal/CSS3DRenderPlugin-CEatgl0m.js.map +1 -0
  14. package/dist/internal/{Controller-Csut_kcH.js → Controller-D6o4OGWJ.js} +8 -8
  15. package/dist/internal/{Controller-Csut_kcH.js.map → Controller-D6o4OGWJ.js.map} +1 -1
  16. package/dist/internal/{FiveDomEvents-3H9NvDOz.js → FiveDomEvents-BUBLFzti.js} +2 -2
  17. package/dist/internal/{FiveDomEvents-3H9NvDOz.js.map → FiveDomEvents-BUBLFzti.js.map} +1 -1
  18. package/dist/internal/FivePuppet-C6QmVY70.js +67 -0
  19. package/dist/internal/FivePuppet-C6QmVY70.js.map +1 -0
  20. package/dist/internal/{PointHelper-D565h9b_.js → PointHelper-DIhgdjY2.js} +48 -48
  21. package/dist/internal/{PointHelper-D565h9b_.js.map → PointHelper-DIhgdjY2.js.map} +1 -1
  22. package/dist/internal/{Polygon-CBGvYUfJ.js → Polygon-D3xIL1Pl.js} +30 -30
  23. package/dist/internal/{Polygon-CBGvYUfJ.js.map → Polygon-D3xIL1Pl.js.map} +1 -1
  24. package/dist/internal/{Prism-Dm5ESkgg.js → Prism-CJlyAEAU.js} +13 -13
  25. package/dist/internal/{Prism-Dm5ESkgg.js.map → Prism-CJlyAEAU.js.map} +1 -1
  26. package/dist/internal/{Rectangle-D-zkDycu.js → Rectangle-BpL9lNKU.js} +118 -129
  27. package/dist/internal/Rectangle-BpL9lNKU.js.map +1 -0
  28. package/dist/internal/{Work-DF8j5GnL.js → Work-BE4AgdwH.js} +9 -9
  29. package/dist/internal/{Work-DF8j5GnL.js.map → Work-BE4AgdwH.js.map} +1 -1
  30. package/dist/internal/{animationFrame-XGKHIeQK.js → animationFrame-CacKXN8l.js} +14 -3
  31. package/dist/internal/animationFrame-CacKXN8l.js.map +1 -0
  32. package/dist/internal/{area-maker-Bd9l2pIp.js → area-maker-Bnhx4SkH.js} +4 -4
  33. package/dist/internal/{area-maker-Bd9l2pIp.js.map → area-maker-Bnhx4SkH.js.map} +1 -1
  34. package/dist/internal/{boundingBox-DvCor5Hd.js → boundingBox-CIqXgNXW.js} +2 -2
  35. package/dist/internal/{boundingBox-DvCor5Hd.js.map → boundingBox-CIqXgNXW.js.map} +1 -1
  36. package/dist/internal/{camera-movement-CwI7UqUk.js → camera-movement-C1pwfMk_.js} +2 -2
  37. package/dist/internal/camera-movement-C1pwfMk_.js.map +1 -0
  38. package/dist/internal/{changeMode-BVGYCoqu.js → changeMode-D_I2AOjH.js} +2 -2
  39. package/dist/internal/{changeMode-BVGYCoqu.js.map → changeMode-D_I2AOjH.js.map} +1 -1
  40. package/dist/internal/{controller-BWkZT0l1.js → controller-DIDtFrBE.js} +1991 -2050
  41. package/dist/internal/controller-DIDtFrBE.js.map +1 -0
  42. package/dist/internal/{cruise-C3F0eNQ-.js → cruise-B50Tcq66.js} +2 -2
  43. package/dist/internal/{cruise-C3F0eNQ-.js.map → cruise-B50Tcq66.js.map} +1 -1
  44. package/dist/internal/{current-pano-image-DKUWluR-.js → current-pano-image-BCFr6njt.js} +4 -4
  45. package/dist/internal/{current-pano-image-DKUWluR-.js.map → current-pano-image-BCFr6njt.js.map} +1 -1
  46. package/dist/internal/{defaultUrls-CjKkS9k9.js → defaultUrls-CfMtGzqM.js} +14 -3
  47. package/dist/internal/defaultUrls-CfMtGzqM.js.map +1 -0
  48. package/dist/internal/{fire-scene-CczaBz2_.js → fire-scene-BzZGvyh_.js} +9 -4
  49. package/dist/internal/fire-scene-BzZGvyh_.js.map +1 -0
  50. package/dist/internal/{fiveModelLoad-mg-TnpnM.js → fiveModelLoad-BUIBYxzp.js} +2 -2
  51. package/dist/internal/{fiveModelLoad-mg-TnpnM.js.map → fiveModelLoad-BUIBYxzp.js.map} +1 -1
  52. package/dist/internal/{floorplan-KWlIsTvO.js → floorplan-C8BGw87S.js} +5 -5
  53. package/dist/internal/{floorplan-KWlIsTvO.js.map → floorplan-C8BGw87S.js.map} +1 -1
  54. package/dist/internal/{generatePolygonGeometry-B_5JFq8y.js → generatePolygonGeometry-BOnzdCaG.js} +181 -178
  55. package/dist/internal/generatePolygonGeometry-BOnzdCaG.js.map +1 -0
  56. package/dist/internal/{lookObject-wesf8xt6.js → lookObject-DuRab5wf.js} +2 -2
  57. package/dist/internal/{lookObject-wesf8xt6.js.map → lookObject-DuRab5wf.js.map} +1 -1
  58. package/dist/internal/{measure-BX6boAC7.js → measure-B4jFwdQ6.js} +5 -5
  59. package/dist/internal/{measure-BX6boAC7.js.map → measure-B4jFwdQ6.js.map} +1 -1
  60. package/dist/internal/{model-chassis-compass-InVNmOAQ.js → model-chassis-compass-C6NTVMLo.js} +2 -2
  61. package/dist/internal/{model-chassis-compass-InVNmOAQ.js.map → model-chassis-compass-C6NTVMLo.js.map} +1 -1
  62. package/dist/internal/{model-entry-door-guide-wZbyY77a.js → model-entry-door-guide-DnGTLY2s.js} +2 -2
  63. package/dist/internal/{model-entry-door-guide-wZbyY77a.js.map → model-entry-door-guide-DnGTLY2s.js.map} +1 -1
  64. package/dist/internal/{model-maker-uO8xlTuO.js → model-maker-B1mnDdKY.js} +15 -15
  65. package/dist/internal/{model-maker-uO8xlTuO.js.map → model-maker-B1mnDdKY.js.map} +1 -1
  66. package/dist/internal/{model-tv-video-DzXb2JRf.js → model-tv-video-BP-7HoDC.js} +2 -2
  67. package/dist/internal/{model-tv-video-DzXb2JRf.js.map → model-tv-video-BP-7HoDC.js.map} +1 -1
  68. package/dist/internal/{model-view-CBeeMM98.js → model-view-BWUU0-uq.js} +2 -2
  69. package/dist/internal/{model-view-CBeeMM98.js.map → model-view-BWUU0-uq.js.map} +1 -1
  70. package/dist/internal/object3d-helper-CbRRhnLV.js +7 -0
  71. package/dist/internal/{object3d-helper-DDYsVPN6.js.map → object3d-helper-CbRRhnLV.js.map} +1 -1
  72. package/dist/internal/{pano-compass-jSr629BP.js → pano-compass-BRTM0dCc.js} +7 -7
  73. package/dist/internal/{pano-compass-jSr629BP.js.map → pano-compass-BRTM0dCc.js.map} +1 -1
  74. package/dist/internal/{pano-door-label-DKoYIKLa.js → pano-door-label-BLjYGZrr.js} +3 -3
  75. package/dist/internal/{pano-door-label-DKoYIKLa.js.map → pano-door-label-BLjYGZrr.js.map} +1 -1
  76. package/dist/internal/{pano-measure-DW9mdx1O.js → pano-measure-BIgCWkVJ.js} +14 -14
  77. package/dist/internal/{pano-measure-DW9mdx1O.js.map → pano-measure-BIgCWkVJ.js.map} +1 -1
  78. package/dist/internal/{pano-ruler-pro-D7q0Ob21.js → pano-ruler-pro-D9yTbHJz.js} +2 -2
  79. package/dist/internal/{pano-ruler-pro-D7q0Ob21.js.map → pano-ruler-pro-D9yTbHJz.js.map} +1 -1
  80. package/dist/internal/{pano-spatial-tag-D0qn-__S.js → pano-spatial-tag-B7Gxn3BS.js} +3 -3
  81. package/dist/internal/{pano-spatial-tag-D0qn-__S.js.map → pano-spatial-tag-B7Gxn3BS.js.map} +1 -1
  82. package/dist/internal/{pano-tag-BW5MXXws.js → pano-tag-Bchz-jED.js} +2 -2
  83. package/dist/internal/{pano-tag-BW5MXXws.js.map → pano-tag-Bchz-jED.js.map} +1 -1
  84. package/dist/internal/{pano-video-Bmud_CAn.js → pano-video-BufYQMqo.js} +3 -3
  85. package/dist/internal/{pano-video-Bmud_CAn.js.map → pano-video-BufYQMqo.js.map} +1 -1
  86. package/dist/internal/{pipeline-DDqgb1gw.js → pipeline-t_3IMXKB.js} +4 -4
  87. package/dist/internal/{pipeline-DDqgb1gw.js.map → pipeline-t_3IMXKB.js.map} +1 -1
  88. package/dist/internal/{sculpt-BNkLJR6p.js → sculpt-BCK4PMwL.js} +64 -63
  89. package/dist/internal/{sculpt-BNkLJR6p.js.map → sculpt-BCK4PMwL.js.map} +1 -1
  90. package/dist/internal/tagPosition-DA9YguT8.js +176 -0
  91. package/dist/internal/tagPosition-DA9YguT8.js.map +1 -0
  92. package/dist/internal/withResolvers-DVr4bnnk.js +15 -0
  93. package/dist/internal/withResolvers-DVr4bnnk.js.map +1 -0
  94. package/dist/plugins/area-maker.js +1 -1
  95. package/dist/plugins/camera-movement.js +1 -1
  96. package/dist/plugins/cruise.js +2 -2
  97. package/dist/plugins/css3d-render.js +1 -1
  98. package/dist/plugins/current-pano-image.js +1 -1
  99. package/dist/plugins/digital-performance.d.ts +1 -1
  100. package/dist/plugins/digital-performance.js +1 -1
  101. package/dist/plugins/fire-scene.d.ts +1 -1
  102. package/dist/plugins/fire-scene.js +1 -1
  103. package/dist/plugins/guide-line.js +1 -1
  104. package/dist/plugins/measure.js +1 -1
  105. package/dist/plugins/model-chassis-compass.js +1 -1
  106. package/dist/plugins/model-entry-door-guide.js +1 -1
  107. package/dist/plugins/model-maker.d.ts +1 -1
  108. package/dist/plugins/model-maker.js +1 -1
  109. package/dist/plugins/model-tv-video.js +1 -1
  110. package/dist/plugins/model-view.js +1 -1
  111. package/dist/plugins/object3d-helper.d.ts +1 -1
  112. package/dist/plugins/object3d-helper.js +3 -1
  113. package/dist/plugins/pano-compass.js +1 -1
  114. package/dist/plugins/pano-door-label.js +1 -1
  115. package/dist/plugins/pano-measure.js +1 -1
  116. package/dist/plugins/pano-ruler-pro.js +1 -1
  117. package/dist/plugins/pano-spatial-tag.js +1 -1
  118. package/dist/plugins/pano-tag.d.ts +1 -1
  119. package/dist/plugins/pano-tag.js +4 -1
  120. package/dist/plugins/pano-video.js +1 -1
  121. package/dist/plugins/pipeline.js +1 -1
  122. package/dist/plugins/sculpt.d.ts +1 -1
  123. package/dist/plugins/sculpt.js +7 -1
  124. package/dist/types/public/index.d.ts +2 -0
  125. package/dist/types/public/plugins/digital-performance.d.ts +1 -0
  126. package/dist/types/public/plugins/fire-scene.d.ts +1 -0
  127. package/dist/types/public/plugins/model-maker.d.ts +1 -0
  128. package/dist/types/public/plugins/object3d-helper.d.ts +1 -0
  129. package/dist/types/public/plugins/pano-tag.d.ts +2 -0
  130. package/dist/types/public/plugins/sculpt.d.ts +8 -0
  131. package/dist/types/public/utils.d.ts +5 -0
  132. package/dist/utils.d.ts +1 -1
  133. package/dist/utils.js +16 -50
  134. package/package.json +1 -1
  135. package/dist/internal/BasePluginWithData-9z4tpAT4.js +0 -7
  136. package/dist/internal/CSS3DRenderPlugin-ccSpcvwd.js.map +0 -1
  137. package/dist/internal/Rectangle-D-zkDycu.js.map +0 -1
  138. package/dist/internal/animationFrame-XGKHIeQK.js.map +0 -1
  139. package/dist/internal/blink-DD_0mH-m.js +0 -113
  140. package/dist/internal/blink-DD_0mH-m.js.map +0 -1
  141. package/dist/internal/camera-movement-CwI7UqUk.js.map +0 -1
  142. package/dist/internal/controller-BWkZT0l1.js.map +0 -1
  143. package/dist/internal/defaultUrls-CjKkS9k9.js.map +0 -1
  144. package/dist/internal/fire-scene-CczaBz2_.js.map +0 -1
  145. package/dist/internal/generatePolygonGeometry-B_5JFq8y.js.map +0 -1
  146. package/dist/internal/object3d-helper-DDYsVPN6.js +0 -7
  147. package/dist/utils.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Controller-Csut_kcH.js","names":["o","disposedErrorLog","disableWarnLog","disableErrorLog","BasePluginController","FiveControllerWrapper","Subscribe","generateBehindFiveElement","waitFiveModelLoaded","toArray","IObject3D","getNormal","formatRad","notNil","isNil","rayOnLine","worldBoundingBox","boundingSphere","boundingBox","CSS3DRender","Controller","rad2Deg","vectorIsEqual","THREE","setObjectQuaternion","rotateCenter","v","object","quaternion","BaseHelper","originObject3D","config","raycaster","intersection","Vector3","offset","xAxis","yAxis","zAxis","newX","newY","newZ","quaternionX","quaternionY","quaternionZ","newMatrix","matrix","origin","MoveHelperAbstract","BoundingBoxHelperAbstract","RotateHelperAbstract","ScaleHelperAbstract","RectangleScaleHelperAbstract","DirectionGroup","direction","DirectionMesh","geometry","material","calculateThreeMouse","width","height","element","originMouse","left","top","getMouseRaycaster","mouse","camera","threeMouse","RENDER_ORDER","ArrowGroup","param","color","arrow","radius","cylinder","CenterHandle","centerSize","brightColor","centerGeometry","cube","cameraDirection","worldQuaternion","faceAngles","dotProduct","normal","a","b","colors","colorIndex","sortedIndex","item","AXES_COLOR","AXES_THREE_COLOR","calculateScaleByCamera","distance","position","fov","cameraDistance","distanceScale","fovScale","cameraDistanceScale","scale","min","limit","max","clamp","value","getPoseFromCamera","latitude","longitude","e","getOrthographicCameraDirection","pose","vector","HalfPI","isSame","v1","v2","MoveHelper","worldDirectionX","worldDirectionY","worldDirectionZ","orthographicCameraDirection","hideThreshold","angleX","angleY","angleZ","threshold","reverseY","reverseZ","reverseX","directions","createElement","setStyle","tagName","style","key","tipsDom","show","RotateHelper","RotateCircleGroup","child","positiveY","positiveZ","positiveX","gapAngle","angle","options","Circle","DashedRing","AngleSector","meshes","i","mesh","axes","rectangleScaleDom","container","wrapper","border","sphere0","sphereDom","sphere1","sphere2","sphere3","sphere4","sphere5","sphere6","sphere7","sphere","sphereDraggingWrapper","sphereDragging","map","cameraHooks","cancelAnimationFrameId","cameraPose","animate","newCameraPose","CSS3DScaleHelper","scene","cornerPosition","position8","index","css3DObject","currentScale","relativeScaleX","relativeScaleY","parentElement","cornerPositions","css3DInstance","css3DObjectElement","dom","spheres","BoundingBoxHelper","originObject","intersects","box3","lineIndices","lineGeometry","lineMaterial","lineSegments","boxIndices","boxGeometry","boxMaterial","BaseController","otherControllers","params","handleSetObjectScale","handleSetObjectRotate","handleSetObjectPosition","handleApplyObjectScale","handleApplyObjectRotate","handleApplyObjectPosition","initialHelperPosition","d","objects","object3D","disposers","\"__originalColor__\"","mat","\"__originalOpacity__\"","setHoverColor","hoverColor","hoverOpacity","resetColor","originalColors","originalOpacities","handleMouseover","handleMouseout","disposer","cameraPosition","objectIntersection","\"intersectRaycaster\"","modelIntersection","result","getBox","box","computeGuideLength","viewWidth","viewHeight","persp","ortho","cam","center","vFov","diag","baseLength","minLen","maxLen","SolidGuideLine","defaults","merged","dir","length","start","end","positions","line","attr","m","MoveController","helper","centerHandle","centerHandleMesh","hide","updateHelperByCamera","mousedownListener","mouseupListener","point","face","alignment","alignmentVector3","faceNormal","event","x","y","intersect","draggingDirection","directionX","directionY","directionZ","directionVector","startIntersect","clickPoint","viewDirection","plane","startProject","dirNormalized","directionsToShow","ray","isPlane","currentVectorProject","projected","denom","t","beforePosition","offsetVector","startVectorProject","transform","newPosition","finalPosition","finalTransform","ControllerWrapper","five","model","onRender","HelperController","donEvents","hooks","internalHooks","HelperControllerConfig","NAMEVERSION","disposedErrorLog$1","disableWarnLog$1","disableErrorLog$1","Object3DHelper","controllers","state","prevState","controller","enabled","visible","func","k","deg2Rad","deg","helperQuaternionOffset","RotateController","dragStart","dragging","dragEnd","euler","z","currentEuler","currentAngles","newAngles","axis","newEuler","angleHelper","tipsPosition","helperQuaternion","startVector","startAngle","processedAngle","matrixQuaternion","currentIntersectPoint","currentVector","rotationAxis","newQuaternion","segments","thetaLength","thetaStart","angleTips","RectangleScaleController","planeIntersection","planeCenter","startPosition","startPoint","ewVector","nsVector","getOffset","defaultVector","baseVector","startPositionProject","nowPositionProject","planeCenterProject","xIsNegative","yIsNegative","zIsNegative","offsetLength","ewOffset","nsOffset","setEWScale","setNSScale","scaleX","scaleY","scaleXY","scaleMatrix","centerPosition","transformMatrix4","CSS3DScaleController","BoundingBoxController","ScaleHelper","scaleMesh","generateSphere","scalePosition","spheresToRemove","connection","oppositeDirections","processedDirections","mesh1","mesh1Id","oppositeId","mesh2","generateDashedLine","it","isOrthographic","objectCenter","toCameraDirection","objectDirections","maxDot","facingDirection","dirVector","dot","meshId","bothMeshesVisible","frontMaterial","frontMesh","groupGeometry","transparentMaterial","transparentSphere","points","point1","point2","ScaleController","_this","scaleMeshUuidSet","hitObject","draggingObject","dragBasePosition","dragHandlePosition","dragVector","worldBox","meshs","list","faces","scaleMeshes","moveMeshes","intersectedMesh","intersectedPoint","closestFace","minDist","dist","draggingObjectWorldPos","faceCenter","centerVec","isMoveControllerDragging","scaleVector3","posAttr","corners","vertexCount","vertex","isNearlyParallel","localIntersect","intersectPoint","inverseMatrix","localStart","scaleStartPoint","handleWorld","baseWorld","vertices","indices","patch","DomEvents","domElement","domEvent","elPosition","tmpElement","elDimension","object3d","eventName","objectCtx","handlers","handler","callback","useCapture","current","obj","boundObjs","visibleBoundObjs","mouseX","mouseY","aRenderOrder","bRenderOrder","oldSelected","notifyOver","notifyOut","notifyMove","newSelected","origDomEvent","objectParent","toPropagate","mouseCoords","touches","PLUGIN_NAME","PLUGIN","disposedErrorLog","disableWarnLog","disableErrorLog","Object3DHelperController","paramsConfig","helperEnable","moveHelper","c","controllerWrapper","rotateHelper","boundingBoxHelper","scaleHelper","css3dScaleHelper","css3dObject","parent"],"sources":["../../src/shared-utils/Object3DHelper/utils/setObjectQuaternion.ts","../../src/shared-utils/Object3DHelper/Base/BaseHelper.ts","../../src/shared-utils/Object3DHelper/utils/direction.ts","../../src/shared-utils/Object3DHelper/utils/calculateThreeMouse.ts","../../src/shared-utils/Object3DHelper/utils/getMouseRaycaster.ts","../../src/shared-utils/Object3DHelper/Constants/RenderOrder.ts","../../src/shared-utils/Object3DHelper/Helper/Objects/ArrowGroup.ts","../../src/shared-utils/Object3DHelper/Helper/Objects/CenterHandle.ts","../../src/shared-utils/Object3DHelper/Constants/color.ts","../../src/shared-utils/Object3DHelper/utils/calculateScaleByCamera.ts","../../src/shared-utils/clamp.ts","../../src/shared-utils/Object3DHelper/utils/getPoseFromCamera.ts","../../src/shared-utils/Object3DHelper/utils/getOrthographicCameraDirection.ts","../../src/shared-utils/Object3DHelper/Helper/MoveHelper.ts","../../src/shared-utils/Object3DHelper/Helper/HTML/utils/createElement.ts","../../src/shared-utils/Object3DHelper/Helper/HTML/tipsDom.ts","../../src/shared-utils/Object3DHelper/Helper/RotateHelper.ts","../../src/shared-utils/Object3DHelper/Helper/HTML/rectangleScaleDom.ts","../../src/shared-utils/Object3DHelper/utils/cameraHooks.ts","../../src/shared-utils/Object3DHelper/Helper/CSS3DScaleHelper.ts","../../src/shared-utils/Object3DHelper/Helper/BoundingBoxHelper.ts","../../src/shared-utils/Object3DHelper/Base/BaseController.ts","../../src/shared-utils/Object3DHelper/utils/solidGuide.ts","../../src/shared-utils/Object3DHelper/Controller/MoveController.ts","../../src/Object3DHelperPlugin/FiveControllerWrapper.ts","../../src/shared-utils/Object3DHelper/index.ts","../../src/shared-utils/math/deg2Rad.ts","../../src/shared-utils/Object3DHelper/Controller/RotateController.ts","../../src/shared-utils/Object3DHelper/Controller/RectangleScaleController.ts","../../src/shared-utils/Object3DHelper/Controller/CSS3DScaleController.ts","../../src/shared-utils/Object3DHelper/Controller/BoundingBoxController.ts","../../src/shared-utils/Object3DHelper/Helper/ScaleHelper.ts","../../src/shared-utils/Object3DHelper/Controller/ScaleController.ts","../../src/shared-utils/threex/domevents/index.js","../../src/Object3DHelperPlugin/Controller.ts"],"sourcesContent":["import * as THREE from 'three/webgpu'\n\n/**\n * @description: 在指定中心点上,使用 quaternion 旋转物体。\n * @param {THREE.Object3D} object 旋转对象\n * @param {THREE.Quaternion} quaternion 旋转四元数\n * @param {THREE.Vector3} rotateCenter 旋转中心\n */\nexport default function setObjectQuaternion(object: THREE.Object3D, quaternion: THREE.Quaternion, rotateCenter: THREE.Vector3) {\n if (rotateCenter) {\n const rotateCenter2Object = new THREE.Vector3().subVectors(object.position, rotateCenter) // 旋转中心到物体的向量\n const v = rotateCenter2Object\n .applyQuaternion(object.quaternion.clone().invert()) // 使用物体的四元数,将旋转中心到物体的向量转换到物体的局部坐标系\n .applyQuaternion(quaternion) // 使用新的四元数,将物体的局部坐标系转换到世界坐标系\n .add(rotateCenter) // 加上旋转中心,得到新的世界坐标\n object.position.copy(v)\n }\n object.quaternion.copy(quaternion)\n}\n","import type { Create3DElementReturnType } from '../../../CSS3DRenderPlugin'\nimport * as THREE from 'three/webgpu'\nimport type { Group, Mesh, Object3D } from 'three/webgpu'\nimport { Vector3 } from 'three/webgpu'\nimport type { Direction, Direction4, PositionFrom, ScalePosition } from '../typings'\nimport type { tipsDom } from '../Helper/HTML/tipsDom'\nimport setObjectQuaternion from '../utils/setObjectQuaternion'\nimport { IObject3D } from '../../three/IObject3D'\nimport { boundingBox, boundingSphere } from '../../three/boundingBox'\nimport { notNil } from '../../isNil'\n\ntype NonVoid<T> = T extends void ? never : T\n\nexport interface BaseHelperConfig {\n onRender?: () => any\n /**\n * @description: helper 初始位置来源\n * @default 'objectPosition'\n */\n positionFrom?: PositionFrom\n}\n\nexport abstract class BaseHelper<OriginObject3D extends Object3D = Object3D> extends IObject3D {\n protected originObject3D: OriginObject3D\n protected onRender: () => any\n private positionFrom: PositionFrom\n\n public get helperObject(): Object3D {\n return this\n }\n\n public constructor(originObject3D: OriginObject3D, config?: BaseHelperConfig) {\n super()\n this.originObject3D = originObject3D\n this.onRender = config?.onRender ?? (() => {})\n this.positionFrom = config?.positionFrom ?? 'objectPosition'\n }\n\n public render() {\n this.onRender()\n }\n\n public enable() {\n if (this.parent.children.includes(this)) return\n this.parent.add(this)\n }\n\n public disable() {\n this.removeFromParent()\n }\n\n public show() {\n this.visible = true\n this.render()\n }\n\n public hide() {\n this.visible = false\n this.render()\n }\n\n public raycasterIntersectObject(raycaster: THREE.Raycaster, intersection: THREE.Intersection[] = []): THREE.Intersection[] {\n return raycaster.intersectObject(this, true, intersection)\n }\n\n public initialPosition(offset?: THREE.Vector3) {\n if (this.positionFrom === 'objectPosition') {\n this.position.copy(this.originObject3D.position)\n } else if (this.positionFrom === 'boundingBox') {\n this.position.copy(boundingBox(this.originObject3D)?.getCenter(new THREE.Vector3()).applyMatrix4(this.originObject3D.matrixWorld))\n } else if (this.positionFrom === 'boundingSphere') {\n this.position.copy(boundingSphere(this.originObject3D)?.center.clone().applyMatrix4(this.originObject3D.matrixWorld))\n } else if (this.positionFrom instanceof Vector3) {\n this.position.copy(this.positionFrom)\n } else if (this.positionFrom instanceof Function) {\n this.position.copy(this.positionFrom(this.originObject3D))\n }\n\n if (offset) {\n this.position.add(offset)\n }\n }\n\n public setScaleByCamera(camera: THREE.PerspectiveCamera | THREE.OrthographicCamera) {}\n\n public initQuaternion(config?: {\n xAxis?: Vector3 | (() => Vector3)\n yAxis?: Vector3 | (() => Vector3)\n zAxis?: Vector3 | (() => Vector3)\n }) {\n this.quaternion.copy(this.originObject3D.quaternion)\n if (config) {\n if (config.xAxis || config.yAxis || config.zAxis) {\n const xAxis = config.xAxis instanceof Function ? config.xAxis() : config.xAxis\n const yAxis = config.yAxis instanceof Function ? config.yAxis() : config.yAxis\n const zAxis = config.zAxis instanceof Function ? config.zAxis() : config.zAxis\n\n let newX = xAxis?.clone()\n let newY = yAxis?.clone()\n let newZ = zAxis?.clone()\n\n // 单个旋转\n if (newX && !newY && !newY) {\n const quaternionX = new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(1, 0, 0), newX.normalize())\n this.applyQuaternion(quaternionX)\n }\n\n if (newY && !newX && !newZ) {\n const quaternionY = new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0, 1, 0), newY.normalize())\n this.applyQuaternion(quaternionY)\n }\n\n if (newZ && !newX && !newY) {\n const quaternionZ = new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0, 0, 1), newZ.normalize())\n this.applyQuaternion(quaternionZ)\n }\n\n // 三轴旋转\n if ([newX, newY, newZ].filter(notNil).length >= 2) {\n // 补全\n if (!newX) newX = new THREE.Vector3().crossVectors(newY, newZ).normalize()\n if (!newY) newY = new THREE.Vector3().crossVectors(newX, newZ).normalize()\n if (!newZ) newZ = new THREE.Vector3().crossVectors(newX, newY).normalize()\n\n newX.applyQuaternion(this.quaternion)\n newY.applyQuaternion(this.quaternion)\n newZ.applyQuaternion(this.quaternion)\n\n const newMatrix = new THREE.Matrix4().makeBasis(newX, newY, newZ)\n\n const quaternion = new THREE.Quaternion().setFromRotationMatrix(newMatrix)\n\n this.quaternion.copy(quaternion)\n }\n }\n }\n }\n\n public applyHelperScaleMatrix4(matrix: THREE.Matrix4, origin?: Vector3) {\n this.scale.applyMatrix4(matrix)\n }\n\n public setHelperQuaternion(quaternion: THREE.Quaternion, origin?: Vector3) {\n this.initQuaternion()\n setObjectQuaternion(this, this.quaternion.clone().premultiply(quaternion), origin)\n }\n\n public applyHelperQuaternion(quaternion: THREE.Quaternion, origin?: Vector3) {\n if (origin) {\n const v = new Vector3().subVectors(this.position, origin).applyQuaternion(quaternion).add(origin)\n this.position.copy(v)\n }\n this.applyQuaternion(quaternion)\n }\n\n public dispose() {\n this.removeFromParent()\n }\n}\n\nexport abstract class MoveHelperAbstract<OriginObject3D extends Object3D = Object3D> extends BaseHelper<OriginObject3D> {\n public abstract xArrow?: Object3D & { arrow: Object3D; line?: Object3D; direction: Direction }\n public abstract yArrow?: Object3D & { arrow: Object3D; line?: Object3D; direction: Direction }\n public abstract zArrow?: Object3D & { arrow: Object3D; line?: Object3D; direction: Direction }\n public abstract centerHandle?: Object3D & { direction: Direction }\n public abstract showDraggingHelper(directions?: Direction[]): void\n public abstract update(camera: THREE.Camera): void\n}\n\nexport abstract class BoundingBoxHelperAbstract<OriginObject3D extends Object3D = Object3D> extends BaseHelper<OriginObject3D> {}\n\ntype Circle = (Mesh | Group) & { direction: Direction; circle: Mesh; angleSector?: Mesh & { angleDirection: number; baseAxes: Vector3 } }\nexport abstract class RotateHelperAbstract<OriginObject3D extends Object3D = Object3D> extends BaseHelper<OriginObject3D> {\n public abstract xCircle?: Circle\n public abstract yCircle?: Circle\n public abstract zCircle?: Circle\n public abstract angleTips?: ReturnType<typeof tipsDom>\n public abstract showDraggingHelper(directions: Direction[]): void\n public abstract update(camera: THREE.Camera): void\n}\n\nexport abstract class ScaleHelperAbstract<OriginObject3D extends Object3D = Object3D> extends BaseHelper<OriginObject3D> {\n public abstract scaleMeshes: Array<Object3D & { scalePosition: ScalePosition }>\n public abstract update(camera: THREE.Camera): void\n public abstract updateHandlePositions(): void\n}\n\nexport abstract class RectangleScaleHelperAbstract<\n OriginObject3D extends Object3D,\n PointType extends Object3D | HTMLElement,\n> extends BaseHelper<OriginObject3D> {\n public abstract points: PointType extends Object3D\n ? { point: PointType; direction: Direction4 }[]\n : { point: PointType; direction: Direction4; position: Vector3 }[]\n public abstract cornerPositions: Vector3[]\n public abstract css3DInstance?: NonVoid<Create3DElementReturnType>\n public abstract plane?: THREE.Mesh\n public abstract showDraggingHelper(directions?: Direction[]): void\n public abstract updatePoints(): void\n public abstract enable(): void\n public abstract disable(): void\n}\n","import type { Direction } from '../typings'\nimport * as THREE from 'three/webgpu'\n\nexport class DirectionGroup extends THREE.Group {\n public direction: Direction\n\n public constructor(direction?: Direction) {\n super()\n this.direction = direction || 'x'\n }\n}\n\nexport class DirectionLine<T extends THREE.BufferGeometry, K extends THREE.Material> extends THREE.Line<T, K> {\n public direction: Direction\n\n public constructor(geometry?: T, material?: K, direction?: Direction) {\n super(geometry, material)\n this.direction = direction || 'x'\n }\n}\n\nexport class DirectionMesh<T extends THREE.BufferGeometry, K extends THREE.Material> extends THREE.Mesh<T, K> {\n public direction: Direction\n\n public constructor(geometry?: T, material?: K, direction?: Direction) {\n super(geometry, material)\n this.direction = direction || 'x'\n }\n}\n","import * as THREE from 'three/webgpu'\n\n/**\n * 计算 three 中的 mouse 的值\n * @param mouseXY - 鼠标相对屏幕位置\n * @param element - canvas元素(three的展示元素)\n * @param scissor - 屏幕剪裁\n */\nexport function calculateThreeMouse(originMouse: { x: number; y: number }, element: HTMLElement) {\n const { offsetWidth: width, offsetHeight: height } = element\n const { top, left } = element.getBoundingClientRect()\n return Object.assign(new THREE.Vector2(), {\n x: ((originMouse.x - left) / width) * 2 - 1,\n y: (-(originMouse.y - top) / height) * 2 + 1,\n })\n}\n","import * as THREE from 'three/webgpu'\nimport { calculateThreeMouse } from '.'\n\nexport function getMouseRaycaster(camera: THREE.Camera, mouse: { x: number; y: number }, element: HTMLElement) {\n if (!mouse || !element || !camera) return\n const threeMouse = calculateThreeMouse(mouse, element)\n if (Math.abs(threeMouse.x) === 1 || Math.abs(threeMouse.y) === 1) return\n const raycaster = new THREE.Raycaster()\n raycaster.setFromCamera(threeMouse, camera)\n raycaster.params.Points.threshold = 0.1\n return raycaster\n}\n","/**\n * Object3DHelper 渲染顺序常量\n * 数值越大,渲染优先级越高\n */\nexport const RENDER_ORDER = {\n // 基础几何体(如Box)的渲染顺序通常在 0-100 之间\n // 所以Helper的渲染顺序需要远大于这个范围\n\n // 旋转辅助器 - 最低优先级\n ROTATE_HELPER: 9992,\n\n // 移动辅助器\n MOVE_HELPER: 9993,\n\n // 缩放辅助器的连接线\n SCALE_HELPER_LINE: 9994,\n\n // 缩放辅助器的球体\n SCALE_HELPER_SPHERE: 9995,\n\n // 移动辅助器的箭头 - 确保高于所有透明对象\n MOVE_HELPER_ARROW: 10001,\n\n // 移动辅助器的中心手柄 - 应该盖住箭头,优先响应事件\n MOVE_HELPER_CENTER: 10002,\n\n // 拖拽引导线\n DRAG_GUIDE_LINE: 10003,\n\n // 拖拽面片 - 最高优先级\n DRAG_FACE_PATCH: 10004,\n} as const\n\nexport type RenderOrderType = (typeof RENDER_ORDER)[keyof typeof RENDER_ORDER]\n","import * as THREE from 'three/webgpu'\nimport type { Direction } from '../../typings'\nimport { DirectionGroup, DirectionMesh } from '../../utils'\nimport { RENDER_ORDER } from '../../Constants/RenderOrder'\n\ninterface InstanceParameter {\n direction: Direction\n color?: THREE.Color | string | number\n}\n\nexport class ArrowGroup extends DirectionGroup {\n public line: DirectionMesh<THREE.BufferGeometry, THREE.MeshBasicMaterial>\n public arrow: DirectionMesh<THREE.ConeGeometry, THREE.MeshBasicMaterial>\n private lineHeight = 0.4\n private arrowHeight = 0.1\n public name = 'ArrowGroup'\n\n public constructor(param: InstanceParameter) {\n super(param.direction)\n const color = new THREE.Color(param.color ?? 0xf7692b)\n const material = new THREE.MeshBasicMaterial({\n color,\n transparent: true, // 设置为透明材质,确保在透明渲染队列中\n opacity: 1.0, // 完全不透明,但使用透明渲染队列\n depthTest: false, // 禁用深度测试,避免被其他对象遮挡\n depthWrite: false, // 禁用深度写入,避免影响其他透明对象\n })\n\n // arrow\n const coneGeometry = new THREE.ConeGeometry(0.04, 0.1, 32)\n const arrow = new DirectionMesh(coneGeometry, material.clone(), param.direction)\n arrow.name = `arrow-${param.direction}`\n arrow.renderOrder = RENDER_ORDER.MOVE_HELPER_ARROW\n this.arrow = arrow\n\n // line\n const radius = 0.004\n const cylinderGeometry = new THREE.CylinderGeometry(radius, radius, 0.4, 32)\n const cylinder = new DirectionMesh(cylinderGeometry, material.clone(), param.direction)\n cylinder.name = `line-${param.direction}`\n cylinder.renderOrder = RENDER_ORDER.MOVE_HELPER_ARROW\n this.line = cylinder\n\n this.formatArrow()\n this.formatLine()\n this.add(this.arrow, this.line)\n }\n\n private formatArrow() {\n this.arrow.geometry.translate(0, this.lineHeight + this.arrowHeight / 2, 0)\n if (this.direction === 'x') {\n this.arrow.geometry.rotateX(Math.PI / 2)\n this.arrow.geometry.rotateY(Math.PI / 2)\n } else if (this.direction === 'z') {\n this.arrow.geometry.rotateX(Math.PI / 2)\n }\n }\n\n private formatLine() {\n this.line.geometry.translate(0, this.lineHeight / 2, 0)\n if (this.direction === 'x') {\n this.line.geometry.rotateX(Math.PI / 2)\n this.line.geometry.rotateY(Math.PI / 2)\n } else if (this.direction === 'z') {\n this.line.geometry.rotateX(Math.PI / 2)\n }\n }\n}\n","import * as THREE from 'three/webgpu'\nimport type { Direction } from '../../typings'\nimport { DirectionGroup } from '../../utils'\nimport { RENDER_ORDER } from '../../Constants/RenderOrder'\n\ninterface InstanceParameter {\n color?: THREE.Color | string | number\n size?: number\n}\n\nexport class CenterHandle extends DirectionGroup {\n public cube: THREE.Mesh<THREE.BoxGeometry, THREE.MeshBasicMaterial[]> & { direction: Direction }\n public name = 'CenterHandle'\n private faceMaterials: THREE.MeshBasicMaterial[]\n private baseColor: THREE.Color\n // 立方体6个面的法线方向(局部坐标系)\n private faceNormals = [\n new THREE.Vector3(1, 0, 0), // right (+X)\n new THREE.Vector3(-1, 0, 0), // left (-X)\n new THREE.Vector3(0, 1, 0), // top (+Y)\n new THREE.Vector3(0, -1, 0), // bottom (-Y)\n new THREE.Vector3(0, 0, 1), // front (+Z)\n new THREE.Vector3(0, 0, -1), // back (-Z)\n ]\n\n public constructor(param?: InstanceParameter) {\n super('plane')\n this.baseColor = new THREE.Color(param?.color ?? 0xfa8c16)\n const centerSize = param?.size ?? 0.05\n\n // Three automatically converts these sRGB literals to linear working colors.\n const brightColor = new THREE.Color(0xffa940) // 最亮 #FFA940\n\n // 为立方体的6个面创建独立的材质(使用BasicMaterial,不受光照影响)\n this.faceMaterials = Array.from(\n { length: 6 },\n () =>\n new THREE.MeshBasicMaterial({\n color: brightColor, // 初始都使用最亮色\n transparent: true,\n opacity: 1.0,\n depthTest: false,\n depthWrite: false,\n side: THREE.FrontSide,\n }),\n )\n\n const centerGeometry = new THREE.BoxGeometry(centerSize, centerSize, centerSize)\n const cube = new THREE.Mesh(centerGeometry, this.faceMaterials) as THREE.Mesh<THREE.BoxGeometry, THREE.MeshBasicMaterial[]> & {\n direction: Direction\n }\n cube.direction = 'plane'\n cube.renderOrder = RENDER_ORDER.MOVE_HELPER_CENTER\n cube.name = 'center-plane-handle'\n this.cube = cube\n\n this.add(this.cube)\n }\n\n /**\n * 更新各个面的颜色,根据与相机的角度动态调整\n * @param camera 相机对象\n */\n public update(camera: THREE.Camera) {\n // 获取相机到立方体的方向(世界坐标系)\n const cameraDirection = new THREE.Vector3().subVectors(camera.position, this.cube.getWorldPosition(new THREE.Vector3())).normalize()\n\n // 获取立方体的世界旋转\n const worldQuaternion = this.cube.getWorldQuaternion(new THREE.Quaternion())\n\n // 计算每个面与相机方向的夹角\n const faceAngles = this.faceNormals.map((normal, index) => {\n // 将局部法线转换到世界坐标系\n const worldNormal = normal.clone().applyQuaternion(worldQuaternion)\n // 计算法线与相机方向的夹角(点积的绝对值越大表示越正对相机)\n const dotProduct = worldNormal.dot(cameraDirection)\n return { index, angle: Math.acos(Math.abs(dotProduct)) }\n })\n\n // 按角度排序,角度越小说明越正对相机\n faceAngles.sort((a, b) => a.angle - b.angle)\n\n // Three automatically converts these sRGB literals to linear working colors.\n const colors = [\n new THREE.Color(0xffa940), // 最亮 #FFA940(最正对相机)\n new THREE.Color(0xfa8c16), // 一般 #FA8C16\n new THREE.Color(0xd46b08), // 最暗 #D46B08\n ]\n\n // 为6个面分配颜色:最接近的2个面用最亮色,中间2个面用中等色,最远的2个面用最暗色\n faceAngles.forEach((item, sortedIndex) => {\n const colorIndex = Math.floor(sortedIndex / 2) // 0-1用colors[0], 2-3用colors[1], 4-5用colors[2]\n this.faceMaterials[item.index].color.copy(colors[colorIndex])\n })\n }\n}\n","import * as THREE from 'three/webgpu'\n\nconst AXES_COLOR = {\n X: 0xff4a4a,\n Y: 0x00d68f,\n Z: 0x3366ff,\n}\n\nclass AXES_THREE_COLOR {\n public static get X() {\n return new THREE.Color(AXES_COLOR.X)\n }\n public static get Y() {\n return new THREE.Color(AXES_COLOR.Y)\n }\n public static get Z() {\n return new THREE.Color(AXES_COLOR.Z)\n }\n}\n\nexport { AXES_COLOR, AXES_THREE_COLOR }\n","import type * as THREE from 'three/webgpu'\n\nexport default function calculateScaleByCamera(camera: any, position: THREE.Vector3, limit?: { min?: number; max?: number }) {\n const baseCameraDistance = 3\n const baseDistance = 3\n const baseFov = 90\n\n const distance = camera.position.distanceTo(position)\n const fov = camera.fov\n const cameraDistance = camera.distance || baseCameraDistance\n\n const distanceScale = distance / baseDistance\n const fovScale = fov / baseFov\n const cameraDistanceScale = cameraDistance / baseCameraDistance\n\n const scale = distanceScale * fovScale * cameraDistanceScale\n\n const min = limit?.min || 0.6\n const max = limit?.max\n\n if (min && scale < min) return min\n if (max && scale > max) return max\n\n return scale\n}\n","function clamp(value: number, min: number, max: number) {\n if (value < min) {\n return min;\n }\n if (value > max) {\n return max;\n }\n return value;\n}\n\nexport { clamp };","import type * as THREE from 'three/webgpu'\nimport { isNil } from '../../isNil'\nimport { clamp } from '../../clamp'\nimport { formatRad } from '../../formatRad'\n\n/**\n * @description 从相机反算pose\n */\nexport function getPoseFromCamera(camera: THREE.Camera) {\n let latitude: number = (camera as any).pose.latitude\n let longitude: number = (camera as any).pose.longitude\n if (isNil(latitude) || isNil(longitude)) {\n const e = camera.matrix.elements\n latitude = Math.asin(clamp(e[9], -1, 1))\n if (Math.abs(e[9]) < 0.9999999) {\n longitude = formatRad(Math.atan2(e[8], e[10]))\n } else {\n longitude = formatRad(Math.atan2(-e[2], e[0]))\n }\n }\n\n return { latitude, longitude }\n}\n","import * as THREE from 'three/webgpu'\n\n/**\n * @description 获取正交相机的方向\n */\nexport function getOrthographicCameraDirection(pose: { longitude: number; latitude: number }) {\n const { latitude, longitude } = pose\n\n const vector = new THREE.Vector3()\n\n if (HalfPI - latitude < 0.03) {\n vector.set(0, 1, 0)\n } else if (isSame(0, longitude)) {\n vector.set(0, 0, 1)\n } else if (isSame(Math.PI, longitude)) {\n vector.set(0, 0, -1)\n } else if (isSame(HalfPI, longitude)) {\n vector.set(1, 0, 0)\n } else {\n vector.set(-1, 0, 0)\n }\n\n return vector\n}\n\nconst HalfPI = Number((Math.PI / 2).toFixed(5))\nfunction isSame(v1?: number, v2?: number) {\n if (typeof v1 !== 'number' || typeof v2 !== 'number') return false\n return Math.abs(v1 - v2) < 1e-3\n}\n","import type { Object3D } from 'three/webgpu'\nimport type { Direction } from '../typings'\nimport { MoveHelperAbstract, type BaseHelperConfig } from '.'\nimport { ArrowGroup } from './Objects/ArrowGroup'\nimport { CenterHandle } from './Objects/CenterHandle'\nimport { AXES_THREE_COLOR } from '../Constants/color'\nimport calculateScaleByCamera from '../utils/calculateScaleByCamera'\nimport { getPoseFromCamera } from '../utils/getPoseFromCamera'\nimport { getOrthographicCameraDirection } from '../utils/getOrthographicCameraDirection'\nimport * as THREE from 'three/webgpu'\n\nexport class MoveHelper extends MoveHelperAbstract {\n public name = 'MoveHelper'\n public xArrow?: ArrowGroup\n public yArrow?: ArrowGroup\n public zArrow?: ArrowGroup\n public centerHandle?: CenterHandle\n\n public constructor(\n originObject3D: Object3D,\n config?: {\n xArrowEnable?: boolean\n yArrowEnable?: boolean\n zArrowEnable?: boolean\n centerHandleEnable?: boolean\n } & BaseHelperConfig,\n ) {\n super(originObject3D, config)\n\n if (config.xArrowEnable !== false) this.xArrow = new ArrowGroup({ direction: 'x', color: AXES_THREE_COLOR.X })\n if (config.yArrowEnable !== false) this.yArrow = new ArrowGroup({ direction: 'y', color: AXES_THREE_COLOR.Y })\n if (config.zArrowEnable !== false) this.zArrow = new ArrowGroup({ direction: 'z', color: AXES_THREE_COLOR.Z })\n if (config.centerHandleEnable !== false) this.centerHandle = new CenterHandle()\n\n this.add(...[this.xArrow, this.yArrow, this.zArrow, this.centerHandle].filter(Boolean))\n }\n\n public update(camera: THREE.Camera) {\n if (this.xArrow) this.xArrow.visible = true\n if (this.yArrow) this.yArrow.visible = true\n if (this.zArrow) this.zArrow.visible = true\n\n // 更新中心手柄的面颜色\n if (this.centerHandle) {\n this.centerHandle.update(camera)\n }\n\n const cameraDirection = this.helperObject.position.clone().sub(camera.position).normalize()\n\n // 获取世界坐标系中的轴方向\n const worldDirectionX = new THREE.Vector3(1, 0, 0).applyQuaternion(this.quaternion)\n const worldDirectionY = new THREE.Vector3(0, 1, 0).applyQuaternion(this.quaternion)\n const worldDirectionZ = new THREE.Vector3(0, 0, 1).applyQuaternion(this.quaternion)\n\n // 保留原有的正交相机隐藏逻辑\n if (camera.type === 'OrthographicCamera') {\n const pose = getPoseFromCamera(camera)\n // 正交相机的轴向\n const orthographicCameraDirection = getOrthographicCameraDirection(pose)\n\n // 5度以内隐藏\n const hideThreshold = 0.0872665\n\n if (\n Math.abs(worldDirectionX.angleTo(orthographicCameraDirection) - 0) < hideThreshold ||\n Math.abs(worldDirectionX.angleTo(orthographicCameraDirection) - Math.PI) < hideThreshold\n ) {\n if (this.xArrow) this.xArrow.visible = false\n } else if (\n Math.abs(worldDirectionY.angleTo(orthographicCameraDirection) - 0) < hideThreshold ||\n Math.abs(worldDirectionY.angleTo(orthographicCameraDirection) - Math.PI) < hideThreshold\n ) {\n if (this.yArrow) this.yArrow.visible = false\n } else if (\n Math.abs(worldDirectionZ.angleTo(orthographicCameraDirection) - 0) < hideThreshold ||\n Math.abs(worldDirectionZ.angleTo(orthographicCameraDirection) - Math.PI) < hideThreshold\n ) {\n if (this.zArrow) this.zArrow.visible = false\n }\n }\n\n if (camera.type !== 'OrthographicCamera') {\n // 计算相机方向与各轴的夹角\n const angleX = cameraDirection.angleTo(worldDirectionX)\n const angleY = cameraDirection.angleTo(worldDirectionY)\n const angleZ = cameraDirection.angleTo(worldDirectionZ)\n // 动态调整轴方向\n const threshold = Math.PI / 2\n const reverseY = angleY < threshold\n const reverseZ = angleZ < threshold\n const reverseX = angleX < threshold\n\n if (this.xArrow) {\n if (reverseX) {\n // 夹角小于90度,显示反向轴\n this.xArrow.scale.x = -1\n this.xArrow.scale.y = 1\n this.xArrow.scale.z = 1\n } else {\n // 夹角大于等于90度,显示正向轴\n this.xArrow.scale.x = 1\n this.xArrow.scale.y = 1\n this.xArrow.scale.z = 1\n }\n }\n\n if (this.yArrow) {\n if (reverseY) {\n // 夹角小于90度,显示反向轴\n this.yArrow.scale.x = 1\n this.yArrow.scale.y = -1\n this.yArrow.scale.z = 1\n } else {\n // 夹角大于等于90度,显示正向轴\n this.yArrow.scale.x = 1\n this.yArrow.scale.y = 1\n this.yArrow.scale.z = 1\n }\n }\n if (this.zArrow) {\n if (reverseZ) {\n // 夹角小于90度,显示反向轴\n this.zArrow.scale.x = 1\n this.zArrow.scale.y = 1\n this.zArrow.scale.z = -1\n } else {\n // 夹角大于等于90度,显示正向轴\n this.zArrow.scale.x = 1\n this.zArrow.scale.y = 1\n this.zArrow.scale.z = 1\n }\n }\n }\n }\n\n public show() {\n super.show()\n if (this.xArrow) this.add(this.xArrow)\n if (this.yArrow) this.add(this.yArrow)\n if (this.zArrow) this.add(this.zArrow)\n if (this.centerHandle) this.add(this.centerHandle)\n }\n\n public setScaleByCamera(camera: THREE.PerspectiveCamera | THREE.OrthographicCamera) {\n this.scale.setScalar(calculateScaleByCamera(camera, this.position))\n }\n\n public showDraggingHelper(directions: Direction[]) {\n if (this.xArrow) {\n if (directions.includes('x')) this.add(this.xArrow)\n else this.remove(this.xArrow)\n }\n if (this.yArrow) {\n if (directions.includes('y')) this.add(this.yArrow)\n else this.remove(this.yArrow)\n }\n if (this.zArrow) {\n if (directions.includes('z')) this.add(this.zArrow)\n else this.remove(this.zArrow)\n }\n if (this.centerHandle) {\n if (directions.includes('plane')) this.add(this.centerHandle)\n else this.remove(this.centerHandle)\n }\n }\n\n public dispose() {\n this.remove(...[this.xArrow, this.yArrow, this.zArrow, this.centerHandle].filter(Boolean))\n super.dispose()\n }\n}\n","export function createElement(style?: Partial<CSSStyleDeclaration>, tagName?: string) {\n return setStyle(document.createElement(tagName ?? 'div'), style)\n}\n\nexport function setStyle(element: HTMLElement, style?: Partial<CSSStyleDeclaration>) {\n if (!style) return element\n for (const key in style) {\n if (key && style[key]) element.style[key as any]! = style[key]!\n }\n return element\n}\n","import { createElement } from './utils/createElement'\n\nexport function tipsDom(style?: Partial<CSSStyleDeclaration>) {\n const element = createElement({\n position: 'absolute',\n display: 'block',\n borderRadius: '4px',\n paddingTop: '1px',\n paddingBottom: '1px',\n paddingLeft: '4px',\n paddingRight: '4px',\n pointerEvents: 'none',\n userSelect: 'none',\n zIndex: '99999',\n backgroundColor: 'rgba(0,0,0,0.7)',\n fontSize: '12px',\n color: '#fff',\n letterSpacing: '0',\n lineHeight: '18px',\n ...style,\n })\n const show = () => {\n if (element.style.display === 'block') return\n if (!element.style.top) return\n if (!element.style.left) return\n element.style.display = 'block'\n }\n const hide = () => {\n element.style.display = 'none'\n element.style.top = ''\n element.style.left = ''\n }\n const setLeftTop = (left: string, top: string) => {\n element.style.left = left\n element.style.top = top\n show()\n }\n return { element, show, hide, setLeftTop }\n}\n","import * as THREE from 'three/webgpu'\nimport type { Object3D } from 'three/webgpu'\nimport { RotateHelperAbstract, type BaseHelperConfig } from '../Base/BaseHelper'\nimport type { Color, Direction } from '../typings'\nimport { AXES_THREE_COLOR } from '../Constants/color'\nimport { RENDER_ORDER } from '../Constants/RenderOrder'\nimport { tipsDom } from './HTML/tipsDom'\nimport calculateScaleByCamera from '../utils/calculateScaleByCamera'\n\nexport class RotateHelper extends RotateHelperAbstract {\n public name = 'RotateHelper'\n public xCircle?: RotateCircleGroup\n public yCircle?: RotateCircleGroup\n public zCircle?: RotateCircleGroup\n public children: RotateCircleGroup[] = []\n public angleTips?: ReturnType<typeof tipsDom>\n private container?: HTMLElement\n\n public constructor(\n originObject3D: Object3D,\n config?: {\n container?: HTMLElement\n yzCircleEnable?: boolean\n xzCircleEnable?: boolean\n xyCircleEnable?: boolean\n angleTipsEnable?: boolean\n } & BaseHelperConfig,\n ) {\n super(originObject3D, config)\n\n if (config?.yzCircleEnable !== false) this.xCircle = new RotateCircleGroup({ direction: 'x', color: AXES_THREE_COLOR.X })\n if (config?.xzCircleEnable !== false) this.yCircle = new RotateCircleGroup({ direction: 'y', color: AXES_THREE_COLOR.Y })\n if (config?.xyCircleEnable !== false) this.zCircle = new RotateCircleGroup({ direction: 'z', color: AXES_THREE_COLOR.Z })\n\n if (config?.container && config?.angleTipsEnable !== false) {\n this.container = config?.container\n this.angleTips = tipsDom({ display: 'none' })\n this.container.appendChild(this.angleTips.element)\n }\n\n this.add(...[this.xCircle, this.yCircle, this.zCircle].filter(Boolean))\n this.show()\n }\n\n public hide() {\n this.children.forEach((child) => child.hide())\n }\n\n public show() {\n this.children.forEach((child) => child.showCircle())\n this.angleTips?.hide()\n }\n\n public setScaleByCamera(camera: THREE.PerspectiveCamera | THREE.OrthographicCamera) {\n this.scale.setScalar(calculateScaleByCamera(camera, this.position))\n }\n\n public update(camera: THREE.Camera) {\n if (camera.type === 'OrthographicCamera') return\n // 获取相机朝向向量\n const cameraDirection = this.helperObject.position.clone().sub(camera.position).normalize()\n\n // 获取世界坐标系中的轴方向\n const worldDirectionX = new THREE.Vector3(1, 0, 0).applyQuaternion(this.quaternion)\n const worldDirectionY = new THREE.Vector3(0, 1, 0).applyQuaternion(this.quaternion)\n const worldDirectionZ = new THREE.Vector3(0, 0, 1).applyQuaternion(this.quaternion)\n\n // 计算相机方向与各轴的夹角\n const angleX = cameraDirection.angleTo(worldDirectionX)\n const angleY = cameraDirection.angleTo(worldDirectionY)\n const angleZ = cameraDirection.angleTo(worldDirectionZ)\n\n // 90度阈值(π/2弧度)\n const threshold = Math.PI / 2\n const positiveY = angleY >= threshold\n const positiveZ = angleZ >= threshold\n const positiveX = angleX >= threshold\n\n if (this.xCircle) {\n const gapAngle = this.xCircle.circle.gapAngle\n if (positiveY && positiveZ) {\n this.xCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (positiveY && !positiveZ) {\n this.xCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, Math.PI / 2 + gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (!positiveY && positiveZ) {\n this.xCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, (Math.PI / 2) * 3 + gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (!positiveY && !positiveZ) {\n this.xCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, Math.PI + gapAngle, Math.PI / 2 - gapAngle * 2)\n }\n\n if (this.xCircle.angleSector) {\n this.xCircle.angleSector.offsetAngle = (angle) => angle\n\n if (positiveY && positiveZ) {\n this.xCircle.angleSector.baseAxes = new THREE.Vector3(0, 0, 1)\n } else if (positiveY && !positiveZ) {\n this.xCircle.angleSector.baseAxes = new THREE.Vector3(0, 0, 1)\n } else if (!positiveY && positiveZ) {\n this.xCircle.angleSector.baseAxes = new THREE.Vector3(0, -1, 0)\n this.xCircle.angleSector.offsetAngle = (angle) => angle - Math.PI / 2\n } else if (!positiveY && !positiveZ) {\n this.xCircle.angleSector.baseAxes = new THREE.Vector3(0, 0, -1)\n this.xCircle.angleSector.offsetAngle = (angle) => angle - Math.PI\n }\n }\n }\n\n if (this.yCircle) {\n this.yCircle.angleSector.offsetAngle = (angle) => angle\n const gapAngle = this.yCircle.circle.gapAngle\n\n if (positiveX && positiveZ) {\n this.yCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (positiveX && !positiveZ) {\n this.yCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, (Math.PI / 2) * 3 + gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (!positiveX && positiveZ) {\n this.yCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, Math.PI / 2 + gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (!positiveX && !positiveZ) {\n this.yCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, Math.PI + gapAngle, Math.PI / 2 - gapAngle * 2)\n }\n\n if (positiveX && positiveZ) {\n this.yCircle.angleSector.baseAxes = new THREE.Vector3(1, 0, 0)\n } else if (positiveX && !positiveZ) {\n this.yCircle.angleSector.baseAxes = new THREE.Vector3(0, 0, -1)\n this.yCircle.angleSector.offsetAngle = (angle) => angle - Math.PI / 2\n } else if (!positiveX && positiveZ) {\n this.yCircle.angleSector.baseAxes = new THREE.Vector3(0, 0, 1)\n this.yCircle.angleSector.offsetAngle = (angle) => angle + Math.PI / 2\n } else if (!positiveX && !positiveZ) {\n this.yCircle.angleSector.baseAxes = new THREE.Vector3(-1, 0, 0)\n this.yCircle.angleSector.offsetAngle = (angle) => angle + Math.PI\n }\n }\n\n if (this.zCircle) {\n this.zCircle.angleSector.offsetAngle = (angle) => angle\n const gapAngle = this.zCircle.circle.gapAngle\n\n if (positiveX && positiveY) {\n this.zCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (positiveX && !positiveY) {\n this.zCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, (Math.PI / 2) * 3 + gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (!positiveX && positiveY) {\n this.zCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, Math.PI / 2 + gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (!positiveX && !positiveY) {\n this.zCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, Math.PI + gapAngle, Math.PI / 2 - gapAngle * 2)\n }\n\n if (this.zCircle.angleSector) {\n if (positiveX && positiveY) {\n this.zCircle.angleSector.baseAxes = new THREE.Vector3(1, 0, 0)\n } else if (positiveX && !positiveY) {\n this.zCircle.angleSector.baseAxes = new THREE.Vector3(0, -1, 0)\n this.zCircle.angleSector.offsetAngle = (angle) => angle - Math.PI / 2\n } else if (!positiveX && positiveY) {\n this.zCircle.angleSector.baseAxes = new THREE.Vector3(0, 1, 0)\n this.zCircle.angleSector.offsetAngle = (angle) => angle + Math.PI / 2\n } else if (!positiveX && !positiveY) {\n this.zCircle.angleSector.baseAxes = new THREE.Vector3(-1, 0, 0)\n this.zCircle.angleSector.offsetAngle = (angle) => angle + Math.PI\n }\n }\n }\n }\n\n public showDraggingHelper(directions: Direction[]) {\n this.hide()\n this.children.filter((child) => directions.includes(child.direction)).forEach((child) => child.showRing())\n this.angleTips?.show()\n }\n\n public dispose() {\n this.removeFromParent()\n this.angleTips?.element?.remove()\n }\n}\n\nclass RotateCircleGroup extends THREE.Group {\n public direction: Direction\n /** 1/4 圆 */\n public circle: Circle\n /** 旋转过程中展示的背景圆环 */\n public ring: DashedRing\n /** 旋转过程中表示角度的扇形 */\n public angleSector: AngleSector\n\n public constructor(options: { direction: Direction; color?: Color }) {\n super()\n this.direction = options.direction\n\n this.circle = new Circle(options)\n this.ring = new DashedRing(options)\n this.angleSector = new AngleSector(options)\n\n this.add(this.circle, this.ring, this.angleSector)\n\n if (this.direction === 'y') this.rotation.x = Math.PI / 2\n else if (this.direction === 'x') this.rotation.y = -Math.PI / 2\n }\n\n public showCircle() {\n this.add(this.circle)\n this.remove(this.ring, this.angleSector)\n }\n\n public showRing() {\n this.add(this.ring, this.angleSector)\n this.remove(this.circle)\n }\n\n public hide() {\n // 改为remove而不是设置visible,是因为会影响其他helper的碰撞检测\n this.remove(this.ring, this.angleSector, this.circle)\n }\n}\n\nclass Circle extends THREE.Mesh {\n public direction: Direction\n public declare material: THREE.MeshBasicMaterial\n public gapAngle = 0.02\n public geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, this.gapAngle, Math.PI / 2 - this.gapAngle * 2)\n\n public constructor(options: { direction: Direction; color?: Color }) {\n super()\n\n this.material = new THREE.MeshBasicMaterial({\n opacity: 0.6,\n transparent: true, // 设置为透明材质,确保在透明渲染队列中\n color: options.color ?? 0xffffff,\n side: THREE.DoubleSide,\n depthTest: false,\n })\n this.direction = options.direction\n this.renderOrder = RENDER_ORDER.ROTATE_HELPER\n this.geometry.name = `RotateHelperCircleGeometry-${this.direction}`\n }\n}\n\nclass DashedRing extends THREE.Group {\n public direction: Readonly<Direction>\n\n public constructor(options: { direction: Direction }) {\n super()\n this.direction = options.direction\n\n const gapAngle = 0.015\n\n const meshes = new Array(8).fill(null).map((_, i) => {\n const geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, (Math.PI / 4) * i + gapAngle, Math.PI / 4 - gapAngle * 2)\n const material = new THREE.MeshBasicMaterial({\n opacity: 1,\n color: 0xffffff,\n depthTest: false,\n depthWrite: false,\n transparent: true,\n side: THREE.DoubleSide,\n })\n\n const mesh = new THREE.Mesh(geometry, material)\n mesh.name = `AxesDashedRing-${this.direction}-${i}`\n return mesh\n })\n\n this.add(...meshes)\n }\n}\n\nclass AngleSector extends THREE.Mesh {\n public direction: Direction\n public baseAxes: THREE.Vector3\n public offsetAngle: (angle: number) => number = (angle) => angle\n public angleDirection: 1 | -1\n public declare material: THREE.MeshBasicMaterial\n\n public constructor(options: { direction: Direction; color?: Color }) {\n super()\n\n switch (options.direction) {\n case 'x':\n this.baseAxes = new THREE.Vector3(0, 0, 1)\n break\n case 'y':\n this.baseAxes = new THREE.Vector3(1, 0, 0)\n break\n case 'z':\n this.baseAxes = new THREE.Vector3(1, 0, 0)\n break\n }\n\n const ratio = 0.3 + 0.0005 // 挡住白色圆环的锯齿\n this.geometry = new THREE.CircleGeometry(ratio, 48, 0, 0.0001)\n this.material = new THREE.MeshBasicMaterial({\n opacity: 0.4,\n color: options.color ?? 0xffffff,\n depthTest: false,\n depthWrite: false,\n transparent: true,\n side: THREE.DoubleSide,\n })\n\n this.direction = options.direction\n this.angleDirection = this.direction === 'z' ? 1 : -1\n }\n\n /**\n * 设置扇形旋转方向为顺时针\n */\n public setClockwiseDirection() {\n this.angleDirection = -1\n }\n\n /**\n * 设置扇形旋转方向为逆时针\n */\n public setCounterClockwiseDirection() {\n this.angleDirection = 1\n }\n\n /**\n * 切换扇形旋转方向\n */\n public toggleDirection() {\n this.angleDirection = this.angleDirection === 1 ? -1 : 1\n }\n\n /**\n * 设置扇形的基础轴向\n * @param axes 新的基础轴向向量\n */\n public setBaseAxes(axes: THREE.Vector3) {\n this.baseAxes = axes.clone().normalize()\n }\n\n /**\n * 获取当前旋转方向\n * @returns 'clockwise' | 'counterclockwise'\n */\n public getDirection(): 'clockwise' | 'counterclockwise' {\n return this.angleDirection === -1 ? 'clockwise' : 'counterclockwise'\n }\n}\n","import type { Direction4 } from '../../typings'\nimport { createElement } from './utils/createElement'\n\ninterface Sphere {\n element: HTMLElement\n direction: Direction4\n}\n\nexport function rectangleScaleDom() {\n const container = createElement({\n width: '100%',\n height: '100%',\n left: '0',\n top: '0',\n position: 'absolute',\n pointerEvents: 'none',\n })\n const wrapper = createElement({\n boxSizing: 'border-box',\n width: '100%',\n height: '100%',\n left: '0',\n top: '0',\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n })\n const border = createElement({\n boxSizing: 'border-box',\n width: '100%',\n height: '100%',\n left: '0',\n top: '0',\n position: 'absolute',\n border: '1px solid rgba(255,255,255,0.4)',\n })\n // DELETE\n // const text = createElement({ fontSize: '50px' })\n // text.innerText = '这是正面'\n // wrapper.appendChild(text)\n\n container.appendChild(wrapper)\n wrapper.appendChild(border)\n\n /**\n * 6----5----4\n * | |\n * 7 3\n * | |\n * 0----1----2\n */\n const offset = '-4px'\n const sphere0: Sphere = { direction: 'nesw', element: sphereDom({ cursor: 'nesw-resize', left: offset, bottom: offset }) }\n const sphere1: Sphere = { direction: 'ns', element: sphereDom({ cursor: 'ns-resize', bottom: offset }) }\n const sphere2: Sphere = { direction: 'nwse', element: sphereDom({ cursor: 'nwse-resize', right: offset, bottom: offset }) }\n const sphere3: Sphere = { direction: 'ew', element: sphereDom({ cursor: 'ew-resize', right: offset }) }\n const sphere4: Sphere = { direction: 'nesw', element: sphereDom({ cursor: 'nesw-resize', right: offset, top: offset }) }\n const sphere5: Sphere = { direction: 'ns', element: sphereDom({ cursor: 'ns-resize', top: offset }) }\n const sphere6: Sphere = { direction: 'nwse', element: sphereDom({ cursor: 'nwse-resize', left: offset, top: offset }) }\n const sphere7: Sphere = { direction: 'ew', element: sphereDom({ cursor: 'ew-resize', left: offset }) }\n\n // 0,2,4,6 四个角放后面,当点击区域可能出现互相遮挡的情况时,优先保障四个角的点\n new Array(sphere1, sphere3, sphere5, sphere7, sphere0, sphere2, sphere4, sphere6).forEach((sphere) => wrapper.appendChild(sphere.element))\n const spheres: [Sphere, Sphere, Sphere, Sphere, Sphere, Sphere, Sphere, Sphere] = [\n sphere0,\n sphere1,\n sphere2,\n sphere3,\n sphere4,\n sphere5,\n sphere6,\n sphere7,\n ]\n return { container, spheres }\n}\n\nexport function backgroundDom() {\n return createElement({\n width: '100%',\n height: '100%',\n left: '0',\n top: '0',\n position: 'absolute',\n background: 'rgba(0, 0, 0, 0.15)',\n pointerEvents: 'none',\n })\n}\n\nfunction sphereDom(style?: Partial<CSSStyleDeclaration>) {\n const sphere = createElement({\n background: '#FFFF00',\n width: '9px',\n height: '9px',\n position: 'absolute',\n pointerEvents: 'none',\n borderRadius: '50%',\n ...style,\n })\n const sphereDraggingWrapper = createElement({\n width: '15px',\n height: '15px',\n position: 'absolute',\n left: '50%',\n top: '50%',\n transform: 'translate(-50%, -50%)',\n pointerEvents: 'none',\n })\n const sphereDragging = createElement({\n width: '15px',\n height: '15px',\n cursor: style?.cursor,\n pointerEvents: 'auto',\n // backgroundColor: 'red',\n background: 'transparent',\n })\n sphereDragging.draggable = true\n sphereDraggingWrapper.appendChild(sphereDragging)\n sphere.appendChild(sphereDraggingWrapper)\n return sphere\n}\n","import type * as THREE from 'three/webgpu'\nimport { Subscribe } from '../../Subscribe'\n\nconst map = new Map<\n THREE.Camera,\n {\n dispose: () => void\n hooks: any\n }\n>()\n\nexport function cameraHooks(camera: THREE.Camera) {\n // 单例\n if (map.has(camera)) {\n return map.get(camera).hooks\n }\n\n const cameraHooks = new Subscribe<{\n cameraUpdate: () => any\n }>()\n\n let cancelAnimationFrameId: number | null = null\n let cameraPose: string\n\n const animate = () => {\n cancelAnimationFrameId = requestAnimationFrame(animate)\n const newCameraPose = camera.projectionMatrix.toArray().join(',') + camera.matrixWorld.toArray().join(',')\n if (newCameraPose !== cameraPose) {\n cameraPose = newCameraPose\n cameraHooks.emit('cameraUpdate')\n }\n }\n\n animate()\n\n const dispose = () => {\n map.delete(camera)\n cancelAnimationFrame(cancelAnimationFrameId!)\n }\n\n map.set(camera, {\n hooks: cameraHooks,\n dispose,\n })\n\n return cameraHooks\n}\n\nexport function disposeCameraHooks(camera: THREE.Camera) {\n if (map.has(camera)) map.get(camera).dispose()\n}\n","import { CSS3DRender } from '../../../CSS3DRenderPlugin/utils/three/CSS3DRender'\nimport * as THREE from 'three/webgpu'\nimport { RectangleScaleHelperAbstract } from '.'\nimport type { Create3DElementReturnType } from '../../../CSS3DRenderPlugin'\nimport type { Vector3 } from 'three/webgpu'\nimport { rectangleScaleDom } from './HTML/rectangleScaleDom'\nimport type { CSS3DObjectPlus } from '../../../CSS3DRenderPlugin/utils/three/CSS3DObject'\nimport { cameraHooks } from '../utils/cameraHooks'\n\ntype NonVoid<T> = T extends void ? never : T\n\nexport class CSS3DScaleHelper<T extends CSS3DObjectPlus = CSS3DObjectPlus> extends RectangleScaleHelperAbstract<T, HTMLElement> {\n public name = 'CSS3DScaleHelper'\n public points: RectangleScaleHelperAbstract<THREE.Object3D, HTMLElement>['points'] = []\n public cornerPositions: Vector3[] = []\n public css3DInstance?: NonVoid<Create3DElementReturnType>\n public get helperObject() {\n if (!this.css3DInstance?.css3DObject) throw new Error('css3DInstance is not initialized')\n return this.css3DInstance.css3DObject\n }\n public plane?: THREE.Mesh<THREE.PlaneGeometry, THREE.MeshBasicMaterial>\n private css3DRenderer = new CSS3DRender()\n private camera: THREE.Camera\n private scene: THREE.Scene\n private container: HTMLElement\n private enabled = false\n private initialScale?: { x: number; y: number } // 记录初始缩放值\n\n\n public constructor(originObject3D: T, container: HTMLElement, camera: THREE.Camera, scene: THREE.Scene) {\n super(originObject3D)\n this.camera = camera\n this.scene = scene\n this.container = container\n this.initRectangleScaleHelper()\n }\n\n public initQuaternion(): void {\n this.quaternion.copy(this.originObject3D.quaternion)\n }\n\n public applyMatrix4(matrix: THREE.Matrix4) {\n super.applyMatrix4(matrix)\n this.helperObject.applyMatrix4(matrix)\n this.plane?.applyMatrix4(matrix)\n this.cornerPositions.forEach((cornerPosition) => cornerPosition.applyMatrix4(matrix))\n }\n\n public showDraggingHelper() {\n // nothing to do\n }\n\n public applyHelperScaleMatrix4(matrix: THREE.Matrix4, origin?: Vector3) {\n this.plane?.scale.applyMatrix4(matrix)\n this.helperObject.applyScaleMatrix4(matrix)\n\n // 缩放后更新球体校正和小点容器尺寸\n setTimeout(() => {\n this.updateSphereCorrection()\n }, 0)\n }\n\n public updatePoints() {\n const position8 = this.calculatePointPosition(this.cornerPositions as [Vector3, Vector3, Vector3, Vector3])\n this.points.forEach((point, index) => {\n point.position.copy(position8[index]!)\n })\n }\n\n public update(camera: THREE.Camera) {\n // 更新CSS3D元素的位置\n if (this.css3DInstance?.css3DObject) {\n this.helperObject.position.copy(this.originObject3D.position)\n }\n\n // 更新平面位置\n if (this.plane) {\n this.plane.position.copy(this.originObject3D.position)\n }\n\n // 更新控制点位置\n this.updatePoints()\n\n // 更新CSS3D元素的可见性\n if (this.css3DInstance) {\n this.css3DInstance.show()\n }\n\n if (this.plane) {\n this.plane.visible = true\n }\n }\n\n public applyHelperQuaternion(quaternion: THREE.Quaternion, origin: Vector3) {\n const css3DObject = this.css3DInstance?.css3DObject\n\n if (css3DObject) {\n const v = new THREE.Vector3().subVectors(css3DObject.position, origin).applyQuaternion(quaternion).add(origin)\n css3DObject.position.copy(v)\n css3DObject.applyQuaternion(quaternion)\n }\n\n if (this.plane) {\n const v = new THREE.Vector3().subVectors(this.plane.position, origin).applyQuaternion(quaternion).add(origin)\n this.plane.position.copy(v)\n this.plane.applyQuaternion(quaternion)\n }\n\n this.cornerPositions.forEach((cornerPosition) => {\n const v = new THREE.Vector3().subVectors(cornerPosition, origin).applyQuaternion(quaternion).add(origin)\n cornerPosition.copy(v)\n })\n }\n\n public enable() {\n if (this.enabled) return\n this.enabled = true\n this.css3DInstance?.enable()\n if (this.plane) this.scene.add(this.plane)\n }\n\n public disable() {\n if (!this.enabled) return\n this.enabled = false\n this.css3DInstance?.disable()\n if (this.plane) this.scene.remove(this.plane)\n }\n\n public show() {\n this.css3DInstance?.show()\n if (this.plane) this.plane.visible = true\n }\n\n public hide() {\n this.css3DInstance?.hide()\n if (this.plane) this.plane.visible = false\n }\n\n public dispose() {\n this.disable()\n this.css3DRenderer.dispose()\n }\n\n /**\n * 缩放结束时的回调方法\n * 触发相机更新事件\n */\n public onScaleEnd() {\n // 手动触发相机更新事件\n cameraHooks(this.camera).emit('cameraUpdate')\n }\n\n private updateSphereCorrection() {\n if (!this.css3DInstance) return\n\n // 记录初始缩放值(第一次调用时)\n if (!this.initialScale) {\n this.initialScale = {\n x: this.originObject3D.scale.x,\n y: this.originObject3D.scale.y,\n }\n }\n\n // 计算相对于初始值的缩放比例\n const currentScale = this.originObject3D.scale\n const relativeScaleX = currentScale.x / this.initialScale.x\n const relativeScaleY = currentScale.y / this.initialScale.y\n // 通过 CSS 变量设置父级缩放值\n const parentElement = this.css3DInstance.css3DObject.container\n parentElement.style.setProperty('--parent-scaleX', relativeScaleX.toString())\n parentElement.style.setProperty('--parent-scaleY', relativeScaleY.toString())\n }\n\n private initRectangleScaleHelper() {\n const cornerPositions = this.getCornerPositions()\n\n if (!cornerPositions) return\n\n this.cornerPositions = cornerPositions\n\n const css3DInstance = this.css3DRenderer.create3DElement(this.camera, cornerPositions, { ratio: 0.003 }) // ratio 暂时不用和 originObject3D 保持同步,因为本来就是不同的东西\n\n if (!css3DInstance) return\n\n this.css3DInstance = css3DInstance\n css3DInstance.appendToElement(this.container)\n\n // create UI\n const css3DObjectElement = css3DInstance.css3DObject.container\n const { container: dom, spheres } = rectangleScaleDom()\n this.points = spheres.map((sphere, index) => ({\n direction: sphere.direction,\n point: sphere.element,\n position: this.calculatePointPosition(cornerPositions)[index]!,\n }))\n\n // append html\n // css3DObjectElement.appendChild(backgroundDom())\n css3DObjectElement.insertBefore(dom, css3DObjectElement.children[0] ?? null)\n\n this.helperObject.position.copy(this.originObject3D.position)\n this.plane?.position.copy(this.originObject3D.position)\n }\n\n private getCornerPositions() {\n const { originObject3D } = this\n if ((originObject3D as any).isCSS3DObject && (originObject3D as any).cornerPoints) {\n const o = originObject3D as InstanceType<typeof CSS3DObjectPlus>\n return o.cornerPoints\n } else {\n console.error('当前物体暂时不支持 ScaleHelper')\n }\n }\n\n private calculatePointPosition(cornerPositions: [THREE.Vector3, THREE.Vector3, THREE.Vector3, THREE.Vector3]) {\n /**\n * 6----5----4\n * | |\n * 7 3\n * | |\n * 0----1----2\n */\n return [\n cornerPositions[0].clone(),\n cornerPositions[0].clone().add(cornerPositions[1]).divideScalar(2),\n cornerPositions[1].clone(),\n cornerPositions[1].clone().add(cornerPositions[2]).divideScalar(2),\n cornerPositions[2].clone(),\n cornerPositions[2].clone().add(cornerPositions[3]).divideScalar(2),\n cornerPositions[3].clone(),\n cornerPositions[3].clone().add(cornerPositions[0]).divideScalar(2),\n ]\n }\n}\n","import * as THREE from 'three/webgpu'\nimport { BoundingBoxHelperAbstract } from '../Base/BaseHelper'\nimport { boundingBox } from '../../three/boundingBox'\nimport setObjectQuaternion from '../utils/setObjectQuaternion'\n\nexport class BoundingBoxHelper<T extends THREE.Object3D = THREE.Object3D> extends BoundingBoxHelperAbstract<T> {\n public name = 'BoundingBoxHelper'\n public box: THREE.Mesh<THREE.BufferGeometry, THREE.MeshBasicMaterial>\n public outline: THREE.LineSegments<THREE.BufferGeometry, THREE.LineBasicMaterial>\n private positionAttribute: THREE.BufferAttribute\n\n public constructor(originObject: T) {\n super(originObject)\n\n this.positionAttribute = new THREE.BufferAttribute(new Float32Array(8 * 3), 3)\n this.box = this.createBox()\n this.outline = this.createOutline()\n\n this.add(this.box, this.outline)\n this.update()\n }\n\n public initQuaternion(): void {\n this.quaternion.copy(this.originObject3D.quaternion)\n }\n\n public setHelperQuaternion(quaternion: THREE.Quaternion, origin?: THREE.Vector3) {\n setObjectQuaternion(this, quaternion, origin)\n }\n\n public raycasterIntersectObject(raycaster: THREE.Raycaster, intersection: THREE.Intersection[]): THREE.Intersection[] {\n return raycaster.intersectObject(this, false, intersection)\n }\n\n public raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]) {\n // 判断相交时,只判断面\n this.box.raycast(raycaster, intersects)\n }\n\n private update() {\n /*\n 5____4\n 1/___0/|\n | 6__|_7\n 2/___3/\n\n 0: max.x, max.y, max.z\n 1: min.x, max.y, max.z\n 2: min.x, min.y, max.z\n 3: max.x, min.y, max.z\n 4: max.x, max.y, min.z\n 5: min.x, max.y, min.z\n 6: min.x, min.y, min.z\n 7: max.x, min.y, min.z\n\t\t*/\n const box3 = boundingBox(this.originObject3D)\n if (!box3) return\n\n const { min, max } = box3\n\n this.positionAttribute.setXYZ(0, max.x, max.y, max.z)\n this.positionAttribute.setXYZ(1, min.x, max.y, max.z)\n this.positionAttribute.setXYZ(2, min.x, min.y, max.z)\n this.positionAttribute.setXYZ(3, max.x, min.y, max.z)\n this.positionAttribute.setXYZ(4, max.x, max.y, min.z)\n this.positionAttribute.setXYZ(5, min.x, max.y, min.z)\n this.positionAttribute.setXYZ(6, min.x, min.y, min.z)\n this.positionAttribute.setXYZ(7, max.x, min.y, min.z)\n\n this.positionAttribute.needsUpdate = true\n }\n\n private createOutline() {\n const lineIndices = new Uint16Array([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7])\n const lineGeometry = new THREE.BufferGeometry()\n lineGeometry.setIndex(new THREE.BufferAttribute(lineIndices, 1))\n lineGeometry.setAttribute('position', this.positionAttribute)\n const lineMaterial = new THREE.LineBasicMaterial({\n color: 0x00fcff,\n linewidth: 1,\n opacity: 1,\n toneMapped: false,\n })\n const lineSegments = new THREE.LineSegments(lineGeometry, lineMaterial)\n lineSegments.matrixAutoUpdate = false\n return lineSegments\n }\n\n private createBox() {\n const boxIndices = new Uint16Array([\n 0, 1, 2, 0, 2, 3, 0, 3, 7, 0, 7, 4, 0, 4, 5, 0, 5, 1, 6, 1, 5, 6, 2, 1, 6, 5, 4, 6, 4, 7, 6, 3, 2, 6, 7, 3,\n ])\n const boxGeometry = new THREE.BufferGeometry()\n boxGeometry.setIndex(new THREE.BufferAttribute(boxIndices, 1))\n boxGeometry.setAttribute('position', this.positionAttribute)\n const boxMaterial = new THREE.MeshBasicMaterial({\n color: 0x00fcff,\n opacity: 0.1,\n depthTest: false,\n transparent: true,\n })\n const box = new THREE.Mesh(boxGeometry, boxMaterial)\n return box\n }\n}\n","import * as THREE from 'three/webgpu'\nimport { Subscribe } from '../../Subscribe'\nimport type { SolidGuideOptions } from '../utils/solidGuide'\nimport type { HelperEventMap, HelperOffset, InternalHelperEventMap, ScaleCallback } from '../typings'\nimport type { BaseHelper } from './BaseHelper'\nimport type DomEvents from '../../threex/domevents'\nimport { notNil } from '../../isNil'\nimport { boundingBox } from '../../three/boundingBox'\nimport type { Vector3Position } from '../../../typings/math.type'\nimport { toArray } from '../../util'\nimport { cameraHooks } from '../utils/cameraHooks'\n\nexport let originOpacity: { opacity: number } | null = null\n\ntype Config = {\n offset?: HelperOffset\n yAxis?: THREE.Vector3 | (() => THREE.Vector3)\n xAxis?: THREE.Vector3 | (() => THREE.Vector3)\n zAxis?: THREE.Vector3 | (() => THREE.Vector3)\n scaleCallback?: ScaleCallback\n /** 实线样式与行为配置(透传给 SolidGuideLine) */\n solidGuide?: SolidGuideOptions\n}\n\nexport abstract class BaseController<T extends BaseHelper = BaseHelper, K extends THREE.Object3D = THREE.Object3D> {\n public originObject3D: K\n public hooks: Subscribe<HelperEventMap>\n public preventTapDefaultEvent = false\n protected internalHooks: Subscribe<InternalHelperEventMap>\n protected readonly disposers: (() => void)[] = []\n protected helperObject3D: T\n protected camera: THREE.Camera\n protected model: THREE.Object3D\n protected scene: THREE.Object3D\n protected container: HTMLElement\n protected domEvents: DomEvents\n protected isDragging = false\n protected enabled = false\n protected name = 'BaseController'\n protected boundingBox?: THREE.Box3\n protected config: Config\n private onRender: () => void\n protected cameraHooks: Subscribe<{\n cameraUpdate: () => any\n }>\n /** 其他控制器的引用,用于跨控制器状态检查 */\n protected otherControllers?: {\n moveController?: BaseController\n rotateController?: BaseController\n scaleController?: BaseController\n }\n\n /**\n * 更新其他控制器的引用\n */\n public updateOtherControllers(otherControllers: {\n moveController?: BaseController\n rotateController?: BaseController\n scaleController?: BaseController\n }) {\n this.otherControllers = otherControllers\n }\n\n /**\n * 获取当前控制器的拖拽状态\n */\n public getIsDragging(): boolean {\n return this.isDragging\n }\n\n public constructor(\n params: {\n camera: THREE.Camera\n model: THREE.Object3D\n originObject3D: K\n helperObject3D: T\n container: HTMLElement\n domEvents: DomEvents\n scene: THREE.Object3D\n onRender?: () => void\n sharedHooks?: Subscribe<HelperEventMap>\n sharedInternalHooks?: Subscribe<InternalHelperEventMap>\n /** 其他控制器的引用,用于跨控制器状态检查 */\n otherControllers?: {\n moveController?: BaseController\n rotateController?: BaseController\n scaleController?: BaseController\n }\n },\n config?: Config,\n ) {\n this.hooks = params.sharedHooks ?? new Subscribe<HelperEventMap>()\n this.internalHooks = params.sharedInternalHooks ?? new Subscribe<InternalHelperEventMap>()\n this.camera = params.camera\n this.model = params.model\n this.originObject3D = params.originObject3D\n this.helperObject3D = params.helperObject3D\n this.container = params.container\n this.scene = params.scene\n this.domEvents = params.domEvents\n this.onRender = params.onRender ?? (() => {})\n this.config = config ?? {}\n this.otherControllers = params.otherControllers\n this.initialHelperPosition()\n this.initialHelperQuaternion()\n this.updateHelperScale()\n this.cameraHooks = cameraHooks(this.camera)\n\n this.enable()\n\n const handleSetObjectScale = this.onSetOriginObjectScale.bind(this)\n const handleSetObjectRotate = this.onSetOriginObjectRotate.bind(this)\n const handleSetObjectPosition = this.onSetOriginObjectPosition.bind(this)\n\n const handleApplyObjectScale = this.onApplyOriginObjectScale.bind(this)\n const handleApplyObjectRotate = this.onApplyOriginObjectRotate.bind(this)\n const handleApplyObjectPosition = this.onApplyOriginObjectPosition.bind(this)\n const initialHelperPosition = this.initialHelperPosition.bind(this)\n\n this.cameraHooks.on('cameraUpdate', this.updateHelperScale)\n\n this.internalHooks.on('initialHelperPosition', initialHelperPosition)\n\n this.internalHooks.on('setObjectScale', handleSetObjectScale)\n this.internalHooks.on('setObjectRotate', handleSetObjectRotate)\n this.internalHooks.on('setObjectPosition', handleSetObjectPosition)\n\n this.internalHooks.on('applyObjectPosition', handleApplyObjectPosition)\n this.internalHooks.on('applyObjectRotate', handleApplyObjectRotate)\n this.internalHooks.on('applyObjectScale', handleApplyObjectScale)\n\n // updateHelperScale 监听得在后面,因为要保证先更新 helper 的位置等信息后,再计算大小\n this.hooks.on('moveEnd', this.updateHelperScale)\n this.internalHooks.on('setObjectPosition', this.updateHelperScale)\n this.internalHooks.on('initialHelperPosition', this.updateHelperScale)\n\n this.disposers.push(() => {\n this.cameraHooks.off('cameraUpdate', this.updateHelperScale)\n\n this.internalHooks.off('initialHelperPosition', initialHelperPosition)\n\n this.internalHooks.off('setObjectScale', handleSetObjectScale)\n this.internalHooks.off('setObjectRotate', handleSetObjectRotate)\n this.internalHooks.off('setObjectPosition', handleSetObjectPosition)\n\n this.internalHooks.off('applyObjectPosition', handleApplyObjectPosition)\n this.internalHooks.off('applyObjectRotate', handleApplyObjectRotate)\n this.internalHooks.off('applyObjectScale', handleApplyObjectScale)\n\n this.hooks.off('moveEnd', this.updateHelperScale)\n this.internalHooks.off('setObjectPosition', this.updateHelperScale)\n this.internalHooks.off('initialHelperPosition', this.updateHelperScale)\n })\n }\n\n public initialHelperPosition() {\n this.helperObject3D.initialPosition(this.calculateOffset(this.config.offset))\n }\n\n public initialHelperQuaternion() {\n this.helperObject3D.initQuaternion(this.config)\n }\n\n public enable() {\n if (this.enabled) return\n this.enabled = true\n this.scene.add(this.helperObject3D)\n this.helperObject3D.enable()\n this.render()\n }\n\n public disable() {\n if (!this.enabled) return\n this.enabled = false\n this.helperObject3D.disable()\n this.render()\n }\n\n public show() {\n this.helperObject3D.show()\n this.render()\n }\n\n public hide() {\n this.helperObject3D.hide()\n this.render()\n }\n\n public dispose() {\n this.disposers?.forEach((d) => d?.())\n this.helperObject3D.dispose()\n this.render()\n }\n\n /**\n * @description: applyHelperMatrix4\n * @param {THREE.Matrix4} matrix position 偏移量\n */\n public applyHelperMatrix4(matrix: THREE.Matrix4) {\n this.helperObject3D.applyMatrix4(matrix)\n }\n\n /**\n * @description: applyHelperQuaternion\n * @param {THREE.Quaternion} quaternion 旋转四元数\n * @param {THREE.Vector3} origin 旋转中心\n */\n public applyHelperQuaternion(quaternion: THREE.Quaternion, origin: THREE.Vector3) {\n this.helperObject3D.applyHelperQuaternion(quaternion, origin)\n }\n\n /**\n * @description: applyHelperScaleMatrix4\n * @param {THREE.Matrix4} matrix 缩放矩阵\n * @param {THREE.Vector3} origin 缩放中心\n */\n public applyHelperScaleMatrix4(matrix: THREE.Matrix4, origin?: THREE.Vector3) {\n this.helperObject3D.applyHelperScaleMatrix4(matrix, origin)\n }\n\n public onWantsTapGesture = (raycaster: THREE.Raycaster): false | void => {\n const selectedObject = this.getIntersectObject(raycaster)\n if (selectedObject) return false\n return\n }\n\n public updateHelperScale = () => {\n // 调用 helper 的 update 方法\n if ('update' in this.helperObject3D && typeof this.helperObject3D.update === 'function') {\n this.helperObject3D.update(this.camera)\n }\n this.helperObject3D.setScaleByCamera(this.camera as any)\n }\n\n public onWantsGesture(type: 'press' | 'pan' | string, pointers: { x: number; y: number }[], final: boolean): false | void {\n if (this.isDragging) return false\n }\n\n public onIntersectionOnModelUpdate(intersection: THREE.Intersection) {}\n\n /**\n * @description: onApplyOriginObjectScale\n * @param {THREE.Matrix4} params.matrix 缩放矩阵\n * @param {THREE.Vector3} params.origin 缩放中心\n */\n protected onApplyOriginObjectScale(params: { matrix: THREE.Matrix4; origin?: THREE.Vector3 }) {\n this.applyHelperScaleMatrix4(params.matrix, params.origin)\n }\n\n /**\n * @description: onApplyOriginObjectRotate\n * @param {THREE.Quaternion} params.quaternion 旋转四元数\n * @param {THREE.Vector3} params.origin 旋转中心\n */\n protected onApplyOriginObjectRotate(params: { quaternion: THREE.Quaternion; origin: THREE.Vector3 }) {\n this.applyHelperQuaternion(params.quaternion, params.origin)\n }\n\n /**\n * @description: onApplyOriginObjectPosition\n * @param {THREE.Matrix4} params.matrix position 偏移量\n */\n protected onApplyOriginObjectPosition(params: { matrix: THREE.Matrix4 }) {\n this.applyHelperMatrix4(params.matrix)\n }\n\n protected onSetOriginObjectScale(scale: THREE.Vector3) {\n this.helperObject3D.scale.copy(scale)\n this.updateOffsetByScale(scale)\n }\n\n protected onSetOriginObjectRotate(quaternion: THREE.Quaternion, origin: THREE.Vector3) {\n this.helperObject3D.setHelperQuaternion(quaternion, origin)\n }\n\n protected onSetOriginObjectPosition(position: THREE.Vector3) {\n this.helperObject3D.position.copy(position.clone().add(this.calculateOffset(this.config.offset)))\n }\n\n protected render() {\n this.onRender()\n }\n\n protected updateOffsetByScale(scale: THREE.Vector3) {\n if (this.boundingBox && this.config.offset) {\n const origin = this.originObject3D.position\n const max = new THREE.Vector3().subVectors(this.boundingBox.max, origin).multiply(scale).add(origin)\n const min = new THREE.Vector3().subVectors(this.boundingBox.min, origin).multiply(scale).add(origin)\n const offset = this.calculateOffset(this.config.offset, { min, max })\n this.helperObject3D.initialPosition(offset)\n }\n }\n\n protected hoverListener(\n object3D: THREE.Object3D | undefined | THREE.Group | (THREE.Object3D | undefined | THREE.Group)[],\n hoverColor: THREE.Color | string | number = 0xffffff,\n hoverOpacity = 1,\n ): () => void {\n const objects = toArray(object3D).filter(notNil)\n const disposers: (() => void)[] = []\n for (const object of objects) {\n if ((object as any).material || object instanceof THREE.Group) {\n const meshes =\n object instanceof THREE.Group\n ? (object.children.filter((child) => child instanceof THREE.Mesh) as THREE.Mesh[])\n : ([object] as THREE.Mesh<any, THREE.MeshBasicMaterial>[])\n\n meshes.forEach((mesh) => {\n // 处理材质数组的情况(如 CenterHandle 的多面材质)\n if (Array.isArray(mesh.material)) {\n ;(mesh as any)['__originalColor__'] = (mesh as any)['__originalColor__'] ?? mesh.material.map((mat) => mat.color.clone())\n ;(mesh as any)['__originalOpacity__'] = (mesh as any)['__originalOpacity__'] ?? mesh.material.map((mat) => mat.opacity)\n } else {\n ;(mesh as any)['__originalColor__'] = (mesh as any)['__originalColor__'] ?? mesh.material.color.clone()\n ;(mesh as any)['__originalOpacity__'] = (mesh as any)['__originalOpacity__'] ?? mesh.material.opacity\n }\n })\n\n const setHoverColor = () => {\n meshes.forEach((mesh) => {\n if (mesh.name === 'ScaleHelperTransparentGroup') {\n if (mesh.children[0]) {\n mesh.children[0].material.color.set(hoverColor)\n mesh.children[0].material.opacity = hoverOpacity\n }\n } else {\n // 处理材质数组的情况\n if (Array.isArray(mesh.material)) {\n mesh.material.forEach((mat) => {\n mat.color.set(hoverColor)\n mat.opacity = hoverOpacity\n })\n } else {\n mesh.material.color.set(hoverColor)\n mesh.material.opacity = hoverOpacity\n }\n }\n })\n this.render()\n }\n const resetColor = () => {\n meshes.forEach((mesh) => {\n if (mesh.name === 'ScaleHelperTransparentGroup') {\n if (mesh.children[0]) {\n mesh.children[0].material.color.set(0xffff00)\n mesh.children[0].material.opacity = 1\n }\n } else {\n // 处理材质数组的情况\n if (Array.isArray(mesh.material)) {\n const originalColors = (mesh as any)['__originalColor__']\n const originalOpacities = (mesh as any)['__originalOpacity__']\n mesh.material.forEach((mat, index) => {\n if (originalColors && originalColors[index]) {\n mat.color.copy(originalColors[index])\n }\n if (originalOpacities && originalOpacities[index] !== undefined) {\n mat.opacity = originalOpacities[index]\n }\n })\n } else {\n mesh.material.color.copy((mesh as any)['__originalColor__'])\n mesh.material.opacity = (mesh as any)['__originalOpacity__']\n }\n }\n })\n this.render()\n }\n\n const handleMouseover = (e) => {\n if (this.isDragging) return\n setHoverColor()\n }\n const handleMouseout = (e) => {\n if (this.isDragging) return\n resetColor()\n }\n\n for (const mesh of meshes) {\n this.domEvents.addEventListener(mesh, 'mouseover', handleMouseover)\n this.domEvents.addEventListener(mesh, 'mouseout', handleMouseout)\n this.hooks.on('moveStart', setHoverColor)\n this.hooks.on('moveEnd', resetColor)\n this.hooks.on('rotateEnd', resetColor)\n this.hooks.on('scaleEnd', resetColor)\n disposers.push(() => {\n this.domEvents.removeEventListener(mesh, 'mouseover', handleMouseover)\n this.domEvents.removeEventListener(mesh, 'mouseout', handleMouseout)\n this.hooks.off('moveStart', setHoverColor)\n this.hooks.off('moveEnd', resetColor)\n this.hooks.off('rotateEnd', resetColor)\n this.hooks.off('scaleEnd', resetColor)\n })\n }\n }\n }\n return () => disposers.forEach((disposer) => disposer?.())\n }\n\n private getIntersectObject(raycaster: THREE.Raycaster) {\n const cameraPosition = this.camera.position\n const object = this.helperObject3D\n // 如果当前没有模型,则不存在模型被点击\n if (!object) return undefined\n\n // 如果存在模型,需要判断模型与射线的交点和 model 与射线的交点的远近\n\n const intersection = this.helperObject3D.raycasterIntersectObject(raycaster)[0]\n if (!intersection) return undefined\n const objectIntersection = intersection\n objectIntersection.object = object\n\n // 如果 five model intersection 更近,返回 undefined\n if ((this.model as any)['intersectRaycaster']) {\n const modelIntersection = (this.model as any).intersectRaycaster(raycaster)[0]\n if (modelIntersection && modelIntersection.point.distanceTo(cameraPosition) < objectIntersection.point.distanceTo(cameraPosition))\n return undefined\n }\n\n return objectIntersection.object\n }\n\n private getBox: () => { min: Vector3Position; max: Vector3Position } = () => {\n if (this.boundingBox) return this.boundingBox\n else {\n this.boundingBox = boundingBox(this.originObject3D)\n return this.boundingBox\n }\n }\n\n private calculateOffset(offset?: HelperOffset, box3?: { min: Vector3Position; max: Vector3Position }) {\n const result = new THREE.Vector3(0, 0, 0)\n\n if (!offset) return result\n\n const getBox: () => { min: Vector3Position; max: Vector3Position } = () => {\n if (box3) return box3\n return this.getBox()\n }\n\n // x\n if (typeof offset.x === 'number') result.setX(offset.x)\n else if (typeof offset.x === 'object') {\n const box = getBox()\n result.setX((box.max.x - box.min.x) * offset.x.percents)\n }\n\n // y\n if (typeof offset.y === 'number') result.setY(offset.y)\n else if (typeof offset.y === 'object') {\n const box = getBox()\n result.setY((box.max.y - box.min.y) * offset.y.percents)\n }\n\n // z\n if (typeof offset.z === 'number') result.setZ(offset.z)\n else if (typeof offset.z === 'object') {\n const box = getBox()\n result.setZ((box.max.z - box.min.z) * offset.z.percents)\n }\n\n return result\n }\n}\n","import { RENDER_ORDER } from '../Constants/RenderOrder'\nimport * as THREE from 'three/webgpu'\n\n/** 将世界坐标投影为屏幕像素坐标 */\nexport function projectToScreen(camera: THREE.Camera, container: HTMLElement | null | undefined, point: THREE.Vector3) {\n const width = container?.clientWidth || 1280\n const height = container?.clientHeight || 720\n const p = point.clone().project(camera)\n const x = (p.x + 1) * 0.5 * width\n const y = (1 - (p.y + 1) * 0.5) * height\n return new THREE.Vector2(x, y)\n}\n\n/** 估算某方向上线段的像素与世界长度的比例(世界单位/像素) */\nexport function computeWorldPerPixel(\n camera: THREE.Camera,\n container: HTMLElement | null | undefined,\n center: THREE.Vector3,\n direction: THREE.Vector3,\n) {\n const dir = direction.clone().normalize()\n const sample = 1\n const p1 = center.clone().sub(dir.clone().multiplyScalar(sample))\n const p2 = center.clone().add(dir.clone().multiplyScalar(sample))\n const s1 = projectToScreen(camera, container, p1)\n const s2 = projectToScreen(camera, container, p2)\n const pixelLength = s1.distanceTo(s2)\n if (pixelLength < 1e-3) return undefined\n const worldPerPixel = (2 * sample) / pixelLength\n return worldPerPixel\n}\n\n/** 计算直线长度:随相机距离/视口变化自适应,限制在可视范围内 */\nexport function computeGuideLength(camera: THREE.Camera, center: THREE.Vector3) {\n let viewWidth = 10\n let viewHeight = 10\n\n const persp = (camera as any).isPerspectiveCamera\n const ortho = (camera as any).isOrthographicCamera\n if (persp) {\n const cam = camera as THREE.PerspectiveCamera\n const distance = cam.position.distanceTo(center)\n const vFov = (cam.fov * Math.PI) / 180\n viewHeight = 2 * Math.tan(vFov / 2) * distance\n viewWidth = viewHeight * cam.aspect\n } else if (ortho) {\n const cam = camera as THREE.OrthographicCamera\n viewWidth = Math.abs(cam.right - cam.left)\n viewHeight = Math.abs(cam.top - cam.bottom)\n }\n\n const diag = Math.sqrt(viewWidth * viewWidth + viewHeight * viewHeight)\n const baseLength = diag * 0.8\n const minLen = Math.min(viewWidth, viewHeight) * 0.25\n const maxLen = diag * 1.2\n const length = Math.max(minLen, Math.min(baseLength, maxLen))\n return length\n}\n\nexport type SolidGuideOptions = {\n color?: number\n renderOrder?: number\n}\n\nexport class SolidGuideLine {\n private camera: THREE.Camera\n private container: HTMLElement | null | undefined\n private defaults: SolidGuideOptions\n\n public constructor(camera: THREE.Camera, container: HTMLElement | null | undefined, defaults?: SolidGuideOptions) {\n this.camera = camera\n this.container = container\n this.defaults = { ...(defaults || {}) }\n }\n\n /** 创建无限长直线(Line + LineBasicMaterial),穿过整个平面 */\n public createSolidLine(center: THREE.Vector3, direction: THREE.Vector3, options?: SolidGuideOptions) {\n const merged = { color: 0xffffff, renderOrder: RENDER_ORDER.DRAG_GUIDE_LINE, ...this.defaults, ...(options || {}) }\n const dir = direction.clone().normalize()\n\n // 创建一条足够长的直线,穿过整个可视区域\n const length = this.computeInfiniteLineLength(center)\n const start = center.clone().add(dir.clone().multiplyScalar(-length))\n const end = center.clone().add(dir.clone().multiplyScalar(length))\n\n const positions = new Float32Array([start.x, start.y, start.z, end.x, end.y, end.z])\n\n const geometry = new THREE.BufferGeometry()\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))\n\n const material = new THREE.LineBasicMaterial({\n color: merged.color,\n depthTest: false,\n depthWrite: false,\n transparent: true,\n opacity: 0.65,\n })\n\n const line = new THREE.Line(geometry, material)\n line.renderOrder = merged.renderOrder\n return line\n }\n\n /** 更新已创建的直线,使其始终穿过整个平面 */\n public updateSolidLine(\n line: THREE.Line<THREE.BufferGeometry, THREE.LineBasicMaterial>,\n center: THREE.Vector3,\n direction: THREE.Vector3,\n options?: SolidGuideOptions,\n ) {\n const dir = direction.clone().normalize()\n\n // 重新计算直线长度和位置\n const length = this.computeInfiniteLineLength(center)\n const start = center.clone().add(dir.clone().multiplyScalar(-length))\n const end = center.clone().add(dir.clone().multiplyScalar(length))\n\n const positions = new Float32Array([start.x, start.y, start.z, end.x, end.y, end.z])\n\n const geometry = line.geometry as THREE.BufferGeometry\n const attr = geometry.getAttribute('position') as THREE.BufferAttribute | undefined\n if (attr && attr.itemSize === 3 && attr.array.length === positions.length) {\n ;(attr.array as Float32Array).set(positions)\n attr.needsUpdate = true\n } else {\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))\n }\n\n // 更新材质颜色\n if (options?.color !== undefined) {\n line.material.color.setHex(options.color)\n }\n }\n\n /** 计算\"无限\"直线的长度,确保穿过整个可视区域 */\n private computeInfiniteLineLength(center: THREE.Vector3): number {\n const baseLength = computeGuideLength(this.camera, center)\n // 使用一个大的倍数确保直线看起来无限长\n return baseLength * 10 // 比原来的虚线长10倍,确保穿过整个平面\n }\n\n /** 释放直线的几何与材质 */\n public dispose(\n line?: THREE.Line<THREE.BufferGeometry, THREE.LineBasicMaterial>,\n ) {\n if (!line) return\n line.geometry.dispose()\n const material = line.material\n if (Array.isArray(material)) material.forEach((m) => m.dispose())\n else material.dispose()\n }\n\n /** 更新默认配置 */\n public updateDefaults(options: SolidGuideOptions) {\n this.defaults = { ...this.defaults, ...options }\n }\n}\n","import { BaseController } from '../Base/BaseController'\nimport { RENDER_ORDER } from '../Constants/RenderOrder'\nimport * as THREE from 'three/webgpu'\nimport { SolidGuideLine } from '../utils/solidGuide'\nimport { getMouseRaycaster } from '../utils'\nimport type { MoveHelperAbstract } from '../Helper'\nimport type { Direction } from '../typings'\nimport { rayOnLine } from '../../../Sculpt/utils/three/rayOnLine'\nimport { CenterHandle } from '../Helper/Objects/CenterHandle'\n\ntype UseFaceNormalInterface =\n | {\n enable?: boolean\n /**\n * @description: 期望对齐的方向,默认为Y轴对齐Face的法向向量,即 `{ x: 0, y: 1, z: 0 }`\n */\n alignmentVector?: { x?: number; y?: number; z?: number }\n /**\n * @description: 修正后的face\n */\n fixedFaceNormal?: (face: THREE.Vector3) => THREE.Vector3\n }\n | boolean\n\nexport class MoveController<T extends MoveHelperAbstract = MoveHelperAbstract> extends BaseController<T> {\n public get moveByMouseEnable() {\n return this._moveByMouse.enabled\n }\n\n protected name = 'MoveController'\n\n private startInfo?: {\n // 开始位置\n startVectorProject: THREE.Vector3\n //\n line: THREE.Line3\n // 拖拽方向(单位向量)\n dirNormalized?: THREE.Vector3\n // 拖拽类型\n draggingDirection: Direction\n // 平面拖拽时的固定平面\n plane?: THREE.Plane\n }\n\n /** 拖拽时用于显示方向参考的直线(与 ScaleController 一致:Line + LineBasicMaterial) */\n private dragGuideLine?: THREE.Line<THREE.BufferGeometry, THREE.LineBasicMaterial>\n private solidGuide = new SolidGuideLine(this.camera, this.container, this.config?.solidGuide ?? {})\n\n private _moveByMouse: {\n enabled: boolean\n useFaceNormal?: UseFaceNormalInterface\n } = {\n enabled: false,\n }\n\n private mouseInfo?: {\n x: number\n y: number\n mouseDownTimestamp: number\n }\n\n private mousedownEventListenerDisposer: () => any\n\n public constructor(...params: ConstructorParameters<typeof BaseController<T>>) {\n super(...params)\n\n // add hover listener\n const helper = this.helperObject3D\n this.hoverListener([helper.xArrow, helper.yArrow, helper.zArrow])\n\n // 为 centerHandle 添加特殊的 hover 处理,保持其动态颜色效果\n if (helper.centerHandle && helper.centerHandle instanceof CenterHandle) {\n const centerHandle = helper.centerHandle as CenterHandle\n const centerHandleMesh = centerHandle.cube\n const hoverColor = 0xffffff\n\n const handleMouseover = () => {\n if (this.isDragging) return\n // hover 时所有面变白\n if (Array.isArray(centerHandleMesh.material)) {\n centerHandleMesh.material.forEach((mat) => {\n mat.color.set(hoverColor)\n })\n }\n this.render()\n }\n\n const handleMouseout = () => {\n if (this.isDragging) return\n // mouseout 时重新计算动态颜色\n centerHandle.update(this.camera)\n this.render()\n }\n\n this.domEvents.addEventListener(centerHandleMesh, 'mouseover', handleMouseover)\n this.domEvents.addEventListener(centerHandleMesh, 'mouseout', handleMouseout)\n }\n\n const show = this.show.bind(this)\n const hide = this.hide.bind(this)\n\n const updateHelperByCamera = () => {\n this.helperObject3D.update(this.camera)\n // 拖拽中时,更新直线以保持像素恒定\n if (this.isDragging) this.updateDragGuideLineScale()\n this.render()\n }\n\n updateHelperByCamera()\n\n // mouse\n this.domEvents.addEventListener(this.helperObject3D, 'mousedown', this.dragStart)\n document.addEventListener('mousemove', this.dragging)\n document.addEventListener('mouseup', this.dragEnd)\n // touch\n this.domEvents.addEventListener(this.helperObject3D, 'touchstart', this.dragStart)\n document.addEventListener('touchmove', this.dragging)\n document.addEventListener('touchend', this.dragEnd)\n\n this.hooks.on('rotateStart', hide)\n this.hooks.on('rotateEnd', show)\n this.hooks.on('scaleStart', hide)\n this.hooks.on('scaleEnd', show)\n this.hooks.on('moveByMouseEnable', hide)\n this.hooks.on('moveByMouseDisable', show)\n this.hooks.on('updateOtherHelpers', (params) => {\n this.helperObject3D.update(params.camera)\n this.render()\n })\n this.cameraHooks.on('cameraUpdate', updateHelperByCamera)\n\n this.disposers.push(() => {\n this.domEvents.removeEventListener(this.helperObject3D, 'mousedown', this.dragStart)\n document.removeEventListener('mousemove', this.dragging)\n document.removeEventListener('mouseup', this.dragEnd)\n\n this.domEvents.removeEventListener(this.helperObject3D, 'touchstart', this.dragStart)\n document.removeEventListener('touchmove', this.dragging)\n document.removeEventListener('touchend', this.dragEnd)\n\n this.hooks.off('rotateStart', hide)\n this.hooks.off('rotateEnd', show)\n this.hooks.off('scaleStart', hide)\n this.hooks.off('scaleEnd', show)\n this.hooks.off('moveByMouseEnable', hide)\n this.hooks.off('moveByMouseDisable', show)\n this.hooks.off('updateOtherHelpers')\n this.cameraHooks.off('cameraUpdate', updateHelperByCamera)\n })\n\n if (this.moveByMouseEnable) this.moveByMouse()\n }\n\n public dispose(): void {\n super.dispose()\n this.disposers?.forEach((d) => d?.())\n }\n\n /**\n * @description: 跟随鼠标移动\n * @param {boolean} params.useFaceNormal 是否使用面的法线,默认为false\n * @param {boolean} params.useFaceNormal.enable 是否使用面的法线,默认为true\n * @param {Vector3} params.useFaceNormal.alignmentVector 期望对齐的方向,默认为Y轴对齐Face的法向向量,即 `{ x: 0, y: 1, z: 0 }`\n * @param {Function} params.useFaceNormal.fixedFaceNormal 修正后的face normal\n */\n public moveByMouse(params?: { useFaceNormal: UseFaceNormalInterface }) {\n this._moveByMouse = { enabled: true, useFaceNormal: params?.useFaceNormal }\n this.preventTapDefaultEvent = true\n\n const mousedownListener = this.handleMouseDown.bind(this)\n const mouseupListener = this.handleMouseUp.bind(this)\n this.hooks.emit('moveByMouseEnable')\n setTimeout(() => {\n this.container.addEventListener('mousedown', mousedownListener)\n this.container.addEventListener('mouseup', mouseupListener)\n })\n\n this.mousedownEventListenerDisposer = () => {\n this.container.removeEventListener('mousedown', mousedownListener)\n this.container.removeEventListener('mouseup', mouseupListener)\n }\n }\n\n /**\n * @description: 禁用跟随鼠标移动\n */\n public disableMoveByMouse() {\n this._moveByMouse = { enabled: false }\n this.preventTapDefaultEvent = false\n\n this.hooks.emit('moveByMouseDisable')\n this.mousedownEventListenerDisposer?.()\n }\n\n public onIntersectionOnModelUpdate(intersection: THREE.Intersection) {\n if (!this.moveByMouseEnable) return\n const { point, face } = intersection\n const canceled = this.hooks.emit('wantToMove', point)\n if (canceled) return\n this.originObject3D.position.copy(point)\n if (\n this._moveByMouse.useFaceNormal === true ||\n (typeof this._moveByMouse.useFaceNormal === 'object' && this._moveByMouse.useFaceNormal.enable !== false)\n ) {\n if (face?.normal) {\n const alignment = (() => {\n if (typeof this._moveByMouse.useFaceNormal === 'object' && this._moveByMouse.useFaceNormal.alignmentVector) {\n return this._moveByMouse.useFaceNormal.alignmentVector\n }\n return { x: 0, y: 1, z: 0 }\n })()\n const alignmentVector3 = new THREE.Vector3(alignment.x ?? 0, alignment.y ?? 0, alignment.z ?? 0)\n\n const faceNormal = (() => {\n if (typeof this._moveByMouse.useFaceNormal === 'object' && this._moveByMouse.useFaceNormal.fixedFaceNormal) {\n return this._moveByMouse.useFaceNormal.fixedFaceNormal(face.normal)\n }\n return face.normal\n })()\n\n this.originObject3D.quaternion.setFromUnitVectors(alignmentVector3, faceNormal)\n this.internalHooks.emit('setObjectRotate', this.originObject3D.quaternion.clone())\n }\n }\n this.internalHooks.emit('setObjectPosition', point)\n this.hooks.emit('move', point)\n }\n\n private handleMouseDown(event: MouseEvent) {\n const { x, y } = event\n this.mouseInfo = { x, y, mouseDownTimestamp: Date.now() }\n }\n\n private handleMouseUp(event: MouseEvent) {\n if (!this.mouseInfo) return\n const { x, y } = event\n if (this.mouseInfo.x === x && this.mouseInfo.y === y && Date.now() - this.mouseInfo.mouseDownTimestamp < 500) {\n this.disableMoveByMouse()\n this.mouseInfo = undefined\n }\n }\n\n /**\n * @description: 拖动开始,找出拖的Direction\n */\n private dragStart = (params: { intersect: THREE.Intersection }) => {\n if (this.moveByMouseEnable) return\n if (this.isDragging) return\n\n const intersect = params?.intersect\n\n if (!intersect) return this.dragEnd()\n\n const draggingDirection = (intersect?.object as any).direction as Direction\n\n if (!draggingDirection) return this.dragEnd()\n\n const directionX = new THREE.Vector3(1, 0, 0).applyQuaternion(this.helperObject3D.quaternion)\n const directionY = new THREE.Vector3(0, 1, 0).applyQuaternion(this.helperObject3D.quaternion)\n const directionZ = new THREE.Vector3(0, 0, 1).applyQuaternion(this.helperObject3D.quaternion)\n\n const directionVector = (() => {\n switch (draggingDirection) {\n case 'x':\n return directionX\n case 'y':\n return directionY\n case 'z':\n return directionZ\n case 'plane':\n return undefined\n }\n })()\n\n const startIntersect = intersect.point.clone()\n\n if (draggingDirection === 'plane') {\n // 平面拖拽:过点击位置,垂直于相机到该点的视线\n const cameraPosition = this.camera.position.clone()\n const clickPoint = startIntersect.clone()\n\n // 计算从相机到点击点的方向向量作为平面法向量\n const viewDirection = clickPoint.clone().sub(cameraPosition).normalize()\n\n // 创建过点击位置且垂直于视线的平面\n const plane = new THREE.Plane().setFromNormalAndCoplanarPoint(viewDirection, clickPoint)\n\n // 直接使用点击位置作为起始点(已经在平面上)\n const startProject = clickPoint.clone()\n\n this.startInfo = {\n draggingDirection,\n startVectorProject: startProject,\n line: new THREE.Line3(startProject.clone(), startProject.clone()),\n // 保存固定的平面,拖拽过程中不变\n plane: plane,\n } as any\n // 平面拖拽时不显示直线\n } else {\n /** 拖动的轴的线 */\n const line = new THREE.Line3(\n startIntersect.clone().sub(directionVector.normalize()),\n startIntersect.clone().add(directionVector.normalize()),\n )\n this.startInfo = { draggingDirection, startVectorProject: startIntersect, line }\n // 显示拖拽方向的无限长直线参考线(像素恒定、与缩放控制一致)\n try {\n const dirNormalized = directionVector.clone().normalize()\n const center = this.helperObject3D.getWorldPosition(new THREE.Vector3())\n\n // 使用 SolidGuideLine 创建直线(提高 renderOrder,保证在包围盒半透明面之上渲染)\n const line = this.solidGuide.createSolidLine(center, dirNormalized, { color: 0xffffff, renderOrder: RENDER_ORDER.DRAG_GUIDE_LINE })\n this.scene.add(line)\n this.dragGuideLine = line\n } catch {}\n }\n\n // 隐藏其他箭头,拖拽 centerHandle 时也隐藏它\n const directionsToShow = draggingDirection === 'plane' ? [] : [draggingDirection]\n this.helperObject3D.showDraggingHelper(directionsToShow)\n this.hooks.emit('moveStart', draggingDirection)\n this.isDragging = true\n // console.info('%c MoveController dragStart', 'color: #e5af2e')\n }\n\n private dragging = (point: { x: number; y: number } | TouchEvent): false | void => {\n if (!this.isDragging) return\n if (!this.startInfo) return\n\n const x = 'touches' in point ? point.touches[0].clientX : point.x\n const y = 'touches' in point ? point.touches[0].clientY : point.y\n\n const ray = getMouseRaycaster(this.camera, { x, y }, this.container)\n if (!ray) return this.dragEnd()\n\n // console.info(`%c MoveController dragging`, 'color: #49de1b')\n this.move(ray)\n\n return false\n }\n\n /**\n * 更新直线缩放,保持视觉上的恒定大小(与 ScaleController 保持一致)\n */\n private updateDragGuideLineScale() {\n if (!this.dragGuideLine || !this.startInfo) return\n const { line } = this.startInfo\n // 从 line 导出方向\n const dirNormalized = line.end.clone().sub(line.start).normalize()\n if (dirNormalized.lengthSq() < 1e-6) return\n const center = this.helperObject3D.getWorldPosition(new THREE.Vector3())\n this.solidGuide.updateSolidLine(this.dragGuideLine, center, dirNormalized)\n }\n\n private move(raycaster: THREE.Raycaster) {\n if (!this.startInfo) return this.dragEnd()\n\n const { line, startVectorProject } = this.startInfo\n const object = this.originObject3D\n\n // 判断是否为平面拖拽:当 line 两端相同,表示 plane 模式占位\n const isPlane = this.startInfo.draggingDirection === 'plane'\n let currentVectorProject: THREE.Vector3\n\n if (isPlane) {\n // 使用固定的平面(在dragStart时确定,拖拽过程中不变)\n const plane = (this.startInfo as any).plane as THREE.Plane\n if (!plane) return\n\n const projected = new THREE.Vector3()\n // 使用射线和平面的交点,three@0.1xx 没有 intersectRay 则手动求解 t\n const denom = plane.normal.dot(raycaster.ray.direction)\n if (Math.abs(denom) < 1e-6) return\n const t = -(plane.normal.dot(raycaster.ray.origin) + plane.constant) / denom\n if (t < 0) return\n projected.copy(raycaster.ray.origin.clone().add(raycaster.ray.direction.clone().multiplyScalar(t)))\n\n currentVectorProject = projected\n } else {\n currentVectorProject = rayOnLine({ raycaster, line, clampToLine: false })\n }\n\n const beforePosition = object.position.clone()\n const offsetVector = currentVectorProject.clone().sub(startVectorProject)\n\n // 移动transform\n const transform = new THREE.Matrix4()\n transform.setPosition(offsetVector)\n\n const newPosition = object.position.clone().applyMatrix4(transform)\n const canceled = this.hooks.emit('wantToMove', newPosition)\n if (canceled) return\n\n const finalPosition = this.hooks.emitWithResult('moveBefore', newPosition) ?? newPosition\n const finalTransform = new THREE.Matrix4()\n finalTransform.setPosition(finalPosition.clone().sub(beforePosition))\n\n object.position.copy(finalPosition)\n\n startVectorProject.copy(currentVectorProject)\n this.internalHooks.emit('applyObjectPosition', { matrix: finalTransform })\n this.hooks.emit('move', finalPosition)\n }\n\n private dragEnd = () => {\n if (!this.isDragging) return\n // console.info('%c MoveController dragEnd', 'color: #e94e4e')\n // 拖动结束,重置currentDraggingDirection\n this.startInfo = undefined\n this.isDragging = false\n // 移除直线\n if (this.dragGuideLine) {\n this.scene.remove(this.dragGuideLine)\n this.dragGuideLine.geometry.dispose()\n const material = this.dragGuideLine.material\n if (Array.isArray(material)) material.forEach((m) => m.dispose())\n else material.dispose()\n this.dragGuideLine = undefined\n }\n // 显示所有箭头\n this.helperObject3D.show()\n this.hooks.emit('moveEnd')\n return\n }\n}\n","import type * as THREE from 'three/webgpu'\n/**\n * @description: 将手势操作绑定到controller上\n */\nimport type { Five, EventCallback } from '@realsee/five-webgpu'\nimport type { BaseController } from '../shared-utils/Object3DHelper/Base/BaseController'\nimport type { Subscribe } from '../shared-utils/Subscribe'\nimport type DomEvents from '../shared-utils/threex/domevents'\n\nclass ControllerWrapper<HelperControllerInterface extends new (...params: ConstructorParameters<typeof BaseController<any>>) => any> {\n public helperController?: InstanceType<HelperControllerInterface>\n private five: Five\n\n\n public constructor(\n five: Five,\n donEvents: DomEvents,\n HelperController: HelperControllerInterface,\n object: THREE.Object3D,\n helperObject3D: InstanceType<HelperControllerInterface>['helperObject3D'],\n HelperControllerConfig?: ConstructorParameters<HelperControllerInterface>[1],\n hooks?: Subscribe<any>,\n internalHooks?: Subscribe<any>,\n otherControllers?: {\n moveController?: BaseController\n rotateController?: BaseController\n scaleController?: BaseController\n },\n ) {\n const { camera, model, scene } = five\n const container = five.getElement()\n this.five = five\n if (!camera || !model || !container || !scene) return\n const onRender = () => {\n five.needsRender = true\n }\n // TODO: 是否要改为绑定\n this.helperController = new HelperController(\n {\n camera,\n model,\n domEvents: donEvents,\n originObject3D: object,\n helperObject3D,\n container,\n scene,\n onRender,\n sharedHooks: hooks as any,\n sharedInternalHooks: internalHooks as any,\n otherControllers,\n },\n HelperControllerConfig,\n )\n five.on('wantsTapGesture', this.onFiveWantsTapGesture)\n five.on('wantsGesture', this.onFiveWantsGesture)\n five.on('intersectionOnModelUpdate', this.onFiveIntersectionOnModelUpdate)\n }\n\n public dispose() {\n this.five.off('wantsTapGesture', this.onFiveWantsTapGesture)\n this.five.off('wantsGesture', this.onFiveWantsGesture)\n this.five.off('intersectionOnModelUpdate', this.onFiveIntersectionOnModelUpdate)\n this.helperController?.dispose()\n }\n\n private onFiveWantsTapGesture: EventCallback['wantsTapGesture'] = (params) => {\n if (!this.helperController) return\n if (this.helperController.preventTapDefaultEvent) return false\n const result = this.helperController.onWantsTapGesture(params)\n this.five.needsRender = true\n return result\n }\n\n private onFiveWantsGesture: EventCallback['wantsGesture'] = (...params) => {\n if (!this.helperController) return\n const result = this.helperController.onWantsGesture(...params)\n this.five.needsRender = true\n return result\n }\n\n private onFiveIntersectionOnModelUpdate: EventCallback['intersectionOnModelUpdate'] = (...params) => {\n if (!this.helperController) return\n this.helperController.onIntersectionOnModelUpdate(...params)\n }\n}\n\nexport { ControllerWrapper }\nexport { ControllerWrapper as FiveControllerWrapper }\n","import type { Object3DHelperEventMap, Object3DHelperState } from './typings'\nimport type { ObjectHelperControllers } from './typings'\nimport type { BaseController } from './Base/BaseController'\nimport { Subscribe } from '../Subscribe'\n\nconst VERSION = 'v1.0.1'\n\nconst NAME = 'Object3DHelper'\n\nconst NAMEVERSION = `${NAME}@${VERSION}`\n\nconst disposedErrorLog = () => {\n console.error(`${NAMEVERSION} is disposed`)\n}\n\nconst disableWarnLog = () => {\n console.warn(`${NAMEVERSION} is disabled`)\n}\n\nconst disableErrorLog = () => {\n console.error(`${NAMEVERSION} is disabled`)\n}\n\ntype EventListener = {\n [K in keyof ObjectHelperControllers]?: () => void\n}\n\nexport class Object3DHelper {\n public controllers: ObjectHelperControllers = {}\n public state: Object3DHelperState = {\n visible: true,\n enabled: true,\n disposed: false,\n }\n public hooks: Subscribe<Object3DHelperEventMap> = new Subscribe<Object3DHelperEventMap>()\n private eventListener: EventListener = {}\n\n public constructor(controllers?: ObjectHelperControllers) {\n if (controllers) this.addControllers(controllers)\n this.setState(this.state)\n }\n\n /**\n * @description Show guide line\n */\n public async show(options?: { userAction?: boolean }) {\n this.setState({ visible: true }, options)\n }\n\n /**\n * @description Hide guide line\n */\n public async hide(options?: { userAction?: boolean }) {\n this.setState({ visible: false }, options)\n }\n\n /**\n * @description Enable\n */\n public enable(options?: { userAction?: boolean }) {\n this.setState({ enabled: true }, options)\n }\n\n /**\n * @description Disable\n */\n public disable(options?: { userAction?: boolean }) {\n this.setState({ enabled: false }, options)\n }\n\n /**\n * @description Dispose\n */\n public dispose() {\n this.setState({ disposed: true })\n }\n\n public setState(state: Partial<Object3DHelperState>, options?: { userAction?: boolean } & Record<string, any>): void {\n if (this.state.disposed) return disposedErrorLog()\n if (!this.state.enabled) {\n // when plugin is disabled, only can change enabled or disposed to true\n if (state.enabled !== true && state.disposed !== true) return disableErrorLog()\n }\n const prevState = { ...this.state }\n this.state = { ...this.state, ...state }\n if (state.disposed !== undefined && state.disposed !== prevState.disposed) {\n if (state.disposed) this.handleDispose()\n }\n if (state.visible !== undefined) {\n this.handleVisible(state.visible)\n }\n if (state.enabled !== undefined) {\n this.handleEnable(state.enabled)\n }\n\n this.hooks.emit('stateChange', { state: this.state, prevState })\n }\n\n public addControllers(controllers: ObjectHelperControllers): void {\n this.controllers = { ...this.controllers, ...controllers }\n // this.addEventListener()\n this.setState(this.state)\n }\n\n /**\n * @description 初始化 helpers 的位置\n */\n public initialHelperMatrix() {\n this.everyControllerDo((controller) => {\n controller.initialHelperPosition()\n controller.initialHelperQuaternion()\n })\n }\n\n public getCurrentState() {\n return this.state\n }\n\n private handleEnable(enabled: boolean, userAction = true) {\n if (enabled) {\n this.everyControllerDo((controller) => {\n controller.enable()\n // controller.setOpacity(OBJECT_OPACITY)\n })\n this.hooks.emit('enable', { userAction })\n } else {\n this.everyControllerDo((controller) => {\n controller.disable()\n })\n this.hooks.emit('disable', { userAction })\n }\n this.state.enabled = enabled\n }\n\n private handleVisible(visible: boolean, userAction = true) {\n if (visible) {\n this.everyControllerDo((controller) => {\n controller.show()\n // controller.setOpacity(OBJECT_OPACITY)\n })\n this.actionIfStateIsEnabled(() => this.hooks.emit('show', { userAction }))\n } else {\n this.everyControllerDo((controller) => {\n controller.hide()\n })\n this.actionIfStateIsEnabled(() => this.hooks.emit('hide', { userAction }))\n }\n this.state.visible = visible\n }\n\n private everyControllerDo(func: (controller: BaseController) => any) {\n Object.values(this.controllers).forEach((controller: BaseController | undefined) => {\n if (controller) func(controller)\n })\n }\n\n private handleDispose() {\n Object.values(this.controllers).forEach((controller: BaseController | undefined) => {\n controller?.dispose()\n })\n\n for (const k in this.controllers) {\n if (!k) continue\n const key: keyof ObjectHelperControllers = k as keyof ObjectHelperControllers\n this.eventListener[key]?.()\n }\n }\n\n private actionIfStateIsEnabled<T = any>(func: () => T, options?: { warnLog?: true }) {\n if (this.state.enabled) return func()\n else {\n if (options?.warnLog) disableWarnLog()\n }\n }\n}\n","export function deg2Rad(deg: number) {\n return (deg * Math.PI) / 180\n}\n","import { BaseController } from '../Base/BaseController'\nimport type { RotateHelperAbstract } from '../Helper'\nimport * as THREE from 'three/webgpu'\nimport type { Direction } from '../typings'\nimport { getMouseRaycaster } from '../utils'\nimport setObjectQuaternion from '../utils/setObjectQuaternion'\nimport { rad2Deg } from '../../math/rad2Deg'\nimport { deg2Rad } from '../../math/deg2Rad'\n\n/**\n * @description 记录单次旋转中,旋转前后的差值\n */\nlet helperQuaternionOffset = new THREE.Quaternion()\n\nexport class RotateController<T extends RotateHelperAbstract = RotateHelperAbstract> extends BaseController<T> {\n protected name = 'RotateController'\n\n private get rotateCenter() {\n return this.helperObject3D.position.clone()\n }\n\n private startInfo?: {\n // 当前拖动的圆\n direction: Direction\n // 开始位置,旋转过程中会实时修改\n startVector: THREE.Vector3\n // plane\n plane: THREE.Plane\n helperQuaternion: THREE.Quaternion\n angle: number\n directionVector: THREE.Vector3\n rotatedVectors?: THREE.Vector3[]\n lineMeshes?: THREE.Mesh[]\n angleHelper: THREE.Object3D & {\n baseAxes: THREE.Vector3\n angleDirection: number\n offsetAngle: (angle: number) => number\n }\n startQuaternion?: THREE.Quaternion\n }\n\n private removeListener: () => any\n\n public constructor(...params: ConstructorParameters<typeof BaseController<T>>) {\n super(...params)\n\n // add hover listener\n const helper = this.helperObject3D\n this.hoverListener([helper.xCircle?.circle, helper.yCircle?.circle, helper.zCircle?.circle].filter(Boolean))\n\n const dragStart = this.dragStart.bind(this)\n const dragging = this.dragging.bind(this)\n const dragEnd = this.dragEnd.bind(this)\n const show = this.show.bind(this)\n const hide = this.hide.bind(this)\n\n const updateHelperByCamera = () => {\n this.helperObject3D.update(this.camera)\n this.render()\n }\n\n updateHelperByCamera()\n\n this.domEvents.addEventListener(this.helperObject3D, 'mousedown', dragStart)\n document.addEventListener('mousemove', dragging)\n document.addEventListener('mouseup', dragEnd)\n\n this.domEvents.addEventListener(this.helperObject3D, 'touchstart', dragStart)\n document.addEventListener('touchmove', dragging)\n document.addEventListener('touchend', dragEnd)\n\n this.hooks.on('moveStart', hide)\n this.hooks.on('moveEnd', show)\n this.hooks.on('scaleStart', hide)\n this.hooks.on('scaleEnd', show)\n this.hooks.on('moveByMouseEnable', hide)\n this.hooks.on('moveByMouseDisable', show)\n this.hooks.on('updateOtherHelpers', (params) => {\n // 排除自己,避免无限循环\n this.helperObject3D.update(params.camera)\n this.render()\n })\n this.cameraHooks.on('cameraUpdate', updateHelperByCamera)\n\n this.disposers.push(() => {\n this.domEvents.removeEventListener(this.helperObject3D, 'mousedown', dragStart)\n document.removeEventListener('mousemove', dragging)\n document.removeEventListener('mouseup', dragEnd)\n\n this.domEvents.removeEventListener(this.helperObject3D, 'touchstart', dragStart)\n document.removeEventListener('touchmove', dragging)\n document.removeEventListener('touchend', dragEnd)\n\n this.hooks.off('moveStart', hide)\n this.hooks.off('moveEnd', show)\n this.hooks.off('scaleStart', hide)\n this.hooks.off('scaleEnd', show)\n this.hooks.off('moveByMouseEnable', hide)\n this.hooks.off('moveByMouseDisable', show)\n this.hooks.off('updateOtherHelpers')\n this.cameraHooks.off('cameraUpdate', updateHelperByCamera)\n })\n }\n\n public setRotateAngle(angle: { x?: number; y?: number; z?: number }) {\n const { x = 0, y = 0, z = 0 } = angle\n const euler = new THREE.Euler(deg2Rad(x), deg2Rad(y), deg2Rad(z))\n const quaternion = new THREE.Quaternion().setFromEuler(euler)\n\n const canceled = this.hooks.emit('wantToRotate', quaternion)\n if (canceled) return\n\n const { originObject3D, rotateCenter } = this\n setObjectQuaternion(originObject3D, quaternion, rotateCenter)\n this.internalHooks.emit('setObjectRotate', quaternion, rotateCenter)\n this.hooks.emit('rotate', quaternion)\n\n this.render()\n }\n\n /**\n * @description 通过改变欧拉角中的某一个值来改变旋转,但保持其他两个轴的旋转不变\n * @param axis 要修改的轴 ('x' | 'y' | 'z')\n * @param angle 新的角度值(度)\n * @returns 新的四元数值\n */\n public getEulerAngle(axis: 'x' | 'y' | 'z', angle: number): THREE.Quaternion {\n const { originObject3D } = this\n\n // 从当前对象的四元数中提取欧拉角\n const currentEuler = new THREE.Euler().setFromQuaternion(originObject3D.quaternion)\n\n // 将弧度转换为度\n const currentAngles = {\n x: rad2Deg(currentEuler.x),\n y: rad2Deg(currentEuler.y),\n z: rad2Deg(currentEuler.z),\n }\n\n // 修改指定轴的角度,保持其他轴不变\n const newAngles = {\n x: axis === 'x' ? angle : currentAngles.x,\n y: axis === 'y' ? angle : currentAngles.y,\n z: axis === 'z' ? angle : currentAngles.z,\n }\n\n // 创建新的欧拉角\n const newEuler = new THREE.Euler(deg2Rad(newAngles.x), deg2Rad(newAngles.y), deg2Rad(newAngles.z))\n\n // 从欧拉角创建新的四元数\n const newQuaternion = new THREE.Quaternion().setFromEuler(newEuler)\n\n return newQuaternion\n }\n\n protected onApplyOriginObjectRotate(params: { quaternion: THREE.Quaternion; origin: THREE.Vector3 }) {\n if (this.isDragging) return\n super.onApplyOriginObjectRotate(params)\n }\n\n protected onApplyOriginObjectScale(params: { matrix: THREE.Matrix4; origin?: THREE.Vector3 }): void {}\n\n /**\n * @description: 拖动开始,找出拖的Direction\n */\n private dragStart(params: { intersect: THREE.Intersection }): void {\n if (this.isDragging) return\n\n // 更新helper状态\n this.helperObject3D.update(this.camera)\n\n const intersect = params?.intersect\n\n if (!intersect) return this.dragEnd()\n\n const direction = (intersect?.object as any).direction as Direction\n\n if (!direction) return this.dragEnd()\n // 检查end\n\n const startIntersect = intersect.point\n\n const angleHelper = this.getAngleHelper(direction)\n\n // init tips\n this.setTipsAngle(0)\n const tipsPosition = startIntersect.clone()\n tipsPosition.y += 0.2\n this.setTipsPosition(tipsPosition)\n // end\n\n const helperQuaternion = this.helperObject3D.quaternion.clone()\n\n // init plane: 鼠标应该投影的平面\n const directionVector = (() => {\n if (direction === 'x') return new THREE.Vector3(1, 0, 0).applyQuaternion(helperQuaternion)\n if (direction === 'y') return new THREE.Vector3(0, 1, 0).applyQuaternion(helperQuaternion)\n if (direction === 'z') return new THREE.Vector3(0, 0, 1).applyQuaternion(helperQuaternion)\n })()\n const plane = new THREE.Plane().setFromNormalAndCoplanarPoint(directionVector, startIntersect)\n\n // init startVector: 旋转中心指向鼠标位置的向量\n const projectPoint = plane.projectPoint(startIntersect.clone(), new THREE.Vector3())\n const startVector = projectPoint.clone().sub(this.rotateCenter)\n // end\n\n // 计算开始角度\n const startAngle = startVector.angleTo(angleHelper.baseAxes.clone().applyQuaternion(helperQuaternion))\n\n const processedAngle = angleHelper.offsetAngle(startAngle)\n\n this.setAngleHelperStart(direction, processedAngle)\n this.setAngleHelperLength(direction, 0)\n\n // end\n\n this.startInfo = {\n direction,\n startVector,\n directionVector,\n plane,\n angleHelper,\n angle: 0,\n helperQuaternion: helperQuaternion.clone(),\n }\n\n helperQuaternionOffset = new THREE.Quaternion()\n\n this.helperObject3D.showDraggingHelper([direction])\n this.hooks.emit('rotateStart', direction)\n this.isDragging = true\n // console.info(`%c RotateController dragStart ${direction}`, 'color: #e5af2e')\n }\n\n private getMatrix() {\n // @ts-ignore\n const matrix = this.originObject3D?.ext?.matrix\n return matrix\n }\n\n private getMatrixAngle(matrix: any, direction: Direction) {\n let matrixQuaternion: THREE.Quaternion | undefined\n if (matrix && matrix.isMatrix4) {\n matrixQuaternion = new THREE.Quaternion()\n matrix.decompose(new THREE.Vector3(), matrixQuaternion, new THREE.Vector3())\n const euler = new THREE.Euler().setFromQuaternion(matrixQuaternion)\n if (direction === 'x') return Math.round(rad2Deg(euler.z))\n if (direction === 'y') return Math.round(rad2Deg(euler.y))\n if (direction === 'z') return Math.round(rad2Deg(euler.x))\n }\n }\n\n private parseAngleByDirection(direction: Direction): number | undefined {\n // @ts-ignore\n const matrix = this.originObject3D?.ext?.matrix\n let matrixQuaternion: THREE.Quaternion | undefined\n if (matrix && matrix.isMatrix4) {\n matrixQuaternion = new THREE.Quaternion()\n matrix.decompose(new THREE.Vector3(), matrixQuaternion, new THREE.Vector3())\n const euler = new THREE.Euler().setFromQuaternion(matrixQuaternion)\n if (direction === 'x') return Math.round(rad2Deg(euler.z))\n if (direction === 'y') return Math.round(rad2Deg(euler.y))\n if (direction === 'z') return Math.round(rad2Deg(euler.x))\n }\n }\n\n private dragging(point: { x: number; y: number } | TouchEvent): false | void {\n if (!this.isDragging) return\n\n const x = 'touches' in point ? point.touches[0].clientX : point.x\n const y = 'touches' in point ? point.touches[0].clientY : point.y\n\n const ray = getMouseRaycaster(this.camera, { x, y }, this.container)\n if (!ray) return this.dragEnd()\n\n // console.info(`%c RotateController dragging ${this.startInfo?.direction}`, 'color: #49de1b')\n this.rotate(ray)\n\n return false\n }\n\n private rotate(raycaster: THREE.Raycaster) {\n if (!this.startInfo) return this.dragEnd()\n const { startVector, plane, angleHelper, direction, helperQuaternion } = this.startInfo\n const { originObject3D } = this\n const currentIntersectPoint = raycaster.ray.intersectPlane(plane, new THREE.Vector3())\n if (!currentIntersectPoint) return\n\n const rotateCenter = this.rotateCenter.clone()\n const projectPoint = plane.projectPoint(currentIntersectPoint.clone(), new THREE.Vector3())\n // 旋转中心指向鼠标位置的向量\n let currentVector = projectPoint.clone().sub(rotateCenter)\n\n // 确保向量在平面上,垂直于旋转轴\n const rotationAxis = this.startInfo.directionVector.clone().normalize()\n const projection = currentVector.clone().projectOnPlane(rotationAxis)\n currentVector = projection.normalize().multiplyScalar(currentVector.length())\n\n const quaternion = new THREE.Quaternion().setFromUnitVectors(startVector.clone().normalize(), currentVector.clone().normalize())\n const newQuaternion = originObject3D.quaternion.clone().premultiply(quaternion)\n\n // 计算当前角度\n if (startVector.angleTo(currentVector) === 0) return\n\n const canceled = this.hooks.emit('wantToRotate', newQuaternion)\n if (canceled) return\n\n /**\n * - 计算角度。\n * 先使用 applyQuaternion(objectQuaternion.clone().invert()) 的方式将 currentVector 和 startVector 还原到初始的平面(xoy/xoz/yoz)上,\n * 然后指定 order 的第一个旋转方向(即 direction)为初始平面的法向量,这样获取到的 euler[direction] 即为本次旋转的角度。\n * 还原到初始平面是为了确保 euler 的其他旋转分量为 0,这样才能保证 euler[direction] 为本次旋转的角度。\n */\n const euler = new THREE.Euler().setFromQuaternion(\n new THREE.Quaternion().setFromUnitVectors(\n startVector.clone().normalize().applyQuaternion(helperQuaternion.clone().invert()),\n currentVector.clone().normalize().applyQuaternion(helperQuaternion.clone().invert()),\n ),\n `${direction.toUpperCase()}${'XZY'.replace(direction.toUpperCase(), '')}` as THREE.EulerOrder,\n )\n const angle = euler[direction] * angleHelper.angleDirection\n this.startInfo.angle += angle\n this.setAngleHelperLength(direction, this.startInfo.angle)\n this.setTipsAngle(rad2Deg(this.startInfo.angle))\n\n if (rotateCenter) {\n const v = new THREE.Vector3().subVectors(originObject3D.position, rotateCenter).applyQuaternion(quaternion).add(rotateCenter)\n originObject3D.position.copy(v)\n }\n\n originObject3D.applyQuaternion(quaternion)\n helperQuaternionOffset.premultiply(quaternion)\n\n this.internalHooks.emit('applyObjectRotate', { quaternion, origin: rotateCenter })\n this.hooks.emit('rotate', originObject3D.quaternion)\n\n this.startInfo.startVector = currentVector\n }\n\n private dragEnd(): void {\n if (!this.isDragging) return\n // 结束的时候再旋转helper,拖动过程中,helper不旋转\n this.applyHelperQuaternion(helperQuaternionOffset, this.rotateCenter)\n\n // 删除创建的线段\n if (this.startInfo?.lineMeshes) {\n this.startInfo.lineMeshes.forEach((mesh) => {\n this.scene.remove(mesh)\n mesh.geometry.dispose()\n if (mesh.material instanceof THREE.Material) {\n mesh.material.dispose()\n }\n })\n }\n\n // console.info('%c RotateController dragEnd', 'color: #e94e4e')\n // 拖动结束,重置\n this.startInfo = undefined\n this.isDragging = false\n // 显示所有\n this.helperObject3D.show()\n\n // 更新其他helper\n this.updateOtherHelpers()\n\n this.hooks.emit('rotateEnd')\n return\n }\n\n private updateOtherHelpers(): void {\n // 通过sharedHooks获取其他controller\n // 由于所有controller共享同一个hooks实例,我们可以通过hooks来触发更新事件\n this.hooks.emit('updateOtherHelpers', { camera: this.camera })\n }\n\n private getAngleHelper(direction: Direction):\n | (THREE.Object3D & {\n baseAxes: THREE.Vector3\n angleDirection: number\n offsetAngle: (angle: number) => number\n })\n | undefined {\n switch (direction) {\n case 'x':\n return this.helperObject3D.xCircle?.angleSector as any\n case 'y':\n return this.helperObject3D.yCircle?.angleSector as any\n case 'z':\n return this.helperObject3D.zCircle?.angleSector as any\n }\n }\n\n private setAngleHelperStart(direction: Direction, start: number) {\n const angleHelper = this.getAngleHelper(direction)\n if (!angleHelper) {\n console.warn('angleHelper is undefined')\n return\n }\n if (angleHelper instanceof THREE.Mesh && angleHelper.geometry instanceof THREE.CircleGeometry) {\n const { radius, segments, thetaLength } = angleHelper.geometry.parameters\n angleHelper.geometry = new THREE.CircleGeometry(radius, segments, start, thetaLength)\n } else {\n console.warn('only support THREE.CircleGeometry')\n }\n }\n\n private setAngleHelperLength(direction: Direction, length: number) {\n const minLength = 0.001\n const thetaLength = length >= 0 ? Math.max(length, minLength) : Math.min(length, -minLength)\n const angleHelper = this.getAngleHelper(direction)\n if (angleHelper instanceof THREE.Mesh && angleHelper.geometry instanceof THREE.CircleGeometry) {\n const { radius, thetaStart } = angleHelper.geometry.parameters\n const segments = Math.ceil(Math.abs(thetaLength) * (40 / (2 * Math.PI)))\n angleHelper.geometry = new THREE.CircleGeometry(radius, segments, thetaStart, thetaLength)\n } else {\n console.warn('only support THREE.CircleGeometry')\n }\n }\n\n private setTipsAngle(angle: number) {\n const element = this.helperObject3D.angleTips?.element\n if (!element) return\n element.innerText = `${angle.toFixed(0)}°`\n }\n\n private setTipsPosition(position: THREE.Vector3) {\n const angleTips = this.helperObject3D.angleTips\n if (!angleTips) return\n const project = position.project(this.camera)\n const { x, y, z } = project\n if (z > 1) return\n const left = ((x + 1) / 2) * 100 + '%'\n const top = ((-y + 1) / 2) * 100 + '%'\n angleTips.setLeftTop(left, top)\n }\n}\n","import { BaseController } from '../Base/BaseController'\nimport type { RectangleScaleHelperAbstract } from '../Helper'\nimport * as THREE from 'three/webgpu'\nimport { getMouseRaycaster, vectorIsEqual } from '../utils'\nimport type { Direction4 } from '../typings'\nimport { Vector3 } from 'three/webgpu'\nimport type { CSS3DObjectPlus } from '../../../CSS3DRenderPlugin/utils/three/CSS3DObject'\n\ninterface StartInfo {\n startPoint: {\n position: Vector3\n direction: Direction4\n }\n dragPointInCenterBottom?: boolean | null\n dragPointInCenterLeft?: boolean | null\n plane: THREE.Plane\n}\n\nexport class RectangleScaleController<\n OriginObject3D extends THREE.Object3D,\n PointType extends THREE.Object3D | HTMLElement,\n> extends BaseController<RectangleScaleHelperAbstract<OriginObject3D, PointType>> {\n protected startInfo?: StartInfo\n\n protected name = 'RectangleScaleController'\n\n public constructor(...params: ConstructorParameters<typeof BaseController<RectangleScaleHelperAbstract<OriginObject3D, PointType>>>) {\n super(...params)\n }\n\n public enable() {\n this.helperObject3D.enable()\n super.enable()\n }\n\n public disable() {\n this.helperObject3D.disable()\n super.disable()\n }\n\n public show() {\n this.helperObject3D.show()\n super.show()\n }\n\n public hide() {\n this.helperObject3D.hide()\n super.hide()\n }\n\n protected onApplyOriginObjectPosition(params: { matrix: THREE.Matrix4 }) {\n if (this.isDragging) return\n super.onApplyOriginObjectPosition(params)\n }\n\n protected onApplyOriginObjectScale(params: { matrix: THREE.Matrix4; origin?: THREE.Vector3 }): void {\n this.helperObject3D.applyHelperScaleMatrix4(params.matrix, params.origin)\n }\n\n protected getDragPlane() {\n const plane = new THREE.Plane()\n // get normal from points\n const positions: Vector3[] = this.helperObject3D.cornerPositions\n if (positions.length === 0) return\n if (positions.length < 3) plane.setFromNormalAndCoplanarPoint(this.originObject3D.getWorldDirection(new Vector3()), positions[0]!)\n else plane.setFromCoplanarPoints(positions[0]!, positions[1]!, positions[2]!)\n\n return plane\n }\n\n protected dragStart(\n mousePoint: { x: number; y: number },\n point: {\n position: THREE.Vector3\n direction: Direction4\n },\n ) {\n this.helperObject3D.updatePoints?.()\n const plane = this.getDragPlane()\n\n if (!plane) return this.dragEnd()\n\n this.startInfo = { startPoint: { position: point.position.clone(), direction: point.direction }, plane }\n\n // this.scene.add(getPoint(point.position.clone(), 3))\n\n this.hooks.emit('scaleStart', point.direction)\n this.render()\n this.isDragging = true\n // console.info('%c RectangleScaleController dragStart', 'color: #e5af2e')\n }\n\n protected dragging(point: { x: number; y: number }): false | void {\n if (!this.isDragging) return\n\n const raycaster = getMouseRaycaster(this.camera, point, this.container)\n if (!raycaster) return this.dragEnd()\n\n this.scale(raycaster)\n // console.info('%c RectangleScaleController dragging', 'color: #49de1b')\n }\n\n protected scale(raycaster: THREE.Raycaster) {\n if (!this.startInfo) return\n const object = this.originObject3D\n const { startPoint, plane } = this.startInfo\n const cornerPositions = this.helperObject3D.cornerPositions as [Vector3, Vector3, Vector3, Vector3]\n if (cornerPositions.length < 4) return this.dragEnd()\n\n const planeIntersection = raycaster.ray.intersectPlane(plane, new Vector3())\n if (!planeIntersection) return\n if (vectorIsEqual(planeIntersection, this.camera.position)) return\n\n const planeCenter = new Vector3().addVectors(cornerPositions[0], cornerPositions[2]).divideScalar(2)\n\n const { position: startPosition, direction } = startPoint\n\n const ewVector = new Vector3().subVectors(cornerPositions[1], cornerPositions[0]) // west -> east vector\n const nsVector = new Vector3().subVectors(cornerPositions[3], cornerPositions[0]) // south -> north vector\n\n\n const getOffset = (direction: 'ew' | 'ns') => {\n const defaultVector = new Vector3(0, 0, 0)\n if (!this.startInfo) return defaultVector\n const baseVector = (direction === 'ew' ? ewVector : nsVector).clone()\n\n const startPositionProject = startPosition.clone().projectOnVector(baseVector)\n const nowPositionProject = planeIntersection.clone().projectOnVector(baseVector)\n const planeCenterProject = planeCenter.clone().projectOnVector(baseVector)\n\n // this.scene.add(getPoint(startPosition, 0))\n // this.scene.add(getPoint(planeIntersection, 0))\n\n if (nowPositionProject.equals(startPositionProject)) return defaultVector\n\n if (direction === 'ns' && typeof this.startInfo.dragPointInCenterBottom !== 'boolean') {\n const offset = new Vector3().subVectors(nowPositionProject, planeCenterProject)\n const xIsNegative = offset.x < 0 && baseVector.x >= 0\n const yIsNegative = offset.y < 0 && baseVector.y >= 0\n const zIsNegative = offset.z < 0 && baseVector.z >= 0\n this.startInfo.dragPointInCenterBottom = xIsNegative || yIsNegative || zIsNegative\n }\n if (direction === 'ew' && typeof this.startInfo.dragPointInCenterLeft !== 'boolean') {\n const offset = new Vector3().subVectors(nowPositionProject, planeCenterProject)\n const xIsNegative = offset.x < 0 && baseVector.x >= 0\n const yIsNegative = offset.y < 0 && baseVector.y >= 0\n const zIsNegative = offset.z < 0 && baseVector.z >= 0\n this.startInfo.dragPointInCenterLeft = xIsNegative || yIsNegative || zIsNegative\n }\n\n const offset = new Vector3().subVectors(nowPositionProject, startPositionProject)\n\n // TODO: 不知道为啥b端在缩放结束有问题,先临时加个限制\n const offsetLength = offset.length()\n if (offsetLength > 0.3) {\n console.warn('offset.length() > 0.3, skipped', offsetLength)\n return defaultVector\n }\n\n return offset\n }\n\n const ewOffset = getOffset('ew')\n const nsOffset = getOffset('ns')\n\n const setEWScale = () => {\n const offset = ewOffset\n this.helperObject3D.cornerPositions.forEach((position, index) => {\n if (this.startInfo?.dragPointInCenterLeft) {\n if (index === 0 || index === 3) position.add(offset) // 拖左边,只改左边点\n } else {\n if (index === 1 || index === 2) position.add(offset) // 拖右边,只改右边点\n }\n })\n }\n\n const setNSScale = () => {\n const offset = nsOffset\n this.helperObject3D.cornerPositions.forEach((position, index) => {\n if (this.startInfo?.dragPointInCenterBottom) {\n if (index === 0 || index === 1) position.add(offset) // 拖下边,只改下边点\n } else {\n if (index === 2 || index === 3) position.add(offset) // 拖上边,只改上边点\n }\n })\n }\n\n switch (direction) {\n case 'ew':\n setEWScale()\n break\n case 'ns':\n setNSScale()\n break\n case 'nesw':\n case 'nwse':\n setEWScale()\n setNSScale()\n }\n\n // this.helperObject3D.cornerPositions.forEach((position, index) => {\n // this.scene.add(getPoint(position, index))\n // })\n\n const scaleX = new Vector3().subVectors(cornerPositions[1], cornerPositions[0]).length() / ewVector.length()\n const scaleY = new Vector3().subVectors(cornerPositions[3], cornerPositions[0]).length() / nsVector.length()\n const scaleXY = new Vector3(scaleX, scaleY, 1)\n\n const scaleMatrix = new THREE.Matrix4().scale(scaleXY)\n\n // const newScale = object.scale.clone().applyMatrix4(scaleMatrix)\n // object.scale.copy(newScale) // 或者 object.scale.applyMatrix4(scaleMatrix)\n if ((object as any).isCSS3DObjectPlus && (object as any).applyScaleMatrix4) {\n ;(object as InstanceType<typeof CSS3DObjectPlus>).applyScaleMatrix4(scaleMatrix)\n } else {\n object.scale.applyMatrix4(scaleMatrix)\n }\n\n startPoint.position.copy(planeIntersection)\n\n // =================================================================================================================================================================\n // =================================================================================================================================================================\n // 移动位置\n const centerPosition = new Vector3().addVectors(cornerPositions[0], cornerPositions[2]).divideScalar(2)\n const offset = new Vector3().subVectors(centerPosition, planeCenter)\n const transformMatrix4 = new THREE.Matrix4().setPosition(offset)\n\n object.applyMatrix4(transformMatrix4)\n this.helperObject3D.css3DInstance?.css3DObject.applyMatrix4(transformMatrix4)\n this.helperObject3D.plane?.applyMatrix4(transformMatrix4)\n\n this.internalHooks.emit('applyObjectScale', { matrix: scaleMatrix })\n this.internalHooks.emit('applyObjectPosition', { matrix: transformMatrix4 })\n // 移动位置end\n\n // this.helperObject3D.cornerPositions.forEach((position, index) => {\n // this.scene.add(getPoint(position, index))\n // })\n\n this.render()\n }\n\n protected dragEnd(): void {\n if (!this.isDragging) return\n this.startInfo = undefined\n this.isDragging = false\n\n // 如果是CSS3DScaleHelper,调用其onScaleEnd方法\n if ('onScaleEnd' in this.helperObject3D && typeof this.helperObject3D.onScaleEnd === 'function') {\n this.helperObject3D.onScaleEnd()\n }\n\n this.hooks.emit('scaleEnd')\n this.render()\n // console.info('%c RectangleScaleController dragEnd', 'color: #e94e4e')\n }\n}\n","import type { CSS3DObject } from '../../three/CSS3DRenderer'\nimport { RectangleScaleController } from './RectangleScaleController'\n\nexport class CSS3DScaleController extends RectangleScaleController<CSS3DObject, HTMLElement> {\n protected name = 'CSS3DScaleController'\n\n public constructor(...params: ConstructorParameters<typeof RectangleScaleController<CSS3DObject, HTMLElement>>) {\n super(...params)\n this.addHTMLEventListener()\n }\n\n private addHTMLEventListener() {\n this.helperObject3D.points.forEach((startPoint) => {\n if (!startPoint) return\n const element = startPoint.point\n const dragStart = (event: DragEvent) => this.dragStart(event, startPoint)\n const dragging = this.dragging.bind(this)\n const dragEnd = this.dragEnd.bind(this)\n element.addEventListener('dragstart', dragStart)\n element.addEventListener('drag', dragging)\n element.addEventListener('dragend', dragEnd)\n })\n }\n}\n","import type * as THREE from 'three/webgpu'\nimport { BaseController } from '../Base/BaseController'\nimport type { BoundingBoxHelperAbstract } from '../Helper'\n\nexport class BoundingBoxController<OriginObject3D extends THREE.Object3D = THREE.Object3D> extends BaseController<\n BoundingBoxHelperAbstract<OriginObject3D>\n> {\n protected name = 'BoundingBoxController'\n public constructor(...params: ConstructorParameters<typeof BaseController<BoundingBoxHelperAbstract<OriginObject3D>>>) {\n super(...params)\n }\n}\n","import * as THREE from 'three/webgpu'\nimport { ScaleHelperAbstract, type BaseHelperConfig } from '../Base/BaseHelper'\nimport type { ScalePosition } from '../typings'\nimport { RENDER_ORDER } from '../Constants/RenderOrder'\nimport calculateScaleByCamera from '../utils/calculateScaleByCamera'\nimport { computeWorldPerPixel } from '../utils/solidGuide'\n\n// 直线连接信息\ninterface LineConnection {\n line: THREE.Line\n mesh1: THREE.Object3D & { scalePosition: ScalePosition }\n mesh2: THREE.Object3D & { scalePosition: ScalePosition }\n}\n\nexport class ScaleHelper<T extends THREE.Object3D = THREE.Object3D> extends ScaleHelperAbstract<T> {\n public name = 'ScaleHelper'\n public scaleMeshes: Array<THREE.Object3D & { scalePosition: ScalePosition }> = []\n public lineConnections: Array<LineConnection> = []\n private positions: Array<ScalePosition> | (() => Array<ScalePosition>) = []\n private container: HTMLElement | null | undefined\n private needsInitialScaling = false\n private lastCamera: THREE.PerspectiveCamera | THREE.OrthographicCamera | null = null\n private isInitializing = false\n\n public constructor(\n originObject3D: T,\n config?: { positions?: Array<ScalePosition> | (() => Array<ScalePosition>); container?: HTMLElement | null } & BaseHelperConfig,\n ) {\n super(originObject3D, config)\n\n if (config) {\n this.positions = config.positions\n this.container = config.container\n }\n\n // 禁用容器本身的raycast,只有球应该能被点击\n this.raycast = () => {}\n }\n\n public initQuaternion(): void {\n this.quaternion.copy(this.originObject3D.quaternion)\n }\n\n public initialPosition(offset?: THREE.Vector3) {\n // 防止重复初始化\n if (this.isInitializing) {\n console.warn('ScaleHelper: initialPosition called while already initializing, skipping')\n return\n }\n\n this.isInitializing = true\n\n try {\n this.position.copy(this.originObject3D.position)\n\n const positions = typeof this.positions === 'function' ? this.positions() : this.positions\n\n if (!positions) {\n this.isInitializing = false\n return\n }\n\n // 完全清理现有的球,确保没有重复\n this.clearAllSpheres()\n\n // 重新创建所需的球\n this.scaleMeshes = positions.map((scalePosition, index) => {\n const scaleMesh = generateSphere()\n scaleMesh.position.copy(scalePosition.handlePosition)\n ;(scaleMesh as any).scalePosition = scalePosition\n\n // 为子Mesh也设置scalePosition属性,确保raycaster击中子元素时也能访问到\n scaleMesh.children.forEach((child) => {\n ;(child as any).scalePosition = scalePosition\n })\n\n this.add(scaleMesh)\n return scaleMesh as unknown as typeof scaleMesh & { scalePosition: ScalePosition }\n })\n\n // 创建球之间的直线连接\n this.createLineConnections()\n\n // 标记需要初始缩放\n this.needsInitialScaling = true\n\n // 如果已经有相机信息,立即应用缩放(包括球和直线)\n if (this.lastCamera) {\n this.applySphereScaling(this.lastCamera)\n this.applyLineScaling(this.lastCamera)\n this.needsInitialScaling = false\n }\n } finally {\n this.isInitializing = false\n }\n }\n\n /**\n * 清理所有缩放球\n */\n private clearAllSpheres() {\n // 从场景中移除所有缩放球\n this.scaleMeshes.forEach((mesh) => {\n this.remove(mesh)\n })\n\n // 清空数组\n this.scaleMeshes = []\n\n // 额外保险:移除所有名为 'ScaleHelperSphere' 的子对象\n const spheresToRemove = this.children.filter((child) => child.name === 'ScaleHelperSphere')\n if (spheresToRemove.length > 0) {\n spheresToRemove.forEach((sphere) => {\n this.remove(sphere)\n })\n }\n }\n\n /**\n * 创建中心对称球之间的直线连接\n */\n private createLineConnections() {\n // 清除现有的直线\n this.lineConnections.forEach((connection) => {\n this.remove(connection.line)\n })\n this.lineConnections = []\n\n // 定义对立方向的映射关系\n const oppositeDirections: Record<string, string> = {\n top: 'bottom',\n bottom: 'top',\n left: 'right',\n right: 'left',\n front: 'back',\n back: 'front',\n }\n\n // 创建已处理的方向集合,避免重复创建连线\n const processedDirections = new Set<string>()\n\n // 只为中心对称的球对创建直线\n for (const mesh1 of this.scaleMeshes) {\n const mesh1Id = mesh1.scalePosition.id\n if (!mesh1Id || processedDirections.has(mesh1Id)) continue\n\n const oppositeId = oppositeDirections[mesh1Id]\n if (!oppositeId) continue\n\n // 查找对应的对称球\n const mesh2 = this.scaleMeshes.find((mesh) => mesh.scalePosition.id === oppositeId)\n if (!mesh2) continue\n\n // 创建直线,连接两个对称球的中心\n const line = generateDashedLine(mesh1.position.clone(), mesh2.position.clone())\n\n // 添加到场景\n this.add(line)\n\n // 保存连接信息\n this.lineConnections.push({\n line,\n mesh1,\n mesh2,\n })\n\n // 标记这两个方向已处理,避免重复创建\n processedDirections.add(mesh1Id)\n processedDirections.add(oppositeId)\n }\n }\n\n /**\n * 拖拽过程中,把已有把手挪到 `positions()` 算出的最新位置,不重建 `scaleMeshes`。\n */\n public updateHandlePositions() {\n const positions = typeof this.positions === 'function' ? this.positions() : this.positions\n if (!positions) return\n\n positions.forEach((scalePosition) => {\n const mesh = this.scaleMeshes.find((it) => it.scalePosition.id === scalePosition.id)\n if (!mesh) return\n mesh.position.copy(scalePosition.handlePosition)\n mesh.scalePosition = scalePosition\n })\n\n this.updateLineConnections()\n if (this.lastCamera) this.applySphereScaling(this.lastCamera)\n }\n\n public update(camera: THREE.Camera) {\n const isOrthographic = camera.type === 'OrthographicCamera'\n\n // 获取相机位置\n const cameraPosition = camera.position.clone()\n\n // 获取当前操作对象的中心位置\n const objectCenter = this.originObject3D.getWorldPosition(new THREE.Vector3())\n\n // 计算从对象中心到相机的方向向量\n const toCameraDirection = cameraPosition.sub(objectCenter).normalize()\n\n // 获取对象的6个方向(前后左右上下)\n const objectDirections = {\n front: new THREE.Vector3(0, 0, 1).applyQuaternion(this.originObject3D.getWorldQuaternion(new THREE.Quaternion())),\n back: new THREE.Vector3(0, 0, -1).applyQuaternion(this.originObject3D.getWorldQuaternion(new THREE.Quaternion())),\n left: new THREE.Vector3(-1, 0, 0).applyQuaternion(this.originObject3D.getWorldQuaternion(new THREE.Quaternion())),\n right: new THREE.Vector3(1, 0, 0).applyQuaternion(this.originObject3D.getWorldQuaternion(new THREE.Quaternion())),\n top: new THREE.Vector3(0, 1, 0).applyQuaternion(this.originObject3D.getWorldQuaternion(new THREE.Quaternion())),\n bottom: new THREE.Vector3(0, -1, 0).applyQuaternion(this.originObject3D.getWorldQuaternion(new THREE.Quaternion())),\n }\n\n // 计算每个方向与相机方向的点积,找出最接近的方向\n let maxDot = -1\n let facingDirection = ''\n\n Object.entries(objectDirections).forEach(([direction, dirVector]) => {\n const dot = toCameraDirection.dot(dirVector)\n if (dot > maxDot) {\n maxDot = dot\n facingDirection = direction\n }\n })\n\n // 定义对立面的映射关系\n const oppositeDirections = {\n top: 'bottom',\n bottom: 'top',\n left: 'right',\n right: 'left',\n front: 'back',\n back: 'front',\n }\n\n // 隐藏朝向相机的方向及其对立面\n this.scaleMeshes.forEach((scaleMesh) => {\n if (!isOrthographic) {\n scaleMesh.visible = true\n return\n }\n const meshId = scaleMesh.scalePosition.id\n const oppositeId = oppositeDirections[facingDirection as keyof typeof oppositeDirections]\n\n if (meshId === facingDirection || meshId === oppositeId) {\n scaleMesh.visible = false\n } else {\n scaleMesh.visible = true\n }\n })\n\n // 更新直线位置和可见性\n this.updateLineConnections()\n\n // 如果有相机信息,确保球和直线缩放都正确\n if (this.lastCamera) {\n this.applySphereScaling(this.lastCamera)\n this.applyLineScaling(this.lastCamera)\n }\n }\n\n /**\n * 应用球的缩放逻辑\n */\n private applySphereScaling(camera: THREE.PerspectiveCamera | THREE.OrthographicCamera) {\n // 强制更新世界矩阵,确保使用最新的变换\n this.updateMatrixWorld(true)\n\n this.scaleMeshes.forEach((scaleMesh) => {\n scaleMesh.scale.setScalar(\n calculateScaleByCamera(camera, scaleMesh.scalePosition.handlePosition.clone().applyMatrix4(this.matrixWorld)),\n )\n })\n }\n\n /**\n * 应用直线缩放逻辑(直线不需要特殊的缩放处理)\n */\n private applyLineScaling(camera: THREE.PerspectiveCamera | THREE.OrthographicCamera) {\n // 直线材质不需要像虚线那样的特殊缩放处理\n // 保留此方法以维持接口一致性,但无需执行任何操作\n }\n\n /**\n * 显示所有直线连接\n */\n public showLineConnections() {\n this.lineConnections.forEach((connection) => {\n // 恢复原有的可见性逻辑\n const bothMeshesVisible = connection.mesh1.visible && connection.mesh2.visible\n connection.line.visible = bothMeshesVisible\n })\n }\n\n /**\n * 隐藏所有直线连接\n */\n public hideLineConnections() {\n this.lineConnections.forEach((connection) => {\n connection.line.visible = false\n })\n }\n\n /**\n * 更新直线连接的位置和可见性\n */\n private updateLineConnections() {\n this.lineConnections.forEach((connection) => {\n // 确保直线没有应用任何缩放变换,保持原始大小\n connection.line.scale.set(1, 1, 1)\n connection.line.position.set(0, 0, 0)\n connection.line.rotation.set(0, 0, 0)\n\n // 更新直线位置\n const geometry = connection.line.geometry as THREE.BufferGeometry\n const positions = geometry.attributes.position as THREE.BufferAttribute\n\n // 更新起点和终点位置\n positions.setXYZ(0, connection.mesh1.position.x, connection.mesh1.position.y, connection.mesh1.position.z)\n positions.setXYZ(1, connection.mesh2.position.x, connection.mesh2.position.y, connection.mesh2.position.z)\n positions.needsUpdate = true\n\n // 控制可见性:只有当两个球都显示时才显示直线\n const bothMeshesVisible = connection.mesh1.visible && connection.mesh2.visible\n connection.line.visible = bothMeshesVisible\n })\n }\n\n public setScaleByCamera(camera: THREE.PerspectiveCamera | THREE.OrthographicCamera) {\n this.lastCamera = camera\n\n // 应用球的缩放\n this.applySphereScaling(camera)\n\n // 应用直线缩放,确保与球的缩放保持同步\n this.applyLineScaling(camera)\n\n // 如果是初始缩放,延迟一帧再次应用,确保所有变换都已完成\n if (this.needsInitialScaling) {\n requestAnimationFrame(() => {\n this.applySphereScaling(camera)\n this.applyLineScaling(camera)\n })\n }\n\n // 重置初始缩放标志\n this.needsInitialScaling = false\n }\n}\n\nfunction generateSphere() {\n const radius = 0.03\n const geometry = new THREE.SphereGeometry(radius, 16, 16)\n\n const frontMaterial = new THREE.MeshBasicMaterial({\n color: 0xffff00,\n side: THREE.DoubleSide,\n transparent: true,\n opacity: 1,\n depthTest: false,\n depthWrite: false,\n })\n\n const frontMesh = new THREE.Mesh(geometry, frontMaterial)\n frontMesh.name = 'ScaleHelperSphere'\n frontMesh.renderOrder = RENDER_ORDER.SCALE_HELPER_SPHERE // 缩放Helper优先级中等\n\n // 创建一个透明的 group,半径为黄球的2倍\n const groupRadius = radius * 4\n const groupGeometry = new THREE.SphereGeometry(groupRadius, 16, 16)\n const transparentMaterial = new THREE.MeshBasicMaterial({\n transparent: true,\n opacity: 0, // 完全透明\n side: THREE.DoubleSide,\n depthTest: false,\n depthWrite: false,\n })\n\n const transparentSphere = new THREE.Mesh(groupGeometry, transparentMaterial)\n transparentSphere.name = 'ScaleHelperTransparentGroup'\n transparentSphere.renderOrder = RENDER_ORDER.SCALE_HELPER_SPHERE\n\n // 将黄球添加到透明球中\n transparentSphere.add(frontMesh)\n\n return transparentSphere\n}\n\n/**\n * 生成两个点之间的黄色直线\n * @param point1 起始点\n * @param point2 结束点\n * @returns THREE.Line 直线对象\n */\nfunction generateDashedLine(point1: THREE.Vector3, point2: THREE.Vector3): THREE.Line {\n const geometry = new THREE.BufferGeometry()\n const points = [point1, point2]\n geometry.setFromPoints(points)\n\n // 创建黄色直线材质\n const material = new THREE.LineBasicMaterial({\n color: 0xffff00, // 黄色,与球的颜色一致\n opacity: 0.75,\n transparent: true,\n depthTest: false,\n depthWrite: false,\n })\n\n const line = new THREE.Line(geometry, material)\n line.name = 'ScaleHelperSolidLine'\n line.renderOrder = RENDER_ORDER.SCALE_HELPER_LINE // 确保在球的后面渲染\n line.raycast = () => {} // 禁用raycast,防止干扰拖拽操作\n\n return line\n}\n","import { BaseController } from '../Base/BaseController'\nimport type { ScaleHelperAbstract } from '../Helper'\nimport { RENDER_ORDER } from '../Constants/RenderOrder'\nimport * as THREE from 'three/webgpu'\nimport { getMouseRaycaster } from '../utils'\nimport { SolidGuideLine } from '../utils/solidGuide'\nimport { rayOnLine } from '../../../Sculpt/utils/three/rayOnLine'\nimport type { ScalePosition } from '../typings'\nimport { MoveHelper } from '../Helper/MoveHelper'\nimport { worldBoundingBox } from '../../three/boundingBox'\nimport type { RectangleWithEdgeMesh } from '../../../Sculpt/Meshes/RectangleWithEdge'\nimport getNormal from '../../three/getNormal'\n\nexport class ScaleController<T extends ScaleHelperAbstract = ScaleHelperAbstract> extends BaseController<T> {\n protected name = 'ScaleController'\n /** 拖拽时用于显示方向参考的直线(使用 Line 实现无限长穿透整个平面的直线) */\n private dragGuideLine?: THREE.Line<THREE.BufferGeometry, THREE.LineBasicMaterial>\n /** 当前拖拽时显示的面片 */\n private currentFacePatch?: THREE.Mesh\n private solidGuide = new SolidGuideLine(this.camera, this.container, this.config?.solidGuide ?? {})\n\n private startInfo?: {\n // 开始缩放时的鼠标点的位置\n scaleStartPoint: THREE.Vector3\n // 缩放辅助线\n line: THREE.Line3\n // dragging object\n draggingObject: THREE.Object3D & { scalePosition: ScalePosition }\n }\n\n public constructor(...params: ConstructorParameters<typeof BaseController<T>>) {\n super(...params)\n\n const show = this.show.bind(this)\n const hide = this.hide.bind(this)\n\n const updateHelperByCamera = () => {\n if ('update' in this.helperObject3D && typeof this.helperObject3D.update === 'function') {\n this.helperObject3D.update(this.camera)\n }\n // 如果正在拖拽,更新直线缩放\n if (this.isDragging) {\n this.updateDragGuideLineScale()\n }\n this.render()\n }\n\n updateHelperByCamera()\n\n // mouse\n this.domEvents.addEventListener(this.helperObject3D, 'mousedown', this.dragStart)\n document.addEventListener('mousemove', this.dragging)\n document.addEventListener('mouseup', this.dragEnd)\n // touch\n this.domEvents.addEventListener(this.helperObject3D, 'touchstart', this.dragStart)\n document.addEventListener('touchmove', this.dragging)\n document.addEventListener('touchend', this.dragEnd)\n\n this.hooks.on('rotateStart', hide)\n this.hooks.on('rotateEnd', show)\n this.hooks.on('moveStart', () => {\n hide()\n // 移除高亮面,避免拖拽 CenterHandle 时显示\n this.removeFaceMesh()\n })\n this.hooks.on('moveEnd', show)\n this.hooks.on('moveByMouseEnable', hide)\n this.hooks.on('moveByMouseDisable', show)\n this.hooks.on('updateOtherHelpers', (params) => {\n if ('update' in this.helperObject3D && typeof this.helperObject3D.update === 'function') {\n this.helperObject3D.update(params.camera)\n }\n // 如果正在拖拽,更新直线缩放\n if (this.isDragging) {\n this.updateDragGuideLineScale()\n }\n this.render()\n })\n this.cameraHooks.on('cameraUpdate', updateHelperByCamera)\n\n this.disposers.push(() => {\n this.domEvents.removeEventListener(this.helperObject3D, 'mousedown', this.dragStart)\n document.removeEventListener('mousemove', this.dragging)\n document.removeEventListener('mouseup', this.dragEnd)\n\n this.domEvents.removeEventListener(this.helperObject3D, 'touchstart', this.dragStart)\n document.removeEventListener('touchmove', this.dragging)\n document.removeEventListener('touchend', this.dragEnd)\n\n this.hooks.off('rotateStart', hide)\n this.hooks.off('rotateEnd', show)\n this.hooks.off('moveStart', hide)\n this.hooks.off('moveEnd', show)\n this.hooks.off('moveByMouseEnable', hide)\n this.hooks.off('moveByMouseDisable', show)\n this.hooks.off('updateOtherHelpers')\n this.cameraHooks.off('cameraUpdate', updateHelperByCamera)\n\n // 清理面片\n if (this.currentFacePatch) {\n this.scene.remove(this.currentFacePatch)\n this.currentFacePatch.geometry.dispose()\n const material = this.currentFacePatch.material\n if (Array.isArray(material)) material.forEach((m) => m.dispose())\n else material.dispose()\n this.currentFacePatch = undefined\n }\n })\n }\n\n public initialHelperPosition() {\n this.helperObject3D.initialPosition()\n\n // 这里是因为不能在this上声明offHoverListener属性,因为这样会导致offHoverListener第一次实例化时候被覆盖\n const _this = this as any\n if (_this.offHoverListener) _this.offHoverListener()\n _this.offHoverListener = this.hoverListener(this.helperObject3D.scaleMeshes)\n }\n\n public dragStart = (params: { intersect: THREE.Intersection }) => {\n if (this.isDragging) return\n\n this.isDragging = true\n const { intersect } = params\n const cameraPosition = this.camera.position\n // 命中对象可能是球体的子 Mesh,这里统一上移到被追踪的根 Group(即 scaleMeshes 中的对象)\n const scaleMeshUuidSet = new Set(this.helperObject3D.scaleMeshes.map((m) => m.uuid))\n let hitObject = intersect.object as THREE.Object3D & { scalePosition?: ScalePosition }\n while (hitObject.parent && !scaleMeshUuidSet.has(hitObject.uuid)) {\n hitObject = hitObject.parent as THREE.Object3D & { scalePosition?: ScalePosition }\n }\n const draggingObject = hitObject as THREE.Object3D & { scalePosition: ScalePosition }\n const dragBasePosition = draggingObject.scalePosition.basePosition.clone()\n const dragHandlePosition = draggingObject.scalePosition.handlePosition.clone()\n const dragVector = dragHandlePosition.clone().sub(dragBasePosition).clone()\n\n const line = new THREE.Line3(dragBasePosition, dragBasePosition.clone().add(dragVector.normalize().multiplyScalar(5)))\n line.applyMatrix4(this.helperObject3D.matrixWorld)\n\n const raycaster = new THREE.Raycaster(cameraPosition, intersect.point.clone().sub(cameraPosition))\n const point = rayOnLine({ raycaster, line })\n\n this.startInfo = { line, scaleStartPoint: point, draggingObject }\n\n // hide other scale helpers\n this.helperObject3D.scaleMeshes.forEach((mesh) => {\n if (mesh.uuid === draggingObject.uuid) return\n mesh.visible = false\n })\n\n // 隐藏黄色直线连接\n if ('hideLineConnections' in this.helperObject3D && typeof this.helperObject3D.hideLineConnections === 'function') {\n this.helperObject3D.hideLineConnections()\n }\n\n // 显示拖拽方向的直线参考线(经过物体中心和拉伸球中心,无限延伸穿过整个平面)\n try {\n // 确保世界矩阵是最新的\n this.originObject3D.updateMatrixWorld(true)\n this.helperObject3D.updateMatrixWorld(true)\n\n // 获取原始物体的真正几何中心(世界坐标)\n const objectCenter = this.getObjectWorldCenter()\n\n // 获取拉伸球的世界位置\n const scaleHandleWorldPos = dragHandlePosition.clone().applyMatrix4(this.helperObject3D.matrixWorld)\n // 计算从物体中心指向拉伸球中心的方向向量\n const dirNormalized = scaleHandleWorldPos.clone().sub(objectCenter).normalize()\n\n // 使用物体几何中心作为直线中心\n const center = objectCenter\n\n // 创建无限长直线(提高 renderOrder,保证在包围盒半透明面之上渲染)\n const line = this.solidGuide.createSolidLine(center, dirNormalized, { color: 0xffffff, renderOrder: RENDER_ORDER.DRAG_GUIDE_LINE })\n if (!this.isRectangleWithEdgeMesh()) this.scene.add(line)\n this.dragGuideLine = line\n this.addFaceMesh()\n } catch {}\n\n // show dragging object\n draggingObject.visible = true\n\n this.hooks.emit('scaleStart')\n }\n\n /**\n * 获取物体的真正几何中心(世界坐标)\n * 优先使用 worldCenter 属性(对于 PrismMesh 等),否则使用包围盒中心\n */\n private getObjectWorldCenter(): THREE.Vector3 {\n // 优先使用 worldCenter 属性(对于多边形棱柱等,这才是真正的几何中心)\n if ('worldCenter' in this.originObject3D && typeof (this.originObject3D as any).worldCenter === 'object') {\n return (this.originObject3D as any).worldCenter.clone()\n }\n // 回退到包围盒中心\n const worldBox = worldBoundingBox(this.originObject3D)\n return worldBox ? worldBox.getCenter(new THREE.Vector3()) : this.originObject3D.getWorldPosition(new THREE.Vector3())\n }\n\n private getMoveMeshes() {\n const meshs = []\n const list = this.helperObject3D.parent?.children?.find((it) => it.name === 'MoveHelper')?.children ?? []\n for (const item of list) {\n if (item.name === 'ArrowGroup') {\n meshs.push(...item.children)\n } else if (item.name === 'center-plane-handle') {\n meshs.push(item)\n }\n }\n return meshs\n }\n\n private addHoverFaceMesh(ray: THREE.Raycaster) {\n // 如果 MoveController 正在拖拽,不显示高亮面\n if (this.isMoveControllerDragging()) return\n this.removeFaceMesh()\n // @ts-ignore\n if (!this.originObject3D.parent?.getWorldFacesGeometry) return\n\n // @ts-ignore\n const faces = this.originObject3D.parent?.getWorldFacesGeometry()\n const scaleMeshes = this.helperObject3D.scaleMeshes\n const moveMeshes = this.getMoveMeshes()\n const intersects = ray.intersectObjects(moveMeshes, false)\n\n if (ray.intersectObjects(moveMeshes, false).length > 0) return\n\n // 1. 判断 ray 与 meshs 相交的那个 mesh\n let intersectedMesh = null\n let intersectedPoint = null\n\n // 遍历所有 mesh,使用 raycaster 检测相交\n for (const mesh of scaleMeshes) {\n // 只检测可见的 mesh\n if (!mesh.visible) continue\n // raycaster.intersectObject 返回相交信息数组\n const intersects = ray.intersectObject(mesh, false)\n if (intersects && intersects.length > 0) {\n // 取最近的交点\n intersectedMesh = mesh\n intersectedPoint = intersects[0].point.clone()\n break // 只取第一个相交的 mesh\n }\n }\n\n // 如果找到了相交的 mesh\n if (intersectedMesh && intersectedPoint && Array.isArray(faces) && faces.length > 0) {\n // 2. 在 faces 中找到距离交点最近的 face\n let closestFace = null\n let minDist = Infinity\n for (const face of faces) {\n // 兼容 face.vertices 可能不存在或格式不对\n if (!face.vertices || face.vertices.length < 3) continue\n // 计算面片几何中心\n const center = new THREE.Vector3()\n for (const v of face.vertices) {\n center.add(v)\n }\n center.divideScalar(face.vertices.length)\n // 计算交点到面片中心的距离\n const dist = intersectedPoint.distanceTo(center)\n if (dist < minDist) {\n minDist = dist\n closestFace = face\n }\n }\n // 如果找到最近的面片,则添加高亮面片\n if (closestFace) {\n this.addFacePatch(closestFace)\n }\n }\n }\n\n private addFaceMesh() {\n // 如果 MoveController 正在拖拽,不显示高亮面\n if (this.isMoveControllerDragging()) return\n const draggingObject = this.startInfo?.draggingObject\n if (!draggingObject) return\n // @ts-ignore\n if (!this.originObject3D.parent?.getWorldFacesGeometry) return\n\n // @ts-ignore\n const faces = this.originObject3D.parent?.getWorldFacesGeometry()\n\n if (faces && faces.length > 0) {\n // 选择距离draggingObject.position最近的face,face的center代表face的位置\n const draggingObjectWorldPos = draggingObject.getWorldPosition(new THREE.Vector3())\n let minDist = Infinity\n let closestFace = faces[0]\n for (const face of faces) {\n // face.center 代表face的位置\n const faceCenter = face.center\n // 有些face.center可能不是Vector3,做个兼容\n let centerVec: THREE.Vector3\n if (faceCenter instanceof THREE.Vector3) {\n centerVec = faceCenter\n } else if (Array.isArray(faceCenter) && faceCenter.length === 3) {\n centerVec = new THREE.Vector3(faceCenter[0], faceCenter[1], faceCenter[2])\n } else {\n continue\n }\n const dist = centerVec.distanceTo(draggingObjectWorldPos)\n if (dist < minDist) {\n minDist = dist\n closestFace = face\n }\n }\n // 只添加一个最近的面片\n this.addFacePatch(closestFace)\n }\n }\n\n private removeFaceMesh() {\n if (this.currentFacePatch) {\n this.scene.remove(this.currentFacePatch)\n this.currentFacePatch.geometry.dispose()\n const material = this.currentFacePatch.material\n if (Array.isArray(material)) material.forEach((m) => m.dispose())\n else material.dispose()\n this.currentFacePatch = undefined\n }\n }\n\n public dragging = (point: { x: number; y: number } | TouchEvent) => {\n const x = 'touches' in point ? point.touches[0].clientX : point.x\n const y = 'touches' in point ? point.touches[0].clientY : point.y\n const ray = getMouseRaycaster(this.camera, { x, y }, this.container)\n\n // 检查 MoveController 是否正在拖拽中\n const isMoveControllerDragging = this.isMoveControllerDragging()\n\n if (!this.isDragging && !isMoveControllerDragging && ray) {\n // hover显示白色面片\n this.addHoverFaceMesh(ray)\n return\n }\n\n if (!this.startInfo) return\n\n if (!ray) return this.dragEnd()\n\n this.scale(ray)\n // 更新直线方向,保持直线始终经过物体中心和当前拉伸球位置\n this.updateDragGuideLineDirection()\n // 更新面片位置,跟随拖拽球位置\n this.removeFaceMesh()\n this.addFaceMesh()\n return false\n }\n\n public setScale(scale: number | { x?: number; y?: number; z?: number }) {\n let x = 1\n let y = 1\n let z = 1\n if (typeof scale === 'number') {\n x = scale\n y = scale\n z = scale\n } else if (typeof scale === 'object') {\n x = scale.x ?? 1\n y = scale.y ?? 1\n z = scale.z ?? 1\n }\n const scaleVector3 = new THREE.Vector3(x, y, z)\n\n const canceled = this.hooks.emit('wantToScale', scaleVector3)\n if (canceled) return\n\n this.originObject3D.scale.copy(scaleVector3)\n this.internalHooks.emit('setObjectScale', scaleVector3)\n this.hooks.emit('scale', scaleVector3)\n this.render()\n }\n\n private isRectangleWithEdgeMesh = () => {\n return (\n this.originObject3D.name === 'RectangleWithEdgeMesh' &&\n ['topleft', 'topright', 'bottomleft', 'bottomright'].includes(this.startInfo.draggingObject.scalePosition.id)\n )\n }\n\n public scale = (raycaster: THREE.Raycaster) => {\n if (!this.startInfo) return\n const { line, scaleStartPoint, draggingObject } = this.startInfo\n const { scalePosition } = draggingObject\n\n if (this.isRectangleWithEdgeMesh()) {\n const mesh = this.originObject3D as RectangleWithEdgeMesh\n // const points = (this.originObject3D as RectangleWithEdgeMesh).position\n // 获取mesh的四个角点坐标\n const geometry = mesh.geometry as THREE.BufferGeometry\n\n // 获取顶点数组\n const posAttr = geometry.attributes.position\n if (!posAttr) return []\n\n const corners: THREE.Vector3[] = []\n const vertexCount = posAttr.count // 顶点数量\n\n // 对 PlaneGeometry 来说,顶点顺序通常是:\n // 0: 左上, 1: 右上, 2: 左下, 3: 右下\n for (let i = 0; i < vertexCount; i++) {\n const vertex = new THREE.Vector3().fromBufferAttribute(posAttr as THREE.BufferAttribute, i)\n // 将局部坐标转换为世界坐标\n mesh.updateMatrixWorld(true)\n vertex.applyMatrix4(mesh.matrixWorld)\n corners.push(vertex)\n }\n\n // 返回前四个顶点(如果是 PlaneGeometry)\n const points = corners.slice(0, 4)\n\n if (!points || points.length < 4) return\n // 计算矩形平面法线\n const normal = getNormal(points).normalize()\n // 构建矩形所在平面\n const plane = new THREE.Plane().setFromNormalAndCoplanarPoint(normal, points[0])\n\n // 检查射线与平面是否接近平行(点积接近0表示垂直,接近1表示平行)\n const rayDotNormal = Math.abs(raycaster.ray.direction.dot(normal))\n const isNearlyParallel = rayDotNormal < 0.1 // 夹角大于约84度视为接近平行\n\n let localIntersect: THREE.Vector3\n\n if (isNearlyParallel) {\n // 射线与矩形平面接近平行,改用拖拽辅助线计算(与普通缩放逻辑一致)\n const point = rayOnLine({ raycaster, line, clampToLine: false })\n // 转换到helperObject3D的坐标系下\n localIntersect = point.applyMatrix4(new THREE.Matrix4().copy(this.helperObject3D.matrixWorld.clone().invert()))\n } else {\n // 射线与平面求交\n const intersectPoint = new THREE.Vector3()\n raycaster.ray.intersectPlane(plane, intersectPoint)\n if (!intersectPoint) return\n\n // 转换到矩形局部坐标系\n const inverseMatrix = new THREE.Matrix4().copy(this.helperObject3D.matrixWorld).invert()\n localIntersect = intersectPoint.clone().applyMatrix4(inverseMatrix)\n }\n\n const localStart = scaleStartPoint.clone().applyMatrix4(new THREE.Matrix4().copy(this.helperObject3D.matrixWorld).invert())\n // 调用回调更新 rectangleMesh 的 points\n const handled = this.config?.scaleCallback?.({\n intersectPoint: localIntersect,\n scalePosition,\n offset: localIntersect.clone().sub(localStart),\n updateHandlePositions: () => this.helperObject3D.updateHandlePositions(),\n })\n\n // 同步辅助对象(拖动点位置)。回调返回 false 表示由调用方接管把手位置\n if (handled !== false) draggingObject.position.copy(localIntersect)\n this.hooks.emit('scale', new THREE.Vector3(1, 1, 1))\n return\n }\n\n const point = rayOnLine({ raycaster, line, clampToLine: false })\n // 因为这个point拿到的点是世界坐标系下的,所以需要转换到helperObject3D的坐标系下\n point.applyMatrix4(new THREE.Matrix4().copy(this.helperObject3D.matrixWorld.clone().invert()))\n\n const handled = this.config?.scaleCallback?.({\n intersectPoint: point,\n scalePosition,\n offset: point.clone().sub(scaleStartPoint),\n updateHandlePositions: () => this.helperObject3D.updateHandlePositions(),\n })\n\n // 回调返回 false 表示由调用方接管把手位置\n if (handled !== false) draggingObject.position.copy(point.clone())\n\n this.hooks.emit('scale', new THREE.Vector3(1, 1, 1))\n }\n\n public dragEnd = () => {\n if (!this.isDragging) return\n // 拖动结束,重置currentDraggingDirection\n this.startInfo = undefined\n this.isDragging = false\n\n // show other scale helpers\n this.helperObject3D.scaleMeshes.forEach((mesh) => {\n mesh.visible = true\n })\n\n // 显示黄色直线连接\n if ('showLineConnections' in this.helperObject3D && typeof this.helperObject3D.showLineConnections === 'function') {\n this.helperObject3D.showLineConnections()\n }\n\n // 移除直线\n if (this.dragGuideLine) {\n this.scene.remove(this.dragGuideLine)\n this.dragGuideLine.geometry.dispose()\n const material = this.dragGuideLine.material\n if (Array.isArray(material)) material.forEach((m) => m.dispose())\n else material.dispose()\n this.dragGuideLine = undefined\n }\n\n // 移除面片\n this.removeFaceMesh()\n\n this.internalHooks.emit('initialHelperPosition')\n this.hooks.emit('scaleEnd')\n return\n }\n\n /**\n * 更新参考线\n */\n private updateDragGuideLineDirection() {\n if (!this.dragGuideLine || !this.startInfo) return\n\n // 确保世界矩阵是最新的\n this.originObject3D.updateMatrixWorld(true)\n this.helperObject3D.updateMatrixWorld(true)\n\n const direction = this.startInfo.line.delta(new THREE.Vector3()).normalize()\n const center = this.getObjectWorldCenter()\n\n this.solidGuide.updateSolidLine(this.dragGuideLine, center, direction)\n }\n\n /**\n * 更新直线缩放,保持视觉上的恒定大小\n */\n private updateDragGuideLineScale() {\n if (!this.dragGuideLine || !this.startInfo) return\n\n // 使用拖拽手柄的世界坐标作为中心点,与创建时保持一致\n const { scalePosition } = this.startInfo.draggingObject\n const handleWorld = scalePosition.handlePosition.clone().applyMatrix4(this.helperObject3D.matrixWorld)\n const baseWorld = scalePosition.basePosition.clone().applyMatrix4(this.helperObject3D.matrixWorld)\n const center = handleWorld\n const dirNormalized = handleWorld.clone().sub(baseWorld).normalize()\n // 复用 SolidGuideLine 的直线更新逻辑\n this.solidGuide.updateSolidLine(this.dragGuideLine, center, dirNormalized)\n }\n\n /**\n * 检查 MoveController 是否正在拖拽中\n */\n private isMoveControllerDragging(): boolean {\n // 直接访问 MoveController 的拖拽状态\n return this.otherControllers?.moveController?.getIsDragging() ?? false\n }\n\n /**\n * 向场景添加一个表示 face 的面片,红色,位置与 face.center 一致,使用两个三角形拼成矩形\n */\n public addFacePatch(\n face:\n | {\n center: THREE.Vector3\n vertices?: THREE.Vector3[]\n normal?: THREE.Vector3\n }\n | {\n center: { x: number; y: number; z: number }\n vertices?: THREE.Vector3[]\n normal?: THREE.Vector3\n },\n ) {\n // 如果已经有面片,先移除旧的\n if (this.currentFacePatch) {\n this.scene.remove(this.currentFacePatch)\n this.currentFacePatch.geometry.dispose()\n const material = this.currentFacePatch.material\n if (Array.isArray(material)) material.forEach((m) => m.dispose())\n else material.dispose()\n this.currentFacePatch = undefined\n }\n\n if (!face.vertices || face.vertices.length < 3) {\n console.warn('Face has no vertices, cannot create patch')\n return\n }\n\n // 创建几何体\n const geometry = new THREE.BufferGeometry()\n\n // 根据顶点数量创建不同的几何体\n if (face.vertices.length === 4) {\n // 四边形:使用两个三角形拼成\n const vertices = new Float32Array([\n // 第一个三角形\n face.vertices[0].x,\n face.vertices[0].y,\n face.vertices[0].z,\n face.vertices[1].x,\n face.vertices[1].y,\n face.vertices[1].z,\n face.vertices[2].x,\n face.vertices[2].y,\n face.vertices[2].z,\n // 第二个三角形\n face.vertices[0].x,\n face.vertices[0].y,\n face.vertices[0].z,\n face.vertices[2].x,\n face.vertices[2].y,\n face.vertices[2].z,\n face.vertices[3].x,\n face.vertices[3].y,\n face.vertices[3].z,\n ])\n\n geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))\n geometry.setIndex([0, 1, 2, 3, 4, 5])\n } else {\n // 三角形或其他形状:直接使用顶点\n const vertices = new Float32Array(face.vertices.length * 3)\n const indices = new Uint16Array(face.vertices.length)\n\n face.vertices.forEach((vertex, index) => {\n vertices[index * 3] = vertex.x\n vertices[index * 3 + 1] = vertex.y\n vertices[index * 3 + 2] = vertex.z\n indices[index] = index\n })\n\n geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))\n geometry.setIndex(new THREE.BufferAttribute(indices, 1))\n }\n\n // 计算法线\n geometry.computeVertexNormals()\n\n const material = new THREE.MeshBasicMaterial({\n color: 0xffffff,\n side: THREE.DoubleSide,\n depthTest: false, // 禁用深度测试,避免被其他对象遮挡\n depthWrite: false, // 禁用深度写入\n transparent: true,\n opacity: 0.45,\n })\n\n const patch = new THREE.Mesh(geometry, material)\n\n // 提高渲染次序,确保在所有几何体之上显示\n patch.renderOrder = RENDER_ORDER.DRAG_FACE_PATCH\n this.scene.add(patch)\n this.currentFacePatch = patch\n this.render()\n return patch\n }\n}\n","// @ts-nocheck\n/* eslint-disable */\n// This THREEx helper makes it easy to handle the mouse events in your 3D scene\n//\n// * CHANGES NEEDED\n// * handle drag/drop\n// * notify events not object3D - like DOM\n// * so single object with property\n// * DONE bubling implement bubling/capturing\n// * DONE implement event.stopPropagation()\n// * DONE implement event.type = \"click\" and co\n// * DONE implement event.target\n//\n// # Lets get started\n//\n// First you include it in your page\n//\n// ```<script src='threex.domevent.js'>< /script>```\n//\n// # use the object oriented api\n//\n// You bind an event like this\n//\n// ```mesh.on('click', function(object3d){ ... })```\n//\n// To unbind an event, just do\n//\n// ```mesh.off('click', function(object3d){ ... })```\n//\n// As an alternative, there is another naming closer DOM events.\n// Pick the one you like, they are doing the same thing\n//\n// ```mesh.addEventListener('click', function(object3d){ ... })```\n// ```mesh.removeEventListener('click', function(object3d){ ... })```\n//\n// # Supported Events\n//\n// Always in a effort to stay close to usual pratices, the events name are the same as in DOM.\n// The semantic is the same too.\n// Currently, the available events are\n// [click, dblclick, mouseup, mousedown](http://www.quirksmode.org/dom/events/click.html),\n// [mouseover and mouse out](http://www.quirksmode.org/dom/events/mouseover.html).\n//\n// # use the standalone api\n//\n// The object-oriented api modifies THREE.Object3D class.\n// It is a global class, so it may be legitimatly considered unclean by some people.\n// If this bother you, simply do ```DomEvents.noConflict()``` and use the\n// standalone API. In fact, the object oriented API is just a thin wrapper\n// on top of the standalone API.\n//\n// First, you instanciate the object\n//\n// ```var domEvent = new THREEx.DomEvent();```\n//\n// Then you bind an event like this\n//\n// ```domEvent.bind(mesh, 'click', function(object3d){ object3d.scale.x *= 2; });```\n//\n// To unbind an event, just do\n//\n// ```domEvent.unbind(mesh, 'click', callback);```\n//\n//\n// # Code\n\n//\n\n// @ts-ignore\nimport * as THREE from 'three/webgpu'\n\n// /** @namespace */\n// var THREEx\t\t= THREEx \t\t|| {};\n\n// # Constructor\nfunction DomEvents(camera, domElement) {\n this._camera = camera || null\n this._domElement = domElement || document\n this._raycaster = new THREE.Raycaster()\n this._selected = null\n this._boundObjs = {}\n // Bind dom event for mouse and touch\n var _this = this\n\n this._$onClick = function () {\n _this._onClick.apply(_this, arguments)\n }\n this._$onDblClick = function () {\n _this._onDblClick.apply(_this, arguments)\n }\n this._$onMouseMove = function () {\n _this._onMouseMove.apply(_this, arguments)\n }\n this._$onMouseDown = function () {\n _this._onMouseDown.apply(_this, arguments)\n }\n this._$onMouseUp = function () {\n _this._onMouseUp.apply(_this, arguments)\n }\n this._$onTouchMove = function () {\n _this._onTouchMove.apply(_this, arguments)\n }\n this._$onTouchStart = function () {\n _this._onTouchStart.apply(_this, arguments)\n }\n this._$onTouchEnd = function () {\n _this._onTouchEnd.apply(_this, arguments)\n }\n this._$onContextmenu = function () {\n _this._onContextmenu.apply(_this, arguments)\n }\n this._domElement.addEventListener('click', this._$onClick, false)\n this._domElement.addEventListener('dblclick', this._$onDblClick, false)\n this._domElement.addEventListener('mousemove', this._$onMouseMove, false)\n this._domElement.addEventListener('mousedown', this._$onMouseDown, false)\n this._domElement.addEventListener('mouseup', this._$onMouseUp, false)\n this._domElement.addEventListener('touchmove', this._$onTouchMove, false)\n this._domElement.addEventListener('touchstart', this._$onTouchStart, false)\n this._domElement.addEventListener('touchend', this._$onTouchEnd, false)\n this._domElement.addEventListener('contextmenu', this._$onContextmenu, false)\n}\n\n// # Destructor\nDomEvents.prototype.destroy = function () {\n // unBind dom event for mouse and touch\n this._domElement.removeEventListener('click', this._$onClick, false)\n this._domElement.removeEventListener('dblclick', this._$onDblClick, false)\n this._domElement.removeEventListener('mousemove', this._$onMouseMove, false)\n this._domElement.removeEventListener('mousedown', this._$onMouseDown, false)\n this._domElement.removeEventListener('mouseup', this._$onMouseUp, false)\n this._domElement.removeEventListener('touchmove', this._$onTouchMove, false)\n this._domElement.removeEventListener('touchstart', this._$onTouchStart, false)\n this._domElement.removeEventListener('touchend', this._$onTouchEnd, false)\n this._domElement.removeEventListener('contextmenu', this._$onContextmenu, false)\n}\n\nDomEvents.eventNames = [\n 'click',\n 'dblclick',\n 'mouseover',\n 'mouseout',\n 'mousemove',\n 'mousedown',\n 'mouseup',\n 'contextmenu',\n 'touchstart',\n 'touchend',\n]\n\nDomEvents.prototype._getRelativeMouseXY = function (domEvent) {\n var element = domEvent.target || domEvent.srcElement\n if (element.nodeType === 3) {\n element = element.parentNode // Safari fix -- see http://www.quirksmode.org/js/events_properties.html\n }\n\n // get the real position of an element relative to the page starting point (0, 0)\n // credits go to brainjam on answering http://stackoverflow.com/questions/5755312/getting-mouse-position-relative-to-content-area-of-an-element\n var elPosition = { x: 0, y: 0 }\n var tmpElement = element\n // store padding\n var style = getComputedStyle(tmpElement, null)\n elPosition.y += parseInt(style.getPropertyValue('padding-top'), 10)\n elPosition.x += parseInt(style.getPropertyValue('padding-left'), 10)\n // add positions\n do {\n elPosition.x += tmpElement.offsetLeft\n elPosition.y += tmpElement.offsetTop\n style = getComputedStyle(tmpElement, null)\n\n elPosition.x += parseInt(style.getPropertyValue('border-left-width'), 10)\n elPosition.y += parseInt(style.getPropertyValue('border-top-width'), 10)\n } while ((tmpElement = tmpElement.offsetParent))\n\n var elDimension = {\n width: element === window ? window.innerWidth : element.offsetWidth,\n height: element === window ? window.innerHeight : element.offsetHeight,\n }\n\n return {\n x: Number((domEvent.pageX - elPosition.x) / elDimension.width) * 2 - 1,\n y: -((domEvent.pageY - elPosition.y) / elDimension.height) * 2 + 1,\n }\n}\n\n/********************************************************************************/\n/*\t\tdomevent context\t\t\t\t\t\t*/\n/********************************************************************************/\n\n// handle domevent context in object3d instance\n\nDomEvents.prototype._objectCtxInit = function (object3d) {\n object3d._3xDomEvent = {}\n}\nDomEvents.prototype._objectCtxDeinit = function (object3d) {\n delete object3d._3xDomEvent\n}\nDomEvents.prototype._objectCtxIsInit = function (object3d) {\n return object3d._3xDomEvent ? true : false\n}\nDomEvents.prototype._objectCtxGet = function (object3d) {\n return object3d._3xDomEvent\n}\n\n/********************************************************************************/\n/*\t\t\t\t\t\t\t\t\t\t*/\n/********************************************************************************/\n\n/**\n * Getter/Setter for camera\n */\nDomEvents.prototype.camera = function (value) {\n if (value) this._camera = value\n return this._camera\n}\n\nDomEvents.prototype.bind = function (object3d, eventName, callback, useCapture) {\n console.assert(DomEvents.eventNames.indexOf(eventName) !== -1, 'not available events:' + eventName)\n\n if (!this._objectCtxIsInit(object3d)) this._objectCtxInit(object3d)\n var objectCtx = this._objectCtxGet(object3d)\n if (!objectCtx[eventName + 'Handlers']) objectCtx[eventName + 'Handlers'] = []\n\n objectCtx[eventName + 'Handlers'].push({\n callback: callback,\n useCapture: useCapture,\n })\n\n // add this object in this._boundObjs\n if (this._boundObjs[eventName] === undefined) {\n this._boundObjs[eventName] = []\n }\n this._boundObjs[eventName].push(object3d)\n}\nDomEvents.prototype.addEventListener = DomEvents.prototype.bind\n\nDomEvents.prototype.unbind = function (object3d, eventName, callback, useCapture) {\n console.assert(DomEvents.eventNames.indexOf(eventName) !== -1, 'not available events:' + eventName)\n\n if (!this._objectCtxIsInit(object3d)) this._objectCtxInit(object3d)\n\n var objectCtx = this._objectCtxGet(object3d)\n if (!objectCtx[eventName + 'Handlers']) objectCtx[eventName + 'Handlers'] = []\n\n var handlers = objectCtx[eventName + 'Handlers']\n for (var i = 0; i < handlers.length; i++) {\n var handler = handlers[i]\n if (callback != handler.callback) continue\n if (useCapture != handler.useCapture) continue\n handlers.splice(i, 1)\n break\n }\n // from this object from this._boundObjs\n var index = this._boundObjs[eventName].indexOf(object3d)\n this._boundObjs[eventName].splice(index, 1)\n}\nDomEvents.prototype.removeEventListener = DomEvents.prototype.unbind\n\nDomEvents.prototype._bound = function (eventName, object3d) {\n var objectCtx = this._objectCtxGet(object3d)\n if (!objectCtx) return false\n return objectCtx[eventName + 'Handlers'] ? true : false\n}\n\n/**\n * 检查对象是否可见(包括检查父级对象的可见性)\n * @param {THREE.Object3D} object3d\n * @returns {boolean}\n */\nDomEvents.prototype._isObjectVisible = function (object3d) {\n var current = object3d\n while (current) {\n if (current.visible === false) {\n return false\n }\n current = current.parent\n }\n return true\n}\n\n/**\n * 过滤出可见的对象\n * @param {Array<THREE.Object3D>} objects\n * @returns {Array<THREE.Object3D>}\n */\nDomEvents.prototype._filterVisibleObjects = function (objects) {\n var _this = this\n return objects.filter(function (obj) {\n return _this._isObjectVisible(obj)\n })\n}\n\n/********************************************************************************/\n/*\t\tonMove\t\t\t\t\t\t\t\t*/\n/********************************************************************************/\n\n// # handle mousemove kind of events\n\nDomEvents.prototype._onMove = function (eventName, mouseX, mouseY, origDomEvent) {\n // get objects bound to this event\n var boundObjs = this._boundObjs[eventName]\n if (boundObjs === undefined || boundObjs.length === 0) return\n\n // 过滤出可见的对象\n var visibleBoundObjs = this._filterVisibleObjects(boundObjs)\n if (visibleBoundObjs.length === 0) return\n\n // compute the intersection\n var vector = new THREE.Vector2()\n\n // update the picking ray with the camera and mouse position\n vector.set(mouseX, mouseY)\n this._raycaster.setFromCamera(vector, this._camera)\n\n var intersects = this._raycaster.intersectObjects(visibleBoundObjs)\n\n // 过滤掉隐藏的相交对象(检查对象本身及其父级链条的可见性)\n var _this = this\n intersects = intersects.filter(function (intersect) {\n return _this._isObjectVisible(intersect.object)\n })\n\n // 按照渲染顺序和距离进行排序,优先选择渲染顺序高的对象\n intersects.sort(function (a, b) {\n var aRenderOrder = a.object.renderOrder || 0\n var bRenderOrder = b.object.renderOrder || 0\n\n // 如果渲染顺序不同,优先选择渲染顺序高的\n if (aRenderOrder !== bRenderOrder) {\n return bRenderOrder - aRenderOrder\n }\n\n // 如果渲染顺序相同,按距离排序(近的优先)\n return a.distance - b.distance\n })\n\n var oldSelected = this._selected\n\n if (intersects.length > 0) {\n var notifyOver\n var notifyOut\n var notifyMove\n var intersect = intersects[0]\n var newSelected = intersect.object\n this._selected = newSelected\n // if newSelected bound mousemove, notify it\n notifyMove = this._bound('mousemove', newSelected)\n\n if (oldSelected != newSelected) {\n // if newSelected bound mouseenter, notify it\n notifyOver = this._bound('mouseover', newSelected)\n // if there is a oldSelect and oldSelected bound mouseleave, notify it\n notifyOut = oldSelected && this._bound('mouseout', oldSelected)\n }\n } else {\n // if there is a oldSelect and oldSelected bound mouseleave, notify it\n notifyOut = oldSelected && this._bound('mouseout', oldSelected)\n this._selected = null\n }\n\n // notify mouseMove - done at the end with a copy of the list to allow callback to remove handlers\n notifyMove && this._notify('mousemove', newSelected, origDomEvent, intersect)\n // notify mouseEnter - done at the end with a copy of the list to allow callback to remove handlers\n notifyOver && this._notify('mouseover', newSelected, origDomEvent, intersect)\n // notify mouseLeave - done at the end with a copy of the list to allow callback to remove handlers\n notifyOut && this._notify('mouseout', oldSelected, origDomEvent, intersect)\n}\n\n/********************************************************************************/\n/*\t\tonEvent\t\t\t\t\t\t\t\t*/\n/********************************************************************************/\n\n// # handle click kind of events\n\nDomEvents.prototype._onEvent = function (eventName, mouseX, mouseY, origDomEvent) {\n // get objects bound to this event\n var boundObjs = this._boundObjs[eventName]\n if (boundObjs === undefined || boundObjs.length === 0) return\n\n // 过滤出可见的对象\n var visibleBoundObjs = this._filterVisibleObjects(boundObjs)\n if (visibleBoundObjs.length === 0) return\n\n // compute the intersection\n var vector = new THREE.Vector2()\n\n // update the picking ray with the camera and mouse position\n vector.set(mouseX, mouseY)\n this._raycaster.setFromCamera(vector, this._camera)\n\n var intersects = this._raycaster.intersectObjects(visibleBoundObjs, true)\n // 过滤掉隐藏的相交对象(检查对象本身及其父级链条的可见性)\n var _this = this\n intersects = intersects.filter(function (intersect) {\n return _this._isObjectVisible(intersect.object)\n })\n\n // 按照渲染顺序和距离进行排序,优先选择渲染顺序高的对象\n intersects.sort(function (a, b) {\n var aRenderOrder = a.object.renderOrder || 0\n var bRenderOrder = b.object.renderOrder || 0\n\n // 如果渲染顺序不同,优先选择渲染顺序高的\n if (aRenderOrder !== bRenderOrder) {\n return bRenderOrder - aRenderOrder\n }\n\n // 如果渲染顺序相同,按距离排序(近的优先)\n return a.distance - b.distance\n })\n // if there are no intersections, return now\n if (intersects.length === 0) return\n // init some variables\n var intersect = intersects[0]\n var object3d = intersect.object\n var objectCtx = this._objectCtxGet(object3d)\n var objectParent = object3d.parent\n\n while (typeof objectCtx === 'undefined' && objectParent) {\n objectCtx = this._objectCtxGet(objectParent)\n objectParent = objectParent.parent\n }\n if (!objectCtx) return\n\n // notify handlers\n this._notify(eventName, object3d, origDomEvent, intersect)\n}\n\nDomEvents.prototype._notify = function (eventName, object3d, origDomEvent, intersect) {\n var objectCtx = this._objectCtxGet(object3d)\n var handlers = objectCtx ? objectCtx[eventName + 'Handlers'] : null\n\n // do bubbling\n if (!objectCtx || !handlers || handlers.length === 0) {\n object3d.parent && this._notify(eventName, object3d.parent, origDomEvent, intersect)\n return\n }\n\n // notify all handlers\n var handlers = objectCtx[eventName + 'Handlers']\n for (var i = 0; i < handlers.length; i++) {\n var handler = handlers[i]\n var toPropagate = true\n handler.callback({\n type: eventName,\n target: object3d,\n origDomEvent: origDomEvent,\n intersect: intersect,\n stopPropagation: function () {\n toPropagate = false\n },\n })\n if (!toPropagate) continue\n // do bubbling\n if (handler.useCapture === false) {\n object3d.parent && this._notify(eventName, object3d.parent, origDomEvent, intersect)\n }\n }\n}\n\n/********************************************************************************/\n/*\t\thandle mouse events\t\t\t\t\t\t*/\n/********************************************************************************/\n// # handle mouse events\n\nDomEvents.prototype._onMouseDown = function (event) {\n return this._onMouseEvent('mousedown', event)\n}\nDomEvents.prototype._onMouseUp = function (event) {\n return this._onMouseEvent('mouseup', event)\n}\n\nDomEvents.prototype._onMouseEvent = function (eventName, domEvent) {\n var mouseCoords = this._getRelativeMouseXY(domEvent)\n this._onEvent(eventName, mouseCoords.x, mouseCoords.y, domEvent)\n}\n\nDomEvents.prototype._onMouseMove = function (domEvent) {\n var mouseCoords = this._getRelativeMouseXY(domEvent)\n this._onMove('mousemove', mouseCoords.x, mouseCoords.y, domEvent)\n this._onMove('mouseover', mouseCoords.x, mouseCoords.y, domEvent)\n this._onMove('mouseout', mouseCoords.x, mouseCoords.y, domEvent)\n}\n\nDomEvents.prototype._onClick = function (event) {\n // TODO handle touch ?\n this._onMouseEvent('click', event)\n}\nDomEvents.prototype._onDblClick = function (event) {\n // TODO handle touch ?\n this._onMouseEvent('dblclick', event)\n}\n\nDomEvents.prototype._onContextmenu = function (event) {\n // TODO don't have a clue about how this should work with touch..\n this._onMouseEvent('contextmenu', event)\n}\n\n/********************************************************************************/\n/*\t\thandle touch events\t\t\t\t\t\t*/\n/********************************************************************************/\n// # handle touch events\n\nDomEvents.prototype._onTouchStart = function (event) {\n return this._onTouchEvent('touchstart', event)\n}\nDomEvents.prototype._onTouchEnd = function (event) {\n return this._onTouchEvent('touchend', event)\n}\n\nDomEvents.prototype._onTouchMove = function (domEvent) {\n if (domEvent.touches.length != 1) return undefined\n\n // domEvent.preventDefault();\n\n var mouseX = Number(domEvent.touches[0].pageX / window.innerWidth) * 2 - 1\n var mouseY = -(domEvent.touches[0].pageY / window.innerHeight) * 2 + 1\n this._onMove('mousemove', mouseX, mouseY, domEvent)\n this._onMove('mouseover', mouseX, mouseY, domEvent)\n this._onMove('mouseout', mouseX, mouseY, domEvent)\n}\n\nDomEvents.prototype._onTouchEvent = function (eventName, domEvent) {\n // 单指 touchend 事件中,touches 为空,这里改为使用 changedTouches\n // if( domEvent.touches.length != 1 )\treturn undefined; // 这是原来的代码\n var touches = domEvent.touches\n if (touches.length == 0) {\n touches = domEvent.changedTouches\n }\n\n if (touches.length != 1) return undefined\n\n // domEvent.preventDefault();\n\n var mouseX = Number(touches[0].pageX / window.innerWidth) * 2 - 1\n var mouseY = -(touches[0].pageY / window.innerHeight) * 2 + 1\n this._onEvent(eventName, mouseX, mouseY, domEvent)\n}\n\nexport default DomEvents\n","import type * as THREE from 'three/webgpu'\nimport type { Five } from '@realsee/five-webgpu'\nimport { Controller as BasePluginController } from '../base/BasePlugin'\nimport { MoveHelper, RotateHelper, CSS3DScaleHelper, BoundingBoxHelper } from '../shared-utils/Object3DHelper/Helper'\nimport { MoveController } from '../shared-utils/Object3DHelper/Controller/MoveController'\nimport { FiveControllerWrapper } from './FiveControllerWrapper'\nimport { Object3DHelper } from '../shared-utils/Object3DHelper/index'\nimport { RotateController } from '../shared-utils/Object3DHelper/Controller/RotateController'\nimport { CSS3DScaleController } from '../shared-utils/Object3DHelper/Controller/CSS3DScaleController'\nimport type {\n Object3DHelperState,\n ObjectHelperControllers,\n PositionFrom,\n ScaleCallback,\n ScalePosition,\n} from '../shared-utils/Object3DHelper/typings'\nimport type { HelperConfig, HelperOffset, Object3DHelperPluginEventMap, Object3DHelperPluginState } from './typings'\nimport type { CSS3DObjectPlus } from '../CSS3DRenderPlugin/utils/three/CSS3DObject'\nimport { CSS3DRender } from '../CSS3DRenderPlugin/utils/three/CSS3DRender'\nimport generateBehindFiveElement from '../CSS3DRenderPlugin/utils/generateBehindFiveElement'\nimport { BoundingBoxController } from '../shared-utils/Object3DHelper/Controller/BoundingBoxController'\nimport { ScaleHelper } from '../shared-utils/Object3DHelper/Helper/ScaleHelper'\nimport { ScaleController } from '../shared-utils/Object3DHelper/Controller/ScaleController'\nimport { waitFiveModelLoaded } from '../shared-utils/five/fiveModelLoad'\nimport { Subscribe } from '../shared-utils/Subscribe'\nimport DomEvents from '../shared-utils/threex/domevents'\n\nconst PLUGIN_NAME = 'Object3DHelperPlugin'\n\nexport const PLUGIN = PLUGIN_NAME\n\nexport type AddObject3DHelperConfig = {\n /**\n * @description 辅助坐标轴的位置,基于 object local 坐标系。\n * ```markdown\n * 'boundingBox': 物体 boundingBox 的中心\n * 'boundingSphere': 物体 boundingSphere 的中心\n * `THREE.Vector3`: 指定 Vector3\n * `(object3D) => THREE.Vector3`: 指定 Vector3\n * ```\n * @default 'objectPosition'\n */\n positionFrom?: PositionFrom\n /**\n * @description 辅助坐标轴的位置偏移量\n */\n offset?: HelperOffset\n /**\n * @description 辅助坐标轴的y轴方向(绿色)\n */\n yAxis?: THREE.Vector3 | (() => THREE.Vector3)\n /**\n * @description 辅助坐标轴的x轴方向(红色)\n */\n xAxis?: THREE.Vector3 | (() => THREE.Vector3)\n /**\n * @description 辅助坐标轴的z轴方向(蓝色)\n */\n zAxis?: THREE.Vector3 | (() => THREE.Vector3)\n /**\n * @description 位移的配置\n */\n moveHelper?: HelperConfig<{\n /**\n * @description 是否开启X轴位移功能(红色)\n */\n xArrowEnable?: boolean\n /**\n * @description 是否开启Y轴位移功能(绿色)\n */\n yArrowEnable?: boolean\n /**\n * @description 是否开启Z轴位移功能(蓝色)\n */\n zArrowEnable?: boolean\n }>\n /**\n * @description 旋转的配置\n */\n rotateHelper?: HelperConfig<{\n /**\n * @description 是否开启X轴旋转功能(红色)\n */\n yzCircleEnable?: boolean\n /**\n * @description 是否开启Y轴旋转功能(绿色)\n */\n xzCircleEnable?: boolean\n /**\n * @description 是否开启Z轴旋转功能(蓝色)\n */\n xyCircleEnable?: boolean\n /**\n * @description 旋转时的角度提示\n */\n angleTipsEnable?: boolean\n }>\n /**\n * @description 缩放的配置\n */\n scaleHelper?: HelperConfig<{\n /**\n * @description 缩放 handlers 的位置\n */\n positions?: Array<ScalePosition> | (() => Array<ScalePosition>)\n /**\n * @description 缩放 handler 被拖动后的回调\n */\n scaleCallback?: ScaleCallback\n }>\n /**\n * @description 物体包围盒\n */\n boundingBoxHelper?: HelperConfig\n}\n\nconst disposedErrorLog = () => {\n console.error(`${PLUGIN} is disposed`)\n}\n\nconst disableWarnLog = () => {\n console.warn(`${PLUGIN} is disabled`)\n}\n\nconst disableErrorLog = () => {\n console.error(`${PLUGIN} is disabled`)\n}\n\nexport class Object3DHelperController extends BasePluginController<Object3DHelperPluginState, Object3DHelperPluginEventMap> {\n public name = PLUGIN_NAME\n public state: Object3DHelperState = {\n visible: true,\n enabled: true,\n disposed: false,\n }\n\n public objectHelperMap: Map<THREE.Object3D, { helper: Object3DHelper; disposers: (() => any)[] }> = new Map()\n\n private css3DObjectParentMap: Map<THREE.Object3D, THREE.Object3D | null> = new Map()\n private css3DObjectModeMap: Map<THREE.Object3D, string> = new Map()\n\n private css3DRender: CSS3DRender\n\n public constructor(five: Five) {\n super(five)\n this.five = five\n this.css3DRender = new CSS3DRender(this.five.scene)\n\n\n // debug\n // Object.assign(window, { THREE: THREE })\n }\n\n /**\n * @description Show guide line\n */\n public async show(options?: { userAction?: boolean }) {\n this.setState({ visible: true }, options)\n }\n\n /**\n * @description Hide guide line\n */\n public async hide(options?: { userAction?: boolean }) {\n this.setState({ visible: false }, options)\n }\n\n /**\n * @description Enable\n */\n public enable(options?: { userAction?: boolean }) {\n this.setState({ enabled: true }, options)\n }\n\n /**\n * @description Disable\n */\n public disable(options?: { userAction?: boolean }) {\n this.setState({ enabled: false }, options)\n }\n\n /**\n * @description Dispose\n */\n public dispose() {\n this.setState({ disposed: true })\n }\n\n public setState(state: Partial<Object3DHelperState>, options?: { userAction?: boolean } & Record<string, any>): void {\n if (this.state.disposed) return disposedErrorLog()\n if (!this.state.enabled) {\n // when plugin is disabled, only can change enabled or disposed to true\n if (state.enabled !== true && state.disposed !== true) return disableErrorLog()\n }\n const prevState = { ...this.state }\n this.state = { ...this.state, ...state }\n if (state.disposed !== undefined && state.disposed !== prevState.disposed) {\n if (state.disposed) this.handleDispose()\n }\n if (state.visible !== undefined && state.visible !== prevState.visible) {\n this.handleVisible(state.visible)\n }\n if (state.enabled !== undefined && state.enabled !== prevState.enabled) {\n this.handleEnable(state.enabled)\n }\n\n this.hooks.emit('stateChange', { state: this.state, prevState })\n }\n\n public getObject3DHelper(object3D: THREE.Object3D) {\n return this.objectHelperMap.get(object3D)\n }\n\n /**\n * @description 添加 helper\n * @param { THREE.Object3D } object3D 要添加helper的物体\n * @param { boolean } config.moveHelper 位移helper\n * @param { boolean } config.rotateHelper 旋转helper\n * @param { boolean } config.scaleHelper 缩放helper\n */\n public addObject3DHelper(object3D: THREE.Object3D, paramsConfig: AddObject3DHelperConfig = {}): ObjectHelperControllers | undefined {\n if (!object3D) {\n console.error('Object3D is undefined')\n return\n }\n\n if (this.objectHelperMap.has(object3D)) {\n console.warn(`Object3DHelperPlugin: object3D ${object3D.name} is already has helper`)\n return\n }\n const helper = new Object3DHelper()\n\n const disposers: (() => any)[] = []\n\n const container = this.five.getElement()?.parentElement\n const camera = this.five.camera\n // 创建空的helperGroup\n // merge config\n const defaultConfig: AddObject3DHelperConfig = {\n moveHelper: true,\n rotateHelper: true,\n scaleHelper: true,\n boundingBoxHelper: false,\n positionFrom: 'objectPosition',\n }\n const config = { ...defaultConfig, ...paramsConfig }\n const { moveHelper, rotateHelper, scaleHelper, boundingBoxHelper } = config\n\n const hooks = helper.hooks\n const internalHooks = new Subscribe()\n const donEvents = new DomEvents(this.five.camera, this.five.getElement())\n\n const helperEnable = (helper: HelperConfig<{}>) => {\n if (!helper) return\n if (typeof helper === 'boolean') return helper\n return helper.enable\n }\n\n // 先创建所有控制器,但不设置引用关系\n const controllers: { [key: string]: any } = {}\n\n // 筛选\n if (helperEnable(moveHelper)) {\n const c = { ...this.getConfig(config.moveHelper), ...config }\n const moveHelper = new MoveHelper(object3D, { ...c })\n const controllerWrapper = new FiveControllerWrapper(\n this.five,\n donEvents,\n MoveController,\n object3D,\n moveHelper,\n c,\n hooks,\n internalHooks,\n )\n controllers.moveController = controllerWrapper.helperController\n disposers.push(() => controllerWrapper.dispose())\n }\n\n if (helperEnable(rotateHelper)) {\n const c = { ...this.getConfig(config.rotateHelper), ...config }\n const rotateHelper = new RotateHelper(object3D, { container, ...c })\n const controllerWrapper = new FiveControllerWrapper(\n this.five,\n donEvents,\n RotateController,\n object3D,\n rotateHelper,\n c,\n hooks,\n internalHooks,\n )\n controllers.rotateController = controllerWrapper.helperController\n disposers.push(() => controllerWrapper.dispose())\n }\n\n if (helperEnable(boundingBoxHelper)) {\n const boundingBoxHelper = new BoundingBoxHelper(object3D)\n const controllerWrapper = new FiveControllerWrapper(\n this.five,\n donEvents,\n BoundingBoxController,\n object3D,\n boundingBoxHelper,\n undefined,\n hooks,\n internalHooks,\n )\n controllers.boundingBoxController = controllerWrapper.helperController\n disposers.push(() => controllerWrapper.dispose())\n }\n\n if (helperEnable(scaleHelper)) {\n if ((object3D as any).isCSS3DObject && container) {\n const css3dScaleHelper = new CSS3DScaleHelper(object3D as CSS3DObjectPlus, container, camera, this.five.scene)\n const controllerWrapper = new FiveControllerWrapper(\n this.five,\n donEvents,\n CSS3DScaleController,\n object3D,\n css3dScaleHelper,\n undefined,\n hooks,\n internalHooks,\n )\n controllers.scaleController = controllerWrapper.helperController\n disposers.push(() => controllerWrapper.dispose())\n\n waitFiveModelLoaded(this.five).then(() => {\n if ((object3D as any).isCSS3DObjectPlus) {\n const css3dObject = object3D as CSS3DObjectPlus\n if (!css3dObject) return\n if (css3dObject.mode !== 'front') return\n const wrapper = this.css3DRender.behindModeCSS3DRenderer.wrapper ?? generateBehindFiveElement(this.five)\n if (wrapper) {\n this.css3DObjectParentMap.set(css3dObject, css3dObject.parent)\n // 移除\n css3dObject.removeFromParent()\n // 添加\n this.css3DRender.behindModeCSS3DRenderer.setWrapper(wrapper)\n this.css3DRender.getBehindCSS3DObjectGroup()?.add(css3dObject)\n this.css3DRender.render(this.five.camera)\n }\n } else if ((object3D as any).isCSS3DObject) {\n this.css3DObjectModeMap.set(object3D, (object3D as any).mode)\n ;(object3D as any).mode = 'behind'\n }\n })\n } else {\n const c = { ...this.getConfig(config.scaleHelper), ...config }\n const scaleHelper = new ScaleHelper(object3D, c)\n const controllerWrapper = new FiveControllerWrapper(\n this.five,\n donEvents,\n ScaleController,\n object3D,\n scaleHelper,\n c,\n hooks,\n internalHooks,\n )\n controllers.scaleController = controllerWrapper.helperController\n disposers.push(() => controllerWrapper.dispose())\n }\n }\n\n // 所有控制器创建完成后,更新它们的引用关系\n Object.values(controllers).forEach((controller: any) => {\n if (controller && typeof controller.updateOtherControllers === 'function') {\n controller.updateOtherControllers(controllers)\n }\n })\n\n // 所有控制器创建完成后,将它们添加到 helper 中\n helper.addControllers(controllers)\n\n this.objectHelperMap.set(object3D, { helper, disposers })\n\n return helper.controllers\n }\n\n public removeObject3DHelper(object3D: THREE.Object3D) {\n if (!this.objectHelperMap.has(object3D)) return\n const { helper, disposers } = this.objectHelperMap.get(object3D)\n if (!helper) return\n if ((object3D as any).isCSS3DObjectPlus) {\n const css3DObject = object3D as CSS3DObjectPlus\n const parent = this.css3DObjectParentMap.get(css3DObject)\n if (parent) parent.add(css3DObject)\n this.css3DRender.render(this.five.camera)\n } else if ((object3D as any).isCSS3DObject) {\n const mode = this.css3DObjectModeMap.get(object3D)\n ;(object3D as any).mode = mode\n }\n this.objectHelperMap.delete(object3D)\n helper.dispose()\n disposers?.forEach((d) => d?.())\n }\n\n private handleEnable(enabled: boolean, userAction = true) {\n if (enabled) {\n this.everyHelperDo((helper) => helper.enable())\n this.hooks.emit('enable', { userAction })\n } else {\n this.everyHelperDo((helper) => helper.disable())\n this.hooks.emit('disable', { userAction })\n }\n this.state.enabled = enabled\n }\n\n private handleVisible(visible: boolean, userAction = true) {\n if (visible) {\n this.everyHelperDo((helper) => helper.show())\n this.actionIfStateIsEnabled(() => this.hooks.emit('show', { userAction }))\n } else {\n this.everyHelperDo((helper) => helper.hide())\n this.actionIfStateIsEnabled(() => this.hooks.emit('hide', { userAction }))\n }\n this.state.visible = visible\n }\n\n private handleDispose() {\n this.everyHelperDo((helper, disposers) => {\n helper.dispose()\n disposers?.forEach((d) => d?.())\n })\n }\n\n private everyHelperDo(func: (helper: Object3DHelper, disposers?: (() => any)[]) => any) {\n this.objectHelperMap.forEach(({ helper, disposers }) => {\n if (helper) func(helper, disposers)\n })\n }\n\n private actionIfStateIsEnabled<T = any>(func: () => T, options?: { warnLog?: true }) {\n if (this.state.enabled) return func()\n else {\n if (options?.warnLog) disableWarnLog()\n }\n }\n\n private getConfig<T>(config?: HelperConfig<T>): T | undefined {\n if (!config) return\n if (typeof config === 'boolean') return\n if (config.enable) return config\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAQA,SAAwBwB,EAAoB,GAAwB,GAA8B,GAA6B;CAC7H,IAAIC,GAAc;EAEhB,IAAMC,IADsB,IAAIH,EAAM,QAAQ,CAAC,CAAC,WAAWI,EAAO,UAAUF,CAClE,CAAA,CACP,gBAAgBE,EAAO,WAAW,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CACnD,gBAAgBC,CAAU,CAAC,CAC3B,IAAIH,CAAY;EACnB,EAAO,SAAS,KAAKC,CAAC;CACxB;CACA,EAAO,WAAW,KAAKE,CAAU;AACnC;;;ACIA,IAAsBC,IAAtB,cAAqFnB,EAAU;CAC7F;CACA;CACA;CAEA,IAAW,eAAyB;EAClC,OAAO;CACT;CAEA,YAAmB,GAAgC,GAA2B;EAI5E,AAHA,MAAM,GACN,KAAK,iBAAiBoB,GACtB,KAAK,WAAWC,GAAQ,mBAAmB,CAAC,IAC5C,KAAK,eAAeA,GAAQ,gBAAgB;CAC9C;CAEA,SAAgB;EACd,KAAK,SAAS;CAChB;CAEA,SAAgB;EACd,AAAI,KAAK,OAAO,SAAS,SAAS,IAAI,KACtC,KAAK,OAAO,IAAI,IAAI;CACtB;CAEA,UAAiB;EACf,KAAK,iBAAiB;CACxB;CAEA,OAAc;EAEZ,AADA,KAAK,UAAU,IACf,KAAK,OAAO;CACd;CAEA,OAAc;EAEZ,AADA,KAAK,UAAU,IACf,KAAK,OAAO;CACd;CAEA,yBAAgC,GAA4B,IAAqC,CAAC,GAAyB;EACzH,OAAOC,EAAU,gBAAgB,MAAM,IAAMC,CAAY;CAC3D;CAEA,gBAAuB,GAAwB;EAa7C,AAZI,KAAK,iBAAiB,mBACxB,KAAK,SAAS,KAAK,KAAK,eAAe,QAAQ,IACtC,KAAK,iBAAiB,gBAC/B,KAAK,SAAS,KAAKf,EAAY,KAAK,cAAc,CAAC,EAAE,UAAU,IAAIK,EAAM,QAAQ,CAAC,CAAC,CAAC,aAAa,KAAK,eAAe,WAAW,CAAC,IACxH,KAAK,iBAAiB,mBAC/B,KAAK,SAAS,KAAKN,EAAe,KAAK,cAAc,CAAC,EAAE,OAAO,MAAM,CAAC,CAAC,aAAa,KAAK,eAAe,WAAW,CAAC,IAC3G,KAAK,wBAAwBiB,IACtC,KAAK,SAAS,KAAK,KAAK,YAAY,IAC3B,KAAK,wBAAwB,YACtC,KAAK,SAAS,KAAK,KAAK,aAAa,KAAK,cAAc,CAAC,GAGvDC,KACF,KAAK,SAAS,IAAIA,CAAM;CAE5B;CAEA,iBAAwB,GAA4D,CAAC;CAErF,eAAsB,GAInB;EAED,IADA,KAAK,WAAW,KAAK,KAAK,eAAe,UAAU,GAC/CJ,MACEA,EAAO,SAASA,EAAO,SAASA,EAAO,QAAO;GAChD,IAAMK,IAAQL,EAAO,iBAAiB,WAAWA,EAAO,MAAM,IAAIA,EAAO,OACnEM,IAAQN,EAAO,iBAAiB,WAAWA,EAAO,MAAM,IAAIA,EAAO,OACnEO,IAAQP,EAAO,iBAAiB,WAAWA,EAAO,MAAM,IAAIA,EAAO,OAErEQ,IAAOH,GAAO,MAAM,GACpBI,IAAOH,GAAO,MAAM,GACpBI,IAAOH,GAAO,MAAM;GAGxB,IAAIC,KAAQ,CAACC,KAAQ,CAACA,GAAM;IAC1B,IAAME,IAAc,IAAInB,EAAM,WAAW,CAAC,CAAC,mBAAmB,IAAIA,EAAM,QAAQ,GAAG,GAAG,CAAC,GAAGgB,EAAK,UAAU,CAAC;IAC1G,KAAK,gBAAgBG,CAAW;GAClC;GAEA,IAAIF,KAAQ,CAACD,KAAQ,CAACE,GAAM;IAC1B,IAAME,IAAc,IAAIpB,EAAM,WAAW,CAAC,CAAC,mBAAmB,IAAIA,EAAM,QAAQ,GAAG,GAAG,CAAC,GAAGiB,EAAK,UAAU,CAAC;IAC1G,KAAK,gBAAgBG,CAAW;GAClC;GAEA,IAAIF,KAAQ,CAACF,KAAQ,CAACC,GAAM;IAC1B,IAAMI,IAAc,IAAIrB,EAAM,WAAW,CAAC,CAAC,mBAAmB,IAAIA,EAAM,QAAQ,GAAG,GAAG,CAAC,GAAGkB,EAAK,UAAU,CAAC;IAC1G,KAAK,gBAAgBG,CAAW;GAClC;GAGA,IAAI;IAACL;IAAMC;IAAMC;GAAI,CAAC,CAAC,OAAO5B,CAAM,CAAC,CAAC,UAAU,GAAG;IAQjD,AANA,AAAW0B,MAAO,IAAIhB,EAAM,QAAQ,CAAC,CAAC,aAAaiB,GAAMC,CAAI,CAAC,CAAC,UAAU,GACzE,AAAWD,MAAO,IAAIjB,EAAM,QAAQ,CAAC,CAAC,aAAagB,GAAME,CAAI,CAAC,CAAC,UAAU,GACzE,AAAWA,MAAO,IAAIlB,EAAM,QAAQ,CAAC,CAAC,aAAagB,GAAMC,CAAI,CAAC,CAAC,UAAU,GAEzED,EAAK,gBAAgB,KAAK,UAAU,GACpCC,EAAK,gBAAgB,KAAK,UAAU,GACpCC,EAAK,gBAAgB,KAAK,UAAU;IAEpC,IAAMI,IAAY,IAAItB,EAAM,QAAQ,CAAC,CAAC,UAAUgB,GAAMC,GAAMC,CAAI,GAE1Db,IAAa,IAAIL,EAAM,WAAW,CAAC,CAAC,sBAAsBsB,CAAS;IAEzE,KAAK,WAAW,KAAKjB,CAAU;GACjC;EACF;CAEJ;CAEA,wBAA+B,GAAuB,GAAkB;EACtE,KAAK,MAAM,aAAakB,CAAM;CAChC;CAEA,oBAA2B,GAA8B,GAAkB;EAEzE,AADA,KAAK,eAAe,GACpBtB,EAAoB,MAAM,KAAK,WAAW,MAAM,CAAC,CAAC,YAAYI,CAAU,GAAGmB,CAAM;CACnF;CAEA,sBAA6B,GAA8B,GAAkB;EAC3E,IAAIA,GAAQ;GACV,IAAMrB,IAAI,IAAIQ,EAAQ,CAAC,CAAC,WAAW,KAAK,UAAUa,CAAM,CAAC,CAAC,gBAAgBnB,CAAU,CAAC,CAAC,IAAImB,CAAM;GAChG,KAAK,SAAS,KAAKrB,CAAC;EACtB;EACA,KAAK,gBAAgBE,CAAU;CACjC;CAEA,UAAiB;EACf,KAAK,iBAAiB;CACxB;AACF,GAEsBoB,IAAtB,cAA6FnB,EAA2B,CAOxH,GAEsBoB,IAAtB,cAAoGpB,EAA2B,CAAC,GAG1GqB,IAAtB,cAA+FrB,EAA2B,CAO1H,GAEsBsB,IAAtB,cAA8FtB,EAA2B,CAIzH,GAEsBuB,IAAtB,cAGUvB,EAA2B,CAWrC,GCtMawB,IAAb,cAAoC9B,EAAM,MAAM;CAC9C;CAEA,YAAmB,GAAuB;EAExC,AADA,MAAM,GACN,KAAK,YAAY+B,KAAa;CAChC;AACF;AAE6F/B,EAAM;AASnG,IAAagC,IAAb,cAA6FhC,EAAM,KAAW;CAC5G;CAEA,YAAmB,GAAc,GAAc,GAAuB;EAEpE,AADA,MAAMiC,GAAUC,CAAQ,GACxB,KAAK,YAAYH,KAAa;CAChC;AACF;;;ACpBA,SAAgBI,GAAoB,GAAuC,GAAsB;CAC/F,IAAM,EAAE,aAAaC,GAAO,cAAcC,MAAWC,GAC/C,EAAE,QAAK,YAASA,EAAQ,sBAAsB;CACpD,OAAO,OAAO,OAAO,IAAItC,EAAM,QAAQ,GAAG;EACxC,IAAKuC,EAAY,IAAIC,KAAQJ,IAAS,IAAI;EAC1C,GAAI,EAAEG,EAAY,IAAIE,KAAOJ,IAAU,IAAI;CAC7C,CAAC;AACH;;;ACZA,SAAgBK,EAAkB,GAAsB,GAAiC,GAAsB;CAC7G,IAAI,CAACC,KAAS,CAACL,KAAW,CAACM,GAAQ;CACnC,IAAMC,IAAaV,GAAoBQ,GAAOL,CAAO;CACrD,IAAI,KAAK,IAAIO,EAAW,CAAC,MAAM,KAAK,KAAK,IAAIA,EAAW,CAAC,MAAM,GAAG;CAClE,IAAMpC,IAAY,IAAIT,EAAM,UAAU;CAGtC,OAFAS,EAAU,cAAcoC,GAAYD,CAAM,GAC1C,EAAU,OAAO,OAAO,YAAY,IAC7BnC;AACT;;;ACPA,IAAaqC,IAAe;CAK1B,eAAe;CAGf,aAAa;CAGb,mBAAmB;CAGnB,qBAAqB;CAGrB,mBAAmB;CAGnB,oBAAoB;CAGpB,iBAAiB;CAGjB,iBAAiB;AACnB,GCrBaC,IAAb,cAAgCjB,EAAe;CAC7C;CACA;CACA,aAAqB;CACrB,cAAsB;CACtB,OAAc;CAEd,YAAmB,GAA0B;EAC3C,MAAMkB,EAAM,SAAS;EACrB,IAAMC,IAAQ,IAAIjD,EAAM,MAAMgD,EAAM,SAAS,QAAQ,GAC/Cd,IAAW,IAAIlC,EAAM,kBAAkB;GAC3C;GACA,aAAa;GACb,SAAS;GACT,WAAW;GACX,YAAY;EACd,CAAC,GAIKkD,IAAQ,IAAIlB,EAAc,IADPhC,EAAM,aAAa,KAAM,IAAK,EACvB,GAAckC,EAAS,MAAM,GAAGc,EAAM,SAAS;EAG/E,AAFA,EAAM,OAAO,SAASA,EAAM,aAC5B,EAAM,cAAcF,EAAa,mBACjC,KAAK,QAAQI;EAGb,IAAMC,IAAS,MAETC,IAAW,IAAIpB,EAAc,IADNhC,EAAM,iBAAiBmD,GAAQA,GAAQ,IAAK,EACtC,GAAkBjB,EAAS,MAAM,GAAGc,EAAM,SAAS;EAOtF,AANA,EAAS,OAAO,QAAQA,EAAM,aAC9B,EAAS,cAAcF,EAAa,mBACpC,KAAK,OAAOM,GAEZ,KAAK,YAAY,GACjB,KAAK,WAAW,GAChB,KAAK,IAAI,KAAK,OAAO,KAAK,IAAI;CAChC;CAEA,cAAsB;EAEpB,AADA,KAAK,MAAM,SAAS,UAAU,GAAG,KAAK,aAAa,KAAK,cAAc,GAAG,CAAC,GACtE,KAAK,cAAc,OACrB,KAAK,MAAM,SAAS,QAAQ,KAAK,KAAK,CAAC,GACvC,KAAK,MAAM,SAAS,QAAQ,KAAK,KAAK,CAAC,KAC9B,KAAK,cAAc,OAC5B,KAAK,MAAM,SAAS,QAAQ,KAAK,KAAK,CAAC;CAE3C;CAEA,aAAqB;EAEnB,AADA,KAAK,KAAK,SAAS,UAAU,GAAG,KAAK,aAAa,GAAG,CAAC,GAClD,KAAK,cAAc,OACrB,KAAK,KAAK,SAAS,QAAQ,KAAK,KAAK,CAAC,GACtC,KAAK,KAAK,SAAS,QAAQ,KAAK,KAAK,CAAC,KAC7B,KAAK,cAAc,OAC5B,KAAK,KAAK,SAAS,QAAQ,KAAK,KAAK,CAAC;CAE1C;AACF,GCzDaC,IAAb,cAAkCvB,EAAe;CAC/C;CACA,OAAc;CACd;CACA;CAEA,cAAsB;EACpB,IAAI9B,EAAM,QAAQ,GAAG,GAAG,CAAC;EACzB,IAAIA,EAAM,QAAQ,IAAI,GAAG,CAAC;EAC1B,IAAIA,EAAM,QAAQ,GAAG,GAAG,CAAC;EACzB,IAAIA,EAAM,QAAQ,GAAG,IAAI,CAAC;EAC1B,IAAIA,EAAM,QAAQ,GAAG,GAAG,CAAC;EACzB,IAAIA,EAAM,QAAQ,GAAG,GAAG,EAAE;CAC5B;CAEA,YAAmB,GAA2B;EAE5C,AADA,MAAM,OAAO,GACb,KAAK,YAAY,IAAIA,EAAM,MAAMgD,GAAO,SAAS,QAAQ;EACzD,IAAMM,IAAaN,GAAO,QAAQ,KAG5BO,IAAc,IAAIvD,EAAM,MAAM,QAAQ;EAG5C,KAAK,gBAAgB,MAAM,KACzB,EAAE,QAAQ,EAAE,SAEV,IAAIA,EAAM,kBAAkB;GAC1B,OAAOuD;GACP,aAAa;GACb,SAAS;GACT,WAAW;GACX,YAAY;GACZ,MAAMvD,EAAM;EACd,CAAC,CACL;EAEA,IAAMwD,IAAiB,IAAIxD,EAAM,YAAYsD,GAAYA,GAAYA,CAAU,GACzEG,IAAO,IAAIzD,EAAM,KAAKwD,GAAgB,KAAK,aAAa;EAQ9D,AALA,EAAK,YAAY,SACjB,EAAK,cAAcV,EAAa,oBAChC,EAAK,OAAO,uBACZ,KAAK,OAAOW,GAEZ,KAAK,IAAI,KAAK,IAAI;CACpB;CAMA,OAAc,GAAsB;EAElC,IAAMC,IAAkB,IAAI1D,EAAM,QAAQ,CAAC,CAAC,WAAW4C,EAAO,UAAU,KAAK,KAAK,iBAAiB,IAAI5C,EAAM,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,GAG7H2D,IAAkB,KAAK,KAAK,mBAAmB,IAAI3D,EAAM,WAAW,CAAC,GAGrE4D,IAAa,KAAK,YAAY,KAAK,GAAQ,MAAU;GAIzD,IAAMC,IAFcC,EAAO,MAAM,CAAC,CAAC,gBAAgBH,CAEhC,CAAA,CAAY,IAAID,CAAe;GAClD,OAAO;IAAE;IAAO,OAAO,KAAK,KAAK,KAAK,IAAIG,CAAU,CAAC;GAAE;EACzD,CAAC;EAGD,EAAW,MAAM,GAAG,MAAME,EAAE,QAAQC,EAAE,KAAK;EAG3C,IAAMC,IAAS;GACb,IAAIjE,EAAM,MAAM,QAAQ;GACxB,IAAIA,EAAM,MAAM,QAAQ;GACxB,IAAIA,EAAM,MAAM,QAAQ;EAC1B;EAGA,EAAW,SAAS,GAAM,MAAgB;GACxC,IAAMkE,IAAa,KAAK,MAAMC,IAAc,CAAC;GAC7C,KAAK,cAAcC,EAAK,MAAM,CAAC,MAAM,KAAKH,EAAOC,EAAW;EAC9D,CAAC;CACH;AACF,GC7FMG,IAAa;CACjB,GAAG;CACH,GAAG;CACH,GAAG;AACL,GAEMC,IAAN,MAAuB;CACrB,WAAkB,IAAI;EACpB,OAAO,IAAItE,EAAM,MAAMqE,EAAW,CAAC;CACrC;CACA,WAAkB,IAAI;EACpB,OAAO,IAAIrE,EAAM,MAAMqE,EAAW,CAAC;CACrC;CACA,WAAkB,IAAI;EACpB,OAAO,IAAIrE,EAAM,MAAMqE,EAAW,CAAC;CACrC;AACF;;;AChBA,SAAwBE,EAAuB,GAAa,GAAyB,GAAwC;CAC3H,IAIMC,IAAW5B,EAAO,SAAS,WAAW6B,CAAQ,GAC9CC,IAAM9B,EAAO,KACb+B,IAAiB/B,EAAO,YAAY,GAEpCgC,IAAgBJ,IAAW,GAC3BK,IAAWH,IAAM,IACjBI,IAAsBH,IAAiB,GAEvCI,IAAQH,IAAgBC,IAAWC,GAEnCE,IAAMC,GAAO,OAAO,IACpBC,IAAMD,GAAO;CAKnB,OAHID,KAAOD,IAAQC,IAAYA,IAC3BE,KAAOH,IAAQG,IAAYA,IAExBH;AACT;;;ACxBA,SAASI,EAAM,GAAe,GAAa,GAAa;CAOtD,OANIC,IAAQJ,IACHA,IAELI,IAAQF,IACHA,IAEFE;AACT;;;ACAA,SAAgBC,GAAkB,GAAsB;CACtD,IAAIC,IAAoB1C,EAAe,KAAK,UACxC2C,IAAqB3C,EAAe,KAAK;CAC7C,IAAIrD,EAAM+F,CAAQ,KAAK/F,EAAMgG,CAAS,GAAG;EACvC,IAAMC,IAAI5C,EAAO,OAAO;EAExB,AADA,IAAW,KAAK,KAAKuC,EAAMK,EAAE,IAAI,IAAI,CAAC,CAAC,GACvC,AAGED,IAHE,KAAK,IAAIC,EAAE,EAAE,IAAI,WACPnG,EAAU,KAAK,MAAMmG,EAAE,IAAIA,EAAE,GAAG,CAAC,IAEjCnG,EAAU,KAAK,MAAM,CAACmG,EAAE,IAAIA,EAAE,EAAE,CAAC;CAEjD;CAEA,OAAO;EAAE;EAAU;CAAU;AAC/B;;;ACjBA,SAAgBC,GAA+B,GAA+C;CAC5F,IAAM,EAAE,aAAU,iBAAcC,GAE1BC,IAAS,IAAI3F,EAAM,QAAQ;CAcjC,OAZI4F,IAASN,IAAW,MACtBK,EAAO,IAAI,GAAG,GAAG,CAAC,IACTE,EAAO,GAAGN,CAAS,IAC5BI,EAAO,IAAI,GAAG,GAAG,CAAC,IACTE,EAAO,KAAK,IAAIN,CAAS,IAClCI,EAAO,IAAI,GAAG,GAAG,EAAE,IACVE,EAAOD,GAAQL,CAAS,IACjCI,EAAO,IAAI,GAAG,GAAG,CAAC,IAElBA,EAAO,IAAI,IAAI,GAAG,CAAC,GAGdA;AACT;AAEA,IAAMC,IAAS,QAAQ,KAAK,KAAK,EAAA,CAAG,QAAQ,CAAC,CAAC;AAC9C,SAASC,EAAO,GAAa,GAAa;CAExC,OADI,OAAOC,KAAO,YAAY,OAAOC,KAAO,WAAiB,KACtD,KAAK,IAAID,IAAKC,CAAE,IAAI;AAC7B;;;AClBA,IAAaC,IAAb,cAAgCvE,EAAmB;CACjD,OAAc;CACd;CACA;CACA;CACA;CAEA,YACE,GACA,GAMA;EAQA,AAPA,MAAMlB,GAAgBC,CAAM,GAExBA,EAAO,iBAAiB,OAAO,KAAK,SAAS,IAAIuC,EAAW;GAAE,WAAW;GAAK,OAAOuB,EAAiB;EAAE,CAAC,IACzG9D,EAAO,iBAAiB,OAAO,KAAK,SAAS,IAAIuC,EAAW;GAAE,WAAW;GAAK,OAAOuB,EAAiB;EAAE,CAAC,IACzG9D,EAAO,iBAAiB,OAAO,KAAK,SAAS,IAAIuC,EAAW;GAAE,WAAW;GAAK,OAAOuB,EAAiB;EAAE,CAAC,IACzG9D,EAAO,uBAAuB,OAAO,KAAK,eAAe,IAAI6C,EAAa,IAE9E,KAAK,IAAI,GAAG;GAAC,KAAK;GAAQ,KAAK;GAAQ,KAAK;GAAQ,KAAK;EAAY,CAAC,CAAC,OAAO,OAAO,CAAC;CACxF;CAEA,OAAc,GAAsB;EAMlC,AALI,KAAK,WAAQ,KAAK,OAAO,UAAU,KACnC,KAAK,WAAQ,KAAK,OAAO,UAAU,KACnC,KAAK,WAAQ,KAAK,OAAO,UAAU,KAGnC,KAAK,gBACP,KAAK,aAAa,OAAOT,CAAM;EAGjC,IAAMc,IAAkB,KAAK,aAAa,SAAS,MAAM,CAAC,CAAC,IAAId,EAAO,QAAQ,CAAC,CAAC,UAAU,GAGpFqD,IAAkB,IAAIjG,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB,KAAK,UAAU,GAC5EkG,IAAkB,IAAIlG,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB,KAAK,UAAU,GAC5EmG,IAAkB,IAAInG,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB,KAAK,UAAU;EAGlF,IAAI4C,EAAO,SAAS,sBAAsB;GAGxC,IAAMwD,IAA8BX,GAFvBJ,GAAkBzC,CAEoC,CAAI,GAGjEyD,IAAgB;GAEtB,AACE,KAAK,IAAIJ,EAAgB,QAAQG,CAA2B,IAAI,CAAC,IAAIC,KACrE,KAAK,IAAIJ,EAAgB,QAAQG,CAA2B,IAAI,KAAK,EAAE,IAAIC,IAEvE,KAAK,WAAQ,KAAK,OAAO,UAAU,MAEvC,KAAK,IAAIH,EAAgB,QAAQE,CAA2B,IAAI,CAAC,IAAIC,KACrE,KAAK,IAAIH,EAAgB,QAAQE,CAA2B,IAAI,KAAK,EAAE,IAAIC,IAEvE,KAAK,WAAQ,KAAK,OAAO,UAAU,OAEvC,KAAK,IAAIF,EAAgB,QAAQC,CAA2B,IAAI,CAAC,IAAIC,KACrE,KAAK,IAAIF,EAAgB,QAAQC,CAA2B,IAAI,KAAK,EAAE,IAAIC,MAEvE,KAAK,WAAQ,KAAK,OAAO,UAAU;EAE3C;EAEA,IAAIzD,EAAO,SAAS,sBAAsB;GAExC,IAAM0D,IAAS5C,EAAgB,QAAQuC,CAAe,GAChDM,IAAS7C,EAAgB,QAAQwC,CAAe,GAChDM,IAAS9C,EAAgB,QAAQyC,CAAe,GAEhDM,IAAY,KAAK,KAAK,GACtBC,IAAWH,IAASE,GACpBE,IAAWH,IAASC,GACpBG,IAAWN,IAASG;GA6B1B,AA3BI,KAAK,WACHG,KAEF,KAAK,OAAO,MAAM,IAAI,IACtB,KAAK,OAAO,MAAM,IAAI,GACtB,KAAK,OAAO,MAAM,IAAI,MAGtB,KAAK,OAAO,MAAM,IAAI,GACtB,KAAK,OAAO,MAAM,IAAI,GACtB,KAAK,OAAO,MAAM,IAAI,KAItB,KAAK,WACHF,KAEF,KAAK,OAAO,MAAM,IAAI,GACtB,KAAK,OAAO,MAAM,IAAI,IACtB,KAAK,OAAO,MAAM,IAAI,MAGtB,KAAK,OAAO,MAAM,IAAI,GACtB,KAAK,OAAO,MAAM,IAAI,GACtB,KAAK,OAAO,MAAM,IAAI,KAGtB,KAAK,WACHC,KAEF,KAAK,OAAO,MAAM,IAAI,GACtB,KAAK,OAAO,MAAM,IAAI,GACtB,KAAK,OAAO,MAAM,IAAI,OAGtB,KAAK,OAAO,MAAM,IAAI,GACtB,KAAK,OAAO,MAAM,IAAI,GACtB,KAAK,OAAO,MAAM,IAAI;EAG5B;CACF;CAEA,OAAc;EAKZ,AAJA,MAAM,KAAK,GACP,KAAK,UAAQ,KAAK,IAAI,KAAK,MAAM,GACjC,KAAK,UAAQ,KAAK,IAAI,KAAK,MAAM,GACjC,KAAK,UAAQ,KAAK,IAAI,KAAK,MAAM,GACjC,KAAK,gBAAc,KAAK,IAAI,KAAK,YAAY;CACnD;CAEA,iBAAwB,GAA4D;EAClF,KAAK,MAAM,UAAUpC,EAAuB3B,GAAQ,KAAK,QAAQ,CAAC;CACpE;CAEA,mBAA0B,GAAyB;EAajD,AAZI,KAAK,WACHiE,EAAW,SAAS,GAAG,IAAG,KAAK,IAAI,KAAK,MAAM,IAC7C,KAAK,OAAO,KAAK,MAAM,IAE1B,KAAK,WACHA,EAAW,SAAS,GAAG,IAAG,KAAK,IAAI,KAAK,MAAM,IAC7C,KAAK,OAAO,KAAK,MAAM,IAE1B,KAAK,WACHA,EAAW,SAAS,GAAG,IAAG,KAAK,IAAI,KAAK,MAAM,IAC7C,KAAK,OAAO,KAAK,MAAM,IAE1B,KAAK,iBACHA,EAAW,SAAS,OAAO,IAAG,KAAK,IAAI,KAAK,YAAY,IACvD,KAAK,OAAO,KAAK,YAAY;CAEtC;CAEA,UAAiB;EAEf,AADA,KAAK,OAAO,GAAG;GAAC,KAAK;GAAQ,KAAK;GAAQ,KAAK;GAAQ,KAAK;EAAY,CAAC,CAAC,OAAO,OAAO,CAAC,GACzF,MAAM,QAAQ;CAChB;AACF;;;AC1KA,SAAgBC,EAAc,GAAsC,GAAkB;CACpF,OAAOC,GAAS,SAAS,cAAcC,KAAW,KAAK,GAAGC,CAAK;AACjE;AAEA,SAAgBF,GAAS,GAAsB,GAAsC;CACnF,IAAI,CAACE,GAAO,OAAO3E;CACnB,KAAK,IAAM4E,KAAOD,GAChB,AAAIC,KAAOD,EAAMC,OAAM,EAAQ,MAAMA,KAAeD,EAAMC;CAE5D,OAAO5E;AACT;;;ACRA,SAAgB6E,GAAQ,GAAsC;CAC5D,IAAM7E,IAAUwE,EAAc;EAC5B,UAAU;EACV,SAAS;EACT,cAAc;EACd,YAAY;EACZ,eAAe;EACf,aAAa;EACb,cAAc;EACd,eAAe;EACf,YAAY;EACZ,QAAQ;EACR,iBAAiB;EACjB,UAAU;EACV,OAAO;EACP,eAAe;EACf,YAAY;EACZ,GAAGG;CACL,CAAC,GACKG,UAAa;EACjB,AAAI9E,EAAQ,MAAM,YAAY,WACzBA,EAAQ,MAAM,OACdA,EAAQ,MAAM,SACnB,EAAQ,MAAM,UAAU;CAC1B;CAWA,OAAO;EAAE;EAAS;EAAM,YAVL;GAGjB,AAFA,EAAQ,MAAM,UAAU,QACxB,EAAQ,MAAM,MAAM,IACpB,EAAQ,MAAM,OAAO;EACvB;EAM8B,aALV,GAAc,MAAgB;GAGhD,AAFA,EAAQ,MAAM,OAAOE,GACrB,EAAQ,MAAM,MAAMC,GACpB2E,EAAK;EACP;CACyC;AAC3C;;;AC7BA,IAAaC,KAAb,cAAkC1F,EAAqB;CACrD,OAAc;CACd;CACA;CACA;CACA,WAAuC,CAAC;CACxC;CACA;CAEA,YACE,GACA,GAOA;EAcA,AAbA,MAAMpB,GAAgBC,CAAM,GAExBA,GAAQ,mBAAmB,OAAO,KAAK,UAAU,IAAI8G,EAAkB;GAAE,WAAW;GAAK,OAAOhD,EAAiB;EAAE,CAAC,IACpH9D,GAAQ,mBAAmB,OAAO,KAAK,UAAU,IAAI8G,EAAkB;GAAE,WAAW;GAAK,OAAOhD,EAAiB;EAAE,CAAC,IACpH9D,GAAQ,mBAAmB,OAAO,KAAK,UAAU,IAAI8G,EAAkB;GAAE,WAAW;GAAK,OAAOhD,EAAiB;EAAE,CAAC,IAEpH9D,GAAQ,aAAaA,GAAQ,oBAAoB,OACnD,KAAK,YAAYA,GAAQ,WACzB,KAAK,YAAY2G,GAAQ,EAAE,SAAS,OAAO,CAAC,GAC5C,KAAK,UAAU,YAAY,KAAK,UAAU,OAAO,IAGnD,KAAK,IAAI,GAAG;GAAC,KAAK;GAAS,KAAK;GAAS,KAAK;EAAO,CAAC,CAAC,OAAO,OAAO,CAAC,GACtE,KAAK,KAAK;CACZ;CAEA,OAAc;EACZ,KAAK,SAAS,SAAS,MAAUI,EAAM,KAAK,CAAC;CAC/C;CAEA,OAAc;EAEZ,AADA,KAAK,SAAS,SAAS,MAAUA,EAAM,WAAW,CAAC,GACnD,KAAK,WAAW,KAAK;CACvB;CAEA,iBAAwB,GAA4D;EAClF,KAAK,MAAM,UAAUhD,EAAuB3B,GAAQ,KAAK,QAAQ,CAAC;CACpE;CAEA,OAAc,GAAsB;EAClC,IAAIA,EAAO,SAAS,sBAAsB;EAE1C,IAAMc,IAAkB,KAAK,aAAa,SAAS,MAAM,CAAC,CAAC,IAAId,EAAO,QAAQ,CAAC,CAAC,UAAU,GAGpFqD,IAAkB,IAAIjG,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB,KAAK,UAAU,GAC5EkG,IAAkB,IAAIlG,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB,KAAK,UAAU,GAC5EmG,IAAkB,IAAInG,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB,KAAK,UAAU,GAG5EsG,IAAS5C,EAAgB,QAAQuC,CAAe,GAChDM,IAAS7C,EAAgB,QAAQwC,CAAe,GAChDM,IAAS9C,EAAgB,QAAQyC,CAAe,GAGhDM,IAAY,KAAK,KAAK,GACtBe,IAAYjB,KAAUE,GACtBgB,IAAYjB,KAAUC,GACtBiB,IAAYpB,KAAUG;EAE5B,IAAI,KAAK,SAAS;GAChB,IAAMkB,IAAW,KAAK,QAAQ,OAAO;GAWrC,AAVIH,KAAaC,IACf,KAAK,QAAQ,OAAO,WAAW,IAAIzH,EAAM,aAAa,KAAM,IAAK,IAAI,GAAG2H,GAAU,KAAK,KAAK,IAAIA,IAAW,CAAC,IACnGH,KAAa,CAACC,IACvB,KAAK,QAAQ,OAAO,WAAW,IAAIzH,EAAM,aAAa,KAAM,IAAK,IAAI,GAAG,KAAK,KAAK,IAAI2H,GAAU,KAAK,KAAK,IAAIA,IAAW,CAAC,IACjH,CAACH,KAAaC,IACvB,KAAK,QAAQ,OAAO,WAAW,IAAIzH,EAAM,aAAa,KAAM,IAAK,IAAI,GAAI,KAAK,KAAK,IAAK,IAAI2H,GAAU,KAAK,KAAK,IAAIA,IAAW,CAAC,IACvH,CAACH,KAAa,CAACC,MACxB,KAAK,QAAQ,OAAO,WAAW,IAAIzH,EAAM,aAAa,KAAM,IAAK,IAAI,GAAG,KAAK,KAAK2H,GAAU,KAAK,KAAK,IAAIA,IAAW,CAAC,IAGpH,KAAK,QAAQ,gBACf,KAAK,QAAQ,YAAY,eAAe,MAAUC,GAE9CJ,KAAaC,KAEND,KAAa,CAACC,IADvB,KAAK,QAAQ,YAAY,WAAW,IAAIzH,EAAM,QAAQ,GAAG,GAAG,CAAC,IAGpD,CAACwH,KAAaC,KACvB,KAAK,QAAQ,YAAY,WAAW,IAAIzH,EAAM,QAAQ,GAAG,IAAI,CAAC,GAC9D,KAAK,QAAQ,YAAY,eAAe,MAAU4H,IAAQ,KAAK,KAAK,KAC3D,CAACJ,KAAa,CAACC,MACxB,KAAK,QAAQ,YAAY,WAAW,IAAIzH,EAAM,QAAQ,GAAG,GAAG,EAAE,GAC9D,KAAK,QAAQ,YAAY,eAAe,MAAU4H,IAAQ,KAAK;EAGrE;EAEA,IAAI,KAAK,SAAS;GAChB,KAAK,QAAQ,YAAY,eAAe,MAAUA;GAClD,IAAMD,IAAW,KAAK,QAAQ,OAAO;GAYrC,AAVID,KAAaD,IACf,KAAK,QAAQ,OAAO,WAAW,IAAIzH,EAAM,aAAa,KAAM,IAAK,IAAI,GAAG2H,GAAU,KAAK,KAAK,IAAIA,IAAW,CAAC,IACnGD,KAAa,CAACD,IACvB,KAAK,QAAQ,OAAO,WAAW,IAAIzH,EAAM,aAAa,KAAM,IAAK,IAAI,GAAI,KAAK,KAAK,IAAK,IAAI2H,GAAU,KAAK,KAAK,IAAIA,IAAW,CAAC,IACvH,CAACD,KAAaD,IACvB,KAAK,QAAQ,OAAO,WAAW,IAAIzH,EAAM,aAAa,KAAM,IAAK,IAAI,GAAG,KAAK,KAAK,IAAI2H,GAAU,KAAK,KAAK,IAAIA,IAAW,CAAC,IACjH,CAACD,KAAa,CAACD,MACxB,KAAK,QAAQ,OAAO,WAAW,IAAIzH,EAAM,aAAa,KAAM,IAAK,IAAI,GAAG,KAAK,KAAK2H,GAAU,KAAK,KAAK,IAAIA,IAAW,CAAC,IAGpHD,KAAaD,IACf,KAAK,QAAQ,YAAY,WAAW,IAAIzH,EAAM,QAAQ,GAAG,GAAG,CAAC,IACpD0H,KAAa,CAACD,KACvB,KAAK,QAAQ,YAAY,WAAW,IAAIzH,EAAM,QAAQ,GAAG,GAAG,EAAE,GAC9D,KAAK,QAAQ,YAAY,eAAe,MAAU4H,IAAQ,KAAK,KAAK,KAC3D,CAACF,KAAaD,KACvB,KAAK,QAAQ,YAAY,WAAW,IAAIzH,EAAM,QAAQ,GAAG,GAAG,CAAC,GAC7D,KAAK,QAAQ,YAAY,eAAe,MAAU4H,IAAQ,KAAK,KAAK,KAC3D,CAACF,KAAa,CAACD,MACxB,KAAK,QAAQ,YAAY,WAAW,IAAIzH,EAAM,QAAQ,IAAI,GAAG,CAAC,GAC9D,KAAK,QAAQ,YAAY,eAAe,MAAU4H,IAAQ,KAAK;EAEnE;EAEA,IAAI,KAAK,SAAS;GAChB,KAAK,QAAQ,YAAY,eAAe,MAAUA;GAClD,IAAMD,IAAW,KAAK,QAAQ,OAAO;GAYrC,AAVID,KAAaF,IACf,KAAK,QAAQ,OAAO,WAAW,IAAIxH,EAAM,aAAa,KAAM,IAAK,IAAI,GAAG2H,GAAU,KAAK,KAAK,IAAIA,IAAW,CAAC,IACnGD,KAAa,CAACF,IACvB,KAAK,QAAQ,OAAO,WAAW,IAAIxH,EAAM,aAAa,KAAM,IAAK,IAAI,GAAI,KAAK,KAAK,IAAK,IAAI2H,GAAU,KAAK,KAAK,IAAIA,IAAW,CAAC,IACvH,CAACD,KAAaF,IACvB,KAAK,QAAQ,OAAO,WAAW,IAAIxH,EAAM,aAAa,KAAM,IAAK,IAAI,GAAG,KAAK,KAAK,IAAI2H,GAAU,KAAK,KAAK,IAAIA,IAAW,CAAC,IACjH,CAACD,KAAa,CAACF,MACxB,KAAK,QAAQ,OAAO,WAAW,IAAIxH,EAAM,aAAa,KAAM,IAAK,IAAI,GAAG,KAAK,KAAK2H,GAAU,KAAK,KAAK,IAAIA,IAAW,CAAC,IAGpH,KAAK,QAAQ,gBACXD,KAAaF,IACf,KAAK,QAAQ,YAAY,WAAW,IAAIxH,EAAM,QAAQ,GAAG,GAAG,CAAC,IACpD0H,KAAa,CAACF,KACvB,KAAK,QAAQ,YAAY,WAAW,IAAIxH,EAAM,QAAQ,GAAG,IAAI,CAAC,GAC9D,KAAK,QAAQ,YAAY,eAAe,MAAU4H,IAAQ,KAAK,KAAK,KAC3D,CAACF,KAAaF,KACvB,KAAK,QAAQ,YAAY,WAAW,IAAIxH,EAAM,QAAQ,GAAG,GAAG,CAAC,GAC7D,KAAK,QAAQ,YAAY,eAAe,MAAU4H,IAAQ,KAAK,KAAK,KAC3D,CAACF,KAAa,CAACF,MACxB,KAAK,QAAQ,YAAY,WAAW,IAAIxH,EAAM,QAAQ,IAAI,GAAG,CAAC,GAC9D,KAAK,QAAQ,YAAY,eAAe,MAAU4H,IAAQ,KAAK;EAGrE;CACF;CAEA,mBAA0B,GAAyB;EAGjD,AAFA,KAAK,KAAK,GACV,KAAK,SAAS,QAAQ,MAAUf,EAAW,SAASU,EAAM,SAAS,CAAC,CAAC,CAAC,SAAS,MAAUA,EAAM,SAAS,CAAC,GACzG,KAAK,WAAW,KAAK;CACvB;CAEA,UAAiB;EAEf,AADA,KAAK,iBAAiB,GACtB,KAAK,WAAW,SAAS,OAAO;CAClC;AACF,GAEMD,IAAN,cAAgCtH,EAAM,MAAM;CAC1C;CAEA;CAEA;CAEA;CAEA,YAAmB,GAAkD;EAUnE,AATA,MAAM,GACN,KAAK,YAAY6H,EAAQ,WAEzB,KAAK,SAAS,IAAIC,GAAOD,CAAO,GAChC,KAAK,OAAO,IAAIE,GAAWF,CAAO,GAClC,KAAK,cAAc,IAAIG,GAAYH,CAAO,GAE1C,KAAK,IAAI,KAAK,QAAQ,KAAK,MAAM,KAAK,WAAW,GAE7C,KAAK,cAAc,MAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAC/C,KAAK,cAAc,QAAK,KAAK,SAAS,IAAI,CAAC,KAAK,KAAK;CAChE;CAEA,aAAoB;EAElB,AADA,KAAK,IAAI,KAAK,MAAM,GACpB,KAAK,OAAO,KAAK,MAAM,KAAK,WAAW;CACzC;CAEA,WAAkB;EAEhB,AADA,KAAK,IAAI,KAAK,MAAM,KAAK,WAAW,GACpC,KAAK,OAAO,KAAK,MAAM;CACzB;CAEA,OAAc;EAEZ,KAAK,OAAO,KAAK,MAAM,KAAK,aAAa,KAAK,MAAM;CACtD;AACF,GAEMC,KAAN,cAAqB9H,EAAM,KAAK;CAC9B;CAEA,WAAkB;CAClB,WAAkB,IAAIA,EAAM,aAAa,KAAM,IAAK,IAAI,GAAG,KAAK,UAAU,KAAK,KAAK,IAAI,KAAK,WAAW,CAAC;CAEzG,YAAmB,GAAkD;EAYnE,AAXA,MAAM,GAEN,KAAK,WAAW,IAAIA,EAAM,kBAAkB;GAC1C,SAAS;GACT,aAAa;GACb,OAAO6H,EAAQ,SAAS;GACxB,MAAM7H,EAAM;GACZ,WAAW;EACb,CAAC,GACD,KAAK,YAAY6H,EAAQ,WACzB,KAAK,cAAc/E,EAAa,eAChC,KAAK,SAAS,OAAO,8BAA8B,KAAK;CAC1D;AACF,GAEMiF,KAAN,cAAyB/H,EAAM,MAAM;CACnC;CAEA,YAAmB,GAAmC;EAEpD,AADA,MAAM,GACN,KAAK,YAAY6H,EAAQ;EAEzB,IAAMF,IAAW,MAEXM,IAAa,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,GAAG,MAAM;GACnD,IAAMhG,IAAW,IAAIjC,EAAM,aAAa,KAAM,IAAK,IAAI,GAAI,KAAK,KAAK,IAAKkI,IAAIP,GAAU,KAAK,KAAK,IAAIA,IAAW,CAAC,GAC5GzF,IAAW,IAAIlC,EAAM,kBAAkB;IAC3C,SAAS;IACT,OAAO;IACP,WAAW;IACX,YAAY;IACZ,aAAa;IACb,MAAMA,EAAM;GACd,CAAC,GAEKmI,IAAO,IAAInI,EAAM,KAAKiC,GAAUC,CAAQ;GAE9C,OADA,EAAK,OAAO,kBAAkB,KAAK,UAAU,GAAGgG,KACzCC;EACT,CAAC;EAED,KAAK,IAAI,GAAGF,CAAM;CACpB;AACF,GAEMD,KAAN,cAA0BhI,EAAM,KAAK;CACnC;CACA;CACA,eAAiD,MAAU4H;CAC3D;CAGA,YAAmB,GAAkD;EAGnE,QAFA,MAAM,GAEEC,EAAQ,WAAhB;GACE,KAAK;IACH,KAAK,WAAW,IAAI7H,EAAM,QAAQ,GAAG,GAAG,CAAC;IACzC;GACF,KAAK;IACH,KAAK,WAAW,IAAIA,EAAM,QAAQ,GAAG,GAAG,CAAC;IACzC;GACF,KAAK,KACH,KAAK,WAAW,IAAIA,EAAM,QAAQ,GAAG,GAAG,CAAC;EAE7C;EAcA,AAXA,KAAK,WAAW,IAAIA,EAAM,eAAe,OAAO,IAAI,GAAG,IAAM,GAC7D,KAAK,WAAW,IAAIA,EAAM,kBAAkB;GAC1C,SAAS;GACT,OAAO6H,EAAQ,SAAS;GACxB,WAAW;GACX,YAAY;GACZ,aAAa;GACb,MAAM7H,EAAM;EACd,CAAC,GAED,KAAK,YAAY6H,EAAQ,WACzB,KAAK,iBAAiB,KAAK,cAAc,MAAM,IAAI;CACrD;CAKA,wBAA+B;EAC7B,KAAK,iBAAiB;CACxB;CAKA,+BAAsC;EACpC,KAAK,iBAAiB;CACxB;CAKA,kBAAyB;EACvB,KAAK,iBAAiB,KAAK,mBAAmB,IAAI,KAAK;CACzD;CAMA,YAAmB,GAAqB;EACtC,KAAK,WAAWO,EAAK,MAAM,CAAC,CAAC,UAAU;CACzC;CAMA,eAAwD;EACtD,OAAO,KAAK,mBAAmB,KAAK,cAAc;CACpD;AACF;;;AC7UA,SAAgBC,KAAoB;CAClC,IAAMC,IAAYxB,EAAc;EAC9B,OAAO;EACP,QAAQ;EACR,MAAM;EACN,KAAK;EACL,UAAU;EACV,eAAe;CACjB,CAAC,GACKyB,IAAUzB,EAAc;EAC5B,WAAW;EACX,OAAO;EACP,QAAQ;EACR,MAAM;EACN,KAAK;EACL,UAAU;EACV,SAAS;EACT,YAAY;EACZ,gBAAgB;CAClB,CAAC,GACK0B,IAAS1B,EAAc;EAC3B,WAAW;EACX,OAAO;EACP,QAAQ;EACR,MAAM;EACN,KAAK;EACL,UAAU;EACV,QAAQ;CACV,CAAC;CAOD,AADAwB,EAAU,YAAYC,CAAO,GAC7BA,EAAQ,YAAYC,CAAM;CAS1B,IAAM5H,IAAS,QACT6H,IAAkB;EAAE,WAAW;EAAQ,SAASC,EAAU;GAAE,QAAQ;GAAe,MAAM9H;GAAQ,QAAQA;EAAO,CAAC;CAAE,GACnH+H,IAAkB;EAAE,WAAW;EAAM,SAASD,EAAU;GAAE,QAAQ;GAAa,QAAQ9H;EAAO,CAAC;CAAE,GACjGgI,IAAkB;EAAE,WAAW;EAAQ,SAASF,EAAU;GAAE,QAAQ;GAAe,OAAO9H;GAAQ,QAAQA;EAAO,CAAC;CAAE,GACpHiI,IAAkB;EAAE,WAAW;EAAM,SAASH,EAAU;GAAE,QAAQ;GAAa,OAAO9H;EAAO,CAAC;CAAE,GAChGkI,IAAkB;EAAE,WAAW;EAAQ,SAASJ,EAAU;GAAE,QAAQ;GAAe,OAAO9H;GAAQ,KAAKA;EAAO,CAAC;CAAE,GACjHmI,IAAkB;EAAE,WAAW;EAAM,SAASL,EAAU;GAAE,QAAQ;GAAa,KAAK9H;EAAO,CAAC;CAAE,GAC9FoI,IAAkB;EAAE,WAAW;EAAQ,SAASN,EAAU;GAAE,QAAQ;GAAe,MAAM9H;GAAQ,KAAKA;EAAO,CAAC;CAAE,GAChHqI,IAAkB;EAAE,WAAW;EAAM,SAASP,EAAU;GAAE,QAAQ;GAAa,MAAM9H;EAAO,CAAC;CAAE;CAcrG,OAXA;EAAU+H;EAASE;EAASE;EAASE;EAASR;EAASG;EAASE;EAASE;CAAO,CAAC,CAAC,SAAS,MAAWT,EAAQ,YAAYW,EAAO,OAAO,CAAC,GAWlI;EAAE;EAAW,SAAA;GATlBT;GACAE;GACAC;GACAC;GACAC;GACAC;GACAC;GACAC;EAEkB;CAAQ;AAC9B;AAcA,SAASP,EAAU,GAAsC;CACvD,IAAMQ,IAASpC,EAAc;EAC3B,YAAY;EACZ,OAAO;EACP,QAAQ;EACR,UAAU;EACV,eAAe;EACf,cAAc;EACd,GAAGG;CACL,CAAC,GACKkC,IAAwBrC,EAAc;EAC1C,OAAO;EACP,QAAQ;EACR,UAAU;EACV,MAAM;EACN,KAAK;EACL,WAAW;EACX,eAAe;CACjB,CAAC,GACKsC,IAAiBtC,EAAc;EACnC,OAAO;EACP,QAAQ;EACR,QAAQG,GAAO;EACf,eAAe;EAEf,YAAY;CACd,CAAC;CAID,OAHA,EAAe,YAAY,IAC3BkC,EAAsB,YAAYC,CAAc,GAChDF,EAAO,YAAYC,CAAqB,GACjCD;AACT;;;ACrHA,IAAMG,oBAAM,IAAI,IAMd;AAEF,SAAgBC,EAAY,GAAsB;CAEhD,IAAID,EAAI,IAAIzG,CAAM,GAChB,OAAOyG,EAAI,IAAIzG,CAAM,CAAC,CAAC;CAGzB,IAAM0G,IAAc,IAAIvK,EAErB,GAECwK,IAAwC,MACxCC,GAEEC,UAAgB;EACpB,IAAyB,sBAAsBA,CAAO;EACtD,IAAMC,IAAgB9G,EAAO,iBAAiB,QAAQ,CAAC,CAAC,KAAK,GAAG,IAAIA,EAAO,YAAY,QAAQ,CAAC,CAAC,KAAK,GAAG;EACzG,AAAI8G,MAAkBF,MACpB,IAAaE,GACbJ,EAAY,KAAK,cAAc;CAEnC;CAcA,OAZAG,EAAQ,GAORJ,EAAI,IAAIzG,GAAQ;EACd,OAAO0G;EACP,eAPoB;GAEpB,AADAD,EAAI,OAAOzG,CAAM,GACjB,qBAAqB2G,CAAuB;EAC9C;CAKA,CAAC,GAEMD;AACT;;;ACnCA,IAAaK,KAAb,cAAmF9H,EAA6C;CAC9H,OAAc;CACd,SAAqF,CAAC;CACtF,kBAAoC,CAAC;CACrC;CACA,IAAW,eAAe;EACxB,IAAI,CAAC,KAAK,eAAe,aAAa,MAAU,MAAM,kCAAkC;EACxF,OAAO,KAAK,cAAc;CAC5B;CACA;CACA,gBAAwB,IAAIjC,EAAY;CACxC;CACA;CACA;CACA,UAAkB;CAClB;CAGA,YAAmB,GAAmB,GAAwB,GAAsB,GAAoB;EAKtG,AAJA,MAAMW,CAAc,GACpB,KAAK,SAASqC,GACd,KAAK,QAAQgH,GACb,KAAK,YAAYtB,GACjB,KAAK,yBAAyB;CAChC;CAEA,iBAA8B;EAC5B,KAAK,WAAW,KAAK,KAAK,eAAe,UAAU;CACrD;CAEA,aAAoB,GAAuB;EAIzC,AAHA,MAAM,aAAa/G,CAAM,GACzB,KAAK,aAAa,aAAaA,CAAM,GACrC,KAAK,OAAO,aAAaA,CAAM,GAC/B,KAAK,gBAAgB,SAAS,MAAmBsI,EAAe,aAAatI,CAAM,CAAC;CACtF;CAEA,qBAA4B,CAE5B;CAEA,wBAA+B,GAAuB,GAAkB;EAKtE,AAJA,KAAK,OAAO,MAAM,aAAaA,CAAM,GACrC,KAAK,aAAa,kBAAkBA,CAAM,GAG1C,iBAAiB;GACf,KAAK,uBAAuB;EAC9B,GAAG,CAAC;CACN;CAEA,eAAsB;EACpB,IAAMuI,IAAY,KAAK,uBAAuB,KAAK,eAAuD;EAC1G,KAAK,OAAO,SAAS,GAAO,MAAU;GACpC,EAAM,SAAS,KAAKA,EAAUC,EAAO;EACvC,CAAC;CACH;CAEA,OAAc,GAAsB;EAmBlC,AAjBI,KAAK,eAAe,eACtB,KAAK,aAAa,SAAS,KAAK,KAAK,eAAe,QAAQ,GAI1D,KAAK,SACP,KAAK,MAAM,SAAS,KAAK,KAAK,eAAe,QAAQ,GAIvD,KAAK,aAAa,GAGd,KAAK,iBACP,KAAK,cAAc,KAAK,GAGtB,KAAK,UACP,KAAK,MAAM,UAAU;CAEzB;CAEA,sBAA6B,GAA8B,GAAiB;EAC1E,IAAMC,IAAc,KAAK,eAAe;EAExC,IAAIA,GAAa;GACf,IAAM7J,IAAI,IAAIH,EAAM,QAAQ,CAAC,CAAC,WAAWgK,EAAY,UAAUxI,CAAM,CAAC,CAAC,gBAAgBnB,CAAU,CAAC,CAAC,IAAImB,CAAM;GAE7G,AADAwI,EAAY,SAAS,KAAK7J,CAAC,GAC3B6J,EAAY,gBAAgB3J,CAAU;EACxC;EAEA,IAAI,KAAK,OAAO;GACd,IAAMF,IAAI,IAAIH,EAAM,QAAQ,CAAC,CAAC,WAAW,KAAK,MAAM,UAAUwB,CAAM,CAAC,CAAC,gBAAgBnB,CAAU,CAAC,CAAC,IAAImB,CAAM;GAE5G,AADA,KAAK,MAAM,SAAS,KAAKrB,CAAC,GAC1B,KAAK,MAAM,gBAAgBE,CAAU;EACvC;EAEA,KAAK,gBAAgB,SAAS,MAAmB;GAC/C,IAAMF,IAAI,IAAIH,EAAM,QAAQ,CAAC,CAAC,WAAW6J,GAAgBrI,CAAM,CAAC,CAAC,gBAAgBnB,CAAU,CAAC,CAAC,IAAImB,CAAM;GACvG,EAAe,KAAKrB,CAAC;EACvB,CAAC;CACH;CAEA,SAAgB;EACd,AAAI,KAAK,YACT,KAAK,UAAU,IACf,KAAK,eAAe,OAAO,GACvB,KAAK,SAAO,KAAK,MAAM,IAAI,KAAK,KAAK;CAC3C;CAEA,UAAiB;EACf,AAAK,KAAK,YACV,KAAK,UAAU,IACf,KAAK,eAAe,QAAQ,GACxB,KAAK,SAAO,KAAK,MAAM,OAAO,KAAK,KAAK;CAC9C;CAEA,OAAc;EAEZ,AADA,KAAK,eAAe,KAAK,GACrB,KAAK,UAAO,KAAK,MAAM,UAAU;CACvC;CAEA,OAAc;EAEZ,AADA,KAAK,eAAe,KAAK,GACrB,KAAK,UAAO,KAAK,MAAM,UAAU;CACvC;CAEA,UAAiB;EAEf,AADA,KAAK,QAAQ,GACb,KAAK,cAAc,QAAQ;CAC7B;CAMA,aAAoB;EAElB,EAAY,KAAK,MAAM,CAAC,CAAC,KAAK,cAAc;CAC9C;CAEA,yBAAiC;EAC/B,IAAI,CAAC,KAAK,eAAe;EAGzB,AACE,KAAK,iBAAe;GAClB,GAAG,KAAK,eAAe,MAAM;GAC7B,GAAG,KAAK,eAAe,MAAM;EAC/B;EAIF,IAAM8J,IAAe,KAAK,eAAe,OACnCC,IAAiBD,EAAa,IAAI,KAAK,aAAa,GACpDE,IAAiBF,EAAa,IAAI,KAAK,aAAa,GAEpDG,IAAgB,KAAK,cAAc,YAAY;EAErD,AADAA,EAAc,MAAM,YAAY,mBAAmBF,EAAe,SAAS,CAAC,GAC5EE,EAAc,MAAM,YAAY,mBAAmBD,EAAe,SAAS,CAAC;CAC9E;CAEA,2BAAmC;EACjC,IAAME,IAAkB,KAAK,mBAAmB;EAEhD,IAAI,CAACA,GAAiB;EAEtB,KAAK,kBAAkBA;EAEvB,IAAMC,IAAgB,KAAK,cAAc,gBAAgB,KAAK,QAAQD,GAAiB,EAAE,OAAO,KAAM,CAAC;EAEvG,IAAI,CAACC,GAAe;EAGpB,AADA,KAAK,gBAAgBA,GACrBA,EAAc,gBAAgB,KAAK,SAAS;EAG5C,IAAMC,IAAqBD,EAAc,YAAY,WAC/C,EAAE,WAAWE,GAAK,eAAYnC,GAAkB;EAYtD,AAXA,KAAK,SAASoC,EAAQ,KAAK,GAAQ,OAAW;GAC5C,WAAWvB,EAAO;GAClB,OAAOA,EAAO;GACd,UAAU,KAAK,uBAAuBmB,CAAe,CAAC,CAACN;EACzD,EAAE,GAIFQ,EAAmB,aAAaC,GAAKD,EAAmB,SAAS,MAAM,IAAI,GAE3E,KAAK,aAAa,SAAS,KAAK,KAAK,eAAe,QAAQ,GAC5D,KAAK,OAAO,SAAS,KAAK,KAAK,eAAe,QAAQ;CACxD;CAEA,qBAA6B;EAC3B,IAAM,EAAE,sBAAmB;EAC3B,IAAKhK,EAAuB,iBAAkBA,EAAuB,cAEnE,OAAO9B,EAAE;EAET,QAAQ,MAAM,uBAAuB;CAEzC;CAEA,uBAA+B,GAA+E;EAQ5G,OAAO;GACL4L,EAAgB,EAAE,CAAC,MAAM;GACzBA,EAAgB,EAAE,CAAC,MAAM,CAAC,CAAC,IAAIA,EAAgB,EAAE,CAAC,CAAC,aAAa,CAAC;GACjEA,EAAgB,EAAE,CAAC,MAAM;GACzBA,EAAgB,EAAE,CAAC,MAAM,CAAC,CAAC,IAAIA,EAAgB,EAAE,CAAC,CAAC,aAAa,CAAC;GACjEA,EAAgB,EAAE,CAAC,MAAM;GACzBA,EAAgB,EAAE,CAAC,MAAM,CAAC,CAAC,IAAIA,EAAgB,EAAE,CAAC,CAAC,aAAa,CAAC;GACjEA,EAAgB,EAAE,CAAC,MAAM;GACzBA,EAAgB,EAAE,CAAC,MAAM,CAAC,CAAC,IAAIA,EAAgB,EAAE,CAAC,CAAC,aAAa,CAAC;EACnE;CACF;AACF,GCpOaK,KAAb,cAAkFhJ,EAA6B;CAC7G,OAAc;CACd;CACA;CACA;CAEA,YAAmB,GAAiB;EAQlC,AAPA,MAAMiJ,CAAY,GAElB,KAAK,oBAAoB,IAAI3K,EAAM,gCAAgB,IAAI,aAAa,EAAK,GAAG,CAAC,GAC7E,KAAK,MAAM,KAAK,UAAU,GAC1B,KAAK,UAAU,KAAK,cAAc,GAElC,KAAK,IAAI,KAAK,KAAK,KAAK,OAAO,GAC/B,KAAK,OAAO;CACd;CAEA,iBAA8B;EAC5B,KAAK,WAAW,KAAK,KAAK,eAAe,UAAU;CACrD;CAEA,oBAA2B,GAA8B,GAAwB;EAC/E,EAAoB,MAAMK,GAAYmB,CAAM;CAC9C;CAEA,yBAAgC,GAA4B,GAA0D;EACpH,OAAOf,EAAU,gBAAgB,MAAM,IAAOC,CAAY;CAC5D;CAEA,QAAe,GAA4B,GAAkC;EAE3E,KAAK,IAAI,QAAQD,GAAWmK,CAAU;CACxC;CAEA,SAAiB;EAgBf,IAAMC,IAAOlL,EAAY,KAAK,cAAc;EAC5C,IAAI,CAACkL,GAAM;EAEX,IAAM,EAAE,QAAK,WAAQA;EAWrB,AATA,KAAK,kBAAkB,OAAO,GAAG3F,EAAI,GAAGA,EAAI,GAAGA,EAAI,CAAC,GACpD,KAAK,kBAAkB,OAAO,GAAGF,EAAI,GAAGE,EAAI,GAAGA,EAAI,CAAC,GACpD,KAAK,kBAAkB,OAAO,GAAGF,EAAI,GAAGA,EAAI,GAAGE,EAAI,CAAC,GACpD,KAAK,kBAAkB,OAAO,GAAGA,EAAI,GAAGF,EAAI,GAAGE,EAAI,CAAC,GACpD,KAAK,kBAAkB,OAAO,GAAGA,EAAI,GAAGA,EAAI,GAAGF,EAAI,CAAC,GACpD,KAAK,kBAAkB,OAAO,GAAGA,EAAI,GAAGE,EAAI,GAAGF,EAAI,CAAC,GACpD,KAAK,kBAAkB,OAAO,GAAGA,EAAI,GAAGA,EAAI,GAAGA,EAAI,CAAC,GACpD,KAAK,kBAAkB,OAAO,GAAGE,EAAI,GAAGF,EAAI,GAAGA,EAAI,CAAC,GAEpD,KAAK,kBAAkB,cAAc;CACvC;CAEA,gBAAwB;EACtB,IAAM8F,IAAc,IAAI,YAAY;GAAC;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;EAAC,CAAC,GACtGC,IAAe,IAAI/K,EAAM,eAAe;EAE9C,AADA+K,EAAa,SAAS,IAAI/K,EAAM,gBAAgB8K,GAAa,CAAC,CAAC,GAC/DC,EAAa,aAAa,YAAY,KAAK,iBAAiB;EAC5D,IAAMC,IAAe,IAAIhL,EAAM,kBAAkB;GAC/C,OAAO;GACP,WAAW;GACX,SAAS;GACT,YAAY;EACd,CAAC,GACKiL,IAAe,IAAIjL,EAAM,aAAa+K,GAAcC,CAAY;EAEtE,OADA,EAAa,mBAAmB,IACzBC;CACT;CAEA,YAAoB;EAClB,IAAMC,IAAa,IAAI,YAAY;GACjC;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;EAC3G,CAAC,GACKC,IAAc,IAAInL,EAAM,eAAe;EAE7C,AADAmL,EAAY,SAAS,IAAInL,EAAM,gBAAgBkL,GAAY,CAAC,CAAC,GAC7DC,EAAY,aAAa,YAAY,KAAK,iBAAiB;EAC3D,IAAMC,IAAc,IAAIpL,EAAM,kBAAkB;GAC9C,OAAO;GACP,SAAS;GACT,WAAW;GACX,aAAa;EACf,CAAC;EAED,OAAO,IADSA,EAAM,KAAKmL,GAAaC,CACjC;CACT;AACF,GChFsBC,IAAtB,MAAmH;CACjH;CACA;CACA,yBAAgC;CAChC;CACA,YAA+C,CAAC;CAChD;CACA;CACA;CACA;CACA;CACA;CACA,aAAuB;CACvB,UAAoB;CACpB,OAAiB;CACjB;CACA;CACA;CACA;CAIA;CASA,uBAA8B,GAI3B;EACD,KAAK,mBAAmBC;CAC1B;CAKA,gBAAgC;EAC9B,OAAO,KAAK;CACd;CAEA,YACE,GAkBA,GACA;EAkBA,AAjBA,KAAK,QAAQC,EAAO,eAAe,IAAIxM,EAA0B,GACjE,KAAK,gBAAgBwM,EAAO,uBAAuB,IAAIxM,EAAkC,GACzF,KAAK,SAASwM,EAAO,QACrB,KAAK,QAAQA,EAAO,OACpB,KAAK,iBAAiBA,EAAO,gBAC7B,KAAK,iBAAiBA,EAAO,gBAC7B,KAAK,YAAYA,EAAO,WACxB,KAAK,QAAQA,EAAO,OACpB,KAAK,YAAYA,EAAO,WACxB,KAAK,WAAWA,EAAO,mBAAmB,CAAC,IAC3C,KAAK,SAAS/K,KAAU,CAAC,GACzB,KAAK,mBAAmB+K,EAAO,kBAC/B,KAAK,sBAAsB,GAC3B,KAAK,wBAAwB,GAC7B,KAAK,kBAAkB,GACvB,KAAK,cAAcjC,EAAY,KAAK,MAAM,GAE1C,KAAK,OAAO;EAEZ,IAAMkC,IAAuB,KAAK,uBAAuB,KAAK,IAAI,GAC5DC,IAAwB,KAAK,wBAAwB,KAAK,IAAI,GAC9DC,IAA0B,KAAK,0BAA0B,KAAK,IAAI,GAElEC,IAAyB,KAAK,yBAAyB,KAAK,IAAI,GAChEC,IAA0B,KAAK,0BAA0B,KAAK,IAAI,GAClEC,IAA4B,KAAK,4BAA4B,KAAK,IAAI,GACtEC,IAAwB,KAAK,sBAAsB,KAAK,IAAI;EAmBlE,AAjBA,KAAK,YAAY,GAAG,gBAAgB,KAAK,iBAAiB,GAE1D,KAAK,cAAc,GAAG,yBAAyBA,CAAqB,GAEpE,KAAK,cAAc,GAAG,kBAAkBN,CAAoB,GAC5D,KAAK,cAAc,GAAG,mBAAmBC,CAAqB,GAC9D,KAAK,cAAc,GAAG,qBAAqBC,CAAuB,GAElE,KAAK,cAAc,GAAG,uBAAuBG,CAAyB,GACtE,KAAK,cAAc,GAAG,qBAAqBD,CAAuB,GAClE,KAAK,cAAc,GAAG,oBAAoBD,CAAsB,GAGhE,KAAK,MAAM,GAAG,WAAW,KAAK,iBAAiB,GAC/C,KAAK,cAAc,GAAG,qBAAqB,KAAK,iBAAiB,GACjE,KAAK,cAAc,GAAG,yBAAyB,KAAK,iBAAiB,GAErE,KAAK,UAAU,WAAW;GAexB,AAdA,KAAK,YAAY,IAAI,gBAAgB,KAAK,iBAAiB,GAE3D,KAAK,cAAc,IAAI,yBAAyBG,CAAqB,GAErE,KAAK,cAAc,IAAI,kBAAkBN,CAAoB,GAC7D,KAAK,cAAc,IAAI,mBAAmBC,CAAqB,GAC/D,KAAK,cAAc,IAAI,qBAAqBC,CAAuB,GAEnE,KAAK,cAAc,IAAI,uBAAuBG,CAAyB,GACvE,KAAK,cAAc,IAAI,qBAAqBD,CAAuB,GACnE,KAAK,cAAc,IAAI,oBAAoBD,CAAsB,GAEjE,KAAK,MAAM,IAAI,WAAW,KAAK,iBAAiB,GAChD,KAAK,cAAc,IAAI,qBAAqB,KAAK,iBAAiB,GAClE,KAAK,cAAc,IAAI,yBAAyB,KAAK,iBAAiB;EACxE,CAAC;CACH;CAEA,wBAA+B;EAC7B,KAAK,eAAe,gBAAgB,KAAK,gBAAgB,KAAK,OAAO,MAAM,CAAC;CAC9E;CAEA,0BAAiC;EAC/B,KAAK,eAAe,eAAe,KAAK,MAAM;CAChD;CAEA,SAAgB;EACd,AAAI,KAAK,YACT,KAAK,UAAU,IACf,KAAK,MAAM,IAAI,KAAK,cAAc,GAClC,KAAK,eAAe,OAAO,GAC3B,KAAK,OAAO;CACd;CAEA,UAAiB;EACf,AAAK,KAAK,YACV,KAAK,UAAU,IACf,KAAK,eAAe,QAAQ,GAC5B,KAAK,OAAO;CACd;CAEA,OAAc;EAEZ,AADA,KAAK,eAAe,KAAK,GACzB,KAAK,OAAO;CACd;CAEA,OAAc;EAEZ,AADA,KAAK,eAAe,KAAK,GACzB,KAAK,OAAO;CACd;CAEA,UAAiB;EAGf,AAFA,KAAK,WAAW,SAAS,MAAMI,IAAI,CAAC,GACpC,KAAK,eAAe,QAAQ,GAC5B,KAAK,OAAO;CACd;CAMA,mBAA0B,GAAuB;EAC/C,KAAK,eAAe,aAAaxK,CAAM;CACzC;CAOA,sBAA6B,GAA8B,GAAuB;EAChF,KAAK,eAAe,sBAAsBlB,GAAYmB,CAAM;CAC9D;CAOA,wBAA+B,GAAuB,GAAwB;EAC5E,KAAK,eAAe,wBAAwBD,GAAQC,CAAM;CAC5D;CAEA,qBAA4B,MAA6C;EAEvE,IADuB,KAAK,mBAAmBf,CAC3C,GAAgB,OAAO;CAE7B;CAEA,0BAAiC;EAK/B,AAHI,YAAY,KAAK,kBAAkB,OAAO,KAAK,eAAe,UAAW,cAC3E,KAAK,eAAe,OAAO,KAAK,MAAM,GAExC,KAAK,eAAe,iBAAiB,KAAK,MAAa;CACzD;CAEA,eAAsB,GAAgC,GAAsC,GAA8B;EACxH,IAAI,KAAK,YAAY,OAAO;CAC9B;CAEA,4BAAmC,GAAkC,CAAC;CAOtE,yBAAmC,GAA2D;EAC5F,KAAK,wBAAwB8K,EAAO,QAAQA,EAAO,MAAM;CAC3D;CAOA,0BAAoC,GAAiE;EACnG,KAAK,sBAAsBA,EAAO,YAAYA,EAAO,MAAM;CAC7D;CAMA,4BAAsC,GAAmC;EACvE,KAAK,mBAAmBA,EAAO,MAAM;CACvC;CAEA,uBAAiC,GAAsB;EAErD,AADA,KAAK,eAAe,MAAM,KAAKxG,CAAK,GACpC,KAAK,oBAAoBA,CAAK;CAChC;CAEA,wBAAkC,GAA8B,GAAuB;EACrF,KAAK,eAAe,oBAAoB1E,GAAYmB,CAAM;CAC5D;CAEA,0BAAoC,GAAyB;EAC3D,KAAK,eAAe,SAAS,KAAKiD,EAAS,MAAM,CAAC,CAAC,IAAI,KAAK,gBAAgB,KAAK,OAAO,MAAM,CAAC,CAAC;CAClG;CAEA,SAAmB;EACjB,KAAK,SAAS;CAChB;CAEA,oBAA8B,GAAsB;EAClD,IAAI,KAAK,eAAe,KAAK,OAAO,QAAQ;GAC1C,IAAMjD,IAAS,KAAK,eAAe,UAC7B0D,IAAM,IAAIlF,EAAM,QAAQ,CAAC,CAAC,WAAW,KAAK,YAAY,KAAKwB,CAAM,CAAC,CAAC,SAASuD,CAAK,CAAC,CAAC,IAAIvD,CAAM,GAC7FwD,IAAM,IAAIhF,EAAM,QAAQ,CAAC,CAAC,WAAW,KAAK,YAAY,KAAKwB,CAAM,CAAC,CAAC,SAASuD,CAAK,CAAC,CAAC,IAAIvD,CAAM,GAC7FZ,IAAS,KAAK,gBAAgB,KAAK,OAAO,QAAQ;IAAE;IAAK;GAAI,CAAC;GACpE,KAAK,eAAe,gBAAgBA,CAAM;EAC5C;CACF;CAEA,cACE,GACA,IAA4C,UAC5C,IAAe,GACH;EACZ,IAAMoL,IAAU9M,EAAQ+M,CAAQ,CAAC,CAAC,OAAO3M,CAAM,GACzC4M,IAA4B,CAAC;EACnC,KAAK,IAAM9L,KAAU4L,GACnB,IAAK5L,EAAe,YAAYA,aAAkBJ,EAAM,OAAO;GAC7D,IAAMiI,IACJ7H,aAAkBJ,EAAM,QACnBI,EAAO,SAAS,QAAQ,MAAUmH,aAAiBvH,EAAM,IAAI,IAC7D,CAACI,CAAM;GAEd,EAAO,SAAS,MAAS;IAEvB,AAAI,MAAM,QAAQ+H,EAAK,QAAQ,KAC5B,EAAcgE,oBAAwBhE,EAAagE,qBAAwBhE,EAAK,SAAS,KAAK,MAAQiE,EAAI,MAAM,MAAM,CAAC,GACvH,EAAcC,sBAA0BlE,EAAakE,uBAA0BlE,EAAK,SAAS,KAAK,MAAQiE,EAAI,OAAO,MAErH,EAAcD,oBAAwBhE,EAAagE,qBAAwBhE,EAAK,SAAS,MAAM,MAAM,GACrG,EAAckE,sBAA0BlE,EAAakE,uBAA0BlE,EAAK,SAAS;GAElG,CAAC;GAED,IAAMmE,UAAsB;IAoB1B,AAnBArE,EAAO,SAAS,MAAS;KACvB,AAAIE,EAAK,SAAS,gCACZA,EAAK,SAAS,OAChBA,EAAK,SAAS,EAAE,CAAC,SAAS,MAAM,IAAIoE,CAAU,GAC9C,EAAK,SAAS,EAAE,CAAC,SAAS,UAAUC,KAIlC,MAAM,QAAQrE,EAAK,QAAQ,IAC7BA,EAAK,SAAS,SAAS,MAAQ;MAE7B,AADAiE,EAAI,MAAM,IAAIG,CAAU,GACxB,EAAI,UAAUC;KAChB,CAAC,KAEDrE,EAAK,SAAS,MAAM,IAAIoE,CAAU,GAClC,EAAK,SAAS,UAAUC;IAG9B,CAAC,GACD,KAAK,OAAO;GACd,GACMC,UAAmB;IA0BvB,AAzBAxE,EAAO,SAAS,MAAS;KACvB,IAAIE,EAAK,SAAS,+BACZ,AAAAA,EAAK,SAAS,OAChBA,EAAK,SAAS,EAAE,CAAC,SAAS,MAAM,IAAI,QAAQ,GAC5C,EAAK,SAAS,EAAE,CAAC,SAAS,UAAU;UAItC,IAAI,MAAM,QAAQA,EAAK,QAAQ,GAAG;MAChC,IAAMuE,IAAkBvE,EAAagE,mBAC/BQ,IAAqBxE,EAAakE;MACxC,EAAK,SAAS,SAAS,GAAK,MAAU;OAIpC,AAHIK,KAAkBA,EAAe3C,MACnCqC,EAAI,MAAM,KAAKM,EAAe3C,EAAM,GAElC4C,KAAqBA,EAAkB5C,OAAW,KAAA,MACpD,EAAI,UAAU4C,EAAkB5C;MAEpC,CAAC;KACH,OAEE,AADA5B,EAAK,SAAS,MAAM,KAAMA,EAAagE,iBAAoB,GAC3D,EAAK,SAAS,UAAWhE,EAAakE;IAG5C,CAAC,GACD,KAAK,OAAO;GACd,GAEMO,KAAmB,MAAM;IAC7B,AAAI,KAAK,cACTN,EAAc;GAChB,GACMO,KAAkB,MAAM;IAC5B,AAAI,KAAK,cACTJ,EAAW;GACb;GAEA,KAAK,IAAMtE,KAAQF,GAOjB,AANA,KAAK,UAAU,iBAAiBE,GAAM,aAAayE,CAAe,GAClE,KAAK,UAAU,iBAAiBzE,GAAM,YAAY0E,CAAc,GAChE,KAAK,MAAM,GAAG,aAAaP,CAAa,GACxC,KAAK,MAAM,GAAG,WAAWG,CAAU,GACnC,KAAK,MAAM,GAAG,aAAaA,CAAU,GACrC,KAAK,MAAM,GAAG,YAAYA,CAAU,GACpCP,EAAU,WAAW;IAMnB,AALA,KAAK,UAAU,oBAAoB/D,GAAM,aAAayE,CAAe,GACrE,KAAK,UAAU,oBAAoBzE,GAAM,YAAY0E,CAAc,GACnE,KAAK,MAAM,IAAI,aAAaP,CAAa,GACzC,KAAK,MAAM,IAAI,WAAWG,CAAU,GACpC,KAAK,MAAM,IAAI,aAAaA,CAAU,GACtC,KAAK,MAAM,IAAI,YAAYA,CAAU;GACvC,CAAC;EAEL;EAEF,aAAaP,EAAU,SAAS,MAAaY,IAAW,CAAC;CAC3D;CAEA,mBAA2B,GAA4B;EACrD,IAAMC,IAAiB,KAAK,OAAO,UAC7B3M,IAAS,KAAK;EAEpB,IAAI,CAACA,GAAQ;EAIb,IAAMM,IAAe,KAAK,eAAe,yBAAyBD,CAAS,CAAC,CAAC;EAC7E,IAAI,CAACC,GAAc;EACnB,IAAMsM,IAAqBtM;EAI3B,IAHA,EAAmB,SAASN,GAGvB,KAAK,MAAc6M,oBAAuB;GAC7C,IAAMC,IAAqB,KAAK,MAAc,mBAAmBzM,CAAS,CAAC,CAAC;GAC5E,IAAIyM,KAAqBA,EAAkB,MAAM,WAAWH,CAAc,IAAIC,EAAmB,MAAM,WAAWD,CAAc,GAC9H;EACJ;EAEA,OAAOC,EAAmB;CAC5B;CAEA,gBACM,AAEF,KAAK,gBAAcrN,EAAY,KAAK,cAAc,GAC3C,KAAK;CAIhB,gBAAwB,GAAuB,GAAuD;EACpG,IAAMwN,IAAS,IAAInN,EAAM,QAAQ,GAAG,GAAG,CAAC;EAExC,IAAI,CAACY,GAAQ,OAAOuM;EAEpB,IAAMC,UACAvC,KACG,KAAK,OAAO;EAIrB,IAAI,OAAOjK,EAAO,KAAM,UAAU,EAAO,KAAKA,EAAO,CAAC;OACjD,IAAI,OAAOA,EAAO,KAAM,UAAU;GACrC,IAAMyM,IAAMD,EAAO;GACnB,EAAO,MAAMC,EAAI,IAAI,IAAIA,EAAI,IAAI,KAAKzM,EAAO,EAAE,QAAQ;EACzD;EAGA,IAAI,OAAOA,EAAO,KAAM,UAAU,EAAO,KAAKA,EAAO,CAAC;OACjD,IAAI,OAAOA,EAAO,KAAM,UAAU;GACrC,IAAMyM,IAAMD,EAAO;GACnB,EAAO,MAAMC,EAAI,IAAI,IAAIA,EAAI,IAAI,KAAKzM,EAAO,EAAE,QAAQ;EACzD;EAGA,IAAI,OAAOA,EAAO,KAAM,UAAU,EAAO,KAAKA,EAAO,CAAC;OACjD,IAAI,OAAOA,EAAO,KAAM,UAAU;GACrC,IAAMyM,IAAMD,EAAO;GACnB,EAAO,MAAMC,EAAI,IAAI,IAAIA,EAAI,IAAI,KAAKzM,EAAO,EAAE,QAAQ;EACzD;EAEA,OAAOuM;CACT;AACF;;;AC9aA,SAAgBG,GAAmB,GAAsB,GAAuB;CAC9E,IAAIC,IAAY,IACZC,IAAa,IAEXC,IAAS7K,EAAe,qBACxB8K,IAAS9K,EAAe;CAC9B,IAAI6K,GAAO;EACT,IAAME,IAAM/K,GACN4B,IAAWmJ,EAAI,SAAS,WAAWC,CAAM,GACzCC,IAAQF,EAAI,MAAM,KAAK,KAAM;EAEnC,AADA,IAAa,IAAI,KAAK,IAAIE,IAAO,CAAC,IAAIrJ,GACtC,IAAYgJ,IAAaG,EAAI;CAC/B,OAAO,IAAID,GAAO;EAChB,IAAMC,IAAM/K;EAEZ,AADA,IAAY,KAAK,IAAI+K,EAAI,QAAQA,EAAI,IAAI,GACzC,IAAa,KAAK,IAAIA,EAAI,MAAMA,EAAI,MAAM;CAC5C;CAEA,IAAMG,IAAO,KAAK,KAAKP,IAAYA,IAAYC,IAAaA,CAAU,GAChEO,IAAaD,IAAO,IACpBE,IAAS,KAAK,IAAIT,GAAWC,CAAU,IAAI,KAC3CS,IAASH,IAAO;CAEtB,OADe,KAAK,IAAIE,GAAQ,KAAK,IAAID,GAAYE,CAAM,CACpD;AACT;AAOA,IAAaC,IAAb,MAA4B;CAC1B;CACA;CACA;CAEA,YAAmB,GAAsB,GAA2C,GAA8B;EAGhH,AAFA,KAAK,SAAStL,GACd,KAAK,YAAY0F,GACjB,KAAK,WAAW,EAAE,GAAI6F,KAAY,CAAC,EAAG;CACxC;CAGA,gBAAuB,GAAuB,GAA0B,GAA6B;EACnG,IAAMC,IAAS;GAAE,OAAO;GAAU,aAAatL,EAAa;GAAiB,GAAG,KAAK;GAAU,GAAI+E,KAAW,CAAC;EAAG,GAC5GwG,IAAMtM,EAAU,MAAM,CAAC,CAAC,UAAU,GAGlCuM,IAAS,KAAK,0BAA0BV,CAAM,GAC9CW,IAAQX,EAAO,MAAM,CAAC,CAAC,IAAIS,EAAI,MAAM,CAAC,CAAC,eAAe,CAACC,CAAM,CAAC,GAC9DE,IAAMZ,EAAO,MAAM,CAAC,CAAC,IAAIS,EAAI,MAAM,CAAC,CAAC,eAAeC,CAAM,CAAC,GAE3DG,IAAY,IAAI,aAAa;GAACF,EAAM;GAAGA,EAAM;GAAGA,EAAM;GAAGC,EAAI;GAAGA,EAAI;GAAGA,EAAI;EAAC,CAAC,GAE7EvM,IAAW,IAAIjC,EAAM,eAAe;EAC1C,EAAS,aAAa,YAAY,IAAIA,EAAM,gBAAgByO,GAAW,CAAC,CAAC;EAEzE,IAAMvM,IAAW,IAAIlC,EAAM,kBAAkB;GAC3C,OAAOoO,EAAO;GACd,WAAW;GACX,YAAY;GACZ,aAAa;GACb,SAAS;EACX,CAAC,GAEKM,IAAO,IAAI1O,EAAM,KAAKiC,GAAUC,CAAQ;EAE9C,OADA,EAAK,cAAckM,EAAO,aACnBM;CACT;CAGA,gBACE,GACA,GACA,GACA,GACA;EACA,IAAML,IAAMtM,EAAU,MAAM,CAAC,CAAC,UAAU,GAGlCuM,IAAS,KAAK,0BAA0BV,CAAM,GAC9CW,IAAQX,EAAO,MAAM,CAAC,CAAC,IAAIS,EAAI,MAAM,CAAC,CAAC,eAAe,CAACC,CAAM,CAAC,GAC9DE,IAAMZ,EAAO,MAAM,CAAC,CAAC,IAAIS,EAAI,MAAM,CAAC,CAAC,eAAeC,CAAM,CAAC,GAE3DG,IAAY,IAAI,aAAa;GAACF,EAAM;GAAGA,EAAM;GAAGA,EAAM;GAAGC,EAAI;GAAGA,EAAI;GAAGA,EAAI;EAAC,CAAC,GAE7EvM,IAAWyM,EAAK,UAChBC,IAAO1M,EAAS,aAAa,UAAU;EAS7C,AARI0M,KAAQA,EAAK,aAAa,KAAKA,EAAK,MAAM,WAAWF,EAAU,UAChEE,EAAM,MAAuB,IAAIF,CAAS,GAC3C,EAAK,cAAc,MAEnBxM,EAAS,aAAa,YAAY,IAAIjC,EAAM,gBAAgByO,GAAW,CAAC,CAAC,GAIvE5G,GAAS,UAAU,KAAA,KACrB6G,EAAK,SAAS,MAAM,OAAO7G,EAAQ,KAAK;CAE5C;CAGA,0BAAkC,GAA+B;EAG/D,OAFmByF,GAAmB,KAAK,QAAQM,CAE5C,IAAa;CACtB;CAGA,QACE,GACA;EACA,IAAI,CAACc,GAAM;EACX,EAAK,SAAS,QAAQ;EACtB,IAAMxM,IAAWwM,EAAK;EACtB,AAAI,MAAM,QAAQxM,CAAQ,IAAGA,EAAS,SAAS,MAAM0M,EAAE,QAAQ,CAAC,IAC3D1M,EAAS,QAAQ;CACxB;CAGA,eAAsB,GAA4B;EAChD,KAAK,WAAW;GAAE,GAAG,KAAK;GAAU,GAAG2F;EAAQ;CACjD;AACF,GCpIagH,KAAb,cAAuFxD,EAAkB;CACvG,IAAW,oBAAoB;EAC7B,OAAO,KAAK,aAAa;CAC3B;CAEA,OAAiB;CAEjB;CAcA;CACA,aAAqB,IAAI6C,EAAe,KAAK,QAAQ,KAAK,WAAW,KAAK,QAAQ,cAAc,CAAC,CAAC;CAElG,eAGI,EACF,SAAS,GACX;CAEA;CAMA;CAEA,YAAmB,GAAG3C,GAAyD;EAC7E,MAAM,GAAGA,CAAM;EAGf,IAAMuD,IAAS,KAAK;EAIpB,IAHA,KAAK,cAAc;GAACA,EAAO;GAAQA,EAAO;GAAQA,EAAO;EAAM,CAAC,GAG5DA,EAAO,gBAAgBA,EAAO,wBAAwBzL,GAAc;GACtE,IAAM0L,IAAeD,EAAO,cACtBE,IAAmBD,EAAa;GAsBtC,AADA,KAAK,UAAU,iBAAiBC,GAAkB,mBAlBpB;IAC5B,AAAI,KAAK,eAEL,MAAM,QAAQA,EAAiB,QAAQ,KACzCA,EAAiB,SAAS,SAAS,MAAQ;KACzC,EAAI,MAAM,IAAI,QAAU;IAC1B,CAAC,GAEH,KAAK,OAAO;GACd,CAS8E,GAC9E,KAAK,UAAU,iBAAiBA,GAAkB,kBARrB;IAC3B,AAAI,KAAK,eAETD,EAAa,OAAO,KAAK,MAAM,GAC/B,KAAK,OAAO;GACd,CAG4E;EAC9E;EAEA,IAAM3H,IAAO,KAAK,KAAK,KAAK,IAAI,GAC1B6H,IAAO,KAAK,KAAK,KAAK,IAAI,GAE1BC,UAA6B;GAIjC,AAHA,KAAK,eAAe,OAAO,KAAK,MAAM,GAElC,KAAK,cAAY,KAAK,yBAAyB,GACnD,KAAK,OAAO;EACd;EA4CA,AA1CAA,EAAqB,GAGrB,KAAK,UAAU,iBAAiB,KAAK,gBAAgB,aAAa,KAAK,SAAS,GAChF,SAAS,iBAAiB,aAAa,KAAK,QAAQ,GACpD,SAAS,iBAAiB,WAAW,KAAK,OAAO,GAEjD,KAAK,UAAU,iBAAiB,KAAK,gBAAgB,cAAc,KAAK,SAAS,GACjF,SAAS,iBAAiB,aAAa,KAAK,QAAQ,GACpD,SAAS,iBAAiB,YAAY,KAAK,OAAO,GAElD,KAAK,MAAM,GAAG,eAAeD,CAAI,GACjC,KAAK,MAAM,GAAG,aAAa7H,CAAI,GAC/B,KAAK,MAAM,GAAG,cAAc6H,CAAI,GAChC,KAAK,MAAM,GAAG,YAAY7H,CAAI,GAC9B,KAAK,MAAM,GAAG,qBAAqB6H,CAAI,GACvC,KAAK,MAAM,GAAG,sBAAsB7H,CAAI,GACxC,KAAK,MAAM,GAAG,uBAAuB,MAAW;GAE9C,AADA,KAAK,eAAe,OAAOmE,EAAO,MAAM,GACxC,KAAK,OAAO;EACd,CAAC,GACD,KAAK,YAAY,GAAG,gBAAgB2D,CAAoB,GAExD,KAAK,UAAU,WAAW;GAgBxB,AAfA,KAAK,UAAU,oBAAoB,KAAK,gBAAgB,aAAa,KAAK,SAAS,GACnF,SAAS,oBAAoB,aAAa,KAAK,QAAQ,GACvD,SAAS,oBAAoB,WAAW,KAAK,OAAO,GAEpD,KAAK,UAAU,oBAAoB,KAAK,gBAAgB,cAAc,KAAK,SAAS,GACpF,SAAS,oBAAoB,aAAa,KAAK,QAAQ,GACvD,SAAS,oBAAoB,YAAY,KAAK,OAAO,GAErD,KAAK,MAAM,IAAI,eAAeD,CAAI,GAClC,KAAK,MAAM,IAAI,aAAa7H,CAAI,GAChC,KAAK,MAAM,IAAI,cAAc6H,CAAI,GACjC,KAAK,MAAM,IAAI,YAAY7H,CAAI,GAC/B,KAAK,MAAM,IAAI,qBAAqB6H,CAAI,GACxC,KAAK,MAAM,IAAI,sBAAsB7H,CAAI,GACzC,KAAK,MAAM,IAAI,oBAAoB,GACnC,KAAK,YAAY,IAAI,gBAAgB8H,CAAoB;EAC3D,CAAC,GAEG,KAAK,qBAAmB,KAAK,YAAY;CAC/C;CAEA,UAAuB;EAErB,AADA,MAAM,QAAQ,GACd,KAAK,WAAW,SAAS,MAAMnD,IAAI,CAAC;CACtC;CASA,YAAmB,GAAoD;EAErE,AADA,KAAK,eAAe;GAAE,SAAS;GAAM,eAAeR,GAAQ;EAAc,GAC1E,KAAK,yBAAyB;EAE9B,IAAM4D,IAAoB,KAAK,gBAAgB,KAAK,IAAI,GAClDC,IAAkB,KAAK,cAAc,KAAK,IAAI;EAOpD,AANA,KAAK,MAAM,KAAK,mBAAmB,GACnC,iBAAiB;GAEf,AADA,KAAK,UAAU,iBAAiB,aAAaD,CAAiB,GAC9D,KAAK,UAAU,iBAAiB,WAAWC,CAAe;EAC5D,CAAC,GAED,KAAK,uCAAuC;GAE1C,AADA,KAAK,UAAU,oBAAoB,aAAaD,CAAiB,GACjE,KAAK,UAAU,oBAAoB,WAAWC,CAAe;EAC/D;CACF;CAKA,qBAA4B;EAK1B,AAJA,KAAK,eAAe,EAAE,SAAS,GAAM,GACrC,KAAK,yBAAyB,IAE9B,KAAK,MAAM,KAAK,oBAAoB,GACpC,KAAK,iCAAiC;CACxC;CAEA,4BAAmC,GAAkC;EACnE,IAAI,CAAC,KAAK,mBAAmB;EAC7B,IAAM,EAAE,UAAO,YAAS1O;EAExB,IADiB,MAAK,MAAM,KAAK,cAAc2O,CAC3C,GACJ;GACA,IADA,KAAK,eAAe,SAAS,KAAKA,CAAK,IAErC,KAAK,aAAa,kBAAkB,MACnC,OAAO,KAAK,aAAa,iBAAkB,YAAY,KAAK,aAAa,cAAc,WAAW,OAE/FC,GAAM,QAAQ;IAChB,IAAMC,IACA,OAAO,KAAK,aAAa,iBAAkB,YAAY,KAAK,aAAa,cAAc,kBAClF,KAAK,aAAa,cAAc,kBAElC;KAAE,GAAG;KAAG,GAAG;KAAG,GAAG;IAAE,GAEtBC,IAAmB,IAAIxP,EAAM,QAAQuP,EAAU,KAAK,GAAGA,EAAU,KAAK,GAAGA,EAAU,KAAK,CAAC,GAEzFE,IACA,OAAO,KAAK,aAAa,iBAAkB,YAAY,KAAK,aAAa,cAAc,kBAClF,KAAK,aAAa,cAAc,gBAAgBH,EAAK,MAAM,IAE7DA,EAAK;IAId,AADA,KAAK,eAAe,WAAW,mBAAmBE,GAAkBC,CAAU,GAC9E,KAAK,cAAc,KAAK,mBAAmB,KAAK,eAAe,WAAW,MAAM,CAAC;GACnF;GAGF,AADA,KAAK,cAAc,KAAK,qBAAqBJ,CAAK,GAClD,KAAK,MAAM,KAAK,QAAQA,CAAK;EA1BU;CA2BzC;CAEA,gBAAwB,GAAmB;EACzC,IAAM,EAAE,MAAG,SAAMK;EACjB,KAAK,YAAY;GAAE;GAAG;GAAG,oBAAoB,KAAK,IAAI;EAAE;CAC1D;CAEA,cAAsB,GAAmB;EACvC,IAAI,CAAC,KAAK,WAAW;EACrB,IAAM,EAAE,MAAG,SAAMA;EACjB,AAAI,KAAK,UAAU,MAAMC,KAAK,KAAK,UAAU,MAAMC,KAAK,KAAK,IAAI,IAAI,KAAK,UAAU,qBAAqB,QACvG,KAAK,mBAAmB,GACxB,KAAK,YAAY,KAAA;CAErB;CAKA,aAAqB,MAA8C;EAEjE,IADI,KAAK,qBACL,KAAK,YAAY;EAErB,IAAMC,IAAYtE,GAAQ;EAE1B,IAAI,CAACsE,GAAW,OAAO,KAAK,QAAQ;EAEpC,IAAMC,KAAqBD,GAAW,OAAA,CAAe;EAErD,IAAI,CAACC,GAAmB,OAAO,KAAK,QAAQ;EAE5C,IAAMC,IAAa,IAAI/P,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB,KAAK,eAAe,UAAU,GACtFgQ,IAAa,IAAIhQ,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB,KAAK,eAAe,UAAU,GACtFiQ,IAAa,IAAIjQ,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB,KAAK,eAAe,UAAU,GAEtFkQ,WAAyB;GAC7B,QAAQJ,GAAR;IACE,KAAK,KACH,OAAOC;IACT,KAAK,KACH,OAAOC;IACT,KAAK,KACH,OAAOC;IACT,KAAK,SACH;GACJ;EACF,EAAA,CAAG,GAEGE,IAAiBN,EAAU,MAAM,MAAM;EAE7C,IAAIC,MAAsB,SAAS;GAEjC,IAAM/C,IAAiB,KAAK,OAAO,SAAS,MAAM,GAC5CqD,IAAaD,EAAe,MAAM,GAGlCE,IAAgBD,EAAW,MAAM,CAAC,CAAC,IAAIrD,CAAc,CAAC,CAAC,UAAU,GAGjEuD,IAAQ,IAAItQ,EAAM,MAAM,CAAC,CAAC,8BAA8BqQ,GAAeD,CAAU,GAGjFG,IAAeH,EAAW,MAAM;GAEtC,KAAK,YAAY;IACf;IACA,oBAAoBG;IACpB,MAAM,IAAIvQ,EAAM,MAAMuQ,EAAa,MAAM,GAAGA,EAAa,MAAM,CAAC;IAEzD;GACT;EAEF,OAAO;GAEL,IAAM7B,IAAO,IAAI1O,EAAM,MACrBmQ,EAAe,MAAM,CAAC,CAAC,IAAID,EAAgB,UAAU,CAAC,GACtDC,EAAe,MAAM,CAAC,CAAC,IAAID,EAAgB,UAAU,CAAC,CACxD;GACA,KAAK,YAAY;IAAE;IAAmB,oBAAoBC;IAAgB;GAAK;GAE/E,IAAI;IACF,IAAMK,IAAgBN,EAAgB,MAAM,CAAC,CAAC,UAAU,GAClDtC,IAAS,KAAK,eAAe,iBAAiB,IAAI5N,EAAM,QAAQ,CAAC,GAGjE0O,IAAO,KAAK,WAAW,gBAAgBd,GAAQ4C,GAAe;KAAE,OAAO;KAAU,aAAa1N,EAAa;IAAgB,CAAC;IAElI,AADA,KAAK,MAAM,IAAI4L,CAAI,GACnB,KAAK,gBAAgBA;GACvB,QAAQ,CAAC;EACX;EAGA,IAAM+B,IAAmBX,MAAsB,UAAU,CAAC,IAAI,CAACA,CAAiB;EAGhF,AAFA,KAAK,eAAe,mBAAmBW,CAAgB,GACvD,KAAK,MAAM,KAAK,aAAaX,CAAiB,GAC9C,KAAK,aAAa;CAEpB;CAEA,YAAoB,MAA+D;EAEjF,IADI,CAAC,KAAK,cACN,CAAC,KAAK,WAAW;EAErB,IAAMH,IAAI,aAAaN,IAAQA,EAAM,QAAQ,EAAE,CAAC,UAAUA,EAAM,GAC1DO,IAAI,aAAaP,IAAQA,EAAM,QAAQ,EAAE,CAAC,UAAUA,EAAM,GAE1DqB,IAAMhO,EAAkB,KAAK,QAAQ;GAAE;GAAG;EAAE,GAAG,KAAK,SAAS;EAMnE,OALKgO,KAGL,KAAK,KAAKA,CAAG,GAEN,MALU,KAAK,QAAQ;CAMhC;CAKA,2BAAmC;EACjC,IAAI,CAAC,KAAK,iBAAiB,CAAC,KAAK,WAAW;EAC5C,IAAM,EAAE,YAAS,KAAK,WAEhBF,IAAgB9B,EAAK,IAAI,MAAM,CAAC,CAAC,IAAIA,EAAK,KAAK,CAAC,CAAC,UAAU;EACjE,IAAI8B,EAAc,SAAS,IAAI,MAAM;EACrC,IAAM5C,IAAS,KAAK,eAAe,iBAAiB,IAAI5N,EAAM,QAAQ,CAAC;EACvE,KAAK,WAAW,gBAAgB,KAAK,eAAe4N,GAAQ4C,CAAa;CAC3E;CAEA,KAAa,GAA4B;EACvC,IAAI,CAAC,KAAK,WAAW,OAAO,KAAK,QAAQ;EAEzC,IAAM,EAAE,SAAM,0BAAuB,KAAK,WACpCpQ,IAAS,KAAK,gBAGduQ,IAAU,KAAK,UAAU,sBAAsB,SACjDC;EAEJ,IAAID,GAAS;GAEX,IAAML,IAAS,KAAK,UAAkB;GACtC,IAAI,CAACA,GAAO;GAEZ,IAAMO,IAAY,IAAI7Q,EAAM,QAAQ,GAE9B8Q,IAAQR,EAAM,OAAO,IAAI7P,EAAU,IAAI,SAAS;GACtD,IAAI,KAAK,IAAIqQ,CAAK,IAAI,MAAM;GAC5B,IAAMC,IAAI,EAAET,EAAM,OAAO,IAAI7P,EAAU,IAAI,MAAM,IAAI6P,EAAM,YAAYQ;GACvE,IAAIC,IAAI,GAAG;GAGX,AAFAF,EAAU,KAAKpQ,EAAU,IAAI,OAAO,MAAM,CAAC,CAAC,IAAIA,EAAU,IAAI,UAAU,MAAM,CAAC,CAAC,eAAesQ,CAAC,CAAC,CAAC,GAElG,IAAuBF;EACzB,OACE,IAAuBrR,EAAU;GAAE;GAAW;GAAM,aAAa;EAAM,CAAC;EAG1E,IAAMwR,IAAiB5Q,EAAO,SAAS,MAAM,GACvC6Q,IAAeL,EAAqB,MAAM,CAAC,CAAC,IAAIM,CAAkB,GAGlEC,IAAY,IAAInR,EAAM,QAAQ;EACpC,EAAU,YAAYiR,CAAY;EAElC,IAAMG,IAAchR,EAAO,SAAS,MAAM,CAAC,CAAC,aAAa+Q,CAAS;EAElE,IADiB,KAAK,MAAM,KAAK,cAAcC,CAC3C,GAAU;EAEd,IAAMC,IAAgB,KAAK,MAAM,eAAe,cAAcD,CAAW,KAAKA,GACxEE,IAAiB,IAAItR,EAAM,QAAQ;EAOzC,AANAsR,EAAe,YAAYD,EAAc,MAAM,CAAC,CAAC,IAAIL,CAAc,CAAC,GAEpE5Q,EAAO,SAAS,KAAKiR,CAAa,GAElCH,EAAmB,KAAKN,CAAoB,GAC5C,KAAK,cAAc,KAAK,uBAAuB,EAAE,QAAQU,EAAe,CAAC,GACzE,KAAK,MAAM,KAAK,QAAQD,CAAa;CACvC;CAEA,gBAAwB;EACtB,IAAK,KAAK,YAGV;GAGA,IAHA,KAAK,YAAY,KAAA,GACjB,KAAK,aAAa,IAEd,KAAK,eAAe;IAEtB,AADA,KAAK,MAAM,OAAO,KAAK,aAAa,GACpC,KAAK,cAAc,SAAS,QAAQ;IACpC,IAAMnP,IAAW,KAAK,cAAc;IAGpC,AAFI,MAAM,QAAQA,CAAQ,IAAGA,EAAS,SAAS,MAAM0M,EAAE,QAAQ,CAAC,IAC3D1M,EAAS,QAAQ,GACtB,KAAK,gBAAgB,KAAA;GACvB;GAGA,AADA,KAAK,eAAe,KAAK,GACzB,KAAK,MAAM,KAAK,SAAS;EAbR;CAenB;AACF,GC/ZMqP,IAAN,MAAqI;CACnI;CACA;CAGA,YACE,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GAKA;EACA,IAAM,EAAE,WAAQ,UAAO,aAAUC,GAC3BlJ,IAAYkJ,EAAK,WAAW;EAElC,IADA,KAAK,OAAOA,GACR,CAAC5O,KAAU,CAAC6O,KAAS,CAACnJ,KAAa,CAACsB,GAAO;EAC/C,IAAM8H,UAAiB;GACrB,EAAK,cAAc;EACrB;EAoBA,AAlBA,KAAK,mBAAmB,IAAIC,EAC1B;GACE;GACA;GACA,WAAWC;GACX,gBAAgBxR;GAChB;GACA;GACA;GACA;GACA,aAAayR;GACb,qBAAqBC;GACrB;EACF,GACAC,CACF,GACAP,EAAK,GAAG,mBAAmB,KAAK,qBAAqB,GACrDA,EAAK,GAAG,gBAAgB,KAAK,kBAAkB,GAC/CA,EAAK,GAAG,6BAA6B,KAAK,+BAA+B;CAC3E;CAEA,UAAiB;EAIf,AAHA,KAAK,KAAK,IAAI,mBAAmB,KAAK,qBAAqB,GAC3D,KAAK,KAAK,IAAI,gBAAgB,KAAK,kBAAkB,GACrD,KAAK,KAAK,IAAI,6BAA6B,KAAK,+BAA+B,GAC/E,KAAK,kBAAkB,QAAQ;CACjC;CAEA,yBAAmE,MAAW;EAC5E,IAAI,CAAC,KAAK,kBAAkB;EAC5B,IAAI,KAAK,iBAAiB,wBAAwB,OAAO;EACzD,IAAMrE,IAAS,KAAK,iBAAiB,kBAAkB5B,CAAM;EAE7D,OADA,KAAK,KAAK,cAAc,IACjB4B;CACT;CAEA,sBAA6D,GAAG5B,MAAW;EACzE,IAAI,CAAC,KAAK,kBAAkB;EAC5B,IAAM4B,IAAS,KAAK,iBAAiB,eAAe,GAAG5B,CAAM;EAE7D,OADA,KAAK,KAAK,cAAc,IACjB4B;CACT;CAEA,mCAAuF,GAAG5B,MAAW;EACnG,AAAK,KAAK,oBACV,KAAK,iBAAiB,4BAA4B,GAAGA,CAAM;CAC7D;AACF,GC3EMyG,IAAc,yBAEdtT,WAAyB;CAC7B,QAAQ,MAAM,GAAGsT,EAAY,aAAa;AAC5C,GAEMrT,WAAuB;CAC3B,QAAQ,KAAK,GAAGqT,EAAY,aAAa;AAC3C,GAEMpT,WAAwB;CAC5B,QAAQ,MAAM,GAAGoT,EAAY,aAAa;AAC5C,GAMaI,KAAb,MAA4B;CAC1B,cAA8C,CAAC;CAC/C,QAAoC;EAClC,SAAS;EACT,SAAS;EACT,UAAU;CACZ;CACA,QAAkD,IAAIrT,EAAkC;CACxF,gBAAuC,CAAC;CAExC,YAAmB,GAAuC;EAExD,AADIsT,KAAa,KAAK,eAAeA,CAAW,GAChD,KAAK,SAAS,KAAK,KAAK;CAC1B;CAKA,MAAa,KAAK,GAAoC;EACpD,KAAK,SAAS,EAAE,SAAS,GAAK,GAAGxK,CAAO;CAC1C;CAKA,MAAa,KAAK,GAAoC;EACpD,KAAK,SAAS,EAAE,SAAS,GAAM,GAAGA,CAAO;CAC3C;CAKA,OAAc,GAAoC;EAChD,KAAK,SAAS,EAAE,SAAS,GAAK,GAAGA,CAAO;CAC1C;CAKA,QAAe,GAAoC;EACjD,KAAK,SAAS,EAAE,SAAS,GAAM,GAAGA,CAAO;CAC3C;CAKA,UAAiB;EACf,KAAK,SAAS,EAAE,UAAU,GAAK,CAAC;CAClC;CAEA,SAAgB,GAAqC,GAAgE;EACnH,IAAI,KAAK,MAAM,UAAU,OAAOnJ,GAAiB;EACjD,IAAI,CAAC,KAAK,MAAM,WAEV4T,EAAM,YAAY,MAAQA,EAAM,aAAa,IAAM,OAAO1T,GAAgB;EAEhF,IAAM2T,IAAY,EAAE,GAAG,KAAK,MAAM;EAYlC,AAXA,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO,GAAGD;EAAM,GACnCA,EAAM,aAAa,KAAA,KAAaA,EAAM,aAAaC,EAAU,YAC3DD,EAAM,YAAU,KAAK,cAAc,GAErCA,EAAM,YAAY,KAAA,KACpB,KAAK,cAAcA,EAAM,OAAO,GAE9BA,EAAM,YAAY,KAAA,KACpB,KAAK,aAAaA,EAAM,OAAO,GAGjC,KAAK,MAAM,KAAK,eAAe;GAAE,OAAO,KAAK;GAAO;EAAU,CAAC;CACjE;CAEA,eAAsB,GAA4C;EAGhE,AAFA,KAAK,cAAc;GAAE,GAAG,KAAK;GAAa,GAAGD;EAAY,GAEzD,KAAK,SAAS,KAAK,KAAK;CAC1B;CAKA,sBAA6B;EAC3B,KAAK,mBAAmB,MAAe;GAErC,AADAG,EAAW,sBAAsB,GACjCA,EAAW,wBAAwB;EACrC,CAAC;CACH;CAEA,kBAAyB;EACvB,OAAO,KAAK;CACd;CAEA,aAAqB,GAAkB,IAAa,IAAM;EAaxD,AAZIC,KACF,KAAK,mBAAmB,MAAe;GACrC,EAAW,OAAO;EAEpB,CAAC,GACD,KAAK,MAAM,KAAK,UAAU,EAAE,cAAW,CAAC,MAExC,KAAK,mBAAmB,MAAe;GACrC,EAAW,QAAQ;EACrB,CAAC,GACD,KAAK,MAAM,KAAK,WAAW,EAAE,cAAW,CAAC,IAE3C,KAAK,MAAM,UAAUA;CACvB;CAEA,cAAsB,GAAkB,IAAa,IAAM;EAazD,AAZIC,KACF,KAAK,mBAAmB,MAAe;GACrC,EAAW,KAAK;EAElB,CAAC,GACD,KAAK,6BAA6B,KAAK,MAAM,KAAK,QAAQ,EAAE,cAAW,CAAC,CAAC,MAEzE,KAAK,mBAAmB,MAAe;GACrC,EAAW,KAAK;EAClB,CAAC,GACD,KAAK,6BAA6B,KAAK,MAAM,KAAK,QAAQ,EAAE,cAAW,CAAC,CAAC,IAE3E,KAAK,MAAM,UAAUA;CACvB;CAEA,kBAA0B,GAA2C;EACnE,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,SAAS,MAA2C;GAClF,AAAIF,KAAYG,EAAKH,CAAU;EACjC,CAAC;CACH;CAEA,gBAAwB;EACtB,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,SAAS,MAA2C;GAClF,GAAY,QAAQ;EACtB,CAAC;EAED,KAAK,IAAMI,KAAK,KAAK,aAAa;GAChC,IAAI,CAACA,GAAG;GACR,IAAM1L,IAAqC0L;GAC3C,KAAK,cAAc1L,EAAI,GAAG;EAC5B;CACF;CAEA,uBAAwC,GAAe,GAA8B;EACnF,IAAI,KAAK,MAAM,SAAS,OAAOyL,EAAK;EAElC,AAAI9K,GAAS,WAASqK,GAAe;CAEzC;AACF;;;AC9KA,SAAgBW,EAAQ,GAAa;CACnC,OAAQC,IAAM,KAAK,KAAM;AAC3B;;;ACUA,IAAIC,IAAyB,IAAI/S,EAAM,WAAW,GAErCgT,KAAb,cAA6F3H,EAAkB;CAC7G,OAAiB;CAEjB,IAAY,eAAe;EACzB,OAAO,KAAK,eAAe,SAAS,MAAM;CAC5C;CAEA;CAoBA;CAEA,YAAmB,GAAGE,GAAyD;EAC7E,MAAM,GAAGA,CAAM;EAGf,IAAMuD,IAAS,KAAK;EACpB,KAAK,cAAc;GAACA,EAAO,SAAS;GAAQA,EAAO,SAAS;GAAQA,EAAO,SAAS;EAAM,CAAC,CAAC,OAAO,OAAO,CAAC;EAE3G,IAAMmE,IAAY,KAAK,UAAU,KAAK,IAAI,GACpCC,IAAW,KAAK,SAAS,KAAK,IAAI,GAClCC,IAAU,KAAK,QAAQ,KAAK,IAAI,GAChC/L,IAAO,KAAK,KAAK,KAAK,IAAI,GAC1B6H,IAAO,KAAK,KAAK,KAAK,IAAI,GAE1BC,UAA6B;GAEjC,AADA,KAAK,eAAe,OAAO,KAAK,MAAM,GACtC,KAAK,OAAO;EACd;EAyBA,AAvBAA,EAAqB,GAErB,KAAK,UAAU,iBAAiB,KAAK,gBAAgB,aAAa+D,CAAS,GAC3E,SAAS,iBAAiB,aAAaC,CAAQ,GAC/C,SAAS,iBAAiB,WAAWC,CAAO,GAE5C,KAAK,UAAU,iBAAiB,KAAK,gBAAgB,cAAcF,CAAS,GAC5E,SAAS,iBAAiB,aAAaC,CAAQ,GAC/C,SAAS,iBAAiB,YAAYC,CAAO,GAE7C,KAAK,MAAM,GAAG,aAAalE,CAAI,GAC/B,KAAK,MAAM,GAAG,WAAW7H,CAAI,GAC7B,KAAK,MAAM,GAAG,cAAc6H,CAAI,GAChC,KAAK,MAAM,GAAG,YAAY7H,CAAI,GAC9B,KAAK,MAAM,GAAG,qBAAqB6H,CAAI,GACvC,KAAK,MAAM,GAAG,sBAAsB7H,CAAI,GACxC,KAAK,MAAM,GAAG,uBAAuB,MAAW;GAG9C,AADA,KAAK,eAAe,OAAOmE,EAAO,MAAM,GACxC,KAAK,OAAO;EACd,CAAC,GACD,KAAK,YAAY,GAAG,gBAAgB2D,CAAoB,GAExD,KAAK,UAAU,WAAW;GAgBxB,AAfA,KAAK,UAAU,oBAAoB,KAAK,gBAAgB,aAAa+D,CAAS,GAC9E,SAAS,oBAAoB,aAAaC,CAAQ,GAClD,SAAS,oBAAoB,WAAWC,CAAO,GAE/C,KAAK,UAAU,oBAAoB,KAAK,gBAAgB,cAAcF,CAAS,GAC/E,SAAS,oBAAoB,aAAaC,CAAQ,GAClD,SAAS,oBAAoB,YAAYC,CAAO,GAEhD,KAAK,MAAM,IAAI,aAAalE,CAAI,GAChC,KAAK,MAAM,IAAI,WAAW7H,CAAI,GAC9B,KAAK,MAAM,IAAI,cAAc6H,CAAI,GACjC,KAAK,MAAM,IAAI,YAAY7H,CAAI,GAC/B,KAAK,MAAM,IAAI,qBAAqB6H,CAAI,GACxC,KAAK,MAAM,IAAI,sBAAsB7H,CAAI,GACzC,KAAK,MAAM,IAAI,oBAAoB,GACnC,KAAK,YAAY,IAAI,gBAAgB8H,CAAoB;EAC3D,CAAC;CACH;CAEA,eAAsB,GAA+C;EACnE,IAAM,EAAE,OAAI,GAAG,OAAI,GAAG,OAAI,MAAMtH,GAC1BwL,IAAQ,IAAIpT,EAAM,MAAM6S,EAAQlD,CAAC,GAAGkD,EAAQjD,CAAC,GAAGiD,EAAQQ,CAAC,CAAC,GAC1DhT,IAAa,IAAIL,EAAM,WAAW,CAAC,CAAC,aAAaoT,CAAK;EAG5D,IADiB,KAAK,MAAM,KAAK,gBAAgB/S,CAC7C,GAAU;EAEd,IAAM,EAAE,mBAAgB,oBAAiB;EAKzC,AAJAJ,EAAoBM,GAAgBF,GAAYH,CAAY,GAC5D,KAAK,cAAc,KAAK,mBAAmBG,GAAYH,CAAY,GACnE,KAAK,MAAM,KAAK,UAAUG,CAAU,GAEpC,KAAK,OAAO;CACd;CAQA,cAAqB,GAAuB,GAAiC;EAC3E,IAAM,EAAE,sBAAmB,MAGrBiT,IAAe,IAAItT,EAAM,MAAM,CAAC,CAAC,kBAAkBO,EAAe,UAAU,GAG5EgT,IAAgB;GACpB,GAAGzT,EAAQwT,EAAa,CAAC;GACzB,GAAGxT,EAAQwT,EAAa,CAAC;GACzB,GAAGxT,EAAQwT,EAAa,CAAC;EAC3B,GAGME,IAAY;GAChB,GAAGC,MAAS,MAAM7L,IAAQ2L,EAAc;GACxC,GAAGE,MAAS,MAAM7L,IAAQ2L,EAAc;GACxC,GAAGE,MAAS,MAAM7L,IAAQ2L,EAAc;EAC1C,GAGMG,IAAW,IAAI1T,EAAM,MAAM6S,EAAQW,EAAU,CAAC,GAAGX,EAAQW,EAAU,CAAC,GAAGX,EAAQW,EAAU,CAAC,CAAC;EAKjG,OAFsB,IAAIxT,EAAM,WAAW,CAAC,CAAC,aAAa0T,CAEnD;CACT;CAEA,0BAAoC,GAAiE;EACnG,AAAI,KAAK,cACT,MAAM,0BAA0BnI,CAAM;CACxC;CAEA,yBAAmC,GAAiE,CAAC;CAKrG,UAAkB,GAAiD;EACjE,IAAI,KAAK,YAAY;EAGrB,KAAK,eAAe,OAAO,KAAK,MAAM;EAEtC,IAAMsE,IAAYtE,GAAQ;EAE1B,IAAI,CAACsE,GAAW,OAAO,KAAK,QAAQ;EAEpC,IAAM9N,KAAa8N,GAAW,OAAA,CAAe;EAE7C,IAAI,CAAC9N,GAAW,OAAO,KAAK,QAAQ;EAGpC,IAAMoO,IAAiBN,EAAU,OAE3B8D,IAAc,KAAK,eAAe5R,CAAS;EAGjD,KAAK,aAAa,CAAC;EACnB,IAAM6R,IAAezD,EAAe,MAAM;EAE1C,AADA,EAAa,KAAK,IAClB,KAAK,gBAAgByD,CAAY;EAGjC,IAAMC,IAAmB,KAAK,eAAe,WAAW,MAAM,GAGxD3D,WAAyB;GAC7B,IAAInO,MAAc,KAAK,OAAO,IAAI/B,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB6T,CAAgB;GACzF,IAAI9R,MAAc,KAAK,OAAO,IAAI/B,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB6T,CAAgB;GACzF,IAAI9R,MAAc,KAAK,OAAO,IAAI/B,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB6T,CAAgB;EAC3F,EAAA,CAAG,GACGvD,IAAQ,IAAItQ,EAAM,MAAM,CAAC,CAAC,8BAA8BkQ,GAAiBC,CAAc,GAIvF2D,IADexD,EAAM,aAAaH,EAAe,MAAM,GAAG,IAAInQ,EAAM,QAAQ,CAC9D,CAAA,CAAa,MAAM,CAAC,CAAC,IAAI,KAAK,YAAY,GAIxD+T,IAAaD,EAAY,QAAQH,EAAY,SAAS,MAAM,CAAC,CAAC,gBAAgBE,CAAgB,CAAC,GAE/FG,IAAiBL,EAAY,YAAYI,CAAU;EAqBzD,AAnBA,KAAK,oBAAoBhS,GAAWiS,CAAc,GAClD,KAAK,qBAAqBjS,GAAW,CAAC,GAItC,KAAK,YAAY;GACf;GACA;GACA;GACA;GACA;GACA,OAAO;GACP,kBAAkB8R,EAAiB,MAAM;EAC3C,GAEA,IAAyB,IAAI7T,EAAM,WAAW,GAE9C,KAAK,eAAe,mBAAmB,CAAC+B,CAAS,CAAC,GAClD,KAAK,MAAM,KAAK,eAAeA,CAAS,GACxC,KAAK,aAAa;CAEpB;CAEA,YAAoB;EAGlB,OADe,KAAK,gBAAgB,KAAK;CAE3C;CAEA,eAAuB,GAAa,GAAsB;EACxD,IAAIkS;EACJ,IAAI1S,KAAUA,EAAO,WAAW;GAE9B,AADA,IAAmB,IAAIvB,EAAM,WAAW,GACxCuB,EAAO,UAAU,IAAIvB,EAAM,QAAQ,GAAGiU,GAAkB,IAAIjU,EAAM,QAAQ,CAAC;GAC3E,IAAMoT,IAAQ,IAAIpT,EAAM,MAAM,CAAC,CAAC,kBAAkBiU,CAAgB;GAClE,IAAIlS,MAAc,KAAK,OAAO,KAAK,MAAMjC,EAAQsT,EAAM,CAAC,CAAC;GACzD,IAAIrR,MAAc,KAAK,OAAO,KAAK,MAAMjC,EAAQsT,EAAM,CAAC,CAAC;GACzD,IAAIrR,MAAc,KAAK,OAAO,KAAK,MAAMjC,EAAQsT,EAAM,CAAC,CAAC;EAC3D;CACF;CAEA,sBAA8B,GAA0C;EAEtE,IAAM7R,IAAS,KAAK,gBAAgB,KAAK,QACrC0S;EACJ,IAAI1S,KAAUA,EAAO,WAAW;GAE9B,AADA,IAAmB,IAAIvB,EAAM,WAAW,GACxCuB,EAAO,UAAU,IAAIvB,EAAM,QAAQ,GAAGiU,GAAkB,IAAIjU,EAAM,QAAQ,CAAC;GAC3E,IAAMoT,IAAQ,IAAIpT,EAAM,MAAM,CAAC,CAAC,kBAAkBiU,CAAgB;GAClE,IAAIlS,MAAc,KAAK,OAAO,KAAK,MAAMjC,EAAQsT,EAAM,CAAC,CAAC;GACzD,IAAIrR,MAAc,KAAK,OAAO,KAAK,MAAMjC,EAAQsT,EAAM,CAAC,CAAC;GACzD,IAAIrR,MAAc,KAAK,OAAO,KAAK,MAAMjC,EAAQsT,EAAM,CAAC,CAAC;EAC3D;CACF;CAEA,SAAiB,GAA4D;EAC3E,IAAI,CAAC,KAAK,YAAY;EAEtB,IAAMzD,IAAI,aAAaN,IAAQA,EAAM,QAAQ,EAAE,CAAC,UAAUA,EAAM,GAC1DO,IAAI,aAAaP,IAAQA,EAAM,QAAQ,EAAE,CAAC,UAAUA,EAAM,GAE1DqB,IAAMhO,EAAkB,KAAK,QAAQ;GAAE;GAAG;EAAE,GAAG,KAAK,SAAS;EAMnE,OALKgO,KAGL,KAAK,OAAOA,CAAG,GAER,MALU,KAAK,QAAQ;CAMhC;CAEA,OAAe,GAA4B;EACzC,IAAI,CAAC,KAAK,WAAW,OAAO,KAAK,QAAQ;EACzC,IAAM,EAAE,gBAAa,UAAO,gBAAa,cAAW,wBAAqB,KAAK,WACxE,EAAE,sBAAmB,MACrBwD,IAAwBzT,EAAU,IAAI,eAAe6P,GAAO,IAAItQ,EAAM,QAAQ,CAAC;EACrF,IAAI,CAACkU,GAAuB;EAE5B,IAAMhU,IAAe,KAAK,aAAa,MAAM,GAGzCiU,IAFiB7D,EAAM,aAAa4D,EAAsB,MAAM,GAAG,IAAIlU,EAAM,QAAQ,CAErE,CAAA,CAAa,MAAM,CAAC,CAAC,IAAIE,CAAY,GAGnDkU,IAAe,KAAK,UAAU,gBAAgB,MAAM,CAAC,CAAC,UAAU;EAEtE,IADmBD,EAAc,MAAM,CAAC,CAAC,eAAeC,CACxC,CAAA,CAAW,UAAU,CAAC,CAAC,eAAeD,EAAc,OAAO,CAAC;EAE5E,IAAM9T,IAAa,IAAIL,EAAM,WAAW,CAAC,CAAC,mBAAmB8T,EAAY,MAAM,CAAC,CAAC,UAAU,GAAGK,EAAc,MAAM,CAAC,CAAC,UAAU,CAAC,GACzHE,IAAgB9T,EAAe,WAAW,MAAM,CAAC,CAAC,YAAYF,CAAU;EAM9E,IAHIyT,EAAY,QAAQK,CAAa,MAAM,KAE1B,KAAK,MAAM,KAAK,gBAAgBE,CAC7C,GAAU;EAed,IAAMzM,IAPQ,IAAI5H,EAAM,MAAM,CAAC,CAAC,kBAC9B,IAAIA,EAAM,WAAW,CAAC,CAAC,mBACrB8T,EAAY,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,gBAAgBD,EAAiB,MAAM,CAAC,CAAC,OAAO,CAAC,GACjFM,EAAc,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,gBAAgBN,EAAiB,MAAM,CAAC,CAAC,OAAO,CAAC,CACrF,GACA,GAAG9R,EAAU,YAAY,IAAI,MAAM,QAAQA,EAAU,YAAY,GAAG,EAAE,GAE1D,CAAA,CAAMA,KAAa4R,EAAY;EAK7C,IAJA,KAAK,UAAU,SAAS/L,GACxB,KAAK,qBAAqB7F,GAAW,KAAK,UAAU,KAAK,GACzD,KAAK,aAAajC,EAAQ,KAAK,UAAU,KAAK,CAAC,GAE3CI,GAAc;GAChB,IAAMC,IAAI,IAAIH,EAAM,QAAQ,CAAC,CAAC,WAAWO,EAAe,UAAUL,CAAY,CAAC,CAAC,gBAAgBG,CAAU,CAAC,CAAC,IAAIH,CAAY;GAC5H,EAAe,SAAS,KAAKC,CAAC;EAChC;EAQA,AANAI,EAAe,gBAAgBF,CAAU,GACzC0S,EAAuB,YAAY1S,CAAU,GAE7C,KAAK,cAAc,KAAK,qBAAqB;GAAE;GAAY,QAAQH;EAAa,CAAC,GACjF,KAAK,MAAM,KAAK,UAAUK,EAAe,UAAU,GAEnD,KAAK,UAAU,cAAc4T;CAC/B;CAEA,UAAwB;EACtB,AAAK,KAAK,eAEV,KAAK,sBAAsBpB,GAAwB,KAAK,YAAY,GAGhE,KAAK,WAAW,cAClB,KAAK,UAAU,WAAW,SAAS,MAAS;GAG1C,AAFA,KAAK,MAAM,OAAO5K,CAAI,GACtBA,EAAK,SAAS,QAAQ,GAClBA,EAAK,oBAAoBnI,EAAM,YACjCmI,EAAK,SAAS,QAAQ;EAE1B,CAAC,GAKH,KAAK,YAAY,KAAA,GACjB,KAAK,aAAa,IAElB,KAAK,eAAe,KAAK,GAGzB,KAAK,mBAAmB,GAExB,KAAK,MAAM,KAAK,WAAW;CAE7B;CAEA,qBAAmC;EAGjC,KAAK,MAAM,KAAK,sBAAsB,EAAE,QAAQ,KAAK,OAAO,CAAC;CAC/D;CAEA,eAAuB,GAMT;EACZ,QAAQpG,GAAR;GACE,KAAK,KACH,OAAO,KAAK,eAAe,SAAS;GACtC,KAAK,KACH,OAAO,KAAK,eAAe,SAAS;GACtC,KAAK,KACH,OAAO,KAAK,eAAe,SAAS;EACxC;CACF;CAEA,oBAA4B,GAAsB,GAAe;EAC/D,IAAM4R,IAAc,KAAK,eAAe5R,CAAS;EACjD,IAAI,CAAC4R,GACH,QAAQ,KAAK,0BAA0B;OAGzC,IAAIA,aAAuB3T,EAAM,QAAQ2T,EAAY,oBAAoB3T,EAAM,gBAAgB;GAC7F,IAAM,EAAE,WAAQ,aAAU,mBAAgB2T,EAAY,SAAS;GAC/D,EAAY,WAAW,IAAI3T,EAAM,eAAemD,GAAQmR,GAAU/F,GAAOgG,CAAW;EACtF,OACE,QAAQ,KAAK,mCAAmC;CAEpD;CAEA,qBAA6B,GAAsB,GAAgB;EAEjE,IAAMA,IAAcjG,KAAU,IAAI,KAAK,IAAIA,GAAQ,IAAS,IAAI,KAAK,IAAIA,GAAQ,KAAU,GACrFqF,IAAc,KAAK,eAAe5R,CAAS;EACjD,IAAI4R,aAAuB3T,EAAM,QAAQ2T,EAAY,oBAAoB3T,EAAM,gBAAgB;GAC7F,IAAM,EAAE,WAAQ,kBAAe2T,EAAY,SAAS,YAC9CW,IAAW,KAAK,KAA8B,MAAM,IAAI,KAAK,MAAxC,KAAK,IAAIC,CAAW,CAAwB;GACvE,EAAY,WAAW,IAAIvU,EAAM,eAAemD,GAAQmR,GAAUE,GAAYD,CAAW;EAC3F,OACE,QAAQ,KAAK,mCAAmC;CAEpD;CAEA,aAAqB,GAAe;EAClC,IAAMjS,IAAU,KAAK,eAAe,WAAW;EAC/C,AAAKA,MACL,EAAQ,YAAY,GAAGsF,EAAM,QAAQ,CAAC,EAAE;CAC1C;CAEA,gBAAwB,GAAyB;EAC/C,IAAM6M,IAAY,KAAK,eAAe;EACtC,IAAI,CAACA,GAAW;EAEhB,IAAM,EAAE,MAAG,MAAG,SADEhQ,EAAS,QAAQ,KAAK,MAClB;EACpB,IAAI4O,IAAI,GAAG;EACX,IAAM7Q,KAASmN,IAAI,KAAK,IAAK,MAAM,KAC7BlN,KAAQ,CAACmN,IAAI,KAAK,IAAK,MAAM;EACnC,EAAU,WAAWpN,GAAMC,CAAG;CAChC;AACF,GCjaaiS,KAAb,cAGUrJ,EAAwE;CAChF;CAEA,OAAiB;CAEjB,YAAmB,GAAGE,GAA+G;EACnI,MAAM,GAAGA,CAAM;CACjB;CAEA,SAAgB;EAEd,AADA,KAAK,eAAe,OAAO,GAC3B,MAAM,OAAO;CACf;CAEA,UAAiB;EAEf,AADA,KAAK,eAAe,QAAQ,GAC5B,MAAM,QAAQ;CAChB;CAEA,OAAc;EAEZ,AADA,KAAK,eAAe,KAAK,GACzB,MAAM,KAAK;CACb;CAEA,OAAc;EAEZ,AADA,KAAK,eAAe,KAAK,GACzB,MAAM,KAAK;CACb;CAEA,4BAAsC,GAAmC;EACvE,AAAI,KAAK,cACT,MAAM,4BAA4BA,CAAM;CAC1C;CAEA,yBAAmC,GAAiE;EAClG,KAAK,eAAe,wBAAwBA,EAAO,QAAQA,EAAO,MAAM;CAC1E;CAEA,eAAyB;EACvB,IAAM+E,IAAQ,IAAItQ,EAAM,MAAM,GAExByO,IAAuB,KAAK,eAAe;EACjD,IAAIA,EAAU,WAAW,GAIzB,OAHIA,EAAU,SAAS,IAAG6B,EAAM,8BAA8B,KAAK,eAAe,kBAAkB,IAAI3P,EAAQ,CAAC,GAAG8N,EAAU,EAAG,IAC5H6B,EAAM,sBAAsB7B,EAAU,IAAKA,EAAU,IAAKA,EAAU,EAAG,GAErE6B;CACT;CAEA,UACE,GACA,GAIA;EACA,KAAK,eAAe,eAAe;EACnC,IAAMA,IAAQ,KAAK,aAAa;EAEhC,IAAI,CAACA,GAAO,OAAO,KAAK,QAAQ;EAQhC,AANA,KAAK,YAAY;GAAE,YAAY;IAAE,UAAUjB,EAAM,SAAS,MAAM;IAAG,WAAWA,EAAM;GAAU;GAAG;EAAM,GAIvG,KAAK,MAAM,KAAK,cAAcA,EAAM,SAAS,GAC7C,KAAK,OAAO,GACZ,KAAK,aAAa;CAEpB;CAEA,SAAmB,GAA+C;EAChE,IAAI,CAAC,KAAK,YAAY;EAEtB,IAAM5O,IAAYiC,EAAkB,KAAK,QAAQ2M,GAAO,KAAK,SAAS;EACtE,IAAI,CAAC5O,GAAW,OAAO,KAAK,QAAQ;EAEpC,KAAK,MAAMA,CAAS;CAEtB;CAEA,MAAgB,GAA4B;EAC1C,IAAI,CAAC,KAAK,WAAW;EACrB,IAAML,IAAS,KAAK,gBACd,EAAE,eAAY,aAAU,KAAK,WAC7BiK,IAAkB,KAAK,eAAe;EAC5C,IAAIA,EAAgB,SAAS,GAAG,OAAO,KAAK,QAAQ;EAEpD,IAAMsK,IAAoBlU,EAAU,IAAI,eAAe6P,GAAO,IAAI3P,EAAQ,CAAC;EAE3E,IADI,CAACgU,KACD5U,EAAc4U,GAAmB,KAAK,OAAO,QAAQ,GAAG;EAE5D,IAAMC,IAAc,IAAIjU,EAAQ,CAAC,CAAC,WAAW0J,EAAgB,IAAIA,EAAgB,EAAE,CAAC,CAAC,aAAa,CAAC,GAE7F,EAAE,UAAUwK,GAAe,iBAAcC,GAEzCC,IAAW,IAAIpU,EAAQ,CAAC,CAAC,WAAW0J,EAAgB,IAAIA,EAAgB,EAAE,GAC1E2K,IAAW,IAAIrU,EAAQ,CAAC,CAAC,WAAW0J,EAAgB,IAAIA,EAAgB,EAAE,GAG1E4K,KAAa,MAA2B;GAC5C,IAAMC,IAAgB,IAAIvU,EAAQ,GAAG,GAAG,CAAC;GACzC,IAAI,CAAC,KAAK,WAAW,OAAOuU;GAC5B,IAAMC,KAAcpT,MAAc,OAAOgT,IAAWC,EAAA,CAAU,MAAM,GAE9DI,IAAuBP,EAAc,MAAM,CAAC,CAAC,gBAAgBM,CAAU,GACvEE,IAAqBV,EAAkB,MAAM,CAAC,CAAC,gBAAgBQ,CAAU,GACzEG,IAAqBV,EAAY,MAAM,CAAC,CAAC,gBAAgBO,CAAU;GAKzE,IAAIE,EAAmB,OAAOD,CAAoB,GAAG,OAAOF;GAE5D,IAAInT,MAAc,QAAQ,OAAO,KAAK,UAAU,2BAA4B,WAAW;IACrF,IAAMnB,IAAS,IAAID,EAAQ,CAAC,CAAC,WAAW0U,GAAoBC,CAAkB,GACxEC,IAAc3U,EAAO,IAAI,KAAKuU,EAAW,KAAK,GAC9CK,IAAc5U,EAAO,IAAI,KAAKuU,EAAW,KAAK,GAC9CM,IAAc7U,EAAO,IAAI,KAAKuU,EAAW,KAAK;IACpD,KAAK,UAAU,0BAA0BI,KAAeC,KAAeC;GACzE;GACA,IAAI1T,MAAc,QAAQ,OAAO,KAAK,UAAU,yBAA0B,WAAW;IACnF,IAAMnB,IAAS,IAAID,EAAQ,CAAC,CAAC,WAAW0U,GAAoBC,CAAkB,GACxEC,IAAc3U,EAAO,IAAI,KAAKuU,EAAW,KAAK,GAC9CK,IAAc5U,EAAO,IAAI,KAAKuU,EAAW,KAAK,GAC9CM,IAAc7U,EAAO,IAAI,KAAKuU,EAAW,KAAK;IACpD,KAAK,UAAU,wBAAwBI,KAAeC,KAAeC;GACvE;GAEA,IAAM7U,IAAS,IAAID,EAAQ,CAAC,CAAC,WAAW0U,GAAoBD,CAAoB,GAG1EM,IAAe9U,EAAO,OAAO;GAMnC,OALI8U,IAAe,MACjB,QAAQ,KAAK,kCAAkCA,CAAY,GACpDR,KAGFtU;EACT,GAEM+U,IAAWV,EAAU,IAAI,GACzBW,IAAWX,EAAU,IAAI,GAEzBY,UAAmB;GACvB,IAAMjV,IAAS+U;GACf,KAAK,eAAe,gBAAgB,SAAS,GAAU,MAAU;IAC/D,AAAI,KAAK,WAAW,yBACd5L,MAAU,KAAKA,MAAU,MAAGtF,EAAS,IAAI7D,CAAM,KAE/CmJ,MAAU,KAAKA,MAAU,MAAGtF,EAAS,IAAI7D,CAAM;GAEvD,CAAC;EACH,GAEMkV,UAAmB;GACvB,IAAMlV,IAASgV;GACf,KAAK,eAAe,gBAAgB,SAAS,GAAU,MAAU;IAC/D,AAAI,KAAK,WAAW,2BACd7L,MAAU,KAAKA,MAAU,MAAGtF,EAAS,IAAI7D,CAAM,KAE/CmJ,MAAU,KAAKA,MAAU,MAAGtF,EAAS,IAAI7D,CAAM;GAEvD,CAAC;EACH;EAEA,QAAQmB,GAAR;GACE,KAAK;IACH,EAAW;IACX;GACF,KAAK;IACH,EAAW;IACX;GACF,KAAK;GACL,KAAK,QAEH,AADA8T,EAAW,GACXC,EAAW;EACf;EAMA,IAAMC,IAAS,IAAIpV,EAAQ,CAAC,CAAC,WAAW0J,EAAgB,IAAIA,EAAgB,EAAE,CAAC,CAAC,OAAO,IAAI0K,EAAS,OAAO,GACrGiB,IAAS,IAAIrV,EAAQ,CAAC,CAAC,WAAW0J,EAAgB,IAAIA,EAAgB,EAAE,CAAC,CAAC,OAAO,IAAI2K,EAAS,OAAO,GACrGiB,IAAU,IAAItV,EAAQoV,GAAQC,GAAQ,CAAC,GAEvCE,IAAc,IAAIlW,EAAM,QAAQ,CAAC,CAAC,MAAMiW,CAAO;EAUrD,AANK7V,EAAe,qBAAsBA,EAAe,oBACtDA,EAAiD,kBAAkB8V,CAAW,IAE/E9V,EAAO,MAAM,aAAa8V,CAAW,GAGvCpB,EAAW,SAAS,KAAKH,CAAiB;EAK1C,IAAMwB,IAAiB,IAAIxV,EAAQ,CAAC,CAAC,WAAW0J,EAAgB,IAAIA,EAAgB,EAAE,CAAC,CAAC,aAAa,CAAC,GAChGzJ,IAAS,IAAID,EAAQ,CAAC,CAAC,WAAWwV,GAAgBvB,CAAW,GAC7DwB,IAAmB,IAAIpW,EAAM,QAAQ,CAAC,CAAC,YAAYY,CAAM;EAc/D,AAZAR,EAAO,aAAagW,CAAgB,GACpC,KAAK,eAAe,eAAe,YAAY,aAAaA,CAAgB,GAC5E,KAAK,eAAe,OAAO,aAAaA,CAAgB,GAExD,KAAK,cAAc,KAAK,oBAAoB,EAAE,QAAQF,EAAY,CAAC,GACnE,KAAK,cAAc,KAAK,uBAAuB,EAAE,QAAQE,EAAiB,CAAC,GAO3E,KAAK,OAAO;CACd;CAEA,UAA0B;EACxB,AAAK,KAAK,eACV,KAAK,YAAY,KAAA,GACjB,KAAK,aAAa,IAGd,gBAAgB,KAAK,kBAAkB,OAAO,KAAK,eAAe,cAAe,cACnF,KAAK,eAAe,WAAW,GAGjC,KAAK,MAAM,KAAK,UAAU,GAC1B,KAAK,OAAO;CAEd;AACF,GC7PaC,KAAb,cAA0C3B,GAAmD;CAC3F,OAAiB;CAEjB,YAAmB,GAAGnJ,GAA0F;EAE9G,AADA,MAAM,GAAGA,CAAM,GACf,KAAK,qBAAqB;CAC5B;CAEA,uBAA+B;EAC7B,KAAK,eAAe,OAAO,SAAS,MAAe;GACjD,IAAI,CAACuJ,GAAY;GACjB,IAAMxS,IAAUwS,EAAW,OACrB7B,KAAa,MAAqB,KAAK,UAAUvD,GAAOoF,CAAU,GAClE5B,IAAW,KAAK,SAAS,KAAK,IAAI,GAClCC,IAAU,KAAK,QAAQ,KAAK,IAAI;GAGtC,AAFA7Q,EAAQ,iBAAiB,aAAa2Q,CAAS,GAC/C3Q,EAAQ,iBAAiB,QAAQ4Q,CAAQ,GACzC5Q,EAAQ,iBAAiB,WAAW6Q,CAAO;EAC7C,CAAC;CACH;AACF,GCnBamD,KAAb,cAAmGjL,EAEjG;CACA,OAAiB;CACjB,YAAmB,GAAGE,GAAiG;EACrH,MAAM,GAAGA,CAAM;CACjB;AACF,GCGagL,KAAb,cAA4E3U,EAAuB;CACjG,OAAc;CACd,cAA+E,CAAC;CAChF,kBAAgD,CAAC;CACjD,YAAyE,CAAC;CAC1E;CACA,sBAA8B;CAC9B,aAAgF;CAChF,iBAAyB;CAEzB,YACE,GACA,GACA;EASA,AARA,MAAMrB,GAAgBC,CAAM,GAExBA,MACF,KAAK,YAAYA,EAAO,WACxB,KAAK,YAAYA,EAAO,YAI1B,KAAK,gBAAgB,CAAC;CACxB;CAEA,iBAA8B;EAC5B,KAAK,WAAW,KAAK,KAAK,eAAe,UAAU;CACrD;CAEA,gBAAuB,GAAwB;EAE7C,IAAI,KAAK,gBACP,QAAQ,KAAK,0EAA0E;OAIzF;QAAK,iBAAiB;GAEtB,IAAI;IACF,KAAK,SAAS,KAAK,KAAK,eAAe,QAAQ;IAE/C,IAAMiO,IAAY,OAAO,KAAK,aAAc,aAAa,KAAK,UAAU,IAAI,KAAK;IAEjF,IAAI,CAACA,GAAW;KACd,KAAK,iBAAiB;KACtB;IACF;IA2BA,AAxBA,KAAK,gBAAgB,GAGrB,KAAK,cAAcA,EAAU,KAAK,GAAe,MAAU;KACzD,IAAM+H,IAAYC,GAAe;KAUjC,OATAD,EAAU,SAAS,KAAKE,EAAc,cAAc,GACnD,EAAmB,gBAAgBA,GAGpCF,EAAU,SAAS,SAAS,MAAU;MACnC,EAAe,gBAAgBE;KAClC,CAAC,GAED,KAAK,IAAIF,CAAS,GACXA;IACT,CAAC,GAGD,KAAK,sBAAsB,GAG3B,KAAK,sBAAsB,IAGvB,KAAK,eACP,KAAK,mBAAmB,KAAK,UAAU,GACvC,KAAK,iBAAiB,KAAK,UAAU,GACrC,KAAK,sBAAsB;GAE/B,UAAU;IACR,KAAK,iBAAiB;GACxB;EA5CsB;CA6CxB;CAKA,kBAA0B;EAOxB,AALA,KAAK,YAAY,SAAS,MAAS;GACjC,KAAK,OAAOrO,CAAI;EAClB,CAAC,GAGD,KAAK,cAAc,CAAC;EAGpB,IAAMwO,IAAkB,KAAK,SAAS,QAAQ,MAAUpP,EAAM,SAAS,mBAAmB;EAC1F,AAAIoP,EAAgB,SAAS,KAC3BA,EAAgB,SAAS,MAAW;GAClC,KAAK,OAAOzN,CAAM;EACpB,CAAC;CAEL;CAKA,wBAAgC;EAK9B,AAHA,KAAK,gBAAgB,SAAS,MAAe;GAC3C,KAAK,OAAO0N,EAAW,IAAI;EAC7B,CAAC,GACD,KAAK,kBAAkB,CAAC;EAGxB,IAAMC,IAA6C;GACjD,KAAK;GACL,QAAQ;GACR,MAAM;GACN,OAAO;GACP,OAAO;GACP,MAAM;EACR,GAGMC,oBAAsB,IAAI,IAAY;EAG5C,KAAK,IAAMC,KAAS,KAAK,aAAa;GACpC,IAAMC,IAAUD,EAAM,cAAc;GACpC,IAAI,CAACC,KAAWF,EAAoB,IAAIE,CAAO,GAAG;GAElD,IAAMC,IAAaJ,EAAmBG;GACtC,IAAI,CAACC,GAAY;GAGjB,IAAMC,IAAQ,KAAK,YAAY,MAAM,MAAS/O,EAAK,cAAc,OAAO8O,CAAU;GAClF,IAAI,CAACC,GAAO;GAGZ,IAAMxI,IAAOyI,EAAmBJ,EAAM,SAAS,MAAM,GAAGG,EAAM,SAAS,MAAM,CAAC;GAc9E,AAXA,KAAK,IAAIxI,CAAI,GAGb,KAAK,gBAAgB,KAAK;IACxB;IACA;IACA;GACF,CAAC,GAGDoI,EAAoB,IAAIE,CAAO,GAC/BF,EAAoB,IAAIG,CAAU;EACpC;CACF;CAKA,wBAA+B;EAC7B,IAAMxI,IAAY,OAAO,KAAK,aAAc,aAAa,KAAK,UAAU,IAAI,KAAK;EACjF,AAAKA,MAELA,EAAU,SAAS,MAAkB;GACnC,IAAMtG,IAAO,KAAK,YAAY,MAAM,MAAOiP,EAAG,cAAc,OAAOV,EAAc,EAAE;GACnF,AAAKvO,MACLA,EAAK,SAAS,KAAKuO,EAAc,cAAc,GAC/C,EAAK,gBAAgBA;EACvB,CAAC,GAED,KAAK,sBAAsB,GACvB,KAAK,cAAY,KAAK,mBAAmB,KAAK,UAAU;CAC9D;CAEA,OAAc,GAAsB;EAClC,IAAMW,IAAiBzU,EAAO,SAAS,sBAGjCmK,IAAiBnK,EAAO,SAAS,MAAM,GAGvC0U,IAAe,KAAK,eAAe,iBAAiB,IAAItX,EAAM,QAAQ,CAAC,GAGvEuX,IAAoBxK,EAAe,IAAIuK,CAAY,CAAC,CAAC,UAAU,GAG/DE,IAAmB;GACvB,OAAO,IAAIxX,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB,KAAK,eAAe,mBAAmB,IAAIA,EAAM,WAAW,CAAC,CAAC;GAChH,MAAM,IAAIA,EAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,CAAC,gBAAgB,KAAK,eAAe,mBAAmB,IAAIA,EAAM,WAAW,CAAC,CAAC;GAChH,MAAM,IAAIA,EAAM,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,gBAAgB,KAAK,eAAe,mBAAmB,IAAIA,EAAM,WAAW,CAAC,CAAC;GAChH,OAAO,IAAIA,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB,KAAK,eAAe,mBAAmB,IAAIA,EAAM,WAAW,CAAC,CAAC;GAChH,KAAK,IAAIA,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,gBAAgB,KAAK,eAAe,mBAAmB,IAAIA,EAAM,WAAW,CAAC,CAAC;GAC9G,QAAQ,IAAIA,EAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,gBAAgB,KAAK,eAAe,mBAAmB,IAAIA,EAAM,WAAW,CAAC,CAAC;EACpH,GAGIyX,IAAS,IACTC,IAAkB;EAEtB,OAAO,QAAQF,CAAgB,CAAC,CAAC,SAAS,CAACzV,GAAW4V,OAAe;GACnE,IAAMC,IAAML,EAAkB,IAAII,CAAS;GAC3C,AAAIC,IAAMH,MACR,IAASG,GACT,IAAkB7V;EAEtB,CAAC;EAGD,IAAM8U,IAAqB;GACzB,KAAK;GACL,QAAQ;GACR,MAAM;GACN,OAAO;GACP,OAAO;GACP,MAAM;EACR;EAsBA,AAnBA,KAAK,YAAY,SAAS,MAAc;GACtC,IAAI,CAACQ,GAAgB;IACnB,EAAU,UAAU;IACpB;GACF;GACA,IAAMQ,IAASrB,EAAU,cAAc,IACjCS,IAAaJ,EAAmBa;GAEtC,AAGElB,EAAU,UAHRqB,MAAWH,KAAmBG,MAAWZ;EAK/C,CAAC,GAGD,KAAK,sBAAsB,GAGvB,KAAK,eACP,KAAK,mBAAmB,KAAK,UAAU,GACvC,KAAK,iBAAiB,KAAK,UAAU;CAEzC;CAKA,mBAA2B,GAA4D;EAIrF,AAFA,KAAK,kBAAkB,EAAI,GAE3B,KAAK,YAAY,SAAS,MAAc;GACtC,EAAU,MAAM,UACd1S,EAAuB3B,GAAQ4T,EAAU,cAAc,eAAe,MAAM,CAAC,CAAC,aAAa,KAAK,WAAW,CAAC,CAC9G;EACF,CAAC;CACH;CAKA,iBAAyB,GAA4D,CAGrF;CAKA,sBAA6B;EAC3B,KAAK,gBAAgB,SAAS,MAAe;GAE3C,IAAMsB,IAAoBlB,EAAW,MAAM,WAAWA,EAAW,MAAM;GACvE,EAAW,KAAK,UAAUkB;EAC5B,CAAC;CACH;CAKA,sBAA6B;EAC3B,KAAK,gBAAgB,SAAS,MAAe;GAC3C,EAAW,KAAK,UAAU;EAC5B,CAAC;CACH;CAKA,wBAAgC;EAC9B,KAAK,gBAAgB,SAAS,MAAe;GAI3C,AAFAlB,EAAW,KAAK,MAAM,IAAI,GAAG,GAAG,CAAC,GACjCA,EAAW,KAAK,SAAS,IAAI,GAAG,GAAG,CAAC,GACpCA,EAAW,KAAK,SAAS,IAAI,GAAG,GAAG,CAAC;GAIpC,IAAMnI,IADWmI,EAAW,KAAK,SACN,WAAW;GAKtC,AAFAnI,EAAU,OAAO,GAAGmI,EAAW,MAAM,SAAS,GAAGA,EAAW,MAAM,SAAS,GAAGA,EAAW,MAAM,SAAS,CAAC,GACzGnI,EAAU,OAAO,GAAGmI,EAAW,MAAM,SAAS,GAAGA,EAAW,MAAM,SAAS,GAAGA,EAAW,MAAM,SAAS,CAAC,GACzG,EAAU,cAAc;GAGxB,IAAMkB,IAAoBlB,EAAW,MAAM,WAAWA,EAAW,MAAM;GACvE,EAAW,KAAK,UAAUkB;EAC5B,CAAC;CACH;CAEA,iBAAwB,GAA4D;EAkBlF,AAjBA,KAAK,aAAalV,GAGlB,KAAK,mBAAmBA,CAAM,GAG9B,KAAK,iBAAiBA,CAAM,GAGxB,KAAK,uBACP,4BAA4B;GAE1B,AADA,KAAK,mBAAmBA,CAAM,GAC9B,KAAK,iBAAiBA,CAAM;EAC9B,CAAC,GAIH,KAAK,sBAAsB;CAC7B;AACF;AAEA,SAAS6T,KAAiB;CACxB,IACMxU,IAAW,IAAIjC,EAAM,eAAe,KAAQ,IAAI,EAAE,GAElD+X,IAAgB,IAAI/X,EAAM,kBAAkB;EAChD,OAAO;EACP,MAAMA,EAAM;EACZ,aAAa;EACb,SAAS;EACT,WAAW;EACX,YAAY;CACd,CAAC,GAEKgY,IAAY,IAAIhY,EAAM,KAAKiC,GAAU8V,CAAa;CAExD,AADA,EAAU,OAAO,qBACjB,EAAU,cAAcjV,EAAa;CAGrC,IACMmV,IAAgB,IAAIjY,EAAM,eAAe,KAAa,IAAI,EAAE,GAC5DkY,IAAsB,IAAIlY,EAAM,kBAAkB;EACtD,aAAa;EACb,SAAS;EACT,MAAMA,EAAM;EACZ,WAAW;EACX,YAAY;CACd,CAAC,GAEKmY,IAAoB,IAAInY,EAAM,KAAKiY,GAAeC,CAAmB;CAO3E,OANA,EAAkB,OAAO,+BACzB,EAAkB,cAAcpV,EAAa,qBAG7CqV,EAAkB,IAAIH,CAAS,GAExBG;AACT;AAQA,SAAShB,EAAmB,GAAuB,GAAmC;CACpF,IAAMlV,IAAW,IAAIjC,EAAM,eAAe,GACpCoY,IAAS,CAACC,GAAQC,CAAM;CAC9B,EAAS,cAAcF,CAAM;CAG7B,IAAMlW,IAAW,IAAIlC,EAAM,kBAAkB;EAC3C,OAAO;EACP,SAAS;EACT,aAAa;EACb,WAAW;EACX,YAAY;CACd,CAAC,GAEK0O,IAAO,IAAI1O,EAAM,KAAKiC,GAAUC,CAAQ;CAK9C,OAJA,EAAK,OAAO,wBACZ,EAAK,cAAcY,EAAa,mBAChC,EAAK,gBAAgB,CAAC,GAEf4L;AACT;;;AChZA,IAAa6J,KAAb,cAA0FlN,EAAkB;CAC1G,OAAiB;CAEjB;CAEA;CACA,aAAqB,IAAI6C,EAAe,KAAK,QAAQ,KAAK,WAAW,KAAK,QAAQ,cAAc,CAAC,CAAC;CAElG;CASA,YAAmB,GAAG3C,GAAyD;EAC7E,MAAM,GAAGA,CAAM;EAEf,IAAMnE,IAAO,KAAK,KAAK,KAAK,IAAI,GAC1B6H,IAAO,KAAK,KAAK,KAAK,IAAI,GAE1BC,UAA6B;GAQjC,AAPI,YAAY,KAAK,kBAAkB,OAAO,KAAK,eAAe,UAAW,cAC3E,KAAK,eAAe,OAAO,KAAK,MAAM,GAGpC,KAAK,cACP,KAAK,yBAAyB,GAEhC,KAAK,OAAO;EACd;EAmCA,AAjCAA,EAAqB,GAGrB,KAAK,UAAU,iBAAiB,KAAK,gBAAgB,aAAa,KAAK,SAAS,GAChF,SAAS,iBAAiB,aAAa,KAAK,QAAQ,GACpD,SAAS,iBAAiB,WAAW,KAAK,OAAO,GAEjD,KAAK,UAAU,iBAAiB,KAAK,gBAAgB,cAAc,KAAK,SAAS,GACjF,SAAS,iBAAiB,aAAa,KAAK,QAAQ,GACpD,SAAS,iBAAiB,YAAY,KAAK,OAAO,GAElD,KAAK,MAAM,GAAG,eAAeD,CAAI,GACjC,KAAK,MAAM,GAAG,aAAa7H,CAAI,GAC/B,KAAK,MAAM,GAAG,mBAAmB;GAG/B,AAFA6H,EAAK,GAEL,KAAK,eAAe;EACtB,CAAC,GACD,KAAK,MAAM,GAAG,WAAW7H,CAAI,GAC7B,KAAK,MAAM,GAAG,qBAAqB6H,CAAI,GACvC,KAAK,MAAM,GAAG,sBAAsB7H,CAAI,GACxC,KAAK,MAAM,GAAG,uBAAuB,MAAW;GAQ9C,AAPI,YAAY,KAAK,kBAAkB,OAAO,KAAK,eAAe,UAAW,cAC3E,KAAK,eAAe,OAAOmE,EAAO,MAAM,GAGtC,KAAK,cACP,KAAK,yBAAyB,GAEhC,KAAK,OAAO;EACd,CAAC,GACD,KAAK,YAAY,GAAG,gBAAgB2D,CAAoB,GAExD,KAAK,UAAU,WAAW;GAmBxB,IAlBA,KAAK,UAAU,oBAAoB,KAAK,gBAAgB,aAAa,KAAK,SAAS,GACnF,SAAS,oBAAoB,aAAa,KAAK,QAAQ,GACvD,SAAS,oBAAoB,WAAW,KAAK,OAAO,GAEpD,KAAK,UAAU,oBAAoB,KAAK,gBAAgB,cAAc,KAAK,SAAS,GACpF,SAAS,oBAAoB,aAAa,KAAK,QAAQ,GACvD,SAAS,oBAAoB,YAAY,KAAK,OAAO,GAErD,KAAK,MAAM,IAAI,eAAeD,CAAI,GAClC,KAAK,MAAM,IAAI,aAAa7H,CAAI,GAChC,KAAK,MAAM,IAAI,aAAa6H,CAAI,GAChC,KAAK,MAAM,IAAI,WAAW7H,CAAI,GAC9B,KAAK,MAAM,IAAI,qBAAqB6H,CAAI,GACxC,KAAK,MAAM,IAAI,sBAAsB7H,CAAI,GACzC,KAAK,MAAM,IAAI,oBAAoB,GACnC,KAAK,YAAY,IAAI,gBAAgB8H,CAAoB,GAGrD,KAAK,kBAAkB;IAEzB,AADA,KAAK,MAAM,OAAO,KAAK,gBAAgB,GACvC,KAAK,iBAAiB,SAAS,QAAQ;IACvC,IAAMhN,IAAW,KAAK,iBAAiB;IAGvC,AAFI,MAAM,QAAQA,CAAQ,IAAGA,EAAS,SAAS,MAAM0M,EAAE,QAAQ,CAAC,IAC3D1M,EAAS,QAAQ,GACtB,KAAK,mBAAmB,KAAA;GAC1B;EACF,CAAC;CACH;CAEA,wBAA+B;EAC7B,KAAK,eAAe,gBAAgB;EAGpC,IAAMsW,IAAQ;EAEd,AADIA,EAAM,oBAAkBA,EAAM,iBAAiB,GACnD,EAAM,mBAAmB,KAAK,cAAc,KAAK,eAAe,WAAW;CAC7E;CAEA,aAAoB,MAA8C;EAChE,IAAI,KAAK,YAAY;EAErB,KAAK,aAAa;EAClB,IAAM,EAAE,iBAAcjN,GAChBwB,IAAiB,KAAK,OAAO,UAE7B0L,IAAmB,IAAI,IAAI,KAAK,eAAe,YAAY,KAAK,MAAM7J,EAAE,IAAI,CAAC,GAC/E8J,IAAY7I,EAAU;EAC1B,OAAO6I,EAAU,UAAU,CAACD,EAAiB,IAAIC,EAAU,IAAI,IAC7D,IAAYA,EAAU;EAExB,IAAMC,IAAiBD,GACjBE,IAAmBD,EAAe,cAAc,aAAa,MAAM,GACnEE,IAAqBF,EAAe,cAAc,eAAe,MAAM,GACvEG,IAAaD,EAAmB,MAAM,CAAC,CAAC,IAAID,CAAgB,CAAC,CAAC,MAAM,GAEpElK,IAAO,IAAI1O,EAAM,MAAM4Y,GAAkBA,EAAiB,MAAM,CAAC,CAAC,IAAIE,EAAW,UAAU,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;EACrH,EAAK,aAAa,KAAK,eAAe,WAAW;EAEjD,IAAMrY,IAAY,IAAIT,EAAM,UAAU+M,GAAgB8C,EAAU,MAAM,MAAM,CAAC,CAAC,IAAI9C,CAAc,CAAC,GAC3FsC,IAAQ7P,EAAU;GAAE;GAAW;EAAK,CAAC;EAW3C,AATA,KAAK,YAAY;GAAE;GAAM,iBAAiB6P;GAAO;EAAe,GAGhE,KAAK,eAAe,YAAY,SAAS,MAAS;GAChD,AAAIlH,EAAK,SAASwQ,EAAe,SACjC,EAAK,UAAU;EACjB,CAAC,GAGG,yBAAyB,KAAK,kBAAkB,OAAO,KAAK,eAAe,uBAAwB,cACrG,KAAK,eAAe,oBAAoB;EAI1C,IAAI;GAGF,AADA,KAAK,eAAe,kBAAkB,EAAI,GAC1C,KAAK,eAAe,kBAAkB,EAAI;GAG1C,IAAMrB,IAAe,KAAK,qBAAqB,GAKzC9G,IAFsBqI,EAAmB,MAAM,CAAC,CAAC,aAAa,KAAK,eAAe,WAElE,CAAA,CAAoB,MAAM,CAAC,CAAC,IAAIvB,CAAY,CAAC,CAAC,UAAU,GAGxE1J,IAAS0J,GAGT5I,IAAO,KAAK,WAAW,gBAAgBd,GAAQ4C,GAAe;IAAE,OAAO;IAAU,aAAa1N,EAAa;GAAgB,CAAC;GAGlI,AAFK,KAAK,wBAAwB,KAAG,KAAK,MAAM,IAAI4L,CAAI,GACxD,KAAK,gBAAgBA,GACrB,KAAK,YAAY;EACnB,QAAQ,CAAC;EAKT,AAFA,EAAe,UAAU,IAEzB,KAAK,MAAM,KAAK,YAAY;CAC9B;CAMA,uBAA8C;EAE5C,IAAI,iBAAiB,KAAK,kBAAkB,OAAQ,KAAK,eAAuB,eAAgB,UAC9F,OAAQ,KAAK,eAAuB,YAAY,MAAM;EAGxD,IAAMqK,IAAWtZ,EAAiB,KAAK,cAAc;EACrD,OAAOsZ,IAAWA,EAAS,UAAU,IAAI/Y,EAAM,QAAQ,CAAC,IAAI,KAAK,eAAe,iBAAiB,IAAIA,EAAM,QAAQ,CAAC;CACtH;CAEA,gBAAwB;EACtB,IAAMgZ,IAAQ,CAAC,GACTC,IAAO,KAAK,eAAe,QAAQ,UAAU,MAAM,MAAO7B,EAAG,SAAS,YAAY,CAAC,EAAE,YAAY,CAAC;EACxG,KAAK,IAAMhT,KAAQ6U,GACjB,AAAI7U,EAAK,SAAS,eAChB4U,EAAM,KAAK,GAAG5U,EAAK,QAAQ,IAClBA,EAAK,SAAS,yBACvB4U,EAAM,KAAK5U,CAAI;EAGnB,OAAO4U;CACT;CAEA,iBAAyB,GAAsB;EAK7C,IAHI,KAAK,yBAAyB,MAClC,KAAK,eAAe,GAEhB,CAAC,KAAK,eAAe,QAAQ,wBAAuB;EAGxD,IAAME,IAAQ,KAAK,eAAe,QAAQ,sBAAsB,GAC1DC,IAAc,KAAK,eAAe,aAClCC,IAAa,KAAK,cAAc;EAGtC,IAFmB1I,EAAI,iBAAiB0I,GAAY,EAAK,GAErD1I,EAAI,iBAAiB0I,GAAY,EAAK,CAAC,CAAC,SAAS,GAAG;EAGxD,IAAIC,IAAkB,MAClBC,IAAmB;EAGvB,KAAK,IAAMnR,KAAQgR,GAAa;GAE9B,IAAI,CAAChR,EAAK,SAAS;GAEnB,IAAMyC,IAAa8F,EAAI,gBAAgBvI,GAAM,EAAK;GAClD,IAAIyC,KAAcA,EAAW,SAAS,GAAG;IAGvC,AADA,IAAkBzC,GAClB,IAAmByC,EAAW,EAAE,CAAC,MAAM,MAAM;IAC7C;GACF;EACF;EAGA,IAAIyO,KAAmBC,KAAoB,MAAM,QAAQJ,CAAK,KAAKA,EAAM,SAAS,GAAG;GAEnF,IAAIK,IAAc,MACdC,IAAU;GACd,KAAK,IAAMlK,KAAQ4J,GAAO;IAExB,IAAI,CAAC5J,EAAK,YAAYA,EAAK,SAAS,SAAS,GAAG;IAEhD,IAAM1B,IAAS,IAAI5N,EAAM,QAAQ;IACjC,KAAK,IAAMG,KAAKmP,EAAK,UACnB,EAAO,IAAInP,CAAC;IAEd,EAAO,aAAamP,EAAK,SAAS,MAAM;IAExC,IAAMmK,IAAOH,EAAiB,WAAW1L,CAAM;IAC/C,AAAI6L,IAAOD,MACT,IAAUC,GACV,IAAcnK;GAElB;GAEA,AAAIiK,KACF,KAAK,aAAaA,CAAW;EAEjC;CACF;CAEA,cAAsB;EAEpB,IAAI,KAAK,yBAAyB,GAAG;EACrC,IAAMZ,IAAiB,KAAK,WAAW;EAGvC,IAFI,CAACA,KAED,CAAC,KAAK,eAAe,QAAQ,uBAAuB;EAGxD,IAAMO,IAAQ,KAAK,eAAe,QAAQ,sBAAsB;EAEhE,IAAIA,KAASA,EAAM,SAAS,GAAG;GAE7B,IAAMQ,IAAyBf,EAAe,iBAAiB,IAAI3Y,EAAM,QAAQ,CAAC,GAC9EwZ,IAAU,UACVD,IAAcL,EAAM;GACxB,KAAK,IAAM5J,KAAQ4J,GAAO;IAExB,IAAMS,IAAarK,EAAK,QAEpBsK;IACJ,IAAID,aAAsB3Z,EAAM,SAC9B,IAAY2Z;SACP,IAAI,MAAM,QAAQA,CAAU,KAAKA,EAAW,WAAW,GAC5D,IAAY,IAAI3Z,EAAM,QAAQ2Z,EAAW,IAAIA,EAAW,IAAIA,EAAW,EAAE;SAEzE;IAEF,IAAMF,IAAOG,EAAU,WAAWF,CAAsB;IACxD,AAAID,IAAOD,MACT,IAAUC,GACV,IAAcnK;GAElB;GAEA,KAAK,aAAaiK,CAAW;EAC/B;CACF;CAEA,iBAAyB;EACvB,IAAI,KAAK,kBAAkB;GAEzB,AADA,KAAK,MAAM,OAAO,KAAK,gBAAgB,GACvC,KAAK,iBAAiB,SAAS,QAAQ;GACvC,IAAMrX,IAAW,KAAK,iBAAiB;GAGvC,AAFI,MAAM,QAAQA,CAAQ,IAAGA,EAAS,SAAS,MAAM0M,EAAE,QAAQ,CAAC,IAC3D1M,EAAS,QAAQ,GACtB,KAAK,mBAAmB,KAAA;EAC1B;CACF;CAEA,YAAmB,MAAiD;EAClE,IAAMyN,IAAI,aAAaN,IAAQA,EAAM,QAAQ,EAAE,CAAC,UAAUA,EAAM,GAC1DO,IAAI,aAAaP,IAAQA,EAAM,QAAQ,EAAE,CAAC,UAAUA,EAAM,GAC1DqB,IAAMhO,EAAkB,KAAK,QAAQ;GAAE;GAAG;EAAE,GAAG,KAAK,SAAS,GAG7DmX,IAA2B,KAAK,yBAAyB;EAE/D,IAAI,CAAC,KAAK,cAAc,CAACA,KAA4BnJ,GAEnD,KAAK,iBAAiBA,CAAG;OAI3B,IAAK,KAAK,WAUV,OARKA,KAEL,KAAK,MAAMA,CAAG,GAEd,KAAK,6BAA6B,GAElC,KAAK,eAAe,GACpB,KAAK,YAAY,GACV,MARU,KAAK,QAAQ;CAShC;CAEA,SAAgB,GAAwD;EACtE,IAAIf,IAAI,GACJC,IAAI,GACJyD,IAAI;EACR,AAAI,OAAOtO,KAAU,YACnB,IAAIA,GACJ,IAAIA,GACJ,IAAIA,KACK,OAAOA,KAAU,aAC1B,IAAIA,EAAM,KAAK,GACf,IAAIA,EAAM,KAAK,GACf,IAAIA,EAAM,KAAK;EAEjB,IAAM+U,IAAe,IAAI9Z,EAAM,QAAQ2P,GAAGC,GAAGyD,CAAC;EAG9C,AADiB,KAAK,MAAM,KAAK,eAAeyG,CAC5C,MAEJ,KAAK,eAAe,MAAM,KAAKA,CAAY,GAC3C,KAAK,cAAc,KAAK,kBAAkBA,CAAY,GACtD,KAAK,MAAM,KAAK,SAASA,CAAY,GACrC,KAAK,OAAO;CACd;CAEA,gCAEI,KAAK,eAAe,SAAS,2BAC7B;EAAC;EAAW;EAAY;EAAc;CAAa,CAAC,CAAC,SAAS,KAAK,UAAU,eAAe,cAAc,EAAE;CAIhH,SAAgB,MAA+B;EAC7C,IAAI,CAAC,KAAK,WAAW;EACrB,IAAM,EAAE,SAAM,oBAAiB,sBAAmB,KAAK,WACjD,EAAE,qBAAkBnB;EAE1B,IAAI,KAAK,wBAAwB,GAAG;GAClC,IAAMxQ,IAAO,KAAK,gBAMZ4R,IAHW5R,EAAK,SAGG,WAAW;GACpC,IAAI,CAAC4R,GAAS,OAAO,CAAC;GAEtB,IAAMC,IAA2B,CAAC,GAC5BC,IAAcF,EAAQ;GAI5B,KAAK,IAAI7R,IAAI,GAAGA,IAAI+R,GAAa,KAAK;IACpC,IAAMC,IAAS,IAAIla,EAAM,QAAQ,CAAC,CAAC,oBAAoB+Z,GAAkC7R,CAAC;IAI1F,AAFAC,EAAK,kBAAkB,EAAI,GAC3B+R,EAAO,aAAa/R,EAAK,WAAW,GACpC6R,EAAQ,KAAKE,CAAM;GACrB;GAGA,IAAM9B,IAAS4B,EAAQ,MAAM,GAAG,CAAC;GAEjC,IAAI,CAAC5B,KAAUA,EAAO,SAAS,GAAG;GAElC,IAAMtU,IAAS1E,EAAUgZ,CAAM,CAAC,CAAC,UAAU,GAErC9H,IAAQ,IAAItQ,EAAM,MAAM,CAAC,CAAC,8BAA8B8D,GAAQsU,EAAO,EAAE,GAIzE+B,IADe,KAAK,IAAI1Z,EAAU,IAAI,UAAU,IAAIqD,CAAM,CACvC,IAAe,IAEpCsW;GAEJ,IAAID,GAIF,IAFc3a,EAAU;IAAE;IAAW;IAAM,aAAa;GAAM,CAE7C,CAAA,CAAM,aAAa,IAAIQ,EAAM,QAAQ,CAAC,CAAC,KAAK,KAAK,eAAe,YAAY,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;QACzG;IAEL,IAAMqa,IAAiB,IAAIra,EAAM,QAAQ;IAEzC,IADAS,EAAU,IAAI,eAAe6P,GAAO+J,CAAc,GAC9C,CAACA,GAAgB;IAGrB,IAAMC,IAAgB,IAAIta,EAAM,QAAQ,CAAC,CAAC,KAAK,KAAK,eAAe,WAAW,CAAC,CAAC,OAAO;IACvF,IAAiBqa,EAAe,MAAM,CAAC,CAAC,aAAaC,CAAa;GACpE;GAEA,IAAMC,IAAaC,EAAgB,MAAM,CAAC,CAAC,aAAa,IAAIxa,EAAM,QAAQ,CAAC,CAAC,KAAK,KAAK,eAAe,WAAW,CAAC,CAAC,OAAO,CAAC;GAW1H,AATgB,KAAK,QAAQ,gBAAgB;IAC3C,gBAAgBoa;IAChB;IACA,QAAQA,EAAe,MAAM,CAAC,CAAC,IAAIG,CAAU;IAC7C,6BAA6B,KAAK,eAAe,sBAAsB;GACzE,CAAC,MAGe,MAAO5B,EAAe,SAAS,KAAKyB,CAAc,GAClE,KAAK,MAAM,KAAK,SAAS,IAAIpa,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC;GACnD;EACF;EAEA,IAAMqP,IAAQ7P,EAAU;GAAE;GAAW;GAAM,aAAa;EAAM,CAAC;EAc/D,AAZA6P,EAAM,aAAa,IAAIrP,EAAM,QAAQ,CAAC,CAAC,KAAK,KAAK,eAAe,YAAY,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GAE7E,KAAK,QAAQ,gBAAgB;GAC3C,gBAAgBqP;GAChB;GACA,QAAQA,EAAM,MAAM,CAAC,CAAC,IAAImL,CAAe;GACzC,6BAA6B,KAAK,eAAe,sBAAsB;EACzE,CAAC,MAGe,MAAO7B,EAAe,SAAS,KAAKtJ,EAAM,MAAM,CAAC,GAEjE,KAAK,MAAM,KAAK,SAAS,IAAIrP,EAAM,QAAQ,GAAG,GAAG,CAAC,CAAC;CACrD;CAEA,gBAAuB;EACrB,IAAK,KAAK,YAEV;GAcA,IAdA,KAAK,YAAY,KAAA,GACjB,KAAK,aAAa,IAGlB,KAAK,eAAe,YAAY,SAAS,MAAS;IAChD,EAAK,UAAU;GACjB,CAAC,GAGG,yBAAyB,KAAK,kBAAkB,OAAO,KAAK,eAAe,uBAAwB,cACrG,KAAK,eAAe,oBAAoB,GAItC,KAAK,eAAe;IAEtB,AADA,KAAK,MAAM,OAAO,KAAK,aAAa,GACpC,KAAK,cAAc,SAAS,QAAQ;IACpC,IAAMkC,IAAW,KAAK,cAAc;IAGpC,AAFI,MAAM,QAAQA,CAAQ,IAAGA,EAAS,SAAS,MAAM0M,EAAE,QAAQ,CAAC,IAC3D1M,EAAS,QAAQ,GACtB,KAAK,gBAAgB,KAAA;GACvB;GAMA,AAHA,KAAK,eAAe,GAEpB,KAAK,cAAc,KAAK,uBAAuB,GAC/C,KAAK,MAAM,KAAK,UAAU;EA3BT;CA6BnB;CAKA,+BAAuC;EACrC,IAAI,CAAC,KAAK,iBAAiB,CAAC,KAAK,WAAW;EAI5C,AADA,KAAK,eAAe,kBAAkB,EAAI,GAC1C,KAAK,eAAe,kBAAkB,EAAI;EAE1C,IAAMH,IAAY,KAAK,UAAU,KAAK,MAAM,IAAI/B,EAAM,QAAQ,CAAC,CAAC,CAAC,UAAU,GACrE4N,IAAS,KAAK,qBAAqB;EAEzC,KAAK,WAAW,gBAAgB,KAAK,eAAeA,GAAQ7L,CAAS;CACvE;CAKA,2BAAmC;EACjC,IAAI,CAAC,KAAK,iBAAiB,CAAC,KAAK,WAAW;EAG5C,IAAM,EAAE,qBAAkB,KAAK,UAAU,gBACnC0Y,IAAc/D,EAAc,eAAe,MAAM,CAAC,CAAC,aAAa,KAAK,eAAe,WAAW,GAC/FgE,IAAYhE,EAAc,aAAa,MAAM,CAAC,CAAC,aAAa,KAAK,eAAe,WAAW,GAC3F9I,IAAS6M,GACTjK,IAAgBiK,EAAY,MAAM,CAAC,CAAC,IAAIC,CAAS,CAAC,CAAC,UAAU;EAEnE,KAAK,WAAW,gBAAgB,KAAK,eAAe9M,GAAQ4C,CAAa;CAC3E;CAKA,2BAA4C;EAE1C,OAAO,KAAK,kBAAkB,gBAAgB,cAAc,KAAK;CACnE;CAKA,aACE,GAWA;EAEA,IAAI,KAAK,kBAAkB;GAEzB,AADA,KAAK,MAAM,OAAO,KAAK,gBAAgB,GACvC,KAAK,iBAAiB,SAAS,QAAQ;GACvC,IAAMtO,IAAW,KAAK,iBAAiB;GAGvC,AAFI,MAAM,QAAQA,CAAQ,IAAGA,EAAS,SAAS,MAAM0M,EAAE,QAAQ,CAAC,IAC3D1M,EAAS,QAAQ,GACtB,KAAK,mBAAmB,KAAA;EAC1B;EAEA,IAAI,CAACoN,EAAK,YAAYA,EAAK,SAAS,SAAS,GAAG;GAC9C,QAAQ,KAAK,2CAA2C;GACxD;EACF;EAGA,IAAMrN,IAAW,IAAIjC,EAAM,eAAe;EAG1C,IAAIsP,EAAK,SAAS,WAAW,GAAG;GAE9B,IAAMqL,IAAW,IAAI,aAAa;IAEhCrL,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IAEjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;IACjBA,EAAK,SAAS,EAAE,CAAC;GACnB,CAAC;GAGD,AADArN,EAAS,aAAa,YAAY,IAAIjC,EAAM,gBAAgB2a,GAAU,CAAC,CAAC,GACxE1Y,EAAS,SAAS;IAAC;IAAG;IAAG;IAAG;IAAG;IAAG;GAAC,CAAC;EACtC,OAAO;GAEL,IAAM0Y,IAAW,IAAI,aAAarL,EAAK,SAAS,SAAS,CAAC,GACpDsL,IAAU,IAAI,YAAYtL,EAAK,SAAS,MAAM;GAUpD,AARAA,EAAK,SAAS,SAAS,GAAQ,MAAU;IAIvC,AAHA,EAASvF,IAAQ,KAAKmQ,EAAO,GAC7B,EAASnQ,IAAQ,IAAI,KAAKmQ,EAAO,GACjC,EAASnQ,IAAQ,IAAI,KAAKmQ,EAAO,GACjC,EAAQnQ,KAASA;GACnB,CAAC,GAED9H,EAAS,aAAa,YAAY,IAAIjC,EAAM,gBAAgB2a,GAAU,CAAC,CAAC,GACxE1Y,EAAS,SAAS,IAAIjC,EAAM,gBAAgB4a,GAAS,CAAC,CAAC;EACzD;EAGA,EAAS,qBAAqB;EAE9B,IAAM1Y,IAAW,IAAIlC,EAAM,kBAAkB;GAC3C,OAAO;GACP,MAAMA,EAAM;GACZ,WAAW;GACX,YAAY;GACZ,aAAa;GACb,SAAS;EACX,CAAC,GAEK6a,IAAQ,IAAI7a,EAAM,KAAKiC,GAAUC,CAAQ;EAO/C,OAJA,EAAM,cAAcY,EAAa,iBACjC,KAAK,MAAM,IAAI+X,CAAK,GACpB,KAAK,mBAAmBA,GACxB,KAAK,OAAO,GACLA;CACT;AACF;;;AC1jBA,SAASC,EAAU,GAAQ,GAAY;CAKrC,AAJA,KAAK,UAAUlY,KAAU,MACzB,KAAK,cAAcmY,KAAc,UACjC,KAAK,aAAa,IAAI/a,EAAM,UAAU,GACtC,KAAK,YAAY,MACjB,KAAK,aAAa,CAAC;CAEnB,IAAIwY,IAAQ;CAqCZ,AAnCA,KAAK,YAAY,WAAY;EAC3B,EAAM,SAAS,MAAMA,GAAO,SAAS;CACvC,GACA,KAAK,eAAe,WAAY;EAC9B,EAAM,YAAY,MAAMA,GAAO,SAAS;CAC1C,GACA,KAAK,gBAAgB,WAAY;EAC/B,EAAM,aAAa,MAAMA,GAAO,SAAS;CAC3C,GACA,KAAK,gBAAgB,WAAY;EAC/B,EAAM,aAAa,MAAMA,GAAO,SAAS;CAC3C,GACA,KAAK,cAAc,WAAY;EAC7B,EAAM,WAAW,MAAMA,GAAO,SAAS;CACzC,GACA,KAAK,gBAAgB,WAAY;EAC/B,EAAM,aAAa,MAAMA,GAAO,SAAS;CAC3C,GACA,KAAK,iBAAiB,WAAY;EAChC,EAAM,cAAc,MAAMA,GAAO,SAAS;CAC5C,GACA,KAAK,eAAe,WAAY;EAC9B,EAAM,YAAY,MAAMA,GAAO,SAAS;CAC1C,GACA,KAAK,kBAAkB,WAAY;EACjC,EAAM,eAAe,MAAMA,GAAO,SAAS;CAC7C,GACA,KAAK,YAAY,iBAAiB,SAAS,KAAK,WAAW,EAAK,GAChE,KAAK,YAAY,iBAAiB,YAAY,KAAK,cAAc,EAAK,GACtE,KAAK,YAAY,iBAAiB,aAAa,KAAK,eAAe,EAAK,GACxE,KAAK,YAAY,iBAAiB,aAAa,KAAK,eAAe,EAAK,GACxE,KAAK,YAAY,iBAAiB,WAAW,KAAK,aAAa,EAAK,GACpE,KAAK,YAAY,iBAAiB,aAAa,KAAK,eAAe,EAAK,GACxE,KAAK,YAAY,iBAAiB,cAAc,KAAK,gBAAgB,EAAK,GAC1E,KAAK,YAAY,iBAAiB,YAAY,KAAK,cAAc,EAAK,GACtE,KAAK,YAAY,iBAAiB,eAAe,KAAK,iBAAiB,EAAK;AAC9E;AAGA,EAAU,UAAU,UAAU,WAAY;CAUxC,AARA,KAAK,YAAY,oBAAoB,SAAS,KAAK,WAAW,EAAK,GACnE,KAAK,YAAY,oBAAoB,YAAY,KAAK,cAAc,EAAK,GACzE,KAAK,YAAY,oBAAoB,aAAa,KAAK,eAAe,EAAK,GAC3E,KAAK,YAAY,oBAAoB,aAAa,KAAK,eAAe,EAAK,GAC3E,KAAK,YAAY,oBAAoB,WAAW,KAAK,aAAa,EAAK,GACvE,KAAK,YAAY,oBAAoB,aAAa,KAAK,eAAe,EAAK,GAC3E,KAAK,YAAY,oBAAoB,cAAc,KAAK,gBAAgB,EAAK,GAC7E,KAAK,YAAY,oBAAoB,YAAY,KAAK,cAAc,EAAK,GACzE,KAAK,YAAY,oBAAoB,eAAe,KAAK,iBAAiB,EAAK;AACjF,GAEA,EAAU,aAAa;CACrB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,GAEA,EAAU,UAAU,sBAAsB,SAAU,GAAU;CAC5D,IAAIlW,IAAU0Y,EAAS,UAAUA,EAAS;CAC1C,AAAI1Y,EAAQ,aAAa,MACvB,IAAUA,EAAQ;CAKpB,IAAI2Y,IAAa;EAAE,GAAG;EAAG,GAAG;CAAE,GAC1BC,IAAa5Y,GAEb2E,IAAQ,iBAAiBiU,GAAY,IAAI;CAE7C,AADA,EAAW,KAAK,SAASjU,EAAM,iBAAiB,aAAa,GAAG,EAAE,GAClE,EAAW,KAAK,SAASA,EAAM,iBAAiB,cAAc,GAAG,EAAE;CAEnE;EAME,AALA,EAAW,KAAKiU,EAAW,YAC3B,EAAW,KAAKA,EAAW,WAC3B,IAAQ,iBAAiBA,GAAY,IAAI,GAEzC,EAAW,KAAK,SAASjU,EAAM,iBAAiB,mBAAmB,GAAG,EAAE,GACxE,EAAW,KAAK,SAASA,EAAM,iBAAiB,kBAAkB,GAAG,EAAE;QAC/D,IAAaiU,EAAW;CAElC,IAAIC,IAAc;EAChB,OAAO7Y,MAAY,SAAS,OAAO,aAAaA,EAAQ;EACxD,QAAQA,MAAY,SAAS,OAAO,cAAcA,EAAQ;CAC5D;CAEA,OAAO;EACL,GAAG,QAAQ0Y,EAAS,QAAQC,EAAW,KAAKE,EAAY,KAAK,IAAI,IAAI;EACrE,GAAG,GAAGH,EAAS,QAAQC,EAAW,KAAKE,EAAY,UAAU,IAAI;CACnE;AACF,GAQA,EAAU,UAAU,iBAAiB,SAAU,GAAU;CACvD,EAAS,cAAc,CAAC;AAC1B,GACA,EAAU,UAAU,mBAAmB,SAAU,GAAU;CACzD,OAAOC,EAAS;AAClB,GACA,EAAU,UAAU,mBAAmB,SAAU,GAAU;CACzD,OAAO,IAAS;AAClB,GACA,EAAU,UAAU,gBAAgB,SAAU,GAAU;CACtD,OAAOA,EAAS;AAClB,GASA,EAAU,UAAU,SAAS,SAAU,GAAO;CAE5C,OADIhW,MAAO,KAAK,UAAUA,IACnB,KAAK;AACd,GAEA,EAAU,UAAU,OAAO,SAAU,GAAU,GAAW,GAAU,GAAY;CAG9E,AAFA,QAAQ,OAAO0V,EAAU,WAAW,QAAQO,CAAS,MAAM,IAAI,0BAA0BA,CAAS,GAE7F,KAAK,iBAAiBD,CAAQ,KAAG,KAAK,eAAeA,CAAQ;CAClE,IAAIE,IAAY,KAAK,cAAcF,CAAQ;CAY3C,AAXKE,EAAUD,IAAY,gBAAa,EAAUA,IAAY,cAAc,CAAC,IAE7EC,EAAUD,IAAY,WAAW,CAAC,KAAK;EAC3B;EACE;CACd,CAAC,GAGG,KAAK,WAAWA,OAAe,KAAA,MACjC,KAAK,WAAWA,KAAa,CAAC,IAEhC,KAAK,WAAWA,EAAU,CAAC,KAAKD,CAAQ;AAC1C,GACA,EAAU,UAAU,mBAAmBN,EAAU,UAAU,MAE3D,EAAU,UAAU,SAAS,SAAU,GAAU,GAAW,GAAU,GAAY;CAGhF,AAFA,QAAQ,OAAOA,EAAU,WAAW,QAAQO,CAAS,MAAM,IAAI,0BAA0BA,CAAS,GAE7F,KAAK,iBAAiBD,CAAQ,KAAG,KAAK,eAAeA,CAAQ;CAElE,IAAIE,IAAY,KAAK,cAAcF,CAAQ;CAC3C,AAAKE,EAAUD,IAAY,gBAAa,EAAUA,IAAY,cAAc,CAAC;CAG7E,KAAK,IADDE,IAAWD,EAAUD,IAAY,aAC5BnT,IAAI,GAAGA,IAAIqT,EAAS,QAAQ,KAAK;EACxC,IAAIC,IAAUD,EAASrT;EACvB,IAAIuT,KAAYD,EAAQ,YACpBE,KAAcF,EAAQ,YAC1B;KAAS,OAAOtT,GAAG,CAAC;GACpB;EADoB;CAEtB;CAEA,IAAI6B,IAAQ,KAAK,WAAWsR,EAAU,CAAC,QAAQD,CAAQ;CACvD,KAAK,WAAWC,EAAU,CAAC,OAAOtR,GAAO,CAAC;AAC5C,GACA,EAAU,UAAU,sBAAsB+Q,EAAU,UAAU,QAE9D,EAAU,UAAU,SAAS,SAAU,GAAW,GAAU;CAC1D,IAAIQ,IAAY,KAAK,cAAcF,CAAQ;CAE3C,OADKE,IACE,IAAUD,IAAY,cADN;AAEzB,GAOA,EAAU,UAAU,mBAAmB,SAAU,GAAU;CAEzD,KADA,IAAIM,IAAUP,GACPO,IAAS;EACd,IAAIA,EAAQ,YAAY,IACtB,OAAO;EAET,IAAUA,EAAQ;CACpB;CACA,OAAO;AACT,GAOA,EAAU,UAAU,wBAAwB,SAAU,GAAS;CAC7D,IAAInD,IAAQ;CACZ,OAAOxM,EAAQ,OAAO,SAAU,GAAK;EACnC,OAAOwM,EAAM,iBAAiBoD,CAAG;CACnC,CAAC;AACH,GAQA,EAAU,UAAU,UAAU,SAAU,GAAW,GAAQ,GAAQ,GAAc;CAE/E,IAAIC,IAAY,KAAK,WAAWR;CAChC,IAAIQ,MAAc,KAAA,KAAaA,EAAU,WAAW,GAGpD;MAAIC,IAAmB,KAAK,sBAAsBD,CAAS;EAC3D,IAAIC,EAAiB,WAAW,GAGhC;OAAInW,IAAS,IAAI3F,EAAM,QAAQ;GAI/B,AADA2F,EAAO,IAAIoW,GAAQC,CAAM,GACzB,KAAK,WAAW,cAAcrW,GAAQ,KAAK,OAAO;GAElD,IAAIiF,IAAa,KAAK,WAAW,iBAAiBkR,CAAgB,GAG9DtD,IAAQ;GAMZ,AALA,IAAa5N,EAAW,OAAO,SAAU,GAAW;IAClD,OAAO4N,EAAM,iBAAiB3I,EAAU,MAAM;GAChD,CAAC,GAGDjF,EAAW,KAAK,SAAU,GAAG,GAAG;IAC9B,IAAIqR,IAAelY,EAAE,OAAO,eAAe,GACvCmY,IAAelY,EAAE,OAAO,eAAe;IAQ3C,OALIiY,MAAiBC,IAKdnY,EAAE,WAAWC,EAAE,WAJbkY,IAAeD;GAK1B,CAAC;GAED,IAAIE,IAAc,KAAK;GAEvB,IAAIvR,EAAW,SAAS,GAAG;IACzB,IAAIwR,GACAC,GACAC,GACAzM,IAAYjF,EAAW,IACvB2R,IAAc1M,EAAU;IAK5B,AAJA,KAAK,YAAY0M,GAEjB,IAAa,KAAK,OAAO,aAAaA,CAAW,GAE7CJ,KAAeI,MAEjB,IAAa,KAAK,OAAO,aAAaA,CAAW,GAEjD,IAAYJ,KAAe,KAAK,OAAO,YAAYA,CAAW;GAElE,OAGE,AADA,IAAYA,KAAe,KAAK,OAAO,YAAYA,CAAW,GAC9D,KAAK,YAAY;GAQnB,AAJAG,KAAc,KAAK,QAAQ,aAAaC,GAAaC,GAAc3M,CAAS,GAE5EuM,KAAc,KAAK,QAAQ,aAAaG,GAAaC,GAAc3M,CAAS,GAE5EwM,KAAa,KAAK,QAAQ,YAAYF,GAAaK,GAAc3M,CAAS;EAzD3C;CAJ4B;AA8D7D,GAQA,EAAU,UAAU,WAAW,SAAU,GAAW,GAAQ,GAAQ,GAAc;CAEhF,IAAIgM,IAAY,KAAK,WAAWR;CAChC,IAAIQ,MAAc,KAAA,KAAaA,EAAU,WAAW,GAGpD;MAAIC,IAAmB,KAAK,sBAAsBD,CAAS;EAC3D,IAAIC,EAAiB,WAAW,GAGhC;OAAInW,IAAS,IAAI3F,EAAM,QAAQ;GAI/B,AADA2F,EAAO,IAAIoW,GAAQC,CAAM,GACzB,KAAK,WAAW,cAAcrW,GAAQ,KAAK,OAAO;GAElD,IAAIiF,IAAa,KAAK,WAAW,iBAAiBkR,GAAkB,EAAI,GAEpEtD,IAAQ;GAmBZ,IAlBA,IAAa5N,EAAW,OAAO,SAAU,GAAW;IAClD,OAAO4N,EAAM,iBAAiB3I,EAAU,MAAM;GAChD,CAAC,GAGDjF,EAAW,KAAK,SAAU,GAAG,GAAG;IAC9B,IAAIqR,IAAelY,EAAE,OAAO,eAAe,GACvCmY,IAAelY,EAAE,OAAO,eAAe;IAQ3C,OALIiY,MAAiBC,IAKdnY,EAAE,WAAWC,EAAE,WAJbkY,IAAeD;GAK1B,CAAC,GAEGrR,EAAW,WAAW,GAE1B;IAKA,KALA,IAAIiF,IAAYjF,EAAW,IACvBwQ,IAAWvL,EAAU,QACrByL,IAAY,KAAK,cAAcF,CAAQ,GACvCqB,IAAerB,EAAS,QAEdE,MAAc,UAAemB,IAEzC,AADA,IAAY,KAAK,cAAcA,CAAY,GAC3C,IAAeA,EAAa;IAE9B,AAAKnB,KAGL,KAAK,QAAQD,GAAWD,GAAUoB,GAAc3M,CAAS;GAZ9B;EA7BI;CAJ4B;AA8C7D,GAEA,EAAU,UAAU,UAAU,SAAU,GAAW,GAAU,GAAc,GAAW;CACpF,IAAIyL,IAAY,KAAK,cAAcF,CAAQ,GACvCG,IAAWD,IAAYA,EAAUD,IAAY,cAAc;CAG/D,IAAI,CAACC,KAAa,CAACC,KAAYA,EAAS,WAAW,GACjD,EAAS,UAAU,KAAK,QAAQF,GAAWD,EAAS,QAAQoB,GAAc3M,CAAS;MAMrF,KAAK,IADD0L,IAAWD,EAAUD,IAAY,aAC5BnT,IAAI,GAAGA,IAAIqT,EAAS,QAAQ,KAAK;EACxC,IAAIC,IAAUD,EAASrT,IACnBwU,IAAc;EAUlB,AATAlB,EAAQ,SAAS;GACf,MAAMH;GACN,QAAQD;GACM;GACH;GACX,iBAAiB,WAAY;IAC3B,IAAc;GAChB;EACF,CAAC,GACIsB,KAEDlB,EAAQ,eAAe,MACzBJ,EAAS,UAAU,KAAK,QAAQC,GAAWD,EAAS,QAAQoB,GAAc3M,CAAS;CAEvF;AACF,GAOA,EAAU,UAAU,eAAe,SAAU,GAAO;CAClD,OAAO,KAAK,cAAc,aAAaH,CAAK;AAC9C,GACA,EAAU,UAAU,aAAa,SAAU,GAAO;CAChD,OAAO,KAAK,cAAc,WAAWA,CAAK;AAC5C,GAEA,EAAU,UAAU,gBAAgB,SAAU,GAAW,GAAU;CACjE,IAAIiN,IAAc,KAAK,oBAAoB3B,CAAQ;CACnD,KAAK,SAASK,GAAWsB,EAAY,GAAGA,EAAY,GAAG3B,CAAQ;AACjE,GAEA,EAAU,UAAU,eAAe,SAAU,GAAU;CACrD,IAAI2B,IAAc,KAAK,oBAAoB3B,CAAQ;CAGnD,AAFA,KAAK,QAAQ,aAAa2B,EAAY,GAAGA,EAAY,GAAG3B,CAAQ,GAChE,KAAK,QAAQ,aAAa2B,EAAY,GAAGA,EAAY,GAAG3B,CAAQ,GAChE,KAAK,QAAQ,YAAY2B,EAAY,GAAGA,EAAY,GAAG3B,CAAQ;AACjE,GAEA,EAAU,UAAU,WAAW,SAAU,GAAO;CAE9C,KAAK,cAAc,SAAStL,CAAK;AACnC,GACA,EAAU,UAAU,cAAc,SAAU,GAAO;CAEjD,KAAK,cAAc,YAAYA,CAAK;AACtC,GAEA,EAAU,UAAU,iBAAiB,SAAU,GAAO;CAEpD,KAAK,cAAc,eAAeA,CAAK;AACzC,GAOA,EAAU,UAAU,gBAAgB,SAAU,GAAO;CACnD,OAAO,KAAK,cAAc,cAAcA,CAAK;AAC/C,GACA,EAAU,UAAU,cAAc,SAAU,GAAO;CACjD,OAAO,KAAK,cAAc,YAAYA,CAAK;AAC7C,GAEA,EAAU,UAAU,eAAe,SAAU,GAAU;CACrD,IAAIsL,EAAS,QAAQ,UAAU,GAI/B;MAAIe,IAAS,OAAOf,EAAS,QAAQ,EAAE,CAAC,QAAQ,OAAO,UAAU,IAAI,IAAI,GACrEgB,IAAS,EAAEhB,EAAS,QAAQ,EAAE,CAAC,QAAQ,OAAO,eAAe,IAAI;EAGrE,AAFA,KAAK,QAAQ,aAAae,GAAQC,GAAQhB,CAAQ,GAClD,KAAK,QAAQ,aAAae,GAAQC,GAAQhB,CAAQ,GAClD,KAAK,QAAQ,YAAYe,GAAQC,GAAQhB,CAAQ;CAJwB;AAK3E,GAEA,EAAU,UAAU,gBAAgB,SAAU,GAAW,GAAU;CAGjE,IAAI4B,IAAU5B,EAAS;CAKvB,IAJI4B,EAAQ,UAAU,MACpB,IAAU5B,EAAS,iBAGjB4B,EAAQ,UAAU,GAItB;MAAIb,IAAS,OAAOa,EAAQ,EAAE,CAAC,QAAQ,OAAO,UAAU,IAAI,IAAI,GAC5DZ,IAAS,EAAEY,EAAQ,EAAE,CAAC,QAAQ,OAAO,eAAe,IAAI;EAC5D,KAAK,SAASvB,GAAWU,GAAQC,GAAQhB,CAAQ;CAFe;AAGlE;;;AC7fA,IAAM6B,IAAc,wBAEPC,IAASD,GAuFhBE,WAAyB;CAC7B,QAAQ,MAAM,GAAGD,EAAO,aAAa;AACvC,GAEME,WAAuB;CAC3B,QAAQ,KAAK,GAAGF,EAAO,aAAa;AACtC,GAEMG,WAAwB;CAC5B,QAAQ,MAAM,GAAGH,EAAO,aAAa;AACvC,GAEaI,KAAb,cAA8Cre,EAA8E;CAC1H,OAAcge;CACd,QAAoC;EAClC,SAAS;EACT,SAAS;EACT,UAAU;CACZ;CAEA,kCAAoG,IAAI,IAAI;CAE5G,uCAA2E,IAAI,IAAI;CACnF,qCAA0D,IAAI,IAAI;CAElE;CAEA,YAAmB,GAAY;EAG7B,AAFA,MAAMrL,CAAI,GACV,KAAK,OAAOA,GACZ,KAAK,cAAc,IAAI5R,EAAY,KAAK,KAAK,KAAK;CAKpD;CAKA,MAAa,KAAK,GAAoC;EACpD,KAAK,SAAS,EAAE,SAAS,GAAK,GAAGiI,CAAO;CAC1C;CAKA,MAAa,KAAK,GAAoC;EACpD,KAAK,SAAS,EAAE,SAAS,GAAM,GAAGA,CAAO;CAC3C;CAKA,OAAc,GAAoC;EAChD,KAAK,SAAS,EAAE,SAAS,GAAK,GAAGA,CAAO;CAC1C;CAKA,QAAe,GAAoC;EACjD,KAAK,SAAS,EAAE,SAAS,GAAM,GAAGA,CAAO;CAC3C;CAKA,UAAiB;EACf,KAAK,SAAS,EAAE,UAAU,GAAK,CAAC;CAClC;CAEA,SAAgB,GAAqC,GAAgE;EACnH,IAAI,KAAK,MAAM,UAAU,OAAOkV,GAAiB;EACjD,IAAI,CAAC,KAAK,MAAM,WAEVzK,EAAM,YAAY,MAAQA,EAAM,aAAa,IAAM,OAAO2K,GAAgB;EAEhF,IAAM1K,IAAY,EAAE,GAAG,KAAK,MAAM;EAYlC,AAXA,KAAK,QAAQ;GAAE,GAAG,KAAK;GAAO,GAAGD;EAAM,GACnCA,EAAM,aAAa,KAAA,KAAaA,EAAM,aAAaC,EAAU,YAC3DD,EAAM,YAAU,KAAK,cAAc,GAErCA,EAAM,YAAY,KAAA,KAAaA,EAAM,YAAYC,EAAU,WAC7D,KAAK,cAAcD,EAAM,OAAO,GAE9BA,EAAM,YAAY,KAAA,KAAaA,EAAM,YAAYC,EAAU,WAC7D,KAAK,aAAaD,EAAM,OAAO,GAGjC,KAAK,MAAM,KAAK,eAAe;GAAE,OAAO,KAAK;GAAO;EAAU,CAAC;CACjE;CAEA,kBAAyB,GAA0B;EACjD,OAAO,KAAK,gBAAgB,IAAIrG,CAAQ;CAC1C;CASA,kBAAyB,GAA0B,IAAwC,CAAC,GAAwC;EAClI,IAAI,CAACA,GAAU;GACb,QAAQ,MAAM,uBAAuB;GACrC;EACF;EAEA,IAAI,KAAK,gBAAgB,IAAIA,CAAQ,GAAG;GACtC,QAAQ,KAAK,kCAAkCA,EAAS,KAAK,uBAAuB;GACpF;EACF;EACA,IAAM6C,IAAS,IAAIsD,GAAe,GAE5BlG,IAA2B,CAAC,GAE5B5D,IAAY,KAAK,KAAK,WAAW,CAAC,EAAE,eACpC1F,IAAS,KAAK,KAAK,QAUnBpC,IAAS;GANb,YAAY;GACZ,cAAc;GACd,aAAa;GACb,mBAAmB;GACnB,cAAc;GAEmB,GAAG2c;EAAa,GAC7C,EAAE,eAAY,iBAAc,gBAAa,yBAAsB3c,GAE/DqR,IAAQ/C,EAAO,OACfgD,IAAgB,IAAI/S,EAAU,GAC9B6S,IAAY,IAAIkJ,EAAU,KAAK,KAAK,QAAQ,KAAK,KAAK,WAAW,CAAC,GAElEsC,KAAgB,MAA6B;GACjD,IAAKtO,GAEL,OADI,OAAOA,KAAW,YAAkBA,IACjCA,EAAO;EAChB,GAGMuD,IAAsC,CAAC;EAG7C,IAAI+K,EAAaC,CAAU,GAAG;GAC5B,IAAMC,IAAI;IAAE,GAAG,KAAK,UAAU9c,EAAO,UAAU;IAAG,GAAGA;GAAO,GACtD6c,IAAa,IAAIrX,EAAWiG,GAAU,EAAE,GAAGqR,EAAE,CAAC,GAC9CC,IAAoB,IAAIze,EAC5B,KAAK,MACL8S,GACA/C,IACA5C,GACAoR,GACAC,GACAzL,GACAC,CACF;GAEA,AADA,EAAY,iBAAiByL,EAAkB,kBAC/CrR,EAAU,WAAWqR,EAAkB,QAAQ,CAAC;EAClD;EAEA,IAAIH,EAAaI,CAAY,GAAG;GAC9B,IAAMF,IAAI;IAAE,GAAG,KAAK,UAAU9c,EAAO,YAAY;IAAG,GAAGA;GAAO,GACxDgd,IAAe,IAAInW,GAAa4E,GAAU;IAAE;IAAW,GAAGqR;GAAE,CAAC,GAC7DC,IAAoB,IAAIze,EAC5B,KAAK,MACL8S,GACAoB,IACA/G,GACAuR,GACAF,GACAzL,GACAC,CACF;GAEA,AADA,EAAY,mBAAmByL,EAAkB,kBACjDrR,EAAU,WAAWqR,EAAkB,QAAQ,CAAC;EAClD;EAEA,IAAIH,EAAaK,CAAiB,GAAG;GACnC,IAAMA,IAAoB,IAAI/S,GAAkBuB,CAAQ,GAClDsR,IAAoB,IAAIze,EAC5B,KAAK,MACL8S,GACA0E,IACArK,GACAwR,GACA,KAAA,GACA5L,GACAC,CACF;GAEA,AADA,EAAY,wBAAwByL,EAAkB,kBACtDrR,EAAU,WAAWqR,EAAkB,QAAQ,CAAC;EAClD;EAEA,IAAIH,EAAaM,CAAW,GAAG;GAC7B,IAAKzR,EAAiB,iBAAiB3D,GAAW;IAChD,IAAMqV,IAAmB,IAAIhU,GAAiBsC,GAA6B3D,GAAW1F,GAAQ,KAAK,KAAK,KAAK,GACvG2a,IAAoB,IAAIze,EAC5B,KAAK,MACL8S,GACAyE,IACApK,GACA0R,GACA,KAAA,GACA9L,GACAC,CACF;IAIA,AAHA,EAAY,kBAAkByL,EAAkB,kBAChDrR,EAAU,WAAWqR,EAAkB,QAAQ,CAAC,GAEhDte,EAAoB,KAAK,IAAI,CAAC,CAAC,WAAW;KACxC,IAAKgN,EAAiB,mBAAmB;MACvC,IAAM2R,IAAc3R;MAEpB,IADI,CAAC2R,KACDA,EAAY,SAAS,SAAS;MAClC,IAAMrV,IAAU,KAAK,YAAY,wBAAwB,WAAWvJ,EAA0B,KAAK,IAAI;MACvG,AAAIuJ,MACF,KAAK,qBAAqB,IAAIqV,GAAaA,EAAY,MAAM,GAE7DA,EAAY,iBAAiB,GAE7B,KAAK,YAAY,wBAAwB,WAAWrV,CAAO,GAC3D,KAAK,YAAY,0BAA0B,CAAC,EAAE,IAAIqV,CAAW,GAC7D,KAAK,YAAY,OAAO,KAAK,KAAK,MAAM;KAE5C,OAAO,AAAK3R,EAAiB,kBAC3B,KAAK,mBAAmB,IAAIA,GAAWA,EAAiB,IAAI,GAC3D,EAAkB,OAAO;IAE9B,CAAC;GACH,OAAO;IACL,IAAMqR,IAAI;KAAE,GAAG,KAAK,UAAU9c,EAAO,WAAW;KAAG,GAAGA;IAAO,GACvDkd,IAAc,IAAInH,GAAYtK,GAAUqR,CAAC,GACzCC,IAAoB,IAAIze,EAC5B,KAAK,MACL8S,GACA2G,IACAtM,GACAyR,GACAJ,GACAzL,GACAC,CACF;IAEA,AADA,EAAY,kBAAkByL,EAAkB,kBAChDrR,EAAU,WAAWqR,EAAkB,QAAQ,CAAC;GAClD;EACF;EAcA,OAXA,OAAO,OAAOlL,CAAW,CAAC,CAAC,SAAS,MAAoB;GACtD,AAAIG,KAAc,OAAOA,EAAW,0BAA2B,cAC7DA,EAAW,uBAAuBH,CAAW;EAEjD,CAAC,GAGDvD,EAAO,eAAeuD,CAAW,GAEjC,KAAK,gBAAgB,IAAIpG,GAAU;GAAE;GAAQ;EAAU,CAAC,GAEjD6C,EAAO;CAChB;CAEA,qBAA4B,GAA0B;EACpD,IAAI,CAAC,KAAK,gBAAgB,IAAI7C,CAAQ,GAAG;EACzC,IAAM,EAAE,WAAQ,iBAAc,KAAK,gBAAgB,IAAIA,CAAQ;EAC/D,IAAK6C,GACL;OAAK7C,EAAiB,mBAAmB;IACvC,IAAMjC,IAAciC,GACd4R,IAAS,KAAK,qBAAqB,IAAI7T,CAAW;IAExD,AADI6T,KAAQA,EAAO,IAAI7T,CAAW,GAClC,KAAK,YAAY,OAAO,KAAK,KAAK,MAAM;GAC1C,OAAO,AAAKiC,EAAiB,kBAE1B,EAAkB,OADN,KAAK,mBAAmB,IAAIA,CACf;GAI5B,AAFA,KAAK,gBAAgB,OAAOA,CAAQ,GACpC6C,EAAO,QAAQ,GACf5C,GAAW,SAAS,MAAMH,IAAI,CAAC;EAJH;CAK9B;CAEA,aAAqB,GAAkB,IAAa,IAAM;EAQxD,AAPI0G,KACF,KAAK,eAAe,MAAW3D,EAAO,OAAO,CAAC,GAC9C,KAAK,MAAM,KAAK,UAAU,EAAE,cAAW,CAAC,MAExC,KAAK,eAAe,MAAWA,EAAO,QAAQ,CAAC,GAC/C,KAAK,MAAM,KAAK,WAAW,EAAE,cAAW,CAAC,IAE3C,KAAK,MAAM,UAAU2D;CACvB;CAEA,cAAsB,GAAkB,IAAa,IAAM;EAQzD,AAPIC,KACF,KAAK,eAAe,MAAW5D,EAAO,KAAK,CAAC,GAC5C,KAAK,6BAA6B,KAAK,MAAM,KAAK,QAAQ,EAAE,cAAW,CAAC,CAAC,MAEzE,KAAK,eAAe,MAAWA,EAAO,KAAK,CAAC,GAC5C,KAAK,6BAA6B,KAAK,MAAM,KAAK,QAAQ,EAAE,cAAW,CAAC,CAAC,IAE3E,KAAK,MAAM,UAAU4D;CACvB;CAEA,gBAAwB;EACtB,KAAK,eAAe,GAAQ,MAAc;GAExC,AADA5D,EAAO,QAAQ,GACf5C,GAAW,SAAS,MAAMH,IAAI,CAAC;EACjC,CAAC;CACH;CAEA,cAAsB,GAAkE;EACtF,KAAK,gBAAgB,SAAS,EAAE,WAAQ,mBAAgB;GACtD,AAAI+C,KAAQ6D,EAAK7D,GAAQ5C,CAAS;EACpC,CAAC;CACH;CAEA,uBAAwC,GAAe,GAA8B;EACnF,IAAI,KAAK,MAAM,SAAS,OAAOyG,EAAK;EAElC,AAAI9K,GAAS,WAASmV,GAAe;CAEzC;CAEA,UAAqB,GAAyC;EAC5D,IAAKxc,KACD,OAAOA,KAAW,aAClBA,EAAO,QAAQ,OAAOA;CAC5B;AACF"}
1
+ {"version":3,"file":"Controller-D6o4OGWJ.js","names":["o","disposedErrorLog","disableWarnLog","disableErrorLog","BasePluginController","FiveControllerWrapper","Subscribe","generateBehindFiveElement","toArray","IObject3D","getNormal","formatRad","notNil","isNil","rayOnLine","boundingBox","boundingSphere","worldBoundingBox","CSS3DRender","Controller","rad2Deg","vectorIsEqual","THREE","setObjectQuaternion","rotateCenter","v","object","quaternion","BaseHelper","originObject3D","config","raycaster","intersection","Vector3","offset","xAxis","yAxis","zAxis","newX","newY","newZ","quaternionX","quaternionY","quaternionZ","newMatrix","matrix","origin","MoveHelperAbstract","BoundingBoxHelperAbstract","RotateHelperAbstract","ScaleHelperAbstract","RectangleScaleHelperAbstract","DirectionGroup","direction","DirectionMesh","geometry","material","calculateThreeMouse","width","height","element","originMouse","left","top","getMouseRaycaster","mouse","camera","threeMouse","RENDER_ORDER","ArrowGroup","param","color","arrow","radius","cylinder","CenterHandle","centerSize","brightColor","centerGeometry","cube","cameraDirection","worldQuaternion","faceAngles","dotProduct","normal","a","b","colors","colorIndex","sortedIndex","item","AXES_COLOR","AXES_THREE_COLOR","calculateScaleByCamera","distance","position","fov","cameraDistance","distanceScale","fovScale","cameraDistanceScale","scale","min","limit","max","clamp","value","getPoseFromCamera","latitude","longitude","e","getOrthographicCameraDirection","pose","vector","HalfPI","isSame","v1","v2","MoveHelper","worldDirectionX","worldDirectionY","worldDirectionZ","orthographicCameraDirection","hideThreshold","angleX","angleY","angleZ","threshold","reverseY","reverseZ","reverseX","directions","createElement","setStyle","tagName","style","key","tipsDom","show","RotateHelper","RotateCircleGroup","child","positiveY","positiveZ","positiveX","gapAngle","angle","options","Circle","DashedRing","AngleSector","meshes","i","mesh","axes","rectangleScaleDom","container","wrapper","border","sphere0","sphereDom","sphere1","sphere2","sphere3","sphere4","sphere5","sphere6","sphere7","sphere","sphereDraggingWrapper","sphereDragging","map","cameraHooks","cancelAnimationFrameId","cameraPose","animate","newCameraPose","CSS3DScaleHelper","scene","cornerPosition","position8","index","css3DObject","currentScale","relativeScaleX","relativeScaleY","parentElement","cornerPositions","css3DInstance","css3DObjectElement","dom","spheres","BoundingBoxHelper","originObject","intersects","box3","lineIndices","lineGeometry","lineMaterial","lineSegments","boxIndices","boxGeometry","boxMaterial","BaseController","otherControllers","params","handleSetObjectScale","handleSetObjectRotate","handleSetObjectPosition","handleApplyObjectScale","handleApplyObjectRotate","handleApplyObjectPosition","initialHelperPosition","d","objects","object3D","disposers","\"__originalColor__\"","mat","\"__originalOpacity__\"","setHoverColor","hoverColor","hoverOpacity","resetColor","originalColors","originalOpacities","handleMouseover","handleMouseout","disposer","cameraPosition","objectIntersection","\"intersectRaycaster\"","modelIntersection","result","getBox","box","computeGuideLength","viewWidth","viewHeight","persp","ortho","cam","center","vFov","diag","baseLength","minLen","maxLen","SolidGuideLine","defaults","merged","dir","length","start","end","positions","line","attr","m","MoveController","helper","centerHandle","centerHandleMesh","hide","updateHelperByCamera","mousedownListener","mouseupListener","point","face","alignment","alignmentVector3","faceNormal","event","x","y","intersect","draggingDirection","directionX","directionY","directionZ","directionVector","startIntersect","clickPoint","viewDirection","plane","startProject","dirNormalized","directionsToShow","ray","isPlane","currentVectorProject","projected","denom","t","beforePosition","offsetVector","startVectorProject","transform","newPosition","finalPosition","finalTransform","ControllerWrapper","five","model","onRender","HelperController","donEvents","hooks","internalHooks","HelperControllerConfig","NAMEVERSION","disposedErrorLog$1","disableWarnLog$1","disableErrorLog$1","Object3DHelper","controllers","state","prevState","controller","enabled","visible","func","k","deg2Rad","deg","helperQuaternionOffset","RotateController","dragStart","dragging","dragEnd","euler","z","currentEuler","currentAngles","newAngles","axis","newEuler","angleHelper","tipsPosition","helperQuaternion","startVector","startAngle","processedAngle","matrixQuaternion","currentIntersectPoint","currentVector","rotationAxis","newQuaternion","segments","thetaLength","thetaStart","angleTips","RectangleScaleController","planeIntersection","planeCenter","startPosition","startPoint","ewVector","nsVector","getOffset","defaultVector","baseVector","startPositionProject","nowPositionProject","planeCenterProject","xIsNegative","yIsNegative","zIsNegative","offsetLength","ewOffset","nsOffset","setEWScale","setNSScale","scaleX","scaleY","scaleXY","scaleMatrix","centerPosition","transformMatrix4","CSS3DScaleController","BoundingBoxController","ScaleHelper","scaleMesh","generateSphere","scalePosition","spheresToRemove","connection","oppositeDirections","processedDirections","mesh1","mesh1Id","oppositeId","mesh2","generateDashedLine","it","isOrthographic","objectCenter","toCameraDirection","objectDirections","maxDot","facingDirection","dirVector","dot","meshId","bothMeshesVisible","frontMaterial","frontMesh","groupGeometry","transparentMaterial","transparentSphere","points","point1","point2","ScaleController","_this","scaleMeshUuidSet","hitObject","draggingObject","dragBasePosition","dragHandlePosition","dragVector","worldBox","meshs","list","faces","scaleMeshes","moveMeshes","intersectedMesh","intersectedPoint","closestFace","minDist","dist","draggingObjectWorldPos","faceCenter","centerVec","isMoveControllerDragging","scaleVector3","posAttr","corners","vertexCount","vertex","isNearlyParallel","localIntersect","intersectPoint","inverseMatrix","localStart","scaleStartPoint","handleWorld","baseWorld","vertices","indices","patch","DomEvents","domElement","domEvent","elPosition","tmpElement","elDimension","object3d","eventName","objectCtx","handlers","handler","callback","useCapture","current","obj","boundObjs","visibleBoundObjs","mouseX","mouseY","aRenderOrder","bRenderOrder","oldSelected","notifyOver","notifyOut","notifyMove","newSelected","origDomEvent","objectParent","toPropagate","mouseCoords","touches","PLUGIN_NAME","PLUGIN","disposedErrorLog","disableWarnLog","disableErrorLog","Object3DHelperController","paramsConfig","helperEnable","moveHelper","c","controllerWrapper","rotateHelper","boundingBoxHelper","scaleHelper","css3dScaleHelper","waitFiveModelLoaded","css3dObject","parent"],"sources":["../../src/shared-utils/Object3DHelper/utils/setObjectQuaternion.ts","../../src/shared-utils/Object3DHelper/Base/BaseHelper.ts","../../src/shared-utils/Object3DHelper/utils/direction.ts","../../src/shared-utils/Object3DHelper/utils/calculateThreeMouse.ts","../../src/shared-utils/Object3DHelper/utils/getMouseRaycaster.ts","../../src/shared-utils/Object3DHelper/Constants/RenderOrder.ts","../../src/shared-utils/Object3DHelper/Helper/Objects/ArrowGroup.ts","../../src/shared-utils/Object3DHelper/Helper/Objects/CenterHandle.ts","../../src/shared-utils/Object3DHelper/Constants/color.ts","../../src/shared-utils/Object3DHelper/utils/calculateScaleByCamera.ts","../../src/shared-utils/clamp.ts","../../src/shared-utils/Object3DHelper/utils/getPoseFromCamera.ts","../../src/shared-utils/Object3DHelper/utils/getOrthographicCameraDirection.ts","../../src/shared-utils/Object3DHelper/Helper/MoveHelper.ts","../../src/shared-utils/Object3DHelper/Helper/HTML/utils/createElement.ts","../../src/shared-utils/Object3DHelper/Helper/HTML/tipsDom.ts","../../src/shared-utils/Object3DHelper/Helper/RotateHelper.ts","../../src/shared-utils/Object3DHelper/Helper/HTML/rectangleScaleDom.ts","../../src/shared-utils/Object3DHelper/utils/cameraHooks.ts","../../src/shared-utils/Object3DHelper/Helper/CSS3DScaleHelper.ts","../../src/shared-utils/Object3DHelper/Helper/BoundingBoxHelper.ts","../../src/shared-utils/Object3DHelper/Base/BaseController.ts","../../src/shared-utils/Object3DHelper/utils/solidGuide.ts","../../src/shared-utils/Object3DHelper/Controller/MoveController.ts","../../src/Object3DHelperPlugin/FiveControllerWrapper.ts","../../src/shared-utils/Object3DHelper/index.ts","../../src/shared-utils/math/deg2Rad.ts","../../src/shared-utils/Object3DHelper/Controller/RotateController.ts","../../src/shared-utils/Object3DHelper/Controller/RectangleScaleController.ts","../../src/shared-utils/Object3DHelper/Controller/CSS3DScaleController.ts","../../src/shared-utils/Object3DHelper/Controller/BoundingBoxController.ts","../../src/shared-utils/Object3DHelper/Helper/ScaleHelper.ts","../../src/shared-utils/Object3DHelper/Controller/ScaleController.ts","../../src/shared-utils/threex/domevents/index.js","../../src/Object3DHelperPlugin/Controller.ts"],"sourcesContent":["import * as THREE from 'three/webgpu'\n\n/**\n * @description: 在指定中心点上,使用 quaternion 旋转物体。\n * @param {THREE.Object3D} object 旋转对象\n * @param {THREE.Quaternion} quaternion 旋转四元数\n * @param {THREE.Vector3} rotateCenter 旋转中心\n */\nexport default function setObjectQuaternion(object: THREE.Object3D, quaternion: THREE.Quaternion, rotateCenter: THREE.Vector3) {\n if (rotateCenter) {\n const rotateCenter2Object = new THREE.Vector3().subVectors(object.position, rotateCenter) // 旋转中心到物体的向量\n const v = rotateCenter2Object\n .applyQuaternion(object.quaternion.clone().invert()) // 使用物体的四元数,将旋转中心到物体的向量转换到物体的局部坐标系\n .applyQuaternion(quaternion) // 使用新的四元数,将物体的局部坐标系转换到世界坐标系\n .add(rotateCenter) // 加上旋转中心,得到新的世界坐标\n object.position.copy(v)\n }\n object.quaternion.copy(quaternion)\n}\n","import type { Create3DElementReturnType } from '../../../CSS3DRenderPlugin'\nimport * as THREE from 'three/webgpu'\nimport type { Group, Mesh, Object3D } from 'three/webgpu'\nimport { Vector3 } from 'three/webgpu'\nimport type { Direction, Direction4, PositionFrom, ScalePosition } from '../typings'\nimport type { tipsDom } from '../Helper/HTML/tipsDom'\nimport setObjectQuaternion from '../utils/setObjectQuaternion'\nimport { IObject3D } from '../../three/IObject3D'\nimport { boundingBox, boundingSphere } from '../../three/boundingBox'\nimport { notNil } from '../../isNil'\n\ntype NonVoid<T> = T extends void ? never : T\n\nexport interface BaseHelperConfig {\n onRender?: () => any\n /**\n * @description: helper 初始位置来源\n * @default 'objectPosition'\n */\n positionFrom?: PositionFrom\n}\n\nexport abstract class BaseHelper<OriginObject3D extends Object3D = Object3D> extends IObject3D {\n protected originObject3D: OriginObject3D\n protected onRender: () => any\n private positionFrom: PositionFrom\n\n public get helperObject(): Object3D {\n return this\n }\n\n public constructor(originObject3D: OriginObject3D, config?: BaseHelperConfig) {\n super()\n this.originObject3D = originObject3D\n this.onRender = config?.onRender ?? (() => {})\n this.positionFrom = config?.positionFrom ?? 'objectPosition'\n }\n\n public render() {\n this.onRender()\n }\n\n public enable() {\n if (this.parent.children.includes(this)) return\n this.parent.add(this)\n }\n\n public disable() {\n this.removeFromParent()\n }\n\n public show() {\n this.visible = true\n this.render()\n }\n\n public hide() {\n this.visible = false\n this.render()\n }\n\n public raycasterIntersectObject(raycaster: THREE.Raycaster, intersection: THREE.Intersection[] = []): THREE.Intersection[] {\n return raycaster.intersectObject(this, true, intersection)\n }\n\n public initialPosition(offset?: THREE.Vector3) {\n if (this.positionFrom === 'objectPosition') {\n this.position.copy(this.originObject3D.position)\n } else if (this.positionFrom === 'boundingBox') {\n this.position.copy(boundingBox(this.originObject3D)?.getCenter(new THREE.Vector3()).applyMatrix4(this.originObject3D.matrixWorld))\n } else if (this.positionFrom === 'boundingSphere') {\n this.position.copy(boundingSphere(this.originObject3D)?.center.clone().applyMatrix4(this.originObject3D.matrixWorld))\n } else if (this.positionFrom instanceof Vector3) {\n this.position.copy(this.positionFrom)\n } else if (this.positionFrom instanceof Function) {\n this.position.copy(this.positionFrom(this.originObject3D))\n }\n\n if (offset) {\n this.position.add(offset)\n }\n }\n\n public setScaleByCamera(camera: THREE.PerspectiveCamera | THREE.OrthographicCamera) {}\n\n public initQuaternion(config?: {\n xAxis?: Vector3 | (() => Vector3)\n yAxis?: Vector3 | (() => Vector3)\n zAxis?: Vector3 | (() => Vector3)\n }) {\n this.quaternion.copy(this.originObject3D.quaternion)\n if (config) {\n if (config.xAxis || config.yAxis || config.zAxis) {\n const xAxis = config.xAxis instanceof Function ? config.xAxis() : config.xAxis\n const yAxis = config.yAxis instanceof Function ? config.yAxis() : config.yAxis\n const zAxis = config.zAxis instanceof Function ? config.zAxis() : config.zAxis\n\n let newX = xAxis?.clone()\n let newY = yAxis?.clone()\n let newZ = zAxis?.clone()\n\n // 单个旋转\n if (newX && !newY && !newY) {\n const quaternionX = new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(1, 0, 0), newX.normalize())\n this.applyQuaternion(quaternionX)\n }\n\n if (newY && !newX && !newZ) {\n const quaternionY = new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0, 1, 0), newY.normalize())\n this.applyQuaternion(quaternionY)\n }\n\n if (newZ && !newX && !newY) {\n const quaternionZ = new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0, 0, 1), newZ.normalize())\n this.applyQuaternion(quaternionZ)\n }\n\n // 三轴旋转\n if ([newX, newY, newZ].filter(notNil).length >= 2) {\n // 补全\n if (!newX) newX = new THREE.Vector3().crossVectors(newY, newZ).normalize()\n if (!newY) newY = new THREE.Vector3().crossVectors(newX, newZ).normalize()\n if (!newZ) newZ = new THREE.Vector3().crossVectors(newX, newY).normalize()\n\n newX.applyQuaternion(this.quaternion)\n newY.applyQuaternion(this.quaternion)\n newZ.applyQuaternion(this.quaternion)\n\n const newMatrix = new THREE.Matrix4().makeBasis(newX, newY, newZ)\n\n const quaternion = new THREE.Quaternion().setFromRotationMatrix(newMatrix)\n\n this.quaternion.copy(quaternion)\n }\n }\n }\n }\n\n public applyHelperScaleMatrix4(matrix: THREE.Matrix4, origin?: Vector3) {\n this.scale.applyMatrix4(matrix)\n }\n\n public setHelperQuaternion(quaternion: THREE.Quaternion, origin?: Vector3) {\n this.initQuaternion()\n setObjectQuaternion(this, this.quaternion.clone().premultiply(quaternion), origin)\n }\n\n public applyHelperQuaternion(quaternion: THREE.Quaternion, origin?: Vector3) {\n if (origin) {\n const v = new Vector3().subVectors(this.position, origin).applyQuaternion(quaternion).add(origin)\n this.position.copy(v)\n }\n this.applyQuaternion(quaternion)\n }\n\n public dispose() {\n this.removeFromParent()\n }\n}\n\nexport abstract class MoveHelperAbstract<OriginObject3D extends Object3D = Object3D> extends BaseHelper<OriginObject3D> {\n public abstract xArrow?: Object3D & { arrow: Object3D; line?: Object3D; direction: Direction }\n public abstract yArrow?: Object3D & { arrow: Object3D; line?: Object3D; direction: Direction }\n public abstract zArrow?: Object3D & { arrow: Object3D; line?: Object3D; direction: Direction }\n public abstract centerHandle?: Object3D & { direction: Direction }\n public abstract showDraggingHelper(directions?: Direction[]): void\n public abstract update(camera: THREE.Camera): void\n}\n\nexport abstract class BoundingBoxHelperAbstract<OriginObject3D extends Object3D = Object3D> extends BaseHelper<OriginObject3D> {}\n\ntype Circle = (Mesh | Group) & { direction: Direction; circle: Mesh; angleSector?: Mesh & { angleDirection: number; baseAxes: Vector3 } }\nexport abstract class RotateHelperAbstract<OriginObject3D extends Object3D = Object3D> extends BaseHelper<OriginObject3D> {\n public abstract xCircle?: Circle\n public abstract yCircle?: Circle\n public abstract zCircle?: Circle\n public abstract angleTips?: ReturnType<typeof tipsDom>\n public abstract showDraggingHelper(directions: Direction[]): void\n public abstract update(camera: THREE.Camera): void\n}\n\nexport abstract class ScaleHelperAbstract<OriginObject3D extends Object3D = Object3D> extends BaseHelper<OriginObject3D> {\n public abstract scaleMeshes: Array<Object3D & { scalePosition: ScalePosition }>\n public abstract update(camera: THREE.Camera): void\n public abstract updateHandlePositions(): void\n}\n\nexport abstract class RectangleScaleHelperAbstract<\n OriginObject3D extends Object3D,\n PointType extends Object3D | HTMLElement,\n> extends BaseHelper<OriginObject3D> {\n public abstract points: PointType extends Object3D\n ? { point: PointType; direction: Direction4 }[]\n : { point: PointType; direction: Direction4; position: Vector3 }[]\n public abstract cornerPositions: Vector3[]\n public abstract css3DInstance?: NonVoid<Create3DElementReturnType>\n public abstract plane?: THREE.Mesh\n public abstract showDraggingHelper(directions?: Direction[]): void\n public abstract updatePoints(): void\n public abstract enable(): void\n public abstract disable(): void\n}\n","import type { Direction } from '../typings'\nimport * as THREE from 'three/webgpu'\n\nexport class DirectionGroup extends THREE.Group {\n public direction: Direction\n\n public constructor(direction?: Direction) {\n super()\n this.direction = direction || 'x'\n }\n}\n\nexport class DirectionLine<T extends THREE.BufferGeometry, K extends THREE.Material> extends THREE.Line<T, K> {\n public direction: Direction\n\n public constructor(geometry?: T, material?: K, direction?: Direction) {\n super(geometry, material)\n this.direction = direction || 'x'\n }\n}\n\nexport class DirectionMesh<T extends THREE.BufferGeometry, K extends THREE.Material> extends THREE.Mesh<T, K> {\n public direction: Direction\n\n public constructor(geometry?: T, material?: K, direction?: Direction) {\n super(geometry, material)\n this.direction = direction || 'x'\n }\n}\n","import * as THREE from 'three/webgpu'\n\n/**\n * 计算 three 中的 mouse 的值\n * @param mouseXY - 鼠标相对屏幕位置\n * @param element - canvas元素(three的展示元素)\n * @param scissor - 屏幕剪裁\n */\nexport function calculateThreeMouse(originMouse: { x: number; y: number }, element: HTMLElement) {\n const { offsetWidth: width, offsetHeight: height } = element\n const { top, left } = element.getBoundingClientRect()\n return Object.assign(new THREE.Vector2(), {\n x: ((originMouse.x - left) / width) * 2 - 1,\n y: (-(originMouse.y - top) / height) * 2 + 1,\n })\n}\n","import * as THREE from 'three/webgpu'\nimport { calculateThreeMouse } from '.'\n\nexport function getMouseRaycaster(camera: THREE.Camera, mouse: { x: number; y: number }, element: HTMLElement) {\n if (!mouse || !element || !camera) return\n const threeMouse = calculateThreeMouse(mouse, element)\n if (Math.abs(threeMouse.x) === 1 || Math.abs(threeMouse.y) === 1) return\n const raycaster = new THREE.Raycaster()\n raycaster.setFromCamera(threeMouse, camera)\n raycaster.params.Points.threshold = 0.1\n return raycaster\n}\n","/**\n * Object3DHelper 渲染顺序常量\n * 数值越大,渲染优先级越高\n */\nexport const RENDER_ORDER = {\n // 基础几何体(如Box)的渲染顺序通常在 0-100 之间\n // 所以Helper的渲染顺序需要远大于这个范围\n\n // 旋转辅助器 - 最低优先级\n ROTATE_HELPER: 9992,\n\n // 移动辅助器\n MOVE_HELPER: 9993,\n\n // 缩放辅助器的连接线\n SCALE_HELPER_LINE: 9994,\n\n // 缩放辅助器的球体\n SCALE_HELPER_SPHERE: 9995,\n\n // 移动辅助器的箭头 - 确保高于所有透明对象\n MOVE_HELPER_ARROW: 10001,\n\n // 移动辅助器的中心手柄 - 应该盖住箭头,优先响应事件\n MOVE_HELPER_CENTER: 10002,\n\n // 拖拽引导线\n DRAG_GUIDE_LINE: 10003,\n\n // 拖拽面片 - 最高优先级\n DRAG_FACE_PATCH: 10004,\n} as const\n\nexport type RenderOrderType = (typeof RENDER_ORDER)[keyof typeof RENDER_ORDER]\n","import * as THREE from 'three/webgpu'\nimport type { Direction } from '../../typings'\nimport { DirectionGroup, DirectionMesh } from '../../utils'\nimport { RENDER_ORDER } from '../../Constants/RenderOrder'\n\ninterface InstanceParameter {\n direction: Direction\n color?: THREE.Color | string | number\n}\n\nexport class ArrowGroup extends DirectionGroup {\n public line: DirectionMesh<THREE.BufferGeometry, THREE.MeshBasicMaterial>\n public arrow: DirectionMesh<THREE.ConeGeometry, THREE.MeshBasicMaterial>\n private lineHeight = 0.4\n private arrowHeight = 0.1\n public name = 'ArrowGroup'\n\n public constructor(param: InstanceParameter) {\n super(param.direction)\n const color = new THREE.Color(param.color ?? 0xf7692b)\n const material = new THREE.MeshBasicMaterial({\n color,\n transparent: true, // 设置为透明材质,确保在透明渲染队列中\n opacity: 1.0, // 完全不透明,但使用透明渲染队列\n depthTest: false, // 禁用深度测试,避免被其他对象遮挡\n depthWrite: false, // 禁用深度写入,避免影响其他透明对象\n })\n\n // arrow\n const coneGeometry = new THREE.ConeGeometry(0.04, 0.1, 32)\n const arrow = new DirectionMesh(coneGeometry, material.clone(), param.direction)\n arrow.name = `arrow-${param.direction}`\n arrow.renderOrder = RENDER_ORDER.MOVE_HELPER_ARROW\n this.arrow = arrow\n\n // line\n const radius = 0.004\n const cylinderGeometry = new THREE.CylinderGeometry(radius, radius, 0.4, 32)\n const cylinder = new DirectionMesh(cylinderGeometry, material.clone(), param.direction)\n cylinder.name = `line-${param.direction}`\n cylinder.renderOrder = RENDER_ORDER.MOVE_HELPER_ARROW\n this.line = cylinder\n\n this.formatArrow()\n this.formatLine()\n this.add(this.arrow, this.line)\n }\n\n private formatArrow() {\n this.arrow.geometry.translate(0, this.lineHeight + this.arrowHeight / 2, 0)\n if (this.direction === 'x') {\n this.arrow.geometry.rotateX(Math.PI / 2)\n this.arrow.geometry.rotateY(Math.PI / 2)\n } else if (this.direction === 'z') {\n this.arrow.geometry.rotateX(Math.PI / 2)\n }\n }\n\n private formatLine() {\n this.line.geometry.translate(0, this.lineHeight / 2, 0)\n if (this.direction === 'x') {\n this.line.geometry.rotateX(Math.PI / 2)\n this.line.geometry.rotateY(Math.PI / 2)\n } else if (this.direction === 'z') {\n this.line.geometry.rotateX(Math.PI / 2)\n }\n }\n}\n","import * as THREE from 'three/webgpu'\nimport type { Direction } from '../../typings'\nimport { DirectionGroup } from '../../utils'\nimport { RENDER_ORDER } from '../../Constants/RenderOrder'\n\ninterface InstanceParameter {\n color?: THREE.Color | string | number\n size?: number\n}\n\nexport class CenterHandle extends DirectionGroup {\n public cube: THREE.Mesh<THREE.BoxGeometry, THREE.MeshBasicMaterial[]> & { direction: Direction }\n public name = 'CenterHandle'\n private faceMaterials: THREE.MeshBasicMaterial[]\n private baseColor: THREE.Color\n // 立方体6个面的法线方向(局部坐标系)\n private faceNormals = [\n new THREE.Vector3(1, 0, 0), // right (+X)\n new THREE.Vector3(-1, 0, 0), // left (-X)\n new THREE.Vector3(0, 1, 0), // top (+Y)\n new THREE.Vector3(0, -1, 0), // bottom (-Y)\n new THREE.Vector3(0, 0, 1), // front (+Z)\n new THREE.Vector3(0, 0, -1), // back (-Z)\n ]\n\n public constructor(param?: InstanceParameter) {\n super('plane')\n this.baseColor = new THREE.Color(param?.color ?? 0xfa8c16)\n const centerSize = param?.size ?? 0.05\n\n // Three automatically converts these sRGB literals to linear working colors.\n const brightColor = new THREE.Color(0xffa940) // 最亮 #FFA940\n\n // 为立方体的6个面创建独立的材质(使用BasicMaterial,不受光照影响)\n this.faceMaterials = Array.from(\n { length: 6 },\n () =>\n new THREE.MeshBasicMaterial({\n color: brightColor, // 初始都使用最亮色\n transparent: true,\n opacity: 1.0,\n depthTest: false,\n depthWrite: false,\n side: THREE.FrontSide,\n }),\n )\n\n const centerGeometry = new THREE.BoxGeometry(centerSize, centerSize, centerSize)\n const cube = new THREE.Mesh(centerGeometry, this.faceMaterials) as THREE.Mesh<THREE.BoxGeometry, THREE.MeshBasicMaterial[]> & {\n direction: Direction\n }\n cube.direction = 'plane'\n cube.renderOrder = RENDER_ORDER.MOVE_HELPER_CENTER\n cube.name = 'center-plane-handle'\n this.cube = cube\n\n this.add(this.cube)\n }\n\n /**\n * 更新各个面的颜色,根据与相机的角度动态调整\n * @param camera 相机对象\n */\n public update(camera: THREE.Camera) {\n // 获取相机到立方体的方向(世界坐标系)\n const cameraDirection = new THREE.Vector3().subVectors(camera.position, this.cube.getWorldPosition(new THREE.Vector3())).normalize()\n\n // 获取立方体的世界旋转\n const worldQuaternion = this.cube.getWorldQuaternion(new THREE.Quaternion())\n\n // 计算每个面与相机方向的夹角\n const faceAngles = this.faceNormals.map((normal, index) => {\n // 将局部法线转换到世界坐标系\n const worldNormal = normal.clone().applyQuaternion(worldQuaternion)\n // 计算法线与相机方向的夹角(点积的绝对值越大表示越正对相机)\n const dotProduct = worldNormal.dot(cameraDirection)\n return { index, angle: Math.acos(Math.abs(dotProduct)) }\n })\n\n // 按角度排序,角度越小说明越正对相机\n faceAngles.sort((a, b) => a.angle - b.angle)\n\n // Three automatically converts these sRGB literals to linear working colors.\n const colors = [\n new THREE.Color(0xffa940), // 最亮 #FFA940(最正对相机)\n new THREE.Color(0xfa8c16), // 一般 #FA8C16\n new THREE.Color(0xd46b08), // 最暗 #D46B08\n ]\n\n // 为6个面分配颜色:最接近的2个面用最亮色,中间2个面用中等色,最远的2个面用最暗色\n faceAngles.forEach((item, sortedIndex) => {\n const colorIndex = Math.floor(sortedIndex / 2) // 0-1用colors[0], 2-3用colors[1], 4-5用colors[2]\n this.faceMaterials[item.index].color.copy(colors[colorIndex])\n })\n }\n}\n","import * as THREE from 'three/webgpu'\n\nconst AXES_COLOR = {\n X: 0xff4a4a,\n Y: 0x00d68f,\n Z: 0x3366ff,\n}\n\nclass AXES_THREE_COLOR {\n public static get X() {\n return new THREE.Color(AXES_COLOR.X)\n }\n public static get Y() {\n return new THREE.Color(AXES_COLOR.Y)\n }\n public static get Z() {\n return new THREE.Color(AXES_COLOR.Z)\n }\n}\n\nexport { AXES_COLOR, AXES_THREE_COLOR }\n","import type * as THREE from 'three/webgpu'\n\nexport default function calculateScaleByCamera(camera: any, position: THREE.Vector3, limit?: { min?: number; max?: number }) {\n const baseCameraDistance = 3\n const baseDistance = 3\n const baseFov = 90\n\n const distance = camera.position.distanceTo(position)\n const fov = camera.fov\n const cameraDistance = camera.distance || baseCameraDistance\n\n const distanceScale = distance / baseDistance\n const fovScale = fov / baseFov\n const cameraDistanceScale = cameraDistance / baseCameraDistance\n\n const scale = distanceScale * fovScale * cameraDistanceScale\n\n const min = limit?.min || 0.6\n const max = limit?.max\n\n if (min && scale < min) return min\n if (max && scale > max) return max\n\n return scale\n}\n","function clamp(value: number, min: number, max: number) {\n if (value < min) {\n return min;\n }\n if (value > max) {\n return max;\n }\n return value;\n}\n\nexport { clamp };","import type * as THREE from 'three/webgpu'\nimport { isNil } from '../../isNil'\nimport { clamp } from '../../clamp'\nimport { formatRad } from '../../formatRad'\n\n/**\n * @description 从相机反算pose\n */\nexport function getPoseFromCamera(camera: THREE.Camera) {\n let latitude: number = (camera as any).pose.latitude\n let longitude: number = (camera as any).pose.longitude\n if (isNil(latitude) || isNil(longitude)) {\n const e = camera.matrix.elements\n latitude = Math.asin(clamp(e[9], -1, 1))\n if (Math.abs(e[9]) < 0.9999999) {\n longitude = formatRad(Math.atan2(e[8], e[10]))\n } else {\n longitude = formatRad(Math.atan2(-e[2], e[0]))\n }\n }\n\n return { latitude, longitude }\n}\n","import * as THREE from 'three/webgpu'\n\n/**\n * @description 获取正交相机的方向\n */\nexport function getOrthographicCameraDirection(pose: { longitude: number; latitude: number }) {\n const { latitude, longitude } = pose\n\n const vector = new THREE.Vector3()\n\n if (HalfPI - latitude < 0.03) {\n vector.set(0, 1, 0)\n } else if (isSame(0, longitude)) {\n vector.set(0, 0, 1)\n } else if (isSame(Math.PI, longitude)) {\n vector.set(0, 0, -1)\n } else if (isSame(HalfPI, longitude)) {\n vector.set(1, 0, 0)\n } else {\n vector.set(-1, 0, 0)\n }\n\n return vector\n}\n\nconst HalfPI = Number((Math.PI / 2).toFixed(5))\nfunction isSame(v1?: number, v2?: number) {\n if (typeof v1 !== 'number' || typeof v2 !== 'number') return false\n return Math.abs(v1 - v2) < 1e-3\n}\n","import type { Object3D } from 'three/webgpu'\nimport type { Direction } from '../typings'\nimport { MoveHelperAbstract, type BaseHelperConfig } from '.'\nimport { ArrowGroup } from './Objects/ArrowGroup'\nimport { CenterHandle } from './Objects/CenterHandle'\nimport { AXES_THREE_COLOR } from '../Constants/color'\nimport calculateScaleByCamera from '../utils/calculateScaleByCamera'\nimport { getPoseFromCamera } from '../utils/getPoseFromCamera'\nimport { getOrthographicCameraDirection } from '../utils/getOrthographicCameraDirection'\nimport * as THREE from 'three/webgpu'\n\nexport class MoveHelper extends MoveHelperAbstract {\n public name = 'MoveHelper'\n public xArrow?: ArrowGroup\n public yArrow?: ArrowGroup\n public zArrow?: ArrowGroup\n public centerHandle?: CenterHandle\n\n public constructor(\n originObject3D: Object3D,\n config?: {\n xArrowEnable?: boolean\n yArrowEnable?: boolean\n zArrowEnable?: boolean\n centerHandleEnable?: boolean\n } & BaseHelperConfig,\n ) {\n super(originObject3D, config)\n\n if (config.xArrowEnable !== false) this.xArrow = new ArrowGroup({ direction: 'x', color: AXES_THREE_COLOR.X })\n if (config.yArrowEnable !== false) this.yArrow = new ArrowGroup({ direction: 'y', color: AXES_THREE_COLOR.Y })\n if (config.zArrowEnable !== false) this.zArrow = new ArrowGroup({ direction: 'z', color: AXES_THREE_COLOR.Z })\n if (config.centerHandleEnable !== false) this.centerHandle = new CenterHandle()\n\n this.add(...[this.xArrow, this.yArrow, this.zArrow, this.centerHandle].filter(Boolean))\n }\n\n public update(camera: THREE.Camera) {\n if (this.xArrow) this.xArrow.visible = true\n if (this.yArrow) this.yArrow.visible = true\n if (this.zArrow) this.zArrow.visible = true\n\n // 更新中心手柄的面颜色\n if (this.centerHandle) {\n this.centerHandle.update(camera)\n }\n\n const cameraDirection = this.helperObject.position.clone().sub(camera.position).normalize()\n\n // 获取世界坐标系中的轴方向\n const worldDirectionX = new THREE.Vector3(1, 0, 0).applyQuaternion(this.quaternion)\n const worldDirectionY = new THREE.Vector3(0, 1, 0).applyQuaternion(this.quaternion)\n const worldDirectionZ = new THREE.Vector3(0, 0, 1).applyQuaternion(this.quaternion)\n\n // 保留原有的正交相机隐藏逻辑\n if (camera.type === 'OrthographicCamera') {\n const pose = getPoseFromCamera(camera)\n // 正交相机的轴向\n const orthographicCameraDirection = getOrthographicCameraDirection(pose)\n\n // 5度以内隐藏\n const hideThreshold = 0.0872665\n\n if (\n Math.abs(worldDirectionX.angleTo(orthographicCameraDirection) - 0) < hideThreshold ||\n Math.abs(worldDirectionX.angleTo(orthographicCameraDirection) - Math.PI) < hideThreshold\n ) {\n if (this.xArrow) this.xArrow.visible = false\n } else if (\n Math.abs(worldDirectionY.angleTo(orthographicCameraDirection) - 0) < hideThreshold ||\n Math.abs(worldDirectionY.angleTo(orthographicCameraDirection) - Math.PI) < hideThreshold\n ) {\n if (this.yArrow) this.yArrow.visible = false\n } else if (\n Math.abs(worldDirectionZ.angleTo(orthographicCameraDirection) - 0) < hideThreshold ||\n Math.abs(worldDirectionZ.angleTo(orthographicCameraDirection) - Math.PI) < hideThreshold\n ) {\n if (this.zArrow) this.zArrow.visible = false\n }\n }\n\n if (camera.type !== 'OrthographicCamera') {\n // 计算相机方向与各轴的夹角\n const angleX = cameraDirection.angleTo(worldDirectionX)\n const angleY = cameraDirection.angleTo(worldDirectionY)\n const angleZ = cameraDirection.angleTo(worldDirectionZ)\n // 动态调整轴方向\n const threshold = Math.PI / 2\n const reverseY = angleY < threshold\n const reverseZ = angleZ < threshold\n const reverseX = angleX < threshold\n\n if (this.xArrow) {\n if (reverseX) {\n // 夹角小于90度,显示反向轴\n this.xArrow.scale.x = -1\n this.xArrow.scale.y = 1\n this.xArrow.scale.z = 1\n } else {\n // 夹角大于等于90度,显示正向轴\n this.xArrow.scale.x = 1\n this.xArrow.scale.y = 1\n this.xArrow.scale.z = 1\n }\n }\n\n if (this.yArrow) {\n if (reverseY) {\n // 夹角小于90度,显示反向轴\n this.yArrow.scale.x = 1\n this.yArrow.scale.y = -1\n this.yArrow.scale.z = 1\n } else {\n // 夹角大于等于90度,显示正向轴\n this.yArrow.scale.x = 1\n this.yArrow.scale.y = 1\n this.yArrow.scale.z = 1\n }\n }\n if (this.zArrow) {\n if (reverseZ) {\n // 夹角小于90度,显示反向轴\n this.zArrow.scale.x = 1\n this.zArrow.scale.y = 1\n this.zArrow.scale.z = -1\n } else {\n // 夹角大于等于90度,显示正向轴\n this.zArrow.scale.x = 1\n this.zArrow.scale.y = 1\n this.zArrow.scale.z = 1\n }\n }\n }\n }\n\n public show() {\n super.show()\n if (this.xArrow) this.add(this.xArrow)\n if (this.yArrow) this.add(this.yArrow)\n if (this.zArrow) this.add(this.zArrow)\n if (this.centerHandle) this.add(this.centerHandle)\n }\n\n public setScaleByCamera(camera: THREE.PerspectiveCamera | THREE.OrthographicCamera) {\n this.scale.setScalar(calculateScaleByCamera(camera, this.position))\n }\n\n public showDraggingHelper(directions: Direction[]) {\n if (this.xArrow) {\n if (directions.includes('x')) this.add(this.xArrow)\n else this.remove(this.xArrow)\n }\n if (this.yArrow) {\n if (directions.includes('y')) this.add(this.yArrow)\n else this.remove(this.yArrow)\n }\n if (this.zArrow) {\n if (directions.includes('z')) this.add(this.zArrow)\n else this.remove(this.zArrow)\n }\n if (this.centerHandle) {\n if (directions.includes('plane')) this.add(this.centerHandle)\n else this.remove(this.centerHandle)\n }\n }\n\n public dispose() {\n this.remove(...[this.xArrow, this.yArrow, this.zArrow, this.centerHandle].filter(Boolean))\n super.dispose()\n }\n}\n","export function createElement(style?: Partial<CSSStyleDeclaration>, tagName?: string) {\n return setStyle(document.createElement(tagName ?? 'div'), style)\n}\n\nexport function setStyle(element: HTMLElement, style?: Partial<CSSStyleDeclaration>) {\n if (!style) return element\n for (const key in style) {\n if (key && style[key]) element.style[key as any]! = style[key]!\n }\n return element\n}\n","import { createElement } from './utils/createElement'\n\nexport function tipsDom(style?: Partial<CSSStyleDeclaration>) {\n const element = createElement({\n position: 'absolute',\n display: 'block',\n borderRadius: '4px',\n paddingTop: '1px',\n paddingBottom: '1px',\n paddingLeft: '4px',\n paddingRight: '4px',\n pointerEvents: 'none',\n userSelect: 'none',\n zIndex: '99999',\n backgroundColor: 'rgba(0,0,0,0.7)',\n fontSize: '12px',\n color: '#fff',\n letterSpacing: '0',\n lineHeight: '18px',\n ...style,\n })\n const show = () => {\n if (element.style.display === 'block') return\n if (!element.style.top) return\n if (!element.style.left) return\n element.style.display = 'block'\n }\n const hide = () => {\n element.style.display = 'none'\n element.style.top = ''\n element.style.left = ''\n }\n const setLeftTop = (left: string, top: string) => {\n element.style.left = left\n element.style.top = top\n show()\n }\n return { element, show, hide, setLeftTop }\n}\n","import * as THREE from 'three/webgpu'\nimport type { Object3D } from 'three/webgpu'\nimport { RotateHelperAbstract, type BaseHelperConfig } from '../Base/BaseHelper'\nimport type { Color, Direction } from '../typings'\nimport { AXES_THREE_COLOR } from '../Constants/color'\nimport { RENDER_ORDER } from '../Constants/RenderOrder'\nimport { tipsDom } from './HTML/tipsDom'\nimport calculateScaleByCamera from '../utils/calculateScaleByCamera'\n\nexport class RotateHelper extends RotateHelperAbstract {\n public name = 'RotateHelper'\n public xCircle?: RotateCircleGroup\n public yCircle?: RotateCircleGroup\n public zCircle?: RotateCircleGroup\n public children: RotateCircleGroup[] = []\n public angleTips?: ReturnType<typeof tipsDom>\n private container?: HTMLElement\n\n public constructor(\n originObject3D: Object3D,\n config?: {\n container?: HTMLElement\n yzCircleEnable?: boolean\n xzCircleEnable?: boolean\n xyCircleEnable?: boolean\n angleTipsEnable?: boolean\n } & BaseHelperConfig,\n ) {\n super(originObject3D, config)\n\n if (config?.yzCircleEnable !== false) this.xCircle = new RotateCircleGroup({ direction: 'x', color: AXES_THREE_COLOR.X })\n if (config?.xzCircleEnable !== false) this.yCircle = new RotateCircleGroup({ direction: 'y', color: AXES_THREE_COLOR.Y })\n if (config?.xyCircleEnable !== false) this.zCircle = new RotateCircleGroup({ direction: 'z', color: AXES_THREE_COLOR.Z })\n\n if (config?.container && config?.angleTipsEnable !== false) {\n this.container = config?.container\n this.angleTips = tipsDom({ display: 'none' })\n this.container.appendChild(this.angleTips.element)\n }\n\n this.add(...[this.xCircle, this.yCircle, this.zCircle].filter(Boolean))\n this.show()\n }\n\n public hide() {\n this.children.forEach((child) => child.hide())\n }\n\n public show() {\n this.children.forEach((child) => child.showCircle())\n this.angleTips?.hide()\n }\n\n public setScaleByCamera(camera: THREE.PerspectiveCamera | THREE.OrthographicCamera) {\n this.scale.setScalar(calculateScaleByCamera(camera, this.position))\n }\n\n public update(camera: THREE.Camera) {\n if (camera.type === 'OrthographicCamera') return\n // 获取相机朝向向量\n const cameraDirection = this.helperObject.position.clone().sub(camera.position).normalize()\n\n // 获取世界坐标系中的轴方向\n const worldDirectionX = new THREE.Vector3(1, 0, 0).applyQuaternion(this.quaternion)\n const worldDirectionY = new THREE.Vector3(0, 1, 0).applyQuaternion(this.quaternion)\n const worldDirectionZ = new THREE.Vector3(0, 0, 1).applyQuaternion(this.quaternion)\n\n // 计算相机方向与各轴的夹角\n const angleX = cameraDirection.angleTo(worldDirectionX)\n const angleY = cameraDirection.angleTo(worldDirectionY)\n const angleZ = cameraDirection.angleTo(worldDirectionZ)\n\n // 90度阈值(π/2弧度)\n const threshold = Math.PI / 2\n const positiveY = angleY >= threshold\n const positiveZ = angleZ >= threshold\n const positiveX = angleX >= threshold\n\n if (this.xCircle) {\n const gapAngle = this.xCircle.circle.gapAngle\n if (positiveY && positiveZ) {\n this.xCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (positiveY && !positiveZ) {\n this.xCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, Math.PI / 2 + gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (!positiveY && positiveZ) {\n this.xCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, (Math.PI / 2) * 3 + gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (!positiveY && !positiveZ) {\n this.xCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, Math.PI + gapAngle, Math.PI / 2 - gapAngle * 2)\n }\n\n if (this.xCircle.angleSector) {\n this.xCircle.angleSector.offsetAngle = (angle) => angle\n\n if (positiveY && positiveZ) {\n this.xCircle.angleSector.baseAxes = new THREE.Vector3(0, 0, 1)\n } else if (positiveY && !positiveZ) {\n this.xCircle.angleSector.baseAxes = new THREE.Vector3(0, 0, 1)\n } else if (!positiveY && positiveZ) {\n this.xCircle.angleSector.baseAxes = new THREE.Vector3(0, -1, 0)\n this.xCircle.angleSector.offsetAngle = (angle) => angle - Math.PI / 2\n } else if (!positiveY && !positiveZ) {\n this.xCircle.angleSector.baseAxes = new THREE.Vector3(0, 0, -1)\n this.xCircle.angleSector.offsetAngle = (angle) => angle - Math.PI\n }\n }\n }\n\n if (this.yCircle) {\n this.yCircle.angleSector.offsetAngle = (angle) => angle\n const gapAngle = this.yCircle.circle.gapAngle\n\n if (positiveX && positiveZ) {\n this.yCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (positiveX && !positiveZ) {\n this.yCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, (Math.PI / 2) * 3 + gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (!positiveX && positiveZ) {\n this.yCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, Math.PI / 2 + gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (!positiveX && !positiveZ) {\n this.yCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, Math.PI + gapAngle, Math.PI / 2 - gapAngle * 2)\n }\n\n if (positiveX && positiveZ) {\n this.yCircle.angleSector.baseAxes = new THREE.Vector3(1, 0, 0)\n } else if (positiveX && !positiveZ) {\n this.yCircle.angleSector.baseAxes = new THREE.Vector3(0, 0, -1)\n this.yCircle.angleSector.offsetAngle = (angle) => angle - Math.PI / 2\n } else if (!positiveX && positiveZ) {\n this.yCircle.angleSector.baseAxes = new THREE.Vector3(0, 0, 1)\n this.yCircle.angleSector.offsetAngle = (angle) => angle + Math.PI / 2\n } else if (!positiveX && !positiveZ) {\n this.yCircle.angleSector.baseAxes = new THREE.Vector3(-1, 0, 0)\n this.yCircle.angleSector.offsetAngle = (angle) => angle + Math.PI\n }\n }\n\n if (this.zCircle) {\n this.zCircle.angleSector.offsetAngle = (angle) => angle\n const gapAngle = this.zCircle.circle.gapAngle\n\n if (positiveX && positiveY) {\n this.zCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (positiveX && !positiveY) {\n this.zCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, (Math.PI / 2) * 3 + gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (!positiveX && positiveY) {\n this.zCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, Math.PI / 2 + gapAngle, Math.PI / 2 - gapAngle * 2)\n } else if (!positiveX && !positiveY) {\n this.zCircle.circle.geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, Math.PI + gapAngle, Math.PI / 2 - gapAngle * 2)\n }\n\n if (this.zCircle.angleSector) {\n if (positiveX && positiveY) {\n this.zCircle.angleSector.baseAxes = new THREE.Vector3(1, 0, 0)\n } else if (positiveX && !positiveY) {\n this.zCircle.angleSector.baseAxes = new THREE.Vector3(0, -1, 0)\n this.zCircle.angleSector.offsetAngle = (angle) => angle - Math.PI / 2\n } else if (!positiveX && positiveY) {\n this.zCircle.angleSector.baseAxes = new THREE.Vector3(0, 1, 0)\n this.zCircle.angleSector.offsetAngle = (angle) => angle + Math.PI / 2\n } else if (!positiveX && !positiveY) {\n this.zCircle.angleSector.baseAxes = new THREE.Vector3(-1, 0, 0)\n this.zCircle.angleSector.offsetAngle = (angle) => angle + Math.PI\n }\n }\n }\n }\n\n public showDraggingHelper(directions: Direction[]) {\n this.hide()\n this.children.filter((child) => directions.includes(child.direction)).forEach((child) => child.showRing())\n this.angleTips?.show()\n }\n\n public dispose() {\n this.removeFromParent()\n this.angleTips?.element?.remove()\n }\n}\n\nclass RotateCircleGroup extends THREE.Group {\n public direction: Direction\n /** 1/4 圆 */\n public circle: Circle\n /** 旋转过程中展示的背景圆环 */\n public ring: DashedRing\n /** 旋转过程中表示角度的扇形 */\n public angleSector: AngleSector\n\n public constructor(options: { direction: Direction; color?: Color }) {\n super()\n this.direction = options.direction\n\n this.circle = new Circle(options)\n this.ring = new DashedRing(options)\n this.angleSector = new AngleSector(options)\n\n this.add(this.circle, this.ring, this.angleSector)\n\n if (this.direction === 'y') this.rotation.x = Math.PI / 2\n else if (this.direction === 'x') this.rotation.y = -Math.PI / 2\n }\n\n public showCircle() {\n this.add(this.circle)\n this.remove(this.ring, this.angleSector)\n }\n\n public showRing() {\n this.add(this.ring, this.angleSector)\n this.remove(this.circle)\n }\n\n public hide() {\n // 改为remove而不是设置visible,是因为会影响其他helper的碰撞检测\n this.remove(this.ring, this.angleSector, this.circle)\n }\n}\n\nclass Circle extends THREE.Mesh {\n public direction: Direction\n public declare material: THREE.MeshBasicMaterial\n public gapAngle = 0.02\n public geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, this.gapAngle, Math.PI / 2 - this.gapAngle * 2)\n\n public constructor(options: { direction: Direction; color?: Color }) {\n super()\n\n this.material = new THREE.MeshBasicMaterial({\n opacity: 0.6,\n transparent: true, // 设置为透明材质,确保在透明渲染队列中\n color: options.color ?? 0xffffff,\n side: THREE.DoubleSide,\n depthTest: false,\n })\n this.direction = options.direction\n this.renderOrder = RENDER_ORDER.ROTATE_HELPER\n this.geometry.name = `RotateHelperCircleGeometry-${this.direction}`\n }\n}\n\nclass DashedRing extends THREE.Group {\n public direction: Readonly<Direction>\n\n public constructor(options: { direction: Direction }) {\n super()\n this.direction = options.direction\n\n const gapAngle = 0.015\n\n const meshes = new Array(8).fill(null).map((_, i) => {\n const geometry = new THREE.RingGeometry(0.25, 0.3, 20, 8, (Math.PI / 4) * i + gapAngle, Math.PI / 4 - gapAngle * 2)\n const material = new THREE.MeshBasicMaterial({\n opacity: 1,\n color: 0xffffff,\n depthTest: false,\n depthWrite: false,\n transparent: true,\n side: THREE.DoubleSide,\n })\n\n const mesh = new THREE.Mesh(geometry, material)\n mesh.name = `AxesDashedRing-${this.direction}-${i}`\n return mesh\n })\n\n this.add(...meshes)\n }\n}\n\nclass AngleSector extends THREE.Mesh {\n public direction: Direction\n public baseAxes: THREE.Vector3\n public offsetAngle: (angle: number) => number = (angle) => angle\n public angleDirection: 1 | -1\n public declare material: THREE.MeshBasicMaterial\n\n public constructor(options: { direction: Direction; color?: Color }) {\n super()\n\n switch (options.direction) {\n case 'x':\n this.baseAxes = new THREE.Vector3(0, 0, 1)\n break\n case 'y':\n this.baseAxes = new THREE.Vector3(1, 0, 0)\n break\n case 'z':\n this.baseAxes = new THREE.Vector3(1, 0, 0)\n break\n }\n\n const ratio = 0.3 + 0.0005 // 挡住白色圆环的锯齿\n this.geometry = new THREE.CircleGeometry(ratio, 48, 0, 0.0001)\n this.material = new THREE.MeshBasicMaterial({\n opacity: 0.4,\n color: options.color ?? 0xffffff,\n depthTest: false,\n depthWrite: false,\n transparent: true,\n side: THREE.DoubleSide,\n })\n\n this.direction = options.direction\n this.angleDirection = this.direction === 'z' ? 1 : -1\n }\n\n /**\n * 设置扇形旋转方向为顺时针\n */\n public setClockwiseDirection() {\n this.angleDirection = -1\n }\n\n /**\n * 设置扇形旋转方向为逆时针\n */\n public setCounterClockwiseDirection() {\n this.angleDirection = 1\n }\n\n /**\n * 切换扇形旋转方向\n */\n public toggleDirection() {\n this.angleDirection = this.angleDirection === 1 ? -1 : 1\n }\n\n /**\n * 设置扇形的基础轴向\n * @param axes 新的基础轴向向量\n */\n public setBaseAxes(axes: THREE.Vector3) {\n this.baseAxes = axes.clone().normalize()\n }\n\n /**\n * 获取当前旋转方向\n * @returns 'clockwise' | 'counterclockwise'\n */\n public getDirection(): 'clockwise' | 'counterclockwise' {\n return this.angleDirection === -1 ? 'clockwise' : 'counterclockwise'\n }\n}\n","import type { Direction4 } from '../../typings'\nimport { createElement } from './utils/createElement'\n\ninterface Sphere {\n element: HTMLElement\n direction: Direction4\n}\n\nexport function rectangleScaleDom() {\n const container = createElement({\n width: '100%',\n height: '100%',\n left: '0',\n top: '0',\n position: 'absolute',\n pointerEvents: 'none',\n })\n const wrapper = createElement({\n boxSizing: 'border-box',\n width: '100%',\n height: '100%',\n left: '0',\n top: '0',\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n })\n const border = createElement({\n boxSizing: 'border-box',\n width: '100%',\n height: '100%',\n left: '0',\n top: '0',\n position: 'absolute',\n border: '1px solid rgba(255,255,255,0.4)',\n })\n // DELETE\n // const text = createElement({ fontSize: '50px' })\n // text.innerText = '这是正面'\n // wrapper.appendChild(text)\n\n container.appendChild(wrapper)\n wrapper.appendChild(border)\n\n /**\n * 6----5----4\n * | |\n * 7 3\n * | |\n * 0----1----2\n */\n const offset = '-4px'\n const sphere0: Sphere = { direction: 'nesw', element: sphereDom({ cursor: 'nesw-resize', left: offset, bottom: offset }) }\n const sphere1: Sphere = { direction: 'ns', element: sphereDom({ cursor: 'ns-resize', bottom: offset }) }\n const sphere2: Sphere = { direction: 'nwse', element: sphereDom({ cursor: 'nwse-resize', right: offset, bottom: offset }) }\n const sphere3: Sphere = { direction: 'ew', element: sphereDom({ cursor: 'ew-resize', right: offset }) }\n const sphere4: Sphere = { direction: 'nesw', element: sphereDom({ cursor: 'nesw-resize', right: offset, top: offset }) }\n const sphere5: Sphere = { direction: 'ns', element: sphereDom({ cursor: 'ns-resize', top: offset }) }\n const sphere6: Sphere = { direction: 'nwse', element: sphereDom({ cursor: 'nwse-resize', left: offset, top: offset }) }\n const sphere7: Sphere = { direction: 'ew', element: sphereDom({ cursor: 'ew-resize', left: offset }) }\n\n // 0,2,4,6 四个角放后面,当点击区域可能出现互相遮挡的情况时,优先保障四个角的点\n new Array(sphere1, sphere3, sphere5, sphere7, sphere0, sphere2, sphere4, sphere6).forEach((sphere) => wrapper.appendChild(sphere.element))\n const spheres: [Sphere, Sphere, Sphere, Sphere, Sphere, Sphere, Sphere, Sphere] = [\n sphere0,\n sphere1,\n sphere2,\n sphere3,\n sphere4,\n sphere5,\n sphere6,\n sphere7,\n ]\n return { container, spheres }\n}\n\nexport function backgroundDom() {\n return createElement({\n width: '100%',\n height: '100%',\n left: '0',\n top: '0',\n position: 'absolute',\n background: 'rgba(0, 0, 0, 0.15)',\n pointerEvents: 'none',\n })\n}\n\nfunction sphereDom(style?: Partial<CSSStyleDeclaration>) {\n const sphere = createElement({\n background: '#FFFF00',\n width: '9px',\n height: '9px',\n position: 'absolute',\n pointerEvents: 'none',\n borderRadius: '50%',\n ...style,\n })\n const sphereDraggingWrapper = createElement({\n width: '15px',\n height: '15px',\n position: 'absolute',\n left: '50%',\n top: '50%',\n transform: 'translate(-50%, -50%)',\n pointerEvents: 'none',\n })\n const sphereDragging = createElement({\n width: '15px',\n height: '15px',\n cursor: style?.cursor,\n pointerEvents: 'auto',\n // backgroundColor: 'red',\n background: 'transparent',\n })\n sphereDragging.draggable = true\n sphereDraggingWrapper.appendChild(sphereDragging)\n sphere.appendChild(sphereDraggingWrapper)\n return sphere\n}\n","import type * as THREE from 'three/webgpu'\nimport { Subscribe } from '../../Subscribe'\n\nconst map = new Map<\n THREE.Camera,\n {\n dispose: () => void\n hooks: any\n }\n>()\n\nexport function cameraHooks(camera: THREE.Camera) {\n // 单例\n if (map.has(camera)) {\n return map.get(camera).hooks\n }\n\n const cameraHooks = new Subscribe<{\n cameraUpdate: () => any\n }>()\n\n let cancelAnimationFrameId: number | null = null\n let cameraPose: string\n\n const animate = () => {\n cancelAnimationFrameId = requestAnimationFrame(animate)\n const newCameraPose = camera.projectionMatrix.toArray().join(',') + camera.matrixWorld.toArray().join(',')\n if (newCameraPose !== cameraPose) {\n cameraPose = newCameraPose\n cameraHooks.emit('cameraUpdate')\n }\n }\n\n animate()\n\n const dispose = () => {\n map.delete(camera)\n cancelAnimationFrame(cancelAnimationFrameId!)\n }\n\n map.set(camera, {\n hooks: cameraHooks,\n dispose,\n })\n\n return cameraHooks\n}\n\nexport function disposeCameraHooks(camera: THREE.Camera) {\n if (map.has(camera)) map.get(camera).dispose()\n}\n","import { CSS3DRender } from '../../../CSS3DRenderPlugin/utils/three/CSS3DRender'\nimport * as THREE from 'three/webgpu'\nimport { RectangleScaleHelperAbstract } from '.'\nimport type { Create3DElementReturnType } from '../../../CSS3DRenderPlugin'\nimport type { Vector3 } from 'three/webgpu'\nimport { rectangleScaleDom } from './HTML/rectangleScaleDom'\nimport type { CSS3DObjectPlus } from '../../../CSS3DRenderPlugin/utils/three/CSS3DObject'\nimport { cameraHooks } from '../utils/cameraHooks'\n\ntype NonVoid<T> = T extends void ? never : T\n\nexport class CSS3DScaleHelper<T extends CSS3DObjectPlus = CSS3DObjectPlus> extends RectangleScaleHelperAbstract<T, HTMLElement> {\n public name = 'CSS3DScaleHelper'\n public points: RectangleScaleHelperAbstract<THREE.Object3D, HTMLElement>['points'] = []\n public cornerPositions: Vector3[] = []\n public css3DInstance?: NonVoid<Create3DElementReturnType>\n public get helperObject() {\n if (!this.css3DInstance?.css3DObject) throw new Error('css3DInstance is not initialized')\n return this.css3DInstance.css3DObject\n }\n public plane?: THREE.Mesh<THREE.PlaneGeometry, THREE.MeshBasicMaterial>\n private css3DRenderer = new CSS3DRender()\n private camera: THREE.Camera\n private scene: THREE.Scene\n private container: HTMLElement\n private enabled = false\n private initialScale?: { x: number; y: number } // 记录初始缩放值\n\n\n public constructor(originObject3D: T, container: HTMLElement, camera: THREE.Camera, scene: THREE.Scene) {\n super(originObject3D)\n this.camera = camera\n this.scene = scene\n this.container = container\n this.initRectangleScaleHelper()\n }\n\n public initQuaternion(): void {\n this.quaternion.copy(this.originObject3D.quaternion)\n }\n\n public applyMatrix4(matrix: THREE.Matrix4) {\n super.applyMatrix4(matrix)\n this.helperObject.applyMatrix4(matrix)\n this.plane?.applyMatrix4(matrix)\n this.cornerPositions.forEach((cornerPosition) => cornerPosition.applyMatrix4(matrix))\n }\n\n public showDraggingHelper() {\n // nothing to do\n }\n\n public applyHelperScaleMatrix4(matrix: THREE.Matrix4, origin?: Vector3) {\n this.plane?.scale.applyMatrix4(matrix)\n this.helperObject.applyScaleMatrix4(matrix)\n\n // 缩放后更新球体校正和小点容器尺寸\n setTimeout(() => {\n this.updateSphereCorrection()\n }, 0)\n }\n\n public updatePoints() {\n const position8 = this.calculatePointPosition(this.cornerPositions as [Vector3, Vector3, Vector3, Vector3])\n this.points.forEach((point, index) => {\n point.position.copy(position8[index]!)\n })\n }\n\n public update(camera: THREE.Camera) {\n // 更新CSS3D元素的位置\n if (this.css3DInstance?.css3DObject) {\n this.helperObject.position.copy(this.originObject3D.position)\n }\n\n // 更新平面位置\n if (this.plane) {\n this.plane.position.copy(this.originObject3D.position)\n }\n\n // 更新控制点位置\n this.updatePoints()\n\n // 更新CSS3D元素的可见性\n if (this.css3DInstance) {\n this.css3DInstance.show()\n }\n\n if (this.plane) {\n this.plane.visible = true\n }\n }\n\n public applyHelperQuaternion(quaternion: THREE.Quaternion, origin: Vector3) {\n const css3DObject = this.css3DInstance?.css3DObject\n\n if (css3DObject) {\n const v = new THREE.Vector3().subVectors(css3DObject.position, origin).applyQuaternion(quaternion).add(origin)\n css3DObject.position.copy(v)\n css3DObject.applyQuaternion(quaternion)\n }\n\n if (this.plane) {\n const v = new THREE.Vector3().subVectors(this.plane.position, origin).applyQuaternion(quaternion).add(origin)\n this.plane.position.copy(v)\n this.plane.applyQuaternion(quaternion)\n }\n\n this.cornerPositions.forEach((cornerPosition) => {\n const v = new THREE.Vector3().subVectors(cornerPosition, origin).applyQuaternion(quaternion).add(origin)\n cornerPosition.copy(v)\n })\n }\n\n public enable() {\n if (this.enabled) return\n this.enabled = true\n this.css3DInstance?.enable()\n if (this.plane) this.scene.add(this.plane)\n }\n\n public disable() {\n if (!this.enabled) return\n this.enabled = false\n this.css3DInstance?.disable()\n if (this.plane) this.scene.remove(this.plane)\n }\n\n public show() {\n this.css3DInstance?.show()\n if (this.plane) this.plane.visible = true\n }\n\n public hide() {\n this.css3DInstance?.hide()\n if (this.plane) this.plane.visible = false\n }\n\n public dispose() {\n this.disable()\n this.css3DRenderer.dispose()\n }\n\n /**\n * 缩放结束时的回调方法\n * 触发相机更新事件\n */\n public onScaleEnd() {\n // 手动触发相机更新事件\n cameraHooks(this.camera).emit('cameraUpdate')\n }\n\n private updateSphereCorrection() {\n if (!this.css3DInstance) return\n\n // 记录初始缩放值(第一次调用时)\n if (!this.initialScale) {\n this.initialScale = {\n x: this.originObject3D.scale.x,\n y: this.originObject3D.scale.y,\n }\n }\n\n // 计算相对于初始值的缩放比例\n const currentScale = this.originObject3D.scale\n const relativeScaleX = currentScale.x / this.initialScale.x\n const relativeScaleY = currentScale.y / this.initialScale.y\n // 通过 CSS 变量设置父级缩放值\n const parentElement = this.css3DInstance.css3DObject.container\n parentElement.style.setProperty('--parent-scaleX', relativeScaleX.toString())\n parentElement.style.setProperty('--parent-scaleY', relativeScaleY.toString())\n }\n\n private initRectangleScaleHelper() {\n const cornerPositions = this.getCornerPositions()\n\n if (!cornerPositions) return\n\n this.cornerPositions = cornerPositions\n\n const css3DInstance = this.css3DRenderer.create3DElement(this.camera, cornerPositions, { ratio: 0.003 }) // ratio 暂时不用和 originObject3D 保持同步,因为本来就是不同的东西\n\n if (!css3DInstance) return\n\n this.css3DInstance = css3DInstance\n css3DInstance.appendToElement(this.container)\n\n // create UI\n const css3DObjectElement = css3DInstance.css3DObject.container\n const { container: dom, spheres } = rectangleScaleDom()\n this.points = spheres.map((sphere, index) => ({\n direction: sphere.direction,\n point: sphere.element,\n position: this.calculatePointPosition(cornerPositions)[index]!,\n }))\n\n // append html\n // css3DObjectElement.appendChild(backgroundDom())\n css3DObjectElement.insertBefore(dom, css3DObjectElement.children[0] ?? null)\n\n this.helperObject.position.copy(this.originObject3D.position)\n this.plane?.position.copy(this.originObject3D.position)\n }\n\n private getCornerPositions() {\n const { originObject3D } = this\n if ((originObject3D as any).isCSS3DObject && (originObject3D as any).cornerPoints) {\n const o = originObject3D as InstanceType<typeof CSS3DObjectPlus>\n return o.cornerPoints\n } else {\n console.error('当前物体暂时不支持 ScaleHelper')\n }\n }\n\n private calculatePointPosition(cornerPositions: [THREE.Vector3, THREE.Vector3, THREE.Vector3, THREE.Vector3]) {\n /**\n * 6----5----4\n * | |\n * 7 3\n * | |\n * 0----1----2\n */\n return [\n cornerPositions[0].clone(),\n cornerPositions[0].clone().add(cornerPositions[1]).divideScalar(2),\n cornerPositions[1].clone(),\n cornerPositions[1].clone().add(cornerPositions[2]).divideScalar(2),\n cornerPositions[2].clone(),\n cornerPositions[2].clone().add(cornerPositions[3]).divideScalar(2),\n cornerPositions[3].clone(),\n cornerPositions[3].clone().add(cornerPositions[0]).divideScalar(2),\n ]\n }\n}\n","import * as THREE from 'three/webgpu'\nimport { BoundingBoxHelperAbstract } from '../Base/BaseHelper'\nimport { boundingBox } from '../../three/boundingBox'\nimport setObjectQuaternion from '../utils/setObjectQuaternion'\n\nexport class BoundingBoxHelper<T extends THREE.Object3D = THREE.Object3D> extends BoundingBoxHelperAbstract<T> {\n public name = 'BoundingBoxHelper'\n public box: THREE.Mesh<THREE.BufferGeometry, THREE.MeshBasicMaterial>\n public outline: THREE.LineSegments<THREE.BufferGeometry, THREE.LineBasicMaterial>\n private positionAttribute: THREE.BufferAttribute\n\n public constructor(originObject: T) {\n super(originObject)\n\n this.positionAttribute = new THREE.BufferAttribute(new Float32Array(8 * 3), 3)\n this.box = this.createBox()\n this.outline = this.createOutline()\n\n this.add(this.box, this.outline)\n this.update()\n }\n\n public initQuaternion(): void {\n this.quaternion.copy(this.originObject3D.quaternion)\n }\n\n public setHelperQuaternion(quaternion: THREE.Quaternion, origin?: THREE.Vector3) {\n setObjectQuaternion(this, quaternion, origin)\n }\n\n public raycasterIntersectObject(raycaster: THREE.Raycaster, intersection: THREE.Intersection[]): THREE.Intersection[] {\n return raycaster.intersectObject(this, false, intersection)\n }\n\n public raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]) {\n // 判断相交时,只判断面\n this.box.raycast(raycaster, intersects)\n }\n\n private update() {\n /*\n 5____4\n 1/___0/|\n | 6__|_7\n 2/___3/\n\n 0: max.x, max.y, max.z\n 1: min.x, max.y, max.z\n 2: min.x, min.y, max.z\n 3: max.x, min.y, max.z\n 4: max.x, max.y, min.z\n 5: min.x, max.y, min.z\n 6: min.x, min.y, min.z\n 7: max.x, min.y, min.z\n\t\t*/\n const box3 = boundingBox(this.originObject3D)\n if (!box3) return\n\n const { min, max } = box3\n\n this.positionAttribute.setXYZ(0, max.x, max.y, max.z)\n this.positionAttribute.setXYZ(1, min.x, max.y, max.z)\n this.positionAttribute.setXYZ(2, min.x, min.y, max.z)\n this.positionAttribute.setXYZ(3, max.x, min.y, max.z)\n this.positionAttribute.setXYZ(4, max.x, max.y, min.z)\n this.positionAttribute.setXYZ(5, min.x, max.y, min.z)\n this.positionAttribute.setXYZ(6, min.x, min.y, min.z)\n this.positionAttribute.setXYZ(7, max.x, min.y, min.z)\n\n this.positionAttribute.needsUpdate = true\n }\n\n private createOutline() {\n const lineIndices = new Uint16Array([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7])\n const lineGeometry = new THREE.BufferGeometry()\n lineGeometry.setIndex(new THREE.BufferAttribute(lineIndices, 1))\n lineGeometry.setAttribute('position', this.positionAttribute)\n const lineMaterial = new THREE.LineBasicMaterial({\n color: 0x00fcff,\n linewidth: 1,\n opacity: 1,\n toneMapped: false,\n })\n const lineSegments = new THREE.LineSegments(lineGeometry, lineMaterial)\n lineSegments.matrixAutoUpdate = false\n return lineSegments\n }\n\n private createBox() {\n const boxIndices = new Uint16Array([\n 0, 1, 2, 0, 2, 3, 0, 3, 7, 0, 7, 4, 0, 4, 5, 0, 5, 1, 6, 1, 5, 6, 2, 1, 6, 5, 4, 6, 4, 7, 6, 3, 2, 6, 7, 3,\n ])\n const boxGeometry = new THREE.BufferGeometry()\n boxGeometry.setIndex(new THREE.BufferAttribute(boxIndices, 1))\n boxGeometry.setAttribute('position', this.positionAttribute)\n const boxMaterial = new THREE.MeshBasicMaterial({\n color: 0x00fcff,\n opacity: 0.1,\n depthTest: false,\n transparent: true,\n })\n const box = new THREE.Mesh(boxGeometry, boxMaterial)\n return box\n }\n}\n","import * as THREE from 'three/webgpu'\nimport { Subscribe } from '../../Subscribe'\nimport type { SolidGuideOptions } from '../utils/solidGuide'\nimport type { HelperEventMap, HelperOffset, InternalHelperEventMap, ScaleCallback } from '../typings'\nimport type { BaseHelper } from './BaseHelper'\nimport type DomEvents from '../../threex/domevents'\nimport { notNil } from '../../isNil'\nimport { boundingBox } from '../../three/boundingBox'\nimport type { Vector3Position } from '../../../typings/math.type'\nimport { toArray } from '../../util'\nimport { cameraHooks } from '../utils/cameraHooks'\n\nexport let originOpacity: { opacity: number } | null = null\n\ntype Config = {\n offset?: HelperOffset\n yAxis?: THREE.Vector3 | (() => THREE.Vector3)\n xAxis?: THREE.Vector3 | (() => THREE.Vector3)\n zAxis?: THREE.Vector3 | (() => THREE.Vector3)\n scaleCallback?: ScaleCallback\n /** 实线样式与行为配置(透传给 SolidGuideLine) */\n solidGuide?: SolidGuideOptions\n}\n\nexport abstract class BaseController<T extends BaseHelper = BaseHelper, K extends THREE.Object3D = THREE.Object3D> {\n public originObject3D: K\n public hooks: Subscribe<HelperEventMap>\n public preventTapDefaultEvent = false\n protected internalHooks: Subscribe<InternalHelperEventMap>\n protected readonly disposers: (() => void)[] = []\n protected helperObject3D: T\n protected camera: THREE.Camera\n protected model: THREE.Object3D\n protected scene: THREE.Object3D\n protected container: HTMLElement\n protected domEvents: DomEvents\n protected isDragging = false\n protected enabled = false\n protected name = 'BaseController'\n protected boundingBox?: THREE.Box3\n protected config: Config\n private onRender: () => void\n protected cameraHooks: Subscribe<{\n cameraUpdate: () => any\n }>\n /** 其他控制器的引用,用于跨控制器状态检查 */\n protected otherControllers?: {\n moveController?: BaseController\n rotateController?: BaseController\n scaleController?: BaseController\n }\n\n /**\n * 更新其他控制器的引用\n */\n public updateOtherControllers(otherControllers: {\n moveController?: BaseController\n rotateController?: BaseController\n scaleController?: BaseController\n }) {\n this.otherControllers = otherControllers\n }\n\n /**\n * 获取当前控制器的拖拽状态\n */\n public getIsDragging(): boolean {\n return this.isDragging\n }\n\n public constructor(\n params: {\n camera: THREE.Camera\n model: THREE.Object3D\n originObject3D: K\n helperObject3D: T\n container: HTMLElement\n domEvents: DomEvents\n scene: THREE.Object3D\n onRender?: () => void\n sharedHooks?: Subscribe<HelperEventMap>\n sharedInternalHooks?: Subscribe<InternalHelperEventMap>\n /** 其他控制器的引用,用于跨控制器状态检查 */\n otherControllers?: {\n moveController?: BaseController\n rotateController?: BaseController\n scaleController?: BaseController\n }\n },\n config?: Config,\n ) {\n this.hooks = params.sharedHooks ?? new Subscribe<HelperEventMap>()\n this.internalHooks = params.sharedInternalHooks ?? new Subscribe<InternalHelperEventMap>()\n this.camera = params.camera\n this.model = params.model\n this.originObject3D = params.originObject3D\n this.helperObject3D = params.helperObject3D\n this.container = params.container\n this.scene = params.scene\n this.domEvents = params.domEvents\n this.onRender = params.onRender ?? (() => {})\n this.config = config ?? {}\n this.otherControllers = params.otherControllers\n this.initialHelperPosition()\n this.initialHelperQuaternion()\n this.updateHelperScale()\n this.cameraHooks = cameraHooks(this.camera)\n\n this.enable()\n\n const handleSetObjectScale = this.onSetOriginObjectScale.bind(this)\n const handleSetObjectRotate = this.onSetOriginObjectRotate.bind(this)\n const handleSetObjectPosition = this.onSetOriginObjectPosition.bind(this)\n\n const handleApplyObjectScale = this.onApplyOriginObjectScale.bind(this)\n const handleApplyObjectRotate = this.onApplyOriginObjectRotate.bind(this)\n const handleApplyObjectPosition = this.onApplyOriginObjectPosition.bind(this)\n const initialHelperPosition = this.initialHelperPosition.bind(this)\n\n this.cameraHooks.on('cameraUpdate', this.updateHelperScale)\n\n this.internalHooks.on('initialHelperPosition', initialHelperPosition)\n\n this.internalHooks.on('setObjectScale', handleSetObjectScale)\n this.internalHooks.on('setObjectRotate', handleSetObjectRotate)\n this.internalHooks.on('setObjectPosition', handleSetObjectPosition)\n\n this.internalHooks.on('applyObjectPosition', handleApplyObjectPosition)\n this.internalHooks.on('applyObjectRotate', handleApplyObjectRotate)\n this.internalHooks.on('applyObjectScale', handleApplyObjectScale)\n\n // updateHelperScale 监听得在后面,因为要保证先更新 helper 的位置等信息后,再计算大小\n this.hooks.on('moveEnd', this.updateHelperScale)\n this.internalHooks.on('setObjectPosition', this.updateHelperScale)\n this.internalHooks.on('initialHelperPosition', this.updateHelperScale)\n\n this.disposers.push(() => {\n this.cameraHooks.off('cameraUpdate', this.updateHelperScale)\n\n this.internalHooks.off('initialHelperPosition', initialHelperPosition)\n\n this.internalHooks.off('setObjectScale', handleSetObjectScale)\n this.internalHooks.off('setObjectRotate', handleSetObjectRotate)\n this.internalHooks.off('setObjectPosition', handleSetObjectPosition)\n\n this.internalHooks.off('applyObjectPosition', handleApplyObjectPosition)\n this.internalHooks.off('applyObjectRotate', handleApplyObjectRotate)\n this.internalHooks.off('applyObjectScale', handleApplyObjectScale)\n\n this.hooks.off('moveEnd', this.updateHelperScale)\n this.internalHooks.off('setObjectPosition', this.updateHelperScale)\n this.internalHooks.off('initialHelperPosition', this.updateHelperScale)\n })\n }\n\n public initialHelperPosition() {\n this.helperObject3D.initialPosition(this.calculateOffset(this.config.offset))\n }\n\n public initialHelperQuaternion() {\n this.helperObject3D.initQuaternion(this.config)\n }\n\n public enable() {\n if (this.enabled) return\n this.enabled = true\n this.scene.add(this.helperObject3D)\n this.helperObject3D.enable()\n this.render()\n }\n\n public disable() {\n if (!this.enabled) return\n this.enabled = false\n this.helperObject3D.disable()\n this.render()\n }\n\n public show() {\n this.helperObject3D.show()\n this.render()\n }\n\n public hide() {\n this.helperObject3D.hide()\n this.render()\n }\n\n public dispose() {\n this.disposers?.forEach((d) => d?.())\n this.helperObject3D.dispose()\n this.render()\n }\n\n /**\n * @description: applyHelperMatrix4\n * @param {THREE.Matrix4} matrix position 偏移量\n */\n public applyHelperMatrix4(matrix: THREE.Matrix4) {\n this.helperObject3D.applyMatrix4(matrix)\n }\n\n /**\n * @description: applyHelperQuaternion\n * @param {THREE.Quaternion} quaternion 旋转四元数\n * @param {THREE.Vector3} origin 旋转中心\n */\n public applyHelperQuaternion(quaternion: THREE.Quaternion, origin: THREE.Vector3) {\n this.helperObject3D.applyHelperQuaternion(quaternion, origin)\n }\n\n /**\n * @description: applyHelperScaleMatrix4\n * @param {THREE.Matrix4} matrix 缩放矩阵\n * @param {THREE.Vector3} origin 缩放中心\n */\n public applyHelperScaleMatrix4(matrix: THREE.Matrix4, origin?: THREE.Vector3) {\n this.helperObject3D.applyHelperScaleMatrix4(matrix, origin)\n }\n\n public onWantsTapGesture = (raycaster: THREE.Raycaster): false | void => {\n const selectedObject = this.getIntersectObject(raycaster)\n if (selectedObject) return false\n return\n }\n\n public updateHelperScale = () => {\n // 调用 helper 的 update 方法\n if ('update' in this.helperObject3D && typeof this.helperObject3D.update === 'function') {\n this.helperObject3D.update(this.camera)\n }\n this.helperObject3D.setScaleByCamera(this.camera as any)\n }\n\n public onWantsGesture(type: 'press' | 'pan' | string, pointers: { x: number; y: number }[], final: boolean): false | void {\n if (this.isDragging) return false\n }\n\n public onIntersectionOnModelUpdate(intersection: THREE.Intersection) {}\n\n /**\n * @description: onApplyOriginObjectScale\n * @param {THREE.Matrix4} params.matrix 缩放矩阵\n * @param {THREE.Vector3} params.origin 缩放中心\n */\n protected onApplyOriginObjectScale(params: { matrix: THREE.Matrix4; origin?: THREE.Vector3 }) {\n this.applyHelperScaleMatrix4(params.matrix, params.origin)\n }\n\n /**\n * @description: onApplyOriginObjectRotate\n * @param {THREE.Quaternion} params.quaternion 旋转四元数\n * @param {THREE.Vector3} params.origin 旋转中心\n */\n protected onApplyOriginObjectRotate(params: { quaternion: THREE.Quaternion; origin: THREE.Vector3 }) {\n this.applyHelperQuaternion(params.quaternion, params.origin)\n }\n\n /**\n * @description: onApplyOriginObjectPosition\n * @param {THREE.Matrix4} params.matrix position 偏移量\n */\n protected onApplyOriginObjectPosition(params: { matrix: THREE.Matrix4 }) {\n this.applyHelperMatrix4(params.matrix)\n }\n\n protected onSetOriginObjectScale(scale: THREE.Vector3) {\n this.helperObject3D.scale.copy(scale)\n this.updateOffsetByScale(scale)\n }\n\n protected onSetOriginObjectRotate(quaternion: THREE.Quaternion, origin: THREE.Vector3) {\n this.helperObject3D.setHelperQuaternion(quaternion, origin)\n }\n\n protected onSetOriginObjectPosition(position: THREE.Vector3) {\n this.helperObject3D.position.copy(position.clone().add(this.calculateOffset(this.config.offset)))\n }\n\n protected render() {\n this.onRender()\n }\n\n protected updateOffsetByScale(scale: THREE.Vector3) {\n if (this.boundingBox && this.config.offset) {\n const origin = this.originObject3D.position\n const max = new THREE.Vector3().subVectors(this.boundingBox.max, origin).multiply(scale).add(origin)\n const min = new THREE.Vector3().subVectors(this.boundingBox.min, origin).multiply(scale).add(origin)\n const offset = this.calculateOffset(this.config.offset, { min, max })\n this.helperObject3D.initialPosition(offset)\n }\n }\n\n protected hoverListener(\n object3D: THREE.Object3D | undefined | THREE.Group | (THREE.Object3D | undefined | THREE.Group)[],\n hoverColor: THREE.Color | string | number = 0xffffff,\n hoverOpacity = 1,\n ): () => void {\n const objects = toArray(object3D).filter(notNil)\n const disposers: (() => void)[] = []\n for (const object of objects) {\n if ((object as any).material || object instanceof THREE.Group) {\n const meshes =\n object instanceof THREE.Group\n ? (object.children.filter((child) => child instanceof THREE.Mesh) as THREE.Mesh[])\n : ([object] as THREE.Mesh<any, THREE.MeshBasicMaterial>[])\n\n meshes.forEach((mesh) => {\n // 处理材质数组的情况(如 CenterHandle 的多面材质)\n if (Array.isArray(mesh.material)) {\n ;(mesh as any)['__originalColor__'] = (mesh as any)['__originalColor__'] ?? mesh.material.map((mat) => mat.color.clone())\n ;(mesh as any)['__originalOpacity__'] = (mesh as any)['__originalOpacity__'] ?? mesh.material.map((mat) => mat.opacity)\n } else {\n ;(mesh as any)['__originalColor__'] = (mesh as any)['__originalColor__'] ?? mesh.material.color.clone()\n ;(mesh as any)['__originalOpacity__'] = (mesh as any)['__originalOpacity__'] ?? mesh.material.opacity\n }\n })\n\n const setHoverColor = () => {\n meshes.forEach((mesh) => {\n if (mesh.name === 'ScaleHelperTransparentGroup') {\n if (mesh.children[0]) {\n mesh.children[0].material.color.set(hoverColor)\n mesh.children[0].material.opacity = hoverOpacity\n }\n } else {\n // 处理材质数组的情况\n if (Array.isArray(mesh.material)) {\n mesh.material.forEach((mat) => {\n mat.color.set(hoverColor)\n mat.opacity = hoverOpacity\n })\n } else {\n mesh.material.color.set(hoverColor)\n mesh.material.opacity = hoverOpacity\n }\n }\n })\n this.render()\n }\n const resetColor = () => {\n meshes.forEach((mesh) => {\n if (mesh.name === 'ScaleHelperTransparentGroup') {\n if (mesh.children[0]) {\n mesh.children[0].material.color.set(0xffff00)\n mesh.children[0].material.opacity = 1\n }\n } else {\n // 处理材质数组的情况\n if (Array.isArray(mesh.material)) {\n const originalColors = (mesh as any)['__originalColor__']\n const originalOpacities = (mesh as any)['__originalOpacity__']\n mesh.material.forEach((mat, index) => {\n if (originalColors && originalColors[index]) {\n mat.color.copy(originalColors[index])\n }\n if (originalOpacities && originalOpacities[index] !== undefined) {\n mat.opacity = originalOpacities[index]\n }\n })\n } else {\n mesh.material.color.copy((mesh as any)['__originalColor__'])\n mesh.material.opacity = (mesh as any)['__originalOpacity__']\n }\n }\n })\n this.render()\n }\n\n const handleMouseover = (e) => {\n if (this.isDragging) return\n setHoverColor()\n }\n const handleMouseout = (e) => {\n if (this.isDragging) return\n resetColor()\n }\n\n for (const mesh of meshes) {\n this.domEvents.addEventListener(mesh, 'mouseover', handleMouseover)\n this.domEvents.addEventListener(mesh, 'mouseout', handleMouseout)\n this.hooks.on('moveStart', setHoverColor)\n this.hooks.on('moveEnd', resetColor)\n this.hooks.on('rotateEnd', resetColor)\n this.hooks.on('scaleEnd', resetColor)\n disposers.push(() => {\n this.domEvents.removeEventListener(mesh, 'mouseover', handleMouseover)\n this.domEvents.removeEventListener(mesh, 'mouseout', handleMouseout)\n this.hooks.off('moveStart', setHoverColor)\n this.hooks.off('moveEnd', resetColor)\n this.hooks.off('rotateEnd', resetColor)\n this.hooks.off('scaleEnd', resetColor)\n })\n }\n }\n }\n return () => disposers.forEach((disposer) => disposer?.())\n }\n\n private getIntersectObject(raycaster: THREE.Raycaster) {\n const cameraPosition = this.camera.position\n const object = this.helperObject3D\n // 如果当前没有模型,则不存在模型被点击\n if (!object) return undefined\n\n // 如果存在模型,需要判断模型与射线的交点和 model 与射线的交点的远近\n\n const intersection = this.helperObject3D.raycasterIntersectObject(raycaster)[0]\n if (!intersection) return undefined\n const objectIntersection = intersection\n objectIntersection.object = object\n\n // 如果 five model intersection 更近,返回 undefined\n if ((this.model as any)['intersectRaycaster']) {\n const modelIntersection = (this.model as any).intersectRaycaster(raycaster)[0]\n if (modelIntersection && modelIntersection.point.distanceTo(cameraPosition) < objectIntersection.point.distanceTo(cameraPosition))\n return undefined\n }\n\n return objectIntersection.object\n }\n\n private getBox: () => { min: Vector3Position; max: Vector3Position } = () => {\n if (this.boundingBox) return this.boundingBox\n else {\n this.boundingBox = boundingBox(this.originObject3D)\n return this.boundingBox\n }\n }\n\n private calculateOffset(offset?: HelperOffset, box3?: { min: Vector3Position; max: Vector3Position }) {\n const result = new THREE.Vector3(0, 0, 0)\n\n if (!offset) return result\n\n const getBox: () => { min: Vector3Position; max: Vector3Position } = () => {\n if (box3) return box3\n return this.getBox()\n }\n\n // x\n if (typeof offset.x === 'number') result.setX(offset.x)\n else if (typeof offset.x === 'object') {\n const box = getBox()\n result.setX((box.max.x - box.min.x) * offset.x.percents)\n }\n\n // y\n if (typeof offset.y === 'number') result.setY(offset.y)\n else if (typeof offset.y === 'object') {\n const box = getBox()\n result.setY((box.max.y - box.min.y) * offset.y.percents)\n }\n\n // z\n if (typeof offset.z === 'number') result.setZ(offset.z)\n else if (typeof offset.z === 'object') {\n const box = getBox()\n result.setZ((box.max.z - box.min.z) * offset.z.percents)\n }\n\n return result\n }\n}\n","import { RENDER_ORDER } from '../Constants/RenderOrder'\nimport * as THREE from 'three/webgpu'\n\n/** 将世界坐标投影为屏幕像素坐标 */\nexport function projectToScreen(camera: THREE.Camera, container: HTMLElement | null | undefined, point: THREE.Vector3) {\n const width = container?.clientWidth || 1280\n const height = container?.clientHeight || 720\n const p = point.clone().project(camera)\n const x = (p.x + 1) * 0.5 * width\n const y = (1 - (p.y + 1) * 0.5) * height\n return new THREE.Vector2(x, y)\n}\n\n/** 估算某方向上线段的像素与世界长度的比例(世界单位/像素) */\nexport function computeWorldPerPixel(\n camera: THREE.Camera,\n container: HTMLElement | null | undefined,\n center: THREE.Vector3,\n direction: THREE.Vector3,\n) {\n const dir = direction.clone().normalize()\n const sample = 1\n const p1 = center.clone().sub(dir.clone().multiplyScalar(sample))\n const p2 = center.clone().add(dir.clone().multiplyScalar(sample))\n const s1 = projectToScreen(camera, container, p1)\n const s2 = projectToScreen(camera, container, p2)\n const pixelLength = s1.distanceTo(s2)\n if (pixelLength < 1e-3) return undefined\n const worldPerPixel = (2 * sample) / pixelLength\n return worldPerPixel\n}\n\n/** 计算直线长度:随相机距离/视口变化自适应,限制在可视范围内 */\nexport function computeGuideLength(camera: THREE.Camera, center: THREE.Vector3) {\n let viewWidth = 10\n let viewHeight = 10\n\n const persp = (camera as any).isPerspectiveCamera\n const ortho = (camera as any).isOrthographicCamera\n if (persp) {\n const cam = camera as THREE.PerspectiveCamera\n const distance = cam.position.distanceTo(center)\n const vFov = (cam.fov * Math.PI) / 180\n viewHeight = 2 * Math.tan(vFov / 2) * distance\n viewWidth = viewHeight * cam.aspect\n } else if (ortho) {\n const cam = camera as THREE.OrthographicCamera\n viewWidth = Math.abs(cam.right - cam.left)\n viewHeight = Math.abs(cam.top - cam.bottom)\n }\n\n const diag = Math.sqrt(viewWidth * viewWidth + viewHeight * viewHeight)\n const baseLength = diag * 0.8\n const minLen = Math.min(viewWidth, viewHeight) * 0.25\n const maxLen = diag * 1.2\n const length = Math.max(minLen, Math.min(baseLength, maxLen))\n return length\n}\n\nexport type SolidGuideOptions = {\n color?: number\n renderOrder?: number\n}\n\nexport class SolidGuideLine {\n private camera: THREE.Camera\n private container: HTMLElement | null | undefined\n private defaults: SolidGuideOptions\n\n public constructor(camera: THREE.Camera, container: HTMLElement | null | undefined, defaults?: SolidGuideOptions) {\n this.camera = camera\n this.container = container\n this.defaults = { ...(defaults || {}) }\n }\n\n /** 创建无限长直线(Line + LineBasicMaterial),穿过整个平面 */\n public createSolidLine(center: THREE.Vector3, direction: THREE.Vector3, options?: SolidGuideOptions) {\n const merged = { color: 0xffffff, renderOrder: RENDER_ORDER.DRAG_GUIDE_LINE, ...this.defaults, ...(options || {}) }\n const dir = direction.clone().normalize()\n\n // 创建一条足够长的直线,穿过整个可视区域\n const length = this.computeInfiniteLineLength(center)\n const start = center.clone().add(dir.clone().multiplyScalar(-length))\n const end = center.clone().add(dir.clone().multiplyScalar(length))\n\n const positions = new Float32Array([start.x, start.y, start.z, end.x, end.y, end.z])\n\n const geometry = new THREE.BufferGeometry()\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))\n\n const material = new THREE.LineBasicMaterial({\n color: merged.color,\n depthTest: false,\n depthWrite: false,\n transparent: true,\n opacity: 0.65,\n })\n\n const line = new THREE.Line(geometry, material)\n line.renderOrder = merged.renderOrder\n return line\n }\n\n /** 更新已创建的直线,使其始终穿过整个平面 */\n public updateSolidLine(\n line: THREE.Line<THREE.BufferGeometry, THREE.LineBasicMaterial>,\n center: THREE.Vector3,\n direction: THREE.Vector3,\n options?: SolidGuideOptions,\n ) {\n const dir = direction.clone().normalize()\n\n // 重新计算直线长度和位置\n const length = this.computeInfiniteLineLength(center)\n const start = center.clone().add(dir.clone().multiplyScalar(-length))\n const end = center.clone().add(dir.clone().multiplyScalar(length))\n\n const positions = new Float32Array([start.x, start.y, start.z, end.x, end.y, end.z])\n\n const geometry = line.geometry as THREE.BufferGeometry\n const attr = geometry.getAttribute('position') as THREE.BufferAttribute | undefined\n if (attr && attr.itemSize === 3 && attr.array.length === positions.length) {\n ;(attr.array as Float32Array).set(positions)\n attr.needsUpdate = true\n } else {\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))\n }\n\n // 更新材质颜色\n if (options?.color !== undefined) {\n line.material.color.setHex(options.color)\n }\n }\n\n /** 计算\"无限\"直线的长度,确保穿过整个可视区域 */\n private computeInfiniteLineLength(center: THREE.Vector3): number {\n const baseLength = computeGuideLength(this.camera, center)\n // 使用一个大的倍数确保直线看起来无限长\n return baseLength * 10 // 比原来的虚线长10倍,确保穿过整个平面\n }\n\n /** 释放直线的几何与材质 */\n public dispose(\n line?: THREE.Line<THREE.BufferGeometry, THREE.LineBasicMaterial>,\n ) {\n if (!line) return\n line.geometry.dispose()\n const material = line.material\n if (Array.isArray(material)) material.forEach((m) => m.dispose())\n else material.dispose()\n }\n\n /** 更新默认配置 */\n public updateDefaults(options: SolidGuideOptions) {\n this.defaults = { ...this.defaults, ...options }\n }\n}\n","import { BaseController } from '../Base/BaseController'\nimport { RENDER_ORDER } from '../Constants/RenderOrder'\nimport * as THREE from 'three/webgpu'\nimport { SolidGuideLine } from '../utils/solidGuide'\nimport { getMouseRaycaster } from '../utils'\nimport type { MoveHelperAbstract } from '../Helper'\nimport type { Direction } from '../typings'\nimport { rayOnLine } from '../../../Sculpt/utils/three/rayOnLine'\nimport { CenterHandle } from '../Helper/Objects/CenterHandle'\n\ntype UseFaceNormalInterface =\n | {\n enable?: boolean\n /**\n * @description: 期望对齐的方向,默认为Y轴对齐Face的法向向量,即 `{ x: 0, y: 1, z: 0 }`\n */\n alignmentVector?: { x?: number; y?: number; z?: number }\n /**\n * @description: 修正后的face\n */\n fixedFaceNormal?: (face: THREE.Vector3) => THREE.Vector3\n }\n | boolean\n\nexport class MoveController<T extends MoveHelperAbstract = MoveHelperAbstract> extends BaseController<T> {\n public get moveByMouseEnable() {\n return this._moveByMouse.enabled\n }\n\n protected name = 'MoveController'\n\n private startInfo?: {\n // 开始位置\n startVectorProject: THREE.Vector3\n //\n line: THREE.Line3\n // 拖拽方向(单位向量)\n dirNormalized?: THREE.Vector3\n // 拖拽类型\n draggingDirection: Direction\n // 平面拖拽时的固定平面\n plane?: THREE.Plane\n }\n\n /** 拖拽时用于显示方向参考的直线(与 ScaleController 一致:Line + LineBasicMaterial) */\n private dragGuideLine?: THREE.Line<THREE.BufferGeometry, THREE.LineBasicMaterial>\n private solidGuide = new SolidGuideLine(this.camera, this.container, this.config?.solidGuide ?? {})\n\n private _moveByMouse: {\n enabled: boolean\n useFaceNormal?: UseFaceNormalInterface\n } = {\n enabled: false,\n }\n\n private mouseInfo?: {\n x: number\n y: number\n mouseDownTimestamp: number\n }\n\n private mousedownEventListenerDisposer: () => any\n\n public constructor(...params: ConstructorParameters<typeof BaseController<T>>) {\n super(...params)\n\n // add hover listener\n const helper = this.helperObject3D\n this.hoverListener([helper.xArrow, helper.yArrow, helper.zArrow])\n\n // 为 centerHandle 添加特殊的 hover 处理,保持其动态颜色效果\n if (helper.centerHandle && helper.centerHandle instanceof CenterHandle) {\n const centerHandle = helper.centerHandle as CenterHandle\n const centerHandleMesh = centerHandle.cube\n const hoverColor = 0xffffff\n\n const handleMouseover = () => {\n if (this.isDragging) return\n // hover 时所有面变白\n if (Array.isArray(centerHandleMesh.material)) {\n centerHandleMesh.material.forEach((mat) => {\n mat.color.set(hoverColor)\n })\n }\n this.render()\n }\n\n const handleMouseout = () => {\n if (this.isDragging) return\n // mouseout 时重新计算动态颜色\n centerHandle.update(this.camera)\n this.render()\n }\n\n this.domEvents.addEventListener(centerHandleMesh, 'mouseover', handleMouseover)\n this.domEvents.addEventListener(centerHandleMesh, 'mouseout', handleMouseout)\n }\n\n const show = this.show.bind(this)\n const hide = this.hide.bind(this)\n\n const updateHelperByCamera = () => {\n this.helperObject3D.update(this.camera)\n // 拖拽中时,更新直线以保持像素恒定\n if (this.isDragging) this.updateDragGuideLineScale()\n this.render()\n }\n\n updateHelperByCamera()\n\n // mouse\n this.domEvents.addEventListener(this.helperObject3D, 'mousedown', this.dragStart)\n document.addEventListener('mousemove', this.dragging)\n document.addEventListener('mouseup', this.dragEnd)\n // touch\n this.domEvents.addEventListener(this.helperObject3D, 'touchstart', this.dragStart)\n document.addEventListener('touchmove', this.dragging)\n document.addEventListener('touchend', this.dragEnd)\n\n this.hooks.on('rotateStart', hide)\n this.hooks.on('rotateEnd', show)\n this.hooks.on('scaleStart', hide)\n this.hooks.on('scaleEnd', show)\n this.hooks.on('moveByMouseEnable', hide)\n this.hooks.on('moveByMouseDisable', show)\n this.hooks.on('updateOtherHelpers', (params) => {\n this.helperObject3D.update(params.camera)\n this.render()\n })\n this.cameraHooks.on('cameraUpdate', updateHelperByCamera)\n\n this.disposers.push(() => {\n this.domEvents.removeEventListener(this.helperObject3D, 'mousedown', this.dragStart)\n document.removeEventListener('mousemove', this.dragging)\n document.removeEventListener('mouseup', this.dragEnd)\n\n this.domEvents.removeEventListener(this.helperObject3D, 'touchstart', this.dragStart)\n document.removeEventListener('touchmove', this.dragging)\n document.removeEventListener('touchend', this.dragEnd)\n\n this.hooks.off('rotateStart', hide)\n this.hooks.off('rotateEnd', show)\n this.hooks.off('scaleStart', hide)\n this.hooks.off('scaleEnd', show)\n this.hooks.off('moveByMouseEnable', hide)\n this.hooks.off('moveByMouseDisable', show)\n this.hooks.off('updateOtherHelpers')\n this.cameraHooks.off('cameraUpdate', updateHelperByCamera)\n })\n\n if (this.moveByMouseEnable) this.moveByMouse()\n }\n\n public dispose(): void {\n super.dispose()\n this.disposers?.forEach((d) => d?.())\n }\n\n /**\n * @description: 跟随鼠标移动\n * @param {boolean} params.useFaceNormal 是否使用面的法线,默认为false\n * @param {boolean} params.useFaceNormal.enable 是否使用面的法线,默认为true\n * @param {Vector3} params.useFaceNormal.alignmentVector 期望对齐的方向,默认为Y轴对齐Face的法向向量,即 `{ x: 0, y: 1, z: 0 }`\n * @param {Function} params.useFaceNormal.fixedFaceNormal 修正后的face normal\n */\n public moveByMouse(params?: { useFaceNormal: UseFaceNormalInterface }) {\n this._moveByMouse = { enabled: true, useFaceNormal: params?.useFaceNormal }\n this.preventTapDefaultEvent = true\n\n const mousedownListener = this.handleMouseDown.bind(this)\n const mouseupListener = this.handleMouseUp.bind(this)\n this.hooks.emit('moveByMouseEnable')\n setTimeout(() => {\n this.container.addEventListener('mousedown', mousedownListener)\n this.container.addEventListener('mouseup', mouseupListener)\n })\n\n this.mousedownEventListenerDisposer = () => {\n this.container.removeEventListener('mousedown', mousedownListener)\n this.container.removeEventListener('mouseup', mouseupListener)\n }\n }\n\n /**\n * @description: 禁用跟随鼠标移动\n */\n public disableMoveByMouse() {\n this._moveByMouse = { enabled: false }\n this.preventTapDefaultEvent = false\n\n this.hooks.emit('moveByMouseDisable')\n this.mousedownEventListenerDisposer?.()\n }\n\n public onIntersectionOnModelUpdate(intersection: THREE.Intersection) {\n if (!this.moveByMouseEnable) return\n const { point, face } = intersection\n const canceled = this.hooks.emit('wantToMove', point)\n if (canceled) return\n this.originObject3D.position.copy(point)\n if (\n this._moveByMouse.useFaceNormal === true ||\n (typeof this._moveByMouse.useFaceNormal === 'object' && this._moveByMouse.useFaceNormal.enable !== false)\n ) {\n if (face?.normal) {\n const alignment = (() => {\n if (typeof this._moveByMouse.useFaceNormal === 'object' && this._moveByMouse.useFaceNormal.alignmentVector) {\n return this._moveByMouse.useFaceNormal.alignmentVector\n }\n return { x: 0, y: 1, z: 0 }\n })()\n const alignmentVector3 = new THREE.Vector3(alignment.x ?? 0, alignment.y ?? 0, alignment.z ?? 0)\n\n const faceNormal = (() => {\n if (typeof this._moveByMouse.useFaceNormal === 'object' && this._moveByMouse.useFaceNormal.fixedFaceNormal) {\n return this._moveByMouse.useFaceNormal.fixedFaceNormal(face.normal)\n }\n return face.normal\n })()\n\n this.originObject3D.quaternion.setFromUnitVectors(alignmentVector3, faceNormal)\n this.internalHooks.emit('setObjectRotate', this.originObject3D.quaternion.clone())\n }\n }\n this.internalHooks.emit('setObjectPosition', point)\n this.hooks.emit('move', point)\n }\n\n private handleMouseDown(event: MouseEvent) {\n const { x, y } = event\n this.mouseInfo = { x, y, mouseDownTimestamp: Date.now() }\n }\n\n private handleMouseUp(event: MouseEvent) {\n if (!this.mouseInfo) return\n const { x, y } = event\n if (this.mouseInfo.x === x && this.mouseInfo.y === y && Date.now() - this.mouseInfo.mouseDownTimestamp < 500) {\n this.disableMoveByMouse()\n this.mouseInfo = undefined\n }\n }\n\n /**\n * @description: 拖动开始,找出拖的Direction\n */\n private dragStart = (params: { intersect: THREE.Intersection }) => {\n if (this.moveByMouseEnable) return\n if (this.isDragging) return\n\n const intersect = params?.intersect\n\n if (!intersect) return this.dragEnd()\n\n const draggingDirection = (intersect?.object as any).direction as Direction\n\n if (!draggingDirection) return this.dragEnd()\n\n const directionX = new THREE.Vector3(1, 0, 0).applyQuaternion(this.helperObject3D.quaternion)\n const directionY = new THREE.Vector3(0, 1, 0).applyQuaternion(this.helperObject3D.quaternion)\n const directionZ = new THREE.Vector3(0, 0, 1).applyQuaternion(this.helperObject3D.quaternion)\n\n const directionVector = (() => {\n switch (draggingDirection) {\n case 'x':\n return directionX\n case 'y':\n return directionY\n case 'z':\n return directionZ\n case 'plane':\n return undefined\n }\n })()\n\n const startIntersect = intersect.point.clone()\n\n if (draggingDirection === 'plane') {\n // 平面拖拽:过点击位置,垂直于相机到该点的视线\n const cameraPosition = this.camera.position.clone()\n const clickPoint = startIntersect.clone()\n\n // 计算从相机到点击点的方向向量作为平面法向量\n const viewDirection = clickPoint.clone().sub(cameraPosition).normalize()\n\n // 创建过点击位置且垂直于视线的平面\n const plane = new THREE.Plane().setFromNormalAndCoplanarPoint(viewDirection, clickPoint)\n\n // 直接使用点击位置作为起始点(已经在平面上)\n const startProject = clickPoint.clone()\n\n this.startInfo = {\n draggingDirection,\n startVectorProject: startProject,\n line: new THREE.Line3(startProject.clone(), startProject.clone()),\n // 保存固定的平面,拖拽过程中不变\n plane: plane,\n } as any\n // 平面拖拽时不显示直线\n } else {\n /** 拖动的轴的线 */\n const line = new THREE.Line3(\n startIntersect.clone().sub(directionVector.normalize()),\n startIntersect.clone().add(directionVector.normalize()),\n )\n this.startInfo = { draggingDirection, startVectorProject: startIntersect, line }\n // 显示拖拽方向的无限长直线参考线(像素恒定、与缩放控制一致)\n try {\n const dirNormalized = directionVector.clone().normalize()\n const center = this.helperObject3D.getWorldPosition(new THREE.Vector3())\n\n // 使用 SolidGuideLine 创建直线(提高 renderOrder,保证在包围盒半透明面之上渲染)\n const line = this.solidGuide.createSolidLine(center, dirNormalized, { color: 0xffffff, renderOrder: RENDER_ORDER.DRAG_GUIDE_LINE })\n this.scene.add(line)\n this.dragGuideLine = line\n } catch {}\n }\n\n // 隐藏其他箭头,拖拽 centerHandle 时也隐藏它\n const directionsToShow = draggingDirection === 'plane' ? [] : [draggingDirection]\n this.helperObject3D.showDraggingHelper(directionsToShow)\n this.hooks.emit('moveStart', draggingDirection)\n this.isDragging = true\n // console.info('%c MoveController dragStart', 'color: #e5af2e')\n }\n\n private dragging = (point: { x: number; y: number } | TouchEvent): false | void => {\n if (!this.isDragging) return\n if (!this.startInfo) return\n\n const x = 'touches' in point ? point.touches[0].clientX : point.x\n const y = 'touches' in point ? point.touches[0].clientY : point.y\n\n const ray = getMouseRaycaster(this.camera, { x, y }, this.container)\n if (!ray) return this.dragEnd()\n\n // console.info(`%c MoveController dragging`, 'color: #49de1b')\n this.move(ray)\n\n return false\n }\n\n /**\n * 更新直线缩放,保持视觉上的恒定大小(与 ScaleController 保持一致)\n */\n private updateDragGuideLineScale() {\n if (!this.dragGuideLine || !this.startInfo) return\n const { line } = this.startInfo\n // 从 line 导出方向\n const dirNormalized = line.end.clone().sub(line.start).normalize()\n if (dirNormalized.lengthSq() < 1e-6) return\n const center = this.helperObject3D.getWorldPosition(new THREE.Vector3())\n this.solidGuide.updateSolidLine(this.dragGuideLine, center, dirNormalized)\n }\n\n private move(raycaster: THREE.Raycaster) {\n if (!this.startInfo) return this.dragEnd()\n\n const { line, startVectorProject } = this.startInfo\n const object = this.originObject3D\n\n // 判断是否为平面拖拽:当 line 两端相同,表示 plane 模式占位\n const isPlane = this.startInfo.draggingDirection === 'plane'\n let currentVectorProject: THREE.Vector3\n\n if (isPlane) {\n // 使用固定的平面(在dragStart时确定,拖拽过程中不变)\n const plane = (this.startInfo as any).plane as THREE.Plane\n if (!plane) return\n\n const projected = new THREE.Vector3()\n // 使用射线和平面的交点,three@0.1xx 没有 intersectRay 则手动求解 t\n const denom = plane.normal.dot(raycaster.ray.direction)\n if (Math.abs(denom) < 1e-6) return\n const t = -(plane.normal.dot(raycaster.ray.origin) + plane.constant) / denom\n if (t < 0) return\n projected.copy(raycaster.ray.origin.clone().add(raycaster.ray.direction.clone().multiplyScalar(t)))\n\n currentVectorProject = projected\n } else {\n currentVectorProject = rayOnLine({ raycaster, line, clampToLine: false })\n }\n\n const beforePosition = object.position.clone()\n const offsetVector = currentVectorProject.clone().sub(startVectorProject)\n\n // 移动transform\n const transform = new THREE.Matrix4()\n transform.setPosition(offsetVector)\n\n const newPosition = object.position.clone().applyMatrix4(transform)\n const canceled = this.hooks.emit('wantToMove', newPosition)\n if (canceled) return\n\n const finalPosition = this.hooks.emitWithResult('moveBefore', newPosition) ?? newPosition\n const finalTransform = new THREE.Matrix4()\n finalTransform.setPosition(finalPosition.clone().sub(beforePosition))\n\n object.position.copy(finalPosition)\n\n startVectorProject.copy(currentVectorProject)\n this.internalHooks.emit('applyObjectPosition', { matrix: finalTransform })\n this.hooks.emit('move', finalPosition)\n }\n\n private dragEnd = () => {\n if (!this.isDragging) return\n // console.info('%c MoveController dragEnd', 'color: #e94e4e')\n // 拖动结束,重置currentDraggingDirection\n this.startInfo = undefined\n this.isDragging = false\n // 移除直线\n if (this.dragGuideLine) {\n this.scene.remove(this.dragGuideLine)\n this.dragGuideLine.geometry.dispose()\n const material = this.dragGuideLine.material\n if (Array.isArray(material)) material.forEach((m) => m.dispose())\n else material.dispose()\n this.dragGuideLine = undefined\n }\n // 显示所有箭头\n this.helperObject3D.show()\n this.hooks.emit('moveEnd')\n return\n }\n}\n","import type * as THREE from 'three/webgpu'\n/**\n * @description: 将手势操作绑定到controller上\n */\nimport type { Five, EventCallback } from '@realsee/five-webgpu'\nimport type { BaseController } from '../shared-utils/Object3DHelper/Base/BaseController'\nimport type { Subscribe } from '../shared-utils/Subscribe'\nimport type DomEvents from '../shared-utils/threex/domevents'\n\nclass ControllerWrapper<HelperControllerInterface extends new (...params: ConstructorParameters<typeof BaseController<any>>) => any> {\n public helperController?: InstanceType<HelperControllerInterface>\n private five: Five\n\n\n public constructor(\n five: Five,\n donEvents: DomEvents,\n HelperController: HelperControllerInterface,\n object: THREE.Object3D,\n helperObject3D: InstanceType<HelperControllerInterface>['helperObject3D'],\n HelperControllerConfig?: ConstructorParameters<HelperControllerInterface>[1],\n hooks?: Subscribe<any>,\n internalHooks?: Subscribe<any>,\n otherControllers?: {\n moveController?: BaseController\n rotateController?: BaseController\n scaleController?: BaseController\n },\n ) {\n const { camera, model, scene } = five\n const container = five.getElement()\n this.five = five\n if (!camera || !model || !container || !scene) return\n const onRender = () => {\n five.needsRender = true\n }\n // TODO: 是否要改为绑定\n this.helperController = new HelperController(\n {\n camera,\n model,\n domEvents: donEvents,\n originObject3D: object,\n helperObject3D,\n container,\n scene,\n onRender,\n sharedHooks: hooks as any,\n sharedInternalHooks: internalHooks as any,\n otherControllers,\n },\n HelperControllerConfig,\n )\n five.on('wantsTapGesture', this.onFiveWantsTapGesture)\n five.on('wantsGesture', this.onFiveWantsGesture)\n five.on('intersectionOnModelUpdate', this.onFiveIntersectionOnModelUpdate)\n }\n\n public dispose() {\n this.five.off('wantsTapGesture', this.onFiveWantsTapGesture)\n this.five.off('wantsGesture', this.onFiveWantsGesture)\n this.five.off('intersectionOnModelUpdate', this.onFiveIntersectionOnModelUpdate)\n this.helperController?.dispose()\n }\n\n private onFiveWantsTapGesture: EventCallback['wantsTapGesture'] = (params) => {\n if (!this.helperController) return\n if (this.helperController.preventTapDefaultEvent) return false\n const result = this.helperController.onWantsTapGesture(params)\n this.five.needsRender = true\n return result\n }\n\n private onFiveWantsGesture: EventCallback['wantsGesture'] = (...params) => {\n if (!this.helperController) return\n const result = this.helperController.onWantsGesture(...params)\n this.five.needsRender = true\n return result\n }\n\n private onFiveIntersectionOnModelUpdate: EventCallback['intersectionOnModelUpdate'] = (...params) => {\n if (!this.helperController) return\n this.helperController.onIntersectionOnModelUpdate(...params)\n }\n}\n\nexport { ControllerWrapper }\nexport { ControllerWrapper as FiveControllerWrapper }\n","import type { Object3DHelperEventMap, Object3DHelperState } from './typings'\nimport type { ObjectHelperControllers } from './typings'\nimport type { BaseController } from './Base/BaseController'\nimport { Subscribe } from '../Subscribe'\n\nconst VERSION = 'v1.0.1'\n\nconst NAME = 'Object3DHelper'\n\nconst NAMEVERSION = `${NAME}@${VERSION}`\n\nconst disposedErrorLog = () => {\n console.error(`${NAMEVERSION} is disposed`)\n}\n\nconst disableWarnLog = () => {\n console.warn(`${NAMEVERSION} is disabled`)\n}\n\nconst disableErrorLog = () => {\n console.error(`${NAMEVERSION} is disabled`)\n}\n\ntype EventListener = {\n [K in keyof ObjectHelperControllers]?: () => void\n}\n\nexport class Object3DHelper {\n public controllers: ObjectHelperControllers = {}\n public state: Object3DHelperState = {\n visible: true,\n enabled: true,\n disposed: false,\n }\n public hooks: Subscribe<Object3DHelperEventMap> = new Subscribe<Object3DHelperEventMap>()\n private eventListener: EventListener = {}\n\n public constructor(controllers?: ObjectHelperControllers) {\n if (controllers) this.addControllers(controllers)\n this.setState(this.state)\n }\n\n /**\n * @description Show guide line\n */\n public async show(options?: { userAction?: boolean }) {\n this.setState({ visible: true }, options)\n }\n\n /**\n * @description Hide guide line\n */\n public async hide(options?: { userAction?: boolean }) {\n this.setState({ visible: false }, options)\n }\n\n /**\n * @description Enable\n */\n public enable(options?: { userAction?: boolean }) {\n this.setState({ enabled: true }, options)\n }\n\n /**\n * @description Disable\n */\n public disable(options?: { userAction?: boolean }) {\n this.setState({ enabled: false }, options)\n }\n\n /**\n * @description Dispose\n */\n public dispose() {\n this.setState({ disposed: true })\n }\n\n public setState(state: Partial<Object3DHelperState>, options?: { userAction?: boolean } & Record<string, any>): void {\n if (this.state.disposed) return disposedErrorLog()\n if (!this.state.enabled) {\n // when plugin is disabled, only can change enabled or disposed to true\n if (state.enabled !== true && state.disposed !== true) return disableErrorLog()\n }\n const prevState = { ...this.state }\n this.state = { ...this.state, ...state }\n if (state.disposed !== undefined && state.disposed !== prevState.disposed) {\n if (state.disposed) this.handleDispose()\n }\n if (state.visible !== undefined) {\n this.handleVisible(state.visible)\n }\n if (state.enabled !== undefined) {\n this.handleEnable(state.enabled)\n }\n\n this.hooks.emit('stateChange', { state: this.state, prevState })\n }\n\n public addControllers(controllers: ObjectHelperControllers): void {\n this.controllers = { ...this.controllers, ...controllers }\n // this.addEventListener()\n this.setState(this.state)\n }\n\n /**\n * @description 初始化 helpers 的位置\n */\n public initialHelperMatrix() {\n this.everyControllerDo((controller) => {\n controller.initialHelperPosition()\n controller.initialHelperQuaternion()\n })\n }\n\n public getCurrentState() {\n return this.state\n }\n\n private handleEnable(enabled: boolean, userAction = true) {\n if (enabled) {\n this.everyControllerDo((controller) => {\n controller.enable()\n // controller.setOpacity(OBJECT_OPACITY)\n })\n this.hooks.emit('enable', { userAction })\n } else {\n this.everyControllerDo((controller) => {\n controller.disable()\n })\n this.hooks.emit('disable', { userAction })\n }\n this.state.enabled = enabled\n }\n\n private handleVisible(visible: boolean, userAction = true) {\n if (visible) {\n this.everyControllerDo((controller) => {\n controller.show()\n // controller.setOpacity(OBJECT_OPACITY)\n })\n this.actionIfStateIsEnabled(() => this.hooks.emit('show', { userAction }))\n } else {\n this.everyControllerDo((controller) => {\n controller.hide()\n })\n this.actionIfStateIsEnabled(() => this.hooks.emit('hide', { userAction }))\n }\n this.state.visible = visible\n }\n\n private everyControllerDo(func: (controller: BaseController) => any) {\n Object.values(this.controllers).forEach((controller: BaseController | undefined) => {\n if (controller) func(controller)\n })\n }\n\n private handleDispose() {\n Object.values(this.controllers).forEach((controller: BaseController | undefined) => {\n controller?.dispose()\n })\n\n for (const k in this.controllers) {\n if (!k) continue\n const key: keyof ObjectHelperControllers = k as keyof ObjectHelperControllers\n this.eventListener[key]?.()\n }\n }\n\n private actionIfStateIsEnabled<T = any>(func: () => T, options?: { warnLog?: true }) {\n if (this.state.enabled) return func()\n else {\n if (options?.warnLog) disableWarnLog()\n }\n }\n}\n","export function deg2Rad(deg: number) {\n return (deg * Math.PI) / 180\n}\n","import { BaseController } from '../Base/BaseController'\nimport type { RotateHelperAbstract } from '../Helper'\nimport * as THREE from 'three/webgpu'\nimport type { Direction } from '../typings'\nimport { getMouseRaycaster } from '../utils'\nimport setObjectQuaternion from '../utils/setObjectQuaternion'\nimport { rad2Deg } from '../../math/rad2Deg'\nimport { deg2Rad } from '../../math/deg2Rad'\n\n/**\n * @description 记录单次旋转中,旋转前后的差值\n */\nlet helperQuaternionOffset = new THREE.Quaternion()\n\nexport class RotateController<T extends RotateHelperAbstract = RotateHelperAbstract> extends BaseController<T> {\n protected name = 'RotateController'\n\n private get rotateCenter() {\n return this.helperObject3D.position.clone()\n }\n\n private startInfo?: {\n // 当前拖动的圆\n direction: Direction\n // 开始位置,旋转过程中会实时修改\n startVector: THREE.Vector3\n // plane\n plane: THREE.Plane\n helperQuaternion: THREE.Quaternion\n angle: number\n directionVector: THREE.Vector3\n rotatedVectors?: THREE.Vector3[]\n lineMeshes?: THREE.Mesh[]\n angleHelper: THREE.Object3D & {\n baseAxes: THREE.Vector3\n angleDirection: number\n offsetAngle: (angle: number) => number\n }\n startQuaternion?: THREE.Quaternion\n }\n\n private removeListener: () => any\n\n public constructor(...params: ConstructorParameters<typeof BaseController<T>>) {\n super(...params)\n\n // add hover listener\n const helper = this.helperObject3D\n this.hoverListener([helper.xCircle?.circle, helper.yCircle?.circle, helper.zCircle?.circle].filter(Boolean))\n\n const dragStart = this.dragStart.bind(this)\n const dragging = this.dragging.bind(this)\n const dragEnd = this.dragEnd.bind(this)\n const show = this.show.bind(this)\n const hide = this.hide.bind(this)\n\n const updateHelperByCamera = () => {\n this.helperObject3D.update(this.camera)\n this.render()\n }\n\n updateHelperByCamera()\n\n this.domEvents.addEventListener(this.helperObject3D, 'mousedown', dragStart)\n document.addEventListener('mousemove', dragging)\n document.addEventListener('mouseup', dragEnd)\n\n this.domEvents.addEventListener(this.helperObject3D, 'touchstart', dragStart)\n document.addEventListener('touchmove', dragging)\n document.addEventListener('touchend', dragEnd)\n\n this.hooks.on('moveStart', hide)\n this.hooks.on('moveEnd', show)\n this.hooks.on('scaleStart', hide)\n this.hooks.on('scaleEnd', show)\n this.hooks.on('moveByMouseEnable', hide)\n this.hooks.on('moveByMouseDisable', show)\n this.hooks.on('updateOtherHelpers', (params) => {\n // 排除自己,避免无限循环\n this.helperObject3D.update(params.camera)\n this.render()\n })\n this.cameraHooks.on('cameraUpdate', updateHelperByCamera)\n\n this.disposers.push(() => {\n this.domEvents.removeEventListener(this.helperObject3D, 'mousedown', dragStart)\n document.removeEventListener('mousemove', dragging)\n document.removeEventListener('mouseup', dragEnd)\n\n this.domEvents.removeEventListener(this.helperObject3D, 'touchstart', dragStart)\n document.removeEventListener('touchmove', dragging)\n document.removeEventListener('touchend', dragEnd)\n\n this.hooks.off('moveStart', hide)\n this.hooks.off('moveEnd', show)\n this.hooks.off('scaleStart', hide)\n this.hooks.off('scaleEnd', show)\n this.hooks.off('moveByMouseEnable', hide)\n this.hooks.off('moveByMouseDisable', show)\n this.hooks.off('updateOtherHelpers')\n this.cameraHooks.off('cameraUpdate', updateHelperByCamera)\n })\n }\n\n public setRotateAngle(angle: { x?: number; y?: number; z?: number }) {\n const { x = 0, y = 0, z = 0 } = angle\n const euler = new THREE.Euler(deg2Rad(x), deg2Rad(y), deg2Rad(z))\n const quaternion = new THREE.Quaternion().setFromEuler(euler)\n\n const canceled = this.hooks.emit('wantToRotate', quaternion)\n if (canceled) return\n\n const { originObject3D, rotateCenter } = this\n setObjectQuaternion(originObject3D, quaternion, rotateCenter)\n this.internalHooks.emit('setObjectRotate', quaternion, rotateCenter)\n this.hooks.emit('rotate', quaternion)\n\n this.render()\n }\n\n /**\n * @description 通过改变欧拉角中的某一个值来改变旋转,但保持其他两个轴的旋转不变\n * @param axis 要修改的轴 ('x' | 'y' | 'z')\n * @param angle 新的角度值(度)\n * @returns 新的四元数值\n */\n public getEulerAngle(axis: 'x' | 'y' | 'z', angle: number): THREE.Quaternion {\n const { originObject3D } = this\n\n // 从当前对象的四元数中提取欧拉角\n const currentEuler = new THREE.Euler().setFromQuaternion(originObject3D.quaternion)\n\n // 将弧度转换为度\n const currentAngles = {\n x: rad2Deg(currentEuler.x),\n y: rad2Deg(currentEuler.y),\n z: rad2Deg(currentEuler.z),\n }\n\n // 修改指定轴的角度,保持其他轴不变\n const newAngles = {\n x: axis === 'x' ? angle : currentAngles.x,\n y: axis === 'y' ? angle : currentAngles.y,\n z: axis === 'z' ? angle : currentAngles.z,\n }\n\n // 创建新的欧拉角\n const newEuler = new THREE.Euler(deg2Rad(newAngles.x), deg2Rad(newAngles.y), deg2Rad(newAngles.z))\n\n // 从欧拉角创建新的四元数\n const newQuaternion = new THREE.Quaternion().setFromEuler(newEuler)\n\n return newQuaternion\n }\n\n protected onApplyOriginObjectRotate(params: { quaternion: THREE.Quaternion; origin: THREE.Vector3 }) {\n if (this.isDragging) return\n super.onApplyOriginObjectRotate(params)\n }\n\n protected onApplyOriginObjectScale(params: { matrix: THREE.Matrix4; origin?: THREE.Vector3 }): void {}\n\n /**\n * @description: 拖动开始,找出拖的Direction\n */\n private dragStart(params: { intersect: THREE.Intersection }): void {\n if (this.isDragging) return\n\n // 更新helper状态\n this.helperObject3D.update(this.camera)\n\n const intersect = params?.intersect\n\n if (!intersect) return this.dragEnd()\n\n const direction = (intersect?.object as any).direction as Direction\n\n if (!direction) return this.dragEnd()\n // 检查end\n\n const startIntersect = intersect.point\n\n const angleHelper = this.getAngleHelper(direction)\n\n // init tips\n this.setTipsAngle(0)\n const tipsPosition = startIntersect.clone()\n tipsPosition.y += 0.2\n this.setTipsPosition(tipsPosition)\n // end\n\n const helperQuaternion = this.helperObject3D.quaternion.clone()\n\n // init plane: 鼠标应该投影的平面\n const directionVector = (() => {\n if (direction === 'x') return new THREE.Vector3(1, 0, 0).applyQuaternion(helperQuaternion)\n if (direction === 'y') return new THREE.Vector3(0, 1, 0).applyQuaternion(helperQuaternion)\n if (direction === 'z') return new THREE.Vector3(0, 0, 1).applyQuaternion(helperQuaternion)\n })()\n const plane = new THREE.Plane().setFromNormalAndCoplanarPoint(directionVector, startIntersect)\n\n // init startVector: 旋转中心指向鼠标位置的向量\n const projectPoint = plane.projectPoint(startIntersect.clone(), new THREE.Vector3())\n const startVector = projectPoint.clone().sub(this.rotateCenter)\n // end\n\n // 计算开始角度\n const startAngle = startVector.angleTo(angleHelper.baseAxes.clone().applyQuaternion(helperQuaternion))\n\n const processedAngle = angleHelper.offsetAngle(startAngle)\n\n this.setAngleHelperStart(direction, processedAngle)\n this.setAngleHelperLength(direction, 0)\n\n // end\n\n this.startInfo = {\n direction,\n startVector,\n directionVector,\n plane,\n angleHelper,\n angle: 0,\n helperQuaternion: helperQuaternion.clone(),\n }\n\n helperQuaternionOffset = new THREE.Quaternion()\n\n this.helperObject3D.showDraggingHelper([direction])\n this.hooks.emit('rotateStart', direction)\n this.isDragging = true\n // console.info(`%c RotateController dragStart ${direction}`, 'color: #e5af2e')\n }\n\n private getMatrix() {\n // @ts-ignore\n const matrix = this.originObject3D?.ext?.matrix\n return matrix\n }\n\n private getMatrixAngle(matrix: any, direction: Direction) {\n let matrixQuaternion: THREE.Quaternion | undefined\n if (matrix && matrix.isMatrix4) {\n matrixQuaternion = new THREE.Quaternion()\n matrix.decompose(new THREE.Vector3(), matrixQuaternion, new THREE.Vector3())\n const euler = new THREE.Euler().setFromQuaternion(matrixQuaternion)\n if (direction === 'x') return Math.round(rad2Deg(euler.z))\n if (direction === 'y') return Math.round(rad2Deg(euler.y))\n if (direction === 'z') return Math.round(rad2Deg(euler.x))\n }\n }\n\n private parseAngleByDirection(direction: Direction): number | undefined {\n // @ts-ignore\n const matrix = this.originObject3D?.ext?.matrix\n let matrixQuaternion: THREE.Quaternion | undefined\n if (matrix && matrix.isMatrix4) {\n matrixQuaternion = new THREE.Quaternion()\n matrix.decompose(new THREE.Vector3(), matrixQuaternion, new THREE.Vector3())\n const euler = new THREE.Euler().setFromQuaternion(matrixQuaternion)\n if (direction === 'x') return Math.round(rad2Deg(euler.z))\n if (direction === 'y') return Math.round(rad2Deg(euler.y))\n if (direction === 'z') return Math.round(rad2Deg(euler.x))\n }\n }\n\n private dragging(point: { x: number; y: number } | TouchEvent): false | void {\n if (!this.isDragging) return\n\n const x = 'touches' in point ? point.touches[0].clientX : point.x\n const y = 'touches' in point ? point.touches[0].clientY : point.y\n\n const ray = getMouseRaycaster(this.camera, { x, y }, this.container)\n if (!ray) return this.dragEnd()\n\n // console.info(`%c RotateController dragging ${this.startInfo?.direction}`, 'color: #49de1b')\n this.rotate(ray)\n\n return false\n }\n\n private rotate(raycaster: THREE.Raycaster) {\n if (!this.startInfo) return this.dragEnd()\n const { startVector, plane, angleHelper, direction, helperQuaternion } = this.startInfo\n const { originObject3D } = this\n const currentIntersectPoint = raycaster.ray.intersectPlane(plane, new THREE.Vector3())\n if (!currentIntersectPoint) return\n\n const rotateCenter = this.rotateCenter.clone()\n const projectPoint = plane.projectPoint(currentIntersectPoint.clone(), new THREE.Vector3())\n // 旋转中心指向鼠标位置的向量\n let currentVector = projectPoint.clone().sub(rotateCenter)\n\n // 确保向量在平面上,垂直于旋转轴\n const rotationAxis = this.startInfo.directionVector.clone().normalize()\n const projection = currentVector.clone().projectOnPlane(rotationAxis)\n currentVector = projection.normalize().multiplyScalar(currentVector.length())\n\n const quaternion = new THREE.Quaternion().setFromUnitVectors(startVector.clone().normalize(), currentVector.clone().normalize())\n const newQuaternion = originObject3D.quaternion.clone().premultiply(quaternion)\n\n // 计算当前角度\n if (startVector.angleTo(currentVector) === 0) return\n\n const canceled = this.hooks.emit('wantToRotate', newQuaternion)\n if (canceled) return\n\n /**\n * - 计算角度。\n * 先使用 applyQuaternion(objectQuaternion.clone().invert()) 的方式将 currentVector 和 startVector 还原到初始的平面(xoy/xoz/yoz)上,\n * 然后指定 order 的第一个旋转方向(即 direction)为初始平面的法向量,这样获取到的 euler[direction] 即为本次旋转的角度。\n * 还原到初始平面是为了确保 euler 的其他旋转分量为 0,这样才能保证 euler[direction] 为本次旋转的角度。\n */\n const euler = new THREE.Euler().setFromQuaternion(\n new THREE.Quaternion().setFromUnitVectors(\n startVector.clone().normalize().applyQuaternion(helperQuaternion.clone().invert()),\n currentVector.clone().normalize().applyQuaternion(helperQuaternion.clone().invert()),\n ),\n `${direction.toUpperCase()}${'XZY'.replace(direction.toUpperCase(), '')}` as THREE.EulerOrder,\n )\n const angle = euler[direction] * angleHelper.angleDirection\n this.startInfo.angle += angle\n this.setAngleHelperLength(direction, this.startInfo.angle)\n this.setTipsAngle(rad2Deg(this.startInfo.angle))\n\n if (rotateCenter) {\n const v = new THREE.Vector3().subVectors(originObject3D.position, rotateCenter).applyQuaternion(quaternion).add(rotateCenter)\n originObject3D.position.copy(v)\n }\n\n originObject3D.applyQuaternion(quaternion)\n helperQuaternionOffset.premultiply(quaternion)\n\n this.internalHooks.emit('applyObjectRotate', { quaternion, origin: rotateCenter })\n this.hooks.emit('rotate', originObject3D.quaternion)\n\n this.startInfo.startVector = currentVector\n }\n\n private dragEnd(): void {\n if (!this.isDragging) return\n // 结束的时候再旋转helper,拖动过程中,helper不旋转\n this.applyHelperQuaternion(helperQuaternionOffset, this.rotateCenter)\n\n // 删除创建的线段\n if (this.startInfo?.lineMeshes) {\n this.startInfo.lineMeshes.forEach((mesh) => {\n this.scene.remove(mesh)\n mesh.geometry.dispose()\n if (mesh.material instanceof THREE.Material) {\n mesh.material.dispose()\n }\n })\n }\n\n // console.info('%c RotateController dragEnd', 'color: #e94e4e')\n // 拖动结束,重置\n this.startInfo = undefined\n this.isDragging = false\n // 显示所有\n this.helperObject3D.show()\n\n // 更新其他helper\n this.updateOtherHelpers()\n\n this.hooks.emit('rotateEnd')\n return\n }\n\n private updateOtherHelpers(): void {\n // 通过sharedHooks获取其他controller\n // 由于所有controller共享同一个hooks实例,我们可以通过hooks来触发更新事件\n this.hooks.emit('updateOtherHelpers', { camera: this.camera })\n }\n\n private getAngleHelper(direction: Direction):\n | (THREE.Object3D & {\n baseAxes: THREE.Vector3\n angleDirection: number\n offsetAngle: (angle: number) => number\n })\n | undefined {\n switch (direction) {\n case 'x':\n return this.helperObject3D.xCircle?.angleSector as any\n case 'y':\n return this.helperObject3D.yCircle?.angleSector as any\n case 'z':\n return this.helperObject3D.zCircle?.angleSector as any\n }\n }\n\n private setAngleHelperStart(direction: Direction, start: number) {\n const angleHelper = this.getAngleHelper(direction)\n if (!angleHelper) {\n console.warn('angleHelper is undefined')\n return\n }\n if (angleHelper instanceof THREE.Mesh && angleHelper.geometry instanceof THREE.CircleGeometry) {\n const { radius, segments, thetaLength } = angleHelper.geometry.parameters\n angleHelper.geometry = new THREE.CircleGeometry(radius, segments, start, thetaLength)\n } else {\n console.warn('only support THREE.CircleGeometry')\n }\n }\n\n private setAngleHelperLength(direction: Direction, length: number) {\n const minLength = 0.001\n const thetaLength = length >= 0 ? Math.max(length, minLength) : Math.min(length, -minLength)\n const angleHelper = this.getAngleHelper(direction)\n if (angleHelper instanceof THREE.Mesh && angleHelper.geometry instanceof THREE.CircleGeometry) {\n const { radius, thetaStart } = angleHelper.geometry.parameters\n const segments = Math.ceil(Math.abs(thetaLength) * (40 / (2 * Math.PI)))\n angleHelper.geometry = new THREE.CircleGeometry(radius, segments, thetaStart, thetaLength)\n } else {\n console.warn('only support THREE.CircleGeometry')\n }\n }\n\n private setTipsAngle(angle: number) {\n const element = this.helperObject3D.angleTips?.element\n if (!element) return\n element.innerText = `${angle.toFixed(0)}°`\n }\n\n private setTipsPosition(position: THREE.Vector3) {\n const angleTips = this.helperObject3D.angleTips\n if (!angleTips) return\n const project = position.project(this.camera)\n const { x, y, z } = project\n if (z > 1) return\n const left = ((x + 1) / 2) * 100 + '%'\n const top = ((-y + 1) / 2) * 100 + '%'\n angleTips.setLeftTop(left, top)\n }\n}\n","import { BaseController } from '../Base/BaseController'\nimport type { RectangleScaleHelperAbstract } from '../Helper'\nimport * as THREE from 'three/webgpu'\nimport { getMouseRaycaster, vectorIsEqual } from '../utils'\nimport type { Direction4 } from '../typings'\nimport { Vector3 } from 'three/webgpu'\nimport type { CSS3DObjectPlus } from '../../../CSS3DRenderPlugin/utils/three/CSS3DObject'\n\ninterface StartInfo {\n startPoint: {\n position: Vector3\n direction: Direction4\n }\n dragPointInCenterBottom?: boolean | null\n dragPointInCenterLeft?: boolean | null\n plane: THREE.Plane\n}\n\nexport class RectangleScaleController<\n OriginObject3D extends THREE.Object3D,\n PointType extends THREE.Object3D | HTMLElement,\n> extends BaseController<RectangleScaleHelperAbstract<OriginObject3D, PointType>> {\n protected startInfo?: StartInfo\n\n protected name = 'RectangleScaleController'\n\n public constructor(...params: ConstructorParameters<typeof BaseController<RectangleScaleHelperAbstract<OriginObject3D, PointType>>>) {\n super(...params)\n }\n\n public enable() {\n this.helperObject3D.enable()\n super.enable()\n }\n\n public disable() {\n this.helperObject3D.disable()\n super.disable()\n }\n\n public show() {\n this.helperObject3D.show()\n super.show()\n }\n\n public hide() {\n this.helperObject3D.hide()\n super.hide()\n }\n\n protected onApplyOriginObjectPosition(params: { matrix: THREE.Matrix4 }) {\n if (this.isDragging) return\n super.onApplyOriginObjectPosition(params)\n }\n\n protected onApplyOriginObjectScale(params: { matrix: THREE.Matrix4; origin?: THREE.Vector3 }): void {\n this.helperObject3D.applyHelperScaleMatrix4(params.matrix, params.origin)\n }\n\n protected getDragPlane() {\n const plane = new THREE.Plane()\n // get normal from points\n const positions: Vector3[] = this.helperObject3D.cornerPositions\n if (positions.length === 0) return\n if (positions.length < 3) plane.setFromNormalAndCoplanarPoint(this.originObject3D.getWorldDirection(new Vector3()), positions[0]!)\n else plane.setFromCoplanarPoints(positions[0]!, positions[1]!, positions[2]!)\n\n return plane\n }\n\n protected dragStart(\n mousePoint: { x: number; y: number },\n point: {\n position: THREE.Vector3\n direction: Direction4\n },\n ) {\n this.helperObject3D.updatePoints?.()\n const plane = this.getDragPlane()\n\n if (!plane) return this.dragEnd()\n\n this.startInfo = { startPoint: { position: point.position.clone(), direction: point.direction }, plane }\n\n // this.scene.add(getPoint(point.position.clone(), 3))\n\n this.hooks.emit('scaleStart', point.direction)\n this.render()\n this.isDragging = true\n // console.info('%c RectangleScaleController dragStart', 'color: #e5af2e')\n }\n\n protected dragging(point: { x: number; y: number }): false | void {\n if (!this.isDragging) return\n\n const raycaster = getMouseRaycaster(this.camera, point, this.container)\n if (!raycaster) return this.dragEnd()\n\n this.scale(raycaster)\n // console.info('%c RectangleScaleController dragging', 'color: #49de1b')\n }\n\n protected scale(raycaster: THREE.Raycaster) {\n if (!this.startInfo) return\n const object = this.originObject3D\n const { startPoint, plane } = this.startInfo\n const cornerPositions = this.helperObject3D.cornerPositions as [Vector3, Vector3, Vector3, Vector3]\n if (cornerPositions.length < 4) return this.dragEnd()\n\n const planeIntersection = raycaster.ray.intersectPlane(plane, new Vector3())\n if (!planeIntersection) return\n if (vectorIsEqual(planeIntersection, this.camera.position)) return\n\n const planeCenter = new Vector3().addVectors(cornerPositions[0], cornerPositions[2]).divideScalar(2)\n\n const { position: startPosition, direction } = startPoint\n\n const ewVector = new Vector3().subVectors(cornerPositions[1], cornerPositions[0]) // west -> east vector\n const nsVector = new Vector3().subVectors(cornerPositions[3], cornerPositions[0]) // south -> north vector\n\n\n const getOffset = (direction: 'ew' | 'ns') => {\n const defaultVector = new Vector3(0, 0, 0)\n if (!this.startInfo) return defaultVector\n const baseVector = (direction === 'ew' ? ewVector : nsVector).clone()\n\n const startPositionProject = startPosition.clone().projectOnVector(baseVector)\n const nowPositionProject = planeIntersection.clone().projectOnVector(baseVector)\n const planeCenterProject = planeCenter.clone().projectOnVector(baseVector)\n\n // this.scene.add(getPoint(startPosition, 0))\n // this.scene.add(getPoint(planeIntersection, 0))\n\n if (nowPositionProject.equals(startPositionProject)) return defaultVector\n\n if (direction === 'ns' && typeof this.startInfo.dragPointInCenterBottom !== 'boolean') {\n const offset = new Vector3().subVectors(nowPositionProject, planeCenterProject)\n const xIsNegative = offset.x < 0 && baseVector.x >= 0\n const yIsNegative = offset.y < 0 && baseVector.y >= 0\n const zIsNegative = offset.z < 0 && baseVector.z >= 0\n this.startInfo.dragPointInCenterBottom = xIsNegative || yIsNegative || zIsNegative\n }\n if (direction === 'ew' && typeof this.startInfo.dragPointInCenterLeft !== 'boolean') {\n const offset = new Vector3().subVectors(nowPositionProject, planeCenterProject)\n const xIsNegative = offset.x < 0 && baseVector.x >= 0\n const yIsNegative = offset.y < 0 && baseVector.y >= 0\n const zIsNegative = offset.z < 0 && baseVector.z >= 0\n this.startInfo.dragPointInCenterLeft = xIsNegative || yIsNegative || zIsNegative\n }\n\n const offset = new Vector3().subVectors(nowPositionProject, startPositionProject)\n\n // TODO: 不知道为啥b端在缩放结束有问题,先临时加个限制\n const offsetLength = offset.length()\n if (offsetLength > 0.3) {\n console.warn('offset.length() > 0.3, skipped', offsetLength)\n return defaultVector\n }\n\n return offset\n }\n\n const ewOffset = getOffset('ew')\n const nsOffset = getOffset('ns')\n\n const setEWScale = () => {\n const offset = ewOffset\n this.helperObject3D.cornerPositions.forEach((position, index) => {\n if (this.startInfo?.dragPointInCenterLeft) {\n if (index === 0 || index === 3) position.add(offset) // 拖左边,只改左边点\n } else {\n if (index === 1 || index === 2) position.add(offset) // 拖右边,只改右边点\n }\n })\n }\n\n const setNSScale = () => {\n const offset = nsOffset\n this.helperObject3D.cornerPositions.forEach((position, index) => {\n if (this.startInfo?.dragPointInCenterBottom) {\n if (index === 0 || index === 1) position.add(offset) // 拖下边,只改下边点\n } else {\n if (index === 2 || index === 3) position.add(offset) // 拖上边,只改上边点\n }\n })\n }\n\n switch (direction) {\n case 'ew':\n setEWScale()\n break\n case 'ns':\n setNSScale()\n break\n case 'nesw':\n case 'nwse':\n setEWScale()\n setNSScale()\n }\n\n // this.helperObject3D.cornerPositions.forEach((position, index) => {\n // this.scene.add(getPoint(position, index))\n // })\n\n const scaleX = new Vector3().subVectors(cornerPositions[1], cornerPositions[0]).length() / ewVector.length()\n const scaleY = new Vector3().subVectors(cornerPositions[3], cornerPositions[0]).length() / nsVector.length()\n const scaleXY = new Vector3(scaleX, scaleY, 1)\n\n const scaleMatrix = new THREE.Matrix4().scale(scaleXY)\n\n // const newScale = object.scale.clone().applyMatrix4(scaleMatrix)\n // object.scale.copy(newScale) // 或者 object.scale.applyMatrix4(scaleMatrix)\n if ((object as any).isCSS3DObjectPlus && (object as any).applyScaleMatrix4) {\n ;(object as InstanceType<typeof CSS3DObjectPlus>).applyScaleMatrix4(scaleMatrix)\n } else {\n object.scale.applyMatrix4(scaleMatrix)\n }\n\n startPoint.position.copy(planeIntersection)\n\n // =================================================================================================================================================================\n // =================================================================================================================================================================\n // 移动位置\n const centerPosition = new Vector3().addVectors(cornerPositions[0], cornerPositions[2]).divideScalar(2)\n const offset = new Vector3().subVectors(centerPosition, planeCenter)\n const transformMatrix4 = new THREE.Matrix4().setPosition(offset)\n\n object.applyMatrix4(transformMatrix4)\n this.helperObject3D.css3DInstance?.css3DObject.applyMatrix4(transformMatrix4)\n this.helperObject3D.plane?.applyMatrix4(transformMatrix4)\n\n this.internalHooks.emit('applyObjectScale', { matrix: scaleMatrix })\n this.internalHooks.emit('applyObjectPosition', { matrix: transformMatrix4 })\n // 移动位置end\n\n // this.helperObject3D.cornerPositions.forEach((position, index) => {\n // this.scene.add(getPoint(position, index))\n // })\n\n this.render()\n }\n\n protected dragEnd(): void {\n if (!this.isDragging) return\n this.startInfo = undefined\n this.isDragging = false\n\n // 如果是CSS3DScaleHelper,调用其onScaleEnd方法\n if ('onScaleEnd' in this.helperObject3D && typeof this.helperObject3D.onScaleEnd === 'function') {\n this.helperObject3D.onScaleEnd()\n }\n\n this.hooks.emit('scaleEnd')\n this.render()\n // console.info('%c RectangleScaleController dragEnd', 'color: #e94e4e')\n }\n}\n","import type { CSS3DObject } from '../../three/CSS3DRenderer'\nimport { RectangleScaleController } from './RectangleScaleController'\n\nexport class CSS3DScaleController extends RectangleScaleController<CSS3DObject, HTMLElement> {\n protected name = 'CSS3DScaleController'\n\n public constructor(...params: ConstructorParameters<typeof RectangleScaleController<CSS3DObject, HTMLElement>>) {\n super(...params)\n this.addHTMLEventListener()\n }\n\n private addHTMLEventListener() {\n this.helperObject3D.points.forEach((startPoint) => {\n if (!startPoint) return\n const element = startPoint.point\n const dragStart = (event: DragEvent) => this.dragStart(event, startPoint)\n const dragging = this.dragging.bind(this)\n const dragEnd = this.dragEnd.bind(this)\n element.addEventListener('dragstart', dragStart)\n element.addEventListener('drag', dragging)\n element.addEventListener('dragend', dragEnd)\n })\n }\n}\n","import type * as THREE from 'three/webgpu'\nimport { BaseController } from '../Base/BaseController'\nimport type { BoundingBoxHelperAbstract } from '../Helper'\n\nexport class BoundingBoxController<OriginObject3D extends THREE.Object3D = THREE.Object3D> extends BaseController<\n BoundingBoxHelperAbstract<OriginObject3D>\n> {\n protected name = 'BoundingBoxController'\n public constructor(...params: ConstructorParameters<typeof BaseController<BoundingBoxHelperAbstract<OriginObject3D>>>) {\n super(...params)\n }\n}\n","import * as THREE from 'three/webgpu'\nimport { ScaleHelperAbstract, type BaseHelperConfig } from '../Base/BaseHelper'\nimport type { ScalePosition } from '../typings'\nimport { RENDER_ORDER } from '../Constants/RenderOrder'\nimport calculateScaleByCamera from '../utils/calculateScaleByCamera'\nimport { computeWorldPerPixel } from '../utils/solidGuide'\n\n// 直线连接信息\ninterface LineConnection {\n line: THREE.Line\n mesh1: THREE.Object3D & { scalePosition: ScalePosition }\n mesh2: THREE.Object3D & { scalePosition: ScalePosition }\n}\n\nexport class ScaleHelper<T extends THREE.Object3D = THREE.Object3D> extends ScaleHelperAbstract<T> {\n public name = 'ScaleHelper'\n public scaleMeshes: Array<THREE.Object3D & { scalePosition: ScalePosition }> = []\n public lineConnections: Array<LineConnection> = []\n private positions: Array<ScalePosition> | (() => Array<ScalePosition>) = []\n private container: HTMLElement | null | undefined\n private needsInitialScaling = false\n private lastCamera: THREE.PerspectiveCamera | THREE.OrthographicCamera | null = null\n private isInitializing = false\n\n public constructor(\n originObject3D: T,\n config?: { positions?: Array<ScalePosition> | (() => Array<ScalePosition>); container?: HTMLElement | null } & BaseHelperConfig,\n ) {\n super(originObject3D, config)\n\n if (config) {\n this.positions = config.positions\n this.container = config.container\n }\n\n // 禁用容器本身的raycast,只有球应该能被点击\n this.raycast = () => {}\n }\n\n public initQuaternion(): void {\n this.quaternion.copy(this.originObject3D.quaternion)\n }\n\n public initialPosition(offset?: THREE.Vector3) {\n // 防止重复初始化\n if (this.isInitializing) {\n console.warn('ScaleHelper: initialPosition called while already initializing, skipping')\n return\n }\n\n this.isInitializing = true\n\n try {\n this.position.copy(this.originObject3D.position)\n\n const positions = typeof this.positions === 'function' ? this.positions() : this.positions\n\n if (!positions) {\n this.isInitializing = false\n return\n }\n\n // 完全清理现有的球,确保没有重复\n this.clearAllSpheres()\n\n // 重新创建所需的球\n this.scaleMeshes = positions.map((scalePosition, index) => {\n const scaleMesh = generateSphere()\n scaleMesh.position.copy(scalePosition.handlePosition)\n ;(scaleMesh as any).scalePosition = scalePosition\n\n // 为子Mesh也设置scalePosition属性,确保raycaster击中子元素时也能访问到\n scaleMesh.children.forEach((child) => {\n ;(child as any).scalePosition = scalePosition\n })\n\n this.add(scaleMesh)\n return scaleMesh as unknown as typeof scaleMesh & { scalePosition: ScalePosition }\n })\n\n // 创建球之间的直线连接\n this.createLineConnections()\n\n // 标记需要初始缩放\n this.needsInitialScaling = true\n\n // 如果已经有相机信息,立即应用缩放(包括球和直线)\n if (this.lastCamera) {\n this.applySphereScaling(this.lastCamera)\n this.applyLineScaling(this.lastCamera)\n this.needsInitialScaling = false\n }\n } finally {\n this.isInitializing = false\n }\n }\n\n /**\n * 清理所有缩放球\n */\n private clearAllSpheres() {\n // 从场景中移除所有缩放球\n this.scaleMeshes.forEach((mesh) => {\n this.remove(mesh)\n })\n\n // 清空数组\n this.scaleMeshes = []\n\n // 额外保险:移除所有名为 'ScaleHelperSphere' 的子对象\n const spheresToRemove = this.children.filter((child) => child.name === 'ScaleHelperSphere')\n if (spheresToRemove.length > 0) {\n spheresToRemove.forEach((sphere) => {\n this.remove(sphere)\n })\n }\n }\n\n /**\n * 创建中心对称球之间的直线连接\n */\n private createLineConnections() {\n // 清除现有的直线\n this.lineConnections.forEach((connection) => {\n this.remove(connection.line)\n })\n this.lineConnections = []\n\n // 定义对立方向的映射关系\n const oppositeDirections: Record<string, string> = {\n top: 'bottom',\n bottom: 'top',\n left: 'right',\n right: 'left',\n front: 'back',\n back: 'front',\n }\n\n // 创建已处理的方向集合,避免重复创建连线\n const processedDirections = new Set<string>()\n\n // 只为中心对称的球对创建直线\n for (const mesh1 of this.scaleMeshes) {\n const mesh1Id = mesh1.scalePosition.id\n if (!mesh1Id || processedDirections.has(mesh1Id)) continue\n\n const oppositeId = oppositeDirections[mesh1Id]\n if (!oppositeId) continue\n\n // 查找对应的对称球\n const mesh2 = this.scaleMeshes.find((mesh) => mesh.scalePosition.id === oppositeId)\n if (!mesh2) continue\n\n // 创建直线,连接两个对称球的中心\n const line = generateDashedLine(mesh1.position.clone(), mesh2.position.clone())\n\n // 添加到场景\n this.add(line)\n\n // 保存连接信息\n this.lineConnections.push({\n line,\n mesh1,\n mesh2,\n })\n\n // 标记这两个方向已处理,避免重复创建\n processedDirections.add(mesh1Id)\n processedDirections.add(oppositeId)\n }\n }\n\n /**\n * 拖拽过程中,把已有把手挪到 `positions()` 算出的最新位置,不重建 `scaleMeshes`。\n */\n public updateHandlePositions() {\n const positions = typeof this.positions === 'function' ? this.positions() : this.positions\n if (!positions) return\n\n positions.forEach((scalePosition) => {\n const mesh = this.scaleMeshes.find((it) => it.scalePosition.id === scalePosition.id)\n if (!mesh) return\n mesh.position.copy(scalePosition.handlePosition)\n mesh.scalePosition = scalePosition\n })\n\n this.updateLineConnections()\n if (this.lastCamera) this.applySphereScaling(this.lastCamera)\n }\n\n public update(camera: THREE.Camera) {\n const isOrthographic = camera.type === 'OrthographicCamera'\n\n // 获取相机位置\n const cameraPosition = camera.position.clone()\n\n // 获取当前操作对象的中心位置\n const objectCenter = this.originObject3D.getWorldPosition(new THREE.Vector3())\n\n // 计算从对象中心到相机的方向向量\n const toCameraDirection = cameraPosition.sub(objectCenter).normalize()\n\n // 获取对象的6个方向(前后左右上下)\n const objectDirections = {\n front: new THREE.Vector3(0, 0, 1).applyQuaternion(this.originObject3D.getWorldQuaternion(new THREE.Quaternion())),\n back: new THREE.Vector3(0, 0, -1).applyQuaternion(this.originObject3D.getWorldQuaternion(new THREE.Quaternion())),\n left: new THREE.Vector3(-1, 0, 0).applyQuaternion(this.originObject3D.getWorldQuaternion(new THREE.Quaternion())),\n right: new THREE.Vector3(1, 0, 0).applyQuaternion(this.originObject3D.getWorldQuaternion(new THREE.Quaternion())),\n top: new THREE.Vector3(0, 1, 0).applyQuaternion(this.originObject3D.getWorldQuaternion(new THREE.Quaternion())),\n bottom: new THREE.Vector3(0, -1, 0).applyQuaternion(this.originObject3D.getWorldQuaternion(new THREE.Quaternion())),\n }\n\n // 计算每个方向与相机方向的点积,找出最接近的方向\n let maxDot = -1\n let facingDirection = ''\n\n Object.entries(objectDirections).forEach(([direction, dirVector]) => {\n const dot = toCameraDirection.dot(dirVector)\n if (dot > maxDot) {\n maxDot = dot\n facingDirection = direction\n }\n })\n\n // 定义对立面的映射关系\n const oppositeDirections = {\n top: 'bottom',\n bottom: 'top',\n left: 'right',\n right: 'left',\n front: 'back',\n back: 'front',\n }\n\n // 隐藏朝向相机的方向及其对立面\n this.scaleMeshes.forEach((scaleMesh) => {\n if (!isOrthographic) {\n scaleMesh.visible = true\n return\n }\n const meshId = scaleMesh.scalePosition.id\n const oppositeId = oppositeDirections[facingDirection as keyof typeof oppositeDirections]\n\n if (meshId === facingDirection || meshId === oppositeId) {\n scaleMesh.visible = false\n } else {\n scaleMesh.visible = true\n }\n })\n\n // 更新直线位置和可见性\n this.updateLineConnections()\n\n // 如果有相机信息,确保球和直线缩放都正确\n if (this.lastCamera) {\n this.applySphereScaling(this.lastCamera)\n this.applyLineScaling(this.lastCamera)\n }\n }\n\n /**\n * 应用球的缩放逻辑\n */\n private applySphereScaling(camera: THREE.PerspectiveCamera | THREE.OrthographicCamera) {\n // 强制更新世界矩阵,确保使用最新的变换\n this.updateMatrixWorld(true)\n\n this.scaleMeshes.forEach((scaleMesh) => {\n scaleMesh.scale.setScalar(\n calculateScaleByCamera(camera, scaleMesh.scalePosition.handlePosition.clone().applyMatrix4(this.matrixWorld)),\n )\n })\n }\n\n /**\n * 应用直线缩放逻辑(直线不需要特殊的缩放处理)\n */\n private applyLineScaling(camera: THREE.PerspectiveCamera | THREE.OrthographicCamera) {\n // 直线材质不需要像虚线那样的特殊缩放处理\n // 保留此方法以维持接口一致性,但无需执行任何操作\n }\n\n /**\n * 显示所有直线连接\n */\n public showLineConnections() {\n this.lineConnections.forEach((connection) => {\n // 恢复原有的可见性逻辑\n const bothMeshesVisible = connection.mesh1.visible && connection.mesh2.visible\n connection.line.visible = bothMeshesVisible\n })\n }\n\n /**\n * 隐藏所有直线连接\n */\n public hideLineConnections() {\n this.lineConnections.forEach((connection) => {\n connection.line.visible = false\n })\n }\n\n /**\n * 更新直线连接的位置和可见性\n */\n private updateLineConnections() {\n this.lineConnections.forEach((connection) => {\n // 确保直线没有应用任何缩放变换,保持原始大小\n connection.line.scale.set(1, 1, 1)\n connection.line.position.set(0, 0, 0)\n connection.line.rotation.set(0, 0, 0)\n\n // 更新直线位置\n const geometry = connection.line.geometry as THREE.BufferGeometry\n const positions = geometry.attributes.position as THREE.BufferAttribute\n\n // 更新起点和终点位置\n positions.setXYZ(0, connection.mesh1.position.x, connection.mesh1.position.y, connection.mesh1.position.z)\n positions.setXYZ(1, connection.mesh2.position.x, connection.mesh2.position.y, connection.mesh2.position.z)\n positions.needsUpdate = true\n\n // 控制可见性:只有当两个球都显示时才显示直线\n const bothMeshesVisible = connection.mesh1.visible && connection.mesh2.visible\n connection.line.visible = bothMeshesVisible\n })\n }\n\n public setScaleByCamera(camera: THREE.PerspectiveCamera | THREE.OrthographicCamera) {\n this.lastCamera = camera\n\n // 应用球的缩放\n this.applySphereScaling(camera)\n\n // 应用直线缩放,确保与球的缩放保持同步\n this.applyLineScaling(camera)\n\n // 如果是初始缩放,延迟一帧再次应用,确保所有变换都已完成\n if (this.needsInitialScaling) {\n requestAnimationFrame(() => {\n this.applySphereScaling(camera)\n this.applyLineScaling(camera)\n })\n }\n\n // 重置初始缩放标志\n this.needsInitialScaling = false\n }\n}\n\nfunction generateSphere() {\n const radius = 0.03\n const geometry = new THREE.SphereGeometry(radius, 16, 16)\n\n const frontMaterial = new THREE.MeshBasicMaterial({\n color: 0xffff00,\n side: THREE.DoubleSide,\n transparent: true,\n opacity: 1,\n depthTest: false,\n depthWrite: false,\n })\n\n const frontMesh = new THREE.Mesh(geometry, frontMaterial)\n frontMesh.name = 'ScaleHelperSphere'\n frontMesh.renderOrder = RENDER_ORDER.SCALE_HELPER_SPHERE // 缩放Helper优先级中等\n\n // 创建一个透明的 group,半径为黄球的2倍\n const groupRadius = radius * 4\n const groupGeometry = new THREE.SphereGeometry(groupRadius, 16, 16)\n const transparentMaterial = new THREE.MeshBasicMaterial({\n transparent: true,\n opacity: 0, // 完全透明\n side: THREE.DoubleSide,\n depthTest: false,\n depthWrite: false,\n })\n\n const transparentSphere = new THREE.Mesh(groupGeometry, transparentMaterial)\n transparentSphere.name = 'ScaleHelperTransparentGroup'\n transparentSphere.renderOrder = RENDER_ORDER.SCALE_HELPER_SPHERE\n\n // 将黄球添加到透明球中\n transparentSphere.add(frontMesh)\n\n return transparentSphere\n}\n\n/**\n * 生成两个点之间的黄色直线\n * @param point1 起始点\n * @param point2 结束点\n * @returns THREE.Line 直线对象\n */\nfunction generateDashedLine(point1: THREE.Vector3, point2: THREE.Vector3): THREE.Line {\n const geometry = new THREE.BufferGeometry()\n const points = [point1, point2]\n geometry.setFromPoints(points)\n\n // 创建黄色直线材质\n const material = new THREE.LineBasicMaterial({\n color: 0xffff00, // 黄色,与球的颜色一致\n opacity: 0.75,\n transparent: true,\n depthTest: false,\n depthWrite: false,\n })\n\n const line = new THREE.Line(geometry, material)\n line.name = 'ScaleHelperSolidLine'\n line.renderOrder = RENDER_ORDER.SCALE_HELPER_LINE // 确保在球的后面渲染\n line.raycast = () => {} // 禁用raycast,防止干扰拖拽操作\n\n return line\n}\n","import { BaseController } from '../Base/BaseController'\nimport type { ScaleHelperAbstract } from '../Helper'\nimport { RENDER_ORDER } from '../Constants/RenderOrder'\nimport * as THREE from 'three/webgpu'\nimport { getMouseRaycaster } from '../utils'\nimport { SolidGuideLine } from '../utils/solidGuide'\nimport { rayOnLine } from '../../../Sculpt/utils/three/rayOnLine'\nimport type { ScalePosition } from '../typings'\nimport { MoveHelper } from '../Helper/MoveHelper'\nimport { worldBoundingBox } from '../../three/boundingBox'\nimport type { RectangleWithEdgeMesh } from '../../../Sculpt/Meshes/RectangleWithEdge'\nimport getNormal from '../../three/getNormal'\n\nexport class ScaleController<T extends ScaleHelperAbstract = ScaleHelperAbstract> extends BaseController<T> {\n protected name = 'ScaleController'\n /** 拖拽时用于显示方向参考的直线(使用 Line 实现无限长穿透整个平面的直线) */\n private dragGuideLine?: THREE.Line<THREE.BufferGeometry, THREE.LineBasicMaterial>\n /** 当前拖拽时显示的面片 */\n private currentFacePatch?: THREE.Mesh\n private solidGuide = new SolidGuideLine(this.camera, this.container, this.config?.solidGuide ?? {})\n\n private startInfo?: {\n // 开始缩放时的鼠标点的位置\n scaleStartPoint: THREE.Vector3\n // 缩放辅助线\n line: THREE.Line3\n // dragging object\n draggingObject: THREE.Object3D & { scalePosition: ScalePosition }\n }\n\n public constructor(...params: ConstructorParameters<typeof BaseController<T>>) {\n super(...params)\n\n const show = this.show.bind(this)\n const hide = this.hide.bind(this)\n\n const updateHelperByCamera = () => {\n if ('update' in this.helperObject3D && typeof this.helperObject3D.update === 'function') {\n this.helperObject3D.update(this.camera)\n }\n // 如果正在拖拽,更新直线缩放\n if (this.isDragging) {\n this.updateDragGuideLineScale()\n }\n this.render()\n }\n\n updateHelperByCamera()\n\n // mouse\n this.domEvents.addEventListener(this.helperObject3D, 'mousedown', this.dragStart)\n document.addEventListener('mousemove', this.dragging)\n document.addEventListener('mouseup', this.dragEnd)\n // touch\n this.domEvents.addEventListener(this.helperObject3D, 'touchstart', this.dragStart)\n document.addEventListener('touchmove', this.dragging)\n document.addEventListener('touchend', this.dragEnd)\n\n this.hooks.on('rotateStart', hide)\n this.hooks.on('rotateEnd', show)\n this.hooks.on('moveStart', () => {\n hide()\n // 移除高亮面,避免拖拽 CenterHandle 时显示\n this.removeFaceMesh()\n })\n this.hooks.on('moveEnd', show)\n this.hooks.on('moveByMouseEnable', hide)\n this.hooks.on('moveByMouseDisable', show)\n this.hooks.on('updateOtherHelpers', (params) => {\n if ('update' in this.helperObject3D && typeof this.helperObject3D.update === 'function') {\n this.helperObject3D.update(params.camera)\n }\n // 如果正在拖拽,更新直线缩放\n if (this.isDragging) {\n this.updateDragGuideLineScale()\n }\n this.render()\n })\n this.cameraHooks.on('cameraUpdate', updateHelperByCamera)\n\n this.disposers.push(() => {\n this.domEvents.removeEventListener(this.helperObject3D, 'mousedown', this.dragStart)\n document.removeEventListener('mousemove', this.dragging)\n document.removeEventListener('mouseup', this.dragEnd)\n\n this.domEvents.removeEventListener(this.helperObject3D, 'touchstart', this.dragStart)\n document.removeEventListener('touchmove', this.dragging)\n document.removeEventListener('touchend', this.dragEnd)\n\n this.hooks.off('rotateStart', hide)\n this.hooks.off('rotateEnd', show)\n this.hooks.off('moveStart', hide)\n this.hooks.off('moveEnd', show)\n this.hooks.off('moveByMouseEnable', hide)\n this.hooks.off('moveByMouseDisable', show)\n this.hooks.off('updateOtherHelpers')\n this.cameraHooks.off('cameraUpdate', updateHelperByCamera)\n\n // 清理面片\n if (this.currentFacePatch) {\n this.scene.remove(this.currentFacePatch)\n this.currentFacePatch.geometry.dispose()\n const material = this.currentFacePatch.material\n if (Array.isArray(material)) material.forEach((m) => m.dispose())\n else material.dispose()\n this.currentFacePatch = undefined\n }\n })\n }\n\n public initialHelperPosition() {\n this.helperObject3D.initialPosition()\n\n // 这里是因为不能在this上声明offHoverListener属性,因为这样会导致offHoverListener第一次实例化时候被覆盖\n const _this = this as any\n if (_this.offHoverListener) _this.offHoverListener()\n _this.offHoverListener = this.hoverListener(this.helperObject3D.scaleMeshes)\n }\n\n public dragStart = (params: { intersect: THREE.Intersection }) => {\n if (this.isDragging) return\n\n this.isDragging = true\n const { intersect } = params\n const cameraPosition = this.camera.position\n // 命中对象可能是球体的子 Mesh,这里统一上移到被追踪的根 Group(即 scaleMeshes 中的对象)\n const scaleMeshUuidSet = new Set(this.helperObject3D.scaleMeshes.map((m) => m.uuid))\n let hitObject = intersect.object as THREE.Object3D & { scalePosition?: ScalePosition }\n while (hitObject.parent && !scaleMeshUuidSet.has(hitObject.uuid)) {\n hitObject = hitObject.parent as THREE.Object3D & { scalePosition?: ScalePosition }\n }\n const draggingObject = hitObject as THREE.Object3D & { scalePosition: ScalePosition }\n const dragBasePosition = draggingObject.scalePosition.basePosition.clone()\n const dragHandlePosition = draggingObject.scalePosition.handlePosition.clone()\n const dragVector = dragHandlePosition.clone().sub(dragBasePosition).clone()\n\n const line = new THREE.Line3(dragBasePosition, dragBasePosition.clone().add(dragVector.normalize().multiplyScalar(5)))\n line.applyMatrix4(this.helperObject3D.matrixWorld)\n\n const raycaster = new THREE.Raycaster(cameraPosition, intersect.point.clone().sub(cameraPosition))\n const point = rayOnLine({ raycaster, line })\n\n this.startInfo = { line, scaleStartPoint: point, draggingObject }\n\n // hide other scale helpers\n this.helperObject3D.scaleMeshes.forEach((mesh) => {\n if (mesh.uuid === draggingObject.uuid) return\n mesh.visible = false\n })\n\n // 隐藏黄色直线连接\n if ('hideLineConnections' in this.helperObject3D && typeof this.helperObject3D.hideLineConnections === 'function') {\n this.helperObject3D.hideLineConnections()\n }\n\n // 显示拖拽方向的直线参考线(经过物体中心和拉伸球中心,无限延伸穿过整个平面)\n try {\n // 确保世界矩阵是最新的\n this.originObject3D.updateMatrixWorld(true)\n this.helperObject3D.updateMatrixWorld(true)\n\n // 获取原始物体的真正几何中心(世界坐标)\n const objectCenter = this.getObjectWorldCenter()\n\n // 获取拉伸球的世界位置\n const scaleHandleWorldPos = dragHandlePosition.clone().applyMatrix4(this.helperObject3D.matrixWorld)\n // 计算从物体中心指向拉伸球中心的方向向量\n const dirNormalized = scaleHandleWorldPos.clone().sub(objectCenter).normalize()\n\n // 使用物体几何中心作为直线中心\n const center = objectCenter\n\n // 创建无限长直线(提高 renderOrder,保证在包围盒半透明面之上渲染)\n const line = this.solidGuide.createSolidLine(center, dirNormalized, { color: 0xffffff, renderOrder: RENDER_ORDER.DRAG_GUIDE_LINE })\n if (!this.isRectangleWithEdgeMesh()) this.scene.add(line)\n this.dragGuideLine = line\n this.addFaceMesh()\n } catch {}\n\n // show dragging object\n draggingObject.visible = true\n\n this.hooks.emit('scaleStart')\n }\n\n /**\n * 获取物体的真正几何中心(世界坐标)\n * 优先使用 worldCenter 属性(对于 PrismMesh 等),否则使用包围盒中心\n */\n private getObjectWorldCenter(): THREE.Vector3 {\n // 优先使用 worldCenter 属性(对于多边形棱柱等,这才是真正的几何中心)\n if ('worldCenter' in this.originObject3D && typeof (this.originObject3D as any).worldCenter === 'object') {\n return (this.originObject3D as any).worldCenter.clone()\n }\n // 回退到包围盒中心\n const worldBox = worldBoundingBox(this.originObject3D)\n return worldBox ? worldBox.getCenter(new THREE.Vector3()) : this.originObject3D.getWorldPosition(new THREE.Vector3())\n }\n\n private getMoveMeshes() {\n const meshs = []\n const list = this.helperObject3D.parent?.children?.find((it) => it.name === 'MoveHelper')?.children ?? []\n for (const item of list) {\n if (item.name === 'ArrowGroup') {\n meshs.push(...item.children)\n } else if (item.name === 'center-plane-handle') {\n meshs.push(item)\n }\n }\n return meshs\n }\n\n private addHoverFaceMesh(ray: THREE.Raycaster) {\n // 如果 MoveController 正在拖拽,不显示高亮面\n if (this.isMoveControllerDragging()) return\n this.removeFaceMesh()\n // @ts-ignore\n if (!this.originObject3D.parent?.getWorldFacesGeometry) return\n\n // @ts-ignore\n const faces = this.originObject3D.parent?.getWorldFacesGeometry()\n const scaleMeshes = this.helperObject3D.scaleMeshes\n const moveMeshes = this.getMoveMeshes()\n const intersects = ray.intersectObjects(moveMeshes, false)\n\n if (ray.intersectObjects(moveMeshes, false).length > 0) return\n\n // 1. 判断 ray 与 meshs 相交的那个 mesh\n let intersectedMesh = null\n let intersectedPoint = null\n\n // 遍历所有 mesh,使用 raycaster 检测相交\n for (const mesh of scaleMeshes) {\n // 只检测可见的 mesh\n if (!mesh.visible) continue\n // raycaster.intersectObject 返回相交信息数组\n const intersects = ray.intersectObject(mesh, false)\n if (intersects && intersects.length > 0) {\n // 取最近的交点\n intersectedMesh = mesh\n intersectedPoint = intersects[0].point.clone()\n break // 只取第一个相交的 mesh\n }\n }\n\n // 如果找到了相交的 mesh\n if (intersectedMesh && intersectedPoint && Array.isArray(faces) && faces.length > 0) {\n // 2. 在 faces 中找到距离交点最近的 face\n let closestFace = null\n let minDist = Infinity\n for (const face of faces) {\n // 兼容 face.vertices 可能不存在或格式不对\n if (!face.vertices || face.vertices.length < 3) continue\n // 计算面片几何中心\n const center = new THREE.Vector3()\n for (const v of face.vertices) {\n center.add(v)\n }\n center.divideScalar(face.vertices.length)\n // 计算交点到面片中心的距离\n const dist = intersectedPoint.distanceTo(center)\n if (dist < minDist) {\n minDist = dist\n closestFace = face\n }\n }\n // 如果找到最近的面片,则添加高亮面片\n if (closestFace) {\n this.addFacePatch(closestFace)\n }\n }\n }\n\n private addFaceMesh() {\n // 如果 MoveController 正在拖拽,不显示高亮面\n if (this.isMoveControllerDragging()) return\n const draggingObject = this.startInfo?.draggingObject\n if (!draggingObject) return\n // @ts-ignore\n if (!this.originObject3D.parent?.getWorldFacesGeometry) return\n\n // @ts-ignore\n const faces = this.originObject3D.parent?.getWorldFacesGeometry()\n\n if (faces && faces.length > 0) {\n // 选择距离draggingObject.position最近的face,face的center代表face的位置\n const draggingObjectWorldPos = draggingObject.getWorldPosition(new THREE.Vector3())\n let minDist = Infinity\n let closestFace = faces[0]\n for (const face of faces) {\n // face.center 代表face的位置\n const faceCenter = face.center\n // 有些face.center可能不是Vector3,做个兼容\n let centerVec: THREE.Vector3\n if (faceCenter instanceof THREE.Vector3) {\n centerVec = faceCenter\n } else if (Array.isArray(faceCenter) && faceCenter.length === 3) {\n centerVec = new THREE.Vector3(faceCenter[0], faceCenter[1], faceCenter[2])\n } else {\n continue\n }\n const dist = centerVec.distanceTo(draggingObjectWorldPos)\n if (dist < minDist) {\n minDist = dist\n closestFace = face\n }\n }\n // 只添加一个最近的面片\n this.addFacePatch(closestFace)\n }\n }\n\n private removeFaceMesh() {\n if (this.currentFacePatch) {\n this.scene.remove(this.currentFacePatch)\n this.currentFacePatch.geometry.dispose()\n const material = this.currentFacePatch.material\n if (Array.isArray(material)) material.forEach((m) => m.dispose())\n else material.dispose()\n this.currentFacePatch = undefined\n }\n }\n\n public dragging = (point: { x: number; y: number } | TouchEvent) => {\n const x = 'touches' in point ? point.touches[0].clientX : point.x\n const y = 'touches' in point ? point.touches[0].clientY : point.y\n const ray = getMouseRaycaster(this.camera, { x, y }, this.container)\n\n // 检查 MoveController 是否正在拖拽中\n const isMoveControllerDragging = this.isMoveControllerDragging()\n\n if (!this.isDragging && !isMoveControllerDragging && ray) {\n // hover显示白色面片\n this.addHoverFaceMesh(ray)\n return\n }\n\n if (!this.startInfo) return\n\n if (!ray) return this.dragEnd()\n\n this.scale(ray)\n // 更新直线方向,保持直线始终经过物体中心和当前拉伸球位置\n this.updateDragGuideLineDirection()\n // 更新面片位置,跟随拖拽球位置\n this.removeFaceMesh()\n this.addFaceMesh()\n return false\n }\n\n public setScale(scale: number | { x?: number; y?: number; z?: number }) {\n let x = 1\n let y = 1\n let z = 1\n if (typeof scale === 'number') {\n x = scale\n y = scale\n z = scale\n } else if (typeof scale === 'object') {\n x = scale.x ?? 1\n y = scale.y ?? 1\n z = scale.z ?? 1\n }\n const scaleVector3 = new THREE.Vector3(x, y, z)\n\n const canceled = this.hooks.emit('wantToScale', scaleVector3)\n if (canceled) return\n\n this.originObject3D.scale.copy(scaleVector3)\n this.internalHooks.emit('setObjectScale', scaleVector3)\n this.hooks.emit('scale', scaleVector3)\n this.render()\n }\n\n private isRectangleWithEdgeMesh = () => {\n return (\n this.originObject3D.name === 'RectangleWithEdgeMesh' &&\n ['topleft', 'topright', 'bottomleft', 'bottomright'].includes(this.startInfo.draggingObject.scalePosition.id)\n )\n }\n\n public scale = (raycaster: THREE.Raycaster) => {\n if (!this.startInfo) return\n const { line, scaleStartPoint, draggingObject } = this.startInfo\n const { scalePosition } = draggingObject\n\n if (this.isRectangleWithEdgeMesh()) {\n const mesh = this.originObject3D as RectangleWithEdgeMesh\n // const points = (this.originObject3D as RectangleWithEdgeMesh).position\n // 获取mesh的四个角点坐标\n const geometry = mesh.geometry as THREE.BufferGeometry\n\n // 获取顶点数组\n const posAttr = geometry.attributes.position\n if (!posAttr) return []\n\n const corners: THREE.Vector3[] = []\n const vertexCount = posAttr.count // 顶点数量\n\n // 对 PlaneGeometry 来说,顶点顺序通常是:\n // 0: 左上, 1: 右上, 2: 左下, 3: 右下\n for (let i = 0; i < vertexCount; i++) {\n const vertex = new THREE.Vector3().fromBufferAttribute(posAttr as THREE.BufferAttribute, i)\n // 将局部坐标转换为世界坐标\n mesh.updateMatrixWorld(true)\n vertex.applyMatrix4(mesh.matrixWorld)\n corners.push(vertex)\n }\n\n // 返回前四个顶点(如果是 PlaneGeometry)\n const points = corners.slice(0, 4)\n\n if (!points || points.length < 4) return\n // 计算矩形平面法线\n const normal = getNormal(points).normalize()\n // 构建矩形所在平面\n const plane = new THREE.Plane().setFromNormalAndCoplanarPoint(normal, points[0])\n\n // 检查射线与平面是否接近平行(点积接近0表示垂直,接近1表示平行)\n const rayDotNormal = Math.abs(raycaster.ray.direction.dot(normal))\n const isNearlyParallel = rayDotNormal < 0.1 // 夹角大于约84度视为接近平行\n\n let localIntersect: THREE.Vector3\n\n if (isNearlyParallel) {\n // 射线与矩形平面接近平行,改用拖拽辅助线计算(与普通缩放逻辑一致)\n const point = rayOnLine({ raycaster, line, clampToLine: false })\n // 转换到helperObject3D的坐标系下\n localIntersect = point.applyMatrix4(new THREE.Matrix4().copy(this.helperObject3D.matrixWorld.clone().invert()))\n } else {\n // 射线与平面求交\n const intersectPoint = new THREE.Vector3()\n raycaster.ray.intersectPlane(plane, intersectPoint)\n if (!intersectPoint) return\n\n // 转换到矩形局部坐标系\n const inverseMatrix = new THREE.Matrix4().copy(this.helperObject3D.matrixWorld).invert()\n localIntersect = intersectPoint.clone().applyMatrix4(inverseMatrix)\n }\n\n const localStart = scaleStartPoint.clone().applyMatrix4(new THREE.Matrix4().copy(this.helperObject3D.matrixWorld).invert())\n // 调用回调更新 rectangleMesh 的 points\n const handled = this.config?.scaleCallback?.({\n intersectPoint: localIntersect,\n scalePosition,\n offset: localIntersect.clone().sub(localStart),\n updateHandlePositions: () => this.helperObject3D.updateHandlePositions(),\n })\n\n // 同步辅助对象(拖动点位置)。回调返回 false 表示由调用方接管把手位置\n if (handled !== false) draggingObject.position.copy(localIntersect)\n this.hooks.emit('scale', new THREE.Vector3(1, 1, 1))\n return\n }\n\n const point = rayOnLine({ raycaster, line, clampToLine: false })\n // 因为这个point拿到的点是世界坐标系下的,所以需要转换到helperObject3D的坐标系下\n point.applyMatrix4(new THREE.Matrix4().copy(this.helperObject3D.matrixWorld.clone().invert()))\n\n const handled = this.config?.scaleCallback?.({\n intersectPoint: point,\n scalePosition,\n offset: point.clone().sub(scaleStartPoint),\n updateHandlePositions: () => this.helperObject3D.updateHandlePositions(),\n })\n\n // 回调返回 false 表示由调用方接管把手位置\n if (handled !== false) draggingObject.position.copy(point.clone())\n\n this.hooks.emit('scale', new THREE.Vector3(1, 1, 1))\n }\n\n public dragEnd = () => {\n if (!this.isDragging) return\n // 拖动结束,重置currentDraggingDirection\n this.startInfo = undefined\n this.isDragging = false\n\n // show other scale helpers\n this.helperObject3D.scaleMeshes.forEach((mesh) => {\n mesh.visible = true\n })\n\n // 显示黄色直线连接\n if ('showLineConnections' in this.helperObject3D && typeof this.helperObject3D.showLineConnections === 'function') {\n this.helperObject3D.showLineConnections()\n }\n\n // 移除直线\n if (this.dragGuideLine) {\n this.scene.remove(this.dragGuideLine)\n this.dragGuideLine.geometry.dispose()\n const material = this.dragGuideLine.material\n if (Array.isArray(material)) material.forEach((m) => m.dispose())\n else material.dispose()\n this.dragGuideLine = undefined\n }\n\n // 移除面片\n this.removeFaceMesh()\n\n this.internalHooks.emit('initialHelperPosition')\n this.hooks.emit('scaleEnd')\n return\n }\n\n /**\n * 更新参考线\n */\n private updateDragGuideLineDirection() {\n if (!this.dragGuideLine || !this.startInfo) return\n\n // 确保世界矩阵是最新的\n this.originObject3D.updateMatrixWorld(true)\n this.helperObject3D.updateMatrixWorld(true)\n\n const direction = this.startInfo.line.delta(new THREE.Vector3()).normalize()\n const center = this.getObjectWorldCenter()\n\n this.solidGuide.updateSolidLine(this.dragGuideLine, center, direction)\n }\n\n /**\n * 更新直线缩放,保持视觉上的恒定大小\n */\n private updateDragGuideLineScale() {\n if (!this.dragGuideLine || !this.startInfo) return\n\n // 使用拖拽手柄的世界坐标作为中心点,与创建时保持一致\n const { scalePosition } = this.startInfo.draggingObject\n const handleWorld = scalePosition.handlePosition.clone().applyMatrix4(this.helperObject3D.matrixWorld)\n const baseWorld = scalePosition.basePosition.clone().applyMatrix4(this.helperObject3D.matrixWorld)\n const center = handleWorld\n const dirNormalized = handleWorld.clone().sub(baseWorld).normalize()\n // 复用 SolidGuideLine 的直线更新逻辑\n this.solidGuide.updateSolidLine(this.dragGuideLine, center, dirNormalized)\n }\n\n /**\n * 检查 MoveController 是否正在拖拽中\n */\n private isMoveControllerDragging(): boolean {\n // 直接访问 MoveController 的拖拽状态\n return this.otherControllers?.moveController?.getIsDragging() ?? false\n }\n\n /**\n * 向场景添加一个表示 face 的面片,红色,位置与 face.center 一致,使用两个三角形拼成矩形\n */\n public addFacePatch(\n face:\n | {\n center: THREE.Vector3\n vertices?: THREE.Vector3[]\n normal?: THREE.Vector3\n }\n | {\n center: { x: number; y: number; z: number }\n vertices?: THREE.Vector3[]\n normal?: THREE.Vector3\n },\n ) {\n // 如果已经有面片,先移除旧的\n if (this.currentFacePatch) {\n this.scene.remove(this.currentFacePatch)\n this.currentFacePatch.geometry.dispose()\n const material = this.currentFacePatch.material\n if (Array.isArray(material)) material.forEach((m) => m.dispose())\n else material.dispose()\n this.currentFacePatch = undefined\n }\n\n if (!face.vertices || face.vertices.length < 3) {\n console.warn('Face has no vertices, cannot create patch')\n return\n }\n\n // 创建几何体\n const geometry = new THREE.BufferGeometry()\n\n // 根据顶点数量创建不同的几何体\n if (face.vertices.length === 4) {\n // 四边形:使用两个三角形拼成\n const vertices = new Float32Array([\n // 第一个三角形\n face.vertices[0].x,\n face.vertices[0].y,\n face.vertices[0].z,\n face.vertices[1].x,\n face.vertices[1].y,\n face.vertices[1].z,\n face.vertices[2].x,\n face.vertices[2].y,\n face.vertices[2].z,\n // 第二个三角形\n face.vertices[0].x,\n face.vertices[0].y,\n face.vertices[0].z,\n face.vertices[2].x,\n face.vertices[2].y,\n face.vertices[2].z,\n face.vertices[3].x,\n face.vertices[3].y,\n face.vertices[3].z,\n ])\n\n geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))\n geometry.setIndex([0, 1, 2, 3, 4, 5])\n } else {\n // 三角形或其他形状:直接使用顶点\n const vertices = new Float32Array(face.vertices.length * 3)\n const indices = new Uint16Array(face.vertices.length)\n\n face.vertices.forEach((vertex, index) => {\n vertices[index * 3] = vertex.x\n vertices[index * 3 + 1] = vertex.y\n vertices[index * 3 + 2] = vertex.z\n indices[index] = index\n })\n\n geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))\n geometry.setIndex(new THREE.BufferAttribute(indices, 1))\n }\n\n // 计算法线\n geometry.computeVertexNormals()\n\n const material = new THREE.MeshBasicMaterial({\n color: 0xffffff,\n side: THREE.DoubleSide,\n depthTest: false, // 禁用深度测试,避免被其他对象遮挡\n depthWrite: false, // 禁用深度写入\n transparent: true,\n opacity: 0.45,\n })\n\n const patch = new THREE.Mesh(geometry, material)\n\n // 提高渲染次序,确保在所有几何体之上显示\n patch.renderOrder = RENDER_ORDER.DRAG_FACE_PATCH\n this.scene.add(patch)\n this.currentFacePatch = patch\n this.render()\n return patch\n }\n}\n","// @ts-nocheck\n/* eslint-disable */\n// This THREEx helper makes it easy to handle the mouse events in your 3D scene\n//\n// * CHANGES NEEDED\n// * handle drag/drop\n// * notify events not object3D - like DOM\n// * so single object with property\n// * DONE bubling implement bubling/capturing\n// * DONE implement event.stopPropagation()\n// * DONE implement event.type = \"click\" and co\n// * DONE implement event.target\n//\n// # Lets get started\n//\n// First you include it in your page\n//\n// ```<script src='threex.domevent.js'>< /script>```\n//\n// # use the object oriented api\n//\n// You bind an event like this\n//\n// ```mesh.on('click', function(object3d){ ... })```\n//\n// To unbind an event, just do\n//\n// ```mesh.off('click', function(object3d){ ... })```\n//\n// As an alternative, there is another naming closer DOM events.\n// Pick the one you like, they are doing the same thing\n//\n// ```mesh.addEventListener('click', function(object3d){ ... })```\n// ```mesh.removeEventListener('click', function(object3d){ ... })```\n//\n// # Supported Events\n//\n// Always in a effort to stay close to usual pratices, the events name are the same as in DOM.\n// The semantic is the same too.\n// Currently, the available events are\n// [click, dblclick, mouseup, mousedown](http://www.quirksmode.org/dom/events/click.html),\n// [mouseover and mouse out](http://www.quirksmode.org/dom/events/mouseover.html).\n//\n// # use the standalone api\n//\n// The object-oriented api modifies THREE.Object3D class.\n// It is a global class, so it may be legitimatly considered unclean by some people.\n// If this bother you, simply do ```DomEvents.noConflict()``` and use the\n// standalone API. In fact, the object oriented API is just a thin wrapper\n// on top of the standalone API.\n//\n// First, you instanciate the object\n//\n// ```var domEvent = new THREEx.DomEvent();```\n//\n// Then you bind an event like this\n//\n// ```domEvent.bind(mesh, 'click', function(object3d){ object3d.scale.x *= 2; });```\n//\n// To unbind an event, just do\n//\n// ```domEvent.unbind(mesh, 'click', callback);```\n//\n//\n// # Code\n\n//\n\n// @ts-ignore\nimport * as THREE from 'three/webgpu'\n\n// /** @namespace */\n// var THREEx\t\t= THREEx \t\t|| {};\n\n// # Constructor\nfunction DomEvents(camera, domElement) {\n this._camera = camera || null\n this._domElement = domElement || document\n this._raycaster = new THREE.Raycaster()\n this._selected = null\n this._boundObjs = {}\n // Bind dom event for mouse and touch\n var _this = this\n\n this._$onClick = function () {\n _this._onClick.apply(_this, arguments)\n }\n this._$onDblClick = function () {\n _this._onDblClick.apply(_this, arguments)\n }\n this._$onMouseMove = function () {\n _this._onMouseMove.apply(_this, arguments)\n }\n this._$onMouseDown = function () {\n _this._onMouseDown.apply(_this, arguments)\n }\n this._$onMouseUp = function () {\n _this._onMouseUp.apply(_this, arguments)\n }\n this._$onTouchMove = function () {\n _this._onTouchMove.apply(_this, arguments)\n }\n this._$onTouchStart = function () {\n _this._onTouchStart.apply(_this, arguments)\n }\n this._$onTouchEnd = function () {\n _this._onTouchEnd.apply(_this, arguments)\n }\n this._$onContextmenu = function () {\n _this._onContextmenu.apply(_this, arguments)\n }\n this._domElement.addEventListener('click', this._$onClick, false)\n this._domElement.addEventListener('dblclick', this._$onDblClick, false)\n this._domElement.addEventListener('mousemove', this._$onMouseMove, false)\n this._domElement.addEventListener('mousedown', this._$onMouseDown, false)\n this._domElement.addEventListener('mouseup', this._$onMouseUp, false)\n this._domElement.addEventListener('touchmove', this._$onTouchMove, false)\n this._domElement.addEventListener('touchstart', this._$onTouchStart, false)\n this._domElement.addEventListener('touchend', this._$onTouchEnd, false)\n this._domElement.addEventListener('contextmenu', this._$onContextmenu, false)\n}\n\n// # Destructor\nDomEvents.prototype.destroy = function () {\n // unBind dom event for mouse and touch\n this._domElement.removeEventListener('click', this._$onClick, false)\n this._domElement.removeEventListener('dblclick', this._$onDblClick, false)\n this._domElement.removeEventListener('mousemove', this._$onMouseMove, false)\n this._domElement.removeEventListener('mousedown', this._$onMouseDown, false)\n this._domElement.removeEventListener('mouseup', this._$onMouseUp, false)\n this._domElement.removeEventListener('touchmove', this._$onTouchMove, false)\n this._domElement.removeEventListener('touchstart', this._$onTouchStart, false)\n this._domElement.removeEventListener('touchend', this._$onTouchEnd, false)\n this._domElement.removeEventListener('contextmenu', this._$onContextmenu, false)\n}\n\nDomEvents.eventNames = [\n 'click',\n 'dblclick',\n 'mouseover',\n 'mouseout',\n 'mousemove',\n 'mousedown',\n 'mouseup',\n 'contextmenu',\n 'touchstart',\n 'touchend',\n]\n\nDomEvents.prototype._getRelativeMouseXY = function (domEvent) {\n var element = domEvent.target || domEvent.srcElement\n if (element.nodeType === 3) {\n element = element.parentNode // Safari fix -- see http://www.quirksmode.org/js/events_properties.html\n }\n\n // get the real position of an element relative to the page starting point (0, 0)\n // credits go to brainjam on answering http://stackoverflow.com/questions/5755312/getting-mouse-position-relative-to-content-area-of-an-element\n var elPosition = { x: 0, y: 0 }\n var tmpElement = element\n // store padding\n var style = getComputedStyle(tmpElement, null)\n elPosition.y += parseInt(style.getPropertyValue('padding-top'), 10)\n elPosition.x += parseInt(style.getPropertyValue('padding-left'), 10)\n // add positions\n do {\n elPosition.x += tmpElement.offsetLeft\n elPosition.y += tmpElement.offsetTop\n style = getComputedStyle(tmpElement, null)\n\n elPosition.x += parseInt(style.getPropertyValue('border-left-width'), 10)\n elPosition.y += parseInt(style.getPropertyValue('border-top-width'), 10)\n } while ((tmpElement = tmpElement.offsetParent))\n\n var elDimension = {\n width: element === window ? window.innerWidth : element.offsetWidth,\n height: element === window ? window.innerHeight : element.offsetHeight,\n }\n\n return {\n x: Number((domEvent.pageX - elPosition.x) / elDimension.width) * 2 - 1,\n y: -((domEvent.pageY - elPosition.y) / elDimension.height) * 2 + 1,\n }\n}\n\n/********************************************************************************/\n/*\t\tdomevent context\t\t\t\t\t\t*/\n/********************************************************************************/\n\n// handle domevent context in object3d instance\n\nDomEvents.prototype._objectCtxInit = function (object3d) {\n object3d._3xDomEvent = {}\n}\nDomEvents.prototype._objectCtxDeinit = function (object3d) {\n delete object3d._3xDomEvent\n}\nDomEvents.prototype._objectCtxIsInit = function (object3d) {\n return object3d._3xDomEvent ? true : false\n}\nDomEvents.prototype._objectCtxGet = function (object3d) {\n return object3d._3xDomEvent\n}\n\n/********************************************************************************/\n/*\t\t\t\t\t\t\t\t\t\t*/\n/********************************************************************************/\n\n/**\n * Getter/Setter for camera\n */\nDomEvents.prototype.camera = function (value) {\n if (value) this._camera = value\n return this._camera\n}\n\nDomEvents.prototype.bind = function (object3d, eventName, callback, useCapture) {\n console.assert(DomEvents.eventNames.indexOf(eventName) !== -1, 'not available events:' + eventName)\n\n if (!this._objectCtxIsInit(object3d)) this._objectCtxInit(object3d)\n var objectCtx = this._objectCtxGet(object3d)\n if (!objectCtx[eventName + 'Handlers']) objectCtx[eventName + 'Handlers'] = []\n\n objectCtx[eventName + 'Handlers'].push({\n callback: callback,\n useCapture: useCapture,\n })\n\n // add this object in this._boundObjs\n if (this._boundObjs[eventName] === undefined) {\n this._boundObjs[eventName] = []\n }\n this._boundObjs[eventName].push(object3d)\n}\nDomEvents.prototype.addEventListener = DomEvents.prototype.bind\n\nDomEvents.prototype.unbind = function (object3d, eventName, callback, useCapture) {\n console.assert(DomEvents.eventNames.indexOf(eventName) !== -1, 'not available events:' + eventName)\n\n if (!this._objectCtxIsInit(object3d)) this._objectCtxInit(object3d)\n\n var objectCtx = this._objectCtxGet(object3d)\n if (!objectCtx[eventName + 'Handlers']) objectCtx[eventName + 'Handlers'] = []\n\n var handlers = objectCtx[eventName + 'Handlers']\n for (var i = 0; i < handlers.length; i++) {\n var handler = handlers[i]\n if (callback != handler.callback) continue\n if (useCapture != handler.useCapture) continue\n handlers.splice(i, 1)\n break\n }\n // from this object from this._boundObjs\n var index = this._boundObjs[eventName].indexOf(object3d)\n this._boundObjs[eventName].splice(index, 1)\n}\nDomEvents.prototype.removeEventListener = DomEvents.prototype.unbind\n\nDomEvents.prototype._bound = function (eventName, object3d) {\n var objectCtx = this._objectCtxGet(object3d)\n if (!objectCtx) return false\n return objectCtx[eventName + 'Handlers'] ? true : false\n}\n\n/**\n * 检查对象是否可见(包括检查父级对象的可见性)\n * @param {THREE.Object3D} object3d\n * @returns {boolean}\n */\nDomEvents.prototype._isObjectVisible = function (object3d) {\n var current = object3d\n while (current) {\n if (current.visible === false) {\n return false\n }\n current = current.parent\n }\n return true\n}\n\n/**\n * 过滤出可见的对象\n * @param {Array<THREE.Object3D>} objects\n * @returns {Array<THREE.Object3D>}\n */\nDomEvents.prototype._filterVisibleObjects = function (objects) {\n var _this = this\n return objects.filter(function (obj) {\n return _this._isObjectVisible(obj)\n })\n}\n\n/********************************************************************************/\n/*\t\tonMove\t\t\t\t\t\t\t\t*/\n/********************************************************************************/\n\n// # handle mousemove kind of events\n\nDomEvents.prototype._onMove = function (eventName, mouseX, mouseY, origDomEvent) {\n // get objects bound to this event\n var boundObjs = this._boundObjs[eventName]\n if (boundObjs === undefined || boundObjs.length === 0) return\n\n // 过滤出可见的对象\n var visibleBoundObjs = this._filterVisibleObjects(boundObjs)\n if (visibleBoundObjs.length === 0) return\n\n // compute the intersection\n var vector = new THREE.Vector2()\n\n // update the picking ray with the camera and mouse position\n vector.set(mouseX, mouseY)\n this._raycaster.setFromCamera(vector, this._camera)\n\n var intersects = this._raycaster.intersectObjects(visibleBoundObjs)\n\n // 过滤掉隐藏的相交对象(检查对象本身及其父级链条的可见性)\n var _this = this\n intersects = intersects.filter(function (intersect) {\n return _this._isObjectVisible(intersect.object)\n })\n\n // 按照渲染顺序和距离进行排序,优先选择渲染顺序高的对象\n intersects.sort(function (a, b) {\n var aRenderOrder = a.object.renderOrder || 0\n var bRenderOrder = b.object.renderOrder || 0\n\n // 如果渲染顺序不同,优先选择渲染顺序高的\n if (aRenderOrder !== bRenderOrder) {\n return bRenderOrder - aRenderOrder\n }\n\n // 如果渲染顺序相同,按距离排序(近的优先)\n return a.distance - b.distance\n })\n\n var oldSelected = this._selected\n\n if (intersects.length > 0) {\n var notifyOver\n var notifyOut\n var notifyMove\n var intersect = intersects[0]\n var newSelected = intersect.object\n this._selected = newSelected\n // if newSelected bound mousemove, notify it\n notifyMove = this._bound('mousemove', newSelected)\n\n if (oldSelected != newSelected) {\n // if newSelected bound mouseenter, notify it\n notifyOver = this._bound('mouseover', newSelected)\n // if there is a oldSelect and oldSelected bound mouseleave, notify it\n notifyOut = oldSelected && this._bound('mouseout', oldSelected)\n }\n } else {\n // if there is a oldSelect and oldSelected bound mouseleave, notify it\n notifyOut = oldSelected && this._bound('mouseout', oldSelected)\n this._selected = null\n }\n\n // notify mouseMove - done at the end with a copy of the list to allow callback to remove handlers\n notifyMove && this._notify('mousemove', newSelected, origDomEvent, intersect)\n // notify mouseEnter - done at the end with a copy of the list to allow callback to remove handlers\n notifyOver && this._notify('mouseover', newSelected, origDomEvent, intersect)\n // notify mouseLeave - done at the end with a copy of the list to allow callback to remove handlers\n notifyOut && this._notify('mouseout', oldSelected, origDomEvent, intersect)\n}\n\n/********************************************************************************/\n/*\t\tonEvent\t\t\t\t\t\t\t\t*/\n/********************************************************************************/\n\n// # handle click kind of events\n\nDomEvents.prototype._onEvent = function (eventName, mouseX, mouseY, origDomEvent) {\n // get objects bound to this event\n var boundObjs = this._boundObjs[eventName]\n if (boundObjs === undefined || boundObjs.length === 0) return\n\n // 过滤出可见的对象\n var visibleBoundObjs = this._filterVisibleObjects(boundObjs)\n if (visibleBoundObjs.length === 0) return\n\n // compute the intersection\n var vector = new THREE.Vector2()\n\n // update the picking ray with the camera and mouse position\n vector.set(mouseX, mouseY)\n this._raycaster.setFromCamera(vector, this._camera)\n\n var intersects = this._raycaster.intersectObjects(visibleBoundObjs, true)\n // 过滤掉隐藏的相交对象(检查对象本身及其父级链条的可见性)\n var _this = this\n intersects = intersects.filter(function (intersect) {\n return _this._isObjectVisible(intersect.object)\n })\n\n // 按照渲染顺序和距离进行排序,优先选择渲染顺序高的对象\n intersects.sort(function (a, b) {\n var aRenderOrder = a.object.renderOrder || 0\n var bRenderOrder = b.object.renderOrder || 0\n\n // 如果渲染顺序不同,优先选择渲染顺序高的\n if (aRenderOrder !== bRenderOrder) {\n return bRenderOrder - aRenderOrder\n }\n\n // 如果渲染顺序相同,按距离排序(近的优先)\n return a.distance - b.distance\n })\n // if there are no intersections, return now\n if (intersects.length === 0) return\n // init some variables\n var intersect = intersects[0]\n var object3d = intersect.object\n var objectCtx = this._objectCtxGet(object3d)\n var objectParent = object3d.parent\n\n while (typeof objectCtx === 'undefined' && objectParent) {\n objectCtx = this._objectCtxGet(objectParent)\n objectParent = objectParent.parent\n }\n if (!objectCtx) return\n\n // notify handlers\n this._notify(eventName, object3d, origDomEvent, intersect)\n}\n\nDomEvents.prototype._notify = function (eventName, object3d, origDomEvent, intersect) {\n var objectCtx = this._objectCtxGet(object3d)\n var handlers = objectCtx ? objectCtx[eventName + 'Handlers'] : null\n\n // do bubbling\n if (!objectCtx || !handlers || handlers.length === 0) {\n object3d.parent && this._notify(eventName, object3d.parent, origDomEvent, intersect)\n return\n }\n\n // notify all handlers\n var handlers = objectCtx[eventName + 'Handlers']\n for (var i = 0; i < handlers.length; i++) {\n var handler = handlers[i]\n var toPropagate = true\n handler.callback({\n type: eventName,\n target: object3d,\n origDomEvent: origDomEvent,\n intersect: intersect,\n stopPropagation: function () {\n toPropagate = false\n },\n })\n if (!toPropagate) continue\n // do bubbling\n if (handler.useCapture === false) {\n object3d.parent && this._notify(eventName, object3d.parent, origDomEvent, intersect)\n }\n }\n}\n\n/********************************************************************************/\n/*\t\thandle mouse events\t\t\t\t\t\t*/\n/********************************************************************************/\n// # handle mouse events\n\nDomEvents.prototype._onMouseDown = function (event) {\n return this._onMouseEvent('mousedown', event)\n}\nDomEvents.prototype._onMouseUp = function (event) {\n return this._onMouseEvent('mouseup', event)\n}\n\nDomEvents.prototype._onMouseEvent = function (eventName, domEvent) {\n var mouseCoords = this._getRelativeMouseXY(domEvent)\n this._onEvent(eventName, mouseCoords.x, mouseCoords.y, domEvent)\n}\n\nDomEvents.prototype._onMouseMove = function (domEvent) {\n var mouseCoords = this._getRelativeMouseXY(domEvent)\n this._onMove('mousemove', mouseCoords.x, mouseCoords.y, domEvent)\n this._onMove('mouseover', mouseCoords.x, mouseCoords.y, domEvent)\n this._onMove('mouseout', mouseCoords.x, mouseCoords.y, domEvent)\n}\n\nDomEvents.prototype._onClick = function (event) {\n // TODO handle touch ?\n this._onMouseEvent('click', event)\n}\nDomEvents.prototype._onDblClick = function (event) {\n // TODO handle touch ?\n this._onMouseEvent('dblclick', event)\n}\n\nDomEvents.prototype._onContextmenu = function (event) {\n // TODO don't have a clue about how this should work with touch..\n this._onMouseEvent('contextmenu', event)\n}\n\n/********************************************************************************/\n/*\t\thandle touch events\t\t\t\t\t\t*/\n/********************************************************************************/\n// # handle touch events\n\nDomEvents.prototype._onTouchStart = function (event) {\n return this._onTouchEvent('touchstart', event)\n}\nDomEvents.prototype._onTouchEnd = function (event) {\n return this._onTouchEvent('touchend', event)\n}\n\nDomEvents.prototype._onTouchMove = function (domEvent) {\n if (domEvent.touches.length != 1) return undefined\n\n // domEvent.preventDefault();\n\n var mouseX = Number(domEvent.touches[0].pageX / window.innerWidth) * 2 - 1\n var mouseY = -(domEvent.touches[0].pageY / window.innerHeight) * 2 + 1\n this._onMove('mousemove', mouseX, mouseY, domEvent)\n this._onMove('mouseover', mouseX, mouseY, domEvent)\n this._onMove('mouseout', mouseX, mouseY, domEvent)\n}\n\nDomEvents.prototype._onTouchEvent = function (eventName, domEvent) {\n // 单指 touchend 事件中,touches 为空,这里改为使用 changedTouches\n // if( domEvent.touches.length != 1 )\treturn undefined; // 这是原来的代码\n var touches = domEvent.touches\n if (touches.length == 0) {\n touches = domEvent.changedTouches\n }\n\n if (touches.length != 1) return undefined\n\n // domEvent.preventDefault();\n\n var mouseX = Number(touches[0].pageX / window.innerWidth) * 2 - 1\n var mouseY = -(touches[0].pageY / window.innerHeight) * 2 + 1\n this._onEvent(eventName, mouseX, mouseY, domEvent)\n}\n\nexport default DomEvents\n","import type * as THREE from 'three/webgpu'\nimport type { Five } from '@realsee/five-webgpu'\nimport { Controller as BasePluginController } from '../base/BasePlugin'\nimport { MoveHelper, RotateHelper, CSS3DScaleHelper, BoundingBoxHelper } from '../shared-utils/Object3DHelper/Helper'\nimport { MoveController } from '../shared-utils/Object3DHelper/Controller/MoveController'\nimport { FiveControllerWrapper } from './FiveControllerWrapper'\nimport { Object3DHelper } from '../shared-utils/Object3DHelper/index'\nimport { RotateController } from '../shared-utils/Object3DHelper/Controller/RotateController'\nimport { CSS3DScaleController } from '../shared-utils/Object3DHelper/Controller/CSS3DScaleController'\nimport type {\n Object3DHelperState,\n ObjectHelperControllers,\n PositionFrom,\n ScaleCallback,\n ScalePosition,\n} from '../shared-utils/Object3DHelper/typings'\nimport type { HelperConfig, HelperOffset, Object3DHelperPluginEventMap, Object3DHelperPluginState } from './typings'\nimport type { CSS3DObjectPlus } from '../CSS3DRenderPlugin/utils/three/CSS3DObject'\nimport { CSS3DRender } from '../CSS3DRenderPlugin/utils/three/CSS3DRender'\nimport generateBehindFiveElement from '../CSS3DRenderPlugin/utils/generateBehindFiveElement'\nimport { BoundingBoxController } from '../shared-utils/Object3DHelper/Controller/BoundingBoxController'\nimport { ScaleHelper } from '../shared-utils/Object3DHelper/Helper/ScaleHelper'\nimport { ScaleController } from '../shared-utils/Object3DHelper/Controller/ScaleController'\nimport { waitFiveModelLoaded } from '../shared-utils/five/fiveModelLoad'\nimport { Subscribe } from '../shared-utils/Subscribe'\nimport DomEvents from '../shared-utils/threex/domevents'\n\nconst PLUGIN_NAME = 'Object3DHelperPlugin'\n\nexport const PLUGIN = PLUGIN_NAME\n\nexport type AddObject3DHelperConfig = {\n /**\n * @description 辅助坐标轴的位置,基于 object local 坐标系。\n * ```markdown\n * 'boundingBox': 物体 boundingBox 的中心\n * 'boundingSphere': 物体 boundingSphere 的中心\n * `THREE.Vector3`: 指定 Vector3\n * `(object3D) => THREE.Vector3`: 指定 Vector3\n * ```\n * @default 'objectPosition'\n */\n positionFrom?: PositionFrom\n /**\n * @description 辅助坐标轴的位置偏移量\n */\n offset?: HelperOffset\n /**\n * @description 辅助坐标轴的y轴方向(绿色)\n */\n yAxis?: THREE.Vector3 | (() => THREE.Vector3)\n /**\n * @description 辅助坐标轴的x轴方向(红色)\n */\n xAxis?: THREE.Vector3 | (() => THREE.Vector3)\n /**\n * @description 辅助坐标轴的z轴方向(蓝色)\n */\n zAxis?: THREE.Vector3 | (() => THREE.Vector3)\n /**\n * @description 位移的配置\n */\n moveHelper?: HelperConfig<{\n /**\n * @description 是否开启X轴位移功能(红色)\n */\n xArrowEnable?: boolean\n /**\n * @description 是否开启Y轴位移功能(绿色)\n */\n yArrowEnable?: boolean\n /**\n * @description 是否开启Z轴位移功能(蓝色)\n */\n zArrowEnable?: boolean\n }>\n /**\n * @description 旋转的配置\n */\n rotateHelper?: HelperConfig<{\n /**\n * @description 是否开启X轴旋转功能(红色)\n */\n yzCircleEnable?: boolean\n /**\n * @description 是否开启Y轴旋转功能(绿色)\n */\n xzCircleEnable?: boolean\n /**\n * @description 是否开启Z轴旋转功能(蓝色)\n */\n xyCircleEnable?: boolean\n /**\n * @description 旋转时的角度提示\n */\n angleTipsEnable?: boolean\n }>\n /**\n * @description 缩放的配置\n */\n scaleHelper?: HelperConfig<{\n /**\n * @description 缩放 handlers 的位置\n */\n positions?: Array<ScalePosition> | (() => Array<ScalePosition>)\n /**\n * @description 缩放 handler 被拖动后的回调\n */\n scaleCallback?: ScaleCallback\n }>\n /**\n * @description 物体包围盒\n */\n boundingBoxHelper?: HelperConfig\n}\n\nconst disposedErrorLog = () => {\n console.error(`${PLUGIN} is disposed`)\n}\n\nconst disableWarnLog = () => {\n console.warn(`${PLUGIN} is disabled`)\n}\n\nconst disableErrorLog = () => {\n console.error(`${PLUGIN} is disabled`)\n}\n\nexport class Object3DHelperController extends BasePluginController<Object3DHelperPluginState, Object3DHelperPluginEventMap> {\n public name = PLUGIN_NAME\n public state: Object3DHelperState = {\n visible: true,\n enabled: true,\n disposed: false,\n }\n\n public objectHelperMap: Map<THREE.Object3D, { helper: Object3DHelper; disposers: (() => any)[] }> = new Map()\n\n private css3DObjectParentMap: Map<THREE.Object3D, THREE.Object3D | null> = new Map()\n private css3DObjectModeMap: Map<THREE.Object3D, string> = new Map()\n\n private css3DRender: CSS3DRender\n\n public constructor(five: Five) {\n super(five)\n this.five = five\n this.css3DRender = new CSS3DRender(this.five.scene)\n\n\n // debug\n // Object.assign(window, { THREE: THREE })\n }\n\n /**\n * @description Show guide line\n */\n public async show(options?: { userAction?: boolean }) {\n this.setState({ visible: true }, options)\n }\n\n /**\n * @description Hide guide line\n */\n public async hide(options?: { userAction?: boolean }) {\n this.setState({ visible: false }, options)\n }\n\n /**\n * @description Enable\n */\n public enable(options?: { userAction?: boolean }) {\n this.setState({ enabled: true }, options)\n }\n\n /**\n * @description Disable\n */\n public disable(options?: { userAction?: boolean }) {\n this.setState({ enabled: false }, options)\n }\n\n /**\n * @description Dispose\n */\n public dispose() {\n this.setState({ disposed: true })\n }\n\n public setState(state: Partial<Object3DHelperState>, options?: { userAction?: boolean } & Record<string, any>): void {\n if (this.state.disposed) return disposedErrorLog()\n if (!this.state.enabled) {\n // when plugin is disabled, only can change enabled or disposed to true\n if (state.enabled !== true && state.disposed !== true) return disableErrorLog()\n }\n const prevState = { ...this.state }\n this.state = { ...this.state, ...state }\n if (state.disposed !== undefined && state.disposed !== prevState.disposed) {\n if (state.disposed) this.handleDispose()\n }\n if (state.visible !== undefined && state.visible !== prevState.visible) {\n this.handleVisible(state.visible)\n }\n if (state.enabled !== undefined && state.enabled !== prevState.enabled) {\n this.handleEnable(state.enabled)\n }\n\n this.hooks.emit('stateChange', { state: this.state, prevState })\n }\n\n public getObject3DHelper(object3D: THREE.Object3D) {\n return this.objectHelperMap.get(object3D)\n }\n\n /**\n * @description 添加 helper\n * @param { THREE.Object3D } object3D 要添加helper的物体\n * @param { boolean } config.moveHelper 位移helper\n * @param { boolean } config.rotateHelper 旋转helper\n * @param { boolean } config.scaleHelper 缩放helper\n */\n public addObject3DHelper(object3D: THREE.Object3D, paramsConfig: AddObject3DHelperConfig = {}): ObjectHelperControllers | undefined {\n if (!object3D) {\n console.error('Object3D is undefined')\n return\n }\n\n if (this.objectHelperMap.has(object3D)) {\n console.warn(`Object3DHelperPlugin: object3D ${object3D.name} is already has helper`)\n return\n }\n const helper = new Object3DHelper()\n\n const disposers: (() => any)[] = []\n\n const container = this.five.getElement()?.parentElement\n const camera = this.five.camera\n // 创建空的helperGroup\n // merge config\n const defaultConfig: AddObject3DHelperConfig = {\n moveHelper: true,\n rotateHelper: true,\n scaleHelper: true,\n boundingBoxHelper: false,\n positionFrom: 'objectPosition',\n }\n const config = { ...defaultConfig, ...paramsConfig }\n const { moveHelper, rotateHelper, scaleHelper, boundingBoxHelper } = config\n\n const hooks = helper.hooks\n const internalHooks = new Subscribe()\n const donEvents = new DomEvents(this.five.camera, this.five.getElement())\n\n const helperEnable = (helper: HelperConfig<{}>) => {\n if (!helper) return\n if (typeof helper === 'boolean') return helper\n return helper.enable\n }\n\n // 先创建所有控制器,但不设置引用关系\n const controllers: { [key: string]: any } = {}\n\n // 筛选\n if (helperEnable(moveHelper)) {\n const c = { ...this.getConfig(config.moveHelper), ...config }\n const moveHelper = new MoveHelper(object3D, { ...c })\n const controllerWrapper = new FiveControllerWrapper(\n this.five,\n donEvents,\n MoveController,\n object3D,\n moveHelper,\n c,\n hooks,\n internalHooks,\n )\n controllers.moveController = controllerWrapper.helperController\n disposers.push(() => controllerWrapper.dispose())\n }\n\n if (helperEnable(rotateHelper)) {\n const c = { ...this.getConfig(config.rotateHelper), ...config }\n const rotateHelper = new RotateHelper(object3D, { container, ...c })\n const controllerWrapper = new FiveControllerWrapper(\n this.five,\n donEvents,\n RotateController,\n object3D,\n rotateHelper,\n c,\n hooks,\n internalHooks,\n )\n controllers.rotateController = controllerWrapper.helperController\n disposers.push(() => controllerWrapper.dispose())\n }\n\n if (helperEnable(boundingBoxHelper)) {\n const boundingBoxHelper = new BoundingBoxHelper(object3D)\n const controllerWrapper = new FiveControllerWrapper(\n this.five,\n donEvents,\n BoundingBoxController,\n object3D,\n boundingBoxHelper,\n undefined,\n hooks,\n internalHooks,\n )\n controllers.boundingBoxController = controllerWrapper.helperController\n disposers.push(() => controllerWrapper.dispose())\n }\n\n if (helperEnable(scaleHelper)) {\n if ((object3D as any).isCSS3DObject && container) {\n const css3dScaleHelper = new CSS3DScaleHelper(object3D as CSS3DObjectPlus, container, camera, this.five.scene)\n const controllerWrapper = new FiveControllerWrapper(\n this.five,\n donEvents,\n CSS3DScaleController,\n object3D,\n css3dScaleHelper,\n undefined,\n hooks,\n internalHooks,\n )\n controllers.scaleController = controllerWrapper.helperController\n disposers.push(() => controllerWrapper.dispose())\n\n waitFiveModelLoaded(this.five).then(() => {\n if ((object3D as any).isCSS3DObjectPlus) {\n const css3dObject = object3D as CSS3DObjectPlus\n if (!css3dObject) return\n if (css3dObject.mode !== 'front') return\n const wrapper = this.css3DRender.behindModeCSS3DRenderer.wrapper ?? generateBehindFiveElement(this.five)\n if (wrapper) {\n this.css3DObjectParentMap.set(css3dObject, css3dObject.parent)\n // 移除\n css3dObject.removeFromParent()\n // 添加\n this.css3DRender.behindModeCSS3DRenderer.setWrapper(wrapper)\n this.css3DRender.getBehindCSS3DObjectGroup()?.add(css3dObject)\n this.css3DRender.render(this.five.camera)\n }\n } else if ((object3D as any).isCSS3DObject) {\n this.css3DObjectModeMap.set(object3D, (object3D as any).mode)\n ;(object3D as any).mode = 'behind'\n }\n })\n } else {\n const c = { ...this.getConfig(config.scaleHelper), ...config }\n const scaleHelper = new ScaleHelper(object3D, c)\n const controllerWrapper = new FiveControllerWrapper(\n this.five,\n donEvents,\n ScaleController,\n object3D,\n scaleHelper,\n c,\n hooks,\n internalHooks,\n )\n controllers.scaleController = controllerWrapper.helperController\n disposers.push(() => controllerWrapper.dispose())\n }\n }\n\n // 所有控制器创建完成后,更新它们的引用关系\n Object.values(controllers).forEach((controller: any) => {\n if (controller && typeof controller.updateOtherControllers === 'function') {\n controller.updateOtherControllers(controllers)\n }\n })\n\n // 所有控制器创建完成后,将它们添加到 helper 中\n helper.addControllers(controllers)\n\n this.objectHelperMap.set(object3D, { helper, disposers })\n\n return helper.controllers\n }\n\n public removeObject3DHelper(object3D: THREE.Object3D) {\n if (!this.objectHelperMap.has(object3D)) return\n const { helper, disposers } = this.objectHelperMap.get(object3D)\n if (!helper) return\n if ((object3D as any).isCSS3DObjectPlus) {\n const css3DObject = object3D as CSS3DObjectPlus\n const parent = this.css3DObjectParentMap.get(css3DObject)\n if (parent) parent.add(css3DObject)\n this.css3DRender.render(this.five.camera)\n } else if ((object3D as any).isCSS3DObject) {\n const mode = this.css3DObjectModeMap.get(object3D)\n ;(object3D as any).mode = mode\n }\n this.objectHelperMap.delete(object3D)\n helper.dispose()\n disposers?.forEach((d) => d?.())\n }\n\n private handleEnable(enabled: boolean, userAction = true) {\n if (enabled) {\n this.everyHelperDo((helper) => helper.enable())\n this.hooks.emit('enable', { userAction })\n } else {\n this.everyHelperDo((helper) => helper.disable())\n this.hooks.emit('disable', { userAction })\n }\n this.state.enabled = enabled\n }\n\n private handleVisible(visible: boolean, userAction = true) {\n if (visible) {\n this.everyHelperDo((helper) => helper.show())\n this.actionIfStateIsEnabled(() => this.hooks.emit('show', { userAction }))\n } else {\n this.everyHelperDo((helper) => helper.hide())\n this.actionIfStateIsEnabled(() => this.hooks.emit('hide', { userAction }))\n }\n this.state.visible = visible\n }\n\n private handleDispose() {\n this.everyHelperDo((helper, disposers) => {\n helper.dispose()\n disposers?.forEach((d) => d?.())\n })\n }\n\n private everyHelperDo(func: (helper: Object3DHelper, disposers?: (() => any)[]) => any) {\n this.objectHelperMap.forEach(({ helper, disposers }) => {\n if (helper) func(helper, disposers)\n })\n }\n\n private actionIfStateIsEnabled<T = any>(func: () => T, options?: { warnLog?: true }) {\n if (this.state.enabled) return func()\n else {\n if (options?.warnLog) disableWarnLog()\n }\n }\n\n private getConfig<T>(config?: HelperConfig<T>): T | undefined {\n if (!config) return\n if (typeof config === 'boolean') return\n if (config.enable) return config\n }\n}\n"],"mappings":"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"}