@vincentt-xr/sdk 2.0.0-alpha.8 → 2.0.0-alpha.9

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 (517) hide show
  1. package/GROUNDING.md +4643 -170
  2. package/README.md +1 -0
  3. package/dist/CanonicalHeadFrame-BHcWyaiK.js +1506 -0
  4. package/dist/CanonicalHeadFrame-D-_T1OMU.cjs +1 -0
  5. package/dist/DebuggerUI-7ngnJsBe.js +275 -0
  6. package/dist/DebuggerUI-CoglgKdO.cjs +1 -0
  7. package/dist/FaceRetouch-CLoTfrcs.js +1071 -0
  8. package/dist/FaceRetouch-J1lC1WbS.cjs +134 -0
  9. package/dist/FaceSurface-CHAMEeG1.cjs +1 -0
  10. package/dist/FaceSurface-DmP9AEeC.js +27 -0
  11. package/dist/SegmentationOverlay-D_FWkcyP.cjs +35 -0
  12. package/dist/SegmentationOverlay-vn5x_knv.js +6237 -0
  13. package/dist/SkeletonUtils-C2r90MtN.js +21 -0
  14. package/dist/SkeletonUtils-CddIup1F.cjs +1 -0
  15. package/dist/TextLabel-XE0rQSDn.cjs +2 -0
  16. package/dist/TextLabel-c9BCucOI.js +961 -0
  17. package/dist/assets/gltfLoader.d.ts +16 -0
  18. package/dist/assets/loaders.d.ts +16 -1
  19. package/dist/body-pose/index.d.ts +521 -0
  20. package/dist/body-trigger/__fixtures__/syntheticBody.d.ts +83 -0
  21. package/dist/body-trigger/frame.d.ts +88 -0
  22. package/dist/body-trigger/index.d.ts +6 -0
  23. package/dist/body-trigger/moves.d.ts +235 -0
  24. package/dist/body-trigger/trigger.d.ts +75 -0
  25. package/dist/calibration/calibration.d.ts +11 -6
  26. package/dist/canonicalFace-BHwyCx1c.js +9 -0
  27. package/dist/canonicalFace-C83I225R.cjs +1 -0
  28. package/dist/components/BodyInstruction/BodyPoseHint.d.ts +63 -0
  29. package/dist/components/BodyInstruction/index.d.ts +69 -0
  30. package/dist/components/BodyInstruction/useBodyPose.d.ts +23 -0
  31. package/dist/components/BodyTracker/index.d.ts +10 -2
  32. package/dist/components/BodyTrigger/index.d.ts +49 -0
  33. package/dist/components/Debugger/DebuggerProvider.d.ts +14 -1
  34. package/dist/components/Debugger/DebuggerUI.d.ts +3 -1
  35. package/dist/components/FaceAtlas/FaceAtlasLayer.d.ts +114 -0
  36. package/dist/components/FaceAtlas/MadeUpCamera.d.ts +80 -0
  37. package/dist/components/FaceAtlas/constants.d.ts +8 -0
  38. package/dist/components/FaceAtlas/index.d.ts +7 -0
  39. package/dist/components/FaceAtlas/useFaceAtlasSurface.d.ts +84 -0
  40. package/dist/components/FaceAtlas/useFaceSkin.d.ts +84 -0
  41. package/dist/components/FaceCharacter/ExternalFaceMesh.d.ts +109 -0
  42. package/dist/components/FaceCharacter/FaceExpressionController.d.ts +53 -0
  43. package/dist/components/FaceCharacter/FaceMorph.d.ts +71 -0
  44. package/dist/components/FaceCharacter/FacePiercing.d.ts +65 -0
  45. package/dist/components/FaceCharacter/FaceReprojection.d.ts +85 -0
  46. package/dist/components/FaceCharacter/FaceRig.d.ts +38 -0
  47. package/dist/components/FaceCharacter/FaceSurface.d.ts +49 -0
  48. package/dist/components/FaceCharacter/FaceSurfaceOccluder.d.ts +39 -0
  49. package/dist/components/FaceCharacter/PinToFaceMesh.d.ts +68 -0
  50. package/dist/components/FaceCharacter/index.d.ts +18 -0
  51. package/dist/components/FaceCharacter/useFaceReprojector.d.ts +10 -0
  52. package/dist/components/FaceInset/FaceInset.d.ts +68 -0
  53. package/dist/components/FaceInset/frame.d.ts +94 -0
  54. package/dist/components/FaceInset/index.d.ts +6 -0
  55. package/dist/components/FaceInset/material.d.ts +40 -0
  56. package/dist/components/FaceInset/useFaceInsetTexture.d.ts +37 -0
  57. package/dist/components/FaceInstruction/FaceExpressionHint.d.ts +43 -0
  58. package/dist/components/FaceInstruction/index.d.ts +56 -0
  59. package/dist/components/FaceInstruction/useFaceExpression.d.ts +20 -0
  60. package/dist/components/FaceLiquify/FaceLiquify.d.ts +49 -0
  61. package/dist/components/FaceLiquify/debug.d.ts +37 -0
  62. package/dist/components/FaceLiquify/frame.d.ts +55 -0
  63. package/dist/components/FaceLiquify/index.d.ts +10 -0
  64. package/dist/components/FaceLiquify/material.d.ts +39 -0
  65. package/dist/components/FaceLiquify/pass.d.ts +49 -0
  66. package/dist/components/FaceLiquify/presence.d.ts +25 -0
  67. package/dist/components/FaceLiquify/presets.d.ts +82 -0
  68. package/dist/components/FaceLiquify/selfTest.d.ts +66 -0
  69. package/dist/components/FaceLiquify/target.d.ts +85 -0
  70. package/dist/components/FaceLiquify/warp.d.ts +72 -0
  71. package/dist/components/FaceMesh/canonical/CanonicalFaceMeshRenderer.d.ts +5 -3
  72. package/dist/components/FaceMesh/canonical/geometryGroups.d.ts +21 -0
  73. package/dist/components/FaceMesh/canonical/parseCanonicalFaceModel.d.ts +9 -0
  74. package/dist/components/FaceMesh/index.d.ts +1 -1
  75. package/dist/components/FaceRetouch/Background.d.ts +3 -1
  76. package/dist/components/FaceRetouch/FaceRetouch.d.ts +5 -0
  77. package/dist/components/FaceRetouch/renderState.d.ts +19 -0
  78. package/dist/components/FaceSwap/FaceMirror.d.ts +46 -0
  79. package/dist/components/FaceSwap/FaceSwap.d.ts +58 -0
  80. package/dist/components/FaceSwap/FaceTextureLayer.d.ts +72 -0
  81. package/dist/components/FaceSwap/faceSwapPlan.d.ts +91 -0
  82. package/dist/components/FaceSwap/index.d.ts +13 -0
  83. package/dist/components/FaceSwap/settings.d.ts +300 -0
  84. package/dist/components/FaceSwap/useFaceTexture.d.ts +35 -0
  85. package/dist/components/FaceSwap/useLiveFace.d.ts +38 -0
  86. package/dist/components/FaceSwap/useLiveFaceTexture.d.ts +31 -0
  87. package/dist/components/FaceWarp3D/FaceWarp3D.d.ts +50 -0
  88. package/dist/components/FaceWarp3D/index.d.ts +2 -3
  89. package/dist/components/Faceless/Faceless.d.ts +51 -0
  90. package/dist/components/Faceless/index.d.ts +2 -0
  91. package/dist/components/HairLock/HairLock.d.ts +39 -0
  92. package/dist/components/HairLock/index.d.ts +2 -0
  93. package/dist/components/HairLock/lockGeometry.d.ts +15 -0
  94. package/dist/components/HandCutout/index.d.ts +35 -0
  95. package/dist/components/HandInstruction/HandGestureHint.d.ts +70 -0
  96. package/dist/components/HandInstruction/index.d.ts +74 -0
  97. package/dist/components/HandInstruction/useHandGesture.d.ts +22 -0
  98. package/dist/components/HandRig/ForearmOccluder.d.ts +29 -0
  99. package/dist/components/HandRig/HandAttachment.d.ts +34 -0
  100. package/dist/components/HandRig/HandOccluder.d.ts +55 -0
  101. package/dist/components/HandRig/HandTattoo.d.ts +61 -0
  102. package/dist/components/HandRig/WristAttachment.d.ts +34 -0
  103. package/dist/components/HandRig/index.d.ts +101 -0
  104. package/dist/components/HandRig/useArmMask.d.ts +29 -0
  105. package/dist/components/HandRig/wristSolve.d.ts +69 -0
  106. package/dist/components/HandTouch/HandTouch.d.ts +62 -0
  107. package/dist/components/HandTouch/Touchable.d.ts +36 -0
  108. package/dist/components/HandTouch/index.d.ts +2 -0
  109. package/dist/components/HeadBinding/index.d.ts +14 -0
  110. package/dist/components/HeadOccluder/CanonicalHeadFrame.d.ts +22 -0
  111. package/dist/components/HeadOccluder/Earrings.d.ts +55 -0
  112. package/dist/components/HeadOccluder/HeadAttachment.d.ts +38 -0
  113. package/dist/components/HeadOccluder/NeckOccluder.d.ts +64 -0
  114. package/dist/components/HeadOccluder/earringPlacement.d.ts +31 -0
  115. package/dist/components/HeadOccluder/headAttachmentPoints.d.ts +69 -0
  116. package/dist/components/HeadOccluder/index.d.ts +57 -3
  117. package/dist/components/HeadOccluder/useCanonicalHeadFit.d.ts +36 -0
  118. package/dist/components/HeadOccluder/useLandmarkPoseFit.d.ts +80 -0
  119. package/dist/components/Instruction/HintStage.d.ts +29 -0
  120. package/dist/components/Instruction/InstructionCue.d.ts +126 -0
  121. package/dist/components/Instruction/gestureHold.d.ts +20 -0
  122. package/dist/components/Instruction/ghost.d.ts +129 -0
  123. package/dist/components/Instruction/hintBlend.d.ts +19 -0
  124. package/dist/components/Instruction/hintLook.d.ts +81 -0
  125. package/dist/components/Instruction/hintLoop.d.ts +36 -0
  126. package/dist/components/Instruction/index.d.ts +41 -0
  127. package/dist/components/Instruction/useGhostModel.d.ts +33 -0
  128. package/dist/components/Instruction/useInstructionHold.d.ts +72 -0
  129. package/dist/components/LipEffect/LipEffect.d.ts +22 -2
  130. package/dist/components/LipEffect/LipEffectMaterial.d.ts +62 -10
  131. package/dist/components/LipEffect/LipEffects.d.ts +5 -2
  132. package/dist/components/LipEffect/defaults.d.ts +21 -2
  133. package/dist/components/LipEffect/index.d.ts +1 -1
  134. package/dist/components/LipEffect/lipShading.d.ts +73 -0
  135. package/dist/components/LipEffect/settings.d.ts +117 -13
  136. package/dist/components/LipEffect/shader.d.ts +39 -0
  137. package/dist/components/LipEffect/types.d.ts +82 -10
  138. package/dist/components/LipEffect/useLipDesignTextures.d.ts +6 -0
  139. package/dist/components/LipEffect/uvGuide.d.ts +31 -16
  140. package/dist/components/Makeup/Blush.d.ts +18 -0
  141. package/dist/components/Makeup/Brows.d.ts +20 -0
  142. package/dist/components/Makeup/Contour.d.ts +17 -0
  143. package/dist/components/Makeup/Eyeliner.d.ts +20 -0
  144. package/dist/components/Makeup/Eyeshadow.d.ts +20 -0
  145. package/dist/components/Makeup/Highlighter.d.ts +18 -0
  146. package/dist/components/Makeup/MakeupDesign.d.ts +37 -0
  147. package/dist/components/Makeup/MakeupRegion.d.ts +132 -0
  148. package/dist/components/Makeup/constants.d.ts +44 -0
  149. package/dist/components/Makeup/design.d.ts +106 -0
  150. package/dist/components/Makeup/designSamples.d.ts +42 -0
  151. package/dist/components/Makeup/eyes.d.ts +114 -0
  152. package/dist/components/Makeup/fields.d.ts +10 -0
  153. package/dist/components/Makeup/geometry.d.ts +106 -0
  154. package/dist/components/Makeup/index.d.ts +26 -0
  155. package/dist/components/Makeup/looks.d.ts +28 -0
  156. package/dist/components/Makeup/material.d.ts +239 -0
  157. package/dist/components/Makeup/settings.d.ts +54 -0
  158. package/dist/components/Makeup/shades.d.ts +143 -0
  159. package/dist/components/Makeup/shapes.d.ts +27 -0
  160. package/dist/components/Makeup/skinTone.d.ts +135 -0
  161. package/dist/components/Makeup/types.d.ts +110 -0
  162. package/dist/components/Makeup/useMakeupSkinTone.d.ts +40 -0
  163. package/dist/components/Necklace/Necklace.d.ts +44 -0
  164. package/dist/components/Necklace/index.d.ts +1 -0
  165. package/dist/components/ParticleEmitter/ParticleEmitter.d.ts +69 -0
  166. package/dist/components/ParticleEmitter/index.d.ts +1 -0
  167. package/dist/components/ShoulderOccluder/index.d.ts +43 -0
  168. package/dist/components/ShoulderOccluder/useCanonicalTorsoFit.d.ts +24 -0
  169. package/dist/components/SpringSwing/SpringSwing.d.ts +22 -0
  170. package/dist/components/SpringSwing/index.d.ts +1 -0
  171. package/dist/components/XRScene/renderOutputTarget.d.ts +12 -0
  172. package/dist/components/index.d.ts +8 -0
  173. package/dist/config/index.d.ts +0 -1
  174. package/dist/context-DTxSQvp4.js +13 -0
  175. package/dist/context-hA0Rb2Xa.cjs +1 -0
  176. package/dist/contexts-BH7PdKFS.cjs +1 -0
  177. package/dist/contexts-jak8-tND.js +667 -0
  178. package/dist/coordinates/index.d.ts +2 -0
  179. package/dist/coordinates/side.d.ts +40 -0
  180. package/dist/debug-ui/default-setting.cjs +2 -2
  181. package/dist/debug-ui/face-swap-settings/index.d.ts +22 -0
  182. package/dist/debug-ui/hierarchy-panel/index.d.ts +3 -2
  183. package/dist/debug-ui/index.d.ts +4 -3
  184. package/dist/debug-ui/media-source/index.d.ts +1 -1
  185. package/dist/debug-ui/media-source/session.d.ts +30 -2
  186. package/dist/debug-ui/media-source.cjs +1 -1
  187. package/dist/debug-ui/media-source.js +1 -1
  188. package/dist/debug-ui/object-inspector-panel/index.d.ts +3 -2
  189. package/dist/debug-ui/product-hotspots/index.d.ts +3 -2
  190. package/dist/debug-ui/scene-editor/hierarchy-panel.d.ts +3 -1
  191. package/dist/debug-ui/scene-editor/inspector-panel.d.ts +3 -1
  192. package/dist/debug-ui/screen-image-settings/index.d.ts +3 -1
  193. package/dist/debug-ui/screen-text-settings/ScreenTextSettingsPanel.d.ts +1 -1
  194. package/dist/debug-ui/screen-text-settings/types.d.ts +2 -0
  195. package/dist/debug-ui/settings-panel/index.d.ts +6 -1
  196. package/dist/debug-ui/shared/debugWindow.d.ts +51 -0
  197. package/dist/debug-ui/xr-diagnostics/index.d.ts +3 -2
  198. package/dist/debug-ui.cjs +3 -3
  199. package/dist/debug-ui.js +2250 -2472
  200. package/dist/entries/all.d.ts +3 -1
  201. package/dist/entries/core.d.ts +3 -2
  202. package/dist/entries/face-effects.d.ts +114 -8
  203. package/dist/entries/instructions.d.ts +48 -0
  204. package/dist/entries/internal.d.ts +2 -1
  205. package/dist/entries/low-level.d.ts +28 -1
  206. package/dist/entries/particles.d.ts +11 -0
  207. package/dist/entries/tracking.d.ts +37 -2
  208. package/dist/face-atlas/attributes.d.ts +30 -0
  209. package/dist/face-atlas/eyes.d.ts +272 -0
  210. package/dist/face-atlas/faceAtlas.generated.d.ts +46 -0
  211. package/dist/face-atlas/glsl/atlasVertex.d.ts +46 -0
  212. package/dist/face-atlas/glsl/common.d.ts +55 -0
  213. package/dist/face-atlas/glsl/design.d.ts +49 -0
  214. package/dist/face-atlas/glsl/eyes.d.ts +73 -0
  215. package/dist/face-atlas/glsl/finish.d.ts +24 -0
  216. package/dist/face-atlas/glsl/format.d.ts +4 -0
  217. package/dist/face-atlas/glsl/index.d.ts +59 -0
  218. package/dist/face-atlas/glsl/shading.d.ts +15 -0
  219. package/dist/face-atlas/glsl/shapes.d.ts +66 -0
  220. package/dist/face-atlas/glsl/sparkle.d.ts +19 -0
  221. package/dist/face-atlas/glsl/uniforms.d.ts +106 -0
  222. package/dist/face-atlas/guide.d.ts +51 -0
  223. package/dist/face-atlas/index.d.ts +25 -0
  224. package/dist/face-atlas/lead.d.ts +117 -0
  225. package/dist/face-atlas/madeUpCamera.d.ts +125 -0
  226. package/dist/face-atlas/masks.d.ts +53 -0
  227. package/dist/face-atlas/obj.d.ts +69 -0
  228. package/dist/face-atlas/polylines.d.ts +63 -0
  229. package/dist/face-atlas/probe/FaceSkinProbe.d.ts +208 -0
  230. package/dist/face-atlas/probe/__fixtures__/emulate.d.ts +9 -0
  231. package/dist/face-atlas/probe/__fixtures__/face.d.ts +24 -0
  232. package/dist/face-atlas/probe/constants.d.ts +137 -0
  233. package/dist/face-atlas/probe/glsl.d.ts +43 -0
  234. package/dist/face-atlas/probe/lightFit.d.ts +108 -0
  235. package/dist/face-atlas/probe/schedule.d.ts +44 -0
  236. package/dist/face-atlas/probe/selfTest.d.ts +87 -0
  237. package/dist/face-atlas/probe/stats.d.ts +143 -0
  238. package/dist/face-atlas/probe/targets.d.ts +70 -0
  239. package/dist/face-atlas/probe/unwrap.d.ts +76 -0
  240. package/dist/face-atlas/quality.d.ts +28 -0
  241. package/dist/face-atlas/regions.d.ts +31 -0
  242. package/dist/face-atlas/registry.d.ts +252 -0
  243. package/dist/face-atlas/renderState.d.ts +86 -0
  244. package/dist/face-atlas/selfOcclusion.d.ts +62 -0
  245. package/dist/face-atlas/shading.d.ts +406 -0
  246. package/dist/face-atlas/shapes.d.ts +86 -0
  247. package/dist/face-atlas/sides.d.ts +41 -0
  248. package/dist/face-atlas/skinMask.d.ts +35 -0
  249. package/dist/face-atlas/surface.d.ts +155 -0
  250. package/dist/face-atlas/topology.d.ts +44 -0
  251. package/dist/face-character/__fixtures__/faceImageDetections.d.ts +25 -0
  252. package/dist/face-character/__fixtures__/faceNode.d.ts +22 -0
  253. package/dist/face-character/bindFaceModel.d.ts +106 -0
  254. package/dist/face-character/canonicalFace.d.ts +17 -0
  255. package/dist/face-character/canonicalFaceGeometry.d.ts +11 -0
  256. package/dist/face-character/canonicalFacePositions.d.ts +7 -0
  257. package/dist/face-character/driveFaceModel.d.ts +57 -0
  258. package/dist/face-character/expressionOutputs.d.ts +45 -0
  259. package/dist/face-character/faceExpressions.d.ts +104 -0
  260. package/dist/face-character/faceImageLandmarker.d.ts +93 -0
  261. package/dist/face-character/faceMeshBinding.d.ts +62 -0
  262. package/dist/face-character/faceMorph.d.ts +77 -0
  263. package/dist/face-character/faceMorphs.d.ts +46 -0
  264. package/dist/face-character/facePhoto.d.ts +138 -0
  265. package/dist/face-character/facePiercings.d.ts +116 -0
  266. package/dist/face-character/facePin.d.ts +131 -0
  267. package/dist/face-character/faceReprojection.d.ts +273 -0
  268. package/dist/face-character/faceReprojector.d.ts +171 -0
  269. package/dist/face-character/faceRig.d.ts +176 -0
  270. package/dist/face-character/faceSwapPresence.d.ts +85 -0
  271. package/dist/face-character/faceTexture.d.ts +169 -0
  272. package/dist/face-character/faceTextureBaker.d.ts +86 -0
  273. package/dist/face-character/faceTextureGuide.d.ts +106 -0
  274. package/dist/face-character/faceTextureStats.d.ts +298 -0
  275. package/dist/face-character/faceTransfer.d.ts +396 -0
  276. package/dist/face-character/faceTransferGeometry.d.ts +109 -0
  277. package/dist/face-character/faceTransferSelfTest.d.ts +94 -0
  278. package/dist/face-character/faceWarp3D.d.ts +101 -0
  279. package/dist/face-character/faceless.d.ts +79 -0
  280. package/dist/face-character/featureWarp.d.ts +28 -0
  281. package/dist/face-character/liveFaceRegistry.d.ts +370 -0
  282. package/dist/face-character/liveValue.d.ts +12 -0
  283. package/dist/face-character/memo.d.ts +15 -0
  284. package/dist/face-effects.cjs +2252 -83
  285. package/dist/face-effects.js +14234 -1231
  286. package/dist/face-expression/index.d.ts +182 -0
  287. package/dist/face-info/landmarks.d.ts +17 -3
  288. package/dist/face-info/types.d.ts +20 -3
  289. package/dist/gestures/definitions.d.ts +15 -2
  290. package/dist/gestures/index.d.ts +1 -1
  291. package/dist/gestures/measures.d.ts +21 -8
  292. package/dist/getFaceInfo-B1otSDMX.cjs +1 -0
  293. package/dist/getFaceInfo-Cu4xDWiL.js +62 -0
  294. package/dist/hand/armFit.d.ts +46 -0
  295. package/dist/hand/armMask.d.ts +178 -0
  296. package/dist/hand/handCutout.d.ts +23 -0
  297. package/dist/hand/handCutoutRegistry.d.ts +7 -0
  298. package/dist/hand/handGestures.d.ts +524 -0
  299. package/dist/hand/handPose.d.ts +98 -0
  300. package/dist/hand/handRigSolver.d.ts +159 -0
  301. package/dist/hand/handTattoo.d.ts +81 -0
  302. package/dist/hand/handTouch.d.ts +240 -0
  303. package/dist/hand/wrist.d.ts +44 -0
  304. package/dist/hand/wristFilter.d.ts +44 -0
  305. package/dist/hooks/selectors.d.ts +8 -0
  306. package/dist/hooks/useFaceModelAcquisition.d.ts +38 -0
  307. package/dist/hooks/useTrackerContext.d.ts +6 -0
  308. package/dist/index-B1_TzJaI.js +1104 -0
  309. package/dist/index-BavF06C6.js +190 -0
  310. package/dist/index-BfFmpddl.cjs +21 -0
  311. package/dist/index-BuBzneeW.cjs +46 -0
  312. package/dist/index-CGsQWodV.cjs +1 -0
  313. package/dist/index-CIe7eCMH.js +3200 -0
  314. package/dist/index-CfSF8LXa.cjs +1 -0
  315. package/dist/index-D5GTzOzD.cjs +1 -0
  316. package/dist/index-DBhQzvVa.js +314 -0
  317. package/dist/index-DE17y0ZI.cjs +1 -0
  318. package/dist/index-JII7huPk.js +442 -0
  319. package/dist/index-tpCr9CLj.cjs +1 -0
  320. package/dist/{renderPasses-NnKZVfBy.js → index-w1S7fI2B.js} +219 -247
  321. package/dist/index-zGaqrz_K.js +188 -0
  322. package/dist/instructions.cjs +30 -0
  323. package/dist/instructions.js +1507 -0
  324. package/dist/{internal-vsfNQycj.js → internal-B90P-clC.js} +138 -118
  325. package/dist/internal-Cjinca64.cjs +1 -0
  326. package/dist/internal.cjs +1 -1
  327. package/dist/internal.js +15 -10
  328. package/dist/iris/compute.d.ts +7 -5
  329. package/dist/iris/types.d.ts +6 -4
  330. package/dist/{landmarkMask-CbTFzBYG.js → landmarkMask-BFDyBnKM.js} +6 -6
  331. package/dist/landmarks-BlUqf5MZ.cjs +1 -0
  332. package/dist/landmarks-bftdwq6Z.js +76 -0
  333. package/dist/loaders-BGAUACsd.js +363 -0
  334. package/dist/loaders-BJ1_QCHt.cjs +1 -0
  335. package/dist/low-level.cjs +1 -1
  336. package/dist/low-level.js +666 -602
  337. package/dist/main.cjs +1 -1
  338. package/dist/main.js +866 -1182
  339. package/dist/models/Body/index.d.ts +2 -0
  340. package/dist/models/Face/constants.d.ts +8 -0
  341. package/dist/models/Face/index.d.ts +3 -11
  342. package/dist/models/Face/rotation.d.ts +18 -3
  343. package/dist/models/Hand/HandTracking.d.ts +17 -1
  344. package/dist/models/Segmentation/index.d.ts +2 -0
  345. package/dist/models/nodeSource.d.ts +9 -0
  346. package/dist/particles/emission.d.ts +24 -0
  347. package/dist/particles/eyes.d.ts +24 -0
  348. package/dist/particles/glsl.d.ts +14 -0
  349. package/dist/particles/index.d.ts +10 -0
  350. package/dist/particles/motion.d.ts +42 -0
  351. package/dist/particles/presets.d.ts +12 -0
  352. package/dist/particles/ring.d.ts +58 -0
  353. package/dist/particles/selfTest.d.ts +53 -0
  354. package/dist/particles/settings.d.ts +127 -0
  355. package/dist/particles/shapes.d.ts +29 -0
  356. package/dist/particles/spawner.d.ts +60 -0
  357. package/dist/particles/system.d.ts +64 -0
  358. package/dist/particles.cjs +122 -0
  359. package/dist/particles.js +774 -0
  360. package/dist/product.cjs +1 -1
  361. package/dist/product.js +29 -29
  362. package/dist/{providers-C0Dlhh9Z.js → providers-C8rE26Uf.js} +127 -126
  363. package/dist/providers-DHsrhDI2.cjs +62 -0
  364. package/dist/render/renderPasses.d.ts +8 -0
  365. package/dist/render/sceneBeforeRender.d.ts +12 -0
  366. package/dist/{renderGroups-CN1cGFUo.js → renderGroups-B38pUaX2.js} +1 -1
  367. package/dist/{renderGroups-O4KmaMl9.cjs → renderGroups-Cb_4Ar1Q.cjs} +1 -1
  368. package/dist/renderPasses-B6l8IpJv.js +1290 -0
  369. package/dist/renderPasses-dqmkft4P.cjs +158 -0
  370. package/dist/renderState-CJNmj5jz.js +39 -0
  371. package/dist/renderState-apSfg4eR.cjs +1 -0
  372. package/dist/scene-object.cjs +1 -1
  373. package/dist/scene-object.js +2 -2
  374. package/dist/segmentation-Cb3ouK6Z.js +1758 -0
  375. package/dist/segmentation-D9pYO6aR.cjs +1 -0
  376. package/dist/segmentation2d/types.d.ts +6 -0
  377. package/dist/select-Ck5LGz-J.cjs +1 -0
  378. package/dist/select-pYRo_win.js +233 -0
  379. package/dist/selectors-C4X71aoD.cjs +1 -0
  380. package/dist/selectors-DmNaKIwE.js +196 -0
  381. package/dist/session-BrH8G7iJ.cjs +31 -0
  382. package/dist/session-DgA_z6O1.js +418 -0
  383. package/dist/{settings-aQk845NJ.js → settings-BJ7FMBsO.js} +53 -15
  384. package/dist/settings-C63FMBlF.cjs +1 -0
  385. package/dist/similarityFit-BFqHND2e.cjs +1 -0
  386. package/dist/similarityFit-Bbz-R8AY.js +91 -0
  387. package/dist/spring/index.d.ts +2 -0
  388. package/dist/spring/spring.d.ts +69 -0
  389. package/dist/spring/swing.d.ts +54 -0
  390. package/dist/tracking.cjs +10 -1
  391. package/dist/tracking.js +1002 -855
  392. package/dist/trigger-D0Pm9noT.cjs +49 -0
  393. package/dist/trigger-IQeys0oS.js +2128 -0
  394. package/dist/types/face.d.ts +20 -1
  395. package/dist/types/hand-tracking.d.ts +9 -0
  396. package/dist/types/nodes.d.ts +20 -1
  397. package/dist/types/segmentation.d.ts +5 -0
  398. package/dist/updateThrottle-BseecYag.js +4 -0
  399. package/dist/updateThrottle-Of5Y4SVa.cjs +1 -0
  400. package/dist/useFaceInfo-BHDNCvsJ.cjs +1 -0
  401. package/dist/useFaceInfo-J4x7LsqL.js +76 -0
  402. package/dist/useFaceResultReader-BvEo5REG.js +61 -0
  403. package/dist/useFaceResultReader-DuaL1KJG.cjs +1 -0
  404. package/dist/useInstructionHold-DOu-RpCM.js +53 -0
  405. package/dist/useInstructionHold-DwJY1Alr.cjs +1 -0
  406. package/dist/useLandmarkPoseFit-Bg-h9BPb.cjs +1 -0
  407. package/dist/useLandmarkPoseFit-Bmb3h6Mw.js +87 -0
  408. package/dist/{useXRCapabilities-B1R2ghy-.cjs → useXRCapabilities-Cr3RzuAW.cjs} +1 -1
  409. package/dist/{useXRCapabilities-C68v__wB.js → useXRCapabilities-Cxmlmpbd.js} +1 -1
  410. package/dist/utils/canonicalRigidLandmarks.d.ts +8 -0
  411. package/dist/utils/headOccluderFit.d.ts +42 -0
  412. package/dist/utils/integrity.d.ts +17 -0
  413. package/dist/utils/resolveNumFaces.d.ts +13 -0
  414. package/dist/utils/shoulderOccluderFit.d.ts +38 -0
  415. package/dist/utils/similarityFit.d.ts +23 -0
  416. package/dist/uv-BMFt19bg.cjs +1 -0
  417. package/dist/{index-CsUdQ-pn.js → uv-DJU_XfmN.js} +15 -249
  418. package/docs/SDK_DOCUMENTATION.md +1 -2
  419. package/docs/api/adaptive-quality.mdx +1 -1
  420. package/docs/api/body-instructions.mdx +285 -0
  421. package/docs/api/body-triggers.mdx +234 -0
  422. package/docs/api/camera-permission.mdx +1 -1
  423. package/docs/api/coordinate-spaces.mdx +7 -4
  424. package/docs/api/cross-camera.mdx +3 -2
  425. package/docs/api/debug-ui-scene-editor.mdx +23 -2
  426. package/docs/api/external-face-mesh.mdx +231 -0
  427. package/docs/api/face-actions.mdx +20 -16
  428. package/docs/api/face-attribute-expression.mdx +1 -1
  429. package/docs/api/face-binding-anchors.mdx +4 -2
  430. package/docs/api/face-character.mdx +157 -0
  431. package/docs/api/face-effects.mdx +3 -0
  432. package/docs/api/face-expression-controller.mdx +153 -0
  433. package/docs/api/face-info.mdx +17 -11
  434. package/docs/api/face-inset.mdx +204 -0
  435. package/docs/api/face-instructions.mdx +183 -0
  436. package/docs/api/face-liquify.mdx +196 -0
  437. package/docs/api/face-mesh.mdx +4 -7
  438. package/docs/api/face-morph.mdx +117 -0
  439. package/docs/api/face-painting.mdx +7 -0
  440. package/docs/api/face-reprojection.mdx +154 -0
  441. package/docs/api/face-retouching.mdx +18 -10
  442. package/docs/api/face-swap.mdx +350 -0
  443. package/docs/api/face-warp-3d.mdx +166 -0
  444. package/docs/api/faceless.mdx +143 -0
  445. package/docs/api/gestures.mdx +68 -32
  446. package/docs/api/hair.mdx +97 -0
  447. package/docs/api/hand-instructions.mdx +222 -0
  448. package/docs/api/hand-rig.mdx +535 -0
  449. package/docs/api/hand-touch.mdx +162 -0
  450. package/docs/api/head-occluder.mdx +563 -0
  451. package/docs/api/holistic-tracker.mdx +6 -1
  452. package/docs/api/instructions.mdx +323 -0
  453. package/docs/api/iris-tracking.mdx +24 -19
  454. package/docs/api/made-up-camera.mdx +131 -0
  455. package/docs/api/makeup-skin-tone.mdx +135 -0
  456. package/docs/api/makeup.mdx +353 -0
  457. package/docs/api/multi-subject.mdx +4 -1
  458. package/docs/api/particles.mdx +155 -0
  459. package/docs/api/person-cutout.mdx +1 -1
  460. package/docs/api/pin-to-face-mesh.mdx +274 -0
  461. package/docs/api/product-ar.mdx +5 -2
  462. package/docs/api/segmentation-overlay.mdx +1 -1
  463. package/docs/docs.json +29 -1
  464. package/docs/examples/lip-shaders.mdx +82 -33
  465. package/docs/guides/face-atlas-template.svg +1 -0
  466. package/docs/guides/face-atlas-textures.mdx +186 -0
  467. package/docs/guides/face-texture-template.svg +1 -0
  468. package/docs/guides/harness-debug-ui.mdx +4 -4
  469. package/docs/guides/lip-effect-textures.mdx +178 -102
  470. package/docs/guides/lip-uv-template.png +0 -0
  471. package/docs/guides/lip-uv-template.svg +1 -1
  472. package/docs/guides/makeup-design-textures.mdx +109 -0
  473. package/docs/introduction.mdx +1 -2
  474. package/package.json +11 -1
  475. package/dist/DebuggerUI-C-ldiozL.js +0 -269
  476. package/dist/DebuggerUI-CWX5EtQv.cjs +0 -1
  477. package/dist/FaceMeshRenderer-BEEXZwS6.cjs +0 -158
  478. package/dist/FaceMeshRenderer-UuH5sTXG.js +0 -1322
  479. package/dist/FaceRetouch-C7h7x9kd.js +0 -683
  480. package/dist/FaceRetouch-DqftT26Y.cjs +0 -134
  481. package/dist/GLTFLoader-C5q63sKO.js +0 -1633
  482. package/dist/GLTFLoader-Cb_CRwmG.cjs +0 -1
  483. package/dist/SegmentationOverlay-DQuW3dsc.js +0 -133
  484. package/dist/SegmentationOverlay-aWVod8Kl.cjs +0 -1
  485. package/dist/components/FaceWarp3D/FaceWarp3DHead.d.ts +0 -15
  486. package/dist/components/FaceWarp3D/defaults.d.ts +0 -37
  487. package/dist/components/FaceWarp3D/warp.d.ts +0 -13
  488. package/dist/contexts-CO0sd4JQ.cjs +0 -1
  489. package/dist/contexts-FzlnnMYD.js +0 -669
  490. package/dist/debug-ui/face-warp-3d/index.d.ts +0 -6
  491. package/dist/getFaceInfo-BkZfaQs-.js +0 -118
  492. package/dist/getFaceInfo-ahPxQFGu.cjs +0 -1
  493. package/dist/index--RgGzZ6X.cjs +0 -47
  494. package/dist/index-CHVbH0hz.js +0 -214
  495. package/dist/index-CeVkgsag.cjs +0 -1
  496. package/dist/index-CnGox6Xr.js +0 -3054
  497. package/dist/index-DKBAh6hV.cjs +0 -1
  498. package/dist/index-DsZwTfG0.cjs +0 -1
  499. package/dist/index-Dw6tj2Mi.js +0 -144
  500. package/dist/index-OCPjOaeP.cjs +0 -1
  501. package/dist/index-s9pF4zkG.js +0 -2053
  502. package/dist/internal-BYza1h8_.cjs +0 -1
  503. package/dist/measures-9dQPdw96.js +0 -154
  504. package/dist/measures-KfJzpvod.cjs +0 -1
  505. package/dist/providers-YNwkmNeK.cjs +0 -62
  506. package/dist/renderPasses-Cg-zqmEz.cjs +0 -21
  507. package/dist/screenTransform-BenfCtZt.js +0 -44
  508. package/dist/screenTransform-BiXdpVf0.cjs +0 -1
  509. package/dist/segmentation-9PhSvc-R.cjs +0 -1
  510. package/dist/segmentation-CeOTKemr.js +0 -5
  511. package/dist/selectors-C5G1PMYL.js +0 -195
  512. package/dist/selectors-Du_PsVnW.cjs +0 -1
  513. package/dist/session-BBr0yN8h.cjs +0 -31
  514. package/dist/session-Cy0m7l7-.js +0 -363
  515. package/dist/settings-DRR7-snV.cjs +0 -1
  516. package/dist/useFaceInfo-Blf7FCu3.js +0 -303
  517. package/dist/useFaceInfo-C5mO8NQY.cjs +0 -1
@@ -1,3054 +0,0 @@
1
- var ns = Object.defineProperty;
2
- var rs = (t, s, e) => s in t ? ns(t, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[s] = e;
3
- var d = (t, s, e) => rs(t, typeof s != "symbol" ? s + "" : s, e);
4
- import { jsxs as as, jsx as et } from "react/jsx-runtime";
5
- import { useRef as ie, useMemo as he, useEffect as ce, useContext as De, useCallback as tt, createElement as is, createContext as ut, useState as os } from "react";
6
- import { FilesetResolver as j, PoseLandmarker as cs, FaceLandmarker as ls, GestureRecognizer as ds, HolisticLandmarker as us, HandLandmarker as hs, ImageSegmenter as ht, DrawingUtils as ms } from "@mediapipe/tasks-vision";
7
- import * as B from "three";
8
- import { RGBAFormat as mt, LinearFilter as pe, CanvasTexture as ft, SRGBColorSpace as fs } from "three";
9
- const gs = (t, s) => s, U = {
10
- apiBaseUrl: gs(void 0, "https://api.vincentt.studio"),
11
- // Pinned to the CDN, NOT build-env-driven: a stale VITE_ASSET_STORAGE_ENDPOINT
12
- // baked a now-deleted CloudFront domain into every published bundle, breaking
13
- // WASM/model loads at runtime. The host must never come from a mutable env value.
14
- assetStorageEndpoint: "https://cdn.vincentt.studio",
15
- // Versioned bucket for SDK-shipped reference assets (canonical face model, face textures, etc.).
16
- sdkAssetsBaseUrl: "https://cdn.vincentt.studio/assets/sdk/face/v1",
17
- loggerPrefix: "[vincentt-xr]:",
18
- sessionCheckInterval: 3e4
19
- };
20
- var F = /* @__PURE__ */ ((t) => (t.WEBCAM = "webcam", t.STREAM = "stream", t.CANVAS = "canvas", t))(F || {}), R = /* @__PURE__ */ ((t) => (t.HAND_TRACKER = "vincentt.xr.hand-tracker", t.GESTURE_TRACKER = "vincentt.xr.gesture-tracker", t.FACE_TRACKER = "vincentt.xr.face-tracker", t.BODY_TRACKER = "vincentt.xr.body-tracker", t.HOLISTIC_TRACKER = "vincentt.xr.holistic-tracker", t.BACKGROUND_SEGMENTATION = "vincentt.xr.background-segmentation", t.SEMANTIC_SEGMENTATION = "vincentt.xr.semantic-segmentation", t))(R || {});
21
- const Ee = (t) => Array.from({ length: t }, () => ({ x: 0, y: 0, z: 0 }));
22
- class ps {
23
- constructor(s) {
24
- d(this, "slots", []);
25
- this.options = s;
26
- }
27
- setOptions(s) {
28
- this.options = s;
29
- }
30
- /** Landmark sets to draw this frame: live faces, plus held/predicted ones. */
31
- update(s, e) {
32
- const { holdMs: n, predictMs: r, maxVelocityGapMs: a = 250 } = this.options, o = [], c = Math.max(s.length, this.slots.length);
33
- for (let l = 0; l < c; l += 1) {
34
- const h = s[l], f = this.slots[l] ?? null;
35
- if (h && h.length > 0) {
36
- const S = f && f.points.length === h.length ? f : null, k = S ?? {
37
- points: Ee(h.length),
38
- velocity: Ee(h.length),
39
- lastSeen: e,
40
- output: Ee(h.length)
41
- }, x = (e - k.lastSeen) / 1e3, T = S !== null && x > 0 && x * 1e3 <= a;
42
- for (let _ = 0; _ < h.length; _ += 1) {
43
- const g = h[_], v = k.points[_], y = k.velocity[_], C = g.z ?? 0;
44
- T ? (y.x = 0.5 * y.x + 0.5 * ((g.x - v.x) / x), y.y = 0.5 * y.y + 0.5 * ((g.y - v.y) / x), y.z = 0.5 * y.z + 0.5 * ((C - v.z) / x)) : (y.x = 0, y.y = 0, y.z = 0), v.x = g.x, v.y = g.y, v.z = C;
45
- }
46
- k.lastSeen = e, this.slots[l] = k, o.push(h);
47
- continue;
48
- }
49
- if (!f) continue;
50
- const u = e - f.lastSeen;
51
- if (u > n) {
52
- this.slots[l] = null;
53
- continue;
54
- }
55
- const w = Math.max(0, Math.min(u, r)) / 1e3;
56
- for (let S = 0; S < f.points.length; S += 1)
57
- f.output[S].x = f.points[S].x + f.velocity[S].x * w, f.output[S].y = f.points[S].y + f.velocity[S].y * w, f.output[S].z = f.points[S].z + f.velocity[S].z * w;
58
- o.push(f.output);
59
- }
60
- for (; this.slots.length > 0 && this.slots[this.slots.length - 1] === null; ) this.slots.pop();
61
- return o;
62
- }
63
- reset() {
64
- this.slots = [];
65
- }
66
- }
67
- const le = (t, s = { x: 0, y: 0, z: 0 }) => (s.x = t.x * 2 - 1, s.y = 1 - t.y * 2, s.z = -t.z, s), Qn = (t, s = { x: 0, y: 0, z: 0 }) => (s.x = (t.x + 1) / 2, s.y = (1 - t.y) / 2, s.z = -t.z, s), gt = "https://storage.googleapis.com/mediapipe-models/holistic_landmarker/holistic_landmarker/float16/latest/holistic_landmarker.task", ys = 250, ws = 0, vs = 768, Pe = (t) => ({
68
- hands: (t == null ? void 0 : t.hands) ?? "both",
69
- analysisMaxDimension: (t == null ? void 0 : t.analysisMaxDimension) ?? vs,
70
- holdMs: (t == null ? void 0 : t.holdMs) ?? ys,
71
- predictMs: (t == null ? void 0 : t.predictMs) ?? ws
72
- }), Ss = () => ({
73
- version: 0,
74
- timestampMs: 0,
75
- face: null,
76
- leftHand: null,
77
- rightHand: null,
78
- pose: null
79
- }), st = [
80
- 0,
81
- 4,
82
- 5,
83
- 6,
84
- 1,
85
- 2,
86
- 3,
87
- 8,
88
- 7,
89
- 10,
90
- 9,
91
- 12,
92
- 11,
93
- 14,
94
- 13,
95
- 16,
96
- 15,
97
- 18,
98
- 17,
99
- 20,
100
- 19,
101
- 22,
102
- 21,
103
- 24,
104
- 23,
105
- 26,
106
- 25,
107
- 28,
108
- 27,
109
- 30,
110
- 29,
111
- 32,
112
- 31
113
- ], nt = (t, s) => {
114
- if (t.length !== st.length) return t;
115
- s.length = t.length;
116
- for (let e = 0; e < t.length; e += 1) s[e] = t[st[e]];
117
- return s;
118
- };
119
- class ge {
120
- constructor(s, e) {
121
- d(this, "memory");
122
- d(this, "holdMs");
123
- d(this, "lastLiveMs", -1 / 0);
124
- d(this, "lastConfidence", 0);
125
- this.holdMs = s, this.memory = new ps({ holdMs: s, predictMs: e });
126
- }
127
- setOptions(s, e) {
128
- this.holdMs = s, this.memory.setOptions({ holdMs: s, predictMs: e });
129
- }
130
- reset() {
131
- this.memory.reset(), this.lastLiveMs = -1 / 0, this.lastConfidence = 0;
132
- }
133
- /**
134
- * Returns the landmarks to publish this frame (live, or replayed from
135
- * memory), or `undefined` when the stream is neither detected nor held.
136
- * A held stream's confidence decays linearly from the last live value to
137
- * 0 at `holdMs`.
138
- */
139
- bridge(s, e, n) {
140
- const r = s !== void 0 && s.length > 0, a = this.memory.update(r ? [s] : [], n)[0];
141
- if (!a) return;
142
- if (r)
143
- return this.lastLiveMs = n, this.lastConfidence = e, { points: a, held: !1, confidence: e };
144
- const o = n - this.lastLiveMs, c = this.holdMs > 0 ? Math.max(0, 1 - o / this.holdMs) : 0;
145
- return { points: a, held: !0, confidence: this.lastConfidence * c };
146
- }
147
- }
148
- const ae = (t, s, e) => {
149
- for (t.length > s && (t.length = s); t.length < s; ) t.push(e());
150
- return t;
151
- }, Ae = (t, s) => {
152
- t.x = s.x, t.y = s.y, t.z = s.z;
153
- }, Ms = (t) => {
154
- if (t.length === 0) return 0;
155
- let s = 0;
156
- for (let e = 0; e < t.length; e += 1) s += t[e].visibility ?? 0;
157
- return s / t.length;
158
- };
159
- class ks {
160
- constructor(s) {
161
- d(this, "options", Pe());
162
- d(this, "faceMemory", new ge(this.options.holdMs, this.options.predictMs));
163
- d(this, "leftHandMemory", new ge(this.options.holdMs, this.options.predictMs));
164
- d(this, "rightHandMemory", new ge(this.options.holdMs, this.options.predictMs));
165
- d(this, "poseMemory", new ge(this.options.holdMs, this.options.predictMs));
166
- d(this, "face", {
167
- landmarks: [],
168
- blendshapes: {},
169
- confidence: 0,
170
- held: !1
171
- });
172
- d(this, "leftHand", {
173
- handedness: "left",
174
- landmarks: [],
175
- worldLandmarks: [],
176
- confidence: 0,
177
- held: !1
178
- });
179
- d(this, "rightHand", {
180
- handedness: "right",
181
- landmarks: [],
182
- worldLandmarks: [],
183
- confidence: 0,
184
- held: !1
185
- });
186
- d(this, "poseScratch", []);
187
- d(this, "poseWorldScratch", []);
188
- d(this, "pose", {
189
- landmarks: [],
190
- worldLandmarks: [],
191
- visibility: [],
192
- confidence: 0,
193
- held: !1
194
- });
195
- this.setOptions(s);
196
- }
197
- getOptions() {
198
- return this.options;
199
- }
200
- setOptions(s) {
201
- this.options = Pe({ ...this.options, ...s });
202
- const { holdMs: e, predictMs: n } = this.options;
203
- for (const r of this.memories()) r.setOptions(e, n);
204
- }
205
- reset() {
206
- for (const s of this.memories()) s.reset();
207
- }
208
- memories() {
209
- return [this.faceMemory, this.leftHandMemory, this.rightHandMemory, this.poseMemory];
210
- }
211
- /**
212
- * Publish `raw` (or a miss when `undefined`) into `result` at `nowMs`.
213
- *
214
- * `mirrored` says the analysed frame is a mirror of the person (the
215
- * session's webcam feed). Pose left/right follow the image, and holistic
216
- * assigns hands from the pose, so on a mirrored frame MediaPipe's "left"
217
- * is the person's right. Swap both the hands and the pose's left/right
218
- * landmarks so the whole result is anatomical and self-consistent
219
- * (`leftHand` and pose wrist 15 are the same physical hand), matching the
220
- * convention `HandTracker` reports on that feed.
221
- */
222
- update(s, e, n, r = !1) {
223
- var h, f, u, w;
224
- n.face = this.updateFace(s, e);
225
- const a = {
226
- landmarks: (h = s == null ? void 0 : s.leftHandLandmarks) == null ? void 0 : h[0],
227
- world: (f = s == null ? void 0 : s.leftHandWorldLandmarks) == null ? void 0 : f[0]
228
- }, o = {
229
- landmarks: (u = s == null ? void 0 : s.rightHandLandmarks) == null ? void 0 : u[0],
230
- world: (w = s == null ? void 0 : s.rightHandWorldLandmarks) == null ? void 0 : w[0]
231
- }, c = r ? o : a, l = r ? a : o;
232
- return n.leftHand = this.updateHand("left", c.landmarks, c.world, e), n.rightHand = this.updateHand("right", l.landmarks, l.world, e), n.pose = this.updatePose(s, e, r), n.timestampMs = e, n.version += 1, n;
233
- }
234
- updateFace(s, e) {
235
- var c, l, h, f;
236
- const n = (c = s == null ? void 0 : s.faceLandmarks) == null ? void 0 : c[0], r = this.faceMemory.bridge(n, 1, e);
237
- if (!r) return null;
238
- const { face: a } = this, o = !r.held && n;
239
- ae(a.landmarks, r.points.length, () => ({
240
- x: 0,
241
- y: 0,
242
- z: 0,
243
- visibility: 0
244
- }));
245
- for (let u = 0; u < r.points.length; u += 1) {
246
- const w = a.landmarks[u];
247
- Ae(w, r.points[u]), w.visibility = o ? ((l = n[u]) == null ? void 0 : l.visibility) ?? 0 : 0;
248
- }
249
- if (o) {
250
- const u = (f = (h = s == null ? void 0 : s.faceBlendshapes) == null ? void 0 : h[0]) == null ? void 0 : f.categories;
251
- if (u)
252
- for (const w of u) a.blendshapes[w.categoryName] = w.score;
253
- }
254
- return a.confidence = r.confidence, a.held = r.held, a;
255
- }
256
- updateHand(s, e, n, r) {
257
- const a = s === "left" ? this.leftHandMemory : this.rightHandMemory, { hands: o } = this.options;
258
- if (o === "none" || o !== "both" && o !== s)
259
- return a.reset(), null;
260
- const c = a.bridge(e, 1, r);
261
- if (!c) return null;
262
- const l = s === "left" ? this.leftHand : this.rightHand;
263
- ae(l.landmarks, c.points.length, () => ({ x: 0, y: 0, z: 0 }));
264
- for (let h = 0; h < c.points.length; h += 1)
265
- le(c.points[h], l.landmarks[h]);
266
- if (!c.held && n) {
267
- ae(l.worldLandmarks, n.length, () => ({ x: 0, y: 0, z: 0 }));
268
- for (let h = 0; h < n.length; h += 1) Ae(l.worldLandmarks[h], n[h]);
269
- }
270
- return l.confidence = c.confidence, l.held = c.held, l;
271
- }
272
- updatePose(s, e, n) {
273
- var u, w, S;
274
- const r = (u = s == null ? void 0 : s.poseLandmarks) == null ? void 0 : u[0], a = r && n ? nt(r, this.poseScratch) : r, o = this.poseMemory.bridge(a, a ? Ms(a) : 0, e);
275
- if (!o) return null;
276
- const { pose: c } = this, l = !o.held && a;
277
- ae(c.landmarks, o.points.length, () => ({ x: 0, y: 0, z: 0 })), ae(c.visibility, o.points.length, () => 0);
278
- for (let k = 0; k < o.points.length; k += 1)
279
- le(o.points[k], c.landmarks[k]), l && (c.visibility[k] = ((w = a[k]) == null ? void 0 : w.visibility) ?? 0);
280
- const h = (S = s == null ? void 0 : s.poseWorldLandmarks) == null ? void 0 : S[0], f = h && n ? nt(h, this.poseWorldScratch) : h;
281
- if (l && f) {
282
- ae(c.worldLandmarks, f.length, () => ({ x: 0, y: 0, z: 0 }));
283
- for (let k = 0; k < f.length; k += 1) Ae(c.worldLandmarks[k], f[k]);
284
- }
285
- return c.confidence = o.confidence, c.held = o.held, c;
286
- }
287
- }
288
- const pt = {
289
- "camera-permission-denied": "Camera access was blocked. Allow camera permissions in your browser, then refresh.",
290
- "camera-in-use": "Camera is already in use by another app or browser tab. Close it and refresh.",
291
- "no-camera": "No camera was found on this device.",
292
- "camera-insecure-context": "Camera access needs HTTPS (or localhost). Open the page over HTTPS.",
293
- "camera-unsupported": "This browser cannot open the camera.",
294
- "camera-lost": "The camera stopped sending frames (disconnected, revoked, or taken by another app).",
295
- "webgl-unavailable": "WebGL is unavailable, so nothing can render or track.",
296
- "offscreen-canvas-unavailable": "OffscreenCanvas is unavailable; the tracker feed cannot be built.",
297
- "wasm-unavailable": "WebAssembly is unavailable; the tracking engine cannot load.",
298
- "model-unreachable": "The tracker model could not be downloaded.",
299
- "model-integrity": "The tracker model failed its integrity check.",
300
- "model-init-failed": "The tracker failed to initialize on this device.",
301
- "placement-unsupported": "This device cannot place 3D objects in the room (no WebXR, Scene Viewer or Quick Look).",
302
- unknown: "Tracking is unavailable for an unknown reason."
303
- }, Cs = {
304
- "camera-permission-denied": !0,
305
- "camera-in-use": !0,
306
- "no-camera": !1,
307
- "camera-insecure-context": !1,
308
- "camera-unsupported": !1,
309
- "camera-lost": !0,
310
- "webgl-unavailable": !1,
311
- "offscreen-canvas-unavailable": !1,
312
- "wasm-unavailable": !1,
313
- "model-unreachable": !0,
314
- "model-integrity": !1,
315
- "model-init-failed": !1,
316
- "placement-unsupported": !1,
317
- unknown: !0
318
- }, I = (t, s = pt[t]) => ({ code: t, message: s, recoverable: Cs[t] }), xs = {
319
- [R.FACE_TRACKER]: "/assets/xr/models/face_tracking.task",
320
- [R.HAND_TRACKER]: "/assets/xr/models/hand_tracking.task",
321
- [R.GESTURE_TRACKER]: "/assets/xr/models/gesture_tracking.task",
322
- [R.BODY_TRACKER]: "/assets/xr/models/body_tracking.task",
323
- [R.BACKGROUND_SEGMENTATION]: "/assets/xr/models/segmentation.tflite",
324
- [R.SEMANTIC_SEGMENTATION]: "/assets/xr/models/selfie_multiclass_256x256.tflite",
325
- [R.HOLISTIC_TRACKER]: gt
326
- }, yt = (t) => {
327
- const s = xs[t];
328
- return s ? /^https?:/.test(s) ? s : new URL(s, U.assetStorageEndpoint).toString() : null;
329
- }, bs = Object.values(R), Ts = () => {
330
- var e, n, r;
331
- const t = typeof window < "u", s = typeof document < "u";
332
- return {
333
- navigator: typeof navigator < "u" ? navigator : void 0,
334
- isSecureContext: t ? window.isSecureContext : void 0,
335
- createCanvas: s ? () => document.createElement("canvas") : void 0,
336
- offscreenCanvas: typeof OffscreenCanvas < "u",
337
- wasm: typeof WebAssembly < "u",
338
- fetch: typeof fetch < "u" ? fetch.bind(globalThis) : void 0,
339
- now: () => typeof performance < "u" ? performance.now() : Date.now(),
340
- xrSessionSupported: typeof navigator < "u" && ((e = navigator.xr) != null && e.isSessionSupported) ? (a) => navigator.xr.isSessionSupported(a).catch(() => !1) : void 0,
341
- relSupportsAr: s ? ((r = (n = document.createElement("a").relList) == null ? void 0 : n.supports) == null ? void 0 : r.call(n, "ar")) === !0 : void 0,
342
- userAgent: typeof navigator < "u" ? navigator.userAgent : void 0
343
- };
344
- }, Es = (t) => !!t && /Android/.test(t) && /(Chrome|SamsungBrowser)\//.test(t) && !/Firefox|OPR\//.test(t), As = async (t) => {
345
- let s = !1;
346
- if (t.xrSessionSupported)
347
- try {
348
- s = await t.xrSessionSupported("immersive-ar");
349
- } catch {
350
- s = !1;
351
- }
352
- const e = Es(t.userAgent), n = t.relSupportsAr === !0, r = s || e || n;
353
- return {
354
- webxr: s,
355
- sceneViewer: e,
356
- quickLook: n,
357
- any: r,
358
- reason: r ? null : I("placement-unsupported")
359
- };
360
- }, Rs = (t) => {
361
- switch (t) {
362
- case "granted":
363
- return "supported";
364
- case "denied":
365
- return "permission-denied";
366
- case "prompt":
367
- return "permission-prompt";
368
- default:
369
- return "unknown";
370
- }
371
- }, Fs = async (t, s) => {
372
- var c, l, h;
373
- const e = t.isSecureContext ?? !0, n = (c = t.navigator) == null ? void 0 : c.mediaDevices;
374
- if (!e)
375
- return {
376
- status: "unsupported",
377
- reason: I("camera-insecure-context"),
378
- deviceCount: null,
379
- secureContext: e
380
- };
381
- if (!n || typeof n.getUserMedia != "function")
382
- return {
383
- status: "unsupported",
384
- reason: I("camera-unsupported"),
385
- deviceCount: null,
386
- secureContext: e
387
- };
388
- let r = "unknown";
389
- if (s && ((h = (l = t.navigator) == null ? void 0 : l.permissions) != null && h.query))
390
- try {
391
- const f = await t.navigator.permissions.query({ name: "camera" });
392
- r = Rs(f.state);
393
- } catch {
394
- r = "unknown";
395
- }
396
- let a = null, o = !1;
397
- if (typeof n.enumerateDevices == "function")
398
- try {
399
- const f = await n.enumerateDevices();
400
- a = f.filter((u) => u.kind === "videoinput").length, o = f.some((u) => !!u.label);
401
- } catch {
402
- a = null;
403
- }
404
- return r === "permission-denied" ? {
405
- status: r,
406
- reason: I("camera-permission-denied"),
407
- deviceCount: a,
408
- secureContext: e
409
- } : a === 0 && (r === "supported" || o) ? {
410
- status: "unsupported",
411
- reason: I("no-camera"),
412
- deviceCount: a,
413
- secureContext: e
414
- } : { status: r, reason: null, deviceCount: a, secureContext: e };
415
- }, Is = (t) => {
416
- var e;
417
- const s = (e = t.createCanvas) == null ? void 0 : e.call(t);
418
- if (!s) return 0;
419
- try {
420
- if (s.getContext("webgl2")) return 2;
421
- if (s.getContext("webgl") || s.getContext("experimental-webgl")) return 1;
422
- } catch {
423
- return 0;
424
- }
425
- return 0;
426
- }, _s = (t) => {
427
- var o;
428
- const s = Is(t), e = t.offscreenCanvas ?? !1, n = t.wasm ?? !1, r = !!((o = t.navigator) != null && o.gpu);
429
- let a = null;
430
- return s === 0 ? a = I("webgl-unavailable") : e ? n || (a = I("wasm-unavailable")) : a = I("offscreen-canvas-unavailable"), {
431
- status: a ? "unsupported" : "supported",
432
- reason: a,
433
- webglVersion: s,
434
- webgpu: r,
435
- offscreenCanvas: e,
436
- wasm: n
437
- };
438
- }, Ps = async (t, s, e) => {
439
- var o, c;
440
- const n = yt(t);
441
- if (!n || !s.fetch)
442
- return { model: t, status: "unknown", reason: null, url: n, bytes: null };
443
- const r = typeof AbortController < "u" ? new AbortController() : void 0, a = setTimeout(() => r == null ? void 0 : r.abort(), e);
444
- try {
445
- const l = await s.fetch(n, { method: "HEAD", signal: r == null ? void 0 : r.signal });
446
- if (!l.ok)
447
- return {
448
- model: t,
449
- status: "unsupported",
450
- reason: I(
451
- "model-unreachable",
452
- `${pt["model-unreachable"]} (${l.status})`
453
- ),
454
- url: n,
455
- bytes: null
456
- };
457
- const h = Number(((c = (o = l.headers) == null ? void 0 : o.get) == null ? void 0 : c.call(o, "content-length")) ?? NaN);
458
- return {
459
- model: t,
460
- status: "supported",
461
- reason: null,
462
- url: n,
463
- bytes: Number.isFinite(h) && h > 0 ? h : null
464
- };
465
- } catch {
466
- return {
467
- model: t,
468
- status: "unsupported",
469
- reason: I("model-unreachable"),
470
- url: n,
471
- bytes: null
472
- };
473
- } finally {
474
- clearTimeout(a);
475
- }
476
- }, jn = async (t = {}, s = Ts()) => {
477
- const e = t.timeoutMs ?? 4e3, n = new Set(t.models ?? []), [r, a, o] = await Promise.all([
478
- Fs(s, t.queryPermission ?? !0),
479
- Promise.all(
480
- bs.map(
481
- async (h) => n.has(h) ? Ps(h, s, e) : {
482
- model: h,
483
- status: "unknown",
484
- reason: null,
485
- url: yt(h),
486
- bytes: null
487
- }
488
- )
489
- ),
490
- As(s)
491
- ]), c = _s(s), l = Object.fromEntries(a.map((h) => [h.model, h]));
492
- return {
493
- camera: r,
494
- rendering: c,
495
- placement: o,
496
- models: l,
497
- canRunTracking: c.status === "supported" && r.status !== "unsupported",
498
- checkedAt: s.now ? s.now() : Date.now()
499
- };
500
- }, wt = (t) => {
501
- switch (t) {
502
- case "permission-denied":
503
- return I("camera-permission-denied");
504
- case "camera-in-use":
505
- return I("camera-in-use");
506
- case "no-camera":
507
- return I("no-camera");
508
- case "camera-lost":
509
- return I("camera-lost");
510
- case "unsupported":
511
- return I("camera-unsupported");
512
- default:
513
- return I("unknown");
514
- }
515
- }, Zn = (t, s) => {
516
- const { camera: e, rendering: n } = t, r = t.models[s], a = e.status === "permission-prompt" || e.status === "unknown";
517
- return n.reason ? { supported: !1, reason: n.reason, needsPermission: a } : e.reason ? { supported: !1, reason: e.reason, needsPermission: a } : r != null && r.reason ? { supported: !1, reason: r.reason, needsPermission: a } : { supported: !0, reason: null, needsPermission: a };
518
- }, $n = (t) => {
519
- const s = t instanceof Error ? t.message : String(t ?? ""), e = s.toLowerCase();
520
- return e.includes("integrity") || e.includes("sha-384") || e.includes("sha384") ? I("model-integrity", s) : e.includes("failed to fetch") || e.includes("networkerror") || e.includes("load failed") || /\b(404|403|5\d\d)\b/.test(e) || e.includes("fetch") ? I("model-unreachable", s) : e.includes("webgl") || e.includes("gpu") ? I("webgl-unavailable", s) : s ? I("model-init-failed", s) : I("unknown");
521
- }, vt = (t) => {
522
- switch (t instanceof DOMException ? t.name : "") {
523
- case "NotAllowedError":
524
- case "PermissionDeniedError":
525
- return "permission-denied";
526
- case "NotReadableError":
527
- case "TrackStartError":
528
- return "camera-in-use";
529
- case "NotFoundError":
530
- case "DevicesNotFoundError":
531
- return "no-camera";
532
- case "NotSupportedError":
533
- case "SecurityError":
534
- case "OverconstrainedError":
535
- return "unsupported";
536
- default:
537
- return t instanceof TypeError ? "unsupported" : "unknown";
538
- }
539
- }, rt = {
540
- "permission-denied": "Camera access was blocked. Allow camera permissions in your browser, then refresh.",
541
- "camera-in-use": "Camera is already in use by another app or browser tab. Close it and refresh.",
542
- "no-camera": "No camera was found on this device.",
543
- "camera-lost": "The camera stopped sending frames. Reconnect it or re-allow access, then start again.",
544
- unsupported: "Unable to access camera. Allow camera permissions in your browser, then refresh.",
545
- unknown: "Unable to access camera. Allow camera permissions in your browser, then refresh."
546
- }, Oe = () => ({
547
- mediaDevices: typeof navigator < "u" ? navigator.mediaDevices : void 0,
548
- permissions: typeof navigator < "u" ? navigator.permissions : void 0,
549
- isSecureContext: typeof window < "u" ? window.isSecureContext : void 0
550
- }), St = async (t = Oe()) => {
551
- var s;
552
- if (!((s = t.permissions) != null && s.query)) return { state: "unknown", prompt: !1 };
553
- try {
554
- const e = await t.permissions.query({ name: "camera" });
555
- return e.state === "granted" ? { state: "granted", prompt: !1 } : e.state === "denied" ? { state: "blocked", prompt: !1 } : { state: "unknown", prompt: e.state === "prompt" };
556
- } catch {
557
- return { state: "unknown", prompt: !1 };
558
- }
559
- }, Mt = (t, s) => t === "permission-denied" ? {
560
- state: s === "blocked" ? "blocked" : "denied",
561
- reason: I("camera-permission-denied")
562
- } : { state: "unavailable", reason: wt(t) }, Jn = async (t = {}, s = Oe()) => {
563
- var n;
564
- if (s.isSecureContext === !1)
565
- return {
566
- state: "unavailable",
567
- reason: I("camera-insecure-context"),
568
- stream: null
569
- };
570
- const e = (n = s.mediaDevices) == null ? void 0 : n.getUserMedia;
571
- if (typeof e != "function")
572
- return {
573
- state: "unavailable",
574
- reason: I("camera-unsupported"),
575
- stream: null
576
- };
577
- try {
578
- const r = await e.call(
579
- s.mediaDevices,
580
- t.constraints ?? { video: { facingMode: "user" } }
581
- );
582
- return t.keepStream ? { state: "granted", reason: null, stream: r } : (r.getTracks().forEach((a) => a.stop()), { state: "granted", reason: null, stream: null });
583
- } catch (r) {
584
- const a = vt(r), o = await St(s);
585
- return { ...Mt(a, o.state), stream: null };
586
- }
587
- }, er = async (t, s = Oe()) => {
588
- var e, n;
589
- if (!((e = s.permissions) != null && e.query)) return () => {
590
- };
591
- try {
592
- const r = await s.permissions.query({ name: "camera" }), a = () => {
593
- r.state === "granted" ? t({ state: "granted", prompt: !1 }) : r.state === "denied" ? t({ state: "blocked", prompt: !1 }) : t({ state: "unknown", prompt: r.state === "prompt" });
594
- };
595
- return (n = r.addEventListener) == null || n.call(r, "change", a), () => {
596
- var o;
597
- return (o = r.removeEventListener) == null ? void 0 : o.call(r, "change", a);
598
- };
599
- } catch {
600
- return () => {
601
- };
602
- }
603
- }, tr = (t) => t === "unknown" || t === "denied" || t === "granted", sr = {
604
- unknown: "This experience uses your camera. Nothing is recorded or uploaded.",
605
- requesting: "Waiting for you to allow the camera…",
606
- granted: "Camera access granted.",
607
- denied: "Camera access was not allowed. You can try again.",
608
- blocked: "Camera access is blocked for this site. Allow it in your browser's site settings, then reload.",
609
- unavailable: "The camera is unavailable on this device right now."
610
- }, Ls = (t, s, e = "cover", n = 1) => {
611
- if (t.width <= 0 || t.height <= 0 || s.width <= 0 || s.height <= 0)
612
- return null;
613
- const r = Number.isFinite(n) && n > 0 ? n : 1, a = s.width / t.width, o = s.height / t.height, c = e === "contain" ? o <= a : o >= a, l = (c ? o : a) * r, h = c ? t.width * o * r : s.width * r, f = c ? s.height * r : t.height * a * r;
614
- return {
615
- scale: l,
616
- drawWidth: h,
617
- drawHeight: f,
618
- offsetX: (s.width - h) / 2,
619
- offsetY: (s.height - f) / 2
620
- };
621
- }, He = (t) => t === "webcam" || t === void 0, Ds = ({
622
- source: t,
623
- feed: s,
624
- zoom: e = 1,
625
- mirrored: n = !1
626
- }) => {
627
- const r = Ls(t, s, "cover", e);
628
- return r ? { ...r, source: t, feed: s, zoom: Number.isFinite(e) && e > 0 ? e : 1, mirrored: n } : null;
629
- }, nr = (t, s, e = { x: 0, y: 0 }) => {
630
- const n = s.mirrored ? s.source.width - t.x : t.x;
631
- return e.x = (s.offsetX + n * s.scale) / s.feed.width, e.y = (s.offsetY + t.y * s.scale) / s.feed.height, e;
632
- }, Os = (t, s, e = { x: 0, y: 0 }) => {
633
- const n = (t.x * s.feed.width - s.offsetX) / s.scale;
634
- return e.x = s.mirrored ? s.source.width - n : n, e.y = (t.y * s.feed.height - s.offsetY) / s.scale, e;
635
- }, rr = (t, s) => {
636
- const e = Os(t, s);
637
- return e.x >= 0 && e.x <= s.source.width && e.y >= 0 && e.y <= s.source.height;
638
- }, ar = (t, s = { x: 0, y: 0 }) => (s.x = 1 - t.x, s.y = t.y, t.z !== void 0 && (s.z = t.z), s), ir = (t, s, e, n = { x: 0, y: 0 }) => {
639
- switch (e) {
640
- case 90:
641
- return n.x = s.height - t.y, n.y = t.x, n;
642
- case 180:
643
- return n.x = s.width - t.x, n.y = s.height - t.y, n;
644
- case 270:
645
- return n.x = t.y, n.y = s.width - t.x, n;
646
- default:
647
- return n.x = t.x, n.y = t.y, n;
648
- }
649
- }, or = (t, s) => s === 90 || s === 270 ? { width: t.height, height: t.width } : { width: t.width, height: t.height };
650
- class O extends Error {
651
- constructor(s) {
652
- super(s), this.name = "VincenttXRError";
653
- }
654
- }
655
- class Hs {
656
- constructor(s) {
657
- d(this, "options");
658
- const e = {
659
- verbose: !1,
660
- prefix: U.loggerPrefix
661
- };
662
- this.options = { ...e, ...s };
663
- }
664
- log(...s) {
665
- const { verbose: e, prefix: n } = this.options;
666
- e && console.info(n, ...s);
667
- }
668
- error(...s) {
669
- const { verbose: e, prefix: n } = this.options;
670
- e && console.error(n, ...s);
671
- }
672
- }
673
- const at = new B.Vector3(), Re = new B.Vector3(), kt = (t, s, e, n, r) => {
674
- at.set(t, s, 0).unproject(e), Re.copy(at).sub(e.position).normalize();
675
- const a = (n - e.position.z) / Re.z;
676
- return r.copy(e.position).addScaledVector(Re, a);
677
- }, Us = (t, s, e = new B.Vector3(), n = 0) => kt((t.x - 0.5) * 2, (0.5 - t.y) * 2, s, n, e), cr = (t, s, e = new B.Vector3(), n = 0) => kt(t.x, t.y, s, n, e), X = new B.Vector3(), lr = (t, s, e = { x: 0, y: 0, z: 0 }) => (X.set(t.x, t.y, t.z).project(s), e.x = X.x / 2 + 0.5, e.y = 0.5 - X.y / 2, e.z = X.z, e), dr = (t, s, e = { x: 0, y: 0, z: 0 }) => (X.set(t.x, t.y, t.z).project(s), e.x = X.x, e.y = X.y, e.z = X.z, e), Fe = (t, s, e) => Us(t, s, e, 0), Ns = (t, s, e = 0.2) => e * s + (1 - e) * t;
678
- class de {
679
- constructor(s) {
680
- d(this, "canvas");
681
- d(this, "scale", 1);
682
- this.maxDimension = s;
683
- }
684
- /** Multiply the cap (0.25..1); the adaptive-quality tier sets it. */
685
- setScale(s) {
686
- this.scale = Math.min(1, Math.max(0.25, Number.isFinite(s) && s > 0 ? s : 1));
687
- }
688
- /**
689
- * Returns a downscaled copy of `source` capped to `maxDimension` on its
690
- * longest side (or `source` unchanged if it's already within the cap, or if a
691
- * 2D context can't be obtained). The returned canvas is reused across calls.
692
- */
693
- draw(s) {
694
- const e = s.width, n = s.height, r = Math.min(
695
- 1,
696
- this.maxDimension * this.scale / Math.max(e, n)
697
- );
698
- if (r >= 1) return s;
699
- const a = Math.max(1, Math.round(e * r)), o = Math.max(1, Math.round(n * r));
700
- (!this.canvas || this.canvas.width !== a || this.canvas.height !== o) && (this.canvas = new OffscreenCanvas(a, o));
701
- const c = this.canvas.getContext("2d");
702
- return c ? (c.setTransform(1, 0, 0, 1, 0, 0), c.clearRect(0, 0, a, o), c.drawImage(s, 0, 0, a, o), this.canvas) : s;
703
- }
704
- dispose() {
705
- this.canvas = void 0;
706
- }
707
- }
708
- const Bs = {
709
- "/assets/xr/models/face_tracking.task": "sha384-tYQh+yJE8llY+zO4RviZmWaSKs5W9tsB0ix5rjQVpF5/CLTqmwtP7bYtkUi2w65P",
710
- "/assets/xr/models/hand_tracking.task": "sha384-uWvruVKd887ov8k43S+DBHCsi7UXXS+CKvvdM1PX00rjPzx/B0QrAPfJ1U9yKcze",
711
- "/assets/xr/models/gesture_tracking.task": "sha384-2zuseP9JKKWAYlWQGKA2N+ooabB8V/yIxu23Mv8mtY7SowcySB+xKiOmqBhVvlUC",
712
- "/assets/xr/models/body_tracking.task": "sha384-3Wk9dvRYo36b3Nc9xVjKamb4wCKt9FwiPjcHKfrvyJL/jXoGs+uRLnii6yjWLKul",
713
- "/assets/xr/models/segmentation.tflite": "sha384-A2bQ8+iZyQM3KIGVBUf0FyetqxuynyKpjsjCE8uzoJEnj1ghCu6ge2daiRffAiS5",
714
- "/assets/xr/3d-models/head-occluder-v2.glb": "sha384-+0G60Q6EBVE6hpITxGzQgofAeKexPltpsfPq5T5et9GGBjRhFP5HOdsKAhe73OaI",
715
- // Category segmenters behind XRModel.SEMANTIC_SEGMENTATION. The same bytes
716
- // are pinned under the SDK CDN paths (not yet published) and under
717
- // MediaPipe's published paths, which the presets load by default.
718
- "/assets/xr/models/hair_segmenter.tflite": "sha384-1Eu/EdJcYV/7talPYVVbxPZBLg7UIxqsKisUNh/pEsyvAuUcE49HuqijSXWSHXHK",
719
- "/mediapipe-models/image_segmenter/hair_segmenter/float32/latest/hair_segmenter.tflite": "sha384-1Eu/EdJcYV/7talPYVVbxPZBLg7UIxqsKisUNh/pEsyvAuUcE49HuqijSXWSHXHK",
720
- "/assets/xr/models/selfie_multiclass_256x256.tflite": "sha384-LPLPyzBZ6TTE8146rnDx8CZ5LykB8memkmeO8FNVbGlNthvlUltn3W3KeJmtq9bL",
721
- "/mediapipe-models/image_segmenter/selfie_multiclass_256x256/float32/latest/selfie_multiclass_256x256.tflite": "sha384-LPLPyzBZ6TTE8146rnDx8CZ5LykB8memkmeO8FNVbGlNthvlUltn3W3KeJmtq9bL",
722
- // MediaPipe Holistic Landmarker (face + hands + pose in one graph) behind
723
- // XRModel.HOLISTIC_TRACKER. Same bytes pinned under the SDK CDN path (not yet
724
- // published) and MediaPipe's published path, which the tracker loads by default.
725
- "/assets/xr/models/holistic_landmarker.task": "sha384-6Y2fQ5yP5QtlvJIasfv0fHEyoMqRYYpLtEpsyeXjYDOuFCEXfKIZPZSXq8TLXmsg",
726
- "/mediapipe-models/holistic_landmarker/holistic_landmarker/float16/latest/holistic_landmarker.task": "sha384-6Y2fQ5yP5QtlvJIasfv0fHEyoMqRYYpLtEpsyeXjYDOuFCEXfKIZPZSXq8TLXmsg",
727
- "/assets/sdk/face/v1/canonical_face_model.obj": "sha384-xP8YM/72TXKvbMptXB9a8JUlUf3MZQ8uLurExrsZc05v6/P5RrsaNGMUYS/BZx8A",
728
- "/opencv/facial_expression_recognition/resolve/main/facial_expression_recognition_mobilefacenet_2022july_int8.onnx": "sha384-g8mtFubiIc/yhqi591RsxD76AJLw2CfYgKhKbVkIiFlwBmIyG7ZAIVyGPXafrDGB"
729
- };
730
- async function zs(t, s) {
731
- const e = await fetch(t, s != null && s.signal ? { signal: s.signal } : void 0);
732
- if (!e.ok)
733
- throw new Error(`fetchAndVerify: ${e.status} ${t}`);
734
- const n = await e.arrayBuffer(), r = Vs(t);
735
- if (!r) {
736
- if (Ws(t))
737
- throw new Error(`[xr-sdk integrity] no SRI hash for SDK asset ${t}`);
738
- return console.warn(`[xr-sdk integrity] no SRI hash for ${t} — passing through`), n;
739
- }
740
- const a = await qs(n);
741
- if (a !== r)
742
- throw new Error(
743
- `[xr-sdk integrity] SRI mismatch for ${t}: expected ${r}, got ${a}`
744
- );
745
- return n;
746
- }
747
- function Ws(t) {
748
- try {
749
- return new URL(t).origin === new URL(U.assetStorageEndpoint).origin;
750
- } catch {
751
- return !1;
752
- }
753
- }
754
- async function Z(t) {
755
- const s = await zs(t);
756
- return new Uint8Array(s);
757
- }
758
- function Vs(t) {
759
- try {
760
- const s = new URL(t);
761
- return Bs[s.pathname];
762
- } catch {
763
- return;
764
- }
765
- }
766
- async function qs(t) {
767
- const s = await crypto.subtle.digest("SHA-384", t), e = new Uint8Array(s);
768
- let n = "";
769
- for (let r = 0; r < e.byteLength; r++)
770
- n += String.fromCharCode(e[r]);
771
- return `sha384-${btoa(n)}`;
772
- }
773
- const Ie = /* @__PURE__ */ new Map();
774
- function $(t) {
775
- const s = t.wasmBinaryPath;
776
- let e = Ie.get(s);
777
- return e || (e = Ks(s).catch(() => {
778
- Ie.delete(s);
779
- }), Ie.set(s, e)), e;
780
- }
781
- async function Ks(t) {
782
- const s = await fetch(t, { credentials: "same-origin" });
783
- if (!s.ok || !s.body)
784
- throw new Error(`warmVisionWasm: ${s.status} ${t}`);
785
- const e = s.body.getReader();
786
- for (; ; ) {
787
- const { done: n } = await e.read();
788
- if (n) return;
789
- }
790
- }
791
- class J {
792
- constructor() {
793
- d(this, "disposed", !1);
794
- d(this, "paused", !1);
795
- d(this, "rafId", null);
796
- // Inference bookkeeping behind `getDiagnostics()`. Subclasses call
797
- // `recordInference(startMs)` right after their detect call and
798
- // `recordDetections(count, confidence)` after reading the result.
799
- d(this, "statInferenceMs", null);
800
- d(this, "statInferences", 0);
801
- d(this, "statWindowStart", 0);
802
- d(this, "statWindowCount", 0);
803
- d(this, "statFps", 0);
804
- d(this, "statSkipped", 0);
805
- d(this, "statDetections", null);
806
- d(this, "statConfidence", null);
807
- d(this, "statStatus", "ready");
808
- d(this, "statError", null);
809
- // Inference-rate throttle. `targetFrameIntervalMs` is 0 when uncapped
810
- // (detect every frame); a positive value skips detection until that many ms
811
- // have elapsed since the last inference. `run()` sets this from
812
- // `params.targetFps`; subclasses call `shouldRunInference()` in their RAF
813
- // loop to gate the expensive MediaPipe call.
814
- d(this, "targetFrameIntervalMs", 0);
815
- d(this, "lastInferenceMs", 0);
816
- /** Analysis-resolution multiplier (0.25..1) from the quality tier; subclasses read it where they downscale. */
817
- d(this, "analysisScale", 1);
818
- }
819
- /** Record one completed inference that started at `startMs` (`performance.now()`). */
820
- recordInference(s, e = performance.now()) {
821
- const n = e - s;
822
- this.statInferenceMs = n, this.statInferences += 1, this.statWindowCount += 1, this.statWindowStart === 0 && (this.statWindowStart = e);
823
- const r = e - this.statWindowStart;
824
- return r >= 1e3 && (this.statFps = this.statWindowCount * 1e3 / r, this.statWindowStart = e, this.statWindowCount = 0), n;
825
- }
826
- /** Record what the last inference found (subjects and the primary confidence). */
827
- recordDetections(s, e = null) {
828
- this.statDetections = s, this.statConfidence = e;
829
- }
830
- /** Record an inference failure (or clear it with `null`). */
831
- recordInferenceError(s) {
832
- this.statStatus = s ? "error" : "ready", this.statError = s;
833
- }
834
- /** Current health snapshot. Allocates a small object; sample it at UI rate, not per frame. */
835
- getDiagnostics() {
836
- const s = this.statWindowStart > 0 && performance.now() - this.statWindowStart > 1500;
837
- return {
838
- inferenceMs: this.statInferenceMs,
839
- inferenceFps: s ? 0 : this.statFps,
840
- inferences: this.statInferences,
841
- skippedFrames: this.statSkipped,
842
- detections: this.statDetections,
843
- confidence: this.statConfidence,
844
- status: this.statStatus,
845
- error: this.statError,
846
- paused: this.paused,
847
- disposed: this.disposed
848
- };
849
- }
850
- /** Clamp and store the analysis scale; subclasses with a downscaler forward it. */
851
- setAnalysisScale(s) {
852
- this.analysisScale = s !== void 0 && Number.isFinite(s) && s > 0 ? Math.min(1, Math.max(0.25, s)) : 1;
853
- }
854
- /** Set the per-frame inference cap. fps <= 0 (or undefined) → uncapped. */
855
- setTargetFps(s) {
856
- this.targetFrameIntervalMs = s && s > 0 ? 1e3 / s : 0;
857
- }
858
- /**
859
- * True if enough time has elapsed to run inference this frame (and records
860
- * the timestamp). Always true when uncapped. Call once per RAF tick, right
861
- * before the detect call; skip the detect (but keep rescheduling RAF) when
862
- * it returns false.
863
- */
864
- shouldRunInference() {
865
- if (this.targetFrameIntervalMs <= 0) return !0;
866
- const s = performance.now();
867
- return s - this.lastInferenceMs < this.targetFrameIntervalMs ? (this.statSkipped += 1, !1) : (this.lastInferenceMs = s, !0);
868
- }
869
- // load models
870
- async initialize(s) {
871
- }
872
- // setup for running + start running
873
- async run(s) {
874
- }
875
- // get model's data while processing
876
- getModelNode() {
877
- return {};
878
- }
879
- async getPerformanceData() {
880
- return {
881
- name: this.constructor.name,
882
- processingTime: null
883
- };
884
- }
885
- // Cancel the per-frame RAF loop without releasing MediaPipe resources or
886
- // dropping refs. Subclasses' process* methods check `paused` and return
887
- // without rescheduling. Idempotent.
888
- pause() {
889
- this.paused = !0, this.rafId !== null && (cancelAnimationFrame(this.rafId), this.rafId = null);
890
- }
891
- // Resume a paused loop by running the process function once. Subclasses
892
- // override to kick their specific process* method. Idempotent — no-op if
893
- // not paused. Calling resume() before run() is a no-op.
894
- resume() {
895
- this.paused = !1;
896
- }
897
- // Release MediaPipe landmarkers, cancel rAF loops, drop refs.
898
- // Subclasses MUST override and call super.dispose() at the end.
899
- dispose() {
900
- this.disposed = !0, this.rafId !== null && (cancelAnimationFrame(this.rafId), this.rafId = null);
901
- }
902
- }
903
- const Gs = 768;
904
- class Xs extends J {
905
- constructor() {
906
- super();
907
- d(this, "landmarker", null);
908
- d(this, "processingTime", null);
909
- d(this, "coordinates");
910
- d(this, "sourceCanvas");
911
- d(this, "downscaler", new de(Gs));
912
- }
913
- async getBodyData() {
914
- if (!this.landmarker || !this.sourceCanvas)
915
- return;
916
- const e = this.downscaler.draw(this.sourceCanvas), n = performance.now(), r = this.landmarker.detectForVideo(e, n), a = performance.now();
917
- this.processingTime = a - n, this.recordInference(n, a);
918
- const o = r.landmarks, c = o == null ? void 0 : o[0];
919
- this.recordDetections(
920
- (o == null ? void 0 : o.length) ?? 0,
921
- c && c.length ? c.reduce((h, f) => h + (f.visibility ?? 0), 0) / c.length : null
922
- );
923
- const l = [];
924
- if (o)
925
- return o.forEach((h, f) => {
926
- l[f] || (l[f] = []), h.forEach((u) => {
927
- l[f].push(le(u));
928
- });
929
- }), {
930
- coordinatesList: l
931
- };
932
- }
933
- async processBodyTracking() {
934
- if (!(this.disposed || this.paused || !this.landmarker)) {
935
- if (this.shouldRunInference()) {
936
- const e = await this.getBodyData();
937
- e && (this.coordinates = e.coordinatesList);
938
- }
939
- this.disposed || this.paused || (this.rafId = requestAnimationFrame(this.processBodyTracking.bind(this)));
940
- }
941
- }
942
- resume() {
943
- this.paused && (super.resume(), this.processBodyTracking());
944
- }
945
- dispose() {
946
- if (super.dispose(), this.landmarker) {
947
- try {
948
- this.landmarker.close();
949
- } catch {
950
- }
951
- this.landmarker = null;
952
- }
953
- this.sourceCanvas = void 0, this.downscaler.dispose(), this.coordinates = void 0;
954
- }
955
- getLandmarks2D(e = 0) {
956
- if (this.coordinates)
957
- return this.coordinates[e];
958
- }
959
- async initialize(e) {
960
- const n = await j.forVisionTasks(
961
- new URL("/assets/xr/wasm", U.assetStorageEndpoint).toString()
962
- ), [r] = await Promise.all([
963
- Z(
964
- new URL("/assets/xr/models/body_tracking.task", U.assetStorageEndpoint).toString()
965
- ),
966
- $(n)
967
- ]);
968
- this.landmarker = await cs.createFromOptions(n, {
969
- baseOptions: {
970
- modelAssetBuffer: r,
971
- delegate: "GPU"
972
- },
973
- runningMode: "VIDEO",
974
- numPoses: (e == null ? void 0 : e.numPoses) || 1
975
- });
976
- }
977
- async run({ sourceCanvas: e, targetFps: n, analysisScale: r }) {
978
- this.setAnalysisScale(r), this.downscaler.setScale(this.analysisScale), this.sourceCanvas = e, this.setTargetFps(n), this.rafId === null && await this.processBodyTracking();
979
- }
980
- getModelNode() {
981
- return {
982
- getLandmarks2D: this.getLandmarks2D.bind(this)
983
- };
984
- }
985
- async getPerformanceData() {
986
- return {
987
- name: this.constructor.name,
988
- processingTime: this.processingTime
989
- };
990
- }
991
- }
992
- const Ys = 0.11, Qs = 4e-3, js = (t, s) => s.set(t.x, -t.y, t.z);
993
- class Zs extends J {
994
- constructor() {
995
- super();
996
- d(this, "landmarker", null);
997
- d(this, "processingTime", null);
998
- d(this, "sourceCanvas");
999
- d(this, "analysisCanvas");
1000
- d(this, "getSource");
1001
- d(this, "detectionResults");
1002
- d(this, "numFaces", 1);
1003
- d(this, "cameras", []);
1004
- // camera object to unproject each face's translation
1005
- d(this, "faces", []);
1006
- // Reused per-face work vectors. Allocated once per face index and mutated
1007
- // in place each frame, so the published Face[] doesn't churn the GC at
1008
- // 30+ fps. Per-face indexing means two faces don't alias each other's
1009
- // transforms; consumers see "current value" each frame.
1010
- d(this, "leftCheekScratch", []);
1011
- d(this, "rightCheekScratch", []);
1012
- // Reused per-frame landmark used to feed unprojectToZZeroInto with an
1013
- // x-mirrored copy for non-webcam sources, without allocating a new
1014
- // landmark array (~468 entries) each frame.
1015
- d(this, "landmarkScratch", { x: 0, y: 0, z: 0, visibility: 0 });
1016
- // Reused per-frame rotation scratch (matrix -> quaternion -> mirror -> euler),
1017
- // allocated once to avoid per-frame churn at 30+ fps.
1018
- d(this, "rotMatrixScratch", new B.Matrix4());
1019
- d(this, "rotQuatScratch", new B.Quaternion());
1020
- d(this, "rotEulerScratch", new B.Euler());
1021
- }
1022
- // For non-webcam sources MediaPipe landmarks read as mirrored; flip x in
1023
- // place into the reused scratch so downstream unprojection sees the
1024
- // corrected position. Webcam input is already correct, so it's returned
1025
- // by reference.
1026
- landmarkForSource(e, n) {
1027
- return n ? (this.landmarkScratch.x = 1 - e.x, this.landmarkScratch.y = e.y, this.landmarkScratch.z = e.z, this.landmarkScratch.visibility = e.visibility, this.landmarkScratch) : e;
1028
- }
1029
- extractAndUpdateFaceData(e) {
1030
- var r;
1031
- if (!e.faceLandmarks.length) {
1032
- this.faces = [];
1033
- return;
1034
- }
1035
- const n = e.faceLandmarks.length;
1036
- for (this.faces.length > n && (this.faces.length = n, this.leftCheekScratch.length = n, this.rightCheekScratch.length = n); this.faces.length < n; )
1037
- this.faces.push({
1038
- transform: {
1039
- position: new B.Vector3(),
1040
- rotation: new B.Vector3(),
1041
- scale: new B.Vector3()
1042
- },
1043
- gestures: {}
1044
- }), this.leftCheekScratch.push(new B.Vector3()), this.rightCheekScratch.push(new B.Vector3());
1045
- for (let a = 0; a < n; a += 1) {
1046
- if (!this.cameras[a])
1047
- continue;
1048
- const o = this.faces[a], c = !He((r = this.getSource) == null ? void 0 : r.call(this)), l = e.faceLandmarks[a], h = e.facialTransformationMatrixes[a];
1049
- this.rotMatrixScratch.fromArray(h.data), this.rotQuatScratch.setFromRotationMatrix(this.rotMatrixScratch), this.rotQuatScratch.set(
1050
- -this.rotQuatScratch.x,
1051
- this.rotQuatScratch.y,
1052
- this.rotQuatScratch.z,
1053
- this.rotQuatScratch.w
1054
- ), this.rotEulerScratch.setFromQuaternion(this.rotQuatScratch, "XYZ"), js(this.rotEulerScratch, o.transform.rotation), Fe(
1055
- this.landmarkForSource(l[4], c),
1056
- this.cameras[a],
1057
- o.transform.position
1058
- ), Fe(
1059
- this.landmarkForSource(l[50], c),
1060
- this.cameras[a],
1061
- this.leftCheekScratch[a]
1062
- ), Fe(
1063
- this.landmarkForSource(l[280], c),
1064
- this.cameras[a],
1065
- this.rightCheekScratch[a]
1066
- );
1067
- const u = this.leftCheekScratch[a].distanceTo(this.rightCheekScratch[a]) * Ys, w = Math.abs(B.MathUtils.radToDeg(this.rotEulerScratch.y)), S = u + w * Qs, k = o.transform.scale.x, x = Ns(
1068
- isNaN(k) ? 0 : k,
1069
- S
1070
- );
1071
- o.transform.scale.set(x, x, x);
1072
- const T = o.gestures, _ = e.faceBlendshapes[a].categories;
1073
- for (const g of _)
1074
- T[g.categoryName] = g.score;
1075
- }
1076
- }
1077
- async processFaceTracking() {
1078
- if (this.disposed || this.paused || !this.landmarker || !this.sourceCanvas)
1079
- return null;
1080
- if (!this.shouldRunInference()) {
1081
- this.rafId = requestAnimationFrame(this.processFaceTracking.bind(this));
1082
- return;
1083
- }
1084
- const e = $s(this.numFaces) * this.analysisScale, n = this.sourceCanvas.width, r = this.sourceCanvas.height, a = Math.min(1, e / Math.max(n, r)), o = Math.max(1, Math.round(n * a)), c = Math.max(1, Math.round(r * a));
1085
- (!this.analysisCanvas || this.analysisCanvas.width !== o || this.analysisCanvas.height !== c) && (this.analysisCanvas = new OffscreenCanvas(o, c));
1086
- const l = this.analysisCanvas.getContext("2d");
1087
- if (!l) {
1088
- this.rafId = requestAnimationFrame(this.processFaceTracking.bind(this));
1089
- return;
1090
- }
1091
- l.setTransform(1, 0, 0, 1, 0, 0), l.clearRect(0, 0, o, c), l.drawImage(this.sourceCanvas, 0, 0, o, c);
1092
- const h = performance.now(), f = this.landmarker.detectForVideo(this.analysisCanvas, h), u = performance.now();
1093
- this.processingTime = u - h, this.recordInference(h, u), this.recordDetections(f.faceLandmarks.length, null), this.detectionResults = f, this.extractAndUpdateFaceData(f), !(this.disposed || this.paused) && (this.rafId = requestAnimationFrame(this.processFaceTracking.bind(this)));
1094
- }
1095
- resume() {
1096
- this.paused && (super.resume(), this.processFaceTracking());
1097
- }
1098
- dispose() {
1099
- if (super.dispose(), this.landmarker) {
1100
- try {
1101
- this.landmarker.close();
1102
- } catch {
1103
- }
1104
- this.landmarker = null;
1105
- }
1106
- this.sourceCanvas = void 0, this.analysisCanvas = void 0, this.getSource = void 0, this.detectionResults = void 0, this.processingTime = null, this.cameras = [], this.faces = [], this.leftCheekScratch = [], this.rightCheekScratch = [];
1107
- }
1108
- getFace(e = 0) {
1109
- return this.faces[e];
1110
- }
1111
- getDetectionResults() {
1112
- return this.detectionResults;
1113
- }
1114
- getRawFaceTrackingData(e = 0) {
1115
- var n, r, a, o;
1116
- if (this.detectionResults)
1117
- return {
1118
- landmarks: (n = this.detectionResults.faceLandmarks) == null ? void 0 : n[e],
1119
- blendshapes: (a = (r = this.detectionResults.faceBlendshapes) == null ? void 0 : r[e]) == null ? void 0 : a.categories,
1120
- transformationMatrix: (o = this.detectionResults.facialTransformationMatrixes) == null ? void 0 : o[e]
1121
- };
1122
- }
1123
- async initialize(e) {
1124
- this.numFaces = (e == null ? void 0 : e.numFaces) || 1;
1125
- const n = await j.forVisionTasks(
1126
- new URL("/assets/xr/wasm", U.assetStorageEndpoint).toString()
1127
- ), [r] = await Promise.all([
1128
- Z(
1129
- new URL("/assets/xr/models/face_tracking.task", U.assetStorageEndpoint).toString()
1130
- ),
1131
- $(n)
1132
- ]), a = await ls.createFromOptions(n, {
1133
- baseOptions: {
1134
- modelAssetBuffer: r,
1135
- delegate: "GPU"
1136
- },
1137
- // Keep detection permissive for calibration workflows with dark webcam input.
1138
- minFaceDetectionConfidence: 0.3,
1139
- minFacePresenceConfidence: 0.3,
1140
- minTrackingConfidence: 0.3,
1141
- outputFaceBlendshapes: !0,
1142
- outputFacialTransformationMatrixes: !0,
1143
- runningMode: "VIDEO",
1144
- numFaces: this.numFaces
1145
- });
1146
- if (this.disposed) {
1147
- a.close();
1148
- return;
1149
- }
1150
- this.landmarker = a;
1151
- }
1152
- async run({
1153
- sourceCanvas: e,
1154
- getSource: n,
1155
- targetFps: r,
1156
- analysisScale: a
1157
- }) {
1158
- this.sourceCanvas = e, this.getSource = n, this.setTargetFps(r), this.setAnalysisScale(a), this.analysisCanvas = void 0, this.rafId === null && this.processFaceTracking();
1159
- }
1160
- getModelNode() {
1161
- const e = this;
1162
- return {
1163
- get detectionResults() {
1164
- return e.detectionResults;
1165
- },
1166
- getDetectionResults: this.getDetectionResults.bind(this),
1167
- getFace: this.getFace.bind(this),
1168
- getRawFaceTrackingData: this.getRawFaceTrackingData.bind(this),
1169
- setCamera: (r, a = 0) => {
1170
- this.cameras[a] = r;
1171
- }
1172
- };
1173
- }
1174
- async getPerformanceData() {
1175
- return {
1176
- name: this.constructor.name,
1177
- processingTime: this.processingTime
1178
- };
1179
- }
1180
- }
1181
- const $s = (t) => t > 1 ? 1024 : 512;
1182
- var G = /* @__PURE__ */ ((t) => (t.ClosedFist = "closed_fist", t.OpenPalm = "open_palm", t.PointingUp = "pointing_up", t.ThumbDown = "thumb_down", t.ThumbUp = "thumb_up", t.Victory = "victory", t.ILoveYou = "i_love_you", t.None = "none", t))(G || {});
1183
- const Js = 512, en = {
1184
- Closed_Fist: G.ClosedFist,
1185
- Open_Palm: G.OpenPalm,
1186
- Pointing_Up: G.PointingUp,
1187
- Thumb_Down: G.ThumbDown,
1188
- Thumb_Up: G.ThumbUp,
1189
- Victory: G.Victory,
1190
- ILoveYou: G.ILoveYou,
1191
- None: G.None
1192
- }, tn = 15;
1193
- class sn extends J {
1194
- constructor() {
1195
- super();
1196
- d(this, "landmarker", null);
1197
- d(this, "processingTime", null);
1198
- d(this, "coordinates");
1199
- d(this, "gesture");
1200
- d(this, "sourceCanvas");
1201
- d(this, "downscaler", new de(Js));
1202
- }
1203
- async getGestureData() {
1204
- var l, h;
1205
- if (!this.landmarker || !this.sourceCanvas)
1206
- return;
1207
- const e = this.downscaler.draw(this.sourceCanvas), n = performance.now(), r = this.landmarker.recognizeForVideo(e, n), a = performance.now();
1208
- this.processingTime = a - n, this.recordInference(n, a), this.recordDetections(r.landmarks.length, ((h = (l = r.gestures[0]) == null ? void 0 : l[0]) == null ? void 0 : h.score) ?? null);
1209
- const o = r.landmarks[0], c = [];
1210
- if (o) {
1211
- const f = r.gestures[0][0].categoryName;
1212
- return o.forEach((u) => {
1213
- c.push(le(u));
1214
- }), {
1215
- coordinates: c,
1216
- gesture: en[f]
1217
- };
1218
- }
1219
- return { coordinates: void 0, gesture: void 0 };
1220
- }
1221
- async processGestureTracking() {
1222
- if (!this.disposed) {
1223
- if (this.shouldRunInference()) {
1224
- const e = await this.getGestureData();
1225
- e && (this.coordinates = e.coordinates, this.gesture = e.gesture);
1226
- }
1227
- this.disposed || this.paused || (this.rafId = requestAnimationFrame(this.processGestureTracking.bind(this)));
1228
- }
1229
- }
1230
- resume() {
1231
- this.paused && (super.resume(), this.processGestureTracking());
1232
- }
1233
- dispose() {
1234
- if (super.dispose(), this.landmarker) {
1235
- try {
1236
- this.landmarker.close();
1237
- } catch {
1238
- }
1239
- this.landmarker = null;
1240
- }
1241
- this.sourceCanvas = void 0, this.downscaler.dispose(), this.coordinates = void 0, this.gesture = void 0;
1242
- }
1243
- async initialize() {
1244
- const e = await j.forVisionTasks(
1245
- new URL("/assets/xr/wasm", U.assetStorageEndpoint).toString()
1246
- ), [n] = await Promise.all([
1247
- Z(
1248
- new URL(
1249
- "/assets/xr/models/gesture_tracking.task",
1250
- U.assetStorageEndpoint
1251
- ).toString()
1252
- ),
1253
- $(e)
1254
- ]), r = await ds.createFromOptions(e, {
1255
- baseOptions: {
1256
- modelAssetBuffer: n,
1257
- delegate: "GPU"
1258
- },
1259
- runningMode: "VIDEO",
1260
- numHands: 1
1261
- });
1262
- this.landmarker = r;
1263
- }
1264
- async run({ sourceCanvas: e, targetFps: n, analysisScale: r }) {
1265
- this.setAnalysisScale(r), this.downscaler.setScale(this.analysisScale), this.sourceCanvas = e, this.setTargetFps(n ?? tn), this.rafId === null && await this.processGestureTracking();
1266
- }
1267
- getModelNode() {
1268
- const e = this;
1269
- return {
1270
- get coordinates() {
1271
- return e.coordinates;
1272
- },
1273
- get gesture() {
1274
- return e.gesture;
1275
- }
1276
- };
1277
- }
1278
- async getPerformanceData() {
1279
- return {
1280
- name: this.constructor.name,
1281
- processingTime: this.processingTime
1282
- };
1283
- }
1284
- }
1285
- class nn extends J {
1286
- constructor() {
1287
- super();
1288
- d(this, "landmarker", null);
1289
- d(this, "status", "loading");
1290
- d(this, "error", null);
1291
- d(this, "processingTime", null);
1292
- d(this, "sourceCanvas");
1293
- d(this, "getSource");
1294
- d(this, "downscaler", new de(Pe().analysisMaxDimension));
1295
- d(this, "raw");
1296
- d(this, "delegatePolicy", "auto");
1297
- d(this, "delegate", "GPU");
1298
- /** Kept so the graph can be rebuilt on another delegate without refetching. */
1299
- d(this, "vision", null);
1300
- d(this, "modelBuffer", null);
1301
- d(this, "graphOptions", {});
1302
- d(this, "rebuilding", !1);
1303
- d(this, "fallbackAttempted", !1);
1304
- d(this, "result", Ss());
1305
- d(this, "builder", new ks());
1306
- d(this, "node");
1307
- this.node = {
1308
- getResult: () => this.result,
1309
- getRawResult: () => this.raw,
1310
- getStatus: () => this.status,
1311
- getError: () => this.error,
1312
- getDelegate: () => this.delegate,
1313
- setOptions: (e) => this.setRuntimeOptions(e)
1314
- };
1315
- }
1316
- setRuntimeOptions(e) {
1317
- const n = this.builder.getOptions().analysisMaxDimension;
1318
- this.builder.setOptions(e);
1319
- const r = this.builder.getOptions().analysisMaxDimension;
1320
- r !== n && (this.downscaler.dispose(), this.downscaler = new de(r), this.downscaler.setScale(this.analysisScale));
1321
- }
1322
- async initialize(e) {
1323
- this.status = "loading", this.error = null, this.setRuntimeOptions(e ?? {});
1324
- try {
1325
- const n = await j.forVisionTasks(
1326
- new URL("/assets/xr/wasm", U.assetStorageEndpoint).toString()
1327
- ), [r] = await Promise.all([
1328
- Z((e == null ? void 0 : e.modelUrl) ?? gt),
1329
- $(n)
1330
- ]);
1331
- this.vision = n, this.modelBuffer = r, this.graphOptions = {
1332
- runningMode: "VIDEO",
1333
- outputFaceBlendshapes: (e == null ? void 0 : e.outputFaceBlendshapes) ?? !0,
1334
- minFaceDetectionConfidence: e == null ? void 0 : e.minFaceDetectionConfidence,
1335
- minFacePresenceConfidence: e == null ? void 0 : e.minFacePresenceConfidence,
1336
- minPoseDetectionConfidence: e == null ? void 0 : e.minPoseDetectionConfidence,
1337
- minPosePresenceConfidence: e == null ? void 0 : e.minPosePresenceConfidence,
1338
- minHandLandmarksConfidence: e == null ? void 0 : e.minHandLandmarksConfidence
1339
- }, this.delegatePolicy = (e == null ? void 0 : e.delegate) ?? "auto", this.delegate = this.delegatePolicy === "CPU" ? "CPU" : "GPU";
1340
- const a = await this.createLandmarker(this.delegate);
1341
- if (this.disposed) {
1342
- a.close();
1343
- return;
1344
- }
1345
- this.landmarker = a, this.status = "ready";
1346
- } catch (n) {
1347
- throw this.status = "error", this.error = n instanceof Error ? n : new Error(String(n)), this.error;
1348
- }
1349
- }
1350
- createLandmarker(e) {
1351
- if (!this.vision || !this.modelBuffer)
1352
- throw new Error("HolisticTrackingModel: initialize() has not loaded the model");
1353
- return us.createFromOptions(this.vision, {
1354
- baseOptions: { modelAssetBuffer: this.modelBuffer, delegate: e },
1355
- ...this.graphOptions
1356
- });
1357
- }
1358
- /**
1359
- * The GPU graph can fail on its first run (the face-blendshape stage has no
1360
- * WebGL kernel for one of its ops). Rebuild on the CPU once, keep the RAF
1361
- * loop alive meanwhile, and run one detection right away so static sources
1362
- * (which pulse models once) still get a result.
1363
- */
1364
- async fallbackToCpu(e) {
1365
- this.fallbackAttempted = !0, this.rebuilding = !0, this.status = "loading", console.warn(
1366
- "[xr-sdk holistic] GPU inference failed; rebuilding the graph on the CPU delegate.",
1367
- e.message
1368
- );
1369
- const n = this.landmarker;
1370
- try {
1371
- const r = await this.createLandmarker("CPU");
1372
- if (this.disposed) {
1373
- r.close();
1374
- return;
1375
- }
1376
- this.landmarker = r, this.delegate = "CPU", this.status = "ready", this.error = null;
1377
- try {
1378
- n == null || n.close();
1379
- } catch {
1380
- }
1381
- this.rebuilding = !1, this.detectOnce();
1382
- } catch (r) {
1383
- this.rebuilding = !1, this.status = "error", this.error = r instanceof Error ? r : new Error(String(r));
1384
- }
1385
- }
1386
- /** One detect + publish outside the loop (used after a delegate rebuild). */
1387
- detectOnce() {
1388
- this.disposed || !this.landmarker || !this.sourceCanvas || (this.detect(), this.builder.update(this.raw, performance.now(), this.result, this.isMirrored()));
1389
- }
1390
- detect() {
1391
- var r, a, o, c, l;
1392
- if (!this.landmarker || !this.sourceCanvas) return;
1393
- const e = this.downscaler.draw(this.sourceCanvas), n = performance.now();
1394
- try {
1395
- this.raw = this.landmarker.detectForVideo(e, n), this.status === "error" && (this.status = "ready", this.error = null), this.recordInferenceError(null);
1396
- const h = this.raw, f = ((r = h.faceLandmarks) != null && r.length ? 1 : 0) + ((a = h.leftHandLandmarks) != null && a.length ? 1 : 0) + ((o = h.rightHandLandmarks) != null && o.length ? 1 : 0) + ((c = h.poseLandmarks) != null && c.length ? 1 : 0), u = (l = h.poseLandmarks) == null ? void 0 : l[0];
1397
- this.recordDetections(
1398
- f,
1399
- u && u.length ? u.reduce((w, S) => w + (S.visibility ?? 0), 0) / u.length : null
1400
- );
1401
- } catch (h) {
1402
- const f = h instanceof Error ? h : new Error(String(h));
1403
- this.delegatePolicy === "auto" && this.delegate === "GPU" && !this.fallbackAttempted ? this.fallbackToCpu(f) : (this.status = "error", this.error = f, this.recordInferenceError(f));
1404
- }
1405
- this.processingTime = performance.now() - n, this.recordInference(n);
1406
- }
1407
- /** The session mirrors only the webcam feed (an unknown kind is treated as webcam). */
1408
- isMirrored() {
1409
- var e;
1410
- return He((e = this.getSource) == null ? void 0 : e.call(this));
1411
- }
1412
- async run({
1413
- sourceCanvas: e,
1414
- getSource: n,
1415
- targetFps: r,
1416
- analysisScale: a
1417
- }) {
1418
- this.sourceCanvas = e, this.getSource = n, this.setTargetFps(r), this.setAnalysisScale(a), this.downscaler.setScale(this.analysisScale), this.rafId === null && await this.process();
1419
- }
1420
- async process() {
1421
- this.disposed || this.paused || !this.landmarker || (!this.rebuilding && this.shouldRunInference() && this.detect(), this.builder.update(this.raw, performance.now(), this.result, this.isMirrored()), !(this.disposed || this.paused) && (this.rafId = requestAnimationFrame(this.process.bind(this))));
1422
- }
1423
- resume() {
1424
- this.paused && (super.resume(), this.process());
1425
- }
1426
- dispose() {
1427
- if (super.dispose(), this.landmarker) {
1428
- try {
1429
- this.landmarker.close();
1430
- } catch {
1431
- }
1432
- this.landmarker = null;
1433
- }
1434
- this.sourceCanvas = void 0, this.getSource = void 0, this.downscaler.dispose(), this.vision = null, this.modelBuffer = null, this.raw = void 0, this.builder.reset(), this.result.face = null, this.result.leftHand = null, this.result.rightHand = null, this.result.pose = null;
1435
- }
1436
- getModelNode() {
1437
- return this.node;
1438
- }
1439
- async getPerformanceData() {
1440
- return { name: this.constructor.name, processingTime: this.processingTime };
1441
- }
1442
- }
1443
- const rn = 512;
1444
- class an extends J {
1445
- constructor() {
1446
- super();
1447
- d(this, "landmarker", null);
1448
- d(this, "processingTime", null);
1449
- d(this, "hands");
1450
- d(this, "coordinates");
1451
- d(this, "gesture");
1452
- d(this, "handedness");
1453
- d(this, "sourceCanvas");
1454
- d(this, "downscaler", new de(rn));
1455
- }
1456
- async getHandData() {
1457
- var h, f;
1458
- if (!this.landmarker || !this.sourceCanvas)
1459
- return;
1460
- const e = this.downscaler.draw(this.sourceCanvas), n = performance.now(), r = this.landmarker.detectForVideo(e, n), a = performance.now();
1461
- this.processingTime = a - n, this.recordInference(n, a);
1462
- const o = [], c = r.handedness ?? r.handednesses ?? [];
1463
- if (this.recordDetections(r.landmarks.length, ((f = (h = c[0]) == null ? void 0 : h[0]) == null ? void 0 : f.score) ?? null), r.landmarks.forEach((u, w) => {
1464
- var _, g, v;
1465
- if (!u || u.length === 0)
1466
- return;
1467
- const S = u.map(
1468
- (y) => le(y)
1469
- ), k = (v = (g = (_ = c[w]) == null ? void 0 : _[0]) == null ? void 0 : g.categoryName) == null ? void 0 : v.toLowerCase(), x = k === "left" || k === "right" ? k : void 0, T = u[0].z < 0 ? "closed_fist" : "open_palm";
1470
- o.push({ coordinates: S, gesture: T, handedness: x });
1471
- }), !o.length)
1472
- return {
1473
- hands: void 0,
1474
- coordinates: void 0,
1475
- gesture: void 0,
1476
- handedness: void 0
1477
- };
1478
- const l = o[0];
1479
- return {
1480
- hands: o,
1481
- coordinates: l.coordinates,
1482
- gesture: l.gesture,
1483
- handedness: l.handedness
1484
- };
1485
- }
1486
- async processHandTracking() {
1487
- if (!this.disposed) {
1488
- if (this.shouldRunInference()) {
1489
- const e = await this.getHandData();
1490
- e && (this.hands = e.hands, this.coordinates = e.coordinates, this.gesture = e.gesture, this.handedness = e.handedness);
1491
- }
1492
- this.disposed || this.paused || (this.rafId = requestAnimationFrame(this.processHandTracking.bind(this)));
1493
- }
1494
- }
1495
- resume() {
1496
- this.paused && (super.resume(), this.processHandTracking());
1497
- }
1498
- dispose() {
1499
- if (super.dispose(), this.landmarker) {
1500
- try {
1501
- this.landmarker.close();
1502
- } catch {
1503
- }
1504
- this.landmarker = null;
1505
- }
1506
- this.sourceCanvas = void 0, this.hands = void 0, this.downscaler.dispose(), this.coordinates = void 0, this.gesture = void 0, this.handedness = void 0;
1507
- }
1508
- async initialize() {
1509
- const e = await j.forVisionTasks(
1510
- new URL("/assets/xr/wasm", U.assetStorageEndpoint).toString()
1511
- ), [n] = await Promise.all([
1512
- Z(
1513
- new URL("/assets/xr/models/hand_tracking.task", U.assetStorageEndpoint).toString()
1514
- ),
1515
- $(e)
1516
- ]), r = await hs.createFromOptions(e, {
1517
- baseOptions: {
1518
- modelAssetBuffer: n,
1519
- delegate: "GPU"
1520
- },
1521
- runningMode: "VIDEO",
1522
- numHands: 2
1523
- });
1524
- this.landmarker = r;
1525
- }
1526
- async run({ sourceCanvas: e, targetFps: n, analysisScale: r }) {
1527
- this.setAnalysisScale(r), this.downscaler.setScale(this.analysisScale), this.sourceCanvas = e, this.setTargetFps(n), this.rafId === null && await this.processHandTracking();
1528
- }
1529
- getModelNode() {
1530
- const e = this;
1531
- return {
1532
- get hands() {
1533
- return e.hands;
1534
- },
1535
- get coordinates() {
1536
- return e.coordinates;
1537
- },
1538
- get gesture() {
1539
- return e.gesture;
1540
- },
1541
- get handedness() {
1542
- return e.handedness;
1543
- }
1544
- };
1545
- }
1546
- async getPerformanceData() {
1547
- return {
1548
- name: this.constructor.name,
1549
- processingTime: this.processingTime
1550
- };
1551
- }
1552
- }
1553
- const on = 24, cn = 720, ln = [
1554
- [255, 255, 255, 255],
1555
- // 0: background → green 255, kept
1556
- [0, 0, 0, 0]
1557
- // 1: person → green 0, discarded
1558
- ];
1559
- class dn extends J {
1560
- constructor() {
1561
- super();
1562
- d(this, "segmenter", null);
1563
- d(this, "processingTime", null);
1564
- d(this, "sourceCanvas");
1565
- // input source canvas
1566
- d(this, "processCanvas");
1567
- // downscaled canvas of sourceCanvas for processing
1568
- d(this, "filterCanvas");
1569
- // post-processing (blur) canvas
1570
- // Optional high-resolution input override. The shared session feed canvas is
1571
- // sized to the on-screen display layout (often a small, display-fit crop),
1572
- // which starves the segmenter of the resolution it needs to capture the whole
1573
- // body. When a consumer supplies a native-resolution source here (e.g. the raw
1574
- // <video>/<img>), the segmenter runs on THAT instead — letterboxed into the
1575
- // process canvas so nothing is cropped. Falls back to `sourceCanvas` when unset.
1576
- d(this, "inputSource");
1577
- d(this, "inputSourceSize");
1578
- // The segmenter's own WebGL2 context. DrawingUtils renders the inverted mask
1579
- // into this context on the GPU; we then blit that GL canvas straight into the
1580
- // mask canvas with a single `drawImage` — a GPU→GPU transfer, no CPU readback
1581
- // and no per-pixel JS loop. (A spike proved `drawImage(glCanvas)` reads the
1582
- // full DrawingUtils output correctly; the earlier "reads empty" wall that once
1583
- // forced a readPixels path was a false alarm.)
1584
- d(this, "glCanvas");
1585
- d(this, "drawingUtils");
1586
- d(this, "useGpuMaskPath", !1);
1587
- // CPU-fallback reused ImageData, allocated on size change only. Used ONLY when
1588
- // WebGL2 is unavailable and we must read the single-channel mask back by hand.
1589
- d(this, "maskImageData");
1590
- d(this, "maskCanvas", null);
1591
- d(this, "segmentationMaskTexture");
1592
- d(this, "isMaskSetup", !1);
1593
- d(this, "isProcessing", !1);
1594
- // Live clone of the most recent category mask, kept so getRawSegmentationData()
1595
- // can read the single-channel Uint8Array lazily — that readback is paid ONLY
1596
- // when a consumer actually asks for raw data. Cloned because the mask returned
1597
- // by segmentForVideo is invalidated on the next inference call.
1598
- d(this, "latestMask", null);
1599
- // Per-frame cache of the read-back array, so repeated getRawSegmentationData()
1600
- // calls within one frame don't re-run the GPU→CPU transfer.
1601
- d(this, "rawCache", null);
1602
- d(this, "quality", "medium");
1603
- d(this, "stagingCanvas");
1604
- }
1605
- getQualityScaleFactor() {
1606
- switch (this.quality) {
1607
- case "low":
1608
- return 0.5;
1609
- case "medium":
1610
- return 0.75;
1611
- case "high":
1612
- return 1;
1613
- default:
1614
- return 0.5;
1615
- }
1616
- }
1617
- /**
1618
- * Set (or clear) a high-resolution input override. Pass the raw <video>/<img>
1619
- * (or any CanvasImageSource with intrinsic dimensions) to run segmentation on
1620
- * native-resolution, uncropped frames instead of the small display-fit session
1621
- * feed. Pass `undefined` to revert to the shared feed canvas.
1622
- */
1623
- setInputSource(e) {
1624
- this.inputSource = e, this.inputSourceSize = e ? this.readIntrinsicSize(e) : void 0;
1625
- }
1626
- readIntrinsicSize(e) {
1627
- if (e instanceof HTMLVideoElement)
1628
- return e.videoWidth > 0 ? { width: e.videoWidth, height: e.videoHeight } : void 0;
1629
- if (e instanceof HTMLImageElement)
1630
- return e.naturalWidth > 0 ? { width: e.naturalWidth, height: e.naturalHeight } : void 0;
1631
- const n = e.width, r = e.height;
1632
- return typeof n == "number" && n > 0 && typeof r == "number" && r > 0 ? { width: n, height: r } : void 0;
1633
- }
1634
- /**
1635
- * Size the process canvas to the override input's aspect ratio, bounded by
1636
- * PROCESS_MAX_DIM on the long edge, and keep the GL canvas in sync so the GPU
1637
- * mask renders at the same resolution. No-op when there is no override, or when
1638
- * the intrinsic size hasn't changed since the last frame.
1639
- */
1640
- ensureProcessCanvasForInput() {
1641
- if (!this.processCanvas || !this.inputSource) return;
1642
- const e = this.readIntrinsicSize(this.inputSource);
1643
- if (!e) return;
1644
- this.inputSourceSize = e;
1645
- const n = Math.min(1, cn / Math.max(e.width, e.height)), r = Math.max(1, Math.round(e.width * n)), a = Math.max(1, Math.round(e.height * n));
1646
- this.processCanvas.width === r && this.processCanvas.height === a || (this.processCanvas.width = r, this.processCanvas.height = a, this.glCanvas && (this.glCanvas.width = r, this.glCanvas.height = a), this.maskImageData = void 0);
1647
- }
1648
- async processSegmentation() {
1649
- if (this.disposed || !this.isProcessing || !this.maskCanvas || !this.processCanvas)
1650
- return;
1651
- if (!this.shouldRunInference()) {
1652
- if (this.disposed || this.paused) return;
1653
- this.rafId = requestAnimationFrame(this.processSegmentation.bind(this));
1654
- return;
1655
- }
1656
- const e = this.inputSource ?? this.sourceCanvas;
1657
- if (!this.segmenter || !e) {
1658
- if (this.disposed || this.paused) return;
1659
- this.rafId = requestAnimationFrame(this.processSegmentation.bind(this));
1660
- return;
1661
- }
1662
- const n = performance.now();
1663
- this.ensureProcessCanvasForInput();
1664
- const r = this.processCanvas.getContext("2d");
1665
- if (r) {
1666
- const c = this.processCanvas.width, l = this.processCanvas.height;
1667
- if (r.clearRect(0, 0, c, l), this.inputSource && this.inputSourceSize) {
1668
- const { width: h, height: f } = this.inputSourceSize, u = Math.min(c / h, l / f), w = h * u, S = f * u;
1669
- r.drawImage(this.inputSource, (c - w) / 2, (l - S) / 2, w, S);
1670
- } else
1671
- r.drawImage(e, 0, 0, c, l);
1672
- }
1673
- const o = this.segmenter.segmentForVideo(
1674
- this.processCanvas,
1675
- performance.now()
1676
- ).categoryMask;
1677
- if (!o) {
1678
- if (this.disposed || this.paused) return;
1679
- this.rafId = requestAnimationFrame(this.processSegmentation.bind(this));
1680
- return;
1681
- }
1682
- if (this.rawCache = null, this.latestMask && (this.latestMask.close(), this.latestMask = null), this.useGpuMaskPath && this.drawingUtils && this.glCanvas)
1683
- this.drawingUtils.drawCategoryMask(o, ln), this.latestMask = o.clone(), o.close(), this.blitGlToMask();
1684
- else {
1685
- this.latestMask = o.clone();
1686
- const c = this.readMaskToImageData(o);
1687
- o.close(), c && this.blitImageDataToMask(c);
1688
- }
1689
- this.segmentationMaskTexture && (this.isMaskSetup || (this.segmentationMaskTexture.format = mt, this.segmentationMaskTexture.minFilter = pe, this.segmentationMaskTexture.magFilter = pe, this.segmentationMaskTexture.generateMipmaps = !1, this.isMaskSetup = !0), this.segmentationMaskTexture.needsUpdate = !0), this.processingTime = performance.now() - n, this.recordInference(n), this.recordDetections(1, null), !(this.disposed || this.paused) && (this.rafId = requestAnimationFrame(this.processSegmentation.bind(this)));
1690
- }
1691
- /**
1692
- * Blit the GPU-rendered mask (already RGBA-inverted by drawCategoryMask)
1693
- * straight from the GL canvas into the mask canvas, cover-fitted through the
1694
- * soft-edge blur. `drawImage(glCanvas)` is a GPU→GPU transfer — no readPixels,
1695
- * no CPU array, no ImageData, no row flip (the 2D canvas presents the WebGL
1696
- * canvas right-side-up). This is the zero-readback path.
1697
- */
1698
- blitGlToMask() {
1699
- if (!this.maskCanvas || !this.filterCanvas || !this.glCanvas) return;
1700
- const e = this.maskCanvas.getContext("2d"), n = this.filterCanvas.getContext("2d");
1701
- !e || !n || (n.filter = "blur(0.5px)", n.clearRect(0, 0, this.filterCanvas.width, this.filterCanvas.height), n.drawImage(this.glCanvas, 0, 0, this.filterCanvas.width, this.filterCanvas.height), e.clearRect(0, 0, this.maskCanvas.width, this.maskCanvas.height), e.drawImage(this.filterCanvas, 0, 0, this.maskCanvas.width, this.maskCanvas.height));
1702
- }
1703
- /**
1704
- * CPU-fallback inverted-alpha ImageData build (only when the GPU path is off).
1705
- * The single-channel mask is expanded to RGBA with the person→transparent,
1706
- * background→opaque convention (green carries the signal for the alphaMap).
1707
- */
1708
- readMaskToImageData(e) {
1709
- const n = e.getAsUint8Array(), { width: r, height: a } = e;
1710
- if (!n || r <= 0 || a <= 0) return null;
1711
- (!this.maskImageData || this.maskImageData.width !== r || this.maskImageData.height !== a) && (this.maskImageData = new ImageData(r, a));
1712
- const o = this.maskImageData.data;
1713
- for (let c = 0; c < n.length; c += 1) {
1714
- const l = n[c] === 255 ? 0 : 255;
1715
- o[c * 4] = 255, o[c * 4 + 1] = l, o[c * 4 + 2] = 255, o[c * 4 + 3] = l;
1716
- }
1717
- return this.maskImageData;
1718
- }
1719
- /**
1720
- * CPU-fallback blit: put the inverted-alpha mask ImageData into maskCanvas
1721
- * with a soft-edge blur, cover-fitted to the render target. Only used when the
1722
- * GPU path is off; the GPU path blits the GL canvas directly (blitGlToMask).
1723
- */
1724
- blitImageDataToMask(e) {
1725
- if (!this.maskCanvas || !this.filterCanvas) return;
1726
- const n = this.maskCanvas.getContext("2d"), r = this.filterCanvas.getContext("2d");
1727
- if (!n || !r) return;
1728
- const a = this.getStagingCanvas(e.width, e.height), o = a.getContext("2d");
1729
- o && (o.putImageData(e, 0, 0), r.filter = "blur(0.5px)", r.clearRect(0, 0, this.filterCanvas.width, this.filterCanvas.height), r.drawImage(a, 0, 0, this.filterCanvas.width, this.filterCanvas.height), n.clearRect(0, 0, this.maskCanvas.width, this.maskCanvas.height), n.drawImage(this.filterCanvas, 0, 0, this.maskCanvas.width, this.maskCanvas.height));
1730
- }
1731
- getStagingCanvas(e, n) {
1732
- return this.stagingCanvas || (this.stagingCanvas = document.createElement("canvas")), this.stagingCanvas.width !== e && (this.stagingCanvas.width = e), this.stagingCanvas.height !== n && (this.stagingCanvas.height = n), this.stagingCanvas;
1733
- }
1734
- resume() {
1735
- this.paused && (super.resume(), this.processSegmentation());
1736
- }
1737
- dispose() {
1738
- if (super.dispose(), this.isProcessing = !1, this.latestMask) {
1739
- try {
1740
- this.latestMask.close();
1741
- } catch {
1742
- }
1743
- this.latestMask = null;
1744
- }
1745
- if (this.rawCache = null, this.segmenter) {
1746
- try {
1747
- this.segmenter.close();
1748
- } catch {
1749
- }
1750
- this.segmenter = null;
1751
- }
1752
- this.drawingUtils = void 0, this.glCanvas = void 0, this.maskImageData = void 0, this.segmentationMaskTexture && (this.segmentationMaskTexture.dispose(), this.segmentationMaskTexture = void 0), this.sourceCanvas = void 0, this.inputSource = void 0, this.inputSourceSize = void 0, this.processCanvas = void 0, this.filterCanvas = void 0, this.stagingCanvas = void 0, this.maskCanvas = null;
1753
- }
1754
- async initialize(e) {
1755
- this.quality = (e == null ? void 0 : e.quality) ?? "low";
1756
- const n = await j.forVisionTasks(
1757
- new URL("/assets/xr/wasm", U.assetStorageEndpoint).toString()
1758
- ), [r] = await Promise.all([
1759
- Z(
1760
- new URL("/assets/xr/models/segmentation.tflite", U.assetStorageEndpoint).toString()
1761
- ),
1762
- $(n)
1763
- ]);
1764
- this.glCanvas = new OffscreenCanvas(1, 1);
1765
- const a = this.glCanvas.getContext("webgl2", {
1766
- preserveDrawingBuffer: !0
1767
- });
1768
- this.segmenter = await ht.createFromOptions(n, {
1769
- baseOptions: {
1770
- modelAssetBuffer: r,
1771
- delegate: "GPU"
1772
- },
1773
- ...a ? { canvas: this.glCanvas } : {},
1774
- outputCategoryMask: !0,
1775
- outputConfidenceMasks: !1,
1776
- runningMode: "VIDEO"
1777
- }), a ? (this.drawingUtils = new ms(a), this.useGpuMaskPath = !0) : this.useGpuMaskPath = !1;
1778
- }
1779
- async run({
1780
- sourceCanvas: e,
1781
- renderWidth: n,
1782
- renderHeight: r,
1783
- targetFps: a
1784
- }) {
1785
- var c;
1786
- if (!e)
1787
- return;
1788
- this.setTargetFps(a ?? on), this.isProcessing = !1, this.rafId !== null && (cancelAnimationFrame(this.rafId), this.rafId = null);
1789
- const o = this.getQualityScaleFactor();
1790
- this.sourceCanvas = e, this.processCanvas = document.createElement("canvas"), this.processCanvas.width = e.width * o, this.processCanvas.height = e.height * o, this.glCanvas && (this.glCanvas.width = this.processCanvas.width, this.glCanvas.height = this.processCanvas.height), this.maskImageData = void 0, this.maskCanvas = document.createElement("canvas"), this.maskCanvas.width = n, this.maskCanvas.height = r, this.filterCanvas = document.createElement("canvas"), this.filterCanvas.width = n, this.filterCanvas.height = r, (c = this.segmentationMaskTexture) == null || c.dispose(), this.segmentationMaskTexture = new ft(this.maskCanvas), this.isMaskSetup = !1, this.rawCache = null, this.isProcessing = !0, this.lastInferenceMs = 0, this.rafId = requestAnimationFrame(this.processSegmentation.bind(this));
1791
- }
1792
- /**
1793
- * Lazily read the single-channel mask back to a Uint8Array. Only invoked when
1794
- * a consumer calls getRawSegmentationData(); the default texture path never
1795
- * touches it, so apps that only use <VideoBackground> pay no extra readback.
1796
- */
1797
- getRawSegmentationData() {
1798
- if (this.rawCache) return this.rawCache;
1799
- if (!this.latestMask) return null;
1800
- const e = this.latestMask.getAsUint8Array();
1801
- return this.rawCache = {
1802
- maskData: e,
1803
- width: this.latestMask.width,
1804
- height: this.latestMask.height
1805
- }, this.rawCache;
1806
- }
1807
- getModelNode() {
1808
- const e = this;
1809
- return {
1810
- get backgroundSegmentationMask() {
1811
- return e.segmentationMaskTexture;
1812
- },
1813
- getMaskCanvas: () => e.maskCanvas,
1814
- getRawSegmentationData: () => e.getRawSegmentationData(),
1815
- setInputSource: (n) => e.setInputSource(n ?? void 0)
1816
- };
1817
- }
1818
- async getPerformanceData() {
1819
- return {
1820
- name: this.constructor.name,
1821
- processingTime: this.processingTime
1822
- };
1823
- }
1824
- }
1825
- const un = (t, s, e, n = "feed") => ({
1826
- width: Math.max(1, Math.round(t)),
1827
- height: Math.max(1, Math.round(s)),
1828
- indices: new Uint8Array(Math.max(1, Math.round(t)) * Math.max(1, Math.round(s))),
1829
- labels: e,
1830
- space: n,
1831
- version: 0
1832
- }), ur = (t) => {
1833
- t.indices.fill(0);
1834
- }, hr = (t, s) => t.labels.indexOf(s), hn = (t, s, e) => {
1835
- const { width: n, height: r, indices: a } = t, o = s.length;
1836
- if (o < 3) return;
1837
- let c = 1 / 0, l = -1 / 0;
1838
- for (let w = 0; w < o; w += 1) {
1839
- const S = s[w].y * r;
1840
- S < c && (c = S), S > l && (l = S);
1841
- }
1842
- const h = Math.max(0, Math.floor(c)), f = Math.min(r - 1, Math.ceil(l)), u = [];
1843
- for (let w = h; w <= f; w += 1) {
1844
- const S = w + 0.5;
1845
- u.length = 0;
1846
- for (let x = 0; x < o; x += 1) {
1847
- const T = s[x], _ = s[(x + 1) % o], g = T.y * r, v = _.y * r;
1848
- if (S < g == S < v) continue;
1849
- const y = (S - g) / (v - g);
1850
- u.push((T.x + y * (_.x - T.x)) * n);
1851
- }
1852
- u.sort((x, T) => x - T);
1853
- const k = w * n;
1854
- for (let x = 0; x + 1 < u.length; x += 2) {
1855
- const T = Math.max(0, Math.round(u[x])), _ = Math.min(n, Math.round(u[x + 1]));
1856
- for (let g = T; g < _; g += 1) a[k + g] = e;
1857
- }
1858
- }
1859
- }, mr = (t, s, e, n, r = []) => {
1860
- r.length = 0;
1861
- for (let a = 0; a < e.length; a += 1) {
1862
- const o = s[e[a]];
1863
- if (!o) return;
1864
- r.push(o);
1865
- }
1866
- hn(t, r, n);
1867
- }, it = (t) => t, ot = {
1868
- hair: {
1869
- labels: ["bg", "hair"],
1870
- assetPath: "/assets/xr/models/hair_segmenter.tflite",
1871
- defaultUrl: "https://storage.googleapis.com/mediapipe-models/image_segmenter/hair_segmenter/float32/latest/hair_segmenter.tflite",
1872
- decode: it
1873
- },
1874
- multiclass: {
1875
- labels: ["bg", "hair", "body_skin", "face_skin", "clothes", "others"],
1876
- assetPath: "/assets/xr/models/selfie_multiclass_256x256.tflite",
1877
- defaultUrl: "https://storage.googleapis.com/mediapipe-models/image_segmenter/selfie_multiclass_256x256/float32/latest/selfie_multiclass_256x256.tflite",
1878
- decode: it
1879
- }
1880
- }, mn = (t, s, e) => {
1881
- const n = e.length === t.length ? e : new Uint8Array(t.length);
1882
- for (let r = 0; r < t.length; r += 1) n[r] = s(t[r]);
1883
- return n;
1884
- }, fn = 15, gn = { low: 0.5, medium: 0.75, high: 1 };
1885
- class pn extends J {
1886
- constructor() {
1887
- super();
1888
- d(this, "segmenter", null);
1889
- d(this, "preset", "hair");
1890
- d(this, "quality", "medium");
1891
- d(this, "status", "loading");
1892
- d(this, "error", null);
1893
- d(this, "processingTime", null);
1894
- d(this, "sourceCanvas");
1895
- d(this, "processCanvas");
1896
- d(this, "isProcessing", !1);
1897
- d(this, "mask", un(1, 1, ["bg"]));
1898
- d(this, "node");
1899
- this.node = {
1900
- getMask: () => this.mask,
1901
- getStatus: () => this.status,
1902
- getError: () => this.error
1903
- };
1904
- }
1905
- async initialize(e) {
1906
- this.preset = (e == null ? void 0 : e.preset) ?? "hair", this.quality = (e == null ? void 0 : e.quality) ?? "medium";
1907
- const n = ot[this.preset];
1908
- this.mask.labels = n.labels, this.status = "loading", this.error = null;
1909
- try {
1910
- const r = await j.forVisionTasks(
1911
- new URL("/assets/xr/wasm", U.assetStorageEndpoint).toString()
1912
- ), a = (e == null ? void 0 : e.modelUrl) ?? n.defaultUrl, [o] = await Promise.all([
1913
- Z(a),
1914
- $(r)
1915
- ]);
1916
- this.segmenter = await ht.createFromOptions(r, {
1917
- baseOptions: { modelAssetBuffer: o, delegate: "GPU" },
1918
- outputCategoryMask: !0,
1919
- outputConfidenceMasks: !1,
1920
- runningMode: "VIDEO"
1921
- }), this.status = "ready";
1922
- } catch (r) {
1923
- throw this.status = "error", this.error = r instanceof Error ? r : new Error(String(r)), this.error;
1924
- }
1925
- }
1926
- async run({ sourceCanvas: e, targetFps: n }) {
1927
- e && (this.setTargetFps(n ?? fn), this.isProcessing = !1, this.rafId !== null && (cancelAnimationFrame(this.rafId), this.rafId = null), this.sourceCanvas = e, this.processCanvas = document.createElement("canvas"), this.isProcessing = !0, this.lastInferenceMs = 0, this.rafId = requestAnimationFrame(this.process.bind(this)));
1928
- }
1929
- process() {
1930
- if (this.disposed || this.paused || !this.isProcessing) return;
1931
- const { segmenter: e, sourceCanvas: n, processCanvas: r } = this;
1932
- if (!e || !n || !r || !this.shouldRunInference()) {
1933
- this.rafId = requestAnimationFrame(this.process.bind(this));
1934
- return;
1935
- }
1936
- const a = performance.now(), o = gn[this.quality], c = Math.max(1, Math.round(n.width * o)), l = Math.max(1, Math.round(n.height * o));
1937
- (r.width !== c || r.height !== l) && (r.width = c, r.height = l);
1938
- const h = r.getContext("2d");
1939
- h && h.drawImage(n, 0, 0, c, l);
1940
- try {
1941
- const u = e.segmentForVideo(r, performance.now()).categoryMask;
1942
- if (u) {
1943
- const w = u.getAsUint8Array();
1944
- (this.mask.width !== u.width || this.mask.height !== u.height) && (this.mask.width = u.width, this.mask.height = u.height), this.mask.indices = mn(
1945
- w,
1946
- ot[this.preset].decode,
1947
- this.mask.indices
1948
- ), this.mask.version += 1, u.close();
1949
- }
1950
- this.status === "error" && (this.status = "ready", this.error = null), this.recordInferenceError(null), this.recordDetections(u ? 1 : 0, null);
1951
- } catch (f) {
1952
- this.status = "error", this.error = f instanceof Error ? f : new Error(String(f)), this.recordInferenceError(this.error);
1953
- }
1954
- this.processingTime = performance.now() - a, this.recordInference(a), !(this.disposed || this.paused) && (this.rafId = requestAnimationFrame(this.process.bind(this)));
1955
- }
1956
- resume() {
1957
- this.paused && (super.resume(), this.isProcessing && (this.rafId = requestAnimationFrame(this.process.bind(this))));
1958
- }
1959
- getModelNode() {
1960
- return this.node;
1961
- }
1962
- async getPerformanceData() {
1963
- return { name: this.constructor.name, processingTime: this.processingTime };
1964
- }
1965
- dispose() {
1966
- var e;
1967
- super.dispose(), this.isProcessing = !1;
1968
- try {
1969
- (e = this.segmenter) == null || e.close();
1970
- } catch {
1971
- }
1972
- this.segmenter = null, this.sourceCanvas = void 0, this.processCanvas = void 0;
1973
- }
1974
- }
1975
- const ct = {
1976
- [R.BACKGROUND_SEGMENTATION]: dn,
1977
- [R.SEMANTIC_SEGMENTATION]: pn,
1978
- [R.HAND_TRACKER]: an,
1979
- [R.GESTURE_TRACKER]: sn,
1980
- [R.FACE_TRACKER]: Zs,
1981
- [R.BODY_TRACKER]: Xs,
1982
- [R.HOLISTIC_TRACKER]: nn
1983
- }, yn = async (t) => {
1984
- const s = document.createElement("video");
1985
- s.srcObject = t, s.muted = !0, s.playsInline = !0, s.autoplay = !0, await new Promise((n) => {
1986
- s.onloadedmetadata = () => {
1987
- s.play(), n();
1988
- };
1989
- });
1990
- const e = s;
1991
- return await new Promise((n) => {
1992
- const r = setTimeout(n, 150), a = () => {
1993
- clearTimeout(r), n();
1994
- };
1995
- typeof e.requestVideoFrameCallback == "function" ? e.requestVideoFrameCallback(a) : requestAnimationFrame(() => requestAnimationFrame(() => a()));
1996
- }), s;
1997
- }, wn = (t) => {
1998
- const s = new ft(t);
1999
- return s.colorSpace = fs, s.format = mt, s.minFilter = pe, s.magFilter = pe, s.generateMipmaps = !1, s.needsUpdate = !0, s;
2000
- }, vn = (t, s) => {
2001
- const e = t.videoWidth, n = t.videoHeight;
2002
- e > 0 && n > 0 && (s.width !== e && (s.width = e), s.height !== n && (s.height = n));
2003
- const r = s.getContext("2d", {
2004
- colorSpace: "srgb"
2005
- });
2006
- r.save(), r.scale(-1, 1), r.drawImage(t, -s.width, 0, s.width, s.height), r.restore();
2007
- }, Sn = (t, s, e = 1) => {
2008
- const n = s.getContext("2d", {
2009
- colorSpace: "srgb"
2010
- }), r = Ds({
2011
- source: { width: t.width, height: t.height },
2012
- feed: { width: s.width, height: s.height },
2013
- zoom: e
2014
- });
2015
- r && (n.setTransform(1, 0, 0, 1, 0, 0), n.clearRect(0, 0, s.width, s.height), n.drawImage(
2016
- t,
2017
- 0,
2018
- 0,
2019
- t.width,
2020
- t.height,
2021
- r.offsetX,
2022
- r.offsetY,
2023
- r.drawWidth,
2024
- r.drawHeight
2025
- ));
2026
- }, Mn = (t, s, e) => {
2027
- const n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new WeakSet();
2028
- let a = !1;
2029
- const o = (g, v) => {
2030
- const y = t.getSnapshot().modelErrors;
2031
- if (v === null && !y.has(g)) return;
2032
- const C = new Map(y);
2033
- v === null ? C.delete(g) : C.set(g, { model: g, error: v, at: performance.now() }), t.set({ modelErrors: C });
2034
- }, c = (g, v) => {
2035
- var y;
2036
- try {
2037
- (y = v.dispose) == null || y.call(v);
2038
- } catch (C) {
2039
- console.warn(`[xr-sdk registry] dispose threw for ${g}`, C);
2040
- }
2041
- };
2042
- return {
2043
- acquire: async (g, v, y) => {
2044
- let C = n.get(g);
2045
- if (C)
2046
- return C.refs.add(v), C.activeRefs.add(v), C.initPromise;
2047
- const N = s[g];
2048
- if (!N)
2049
- throw new Error(`Invalid model: ${g}`);
2050
- const E = new N(), V = /* @__PURE__ */ new Set([v]), q = /* @__PURE__ */ new Set([v]);
2051
- o(g, null);
2052
- const L = (async () => {
2053
- await E.initialize(y);
2054
- const A = n.get(g);
2055
- if (!A || A.model !== E || A.refs.size === 0)
2056
- return c(g, E), E;
2057
- e && await e(g, E);
2058
- const W = n.get(g);
2059
- return W && W.refs.size > 0 && (r.add(E), t.setPipeline((K) => K.set(g, E))), E;
2060
- })();
2061
- return C = { model: E, refs: V, activeRefs: q, initPromise: L, options: y }, n.set(g, C), L.catch((A) => {
2062
- n.get(g) === C && (n.delete(g), t.setPipeline((K) => K.delete(g)), o(g, A instanceof Error ? A : new Error(String(A)))), c(g, E);
2063
- }), L;
2064
- },
2065
- release: (g, v) => {
2066
- const y = n.get(g);
2067
- y && (y.refs.delete(v), y.activeRefs.delete(v) && y.refs.size > 0 && y.activeRefs.size === 0 && y.model.pause(), !(y.refs.size > 0) && (n.delete(g), c(g, y.model), t.setPipeline((C) => C.delete(g))));
2068
- },
2069
- setActive: (g, v, y) => {
2070
- const C = n.get(g);
2071
- if (!C || !C.refs.has(v)) return;
2072
- const N = C.activeRefs.size > 0;
2073
- y ? C.activeRefs.add(v) : C.activeRefs.delete(v);
2074
- const E = C.activeRefs.size > 0;
2075
- N !== E && (E && !a ? C.model.resume() : C.model.pause());
2076
- },
2077
- suspendAll: () => {
2078
- a = !0;
2079
- for (const g of n.values())
2080
- g.model.pause();
2081
- },
2082
- resumeActive: () => {
2083
- a = !1;
2084
- for (const g of n.values())
2085
- g.activeRefs.size > 0 && g.model.resume();
2086
- },
2087
- get: (g) => {
2088
- var v;
2089
- return (v = n.get(g)) == null ? void 0 : v.model;
2090
- },
2091
- getOptions: (g) => {
2092
- var v;
2093
- return (v = n.get(g)) == null ? void 0 : v.options;
2094
- },
2095
- releaseAll: () => {
2096
- for (const g of Array.from(n.keys())) {
2097
- const v = n.get(g);
2098
- v && (v.refs.clear(), n.delete(g), c(g, v.model));
2099
- }
2100
- t.setPipeline((g) => g.clear());
2101
- },
2102
- getState: (g) => {
2103
- const v = n.get(g);
2104
- return v ? r.has(v.model) ? "ready" : "initializing" : t.getSnapshot().modelErrors.has(g) ? "error" : "idle";
2105
- },
2106
- getOwners: (g) => {
2107
- const v = n.get(g);
2108
- return {
2109
- refs: v ? Array.from(v.refs) : [],
2110
- active: v ? Array.from(v.activeRefs) : []
2111
- };
2112
- }
2113
- };
2114
- }, kn = {
2115
- lifecycle: "idle",
2116
- ready: !1,
2117
- error: void 0,
2118
- cameraTexture: void 0,
2119
- renderWidth: 0,
2120
- renderHeight: 0,
2121
- source: void 0,
2122
- sourceKind: void 0,
2123
- cameraFacing: null,
2124
- cameraDeviceId: null,
2125
- orientation: { type: "portrait", angle: 0 },
2126
- quality: null,
2127
- qualityConfig: null,
2128
- sourceWidth: 0,
2129
- sourceHeight: 0,
2130
- cameraZoom: 1.2,
2131
- pipeline: /* @__PURE__ */ new Map(),
2132
- modelErrors: /* @__PURE__ */ new Map(),
2133
- cameraPermission: "unknown",
2134
- cameraPermissionReason: null,
2135
- feedFrames: 0
2136
- }, Cn = () => {
2137
- let t = { ...kn, pipeline: /* @__PURE__ */ new Map(), modelErrors: /* @__PURE__ */ new Map() };
2138
- const s = /* @__PURE__ */ new Set(), e = () => {
2139
- s.forEach((n) => n());
2140
- };
2141
- return {
2142
- getSnapshot: () => t,
2143
- set: (n) => {
2144
- let r = !1;
2145
- for (const a of Object.keys(n))
2146
- if (n[a] !== t[a]) {
2147
- r = !0;
2148
- break;
2149
- }
2150
- r && (t = { ...t, ...n }, e());
2151
- },
2152
- setPipeline: (n) => {
2153
- const r = new Map(t.pipeline);
2154
- return n(r), t = { ...t, pipeline: r }, e(), r;
2155
- },
2156
- subscribe: (n) => (s.add(n), () => {
2157
- s.delete(n);
2158
- })
2159
- };
2160
- }, lt = (t, s) => s ?? t === "user", xn = ({
2161
- renderHeight: t,
2162
- renderWidth: s,
2163
- videoHeight: e,
2164
- videoWidth: n
2165
- }) => ({
2166
- height: t || e,
2167
- width: s || n
2168
- }), bn = (t, s) => {
2169
- const e = new Hs({ verbose: !0 }), n = Cn();
2170
- n.set({ cameraZoom: (t == null ? void 0 : t.cameraZoom) ?? 1.2 });
2171
- let r = s, a = t;
2172
- const o = (i) => {
2173
- var p;
2174
- const m = (p = z.getOptions(i)) == null ? void 0 : p.targetFps;
2175
- return typeof m == "number" ? m : a == null ? void 0 : a.targetFps;
2176
- };
2177
- let c, l, h, f, u, w, S, k, x, T, _, g, v = !1, y = !1, C = !1, N = 0, E, V, q, L = !1, A = 0, W = /* @__PURE__ */ new WeakSet();
2178
- const K = /* @__PURE__ */ new Set(), me = (i) => {
2179
- const m = n.getSnapshot().cameraTexture;
2180
- m && m.dispose();
2181
- const p = wn(i);
2182
- return n.set({ cameraTexture: p }), p;
2183
- }, we = async (i, m) => {
2184
- if (W.has(m) || n.getSnapshot().lifecycle !== "running" || !u) return;
2185
- W.add(m);
2186
- const p = A;
2187
- try {
2188
- await m.run({
2189
- sourceCanvas: u,
2190
- renderWidth: n.getSnapshot().renderWidth,
2191
- renderHeight: n.getSnapshot().renderHeight,
2192
- getSource: () => n.getSnapshot().sourceKind,
2193
- targetFps: o(i),
2194
- analysisScale: a == null ? void 0 : a.analysisScale
2195
- }), L && (await new Promise((M) => requestAnimationFrame(() => M())), await new Promise((M) => requestAnimationFrame(() => M())), L && A === p && z.suspendAll());
2196
- } catch (M) {
2197
- throw W.delete(m), M;
2198
- }
2199
- }, z = Mn(n, ct, (i, m) => we(i, m));
2200
- n.subscribe(() => {
2201
- if (n.getSnapshot().lifecycle !== "running") return;
2202
- const i = n.getSnapshot().pipeline;
2203
- for (const [m, p] of i.entries())
2204
- W.has(p) || we(m, p);
2205
- });
2206
- const Ne = () => {
2207
- g !== void 0 && (cancelAnimationFrame(g), g = void 0);
2208
- }, ee = () => {
2209
- if (Ne(), E == null || E(), E = void 0, l) {
2210
- try {
2211
- l.pause();
2212
- } catch {
2213
- }
2214
- try {
2215
- l.srcObject = null;
2216
- } catch {
2217
- }
2218
- l = void 0;
2219
- }
2220
- if (h) {
2221
- try {
2222
- h.getTracks().forEach((i) => i.stop());
2223
- } catch {
2224
- }
2225
- h = void 0;
2226
- }
2227
- }, ve = () => {
2228
- if (v || !l || !f || !u) return;
2229
- const i = typeof window < "u" ? window.__xr_debugger_metrics : void 0;
2230
- if (i != null && i.trackCameraFrame && i.trackCameraFrame(), He(n.getSnapshot().sourceKind))
2231
- vn(l, f);
2232
- else {
2233
- const b = f.getContext("2d");
2234
- if (!b) return;
2235
- const P = l.videoWidth, D = l.videoHeight;
2236
- f.width !== P && (f.width = P), f.height !== D && (f.height = D), b.setTransform(1, 0, 0, 1, 0, 0), b.clearRect(0, 0, P, D), b.drawImage(l, 0, 0, P, D);
2237
- }
2238
- Sn(f, u, (a == null ? void 0 : a.cameraZoom) ?? 1.2);
2239
- const p = n.getSnapshot();
2240
- (p.sourceWidth !== l.videoWidth || p.sourceHeight !== l.videoHeight) && n.set({ sourceWidth: l.videoWidth, sourceHeight: l.videoHeight }), N += 1, N % 10 === 0 && n.set({ feedFrames: N });
2241
- const M = n.getSnapshot().cameraTexture;
2242
- M && (M.needsUpdate = !0);
2243
- }, Se = () => {
2244
- if (!l || !f || !u) return;
2245
- if (L) {
2246
- ve();
2247
- return;
2248
- }
2249
- const i = () => {
2250
- g = requestAnimationFrame(i), ve();
2251
- };
2252
- g = requestAnimationFrame(i);
2253
- }, Rt = async (i, m) => {
2254
- if (i.source === F.WEBCAM)
2255
- try {
2256
- const p = a != null && a.camRes && a.camRes > 0 ? a.camRes : 960;
2257
- n.set({ cameraPermission: "requesting", cameraPermissionReason: null });
2258
- const M = i.deviceId ? { deviceId: { exact: i.deviceId } } : { facingMode: { ideal: i.facingMode ?? "user" } }, b = {
2259
- frameRate: { min: 24, ideal: 30, max: 60 },
2260
- width: { ideal: p },
2261
- ...M
2262
- };
2263
- let P;
2264
- try {
2265
- P = await navigator.mediaDevices.getUserMedia({ video: b });
2266
- } catch (D) {
2267
- if (!(D instanceof DOMException && D.name === "OverconstrainedError")) throw D;
2268
- P = await navigator.mediaDevices.getUserMedia({
2269
- video: { frameRate: { ideal: 30 }, width: { ideal: p }, ...M }
2270
- });
2271
- }
2272
- return m === A && n.set({ cameraPermission: "granted", cameraPermissionReason: null }), P;
2273
- } catch (p) {
2274
- const M = vt(p), b = rt[M], P = await St(), D = Mt(M, P.state);
2275
- throw m === A && n.set({
2276
- error: { error: "PermissionError", message: b, reason: M },
2277
- cameraPermission: D.state,
2278
- cameraPermissionReason: D.reason
2279
- }), new O(p instanceof Error ? p.message : "getUserMedia failed");
2280
- }
2281
- return i.stream;
2282
- }, Be = (i) => {
2283
- const { lifecycle: m } = n.getSnapshot();
2284
- m === "idle" || m === "stopped" || v || (ee(), z.suspendAll(), A += 1, c = void 0, n.set({
2285
- lifecycle: "stopped",
2286
- ready: !1,
2287
- error: { error: "PermissionError", message: rt[i], reason: i },
2288
- cameraPermission: i === "permission-denied" ? "blocked" : "unavailable",
2289
- cameraPermissionReason: wt(i)
2290
- }), e.log("XR session stopped: camera lost.", i));
2291
- }, Ft = (i) => {
2292
- var M;
2293
- E == null || E();
2294
- const m = ((M = i.getVideoTracks) == null ? void 0 : M.call(i)) ?? [], p = () => {
2295
- h === i && Be("camera-lost");
2296
- };
2297
- m.forEach((b) => {
2298
- var P;
2299
- return (P = b.addEventListener) == null ? void 0 : P.call(b, "ended", p);
2300
- }), E = () => {
2301
- m.forEach((b) => {
2302
- var P;
2303
- return (P = b.removeEventListener) == null ? void 0 : P.call(b, "ended", p);
2304
- });
2305
- };
2306
- }, It = async () => {
2307
- if (V || typeof navigator > "u") return;
2308
- const i = navigator.permissions;
2309
- if (i != null && i.query)
2310
- try {
2311
- const m = await i.query({ name: "camera" });
2312
- if (y) return;
2313
- V = m, q = () => {
2314
- m.state === "denied" && (c == null ? void 0 : c.source) === F.WEBCAM && Be("permission-denied");
2315
- }, m.addEventListener("change", q);
2316
- } catch {
2317
- }
2318
- }, _t = () => {
2319
- var i;
2320
- V && q && ((i = V.removeEventListener) == null || i.call(V, "change", q)), V = void 0, q = void 0;
2321
- }, Me = async (i) => {
2322
- var Ze, fe, $e;
2323
- const m = A, p = await Rt(i, m);
2324
- if (m !== A)
2325
- throw p.getTracks().forEach((re) => re.stop()), new O("Media source superseded by a newer bind");
2326
- h = p, Ft(p);
2327
- const M = await yn(p);
2328
- if (m !== A || y)
2329
- throw p.getTracks().forEach((re) => re.stop()), new O("Media source superseded by a newer bind");
2330
- l = M, f = new OffscreenCanvas(M.videoWidth, M.videoHeight);
2331
- const { renderWidth: b, renderHeight: P } = n.getSnapshot(), D = xn({
2332
- renderWidth: b,
2333
- renderHeight: P,
2334
- videoWidth: M.videoWidth,
2335
- videoHeight: M.videoHeight
2336
- });
2337
- u ? (u.width !== D.width || u.height !== D.height) && (u.width = D.width, u.height = D.height, me(u)) : (u = new OffscreenCanvas(D.width, D.height), me(u));
2338
- const je = i.source === F.STREAM ? i.static === !0 : !1;
2339
- L = je;
2340
- const ne = ($e = (fe = (Ze = p.getVideoTracks) == null ? void 0 : Ze.call(p)[0]) == null ? void 0 : fe.getSettings) == null ? void 0 : $e.call(fe), Te = ne == null ? void 0 : ne.facingMode, ss = Te === "user" || Te === "environment" ? Te : null;
2341
- if (i.source === F.WEBCAM) {
2342
- const re = ss ?? i.facingMode ?? "user", Je = lt(re, i.mirrored);
2343
- c = {
2344
- source: F.WEBCAM,
2345
- sourceKind: Je ? "webcam" : "rear-camera",
2346
- facingMode: re,
2347
- deviceId: i.deviceId,
2348
- mirrored: Je
2349
- };
2350
- } else
2351
- c = {
2352
- source: F.STREAM,
2353
- stream: i.stream,
2354
- static: je,
2355
- sourceKind: i.sourceKind ?? "webcam"
2356
- };
2357
- n.set({
2358
- source: i.source,
2359
- sourceKind: c.sourceKind,
2360
- cameraFacing: c.source === F.WEBCAM ? c.facingMode : null,
2361
- cameraDeviceId: c.source === F.WEBCAM ? (ne == null ? void 0 : ne.deviceId) ?? c.deviceId ?? null : null,
2362
- sourceWidth: M.videoWidth,
2363
- sourceHeight: M.videoHeight,
2364
- error: void 0
2365
- }), i.source === F.WEBCAM && It();
2366
- }, ke = async (i) => {
2367
- const m = i.sourceKind ?? "webcam";
2368
- u = i.canvas;
2369
- const p = me(u);
2370
- n.set({
2371
- cameraTexture: p,
2372
- source: F.CANVAS,
2373
- sourceKind: m,
2374
- cameraFacing: null,
2375
- cameraDeviceId: null,
2376
- renderWidth: u.width,
2377
- renderHeight: u.height,
2378
- error: void 0
2379
- }), c = {
2380
- source: F.CANVAS,
2381
- canvas: i.canvas,
2382
- sourceKind: m
2383
- };
2384
- }, Pt = (i, m) => {
2385
- if (!m || i.source !== m.source) return !1;
2386
- if (i.source === F.STREAM && m.source === F.STREAM)
2387
- return i.stream === m.stream && (i.sourceKind ?? "webcam") === m.sourceKind;
2388
- if (i.source === F.WEBCAM && m.source === F.WEBCAM) {
2389
- const p = i.facingMode ?? "user";
2390
- return p === m.facingMode && i.deviceId === m.deviceId && lt(p, i.mirrored) === m.mirrored;
2391
- }
2392
- return !1;
2393
- }, ze = async () => {
2394
- if (!u) return;
2395
- const i = A, m = n.getSnapshot().pipeline;
2396
- for (const [, p] of m.entries())
2397
- p.resume();
2398
- await new Promise((p) => requestAnimationFrame(() => p())), await new Promise((p) => requestAnimationFrame(() => p())), L && A === i && z.suspendAll();
2399
- }, Lt = (i, m) => !m || m.source !== F.CANVAS ? !1 : i.canvas === m.canvas && (i.sourceKind ?? "webcam") === m.sourceKind, Ce = async (i) => {
2400
- const m = i.source;
2401
- if (m !== F.WEBCAM && m !== F.STREAM)
2402
- throw new O(`Invalid media source: ${String(m)}`);
2403
- if (y) throw new O("session.setMediaSource() called after the provider unmounted");
2404
- if (Pt(i, c)) {
2405
- e.log("Media source unchanged, skipping rebind.");
2406
- return;
2407
- }
2408
- A += 1;
2409
- const { lifecycle: p } = n.getSnapshot();
2410
- if (p === "idle" || p === "stopped") {
2411
- await Me(i), n.set({ lifecycle: "media-bound" }), e.log("Media source set to:", i.source);
2412
- return;
2413
- }
2414
- if (p === "media-bound") {
2415
- ee(), await Me(i), e.log("Media source rebound to:", i.source);
2416
- return;
2417
- }
2418
- const M = p === "paused";
2419
- v = !0, await new Promise((b) => requestAnimationFrame(() => b())), ee();
2420
- try {
2421
- await Me(i);
2422
- } finally {
2423
- v = !1;
2424
- }
2425
- if (M) {
2426
- l == null || l.pause(), e.log("Media source swapped (paused) to:", i.source);
2427
- return;
2428
- }
2429
- Se(), L ? await ze() : z.resumeActive(), e.log("Media source swapped to:", i.source);
2430
- }, Dt = async (i) => {
2431
- if (y) throw new O("session.setFrameSource() called after the provider unmounted");
2432
- if (Lt(i, c)) {
2433
- e.log("Frame source unchanged, skipping rebind.");
2434
- return;
2435
- }
2436
- A += 1;
2437
- const { lifecycle: m } = n.getSnapshot();
2438
- if (m === "idle" || m === "stopped") {
2439
- await ke(i), n.set({ lifecycle: "media-bound" }), e.log("Frame source set to canvas.");
2440
- return;
2441
- }
2442
- if (m === "media-bound") {
2443
- ee(), await ke(i), e.log("Frame source rebound to canvas.");
2444
- return;
2445
- }
2446
- v = !0, await new Promise((p) => requestAnimationFrame(() => p())), ee();
2447
- try {
2448
- await ke(i);
2449
- } finally {
2450
- v = !1;
2451
- }
2452
- e.log("Frame source swapped to canvas.");
2453
- }, We = async () => {
2454
- if (y) throw new O("session.start() called after the provider unmounted");
2455
- const { lifecycle: i } = n.getSnapshot();
2456
- if (i === "running") return;
2457
- if (i === "paused") {
2458
- await xe();
2459
- return;
2460
- }
2461
- if (i === "idle")
2462
- throw new O("session.start() called before setMediaSource — call setMediaSource first");
2463
- if (!u)
2464
- throw new O("session.start(): media source not bound");
2465
- const m = (c == null ? void 0 : c.source) === F.CANVAS;
2466
- if (!m && (!l || !f))
2467
- throw i === "stopped" ? new O(
2468
- "session.start() called from stopped state without a media source — call setMediaSource first"
2469
- ) : new O("session.start(): media source not bound");
2470
- m || Se(), z.resumeActive(), n.set({ lifecycle: "running" }), await new Promise((M) => requestAnimationFrame(() => M()));
2471
- const p = n.getSnapshot().pipeline;
2472
- for (const [M, b] of p.entries())
2473
- await we(M, b);
2474
- n.set({ ready: !0 }), e.log("XR session started.");
2475
- }, Ve = () => {
2476
- if (n.getSnapshot().lifecycle === "running") {
2477
- Ne(), z.suspendAll();
2478
- try {
2479
- l == null || l.pause();
2480
- } catch {
2481
- }
2482
- n.set({ lifecycle: "paused" }), e.log("XR session paused.");
2483
- }
2484
- }, xe = async () => {
2485
- if (y) throw new O("session.resume() called after the provider unmounted");
2486
- n.getSnapshot().lifecycle === "paused" && (C = !1, l && l.play().catch(() => {
2487
- }), (c == null ? void 0 : c.source) !== F.CANVAS && Se(), n.set({ lifecycle: "running" }), L ? await ze() : z.resumeActive(), e.log("XR session resumed."));
2488
- }, Ot = async (i = {}) => {
2489
- await Ce({ source: F.WEBCAM, ...i });
2490
- const { lifecycle: m } = n.getSnapshot();
2491
- return (m === "media-bound" || m === "stopped") && await We(), n.getSnapshot().cameraFacing ?? i.facingMode ?? "user";
2492
- }, qe = async () => {
2493
- const { lifecycle: i } = n.getSnapshot();
2494
- i === "stopped" || i === "idle" || (C = !1, ee(), z.suspendAll(), c = void 0, n.set({ lifecycle: "stopped", ready: !1 }), e.log("XR session stopped."));
2495
- }, Ke = async () => {
2496
- await qe(), z.releaseAll(), K.clear();
2497
- const i = n.getSnapshot().cameraTexture;
2498
- i && i.dispose(), W = /* @__PURE__ */ new WeakSet(), c = void 0, A += 1, u = void 0, f = void 0, S = void 0, L = !1, _t(), n.set({
2499
- lifecycle: "idle",
2500
- cameraTexture: void 0,
2501
- source: void 0,
2502
- sourceKind: void 0,
2503
- cameraFacing: null,
2504
- cameraDeviceId: null,
2505
- error: void 0,
2506
- modelErrors: /* @__PURE__ */ new Map(),
2507
- cameraPermission: "unknown",
2508
- cameraPermissionReason: null
2509
- }), e.log("XR session reset.");
2510
- }, Ht = async () => {
2511
- y || (y = !0, se == null || se(), se = void 0, te == null || te(), te = void 0, await Ke(), e.log("XR session disposed."));
2512
- }, Ut = () => {
2513
- y && (y = !1, Qe(), Ye(), e.log("XR session re-armed."));
2514
- }, Nt = () => y, Bt = async (i) => {
2515
- const m = "legacy:registerXRPipeline", p = [];
2516
- await Promise.all(
2517
- i.map(async (M) => {
2518
- const { model: b } = M;
2519
- if (!ct[b])
2520
- throw new O(`Invalid model: ${b}`);
2521
- K.has(b) || p.push(b);
2522
- const P = "options" in M ? M.options : void 0;
2523
- await z.acquire(b, m, P);
2524
- })
2525
- ), p.length > 0 && (p.forEach((M) => K.add(M)), e.log("XR pipeline registered."));
2526
- }, zt = (i) => {
2527
- const m = z.get(i);
2528
- if (!m)
2529
- throw new O(`Model ${i} is not registered in the pipeline`);
2530
- return m.getModelNode();
2531
- }, Ge = async (i, m) => {
2532
- i <= 0 || m <= 0 || (n.set({ renderWidth: i, renderHeight: m }), u && (u.width !== i || u.height !== m) && (u.width = i, u.height = m, me(u), L && ve()), e.log(`Source canvas set. Render size: ${i}x${m}`));
2533
- }, Wt = async (i) => {
2534
- var b;
2535
- w = i;
2536
- const m = (b = i.getBoundingClientRect) == null ? void 0 : b.call(i), p = m && m.width > 0 ? Math.round(m.width) : i.clientWidth, M = m && m.height > 0 ? Math.round(m.height) : i.clientHeight;
2537
- await Ge(p, M);
2538
- }, Vt = (i) => {
2539
- S = i;
2540
- }, be = () => w && k && x && T ? w : S, qt = (i) => {
2541
- k = i.renderer, x = i.scene, T = i.camera, _ = i.renderFrame;
2542
- }, Xe = () => {
2543
- if (!k || !x || !T)
2544
- throw new O(
2545
- "XR frame render requested before the R3F state was bound — make sure <XRScene> is mounted"
2546
- );
2547
- _ ? _() : k.render(x, T);
2548
- }, Kt = () => {
2549
- const i = w;
2550
- if (i && be() === i)
2551
- return Xe(), i.toDataURL("image/png");
2552
- const m = be();
2553
- if (m) return m.toDataURL("image/png");
2554
- throw new O(
2555
- "session.captureFrame() called before an XRScene or XRMediaSurface capture target was bound"
2556
- );
2557
- }, Gt = (i = 30) => {
2558
- const m = be();
2559
- if (!(m != null && m.captureStream))
2560
- throw new O(
2561
- "session.captureStream() called before an XRScene or XRMediaSurface capture target was bound"
2562
- );
2563
- return m.captureStream(i);
2564
- }, Xt = () => l, Yt = () => u ?? null, Qt = (i) => {
2565
- if (a = i, n.set({ cameraZoom: (i == null ? void 0 : i.cameraZoom) ?? 1.2 }), n.getSnapshot().lifecycle !== "running" || !u) return;
2566
- const m = n.getSnapshot().pipeline;
2567
- for (const [p, M] of m.entries())
2568
- M.run({
2569
- sourceCanvas: u,
2570
- renderWidth: n.getSnapshot().renderWidth,
2571
- renderHeight: n.getSnapshot().renderHeight,
2572
- getSource: () => n.getSnapshot().sourceKind,
2573
- targetFps: o(p),
2574
- analysisScale: a == null ? void 0 : a.analysisScale
2575
- });
2576
- }, jt = () => a, Zt = async () => {
2577
- if (!c || c.source !== F.WEBCAM) return;
2578
- const { facingMode: i, deviceId: m, mirrored: p } = c;
2579
- c = void 0, await Ce({ source: F.WEBCAM, facingMode: i, deviceId: m, mirrored: p });
2580
- }, $t = (i) => {
2581
- n.set({ quality: i });
2582
- }, Jt = (i) => {
2583
- n.set({ qualityConfig: i });
2584
- }, es = (i) => {
2585
- r = i;
2586
- }, ts = () => {
2587
- var b;
2588
- if (typeof window > "u") return { type: "portrait", angle: 0 };
2589
- const i = (b = window.screen) == null ? void 0 : b.orientation, m = (i == null ? void 0 : i.angle) ?? 0, p = m === 90 || m === 180 || m === 270 ? m : 0;
2590
- return { type: i != null && i.type ? i.type.startsWith("landscape") ? "landscape" : "portrait" : window.innerWidth > window.innerHeight ? "landscape" : "portrait", angle: p };
2591
- }, oe = () => {
2592
- const i = ts(), m = n.getSnapshot().orientation, p = m.type !== i.type || m.angle !== i.angle ? { orientation: i } : {};
2593
- l && l.videoWidth > 0 && (p.sourceWidth = l.videoWidth, p.sourceHeight = l.videoHeight), Object.keys(p).length && n.set(p);
2594
- };
2595
- let te;
2596
- const Ye = () => {
2597
- var m, p, M;
2598
- if (te || typeof window > "u") return;
2599
- const i = (m = window.screen) == null ? void 0 : m.orientation;
2600
- (p = i == null ? void 0 : i.addEventListener) == null || p.call(i, "change", oe), (M = window.addEventListener) == null || M.call(window, "resize", oe), te = () => {
2601
- var b, P;
2602
- (b = i == null ? void 0 : i.removeEventListener) == null || b.call(i, "change", oe), (P = window.removeEventListener) == null || P.call(window, "resize", oe);
2603
- }, oe();
2604
- };
2605
- let se;
2606
- const Qe = () => {
2607
- if (se || typeof document > "u" || typeof document.addEventListener != "function") return;
2608
- const i = () => {
2609
- if (!y) {
2610
- if (document.hidden) {
2611
- r != null && r.pauseWhenHidden && n.getSnapshot().lifecycle === "running" && (Ve(), C = !0);
2612
- return;
2613
- }
2614
- if (C && n.getSnapshot().lifecycle === "paused") {
2615
- xe();
2616
- return;
2617
- }
2618
- n.getSnapshot().lifecycle === "running" && (l != null && l.paused) && l.play().catch(() => {
2619
- });
2620
- }
2621
- };
2622
- document.addEventListener("visibilitychange", i), se = () => document.removeEventListener("visibilitychange", i);
2623
- };
2624
- return Qe(), Ye(), {
2625
- store: n,
2626
- registry: z,
2627
- setMediaSource: Ce,
2628
- start: We,
2629
- stop: qe,
2630
- reset: Ke,
2631
- pause: Ve,
2632
- resume: xe,
2633
- switchCamera: Ot,
2634
- dispose: Ht,
2635
- rearm: Ut,
2636
- isDisposed: Nt,
2637
- setFrameSource: Dt,
2638
- registerXRPipeline: Bt,
2639
- getModelNode: zt,
2640
- captureFrame: Kt,
2641
- captureStream: Gt,
2642
- getInputFrame: Yt,
2643
- _setRenderTarget: Wt,
2644
- _setCaptureTarget: Vt,
2645
- _setRenderSize: Ge,
2646
- _setR3FState: qt,
2647
- _renderFrame: Xe,
2648
- _getVideoElement: Xt,
2649
- _setPerf: Qt,
2650
- _setLifecycle: es,
2651
- _rebindMedia: Zt,
2652
- _setQuality: $t,
2653
- _setQualityConfig: Jt,
2654
- _getPerf: jt
2655
- };
2656
- }, Tn = (t, s) => {
2657
- const e = ie(t), n = ie(s), r = he(
2658
- () => bn(e.current, n.current),
2659
- []
2660
- ), a = JSON.stringify(s ?? {});
2661
- ce(() => {
2662
- r._setLifecycle(s);
2663
- }, [r, a]), ce(() => (r.rearm(), () => void r.dispose()), [r]);
2664
- const o = JSON.stringify(t ?? {});
2665
- return ce(() => {
2666
- r._setPerf(t);
2667
- }, [r, o]), r;
2668
- }, _e = /* @__PURE__ */ new Map(), En = () => ({
2669
- register: (t, s) => {
2670
- s ? _e.set(t, s) : _e.delete(t);
2671
- },
2672
- resolve: (t) => t ? _e.get(t) ?? null : null
2673
- }), Ct = En(), xt = ut(null), An = ({ children: t }) => {
2674
- const s = ie(/* @__PURE__ */ new Map()), e = tt((a, o) => {
2675
- o ? s.current.set(a, o) : s.current.delete(a);
2676
- }, []), n = tt(
2677
- (a) => a ? s.current.get(a) ?? null : null,
2678
- []
2679
- ), r = he(() => ({ register: e, resolve: n }), [e, n]);
2680
- return is(xt.Provider, { value: r }, t);
2681
- }, bt = () => De(xt) ?? Ct, fr = () => bt().register, gr = () => bt().resolve;
2682
- Ct.register;
2683
- const Rn = {
2684
- [R.FACE_TRACKER]: "face",
2685
- [R.HAND_TRACKER]: "hand",
2686
- [R.GESTURE_TRACKER]: "gesture",
2687
- [R.BODY_TRACKER]: "body",
2688
- [R.HOLISTIC_TRACKER]: "holistic",
2689
- [R.BACKGROUND_SEGMENTATION]: "segmentation",
2690
- [R.SEMANTIC_SEGMENTATION]: "semantic-seg"
2691
- }, dt = Object.values(R), Fn = (t, s) => {
2692
- var n;
2693
- const e = (n = t.registry.getOptions(s)) == null ? void 0 : n.targetFps;
2694
- return typeof e == "number" ? e : null;
2695
- }, Le = (t, s, e, n = performance.now()) => {
2696
- const r = t.store.getSnapshot(), a = e ? n - e.sampledAt : 0, o = e && a > 0 ? Math.max(0, (r.feedFrames - e.feedFrames) * 1e3 / a) : 0, c = r.lifecycle === "running", l = s.map((f) => {
2697
- var T;
2698
- const u = t.registry.getState(f), w = t.store.getSnapshot().pipeline.get(f), S = ((T = r.modelErrors.get(f)) == null ? void 0 : T.error) ?? null, k = (w == null ? void 0 : w.getDiagnostics()) ?? {
2699
- inferenceMs: null,
2700
- inferenceFps: 0,
2701
- inferences: 0,
2702
- skippedFrames: 0,
2703
- detections: null,
2704
- confidence: null,
2705
- status: S ? "error" : "ready",
2706
- error: S,
2707
- paused: !1,
2708
- disposed: !1
2709
- };
2710
- let x;
2711
- return u === "error" || k.status === "error" ? x = "error" : u === "idle" ? x = "unavailable" : u === "initializing" ? x = "loading" : k.paused || !c ? x = "paused" : x = "ready", {
2712
- ...k,
2713
- error: k.error ?? S,
2714
- model: f,
2715
- label: Rn[f] ?? f,
2716
- state: x,
2717
- targetFps: Fn(t, f),
2718
- owners: t.registry.getOwners(f)
2719
- };
2720
- }), h = r.quality;
2721
- return {
2722
- quality: h ? {
2723
- tier: h.decision.tier.name,
2724
- index: h.index,
2725
- locked: h.locked,
2726
- reason: h.decision.reason
2727
- } : null,
2728
- session: {
2729
- lifecycle: r.lifecycle,
2730
- ready: r.ready,
2731
- error: r.error,
2732
- source: r.source,
2733
- sourceKind: r.sourceKind,
2734
- sourceWidth: r.sourceWidth,
2735
- sourceHeight: r.sourceHeight,
2736
- renderWidth: r.renderWidth,
2737
- renderHeight: r.renderHeight,
2738
- feedFps: o,
2739
- feedFrames: r.feedFrames
2740
- },
2741
- models: l,
2742
- inferenceMsTotal: l.reduce(
2743
- (f, u) => f + (u.state === "ready" ? u.inferenceMs ?? 0 : 0),
2744
- 0
2745
- ),
2746
- sampledAt: n
2747
- };
2748
- }, pr = (t = {}) => {
2749
- const { intervalMs: s = 250, enabled: e = !0 } = t, { session: n } = At(), r = (t.models ?? dt).join("|"), a = he(
2750
- () => t.models && t.models.length ? t.models : dt,
2751
- // modelsKey captures the list by value.
2752
- // eslint-disable-next-line react-hooks/exhaustive-deps
2753
- [r]
2754
- ), o = ie(null), [c, l] = os(
2755
- () => Le(n, a, null)
2756
- );
2757
- return ce(() => {
2758
- if (!e) return;
2759
- const h = () => {
2760
- const u = Le(n, a, o.current);
2761
- o.current = { feedFrames: u.session.feedFrames, sampledAt: u.sampledAt }, l(u);
2762
- };
2763
- h();
2764
- const f = window.setInterval(h, Math.max(50, s));
2765
- return () => window.clearInterval(f);
2766
- }, [n, a, s, e]), c;
2767
- }, In = [
2768
- { name: "high", targetFps: 30, renderScale: 1, analysisScale: 1, camRes: 960 },
2769
- { name: "medium", targetFps: 24, renderScale: 0.8, analysisScale: 0.85, camRes: 720 },
2770
- { name: "low", targetFps: 15, renderScale: 0.6, analysisScale: 0.7, camRes: 640 }
2771
- ], Q = {
2772
- maxFrameMs: 1e3 / 24,
2773
- maxInferenceMs: 24,
2774
- maxMemoryMb: null,
2775
- sampleMs: 1e3,
2776
- downgradeAfter: 2,
2777
- upgradeAfter: 6,
2778
- upgradeHeadroom: 0.75,
2779
- cooldownMs: 4e3
2780
- }, Tt = {
2781
- frameMs: null,
2782
- fps: null,
2783
- inferenceMs: null,
2784
- feedFps: null,
2785
- memoryMb: null,
2786
- deviceMemoryGb: null,
2787
- hardwareConcurrency: null,
2788
- thermal: "unknown"
2789
- }, ue = (t, s, e) => Math.min(e, Math.max(s, t)), H = (t, s) => typeof t == "number" && Number.isFinite(t) ? t : s, _n = (t, s) => ({
2790
- name: typeof t.name == "string" && t.name ? t.name : `tier-${s}`,
2791
- ...H(t.targetFps, NaN) > 0 ? { targetFps: H(t.targetFps, 0) } : {},
2792
- ...H(t.renderScale, NaN) > 0 ? { renderScale: ue(H(t.renderScale, 1), 0.25, 1) } : {},
2793
- ...H(t.analysisScale, NaN) > 0 ? { analysisScale: ue(H(t.analysisScale, 1), 0.25, 1) } : {},
2794
- ...H(t.camRes, NaN) > 0 ? { camRes: Math.round(H(t.camRes, 0)) } : {},
2795
- ...t.rebindCamera ? { rebindCamera: !0 } : {}
2796
- }), Pn = (t = {}) => ({
2797
- maxFrameMs: Math.max(1, H(t.maxFrameMs, Q.maxFrameMs)),
2798
- maxInferenceMs: Math.max(
2799
- 0,
2800
- H(t.maxInferenceMs, Q.maxInferenceMs)
2801
- ),
2802
- maxMemoryMb: t.maxMemoryMb === null || t.maxMemoryMb === void 0 ? null : Math.max(1, H(t.maxMemoryMb, 0)) || null,
2803
- sampleMs: Math.max(100, H(t.sampleMs, Q.sampleMs)),
2804
- downgradeAfter: Math.max(
2805
- 1,
2806
- Math.round(H(t.downgradeAfter, Q.downgradeAfter))
2807
- ),
2808
- upgradeAfter: Math.max(
2809
- 1,
2810
- Math.round(H(t.upgradeAfter, Q.upgradeAfter))
2811
- ),
2812
- upgradeHeadroom: ue(
2813
- H(t.upgradeHeadroom, Q.upgradeHeadroom),
2814
- 0.1,
2815
- 1
2816
- ),
2817
- cooldownMs: Math.max(0, H(t.cooldownMs, Q.cooldownMs))
2818
- }), Y = (t, s, e) => {
2819
- if (typeof s == "number" && Number.isInteger(s) && s >= 0 && s < t.length)
2820
- return s;
2821
- if (typeof s == "string") {
2822
- const n = t.findIndex((r) => r.name === s);
2823
- if (n >= 0) return n;
2824
- }
2825
- return e;
2826
- }, Ln = (t = {}) => {
2827
- const s = t.tiers && t.tiers.length ? t.tiers.map((r, a) => _n(r, a)) : In, e = Y(s, t.maxTier, 0), n = Math.max(e, Y(s, t.minTier, s.length - 1));
2828
- return {
2829
- tiers: s,
2830
- budget: Pn(t.budget),
2831
- ...t.initialTier !== void 0 ? { initialTier: t.initialTier } : {},
2832
- minTier: n,
2833
- maxTier: e,
2834
- adaptive: t.adaptive !== !1,
2835
- historySize: Math.max(1, Math.round(H(t.historySize, 20)))
2836
- };
2837
- }, Dn = (t, s) => {
2838
- const e = Y(t.tiers, t.maxTier, 0), n = Y(t.tiers, t.minTier, t.tiers.length - 1);
2839
- if (t.initialTier !== void 0)
2840
- return ue(Y(t.tiers, t.initialTier, e), e, n);
2841
- const r = s.deviceMemoryGb !== null && s.deviceMemoryGb <= 4 || s.hardwareConcurrency !== null && s.hardwareConcurrency <= 4;
2842
- return ue(r ? e + 1 : e, e, n);
2843
- }, Et = (t, s = Tt, e = 0) => {
2844
- const n = Dn(t, s), r = { index: n, tier: t.tiers[n], reason: "init", at: e };
2845
- return {
2846
- index: n,
2847
- locked: !1,
2848
- badStreak: 0,
2849
- goodStreak: 0,
2850
- lastChangeAt: e,
2851
- decision: r,
2852
- history: [r],
2853
- signals: s
2854
- };
2855
- }, ye = (t, s, e, n, r, a = t.signals) => {
2856
- const o = { index: e, tier: s.tiers[e], reason: n, at: r };
2857
- return {
2858
- ...t,
2859
- index: e,
2860
- badStreak: 0,
2861
- goodStreak: 0,
2862
- lastChangeAt: r,
2863
- decision: o,
2864
- history: [o, ...t.history].slice(0, s.historySize),
2865
- signals: a
2866
- };
2867
- }, On = (t, s) => t.thermal === "critical" ? "thermal" : s.maxMemoryMb !== null && t.memoryMb !== null && t.memoryMb > s.maxMemoryMb ? "memory" : t.inferenceMs !== null && t.inferenceMs > s.maxInferenceMs ? "inference" : t.frameMs !== null && t.frameMs > s.maxFrameMs ? "frame-time" : null, Hn = (t, s, e, n) => {
2868
- const { budget: r } = e, a = Y(e.tiers, e.maxTier, 0), o = Y(e.tiers, e.minTier, e.tiers.length - 1);
2869
- if (t.locked || !e.adaptive) return { ...t, signals: s };
2870
- const c = On(s, r), l = c === null && s.frameMs !== null && s.frameMs <= r.maxFrameMs * r.upgradeHeadroom && (s.inferenceMs === null || s.inferenceMs <= r.maxInferenceMs * r.upgradeHeadroom), h = c ? t.badStreak + 1 : 0, f = l ? t.goodStreak + 1 : 0, u = n - t.lastChangeAt >= r.cooldownMs;
2871
- if (c && h >= r.downgradeAfter && u) {
2872
- if (t.index < o)
2873
- return ye(t, e, t.index + 1, c, n, s);
2874
- const w = c === "frame-time" ? "suspected" : s.thermal;
2875
- return { ...t, badStreak: h, goodStreak: f, signals: { ...s, thermal: w } };
2876
- }
2877
- return l && f >= r.upgradeAfter && u && t.index > a ? ye(t, e, t.index - 1, "recovered", n, s) : { ...t, badStreak: h, goodStreak: f, signals: s };
2878
- }, yr = (t, s, e, n) => {
2879
- const r = Y(s.tiers, e, t.index);
2880
- return r === t.index ? t : ye(t, s, r, "manual", n);
2881
- }, wr = (t, s, e, n) => e === t.locked ? t : { ...ye(t, s, t.index, e ? "locked" : "manual", n), locked: e }, Un = (t, s) => t.decision.tier === s ? null : t.decision.tier, vr = (t, s, e) => {
2882
- const n = Et(t, s, e);
2883
- return {
2884
- ...n,
2885
- decision: { ...n.decision, reason: "reset" },
2886
- history: [{ ...n.decision, reason: "reset" }]
2887
- };
2888
- }, Nn = Object.values(R), Bn = () => {
2889
- if (typeof navigator > "u") return { deviceMemoryGb: null, hardwareConcurrency: null };
2890
- const t = navigator;
2891
- return {
2892
- deviceMemoryGb: typeof t.deviceMemory == "number" ? t.deviceMemory : null,
2893
- hardwareConcurrency: typeof t.hardwareConcurrency == "number" ? t.hardwareConcurrency : null
2894
- };
2895
- }, zn = () => {
2896
- const t = performance.memory;
2897
- return t ? t.usedJSHeapSize / 1048576 : null;
2898
- }, Wn = ({ config: t, thermal: s, onDecision: e }) => {
2899
- const { session: n } = At(), r = JSON.stringify(t ?? {}), a = he(() => Ln(t), [r]), o = ie(s ?? "unknown");
2900
- o.current = s ?? "unknown";
2901
- const c = ie(e);
2902
- return c.current = e, ce(() => {
2903
- const l = Bn();
2904
- let h = Et(
2905
- a,
2906
- { ...Tt, ...l },
2907
- performance.now()
2908
- );
2909
- const f = n.store.getSnapshot().quality;
2910
- f && f.index < a.tiers.length && (h = {
2911
- ...f,
2912
- decision: { ...f.decision, tier: a.tiers[f.index] }
2913
- }), n._setQualityConfig(a), n._setQuality(h);
2914
- let u = n._getPerf(), w = null;
2915
- const S = async (y, C) => {
2916
- const N = {
2917
- ...u,
2918
- ...y.targetFps !== void 0 ? { targetFps: y.targetFps } : {},
2919
- ...y.analysisScale !== void 0 ? { analysisScale: y.analysisScale } : {},
2920
- ...y.camRes !== void 0 && y.rebindCamera ? { camRes: y.camRes } : {}
2921
- };
2922
- n._setPerf(N), y.rebindCamera && y.camRes !== void 0 && y.camRes !== (C == null ? void 0 : C.camRes) && await n._rebindMedia().catch(() => {
2923
- });
2924
- };
2925
- w = h.decision.tier, S(h.decision.tier, null);
2926
- let k = 0, x = performance.now(), T = 0;
2927
- const _ = () => {
2928
- k += 1, T = requestAnimationFrame(_);
2929
- };
2930
- T = requestAnimationFrame(_);
2931
- let g = null;
2932
- const v = window.setInterval(() => {
2933
- var W;
2934
- if (typeof document < "u" && document.hidden) {
2935
- k = 0, x = performance.now();
2936
- return;
2937
- }
2938
- const y = performance.now(), C = y - x, N = Le(n, Nn, g, y);
2939
- g = { feedFrames: N.session.feedFrames, sampledAt: y };
2940
- const E = n.store.getSnapshot().lifecycle === "running", V = {
2941
- frameMs: k > 0 && C > 0 && E ? C / k : null,
2942
- fps: k > 0 && C > 0 ? k * 1e3 / C : null,
2943
- inferenceMs: E ? N.inferenceMsTotal : null,
2944
- feedFps: N.session.feedFps,
2945
- memoryMb: zn(),
2946
- ...l,
2947
- thermal: o.current
2948
- };
2949
- k = 0, x = y;
2950
- const q = n.store.getSnapshot().quality ?? h, L = Hn(q, V, a, y);
2951
- h = L, n._setQuality(L);
2952
- const A = Un(L, w);
2953
- if (A) {
2954
- const K = w;
2955
- w = A, S(A, K), (W = c.current) == null || W.call(c, L);
2956
- }
2957
- }, a.budget.sampleMs);
2958
- return () => {
2959
- cancelAnimationFrame(T), window.clearInterval(v);
2960
- const y = (w == null ? void 0 : w.rebindCamera) && w.camRes !== void 0;
2961
- n._setPerf(u), y && (u == null ? void 0 : u.camRes) !== (w == null ? void 0 : w.camRes) && n._rebindMedia().catch(() => {
2962
- }), u = void 0, n._setQualityConfig(null);
2963
- };
2964
- }, [n, a]), null;
2965
- }, Ue = ut(void 0), At = () => {
2966
- const t = De(Ue);
2967
- if (!t)
2968
- throw new O(
2969
- "XR context can only be used inside XRProvider, did you forget to wrap your app in <XRProvider>?"
2970
- );
2971
- return t;
2972
- }, Sr = () => De(Ue) ?? null, Mr = ({ children: t, perf: s, lifecycle: e, quality: n }) => {
2973
- const r = Tn(s, e), a = he(() => ({ session: r }), [r]);
2974
- return /* @__PURE__ */ as(Ue.Provider, { value: a, children: [
2975
- n !== !1 && /* @__PURE__ */ et(Wn, { config: n || void 0 }),
2976
- /* @__PURE__ */ et(An, { children: t })
2977
- ] });
2978
- };
2979
- export {
2980
- er as $,
2981
- Zn as A,
2982
- vt as B,
2983
- Mt as C,
2984
- gt as D,
2985
- pr as E,
2986
- ps as F,
2987
- Rn as G,
2988
- Rs as H,
2989
- Tt as I,
2990
- Et as J,
2991
- On as K,
2992
- wr as L,
2993
- Bn as M,
2994
- vr as N,
2995
- Dn as O,
2996
- Pn as P,
2997
- _n as Q,
2998
- yr as R,
2999
- ot as S,
3000
- Hn as T,
3001
- Un as U,
3002
- hn as V,
3003
- hr as W,
3004
- R as X,
3005
- Oe as Y,
3006
- St as Z,
3007
- Jn as _,
3008
- Ls as a,
3009
- tr as a0,
3010
- sr as a1,
3011
- Ln as a2,
3012
- Ws as a3,
3013
- Mr as a4,
3014
- Os as a5,
3015
- rr as a6,
3016
- ar as a7,
3017
- ir as a8,
3018
- or as a9,
3019
- nr as aa,
3020
- lr as ab,
3021
- dr as ac,
3022
- pt as ad,
3023
- xs as ae,
3024
- yt as af,
3025
- Q as ag,
3026
- In as ah,
3027
- Wn as ai,
3028
- fr as aj,
3029
- ur as b,
3030
- Ds as c,
3031
- jn as d,
3032
- un as e,
3033
- mr as f,
3034
- F as g,
3035
- Sr as h,
3036
- He as i,
3037
- I as j,
3038
- Fe as k,
3039
- U as l,
3040
- $n as m,
3041
- le as n,
3042
- Us as o,
3043
- zs as p,
3044
- gr as q,
3045
- cr as r,
3046
- wt as s,
3047
- Qn as t,
3048
- At as u,
3049
- Pe as v,
3050
- ys as w,
3051
- ws as x,
3052
- vs as y,
3053
- Le as z
3054
- };