@mentra/engine 0.1.0-beta.0 → 0.1.0-dev.1

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 (355) hide show
  1. package/README.md +42 -1
  2. package/build/engine.d.ts +11 -3
  3. package/build/engine.d.ts.map +1 -1
  4. package/build/engine.js +7 -2
  5. package/build/engine.js.map +1 -1
  6. package/build/facades/dev.d.ts.map +1 -1
  7. package/build/facades/dev.js +9 -5
  8. package/build/facades/dev.js.map +1 -1
  9. package/build/facades/gallery.js +1 -1
  10. package/build/facades/gallery.js.map +1 -1
  11. package/build/facades/glasses.d.ts +1 -0
  12. package/build/facades/glasses.d.ts.map +1 -1
  13. package/build/facades/glasses.js +19 -4
  14. package/build/facades/glasses.js.map +1 -1
  15. package/build/facades/glassesSettings.d.ts.map +1 -1
  16. package/build/facades/glassesSettings.js +1 -0
  17. package/build/facades/glassesSettings.js.map +1 -1
  18. package/build/facades/miniapps.d.ts +4 -0
  19. package/build/facades/miniapps.d.ts.map +1 -1
  20. package/build/facades/miniapps.js +5 -0
  21. package/build/facades/miniapps.js.map +1 -1
  22. package/build/facades/ota.d.ts +11 -2
  23. package/build/facades/ota.d.ts.map +1 -1
  24. package/build/facades/ota.js +19 -4
  25. package/build/facades/ota.js.map +1 -1
  26. package/build/facades/pairing.d.ts +4 -0
  27. package/build/facades/pairing.d.ts.map +1 -1
  28. package/build/facades/pairing.js +10 -8
  29. package/build/facades/pairing.js.map +1 -1
  30. package/build/facades/phoneNotifications.d.ts +0 -4
  31. package/build/facades/phoneNotifications.d.ts.map +1 -1
  32. package/build/facades/phoneNotifications.js +4 -14
  33. package/build/facades/phoneNotifications.js.map +1 -1
  34. package/build/index.d.ts +6 -3
  35. package/build/index.d.ts.map +1 -1
  36. package/build/index.js +4 -2
  37. package/build/index.js.map +1 -1
  38. package/build/internal.d.ts +2 -2
  39. package/build/internal.d.ts.map +1 -1
  40. package/build/internal.js +1 -1
  41. package/build/internal.js.map +1 -1
  42. package/build/react/MentraLiveOtaFlow.d.ts +38 -0
  43. package/build/react/MentraLiveOtaFlow.d.ts.map +1 -0
  44. package/build/react/MentraLiveOtaFlow.js +528 -0
  45. package/build/react/MentraLiveOtaFlow.js.map +1 -0
  46. package/build/react/index.d.ts +2 -0
  47. package/build/react/index.d.ts.map +1 -0
  48. package/build/react/index.js +2 -0
  49. package/build/react/index.js.map +1 -0
  50. package/build/react/useEngineSnapshot.d.ts +2 -0
  51. package/build/react/useEngineSnapshot.d.ts.map +1 -0
  52. package/build/react/useEngineSnapshot.js +14 -0
  53. package/build/react/useEngineSnapshot.js.map +1 -0
  54. package/build/runtime/bootstrap.d.ts +24 -1
  55. package/build/runtime/bootstrap.d.ts.map +1 -1
  56. package/build/runtime/bootstrap.js +17 -0
  57. package/build/runtime/bootstrap.js.map +1 -1
  58. package/build/runtime/scanQrSeam.d.ts +7 -0
  59. package/build/runtime/scanQrSeam.d.ts.map +1 -0
  60. package/build/runtime/scanQrSeam.js +16 -0
  61. package/build/runtime/scanQrSeam.js.map +1 -0
  62. package/build/services/AppRegistry.d.ts +18 -8
  63. package/build/services/AppRegistry.d.ts.map +1 -1
  64. package/build/services/AppRegistry.js +44 -45
  65. package/build/services/AppRegistry.js.map +1 -1
  66. package/build/services/AudioCloudUplink.d.ts +9 -3
  67. package/build/services/AudioCloudUplink.d.ts.map +1 -1
  68. package/build/services/AudioCloudUplink.js +9 -3
  69. package/build/services/AudioCloudUplink.js.map +1 -1
  70. package/build/services/AudioPlaybackService.d.ts +9 -1
  71. package/build/services/AudioPlaybackService.d.ts.map +1 -1
  72. package/build/services/AudioPlaybackService.js +77 -32
  73. package/build/services/AudioPlaybackService.js.map +1 -1
  74. package/build/services/BlobStore.d.ts +2 -1
  75. package/build/services/BlobStore.d.ts.map +1 -1
  76. package/build/services/BlobStore.js +17 -9
  77. package/build/services/BlobStore.js.map +1 -1
  78. package/build/services/CloudAudioSubscriptionSync.d.ts.map +1 -1
  79. package/build/services/CloudAudioSubscriptionSync.js +13 -1
  80. package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
  81. package/build/services/CloudClientService.d.ts +15 -0
  82. package/build/services/CloudClientService.d.ts.map +1 -1
  83. package/build/services/CloudClientService.js +75 -0
  84. package/build/services/CloudClientService.js.map +1 -1
  85. package/build/services/ForegroundLocationPermission.d.ts +13 -0
  86. package/build/services/ForegroundLocationPermission.d.ts.map +1 -0
  87. package/build/services/ForegroundLocationPermission.js +12 -0
  88. package/build/services/ForegroundLocationPermission.js.map +1 -0
  89. package/build/services/GlassesSettingsSync.d.ts.map +1 -1
  90. package/build/services/GlassesSettingsSync.js +9 -3
  91. package/build/services/GlassesSettingsSync.js.map +1 -1
  92. package/build/services/GlassesStatusProjection.d.ts +2 -1
  93. package/build/services/GlassesStatusProjection.d.ts.map +1 -1
  94. package/build/services/GlassesStatusProjection.js +15 -8
  95. package/build/services/GlassesStatusProjection.js.map +1 -1
  96. package/build/services/HotspotOtaTransport.d.ts +29 -0
  97. package/build/services/HotspotOtaTransport.d.ts.map +1 -0
  98. package/build/services/HotspotOtaTransport.js +146 -0
  99. package/build/services/HotspotOtaTransport.js.map +1 -0
  100. package/build/services/HotspotShutdown.d.ts +17 -0
  101. package/build/services/HotspotShutdown.d.ts.map +1 -0
  102. package/build/services/HotspotShutdown.js +29 -0
  103. package/build/services/HotspotShutdown.js.map +1 -0
  104. package/build/services/LocalDisplayManager.d.ts +15 -0
  105. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  106. package/build/services/LocalDisplayManager.js +106 -20
  107. package/build/services/LocalDisplayManager.js.map +1 -1
  108. package/build/services/LocalMiniappRuntime.d.ts +67 -1
  109. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  110. package/build/services/LocalMiniappRuntime.js +486 -126
  111. package/build/services/LocalMiniappRuntime.js.map +1 -1
  112. package/build/services/LocalMiniappStorage.d.ts +32 -0
  113. package/build/services/LocalMiniappStorage.d.ts.map +1 -0
  114. package/build/services/LocalMiniappStorage.js +66 -0
  115. package/build/services/LocalMiniappStorage.js.map +1 -0
  116. package/build/services/LocalMiniappUserIdentity.d.ts +20 -0
  117. package/build/services/LocalMiniappUserIdentity.d.ts.map +1 -0
  118. package/build/services/LocalMiniappUserIdentity.js +43 -0
  119. package/build/services/LocalMiniappUserIdentity.js.map +1 -0
  120. package/build/services/MicStateCoordinator.d.ts +42 -1
  121. package/build/services/MicStateCoordinator.d.ts.map +1 -1
  122. package/build/services/MicStateCoordinator.js +141 -3
  123. package/build/services/MicStateCoordinator.js.map +1 -1
  124. package/build/services/MiniappLauncher.d.ts.map +1 -1
  125. package/build/services/MiniappLauncher.js +23 -3
  126. package/build/services/MiniappLauncher.js.map +1 -1
  127. package/build/services/MiniappLiveness.d.ts +12 -0
  128. package/build/services/MiniappLiveness.d.ts.map +1 -0
  129. package/build/services/MiniappLiveness.js +16 -0
  130. package/build/services/MiniappLiveness.js.map +1 -0
  131. package/build/services/OtaArtifactDownloader.d.ts +65 -0
  132. package/build/services/OtaArtifactDownloader.d.ts.map +1 -0
  133. package/build/services/OtaArtifactDownloader.js +226 -0
  134. package/build/services/OtaArtifactDownloader.js.map +1 -0
  135. package/build/services/OtaAutoChain.d.ts +34 -0
  136. package/build/services/OtaAutoChain.d.ts.map +1 -0
  137. package/build/services/OtaAutoChain.js +83 -0
  138. package/build/services/OtaAutoChain.js.map +1 -0
  139. package/build/services/OtaErrorMapping.d.ts +18 -0
  140. package/build/services/OtaErrorMapping.d.ts.map +1 -0
  141. package/build/services/OtaErrorMapping.js +63 -0
  142. package/build/services/OtaErrorMapping.js.map +1 -0
  143. package/build/services/OtaInstallCoordinator.d.ts +94 -14
  144. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  145. package/build/services/OtaInstallCoordinator.js +574 -130
  146. package/build/services/OtaInstallCoordinator.js.map +1 -1
  147. package/build/services/OtaService.d.ts.map +1 -1
  148. package/build/services/OtaService.js +8 -1
  149. package/build/services/OtaService.js.map +1 -1
  150. package/build/services/OtaUpdateCheckService.d.ts +38 -3
  151. package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
  152. package/build/services/OtaUpdateCheckService.js +142 -22
  153. package/build/services/OtaUpdateCheckService.js.map +1 -1
  154. package/build/services/PhoneCalendarService.d.ts.map +1 -1
  155. package/build/services/PhoneCalendarService.js +22 -1
  156. package/build/services/PhoneCalendarService.js.map +1 -1
  157. package/build/services/PhoneCameraFovCoordinator.d.ts +2 -0
  158. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -1
  159. package/build/services/PhoneCameraFovCoordinator.js +14 -0
  160. package/build/services/PhoneCameraFovCoordinator.js.map +1 -1
  161. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  162. package/build/services/PhoneNotificationsSync.js +12 -10
  163. package/build/services/PhoneNotificationsSync.js.map +1 -1
  164. package/build/services/PhonePhotoCoordinator.d.ts +10 -3
  165. package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
  166. package/build/services/PhonePhotoCoordinator.js +21 -3
  167. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  168. package/build/services/PhoneStreamCoordinator.d.ts +8 -1
  169. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  170. package/build/services/PhoneStreamCoordinator.js +125 -13
  171. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  172. package/build/services/PhoneVideoCoordinator.d.ts +2 -0
  173. package/build/services/PhoneVideoCoordinator.d.ts.map +1 -1
  174. package/build/services/PhoneVideoCoordinator.js +10 -0
  175. package/build/services/PhoneVideoCoordinator.js.map +1 -1
  176. package/build/services/SceneRenderer.d.ts.map +1 -1
  177. package/build/services/SceneRenderer.js +15 -0
  178. package/build/services/SceneRenderer.js.map +1 -1
  179. package/build/services/SupportProfileSync.d.ts +22 -0
  180. package/build/services/SupportProfileSync.d.ts.map +1 -0
  181. package/build/services/SupportProfileSync.js +213 -0
  182. package/build/services/SupportProfileSync.js.map +1 -0
  183. package/build/services/TtsTextSanitizer.d.ts +5 -0
  184. package/build/services/TtsTextSanitizer.d.ts.map +1 -0
  185. package/build/services/TtsTextSanitizer.js +61 -0
  186. package/build/services/TtsTextSanitizer.js.map +1 -0
  187. package/build/services/WifiAdbRequest.d.ts +17 -0
  188. package/build/services/WifiAdbRequest.d.ts.map +1 -0
  189. package/build/services/WifiAdbRequest.js +35 -0
  190. package/build/services/WifiAdbRequest.js.map +1 -0
  191. package/build/services/asg/asgCameraApi.d.ts +3 -0
  192. package/build/services/asg/asgCameraApi.d.ts.map +1 -1
  193. package/build/services/asg/asgCameraApi.js +72 -2
  194. package/build/services/asg/asgCameraApi.js.map +1 -1
  195. package/build/services/asg/gallerySyncService.d.ts.map +1 -1
  196. package/build/services/asg/gallerySyncService.js +26 -14
  197. package/build/services/asg/gallerySyncService.js.map +1 -1
  198. package/build/services/asg/localNetworkTransport.d.ts +2 -2
  199. package/build/services/asg/localNetworkTransport.d.ts.map +1 -1
  200. package/build/services/asg/localNetworkTransport.js +6 -6
  201. package/build/services/asg/localNetworkTransport.js.map +1 -1
  202. package/build/services/audioPlaybackAssets.d.ts +8 -0
  203. package/build/services/audioPlaybackAssets.d.ts.map +1 -0
  204. package/build/services/audioPlaybackAssets.js +7 -0
  205. package/build/services/audioPlaybackAssets.js.map +1 -0
  206. package/build/services/glassesClockSync.js +2 -2
  207. package/build/services/glassesClockSync.js.map +1 -1
  208. package/build/services/manifestActions.d.ts +7 -0
  209. package/build/services/manifestActions.d.ts.map +1 -0
  210. package/build/services/manifestActions.js +25 -0
  211. package/build/services/manifestActions.js.map +1 -0
  212. package/build/services/otaDisplayState.d.ts +22 -11
  213. package/build/services/otaDisplayState.d.ts.map +1 -1
  214. package/build/services/otaDisplayState.js +36 -14
  215. package/build/services/otaDisplayState.js.map +1 -1
  216. package/build/services/otaInstallPolicy.d.ts +15 -3
  217. package/build/services/otaInstallPolicy.d.ts.map +1 -1
  218. package/build/services/otaInstallPolicy.js +24 -3
  219. package/build/services/otaInstallPolicy.js.map +1 -1
  220. package/build/services/otaManifestUrl.d.ts +2 -0
  221. package/build/services/otaManifestUrl.d.ts.map +1 -0
  222. package/build/services/{asgOtaVersionUrl.js → otaManifestUrl.js} +15 -5
  223. package/build/services/otaManifestUrl.js.map +1 -0
  224. package/build/services/slimStreamStatus.d.ts +11 -0
  225. package/build/services/slimStreamStatus.d.ts.map +1 -1
  226. package/build/services/slimStreamStatus.js +14 -4
  227. package/build/services/slimStreamStatus.js.map +1 -1
  228. package/build/stores/apps.d.ts.map +1 -1
  229. package/build/stores/apps.js +11 -0
  230. package/build/stores/apps.js.map +1 -1
  231. package/build/stores/bluetoothSettingKeys.d.ts.map +1 -1
  232. package/build/stores/bluetoothSettingKeys.js +2 -0
  233. package/build/stores/bluetoothSettingKeys.js.map +1 -1
  234. package/build/stores/gallerySync.d.ts +2 -0
  235. package/build/stores/gallerySync.d.ts.map +1 -1
  236. package/build/stores/gallerySync.js +2 -0
  237. package/build/stores/gallerySync.js.map +1 -1
  238. package/build/stores/glasses.d.ts.map +1 -1
  239. package/build/stores/glasses.js +3 -0
  240. package/build/stores/glasses.js.map +1 -1
  241. package/build/stores/settings.d.ts +17 -0
  242. package/build/stores/settings.d.ts.map +1 -1
  243. package/build/stores/settings.js +152 -19
  244. package/build/stores/settings.js.map +1 -1
  245. package/build/types/applet.d.ts +2 -0
  246. package/build/types/applet.d.ts.map +1 -1
  247. package/build/types/applet.js.map +1 -1
  248. package/build/types/enums.d.ts +1 -0
  249. package/build/types/enums.d.ts.map +1 -1
  250. package/build/types/enums.js +1 -0
  251. package/build/types/enums.js.map +1 -1
  252. package/build/types/hardware.d.ts +1 -0
  253. package/build/types/hardware.d.ts.map +1 -1
  254. package/build/types/hardware.js +14 -0
  255. package/build/types/hardware.js.map +1 -1
  256. package/build/utils/configuredDevHost.d.ts +6 -0
  257. package/build/utils/configuredDevHost.d.ts.map +1 -0
  258. package/build/utils/configuredDevHost.js +19 -0
  259. package/build/utils/configuredDevHost.js.map +1 -0
  260. package/build/utils/devMiniappLaunch.d.ts +19 -8
  261. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  262. package/build/utils/devMiniappLaunch.js +144 -21
  263. package/build/utils/devMiniappLaunch.js.map +1 -1
  264. package/build/utils/diagnosticContext.d.ts.map +1 -1
  265. package/build/utils/diagnosticContext.js +15 -17
  266. package/build/utils/diagnosticContext.js.map +1 -1
  267. package/build/utils/hardware/hardware.d.ts.map +1 -1
  268. package/build/utils/hardware/hardware.js +7 -3
  269. package/build/utils/hardware/hardware.js.map +1 -1
  270. package/build/utils/miniappDiagnostics.d.ts +64 -0
  271. package/build/utils/miniappDiagnostics.d.ts.map +1 -0
  272. package/build/utils/miniappDiagnostics.js +173 -0
  273. package/build/utils/miniappDiagnostics.js.map +1 -0
  274. package/build/utils/timers/timers.d.ts.map +1 -1
  275. package/build/utils/timers/timers.js +55 -18
  276. package/build/utils/timers/timers.js.map +1 -1
  277. package/package.json +27 -18
  278. package/src/assets/silence.wav +0 -0
  279. package/src/engine.ts +7 -2
  280. package/src/facades/dev.ts +9 -5
  281. package/src/facades/gallery.ts +1 -1
  282. package/src/facades/glasses.ts +17 -4
  283. package/src/facades/glassesSettings.ts +5 -0
  284. package/src/facades/miniapps.ts +7 -0
  285. package/src/facades/ota.ts +19 -4
  286. package/src/facades/pairing.ts +11 -7
  287. package/src/facades/phoneNotifications.ts +4 -13
  288. package/src/index.ts +26 -2
  289. package/src/internal.ts +2 -1
  290. package/src/react/MentraLiveOtaFlow.tsx +856 -0
  291. package/src/react/index.ts +7 -0
  292. package/src/react/useEngineSnapshot.ts +16 -0
  293. package/src/runtime/bootstrap.ts +33 -1
  294. package/src/runtime/scanQrSeam.ts +20 -0
  295. package/src/services/AppRegistry.ts +72 -48
  296. package/src/services/AudioCloudUplink.ts +9 -3
  297. package/src/services/AudioPlaybackService.ts +94 -34
  298. package/src/services/BlobStore.ts +22 -9
  299. package/src/services/CloudAudioSubscriptionSync.ts +13 -1
  300. package/src/services/CloudClientService.ts +74 -0
  301. package/src/services/ForegroundLocationPermission.ts +24 -0
  302. package/src/services/GlassesSettingsSync.ts +9 -3
  303. package/src/services/GlassesStatusProjection.ts +16 -8
  304. package/src/services/HotspotOtaTransport.ts +184 -0
  305. package/src/services/HotspotShutdown.ts +41 -0
  306. package/src/services/LocalDisplayManager.ts +112 -21
  307. package/src/services/LocalMiniappRuntime.ts +576 -130
  308. package/src/services/LocalMiniappStorage.ts +82 -0
  309. package/src/services/LocalMiniappUserIdentity.ts +46 -0
  310. package/src/services/MicStateCoordinator.ts +169 -4
  311. package/src/services/MiniappLauncher.ts +30 -3
  312. package/src/services/MiniappLiveness.ts +24 -0
  313. package/src/services/OtaArtifactDownloader.ts +312 -0
  314. package/src/services/OtaAutoChain.ts +106 -0
  315. package/src/services/OtaErrorMapping.ts +80 -0
  316. package/src/services/OtaInstallCoordinator.ts +645 -143
  317. package/src/services/OtaService.ts +11 -5
  318. package/src/services/OtaUpdateCheckService.ts +180 -20
  319. package/src/services/PhoneCalendarService.ts +27 -4
  320. package/src/services/PhoneCameraFovCoordinator.ts +15 -0
  321. package/src/services/PhoneNotificationsSync.ts +12 -10
  322. package/src/services/PhonePhotoCoordinator.ts +33 -7
  323. package/src/services/PhoneStreamCoordinator.ts +139 -25
  324. package/src/services/PhoneVideoCoordinator.ts +11 -0
  325. package/src/services/SceneRenderer.ts +16 -0
  326. package/src/services/SupportProfileSync.ts +218 -0
  327. package/src/services/TtsTextSanitizer.ts +66 -0
  328. package/src/services/WifiAdbRequest.ts +53 -0
  329. package/src/services/asg/asgCameraApi.ts +99 -8
  330. package/src/services/asg/gallerySyncService.ts +28 -19
  331. package/src/services/asg/localNetworkTransport.ts +7 -11
  332. package/src/services/audioPlaybackAssets.ts +8 -0
  333. package/src/services/glassesClockSync.ts +2 -2
  334. package/src/services/manifestActions.ts +30 -0
  335. package/src/services/otaDisplayState.ts +57 -16
  336. package/src/services/otaInstallPolicy.ts +29 -3
  337. package/src/services/{asgOtaVersionUrl.ts → otaManifestUrl.ts} +16 -4
  338. package/src/services/slimStreamStatus.ts +16 -5
  339. package/src/stores/apps.ts +12 -0
  340. package/src/stores/bluetoothSettingKeys.ts +2 -0
  341. package/src/stores/gallerySync.ts +4 -0
  342. package/src/stores/glasses.ts +3 -0
  343. package/src/stores/settings.ts +174 -21
  344. package/src/types/applet.ts +2 -0
  345. package/src/types/enums.ts +2 -1
  346. package/src/types/hardware.ts +17 -0
  347. package/src/utils/configuredDevHost.ts +17 -0
  348. package/src/utils/devMiniappLaunch.ts +151 -23
  349. package/src/utils/diagnosticContext.ts +17 -17
  350. package/src/utils/hardware/hardware.ts +7 -9
  351. package/src/utils/miniappDiagnostics.ts +226 -0
  352. package/src/utils/timers/timers.ts +57 -21
  353. package/build/services/asgOtaVersionUrl.d.ts +0 -2
  354. package/build/services/asgOtaVersionUrl.d.ts.map +0 -1
  355. package/build/services/asgOtaVersionUrl.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"CloudClientService.js","sourceRoot":"","sources":["../../src/services/CloudClientService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAC,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAC,MAAM,mCAAmC,CAAA;AAG5G,OAAO,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAA;AAGrC,OAAO,YAAY,MAAM,gCAAgC,CAAA;AACzD,OAAO,WAAW,MAAM,eAAe,CAAA;AACvC,OAAO,EAAC,OAAO,EAAE,eAAe,EAAC,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAC,gBAAgB,EAAE,QAAQ,EAAC,MAAM,oBAAoB,CAAA;AAE7D,OAAO,EAAC,oBAAoB,EAAC,MAAM,mCAAmC,CAAA;AACtE,OAAO,EAAC,gBAAgB,EAAC,MAAM,uCAAuC,CAAA;AACtE,OAAO,EAAC,yBAAyB,EAAC,MAAM,6BAA6B,CAAA;AACrE,OAAO,EAAC,mBAAmB,EAAC,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAC,0BAA0B,EAAC,MAAM,6BAA6B,CAAA;AACtE,OAAO,EAAC,sBAAsB,EAAC,MAAM,sBAAsB,CAAA;AAE3D,MAAM,OAAO,GAAG,aAAa,CAAA;AAG7B,oFAAoF;AACpF,qFAAqF;AACrF,qFAAqF;AACrF,+FAA+F;AAC/F,MAAM,2BAA2B,GAAG,MAAM,CAAA;AAE1C,gFAAgF;AAChF,SAAS,2BAA2B;IAClC,IAAI,sBAAsB,EAAE,CAAC;QAC3B,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAA;QAC5C,sBAAsB,GAAG,IAAI,CAAA;IAC/B,CAAC;IACD,yBAAyB,GAAG,KAAK,CAAA;AACnC,CAAC;AAID,iFAAiF;AACjF,gFAAgF;AAChF,wEAAwE;AACxE,MAAM,iBAAiB,GAAG,uBAAuB,CAAA;AACjD,MAAM,oBAAoB,GAAG,uBAAuB,CAAA;AACpD,MAAM,eAAe,GAAG,IAAI,CAAA;AAE5B,IAAI,MAAM,GAAuB,IAAI,CAAA;AACrC,IAAI,SAAS,GAAG,KAAK,CAAA;AACrB,IAAI,sBAAsB,GAAiD,IAAI,CAAA;AAC/E,IAAI,yBAAyB,GAAG,KAAK,CAAA;AACrC,IAAI,kBAAkB,GAAwB,EAAE,CAAA;AAChD,IAAI,eAAe,GAAG,KAAK,CAAA;AAC3B,iFAAiF;AACjF,IAAI,iBAAiB,GAA2C,IAAI,CAAA;AACpE,IAAI,wBAAwB,GAAwB,IAAI,CAAA;AACxD,IAAI,qBAAqB,GAAwB,IAAI,CAAA;AACrD,IAAI,sBAAsB,GAAwB,IAAI,CAAA;AACtD,IAAI,oBAAoB,GAAwB,IAAI,CAAA;AACpD,IAAI,oBAAoB,GAAoE,IAAI,CAAA;AAChG,IAAI,uBAAuB,GAAwB,IAAI,CAAA;AACvD,IAAI,oBAAoB,GAA2B,IAAI,CAAA;AAEvD,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAkC,CAAA;AACrE,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAgC,CAAA;AACpE,MAAM,eAAe,GAAG,IAAI,GAAG,EAAiD,CAAA;AAChF,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAgC,CAAA;AAEnE,SAAS,gBAAgB;IACvB,IAAI,iBAAiB;QAAE,OAAO,iBAAiB,CAAA;IAC/C,MAAM,GAAG,GAAG,eAAe,EAAE,CAAA;IAC7B,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,iBAAiB;QAC9C,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,oBAAoB;KACxD,CAAA;AACH,CAAC;AAED,SAAS,aAAa;IACpB,IAAI,CAAC,MAAM;QAAE,SAAS,EAAE,CAAA;IACxB,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,CAAA;IACzB,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;IAC9D,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,8BAA8B;IACrC,IAAI,oBAAoB;QAAE,OAAO,oBAAoB,CAAA;IAErD,oBAAoB,GAAG,sCAAsC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;QAC3E,oBAAoB,GAAG,IAAI,CAAA;IAC7B,CAAC,CAAC,CAAA;IACF,OAAO,oBAAoB,CAAA;AAC7B,CAAC;AAED,KAAK,UAAU,sCAAsC;IACnD,IAAI,CAAC,MAAM;QAAE,SAAS,EAAE,CAAA;IACxB,MAAM,CAAC,GAAG,MAAM,CAAA;IAChB,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;IAEvD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,CAAA;IACzC,IAAI,CAAC,KAAK,MAAM,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;IAClE,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;IAClG,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QACtB,MAAM,MAAM,CAAC,KAAK,CAAA;IACpB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,YAAY,CAAC,uBAAuB,CAAC,EAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,KAAK,EAAC,CAAC,CAAA;IAChF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,8CAA+C,GAAa,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;IACxG,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,cAAc;IACrB,sEAAsE;IACtE,8EAA8E;IAC9E,0EAA0E;IAC1E,gEAAgE;IAChE,MAAM,YAAY,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;IACxF,MAAM,IAAI,GAAG,YAAY,IAAI,eAAe,EAAE,CAAC,mBAAmB,CAAA;IAClE,OAAO,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;AAC9D,CAAC;AAED,KAAK,UAAU,eAAe;IAC5B,MAAM,CAAC,GAAG,OAAO,EAAE,CAAA;IACnB,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;IAC3E,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,eAAe,EAAE,CAAA;IACnC,8EAA8E;IAC9E,0EAA0E;IAC1E,gEAAgE;IAChE,OAAO,EAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAwB,EAAC,CAAA;AAC3D,CAAC;AAED,SAAS,kBAAkB,CAAC,SAAiB;IAC3C,OAAO,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;AAClE,CAAC;AAED,SAAS,6BAA6B,CAAC,SAA4B;IACjE,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAA;IAC1B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAA;QAChD,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,UAAU,CAAA;IAC5E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,uBAAuB,CAAC,eAAuB,EAAE,IAA+B;IAC7F,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACtB,IACE,CAAC,IAAI,EAAE,YAAY;QACnB,oBAAoB,EAAE,UAAU,KAAK,eAAe;QACpD,oBAAoB,CAAC,WAAW,GAAG,GAAG,GAAG,MAAM,EAC/C,CAAC;QACD,OAAO,oBAAoB,CAAC,KAAK,CAAA;IACnC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAA;IACrC,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,eAAe,CAAC,CAAA;IACnC,IAAI,CAAC,QAAQ,GAAG,wBAAwB,CAAA;IACxC,IAAI,CAAC,MAAM,GAAG,IAAI,eAAe,CAAC,EAAC,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,QAAQ,EAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IAE9F,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;IACxC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,gDAAgD,GAAG,CAAC,MAAM,GAAG,CAAC,CAAA;IAChF,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAiD,CAAA;IAC/E,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAA;IACvF,CAAC;IACD,oBAAoB,GAAG;QACrB,UAAU,EAAE,eAAe;QAC3B,KAAK,EAAE,IAAI,CAAC,YAAY;QACxB,WAAW,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,GAAG,CAAC,GAAG,IAAI;KACnD,CAAA;IACD,OAAO,IAAI,CAAC,YAAY,CAAA;AAC1B,CAAC;AAED,SAAS,2BAA2B,CAAC,QAAyB;IAC5D,OAAO,EAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,CAAC,cAAc,EAAC,CAAA;AAC3E,CAAC;AAED,SAAS,oBAAoB;IAC3B,MAAM,KAAK,GAAG,yBAAyB,CAAC,QAAQ,EAAE,CAAA;IAClD,OAAO,EAAC,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAC,CAAA;AACrE,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAyB;IACjD,yBAAyB,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAA;IAC1D,UAAU,CAAC,2BAA2B,CAAC,QAAQ,CAAC,CAAC,CAAA;AACnD,CAAC;AAED,SAAS,kBAAkB;IACzB,yBAAyB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAA;IAC5C,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAA;AACpC,CAAC;AAED,SAAS,aAAa,CAAC,IAAa;IAClC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAA;IAChD,IAAI,CAAC;QACH,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAA;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED,MAAM,WAAW,GAAG;IAClB,KAAK,EAAE,CAAC,GAAW,EAAE,IAAc,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,YAAY,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;IACtG,IAAI,EAAE,CAAC,GAAW,EAAE,IAAc,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,WAAW,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;IACpG,IAAI,EAAE,CAAC,GAAW,EAAE,IAAc,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,WAAW,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;IACrG,KAAK,EAAE,CAAC,GAAW,EAAE,IAAc,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,YAAY,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;CACxG,CAAA;AAED,SAAS,yBAAyB,CAAC,IAAa;IAC9C,KAAK,MAAM,CAAC,IAAI,mBAAmB,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,CAAC,CAAC,IAAI,CAAC,CAAA;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,gCAAiC,GAAa,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;QAC1F,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAY;IACtC,MAAM,UAAU,GAAc,EAAE,CAAA;IAChC,MAAM,CAAC,GAAG,GAAiD,CAAA;IAC3D,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC/B,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAClB,UAAU,CAAC,IAAI,CAAE,CAAC,CAAC,KAAiC,EAAE,YAAY,CAAC,CAAA;QACnE,UAAU,CAAC,IAAI,CAAE,CAAC,CAAC,IAAgC,EAAE,YAAY,CAAC,CAAA;QAClE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAA;IACjC,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAI,CAA6B,EAAE,WAAW,CAAA;QACzD,IAAI,OAAO,KAAK,KAAK,UAAU;YAAE,OAAO,KAAmB,CAAA;IAC7D,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,eAAe;IACtB,IAAI,oBAAoB;QAAE,OAAM;IAChC,oBAAoB,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;IAE/B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IACtB,IAAI,CAAC,IAAI,EAAE,aAAa;QAAE,OAAM;IAEhC,IAAI,gBAAgB,GAAG,KAAK,CAAA;IAC5B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAChD,IAAI,CAAC,OAAO,EAAE,KAAK;gBAAE,OAAM;YAC3B,IAAI,SAAS,IAAI,gBAAgB;gBAAE,OAAM;YAEzC,gBAAgB,GAAG,IAAI,CAAA;YACvB,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,6BAA6B,KAAK,qCAAqC,CAAC,CAAA;YAC9F,IAAI,CAAC;gBACH,kBAAkB,CAAC,SAAS,EAAE,CAAA;YAChC,CAAC;oBAAS,CAAC;gBACT,UAAU,CAAC,GAAG,EAAE;oBACd,gBAAgB,GAAG,KAAK,CAAA;gBAC1B,CAAC,EAAE,CAAC,CAAC,CAAA;YACP,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAA;QACrC,IAAI,KAAK;YAAE,oBAAoB,GAAG,KAAK,CAAA;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,kCAAmC,GAAa,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;IAC5F,CAAC;AACH,CAAC;AAED,SAAS,aAAa;IACpB,oBAAoB,EAAE,EAAE,CAAA;IACxB,oBAAoB,GAAG,IAAI,CAAA;AAC7B,CAAC;AAED,SAAS,cAAc,CAAC,IAAuB;IAC7C,KAAK,MAAM,CAAC,IAAI,mBAAmB,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,CAAC,CAAC,IAAI,CAAC,CAAA;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,gCAAiC,GAAa,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;QAC1F,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,IAAqB;IAC5C,KAAK,MAAM,CAAC,IAAI,oBAAoB,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,CAAC,CAAC,IAAI,CAAC,CAAA;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,iCAAkC,GAAa,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;QAC3F,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,QAAmC;IACrD,KAAK,MAAM,CAAC,IAAI,eAAe,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,CAAC,CAAC,QAAQ,CAAC,CAAA;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,4BAA6B,GAAa,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;QACtF,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB;IACvB,IAAI,eAAe;QAAE,OAAM;IAC3B,eAAe,GAAG,IAAI,CAAA;IACtB,YAAY,CAAC,GAAG,EAAE,CAAC,oBAAoB,EAAE,CAAC,CAAA;IAC1C,gBAAgB,CAAC,gBAAgB,CAAC,CAAA;IAClC,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS;QAAE,OAAM;IACrC,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAClC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;YACvF,OAAO,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QACtC,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;QACxE,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,iBAAiB,CAChD,IAAI,EAAE,MAAM,IAAI,KAAK,EACrB,KAAK,EACL,OAAO,EACN,IAAI,EAAE,IAA2B,IAAI,IAAI,CAC3C,CAAA;QACD,OAAO,IAAI,QAAQ,CAAC,sBAAsB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE;YACtE,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,8BAA8B;IACrC,wBAAwB,EAAE,EAAE,CAAA;IAC5B,wBAAwB,GAAG,IAAI,CAAA;IAC/B,qBAAqB,EAAE,EAAE,CAAA;IACzB,qBAAqB,GAAG,IAAI,CAAA;IAC5B,sBAAsB,EAAE,EAAE,CAAA;IAC1B,sBAAsB,GAAG,IAAI,CAAA;AAC/B,CAAC;AAED,SAAS,wBAAwB;IAC/B,IAAI,uBAAuB;QAAE,OAAM;IAEnC,IAAI,IAAI,GAAG,cAAc,EAAE,CAAA;IAC3B,uBAAuB,GAAG,gBAAgB,CAAC,SAAS,CAClD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,EACxD,GAAG,EAAE;QACH,MAAM,IAAI,GAAG,cAAc,EAAE,CAAA;QAC7B,IAAI,IAAI,KAAK,IAAI;YAAE,OAAM;QACzB,IAAI,GAAG,IAAI,CAAA;QACX,IAAI,CAAC,MAAM;YAAE,OAAM;QACnB,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,+BAA+B,IAAI,wBAAwB,CAAC,CAAA;QAClF,kBAAkB,CAAC,SAAS,EAAE,CAAA;IAChC,CAAC,CACF,CAAA;AACH,CAAC;AAED,SAAS,uBAAuB;IAC9B,uBAAuB,EAAE,EAAE,CAAA;IAC3B,uBAAuB,GAAG,IAAI,CAAA;AAChC,CAAC;AAED,SAAS,SAAS;IAChB,gBAAgB,EAAE,CAAA;IAElB,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAA;IACpC,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,eAAe,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;IAEjE,MAAM,QAAQ,GAAG,EAAC,eAAe,EAAC,CAAA;IAClC,MAAM,IAAI,GAAG,6BAA6B,CAAC,SAAS,CAAC;QACnD,CAAC,CAAC;YACE,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAC,QAAQ,EAAE,CAAC,IAA+B,EAAE,EAAE,CAAC,uBAAuB,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,EAAC;SAC3G;QACH,CAAC,CAAC,EAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAC,MAAM,EAAE,MAAe,EAAC,EAAC,CAAA;IAExD,MAAM,GAAG,IAAI,WAAW,CAAC;QACvB,SAAS;QACT,2EAA2E;QAC3E,uDAAuD;QACvD,KAAK,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,EAAC;QAC1E,IAAI;QACJ,MAAM,EAAE,WAAW;KACpB,CAAC,CAAA;IAEF,MAAM,CAAC,GAAG,MAAM,CAAA;IAChB,8BAA8B,EAAE,CAAA;IAChC,wBAAwB,GAAG,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,MAAM,EAAE,EAAE;QAC9D,IAAI,CAAC,KAAK,MAAM;YAAE,OAAM;QACxB,gBAAgB,CAAC,MAAM,CAAC,CAAA;IAC1B,CAAC,CAAC,CAAA;IACF,qBAAqB,GAAG,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE;QACtD,IAAI,CAAC,KAAK,MAAM;YAAE,OAAM;QACxB,0BAA0B,CAAC,IAAI,CAAC,CAAA;QAChC,cAAc,CAAC,IAAI,CAAC,CAAA;IACtB,CAAC,CAAC,CAAA;IACF,sBAAsB,GAAG,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,EAAE;QACxD,IAAI,CAAC,KAAK,MAAM;YAAE,OAAM;QACxB,eAAe,CAAC,IAAI,CAAC,CAAA;IACvB,CAAC,CAAC,CAAA;IACF,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;IAEvC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE;QACzB,IAAI,CAAC,KAAK,MAAM;YAAE,OAAM;QACxB,SAAS,GAAG,IAAI,CAAA;QAChB,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,qBAAqB,CAAC,CAAA;QAC5C,+EAA+E;QAC/E,eAAe;QACf,2BAA2B,EAAE,CAAA;QAC7B,2EAA2E;QAC3E,yEAAyE;QACzE,CAAC,CAAC,OAAO;aACN,gBAAgB,CAAC,kBAAkB,CAAC;aACpC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CACb,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,8CAA+C,GAAa,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CACvG,CAAA;QACH,yBAAyB,CAAC,IAAI,CAAC,CAAA;IACjC,CAAC,CAAC,CAAA;IACF,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE;QAChC,IAAI,CAAC,KAAK,MAAM;YAAE,OAAM;QACxB,SAAS,GAAG,KAAK,CAAA;QACjB,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,2BAA2B,IAAI,CAAC,MAAM,GAAG,CAAC,CAAA;QAChE,kFAAkF;QAClF,kFAAkF;QAClF,IAAI,CAAC,sBAAsB,IAAI,CAAC,yBAAyB,EAAE,CAAC;YAC1D,sBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE;gBAC/C,sBAAsB,GAAG,IAAI,CAAA;gBAC7B,IAAI,SAAS;oBAAE,OAAM;gBACrB,yBAAyB,GAAG,IAAI,CAAA;gBAChC,mBAAmB,CAAC,IAAI,CAAC;oBACvB,IAAI,EAAE,8BAA8B;oBACpC,MAAM,EAAE,gDAAgD,IAAI,CAAC,KAAK,CAAC,2BAA2B,GAAG,IAAI,CAAC,GAAG;oBACzG,QAAQ,EAAE,EAAC,SAAS,EAAE,2BAA2B,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAC;oBAC3E,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iBACtB,CAAC,CAAA;YACJ,CAAC,EAAE,2BAA2B,CAAC,CAAA;QACjC,CAAC;QACD,yBAAyB,CAAC,KAAK,CAAC,CAAA;IAClC,CAAC,CAAC,CAAA;IACF,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACxB,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,oBAAoB,GAAG,CAAC,IAAI,EAAE,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;IAEF,6EAA6E;IAC7E,CAAC,CAAC,OAAO;SACN,OAAO,EAAE;SACT,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,sBAAsB,CAAC,CAAC;SACzD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,uBAAuB,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC,CAAA;IAEvF,8BAA8B,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAC7C,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,+CAAgD,GAAa,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CACxG,CAAA;IAED,wBAAwB,EAAE,CAAA;AAC5B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC;;;;OAIG;IACH,IAAI;QACF,IAAI,MAAM;YAAE,OAAM;QAClB,eAAe,EAAE,CAAA;QACjB,SAAS,EAAE,CAAA;IACb,CAAC;IAED;;;;OAIG;IACH,SAAS,CAAC,SAAkD;QAC1D,IAAI,SAAS,KAAK,SAAS;YAAE,iBAAiB,GAAG,SAAS,CAAA;QAC1D,IAAI,CAAC;YACH,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,CAAA;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,+BAAgC,GAAa,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;QACzF,CAAC;QACD,8BAA8B,EAAE,CAAA;QAChC,2BAA2B,EAAE,CAAA;QAE7B,MAAM,YAAY,GAAG,SAAS,CAAA;QAC9B,MAAM,GAAG,IAAI,CAAA;QACb,oBAAoB,GAAG,IAAI,CAAA;QAC3B,SAAS,GAAG,KAAK,CAAA;QACjB,kBAAkB,EAAE,CAAA;QACpB,IAAI,YAAY;YAAE,yBAAyB,CAAC,KAAK,CAAC,CAAA;QAElD,SAAS,EAAE,CAAA;IACb,CAAC;IAED,KAAK,CAAC,8BAA8B;QAClC,IAAI,CAAC,MAAM;YAAE,IAAI,CAAC,IAAI,EAAE,CAAA;QACxB,MAAM,CAAC,GAAG,MAAM,CAAA;QAChB,IAAI,CAAC,CAAC,EAAE,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;QACjE,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAA;IACtC,CAAC;IAED,KAAK,CAAC,mBAAmB,CACvB,WAAmB,EACnB,IAAmD;QAEnD,IAAI,CAAC,MAAM;YAAE,IAAI,CAAC,IAAI,EAAE,CAAA;QACxB,MAAM,CAAC,GAAG,MAAM,CAAA;QAChB,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;QAEvD,MAAM,EAAC,KAAK,EAAE,SAAS,EAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;QAC1E,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAA;QAChC,OAAO;YACL,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,KAAK;YACL,SAAS,EAAE,kBAAkB,CAAC,SAAS,CAAC;SACzC,CAAA;IACH,CAAC;IAED,uEAAuE;IACvE,IAAI;QACF,IAAI,CAAC;YACH,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,CAAA;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,0BAA2B,GAAa,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;QACpF,CAAC;QACD,uBAAuB,EAAE,CAAA;QACzB,aAAa,EAAE,CAAA;QACf,8BAA8B,EAAE,CAAA;QAChC,2BAA2B,EAAE,CAAA;QAC7B,MAAM,YAAY,GAAG,SAAS,CAAA;QAC9B,MAAM,GAAG,IAAI,CAAA;QACb,oBAAoB,GAAG,IAAI,CAAA;QAC3B,SAAS,GAAG,KAAK,CAAA;QACjB,kBAAkB,EAAE,CAAA;QACpB,IAAI,YAAY;YAAE,yBAAyB,CAAC,KAAK,CAAC,CAAA;IACpD,CAAC;IAED,qFAAqF;IACrF,iBAAiB,CAAC,OAAgC,EAAE;QAClD,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;QAC1D,OAAO,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAA;IAC/C,CAAC;IACD,sBAAsB,CAAC,SAAiB;QACtC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;QAC1D,OAAO,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAA;IACzD,CAAC;IAED,2EAA2E;IAC3E,kBAAkB,CAAC,OAAgC,EAAE;QACnD,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;QAC1D,OAAO,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAA;IAChD,CAAC;IACD,sBAAsB,CAAC,QAAgB;QACrC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;QAC1D,OAAO,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAA;IACxD,CAAC;IACD,iBAAiB,CAAC,QAAgB;QAChC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;QAC1D,OAAO,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAA;IACnD,CAAC;IAED,mEAAmE;IACnE,WAAW;QACT,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,4EAA4E;IAC5E,kBAAkB,CAAC,QAAsC;QACvD,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACjC,OAAO,GAAG,EAAE;YACV,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACtC,CAAC,CAAA;IACH,CAAC;IAED,0EAA0E;IAC1E,KAAK,CAAC,gBAAgB,CAAC,IAAyB;QAC9C,wEAAwE;QACxE,6EAA6E;QAC7E,kBAAkB,GAAG,IAAI,CAAA;QACzB,MAAM,CAAC,GAAG,MAAM,CAAA;QAChB,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACnB,MAAM,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAA;QACxC,CAAC;IACH,CAAC;IAED,cAAc,CAAC,KAAiB;QAC9B,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;IACvC,CAAC;IAED,YAAY,CAAC,EAAkC;QAC7C,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC3B,OAAO,GAAG,EAAE;YACV,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAChC,CAAC,CAAA;IACH,CAAC;IAED,aAAa,CAAC,EAAgC;QAC5C,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC5B,OAAO,GAAG,EAAE;YACV,oBAAoB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QACjC,CAAC,CAAA;IACH,CAAC;IAED,SAAS;QACP,OAAO,oBAAoB,EAAE,CAAA;IAC/B,CAAC;IAED,UAAU;QACR,OAAO,gBAAgB,EAAE,CAAC,IAAI,CAAA;IAChC,CAAC;IAED,wBAAwB;QACtB,OAAO,8BAA8B,EAAE,CAAA;IACzC,CAAC;IAED,eAAe,CAAC,EAAiD;QAC/D,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACvB,OAAO,GAAG,EAAE;YACV,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAC5B,CAAC,CAAA;IACH,CAAC;IAED,GAAG,EAAE;QACH,KAAK,CAAC,IAAY,EAAE,OAA+D;YACjF,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;YAC1D,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAChD,CAAC;KACF;IAED,IAAI,EAAE;QACJ,UAAU,CAAC,GAAgE;YACzE,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;YAC1D,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;QAC5C,CAAC;QACD,cAAc,CAAC,KAAsE;YACnF,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;YAC1D,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;QAClD,CAAC;QACD,iBAAiB,CAAC,GAAuE;YACvF,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;YAC1D,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAA;QACnD,CAAC;QACD,YAAY,CAAC,GAAkE;YAC7E,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;YAC1D,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;QAC9C,CAAC;KACF;IAED,IAAI,EAAE;QACJ,OAAO,EAAE;YACP,MAAM,CAAC,GAAG,IAAgD;gBACxD,OAAO,aAAa,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAA;YAChD,CAAC;YACD,OAAO,CAAC,GAAG,IAAiD;gBAC1D,OAAO,aAAa,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAA;YACjD,CAAC;YACD,cAAc,CAAC,GAAG,IAAwD;gBACxE,OAAO,aAAa,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,CAAA;YACxD,CAAC;YACD,QAAQ,CAAC,GAAG,IAAkD;gBAC5D,OAAO,aAAa,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAA;YAClD,CAAC;SACF;KACF;IAED,qBAAqB;QACnB,OAAO,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAA;IACtC,CAAC;CACF,CAAA","sourcesContent":["/**\n * Owns the singleton `@mentra/cloud-client` (CloudClient) for the engine runtime\n * — the keystone move that pulls backend comms INTO engine.\n *\n * engine constructs the client from engine-owned pieces (the native UDP socket,\n * the MMKV secure store, the cloud-status store) plus the two things the host\n * provides through the engine front door: `auth.getSubjectToken` (the one\n * permanent seam — the OEM owns login) and the resolved cloud endpoints\n * (`config.coreUrl/runtimeUrl`, computed host-side from dev/settings). On init it\n * exposes cloud runtime methods directly from this service, so the host no longer\n * injects a cloud adapter — engine owns construction and wiring.\n *\n * The local-miniapp path drives the cloud's transcription/translation through\n * this service.\n */\nimport {CloudClient, setNativeHttp, setNativeUdp, setSecureStorage} from \"@mentra/cloud-client/react-native\"\nimport type {PreinstalledMiniappRegistry, RuntimeSnapshot} from \"@mentra/cloud-client/react-native\"\nimport type {SubjectTokenType} from \"@mentra/cloud-client\"\nimport {Platform} from \"react-native\"\nimport type {AudioSubscription, TranscriptionData, TranslationData} from \"@mentra/cloud-protocol\"\n\nimport BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\nimport CrustModule from \"@mentra/crust\"\nimport {getAuth, getConfigValues} from \"../runtime/bootstrap\"\nimport {useSettingsStore, SETTINGS} from \"../stores/settings\"\nimport {type CloudClientStatusSnapshot, type MiniappAuthToken} from \"../runtime/config\"\nimport {createCloudUdpSocket} from \"../utils/cloudClient/RnUdpAdapter\"\nimport {cloudSecureStore} from \"../utils/cloudClient/cloudSecureStore\"\nimport {useCloudClientStatusStore} from \"../stores/cloudClientStatus\"\nimport {islandNotifications} from \"./NotificationsEmitter\"\nimport {BgTimer} from \"../utils/timers\"\nimport {logCloudV2TranscriptMetric} from \"./CloudTranscriptE2EMetrics\"\nimport {nativeHttpResponseBody} from \"./NativeHttpResponse\"\n\nconst LOG_TAG = \"cloudClient\"\ntype CloudCore = NonNullable<CloudClient[\"core\"]>\n\n// Persistent cloud-disconnect detector: the cloud-client reconnect loop is infinite\n// and never surfaces a \"giving up\" signal, so \"persistent failure\" = the session has\n// been continuously NOT connected for this long. A quick reconnect cancels it; brief\n// flaps that recover don't fire. Raised as engine.notifications(connection_failed_persistent).\nconst CLOUD_PERSISTENT_FAILURE_MS = 60_000\n\n/** Cancel the pending persistent-failure alarm + re-arm for the next outage. */\nfunction clearPersistentFailureAlarm(): void {\n if (persistentFailureTimer) {\n BgTimer.clearTimeout(persistentFailureTimer)\n persistentFailureTimer = null\n }\n persistentFailureNotified = false\n}\n\ntype Lc3FrameSizeBytes = 20 | 40 | 60\n\n// Neutral last-ditch fallbacks (reachable under `adb reverse`) for when the host\n// passes no endpoints. The host normally resolves the real URLs (dev override /\n// Metro host / env) and hands them in via `engine.configure({config})`.\nconst FALLBACK_CORE_URL = \"http://localhost:3000\"\nconst FALLBACK_RUNTIME_URL = \"http://localhost:3001\"\nconst LOCAL_AUTH_PORT = 3002\n\nlet client: CloudClient | null = null\nlet connected = false\nlet persistentFailureTimer: ReturnType<typeof BgTimer.setTimeout> | null = null\nlet persistentFailureNotified = false\nlet audioSubscriptions: AudioSubscription[] = []\nlet transportsReady = false\n/** Endpoints to build with — seeded from config, overridable via reconnect(). */\nlet endpointsOverride: {core: string; runtime: string} | null = null\nlet runtimeStatusUnsubscribe: (() => void) | null = null\nlet transcriptUnsubscribe: (() => void) | null = null\nlet translationUnsubscribe: (() => void) | null = null\nlet authStateUnsubscribe: (() => void) | null = null\nlet localDevRuntimeToken: {runtimeUrl: string; token: string; expiresAtMs: number} | null = null\nlet lc3FrameSizeUnsubscribe: (() => void) | null = null\nlet coreTokenSyncPromise: Promise<string> | null = null\n\nconst transcriptListeners = new Set<(d: TranscriptionData) => void>()\nconst translationListeners = new Set<(d: TranslationData) => void>()\nconst statusListeners = new Set<(snapshot: CloudClientStatusSnapshot) => void>()\nconst connectionListeners = new Set<(connected: boolean) => void>()\n\nfunction resolveEndpoints(): {core: string; runtime: string} {\n if (endpointsOverride) return endpointsOverride\n const cfg = getConfigValues()\n return {\n core: cfg.coreUrl?.trim() || FALLBACK_CORE_URL,\n runtime: cfg.runtimeUrl?.trim() || FALLBACK_RUNTIME_URL,\n }\n}\n\nfunction getCoreClient(): CloudCore {\n if (!client) construct()\n const core = client?.core\n if (!core) throw new Error(\"cloud client core not configured\")\n return core\n}\n\nfunction syncCoreAccessTokenToBluetooth(): Promise<string> {\n if (coreTokenSyncPromise) return coreTokenSyncPromise\n\n coreTokenSyncPromise = syncCoreAccessTokenToBluetoothInternal().finally(() => {\n coreTokenSyncPromise = null\n })\n return coreTokenSyncPromise\n}\n\nasync function syncCoreAccessTokenToBluetoothInternal(): Promise<string> {\n if (!client) construct()\n const c = client\n if (!c) throw new Error(\"cloud client not initialized\")\n\n const token = await c.auth.getCoreToken()\n if (c !== client) {\n throw new Error(\"cloud client changed while syncing core token\")\n }\n const result = await useSettingsStore.getState().setSetting(SETTINGS.core_token.key, token, false)\n if (result.is_error()) {\n throw result.error\n }\n\n try {\n await BluetoothSdk.updateBluetoothSettings({[SETTINGS.core_token.key]: token})\n } catch (err) {\n console.warn(`${LOG_TAG}: direct Bluetooth core_token sync failed: ${(err as Error)?.message ?? err}`)\n }\n\n return token\n}\n\nfunction frameSizeBytes(): Lc3FrameSizeBytes {\n // Read LIVE from the engine settings store (the source of truth) so a\n // reconnect after a glasses swap (G1=20 ↔ G2=40) picks up the new frame size,\n // not the one-time engine.configure({config}) snapshot. Falls back to the\n // config value (set at boot) then 20 when the setting is unset.\n const fromSettings = useSettingsStore.getState().getSetting(SETTINGS.lc3_frame_size.key)\n const size = fromSettings ?? getConfigValues().audioFrameSizeBytes\n return size === 20 || size === 40 || size === 60 ? size : 20\n}\n\nasync function getSubjectToken(): Promise<{token: string; type: SubjectTokenType}> {\n const a = getAuth()\n if (!a) throw new Error(\"cloudClient: engine.configure({auth}) not called\")\n const r = await a.getSubjectToken()\n // IslandAuth's SubjectTokenType is intentionally open (`string & {}`) so OEMs\n // can use other token kinds; cloud-client's is a closed union. The host's\n // actual value (\"supabase\") is valid — narrow at this boundary.\n return {token: r.token, type: r.type as SubjectTokenType}\n}\n\nfunction normalizeExpiresAt(expiresAt: number): number {\n return expiresAt < 10_000_000_000 ? expiresAt * 1000 : expiresAt\n}\n\nfunction shouldUseLocalDevRuntimeToken(endpoints: {runtime: string}): boolean {\n if (!__DEV__) return false\n try {\n const host = new URL(endpoints.runtime).hostname\n return host === \"localhost\" || host === \"127.0.0.1\" || host === \"10.0.2.2\"\n } catch {\n return false\n }\n}\n\nasync function getLocalDevRuntimeToken(runtimeEndpoint: string, opts?: {forceRefresh?: boolean}): Promise<string> {\n const now = Date.now()\n if (\n !opts?.forceRefresh &&\n localDevRuntimeToken?.runtimeUrl === runtimeEndpoint &&\n localDevRuntimeToken.expiresAtMs - now > 60_000\n ) {\n return localDevRuntimeToken.token\n }\n\n const base = new URL(runtimeEndpoint)\n base.port = String(LOCAL_AUTH_PORT)\n base.pathname = \"/api/dev/runtime-token\"\n base.search = new URLSearchParams({userId: \"local-phone-user\", tenantId: \"mentra\"}).toString()\n\n const res = await fetch(base.toString())\n if (!res.ok) {\n throw new Error(`cloudClient: local dev runtime token failed (${res.status})`)\n }\n const body = (await res.json()) as {access_token?: string; expires_in?: number}\n if (!body.access_token) {\n throw new Error(\"cloudClient: local dev runtime token response missing access_token\")\n }\n localDevRuntimeToken = {\n runtimeUrl: runtimeEndpoint,\n token: body.access_token,\n expiresAtMs: now + (body.expires_in ?? 300) * 1000,\n }\n return body.access_token\n}\n\nfunction toCloudClientStatusSnapshot(snapshot: RuntimeSnapshot): CloudClientStatusSnapshot {\n return {status: snapshot.status, audioTransport: snapshot.audioTransport}\n}\n\nfunction currentRuntimeStatus(): CloudClientStatusSnapshot {\n const state = useCloudClientStatusStore.getState()\n return {status: state.status, audioTransport: state.audioTransport}\n}\n\nfunction setRuntimeStatus(snapshot: RuntimeSnapshot): void {\n useCloudClientStatusStore.getState().setSnapshot(snapshot)\n emitStatus(toCloudClientStatusSnapshot(snapshot))\n}\n\nfunction resetRuntimeStatus(): void {\n useCloudClientStatusStore.getState().reset()\n emitStatus(currentRuntimeStatus())\n}\n\nfunction stringifyMeta(meta: unknown): string {\n if (!meta || typeof meta !== \"object\") return \"\"\n try {\n return ` ${JSON.stringify(meta)}`\n } catch {\n return \"\"\n }\n}\n\nconst cloudLogger = {\n debug: (msg: string, meta?: unknown) => console.log(`${LOG_TAG}: debug: ${msg}${stringifyMeta(meta)}`),\n info: (msg: string, meta?: unknown) => console.log(`${LOG_TAG}: info: ${msg}${stringifyMeta(meta)}`),\n warn: (msg: string, meta?: unknown) => console.warn(`${LOG_TAG}: warn: ${msg}${stringifyMeta(meta)}`),\n error: (msg: string, meta?: unknown) => console.warn(`${LOG_TAG}: error: ${msg}${stringifyMeta(meta)}`),\n}\n\nfunction notifyConnectionListeners(next: boolean): void {\n for (const l of connectionListeners) {\n try {\n l(next)\n } catch (err) {\n console.warn(`${LOG_TAG}: connection listener threw: ${(err as Error)?.message ?? err}`)\n }\n }\n}\n\nfunction extractUnsubscribe(sub: unknown): (() => void) | null {\n const candidates: unknown[] = []\n const s = sub as Record<string, unknown> | null | undefined\n if (s && typeof s === \"object\") {\n candidates.push(s)\n candidates.push((s.value as Record<string, unknown>)?.subscription)\n candidates.push((s.data as Record<string, unknown>)?.subscription)\n candidates.push(s.subscription)\n }\n for (const c of candidates) {\n const unsub = (c as {unsubscribe?: unknown})?.unsubscribe\n if (typeof unsub === \"function\") return unsub as () => void\n }\n return null\n}\n\nfunction ensureAuthWatch(): void {\n if (authStateUnsubscribe) return\n authStateUnsubscribe = () => {}\n\n const auth = getAuth()\n if (!auth?.onStateChange) return\n\n let reconnectPending = false\n try {\n const sub = auth.onStateChange((event, session) => {\n if (!session?.token) return\n if (connected || reconnectPending) return\n\n reconnectPending = true\n console.log(`${LOG_TAG}: auth session available (${event}) while disconnected — reconnecting`)\n try {\n cloudClientService.reconnect()\n } finally {\n setTimeout(() => {\n reconnectPending = false\n }, 0)\n }\n })\n\n const unsub = extractUnsubscribe(sub)\n if (unsub) authStateUnsubscribe = unsub\n } catch (err) {\n console.warn(`${LOG_TAG}: auth watch subscribe failed: ${(err as Error)?.message ?? err}`)\n }\n}\n\nfunction stopAuthWatch(): void {\n authStateUnsubscribe?.()\n authStateUnsubscribe = null\n}\n\nfunction emitTranscript(data: TranscriptionData): void {\n for (const l of transcriptListeners) {\n try {\n l(data)\n } catch (err) {\n console.warn(`${LOG_TAG}: transcript listener threw: ${(err as Error)?.message ?? err}`)\n }\n }\n}\n\nfunction emitTranslation(data: TranslationData): void {\n for (const l of translationListeners) {\n try {\n l(data)\n } catch (err) {\n console.warn(`${LOG_TAG}: translation listener threw: ${(err as Error)?.message ?? err}`)\n }\n }\n}\n\nfunction emitStatus(snapshot: CloudClientStatusSnapshot): void {\n for (const l of statusListeners) {\n try {\n l(snapshot)\n } catch (err) {\n console.warn(`${LOG_TAG}: status listener threw: ${(err as Error)?.message ?? err}`)\n }\n }\n}\n\nfunction ensureTransports(): void {\n if (transportsReady) return\n transportsReady = true\n setNativeUdp(() => createCloudUdpSocket())\n setSecureStorage(cloudSecureStore)\n if (Platform.OS !== \"android\") return\n setNativeHttp(async (input, init) => {\n if (typeof input !== \"string\" || (init?.body != null && typeof init.body !== \"string\")) {\n return globalThis.fetch(input, init)\n }\n const headers = Object.fromEntries(new Headers(init?.headers).entries())\n const result = await CrustModule.nativeHttpRequest(\n init?.method ?? \"GET\",\n input,\n headers,\n (init?.body as string | undefined) ?? null,\n )\n return new Response(nativeHttpResponseBody(result.status, result.body), {\n status: result.status,\n statusText: result.statusText,\n headers: result.headers,\n })\n })\n}\n\nfunction clearRuntimeEventSubscriptions(): void {\n runtimeStatusUnsubscribe?.()\n runtimeStatusUnsubscribe = null\n transcriptUnsubscribe?.()\n transcriptUnsubscribe = null\n translationUnsubscribe?.()\n translationUnsubscribe = null\n}\n\nfunction startLc3FrameSizeWatcher(): void {\n if (lc3FrameSizeUnsubscribe) return\n\n let last = frameSizeBytes()\n lc3FrameSizeUnsubscribe = useSettingsStore.subscribe(\n (state) => state.getSetting(SETTINGS.lc3_frame_size.key),\n () => {\n const next = frameSizeBytes()\n if (next === last) return\n last = next\n if (!client) return\n console.log(`${LOG_TAG}: LC3 frame size changed to ${next}; reconnecting runtime`)\n cloudClientService.reconnect()\n },\n )\n}\n\nfunction stopLc3FrameSizeWatcher(): void {\n lc3FrameSizeUnsubscribe?.()\n lc3FrameSizeUnsubscribe = null\n}\n\nfunction construct(): void {\n ensureTransports()\n\n const endpoints = resolveEndpoints()\n console.log(`${LOG_TAG}: endpoints ${JSON.stringify(endpoints)}`)\n\n const coreAuth = {getSubjectToken}\n const auth = shouldUseLocalDevRuntimeToken(endpoints)\n ? {\n core: coreAuth,\n runtime: {getToken: (opts?: {forceRefresh?: boolean}) => getLocalDevRuntimeToken(endpoints.runtime, opts)},\n }\n : {core: coreAuth, runtime: {source: \"core\" as const}}\n\n client = new CloudClient({\n endpoints,\n // The phone LC3-encodes mic audio (even in phone/simulated mode); announce\n // LC3 at 16 kHz with the frame size the encoder emits.\n audio: {codec: \"lc3\", sampleRate: 16000, frameSizeBytes: frameSizeBytes()},\n auth,\n logger: cloudLogger,\n })\n\n const c = client\n clearRuntimeEventSubscriptions()\n runtimeStatusUnsubscribe = c.runtime.onStatusChanged((status) => {\n if (c !== client) return\n setRuntimeStatus(status)\n })\n transcriptUnsubscribe = c.runtime.onTranscript((data) => {\n if (c !== client) return\n logCloudV2TranscriptMetric(data)\n emitTranscript(data)\n })\n translationUnsubscribe = c.runtime.onTranslation((data) => {\n if (c !== client) return\n emitTranslation(data)\n })\n setRuntimeStatus(c.runtime.getStatus())\n\n c.runtime.onConnected(() => {\n if (c !== client) return\n connected = true\n console.log(`${LOG_TAG}: runtime connected`)\n // Cloud is up — cancel any pending persistent-failure alarm and re-arm for the\n // next outage.\n clearPersistentFailureAlarm()\n // Re-apply the authoritative subscription set, including the empty set, so\n // a fresh phone launch clears any stale server-side audio subscriptions.\n c.runtime\n .setSubscriptions(audioSubscriptions)\n .catch((err) =>\n console.warn(`${LOG_TAG}: re-applying queued subscriptions failed: ${(err as Error)?.message ?? err}`),\n )\n notifyConnectionListeners(true)\n })\n c.runtime.onDisconnected((info) => {\n if (c !== client) return\n connected = false\n console.log(`${LOG_TAG}: runtime disconnected (${info.reason})`)\n // Arm the persistent-failure alarm once; if we're still down when it fires, raise\n // the notification. A reconnect within the window cancels it (onConnected above).\n if (!persistentFailureTimer && !persistentFailureNotified) {\n persistentFailureTimer = BgTimer.setTimeout(() => {\n persistentFailureTimer = null\n if (connected) return\n persistentFailureNotified = true\n islandNotifications.emit({\n kind: \"connection_failed_persistent\",\n reason: `Cloud session has been disconnected for over ${Math.round(CLOUD_PERSISTENT_FAILURE_MS / 1000)}s`,\n metadata: {downForMs: CLOUD_PERSISTENT_FAILURE_MS, lastReason: info.reason},\n timestamp: Date.now(),\n })\n }, CLOUD_PERSISTENT_FAILURE_MS)\n }\n notifyConnectionListeners(false)\n })\n c.runtime.onError((err) => {\n console.warn(`${LOG_TAG}: runtime error: ${err.code}`)\n })\n\n // Best-effort connect. Do not crash the app if the dev cloud is unreachable.\n c.runtime\n .connect()\n .then(() => console.log(`${LOG_TAG}: connect() resolved`))\n .catch((err) => console.warn(`${LOG_TAG}: connect() failed: ${err?.message ?? err}`))\n\n syncCoreAccessTokenToBluetooth().catch((err) =>\n console.warn(`${LOG_TAG}: initial Bluetooth core_token sync failed: ${(err as Error)?.message ?? err}`),\n )\n\n startLc3FrameSizeWatcher()\n}\n\n/**\n * engine's cloud client. Owns the singleton CloudClient, its connection state,\n * and the runtime-hook wiring.\n */\nexport const cloudClientService = {\n /**\n * Construct (once) + connect the client. Idempotent. Best-effort connect — a\n * failure is logged and the app keeps running. Requires\n * `engine.configure({auth, config})` first.\n */\n init(): void {\n if (client) return\n ensureAuthWatch()\n construct()\n },\n\n /**\n * Tear down + rebuild. Pass new endpoints to switch URLs; pass `null` to CLEAR\n * a prior override and fall back to the boot config (so cleared/default cloud\n * URLs don't keep reconnecting to a stale override); omit to keep the current.\n */\n reconnect(endpoints?: {core: string; runtime: string} | null): void {\n if (endpoints !== undefined) endpointsOverride = endpoints\n try {\n client?.runtime.close()\n } catch (err) {\n console.warn(`${LOG_TAG}: reconnect close() failed: ${(err as Error)?.message ?? err}`)\n }\n clearRuntimeEventSubscriptions()\n clearPersistentFailureAlarm()\n\n const wasConnected = connected\n client = null\n localDevRuntimeToken = null\n connected = false\n resetRuntimeStatus()\n if (wasConnected) notifyConnectionListeners(false)\n\n construct()\n },\n\n async getPreinstalledMiniappRegistry(): Promise<PreinstalledMiniappRegistry> {\n if (!client) this.init()\n const c = client\n if (!c?.core) throw new Error(\"cloud client core is unavailable\")\n return c.core.miniapps.getRegistry()\n },\n\n async getMiniappAuthToken(\n packageName: string,\n opts?: {minTtlMs?: number; devAttestation?: string},\n ): Promise<MiniappAuthToken> {\n if (!client) this.init()\n const c = client\n if (!c) throw new Error(\"cloud client not initialized\")\n\n const {token, expiresAt} = await c.auth.getMiniappToken(packageName, opts)\n const identity = c.auth.identity\n return {\n mentraUserId: identity.mentraUserId,\n tenantId: identity.tenantId,\n token,\n expiresAt: normalizeExpiresAt(expiresAt),\n }\n },\n\n /** Tear down the client + connection (the engine.stop() lifecycle). */\n stop(): void {\n try {\n client?.runtime.close()\n } catch (err) {\n console.warn(`${LOG_TAG}: stop close() failed: ${(err as Error)?.message ?? err}`)\n }\n stopLc3FrameSizeWatcher()\n stopAuthWatch()\n clearRuntimeEventSubscriptions()\n clearPersistentFailureAlarm()\n const wasConnected = connected\n client = null\n localDevRuntimeToken = null\n connected = false\n resetRuntimeStatus()\n if (wasConnected) notifyConnectionListeners(false)\n },\n\n /** Device-side managed photo (cloud-v2): presign now, deliver bytes, await ready. */\n startManagedPhoto(opts: Record<string, unknown> = {}) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.startManagedPhoto(opts)\n },\n awaitManagedPhotoReady(requestId: string) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.awaitManagedPhotoReady(requestId)\n },\n\n /** Managed stream (cloud-v2): provision ingest+playback on the runtime. */\n startManagedStream(opts: Record<string, unknown> = {}) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.startManagedStream(opts)\n },\n getManagedStreamStatus(streamId: string) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.getManagedStreamStatus(streamId)\n },\n stopManagedStream(streamId: string) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.stopManagedStream(streamId)\n },\n\n /** Current live-session connection state (handshake completed). */\n isConnected(): boolean {\n return connected\n },\n\n /** Subscribe to connection-state transitions. Returns an unsubscribe fn. */\n onConnectionChange(listener: (connected: boolean) => void): () => void {\n connectionListeners.add(listener)\n return () => {\n connectionListeners.delete(listener)\n }\n },\n\n /** Replace the v2 cloud's audio subscription set for the live session. */\n async setSubscriptions(subs: AudioSubscription[]): Promise<void> {\n // Cache unconditionally so the desired set survives a not-yet-connected\n // session and reconnects; the onConnected handler re-applies the cached set.\n audioSubscriptions = subs\n const c = client\n if (connected && c) {\n await c.runtime.setSubscriptions(subs)\n }\n },\n\n sendAudioFrame(frame: Uint8Array): void {\n client?.runtime.sendAudioFrame(frame)\n },\n\n onTranscript(cb: (d: TranscriptionData) => void): () => void {\n transcriptListeners.add(cb)\n return () => {\n transcriptListeners.delete(cb)\n }\n },\n\n onTranslation(cb: (d: TranslationData) => void): () => void {\n translationListeners.add(cb)\n return () => {\n translationListeners.delete(cb)\n }\n },\n\n getStatus(): CloudClientStatusSnapshot {\n return currentRuntimeStatus()\n },\n\n getCoreUrl(): string {\n return resolveEndpoints().core\n },\n\n syncCoreTokenToBluetooth(): Promise<string> {\n return syncCoreAccessTokenToBluetooth()\n },\n\n onStatusChanged(cb: (snapshot: CloudClientStatusSnapshot) => void): () => void {\n statusListeners.add(cb)\n return () => {\n statusListeners.delete(cb)\n }\n },\n\n tts: {\n speak(text: string, options?: Parameters<CloudClient[\"runtime\"][\"tts\"][\"speak\"]>[1]) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.tts.speak(text, options)\n },\n },\n\n maps: {\n directions(req: Parameters<CloudClient[\"runtime\"][\"maps\"][\"directions\"]>[0]) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.maps.directions(req)\n },\n reverseGeocode(coord: Parameters<CloudClient[\"runtime\"][\"maps\"][\"reverseGeocode\"]>[0]) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.maps.reverseGeocode(coord)\n },\n placeAutocomplete(req: Parameters<CloudClient[\"runtime\"][\"maps\"][\"placeAutocomplete\"]>[0]) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.maps.placeAutocomplete(req)\n },\n placeDetails(req: Parameters<CloudClient[\"runtime\"][\"maps\"][\"placeDetails\"]>[0]) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.maps.placeDetails(req)\n },\n },\n\n core: {\n reports: {\n submit(...args: Parameters<CloudCore[\"reports\"][\"submit\"]>) {\n return getCoreClient().reports.submit(...args)\n },\n addLogs(...args: Parameters<CloudCore[\"reports\"][\"addLogs\"]>) {\n return getCoreClient().reports.addLogs(...args)\n },\n addScreenshots(...args: Parameters<CloudCore[\"reports\"][\"addScreenshots\"]>) {\n return getCoreClient().reports.addScreenshots(...args)\n },\n complete(...args: Parameters<CloudCore[\"reports\"][\"complete\"]>) {\n return getCoreClient().reports.complete(...args)\n },\n },\n },\n\n hasAudioSubscriptions(): boolean {\n return audioSubscriptions.length > 0\n },\n}\n"]}
1
+ {"version":3,"file":"CloudClientService.js","sourceRoot":"","sources":["../../src/services/CloudClientService.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Owns the singleton `@mentra/cloud-client` (CloudClient) for the engine runtime\n * — the keystone move that pulls backend comms INTO engine.\n *\n * engine constructs the client from engine-owned pieces (the native UDP socket,\n * the MMKV secure store, the cloud-status store) plus the two things the host\n * provides through the engine front door: `auth.getSubjectToken` (the one\n * permanent seam — the OEM owns login) and the resolved cloud endpoints\n * (`config.coreUrl/runtimeUrl`, computed host-side from dev/settings). On init it\n * exposes cloud runtime methods directly from this service, so the host no longer\n * injects a cloud adapter — engine owns construction and wiring.\n *\n * The local-miniapp path drives the cloud's transcription/translation through\n * this service.\n */\nimport {CloudClient, setNativeHttp, setNativeUdp, setSecureStorage} from \"@mentra/cloud-client/react-native\"\nimport type {PreinstalledMiniappRegistry, RuntimeSnapshot} from \"@mentra/cloud-client/react-native\"\nimport type {SubjectTokenType} from \"@mentra/cloud-client\"\nimport {Platform} from \"react-native\"\nimport type {AudioSubscription, TranscriptionData, TranslationData} from \"@mentra/cloud-protocol\"\n\nimport BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\nimport CrustModule from \"@mentra/crust\"\nimport {getAuth, getConfigValues} from \"../runtime/bootstrap\"\nimport {useSettingsStore, SETTINGS} from \"../stores/settings\"\nimport {type CloudClientStatusSnapshot, type MiniappAuthToken} from \"../runtime/config\"\nimport {createCloudUdpSocket} from \"../utils/cloudClient/RnUdpAdapter\"\nimport {cloudSecureStore} from \"../utils/cloudClient/cloudSecureStore\"\nimport {storage as mmkvStorage} from \"../utils/storage\"\nimport {useCloudClientStatusStore} from \"../stores/cloudClientStatus\"\nimport {islandNotifications} from \"./NotificationsEmitter\"\nimport {BgTimer} from \"../utils/timers\"\nimport {logCloudV2TranscriptMetric} from \"./CloudTranscriptE2EMetrics\"\nimport {LocalMiniappUserIdentity} from \"./LocalMiniappUserIdentity\"\nimport {nativeHttpResponseBody} from \"./NativeHttpResponse\"\n\nconst LOG_TAG = \"cloudClient\"\ntype CloudCore = NonNullable<CloudClient[\"core\"]>\n\n// Persistent cloud-disconnect detector: the cloud-client reconnect loop is infinite\n// and never surfaces a \"giving up\" signal, so \"persistent failure\" = the session has\n// been continuously NOT connected for this long. A quick reconnect cancels it; brief\n// flaps that recover don't fire. Raised as engine.notifications(connection_failed_persistent).\nconst CLOUD_PERSISTENT_FAILURE_MS = 60_000\nconst LOCAL_MINIAPP_USER_ID_KEY = \"mentra.localMiniapp.userId\"\n\n/** Cancel the pending persistent-failure alarm + re-arm for the next outage. */\nfunction clearPersistentFailureAlarm(): void {\n if (persistentFailureTimer) {\n BgTimer.clearTimeout(persistentFailureTimer)\n persistentFailureTimer = null\n }\n persistentFailureNotified = false\n}\n\ntype Lc3FrameSizeBytes = 20 | 40 | 60\n\n// Neutral last-ditch fallbacks (reachable under `adb reverse`) for when the host\n// passes no endpoints. The host normally resolves the real URLs (dev override /\n// Metro host / env) and hands them in via `engine.configure({config})`.\nconst FALLBACK_CORE_URL = \"http://localhost:3000\"\nconst FALLBACK_RUNTIME_URL = \"http://localhost:3001\"\nconst LOCAL_AUTH_PORT = 3002\n\nlet client: CloudClient | null = null\nlet connected = false\nlet persistentFailureTimer: ReturnType<typeof BgTimer.setTimeout> | null = null\nlet persistentFailureNotified = false\nlet audioSubscriptions: AudioSubscription[] = []\nlet transportsReady = false\n/** Endpoints to build with — seeded from config, overridable via reconnect(). */\nlet endpointsOverride: {core: string; runtime: string} | null = null\nlet runtimeStatusUnsubscribe: (() => void) | null = null\nlet transcriptUnsubscribe: (() => void) | null = null\nlet translationUnsubscribe: (() => void) | null = null\nlet authStateUnsubscribe: (() => void) | null = null\nlet localDevRuntimeToken: {runtimeUrl: string; token: string; expiresAtMs: number} | null = null\nlet lc3FrameSizeUnsubscribe: (() => void) | null = null\nlet coreTokenSyncPromise: Promise<string> | null = null\n\nconst localMiniappUserIdentity = new LocalMiniappUserIdentity({\n get(): string | null {\n const result = mmkvStorage.load<string>(LOCAL_MINIAPP_USER_ID_KEY)\n return result.is_ok() ? result.value : null\n },\n set(userId: string): void {\n const result = mmkvStorage.save(LOCAL_MINIAPP_USER_ID_KEY, userId)\n if (result.is_error()) throw result.error\n },\n remove(): void {\n const result = mmkvStorage.remove(LOCAL_MINIAPP_USER_ID_KEY)\n if (result.is_error()) throw result.error\n },\n})\n\nconst transcriptListeners = new Set<(d: TranscriptionData) => void>()\nconst translationListeners = new Set<(d: TranslationData) => void>()\nconst statusListeners = new Set<(snapshot: CloudClientStatusSnapshot) => void>()\nconst connectionListeners = new Set<(connected: boolean) => void>()\n\nfunction resolveEndpoints(): {core: string; runtime: string} {\n if (endpointsOverride) return endpointsOverride\n const cfg = getConfigValues()\n return {\n core: cfg.coreUrl?.trim() || FALLBACK_CORE_URL,\n runtime: cfg.runtimeUrl?.trim() || FALLBACK_RUNTIME_URL,\n }\n}\n\nfunction getCoreClient(): CloudCore {\n if (!client) construct()\n const core = client?.core\n if (!core) throw new Error(\"cloud client core not configured\")\n return core\n}\n\nfunction syncCoreAccessTokenToBluetooth(): Promise<string> {\n if (coreTokenSyncPromise) return coreTokenSyncPromise\n\n coreTokenSyncPromise = syncCoreAccessTokenToBluetoothInternal().finally(() => {\n coreTokenSyncPromise = null\n })\n return coreTokenSyncPromise\n}\n\nasync function syncCoreAccessTokenToBluetoothInternal(): Promise<string> {\n if (!client) construct()\n const c = client\n if (!c) throw new Error(\"cloud client not initialized\")\n\n const token = await c.auth.getCoreToken()\n if (c !== client) {\n throw new Error(\"cloud client changed while syncing core token\")\n }\n localMiniappUserIdentity.remember(c.auth.identity.mentraUserId)\n const result = await useSettingsStore.getState().setSetting(SETTINGS.core_token.key, token, false)\n if (result.is_error()) {\n throw result.error\n }\n\n try {\n await BluetoothSdk.updateBluetoothSettings({[SETTINGS.core_token.key]: token})\n } catch (err) {\n console.warn(`${LOG_TAG}: direct Bluetooth core_token sync failed: ${(err as Error)?.message ?? err}`)\n }\n\n return token\n}\n\nfunction frameSizeBytes(): Lc3FrameSizeBytes {\n // Read LIVE from the engine settings store (the source of truth) so a\n // reconnect after a glasses swap (G1=20 ↔ G2=40) picks up the new frame size,\n // not the one-time engine.configure({config}) snapshot. Falls back to the\n // config value (set at boot) then 20 when the setting is unset.\n const fromSettings = useSettingsStore.getState().getSetting(SETTINGS.lc3_frame_size.key)\n const size = fromSettings ?? getConfigValues().audioFrameSizeBytes\n return size === 20 || size === 40 || size === 60 ? size : 20\n}\n\nasync function getSubjectToken(): Promise<{token: string; type: SubjectTokenType}> {\n const a = getAuth()\n if (!a) throw new Error(\"cloudClient: engine.configure({auth}) not called\")\n const r = await a.getSubjectToken()\n // IslandAuth's SubjectTokenType is intentionally open (`string & {}`) so OEMs\n // can use other token kinds; cloud-client's is a closed union. The host's\n // actual value (\"supabase\") is valid — narrow at this boundary.\n return {token: r.token, type: r.type as SubjectTokenType}\n}\n\nfunction normalizeExpiresAt(expiresAt: number): number {\n return expiresAt < 10_000_000_000 ? expiresAt * 1000 : expiresAt\n}\n\nfunction shouldUseLocalDevRuntimeToken(endpoints: {runtime: string}): boolean {\n if (!__DEV__) return false\n try {\n const host = new URL(endpoints.runtime).hostname\n return host === \"localhost\" || host === \"127.0.0.1\" || host === \"10.0.2.2\"\n } catch {\n return false\n }\n}\n\nasync function getLocalDevRuntimeToken(runtimeEndpoint: string, opts?: {forceRefresh?: boolean}): Promise<string> {\n const now = Date.now()\n if (\n !opts?.forceRefresh &&\n localDevRuntimeToken?.runtimeUrl === runtimeEndpoint &&\n localDevRuntimeToken.expiresAtMs - now > 60_000\n ) {\n return localDevRuntimeToken.token\n }\n\n const base = new URL(runtimeEndpoint)\n base.port = String(LOCAL_AUTH_PORT)\n base.pathname = \"/api/dev/runtime-token\"\n base.search = new URLSearchParams({userId: \"local-phone-user\", tenantId: \"mentra\"}).toString()\n\n const res = await fetch(base.toString())\n if (!res.ok) {\n throw new Error(`cloudClient: local dev runtime token failed (${res.status})`)\n }\n const body = (await res.json()) as {access_token?: string; expires_in?: number}\n if (!body.access_token) {\n throw new Error(\"cloudClient: local dev runtime token response missing access_token\")\n }\n localDevRuntimeToken = {\n runtimeUrl: runtimeEndpoint,\n token: body.access_token,\n expiresAtMs: now + (body.expires_in ?? 300) * 1000,\n }\n return body.access_token\n}\n\nfunction toCloudClientStatusSnapshot(snapshot: RuntimeSnapshot): CloudClientStatusSnapshot {\n return {status: snapshot.status, audioTransport: snapshot.audioTransport}\n}\n\nfunction currentRuntimeStatus(): CloudClientStatusSnapshot {\n const state = useCloudClientStatusStore.getState()\n return {status: state.status, audioTransport: state.audioTransport}\n}\n\nfunction setRuntimeStatus(snapshot: RuntimeSnapshot): void {\n useCloudClientStatusStore.getState().setSnapshot(snapshot)\n emitStatus(toCloudClientStatusSnapshot(snapshot))\n}\n\nfunction resetRuntimeStatus(): void {\n useCloudClientStatusStore.getState().reset()\n emitStatus(currentRuntimeStatus())\n}\n\nfunction stringifyMeta(meta: unknown): string {\n if (!meta || typeof meta !== \"object\") return \"\"\n try {\n return ` ${JSON.stringify(meta)}`\n } catch {\n return \"\"\n }\n}\n\nconst cloudLogger = {\n debug: (msg: string, meta?: unknown) => console.log(`${LOG_TAG}: debug: ${msg}${stringifyMeta(meta)}`),\n info: (msg: string, meta?: unknown) => console.log(`${LOG_TAG}: info: ${msg}${stringifyMeta(meta)}`),\n warn: (msg: string, meta?: unknown) => console.warn(`${LOG_TAG}: warn: ${msg}${stringifyMeta(meta)}`),\n error: (msg: string, meta?: unknown) => console.warn(`${LOG_TAG}: error: ${msg}${stringifyMeta(meta)}`),\n}\n\nfunction notifyConnectionListeners(next: boolean): void {\n for (const l of connectionListeners) {\n try {\n l(next)\n } catch (err) {\n console.warn(`${LOG_TAG}: connection listener threw: ${(err as Error)?.message ?? err}`)\n }\n }\n}\n\nfunction extractUnsubscribe(sub: unknown): (() => void) | null {\n const candidates: unknown[] = []\n const s = sub as Record<string, unknown> | null | undefined\n if (s && typeof s === \"object\") {\n candidates.push(s)\n candidates.push((s.value as Record<string, unknown>)?.subscription)\n candidates.push((s.data as Record<string, unknown>)?.subscription)\n candidates.push(s.subscription)\n }\n for (const c of candidates) {\n const unsub = (c as {unsubscribe?: unknown})?.unsubscribe\n if (typeof unsub === \"function\") return unsub as () => void\n }\n return null\n}\n\nfunction ensureAuthWatch(): void {\n if (authStateUnsubscribe) return\n authStateUnsubscribe = () => {}\n\n const auth = getAuth()\n if (!auth?.onStateChange) return\n\n let reconnectPending = false\n try {\n const sub = auth.onStateChange((event, session) => {\n if (event === \"SIGNED_OUT\") {\n localMiniappUserIdentity.forget()\n return\n }\n // A new sign-in may belong to a different account. Force the next\n // storage request to resolve and persist that account's Core identity.\n if (event === \"SIGNED_IN\") localMiniappUserIdentity.forget()\n if (!session?.token) return\n if (connected || reconnectPending) return\n\n reconnectPending = true\n console.log(`${LOG_TAG}: auth session available (${event}) while disconnected — reconnecting`)\n try {\n cloudClientService.reconnect()\n } finally {\n setTimeout(() => {\n reconnectPending = false\n }, 0)\n }\n })\n\n const unsub = extractUnsubscribe(sub)\n if (unsub) authStateUnsubscribe = unsub\n } catch (err) {\n console.warn(`${LOG_TAG}: auth watch subscribe failed: ${(err as Error)?.message ?? err}`)\n }\n}\n\nfunction stopAuthWatch(): void {\n authStateUnsubscribe?.()\n authStateUnsubscribe = null\n}\n\nfunction emitTranscript(data: TranscriptionData): void {\n for (const l of transcriptListeners) {\n try {\n l(data)\n } catch (err) {\n console.warn(`${LOG_TAG}: transcript listener threw: ${(err as Error)?.message ?? err}`)\n }\n }\n}\n\nfunction emitTranslation(data: TranslationData): void {\n for (const l of translationListeners) {\n try {\n l(data)\n } catch (err) {\n console.warn(`${LOG_TAG}: translation listener threw: ${(err as Error)?.message ?? err}`)\n }\n }\n}\n\nfunction emitStatus(snapshot: CloudClientStatusSnapshot): void {\n for (const l of statusListeners) {\n try {\n l(snapshot)\n } catch (err) {\n console.warn(`${LOG_TAG}: status listener threw: ${(err as Error)?.message ?? err}`)\n }\n }\n}\n\nfunction ensureTransports(): void {\n if (transportsReady) return\n transportsReady = true\n setNativeUdp(() => createCloudUdpSocket())\n setSecureStorage(cloudSecureStore)\n if (Platform.OS !== \"android\") return\n setNativeHttp(async (input, init) => {\n if (typeof input !== \"string\" || (init?.body != null && typeof init.body !== \"string\")) {\n return globalThis.fetch(input, init)\n }\n const headers = Object.fromEntries(new Headers(init?.headers).entries())\n const result = await CrustModule.nativeHttpRequest(\n init?.method ?? \"GET\",\n input,\n headers,\n (init?.body as string | undefined) ?? null,\n )\n return new Response(nativeHttpResponseBody(result.status, result.body), {\n status: result.status,\n statusText: result.statusText,\n headers: result.headers,\n })\n })\n}\n\nfunction clearRuntimeEventSubscriptions(): void {\n runtimeStatusUnsubscribe?.()\n runtimeStatusUnsubscribe = null\n transcriptUnsubscribe?.()\n transcriptUnsubscribe = null\n translationUnsubscribe?.()\n translationUnsubscribe = null\n}\n\nfunction startLc3FrameSizeWatcher(): void {\n if (lc3FrameSizeUnsubscribe) return\n\n let last = frameSizeBytes()\n lc3FrameSizeUnsubscribe = useSettingsStore.subscribe(\n (state) => state.getSetting(SETTINGS.lc3_frame_size.key),\n () => {\n const next = frameSizeBytes()\n if (next === last) return\n last = next\n if (!client) return\n console.log(`${LOG_TAG}: LC3 frame size changed to ${next}; reconnecting runtime`)\n cloudClientService.reconnect()\n },\n )\n}\n\nfunction stopLc3FrameSizeWatcher(): void {\n lc3FrameSizeUnsubscribe?.()\n lc3FrameSizeUnsubscribe = null\n}\n\nfunction construct(): void {\n ensureTransports()\n\n const endpoints = resolveEndpoints()\n console.log(`${LOG_TAG}: endpoints ${JSON.stringify(endpoints)}`)\n\n const coreAuth = {getSubjectToken}\n const auth = shouldUseLocalDevRuntimeToken(endpoints)\n ? {\n core: coreAuth,\n runtime: {getToken: (opts?: {forceRefresh?: boolean}) => getLocalDevRuntimeToken(endpoints.runtime, opts)},\n }\n : {core: coreAuth, runtime: {source: \"core\" as const}}\n\n client = new CloudClient({\n endpoints,\n // The phone LC3-encodes mic audio (even in phone/simulated mode); announce\n // LC3 at 16 kHz with the frame size the encoder emits.\n audio: {codec: \"lc3\", sampleRate: 16000, frameSizeBytes: frameSizeBytes()},\n auth,\n timers: {\n setTimeout: (callback, delayMs) => BgTimer.setTimeout(callback, delayMs),\n clearTimeout: (handle) => BgTimer.clearTimeout(handle as number),\n setInterval: (callback, intervalMs) => BgTimer.setInterval(callback, intervalMs),\n clearInterval: (handle) => BgTimer.clearInterval(handle as number),\n },\n logger: cloudLogger,\n })\n\n const c = client\n clearRuntimeEventSubscriptions()\n runtimeStatusUnsubscribe = c.runtime.onStatusChanged((status) => {\n if (c !== client) return\n setRuntimeStatus(status)\n })\n transcriptUnsubscribe = c.runtime.onTranscript((data) => {\n if (c !== client) return\n logCloudV2TranscriptMetric(data)\n emitTranscript(data)\n })\n translationUnsubscribe = c.runtime.onTranslation((data) => {\n if (c !== client) return\n emitTranslation(data)\n })\n setRuntimeStatus(c.runtime.getStatus())\n\n c.runtime.onConnected(() => {\n if (c !== client) return\n connected = true\n console.log(`${LOG_TAG}: runtime connected`)\n console.log(`${LOG_TAG}: debug: ws-session-debug connected`)\n // Cloud is up — cancel any pending persistent-failure alarm and re-arm for the\n // next outage.\n clearPersistentFailureAlarm()\n // Re-apply the authoritative subscription set, including the empty set, so\n // a fresh phone launch clears any stale server-side audio subscriptions.\n c.runtime\n .setSubscriptions(audioSubscriptions)\n .catch((err) =>\n console.warn(`${LOG_TAG}: re-applying queued subscriptions failed: ${(err as Error)?.message ?? err}`),\n )\n notifyConnectionListeners(true)\n })\n c.runtime.onDisconnected((info) => {\n if (c !== client) return\n connected = false\n console.log(`${LOG_TAG}: runtime disconnected (${info.reason})`)\n console.log(\n `${LOG_TAG}: debug: ws-session-debug disconnected reason=${info.reason} willStayDown=${/superseded by newer session/i.test(info.reason)}`,\n )\n // Arm the persistent-failure alarm once; if we're still down when it fires, raise\n // the notification. A reconnect within the window cancels it (onConnected above).\n if (!persistentFailureTimer && !persistentFailureNotified) {\n persistentFailureTimer = BgTimer.setTimeout(() => {\n persistentFailureTimer = null\n if (connected) return\n persistentFailureNotified = true\n islandNotifications.emit({\n kind: \"connection_failed_persistent\",\n reason: `Cloud session has been disconnected for over ${Math.round(CLOUD_PERSISTENT_FAILURE_MS / 1000)}s`,\n metadata: {downForMs: CLOUD_PERSISTENT_FAILURE_MS, lastReason: info.reason},\n timestamp: Date.now(),\n })\n }, CLOUD_PERSISTENT_FAILURE_MS)\n }\n notifyConnectionListeners(false)\n })\n c.runtime.onError((err) => {\n console.warn(`${LOG_TAG}: runtime error: ${err.code}`)\n })\n\n // Best-effort connect. Do not crash the app if the dev cloud is unreachable.\n c.runtime\n .connect()\n .then(() => console.log(`${LOG_TAG}: connect() resolved`))\n .catch((err) => console.warn(`${LOG_TAG}: connect() failed: ${err?.message ?? err}`))\n\n syncCoreAccessTokenToBluetooth().catch((err) =>\n console.warn(`${LOG_TAG}: initial Bluetooth core_token sync failed: ${(err as Error)?.message ?? err}`),\n )\n\n startLc3FrameSizeWatcher()\n}\n\n/**\n * engine's cloud client. Owns the singleton CloudClient, its connection state,\n * and the runtime-hook wiring.\n */\nexport const cloudClientService = {\n /**\n * Construct (once) + connect the client. Idempotent. Best-effort connect — a\n * failure is logged and the app keeps running. Requires\n * `engine.configure({auth, config})` first.\n */\n init(): void {\n if (client) return\n ensureAuthWatch()\n construct()\n },\n\n /**\n * Tear down + rebuild. Pass new endpoints to switch URLs; pass `null` to CLEAR\n * a prior override and fall back to the boot config (so cleared/default cloud\n * URLs don't keep reconnecting to a stale override); omit to keep the current.\n */\n reconnect(endpoints?: {core: string; runtime: string} | null): void {\n if (endpoints !== undefined) endpointsOverride = endpoints\n try {\n client?.runtime.close()\n } catch (err) {\n console.warn(`${LOG_TAG}: reconnect close() failed: ${(err as Error)?.message ?? err}`)\n }\n clearRuntimeEventSubscriptions()\n clearPersistentFailureAlarm()\n\n const wasConnected = connected\n client = null\n localDevRuntimeToken = null\n connected = false\n resetRuntimeStatus()\n if (wasConnected) notifyConnectionListeners(false)\n\n construct()\n },\n\n async getPreinstalledMiniappRegistry(): Promise<PreinstalledMiniappRegistry> {\n if (!client) this.init()\n const c = client\n if (!c?.core) throw new Error(\"cloud client core is unavailable\")\n return c.core.miniapps.getRegistry()\n },\n\n /**\n * Resolve the stable Core-owned Mentra user id.\n *\n * Storage must use this identity rather than the short-lived Core access\n * token. A previously verified id is restored from MMKV so local miniapps\n * remain available after an offline process restart. On first sign-in,\n * callers join the auth module's single-flight exchange/refresh instead of\n * falling back to an anonymous namespace.\n */\n async resolveMentraUserId(): Promise<string> {\n return localMiniappUserIdentity.resolve(async () => {\n if (!client) this.init()\n const c = client\n if (!c) throw new Error(\"cloud client not initialized\")\n\n await c.auth.getCoreToken()\n if (c !== client) throw new Error(\"cloud client changed while resolving user identity\")\n return c.auth.identity.mentraUserId\n })\n },\n\n /** Read the stable Mentra user id after async identity resolution. */\n getMentraUserId(): string {\n const userId = localMiniappUserIdentity.get()\n if (!userId) throw new Error(\"Mentra user identity is unavailable\")\n return userId\n },\n\n async getMiniappAuthToken(\n packageName: string,\n opts?: {minTtlMs?: number; devAttestation?: string},\n ): Promise<MiniappAuthToken> {\n if (!client) this.init()\n const c = client\n if (!c) throw new Error(\"cloud client not initialized\")\n\n const {token, expiresAt} = await c.auth.getMiniappToken(packageName, opts)\n const identity = c.auth.identity\n return {\n mentraUserId: identity.mentraUserId,\n tenantId: identity.tenantId,\n token,\n expiresAt: normalizeExpiresAt(expiresAt),\n }\n },\n\n /** Tear down the client + connection (the engine.stop() lifecycle). */\n stop(): void {\n try {\n client?.runtime.close()\n } catch (err) {\n console.warn(`${LOG_TAG}: stop close() failed: ${(err as Error)?.message ?? err}`)\n }\n stopLc3FrameSizeWatcher()\n stopAuthWatch()\n clearRuntimeEventSubscriptions()\n clearPersistentFailureAlarm()\n const wasConnected = connected\n client = null\n // stop() is part of the logout lifecycle and runs before the host emits\n // SIGNED_OUT. Remove the persisted namespace owner here so a later account\n // can never inherit it. A force-stop/process kill does not call stop(), so\n // the cached id still survives the offline cold-start case.\n localMiniappUserIdentity.forget()\n localDevRuntimeToken = null\n connected = false\n resetRuntimeStatus()\n if (wasConnected) notifyConnectionListeners(false)\n },\n\n /** Device-side managed photo (cloud-v2): presign now, deliver bytes, await ready. */\n startManagedPhoto(opts: Record<string, unknown> = {}) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.startManagedPhoto(opts)\n },\n awaitManagedPhotoReady(requestId: string) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.awaitManagedPhotoReady(requestId)\n },\n\n /** Managed stream (cloud-v2): provision ingest+playback on the runtime. */\n startManagedStream(opts: Record<string, unknown> = {}) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.startManagedStream(opts)\n },\n getManagedStreamStatus(streamId: string) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.getManagedStreamStatus(streamId)\n },\n stopManagedStream(streamId: string) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.stopManagedStream(streamId)\n },\n\n /** Current live-session connection state (handshake completed). */\n isConnected(): boolean {\n return connected\n },\n\n /** Subscribe to connection-state transitions. Returns an unsubscribe fn. */\n onConnectionChange(listener: (connected: boolean) => void): () => void {\n connectionListeners.add(listener)\n return () => {\n connectionListeners.delete(listener)\n }\n },\n\n /** Replace the v2 cloud's audio subscription set for the live session. */\n async setSubscriptions(subs: AudioSubscription[]): Promise<void> {\n // Cache unconditionally so the desired set survives a not-yet-connected\n // session and reconnects; the onConnected handler re-applies the cached set.\n audioSubscriptions = subs\n const c = client\n if (connected && c) {\n await c.runtime.setSubscriptions(subs)\n }\n },\n\n sendAudioFrame(frame: Uint8Array): void {\n client?.runtime.sendAudioFrame(frame)\n },\n\n onTranscript(cb: (d: TranscriptionData) => void): () => void {\n transcriptListeners.add(cb)\n return () => {\n transcriptListeners.delete(cb)\n }\n },\n\n onTranslation(cb: (d: TranslationData) => void): () => void {\n translationListeners.add(cb)\n return () => {\n translationListeners.delete(cb)\n }\n },\n\n getStatus(): CloudClientStatusSnapshot {\n return currentRuntimeStatus()\n },\n\n getCoreUrl(): string {\n return resolveEndpoints().core\n },\n\n syncCoreTokenToBluetooth(): Promise<string> {\n return syncCoreAccessTokenToBluetooth()\n },\n\n onStatusChanged(cb: (snapshot: CloudClientStatusSnapshot) => void): () => void {\n statusListeners.add(cb)\n return () => {\n statusListeners.delete(cb)\n }\n },\n\n tts: {\n speak(text: string, options?: Parameters<CloudClient[\"runtime\"][\"tts\"][\"speak\"]>[1]) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.tts.speak(text, options)\n },\n },\n\n maps: {\n directions(req: Parameters<CloudClient[\"runtime\"][\"maps\"][\"directions\"]>[0]) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.maps.directions(req)\n },\n reverseGeocode(coord: Parameters<CloudClient[\"runtime\"][\"maps\"][\"reverseGeocode\"]>[0]) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.maps.reverseGeocode(coord)\n },\n placeAutocomplete(req: Parameters<CloudClient[\"runtime\"][\"maps\"][\"placeAutocomplete\"]>[0]) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.maps.placeAutocomplete(req)\n },\n placeDetails(req: Parameters<CloudClient[\"runtime\"][\"maps\"][\"placeDetails\"]>[0]) {\n if (!client) throw new Error(\"cloud client not connected\")\n return client.runtime.maps.placeDetails(req)\n },\n },\n\n core: {\n reports: {\n submit(...args: Parameters<CloudCore[\"reports\"][\"submit\"]>) {\n return getCoreClient().reports.submit(...args)\n },\n addLogs(...args: Parameters<CloudCore[\"reports\"][\"addLogs\"]>) {\n return getCoreClient().reports.addLogs(...args)\n },\n addScreenshots(...args: Parameters<CloudCore[\"reports\"][\"addScreenshots\"]>) {\n return getCoreClient().reports.addScreenshots(...args)\n },\n complete(...args: Parameters<CloudCore[\"reports\"][\"complete\"]>) {\n return getCoreClient().reports.complete(...args)\n },\n },\n supportProfile: {\n update(...args: Parameters<CloudCore[\"supportProfile\"][\"update\"]>) {\n return getCoreClient().supportProfile.update(...args)\n },\n },\n },\n\n hasAudioSubscriptions(): boolean {\n return audioSubscriptions.length > 0\n },\n}\n"]}
@@ -0,0 +1,13 @@
1
+ export interface ForegroundLocationPermissionResponse {
2
+ status: string;
3
+ }
4
+ export interface ForegroundLocationPermissionClient {
5
+ getForegroundPermissionsAsync(): Promise<ForegroundLocationPermissionResponse>;
6
+ requestForegroundPermissionsAsync(): Promise<ForegroundLocationPermissionResponse>;
7
+ }
8
+ /**
9
+ * Resolve foreground location permission without invoking an Activity-bound
10
+ * Android permission request while the app is backgrounded.
11
+ */
12
+ export declare function resolveForegroundLocationPermission(client: ForegroundLocationPermissionClient, getAppState: () => string): Promise<ForegroundLocationPermissionResponse>;
13
+ //# sourceMappingURL=ForegroundLocationPermission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForegroundLocationPermission.d.ts","sourceRoot":"","sources":["../../src/services/ForegroundLocationPermission.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oCAAoC;IACnD,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,kCAAkC;IACjD,6BAA6B,IAAI,OAAO,CAAC,oCAAoC,CAAC,CAAA;IAC9E,iCAAiC,IAAI,OAAO,CAAC,oCAAoC,CAAC,CAAA;CACnF;AAED;;;GAGG;AACH,wBAAsB,mCAAmC,CACvD,MAAM,EAAE,kCAAkC,EAC1C,WAAW,EAAE,MAAM,MAAM,GACxB,OAAO,CAAC,oCAAoC,CAAC,CAO/C"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Resolve foreground location permission without invoking an Activity-bound
3
+ * Android permission request while the app is backgrounded.
4
+ */
5
+ export async function resolveForegroundLocationPermission(client, getAppState) {
6
+ const current = await client.getForegroundPermissionsAsync();
7
+ if (current.status === "granted" || getAppState() !== "active") {
8
+ return current;
9
+ }
10
+ return client.requestForegroundPermissionsAsync();
11
+ }
12
+ //# sourceMappingURL=ForegroundLocationPermission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ForegroundLocationPermission.js","sourceRoot":"","sources":["../../src/services/ForegroundLocationPermission.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mCAAmC,CACvD,MAA0C,EAC1C,WAAyB;IAEzB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,6BAA6B,EAAE,CAAA;IAC5D,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,WAAW,EAAE,KAAK,QAAQ,EAAE,CAAC;QAC/D,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,OAAO,MAAM,CAAC,iCAAiC,EAAE,CAAA;AACnD,CAAC","sourcesContent":["export interface ForegroundLocationPermissionResponse {\n status: string\n}\n\nexport interface ForegroundLocationPermissionClient {\n getForegroundPermissionsAsync(): Promise<ForegroundLocationPermissionResponse>\n requestForegroundPermissionsAsync(): Promise<ForegroundLocationPermissionResponse>\n}\n\n/**\n * Resolve foreground location permission without invoking an Activity-bound\n * Android permission request while the app is backgrounded.\n */\nexport async function resolveForegroundLocationPermission(\n client: ForegroundLocationPermissionClient,\n getAppState: () => string,\n): Promise<ForegroundLocationPermissionResponse> {\n const current = await client.getForegroundPermissionsAsync()\n if (current.status === \"granted\" || getAppState() !== \"active\") {\n return current\n }\n\n return client.requestForegroundPermissionsAsync()\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"GlassesSettingsSync.d.ts","sourceRoot":"","sources":["../../src/services/GlassesSettingsSync.ts"],"names":[],"mappings":"AAmCA;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOzB;AAED,uEAAuE;AACvE,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAO/F;AAKD;;;;;;GAMG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC,CAK9D;AAED;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,CAEjE;AAED,wBAAgB,wBAAwB,IAAI,IAAI,CA8B/C;AAED,wBAAgB,uBAAuB,IAAI,IAAI,CAK9C"}
1
+ {"version":3,"file":"GlassesSettingsSync.d.ts","sourceRoot":"","sources":["../../src/services/GlassesSettingsSync.ts"],"names":[],"mappings":"AAuCA;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOzB;AAED,uEAAuE;AACvE,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAO/F;AAKD;;;;;;GAMG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM9D;AAED;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,CAGjE;AAED,wBAAgB,wBAAwB,IAAI,IAAI,CA8B/C;AAED,wBAAgB,uBAAuB,IAAI,IAAI,CAK9C"}
@@ -18,6 +18,7 @@ import { useSettingsStore, PAIRING_IDENTITY_KEYS } from "../stores/settings";
18
18
  import { useGlassesStore } from "../stores/glasses";
19
19
  import { createDebouncedPatchFlusher } from "../utils/debouncedPatch";
20
20
  import { isGlassesConnected } from "./GlassesReadiness";
21
+ import micStateCoordinator from "./MicStateCoordinator";
21
22
  /**
22
23
  * Change-pushes are debounced (300ms) and merged so a burst of setSetting
23
24
  * calls becomes ONE BLE write (wire v2 keeps BLE JSON small and infrequent).
@@ -26,7 +27,10 @@ import { isGlassesConnected } from "./GlassesReadiness";
26
27
  const flushBluetoothSettingsPatch = createDebouncedPatchFlusher((patch) => {
27
28
  // Settings can change while the glasses are disconnected — a native
28
29
  // rejection must not surface as an unhandled promise rejection.
29
- void Promise.resolve(BluetoothSdk.updateBluetoothSettings(patch)).catch((error) => {
30
+ // Apply mic overrides at flush time, not enqueue time: raw PCM can stop
31
+ // during the debounce window and a captured VAD=false would then be stale.
32
+ const runtimePatch = micStateCoordinator.applyRuntimeOverrides(patch);
33
+ void Promise.resolve(BluetoothSdk.updateBluetoothSettings(runtimePatch)).catch((error) => {
30
34
  console.warn("GlassesSettingsSync: updateBluetoothSettings failed:", error);
31
35
  });
32
36
  }, 300);
@@ -73,7 +77,8 @@ export async function pushAllBluetoothSettings() {
73
77
  // Returns the native write promise so callers can await the seed before the
74
78
  // connect handshake replays settings to the glasses (otherwise the handshake
75
79
  // can race ahead and replay stale native settings).
76
- await BluetoothSdk.updateBluetoothSettings(useSettingsStore.getState().getBluetoothSettings());
80
+ const settings = useSettingsStore.getState().getBluetoothSettings();
81
+ await BluetoothSdk.updateBluetoothSettings(micStateCoordinator.applyRuntimeOverrides(settings));
77
82
  }
78
83
  /**
79
84
  * Push the device-settings set MINUS the pairing identity. The on-connect
@@ -84,7 +89,8 @@ export async function pushAllBluetoothSettings() {
84
89
  * with pre-promotion empties (wiping the pairing it had just made).
85
90
  */
86
91
  export async function pushDeviceSettingsOnConnect() {
87
- await BluetoothSdk.updateBluetoothSettings(stripPairingIdentity(useSettingsStore.getState().getBluetoothSettings()));
92
+ const settings = stripPairingIdentity(useSettingsStore.getState().getBluetoothSettings());
93
+ await BluetoothSdk.updateBluetoothSettings(micStateCoordinator.applyRuntimeOverrides(settings));
88
94
  }
89
95
  export function startGlassesSettingsSync() {
90
96
  if (unsubChange || unsubConnect)
@@ -1 +1 @@
1
- {"version":3,"file":"GlassesSettingsSync.js","sourceRoot":"","sources":["../../src/services/GlassesSettingsSync.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Glasses settings sync — engine-owned. Keeps the connected glasses in sync with\n * the phone's device settings (`BLUETOOTH_SETTING_KEYS`) over the bluetooth-sdk, so\n * `engine.glasses.settings.set()` (and any other settings-store write) reaches the\n * device for ANY host — not just the first-party Mentra app, where this used to live\n * in MantleManager.\n *\n * Two triggers:\n * 1. on change — push the keys that changed.\n * 2. on (re)connect — push the FULL set, so a freshly-connected device gets the\n * phone's current settings (not just future changes).\n *\n * Started by `engine.start()`. Idempotent.\n */\nimport {shallow} from \"zustand/shallow\"\n\nimport BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\nimport {useSettingsStore, PAIRING_IDENTITY_KEYS} from \"../stores/settings\"\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {createDebouncedPatchFlusher} from \"../utils/debouncedPatch\"\nimport {isGlassesConnected} from \"./GlassesReadiness\"\n\n/**\n * Change-pushes are debounced (300ms) and merged so a burst of setSetting\n * calls becomes ONE BLE write (wire v2 keeps BLE JSON small and infrequent).\n * The full on-connect/seed pushes stay direct — callers await their ordering.\n */\nconst flushBluetoothSettingsPatch = createDebouncedPatchFlusher<Record<string, unknown>>((patch) => {\n // Settings can change while the glasses are disconnected — a native\n // rejection must not surface as an unhandled promise rejection.\n void Promise.resolve(BluetoothSdk.updateBluetoothSettings(patch)).catch((error) => {\n console.warn(\"GlassesSettingsSync: updateBluetoothSettings failed:\", error)\n })\n}, 300)\n\n/**\n * The changed-keys diff for the change-push, MINUS the pairing-identity keys.\n * Identity is native-authoritative (promoted on pairing success, cleared on\n * forget, echoed down via save_setting) and reaches native only through the\n * explicit full seeds. Pushing identity from the change subscription would\n * close a feedback loop: native echo → store setSetting → change-push →\n * native apply → echo…, which self-sustains the moment two different values\n * are in flight (e.g. a boot demotion crossing a native promotion) and flaps\n * the pairing UI.\n */\nexport function diffBluetoothSettingsForPush(\n settings: Record<string, unknown>,\n previous: Record<string, unknown>,\n): Record<string, unknown> {\n const changed: Record<string, unknown> = {}\n for (const key in settings) {\n if (PAIRING_IDENTITY_KEYS.includes(key)) continue\n if (settings[key] !== previous[key]) changed[key] = settings[key]\n }\n return changed\n}\n\n/** A copy of the settings record without the pairing-identity keys. */\nexport function stripPairingIdentity(settings: Record<string, unknown>): Record<string, unknown> {\n const stripped: Record<string, unknown> = {}\n for (const key in settings) {\n if (PAIRING_IDENTITY_KEYS.includes(key)) continue\n stripped[key] = settings[key]\n }\n return stripped\n}\n\nlet unsubChange: (() => void) | null = null\nlet unsubConnect: (() => void) | null = null\n\n/**\n * Push the FULL current device-settings set — identity included — to native.\n * This is the explicit identity SEED, for the flows where native genuinely\n * needs the phone's persisted identity BEFORE it can act: the device-store\n * hydration at start, the pre-connect seed (connectDefault targets the seeded\n * identity), the post-demotion re-push, and the abandon re-seed.\n */\nexport async function pushAllBluetoothSettings(): Promise<void> {\n // Returns the native write promise so callers can await the seed before the\n // connect handshake replays settings to the glasses (otherwise the handshake\n // can race ahead and replay stale native settings).\n await BluetoothSdk.updateBluetoothSettings(useSettingsStore.getState().getBluetoothSettings())\n}\n\n/**\n * Push the device-settings set MINUS the pairing identity. The on-connect\n * replay uses this: while connected, NATIVE owns the identity (it promotes at\n * device-ready and echoes down), and the JS snapshot can be mid-relay stale —\n * on Mentra Live \"connected\" lands together with device-ready, and a full\n * replay raced the promotion echoes and overwrote the just-promoted identity\n * with pre-promotion empties (wiping the pairing it had just made).\n */\nexport async function pushDeviceSettingsOnConnect(): Promise<void> {\n await BluetoothSdk.updateBluetoothSettings(stripPairingIdentity(useSettingsStore.getState().getBluetoothSettings()))\n}\n\nexport function startGlassesSettingsSync(): void {\n if (unsubChange || unsubConnect) return\n\n // 1. Push only the keys that changed (matching the prior MantleManager sync).\n // Pairing identity is excluded — see diffBluetoothSettingsForPush.\n unsubChange = useSettingsStore.subscribe(\n (state) => state.getBluetoothSettings(),\n (settings: Record<string, unknown>, previous: Record<string, unknown>) => {\n const changed = diffBluetoothSettingsForPush(settings, previous)\n if (Object.keys(changed).length > 0) {\n flushBluetoothSettingsPatch(changed)\n }\n },\n {equalityFn: shallow},\n )\n\n // 2. Push the device settings whenever the glasses transition to connected —\n // identity EXCLUDED: native owns the identity it just promoted, and a full\n // replay here raced the promotion echoes (see pushDeviceSettingsOnConnect).\n let wasConnected = isGlassesConnected(useGlassesStore.getState().connection)\n unsubConnect = useGlassesStore.subscribe(() => {\n const connected = isGlassesConnected(useGlassesStore.getState().connection)\n if (connected && !wasConnected) {\n // Background sync: log-and-continue if the device drops right after connect.\n void pushDeviceSettingsOnConnect().catch((error) => {\n console.warn(\"GlassesSettingsSync: on-connect settings push failed:\", error)\n })\n }\n wasConnected = connected\n })\n}\n\nexport function stopGlassesSettingsSync(): void {\n unsubChange?.()\n unsubConnect?.()\n unsubChange = null\n unsubConnect = null\n}\n"]}
1
+ {"version":3,"file":"GlassesSettingsSync.js","sourceRoot":"","sources":["../../src/services/GlassesSettingsSync.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Glasses settings sync — engine-owned. Keeps the connected glasses in sync with\n * the phone's device settings (`BLUETOOTH_SETTING_KEYS`) over the bluetooth-sdk, so\n * `engine.glasses.settings.set()` (and any other settings-store write) reaches the\n * device for ANY host — not just the first-party Mentra app, where this used to live\n * in MantleManager.\n *\n * Two triggers:\n * 1. on change — push the keys that changed.\n * 2. on (re)connect — push the FULL set, so a freshly-connected device gets the\n * phone's current settings (not just future changes).\n *\n * Started by `engine.start()`. Idempotent.\n */\nimport {shallow} from \"zustand/shallow\"\n\nimport BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\nimport {useSettingsStore, PAIRING_IDENTITY_KEYS} from \"../stores/settings\"\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {createDebouncedPatchFlusher} from \"../utils/debouncedPatch\"\nimport {isGlassesConnected} from \"./GlassesReadiness\"\nimport micStateCoordinator from \"./MicStateCoordinator\"\n\n/**\n * Change-pushes are debounced (300ms) and merged so a burst of setSetting\n * calls becomes ONE BLE write (wire v2 keeps BLE JSON small and infrequent).\n * The full on-connect/seed pushes stay direct — callers await their ordering.\n */\nconst flushBluetoothSettingsPatch = createDebouncedPatchFlusher<Record<string, unknown>>((patch) => {\n // Settings can change while the glasses are disconnected — a native\n // rejection must not surface as an unhandled promise rejection.\n // Apply mic overrides at flush time, not enqueue time: raw PCM can stop\n // during the debounce window and a captured VAD=false would then be stale.\n const runtimePatch = micStateCoordinator.applyRuntimeOverrides(patch)\n void Promise.resolve(BluetoothSdk.updateBluetoothSettings(runtimePatch)).catch((error) => {\n console.warn(\"GlassesSettingsSync: updateBluetoothSettings failed:\", error)\n })\n}, 300)\n\n/**\n * The changed-keys diff for the change-push, MINUS the pairing-identity keys.\n * Identity is native-authoritative (promoted on pairing success, cleared on\n * forget, echoed down via save_setting) and reaches native only through the\n * explicit full seeds. Pushing identity from the change subscription would\n * close a feedback loop: native echo → store setSetting → change-push →\n * native apply → echo…, which self-sustains the moment two different values\n * are in flight (e.g. a boot demotion crossing a native promotion) and flaps\n * the pairing UI.\n */\nexport function diffBluetoothSettingsForPush(\n settings: Record<string, unknown>,\n previous: Record<string, unknown>,\n): Record<string, unknown> {\n const changed: Record<string, unknown> = {}\n for (const key in settings) {\n if (PAIRING_IDENTITY_KEYS.includes(key)) continue\n if (settings[key] !== previous[key]) changed[key] = settings[key]\n }\n return changed\n}\n\n/** A copy of the settings record without the pairing-identity keys. */\nexport function stripPairingIdentity(settings: Record<string, unknown>): Record<string, unknown> {\n const stripped: Record<string, unknown> = {}\n for (const key in settings) {\n if (PAIRING_IDENTITY_KEYS.includes(key)) continue\n stripped[key] = settings[key]\n }\n return stripped\n}\n\nlet unsubChange: (() => void) | null = null\nlet unsubConnect: (() => void) | null = null\n\n/**\n * Push the FULL current device-settings set — identity included — to native.\n * This is the explicit identity SEED, for the flows where native genuinely\n * needs the phone's persisted identity BEFORE it can act: the device-store\n * hydration at start, the pre-connect seed (connectDefault targets the seeded\n * identity), the post-demotion re-push, and the abandon re-seed.\n */\nexport async function pushAllBluetoothSettings(): Promise<void> {\n // Returns the native write promise so callers can await the seed before the\n // connect handshake replays settings to the glasses (otherwise the handshake\n // can race ahead and replay stale native settings).\n const settings = useSettingsStore.getState().getBluetoothSettings()\n await BluetoothSdk.updateBluetoothSettings(micStateCoordinator.applyRuntimeOverrides(settings))\n}\n\n/**\n * Push the device-settings set MINUS the pairing identity. The on-connect\n * replay uses this: while connected, NATIVE owns the identity (it promotes at\n * device-ready and echoes down), and the JS snapshot can be mid-relay stale —\n * on Mentra Live \"connected\" lands together with device-ready, and a full\n * replay raced the promotion echoes and overwrote the just-promoted identity\n * with pre-promotion empties (wiping the pairing it had just made).\n */\nexport async function pushDeviceSettingsOnConnect(): Promise<void> {\n const settings = stripPairingIdentity(useSettingsStore.getState().getBluetoothSettings())\n await BluetoothSdk.updateBluetoothSettings(micStateCoordinator.applyRuntimeOverrides(settings))\n}\n\nexport function startGlassesSettingsSync(): void {\n if (unsubChange || unsubConnect) return\n\n // 1. Push only the keys that changed (matching the prior MantleManager sync).\n // Pairing identity is excluded — see diffBluetoothSettingsForPush.\n unsubChange = useSettingsStore.subscribe(\n (state) => state.getBluetoothSettings(),\n (settings: Record<string, unknown>, previous: Record<string, unknown>) => {\n const changed = diffBluetoothSettingsForPush(settings, previous)\n if (Object.keys(changed).length > 0) {\n flushBluetoothSettingsPatch(changed)\n }\n },\n {equalityFn: shallow},\n )\n\n // 2. Push the device settings whenever the glasses transition to connected —\n // identity EXCLUDED: native owns the identity it just promoted, and a full\n // replay here raced the promotion echoes (see pushDeviceSettingsOnConnect).\n let wasConnected = isGlassesConnected(useGlassesStore.getState().connection)\n unsubConnect = useGlassesStore.subscribe(() => {\n const connected = isGlassesConnected(useGlassesStore.getState().connection)\n if (connected && !wasConnected) {\n // Background sync: log-and-continue if the device drops right after connect.\n void pushDeviceSettingsOnConnect().catch((error) => {\n console.warn(\"GlassesSettingsSync: on-connect settings push failed:\", error)\n })\n }\n wasConnected = connected\n })\n}\n\nexport function stopGlassesSettingsSync(): void {\n unsubChange?.()\n unsubConnect?.()\n unsubChange = null\n unsubConnect = null\n}\n"]}
@@ -1,3 +1,4 @@
1
- export declare function startGlassesStatusProjection(): void;
1
+ import type { GlassesStatus } from "@mentra/bluetooth-sdk/internal";
2
+ export declare function startGlassesStatusProjection(forwarder?: (status: Partial<GlassesStatus>) => void): Promise<void>;
2
3
  export declare function stopGlassesStatusProjection(): void;
3
4
  //# sourceMappingURL=GlassesStatusProjection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GlassesStatusProjection.d.ts","sourceRoot":"","sources":["../../src/services/GlassesStatusProjection.ts"],"names":[],"mappings":"AAqBA,wBAAgB,4BAA4B,IAAI,IAAI,CA6CnD;AAED,wBAAgB,2BAA2B,IAAI,IAAI,CAIlD"}
1
+ {"version":3,"file":"GlassesStatusProjection.d.ts","sourceRoot":"","sources":["../../src/services/GlassesStatusProjection.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,gCAAgC,CAAA;AASjE,wBAAgB,4BAA4B,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDhH;AAED,wBAAgB,2BAA2B,IAAI,IAAI,CAMlD"}
@@ -14,16 +14,19 @@
14
14
  import BluetoothSdk from "@mentra/bluetooth-sdk/internal";
15
15
  import { useCoreStore } from "../stores/core";
16
16
  import { useGlassesStore } from "../stores/glasses";
17
- import localMiniappRuntime from "./LocalMiniappRuntime";
18
17
  let unsubs = [];
19
18
  let projectionRunId = 0;
20
- export function startGlassesStatusProjection() {
19
+ let glassesStatusForwarder = null;
20
+ let hydrationPromise = null;
21
+ export function startGlassesStatusProjection(forwarder) {
22
+ if (forwarder)
23
+ glassesStatusForwarder = forwarder;
21
24
  if (unsubs.length)
22
- return;
25
+ return hydrationPromise ?? Promise.resolve();
23
26
  const runId = ++projectionRunId;
24
27
  let bluetoothEventSeen = false;
25
28
  let glassesEventSeen = false;
26
- void BluetoothSdk.getBluetoothStatus()
29
+ const bluetoothHydration = BluetoothSdk.getBluetoothStatus()
27
30
  .then((status) => {
28
31
  if (runId !== projectionRunId || bluetoothEventSeen)
29
32
  return;
@@ -32,7 +35,7 @@ export function startGlassesStatusProjection() {
32
35
  .catch((error) => {
33
36
  console.warn("GlassesStatusProjection: getBluetoothStatus failed", error);
34
37
  });
35
- void BluetoothSdk.getGlassesStatus()
38
+ const glassesHydration = BluetoothSdk.getGlassesStatus()
36
39
  .then((status) => {
37
40
  if (runId !== projectionRunId || glassesEventSeen)
38
41
  return;
@@ -46,20 +49,24 @@ export function startGlassesStatusProjection() {
46
49
  bluetoothEventSeen = true;
47
50
  useCoreStore.getState().setCoreInfo(changed);
48
51
  }));
49
- // Glasses status -> glasses store (+ forward to local miniapps; clear any stale
50
- // OTA-available flag on disconnect).
52
+ // Glasses status -> glasses store (+ optional full-runtime forwarding to local
53
+ // miniapps; clear any stale OTA-available flag on disconnect).
51
54
  unsubs.push(BluetoothSdk.onGlassesStatus((changed) => {
52
55
  glassesEventSeen = true;
53
56
  useGlassesStore.getState().setGlassesInfo(changed);
54
- localMiniappRuntime.forwardEvent("glasses_connection_state", changed);
57
+ glassesStatusForwarder?.(changed);
55
58
  if (changed.connection?.state === "disconnected") {
56
59
  useGlassesStore.getState().setOtaUpdateAvailable(null);
57
60
  }
58
61
  }));
62
+ hydrationPromise = Promise.allSettled([bluetoothHydration, glassesHydration]).then(() => undefined);
63
+ return hydrationPromise;
59
64
  }
60
65
  export function stopGlassesStatusProjection() {
61
66
  projectionRunId++;
62
67
  unsubs.forEach((unsub) => unsub());
63
68
  unsubs = [];
69
+ glassesStatusForwarder = null;
70
+ hydrationPromise = null;
64
71
  }
65
72
  //# sourceMappingURL=GlassesStatusProjection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GlassesStatusProjection.js","sourceRoot":"","sources":["../../src/services/GlassesStatusProjection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,YAAY,MAAM,gCAAgC,CAAA;AACzD,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAA;AACjD,OAAO,mBAAmB,MAAM,uBAAuB,CAAA;AAEvD,IAAI,MAAM,GAAsB,EAAE,CAAA;AAClC,IAAI,eAAe,GAAG,CAAC,CAAA;AAEvB,MAAM,UAAU,4BAA4B;IAC1C,IAAI,MAAM,CAAC,MAAM;QAAE,OAAM;IAEzB,MAAM,KAAK,GAAG,EAAE,eAAe,CAAA;IAC/B,IAAI,kBAAkB,GAAG,KAAK,CAAA;IAC9B,IAAI,gBAAgB,GAAG,KAAK,CAAA;IAE5B,KAAK,YAAY,CAAC,kBAAkB,EAAE;SACnC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QACf,IAAI,KAAK,KAAK,eAAe,IAAI,kBAAkB;YAAE,OAAM;QAC3D,YAAY,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;IAC7C,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACf,OAAO,CAAC,IAAI,CAAC,oDAAoD,EAAE,KAAK,CAAC,CAAA;IAC3E,CAAC,CAAC,CAAA;IAEJ,KAAK,YAAY,CAAC,gBAAgB,EAAE;SACjC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QACf,IAAI,KAAK,KAAK,eAAe,IAAI,gBAAgB;YAAE,OAAM;QACzD,eAAe,CAAC,QAAQ,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;IACnD,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACf,OAAO,CAAC,IAAI,CAAC,kDAAkD,EAAE,KAAK,CAAC,CAAA;IACzE,CAAC,CAAC,CAAA;IAEJ,0CAA0C;IAC1C,MAAM,CAAC,IAAI,CACT,YAAY,CAAC,iBAAiB,CAAC,CAAC,OAAO,EAAE,EAAE;QACzC,kBAAkB,GAAG,IAAI,CAAA;QACzB,YAAY,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;IAC9C,CAAC,CAAC,CACH,CAAA;IAED,gFAAgF;IAChF,qCAAqC;IACrC,MAAM,CAAC,IAAI,CACT,YAAY,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,EAAE;QACvC,gBAAgB,GAAG,IAAI,CAAA;QACvB,eAAe,CAAC,QAAQ,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;QAClD,mBAAmB,CAAC,YAAY,CAAC,0BAA0B,EAAE,OAAO,CAAC,CAAA;QACrE,IAAI,OAAO,CAAC,UAAU,EAAE,KAAK,KAAK,cAAc,EAAE,CAAC;YACjD,eAAe,CAAC,QAAQ,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAA;QACxD,CAAC;IACH,CAAC,CAAC,CACH,CAAA;AACH,CAAC;AAED,MAAM,UAAU,2BAA2B;IACzC,eAAe,EAAE,CAAA;IACjB,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAA;IAClC,MAAM,GAAG,EAAE,CAAA;AACb,CAAC","sourcesContent":["/**\n * Glasses status projection — engine-owned. Subscribes to the native bluetooth-sdk\n * status events and projects them into the engine device stores, so engine's own\n * services (which react to those stores) work for ANY host — not just the first-party\n * Mentra app, where this used to live in MantleManager.\n *\n * This is the INBOUND mirror of GlassesSettingsSync: that pushes the settings store\n * OUT to the device; this pulls device status IN to the stores. It's the feed that\n * the rest of the engine runtime depends on (MicStateCoordinator, the settings-sync\n * on-connect trigger, the facade read-models all read these stores).\n *\n * Started by `engine.start()`. Idempotent.\n */\nimport BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\nimport {useCoreStore} from \"../stores/core\"\nimport {useGlassesStore} from \"../stores/glasses\"\nimport localMiniappRuntime from \"./LocalMiniappRuntime\"\n\nlet unsubs: Array<() => void> = []\nlet projectionRunId = 0\n\nexport function startGlassesStatusProjection(): void {\n if (unsubs.length) return\n\n const runId = ++projectionRunId\n let bluetoothEventSeen = false\n let glassesEventSeen = false\n\n void BluetoothSdk.getBluetoothStatus()\n .then((status) => {\n if (runId !== projectionRunId || bluetoothEventSeen) return\n useCoreStore.getState().setCoreInfo(status)\n })\n .catch((error) => {\n console.warn(\"GlassesStatusProjection: getBluetoothStatus failed\", error)\n })\n\n void BluetoothSdk.getGlassesStatus()\n .then((status) => {\n if (runId !== projectionRunId || glassesEventSeen) return\n useGlassesStore.getState().setGlassesInfo(status)\n })\n .catch((error) => {\n console.warn(\"GlassesStatusProjection: getGlassesStatus failed\", error)\n })\n\n // Bluetooth-adapter status -> core store.\n unsubs.push(\n BluetoothSdk.onBluetoothStatus((changed) => {\n bluetoothEventSeen = true\n useCoreStore.getState().setCoreInfo(changed)\n }),\n )\n\n // Glasses status -> glasses store (+ forward to local miniapps; clear any stale\n // OTA-available flag on disconnect).\n unsubs.push(\n BluetoothSdk.onGlassesStatus((changed) => {\n glassesEventSeen = true\n useGlassesStore.getState().setGlassesInfo(changed)\n localMiniappRuntime.forwardEvent(\"glasses_connection_state\", changed)\n if (changed.connection?.state === \"disconnected\") {\n useGlassesStore.getState().setOtaUpdateAvailable(null)\n }\n }),\n )\n}\n\nexport function stopGlassesStatusProjection(): void {\n projectionRunId++\n unsubs.forEach((unsub) => unsub())\n unsubs = []\n}\n"]}
1
+ {"version":3,"file":"GlassesStatusProjection.js","sourceRoot":"","sources":["../../src/services/GlassesStatusProjection.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Glasses status projection — engine-owned. Subscribes to the native bluetooth-sdk\n * status events and projects them into the engine device stores, so engine's own\n * services (which react to those stores) work for ANY host — not just the first-party\n * Mentra app, where this used to live in MantleManager.\n *\n * This is the INBOUND mirror of GlassesSettingsSync: that pushes the settings store\n * OUT to the device; this pulls device status IN to the stores. It's the feed that\n * the rest of the engine runtime depends on (MicStateCoordinator, the settings-sync\n * on-connect trigger, the facade read-models all read these stores).\n *\n * Started by `engine.start()`. Idempotent.\n */\nimport BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\nimport type {GlassesStatus} from \"@mentra/bluetooth-sdk/internal\"\nimport {useCoreStore} from \"../stores/core\"\nimport {useGlassesStore} from \"../stores/glasses\"\n\nlet unsubs: Array<() => void> = []\nlet projectionRunId = 0\nlet glassesStatusForwarder: ((status: Partial<GlassesStatus>) => void) | null = null\nlet hydrationPromise: Promise<void> | null = null\n\nexport function startGlassesStatusProjection(forwarder?: (status: Partial<GlassesStatus>) => void): Promise<void> {\n if (forwarder) glassesStatusForwarder = forwarder\n if (unsubs.length) return hydrationPromise ?? Promise.resolve()\n\n const runId = ++projectionRunId\n let bluetoothEventSeen = false\n let glassesEventSeen = false\n\n const bluetoothHydration = BluetoothSdk.getBluetoothStatus()\n .then((status) => {\n if (runId !== projectionRunId || bluetoothEventSeen) return\n useCoreStore.getState().setCoreInfo(status)\n })\n .catch((error) => {\n console.warn(\"GlassesStatusProjection: getBluetoothStatus failed\", error)\n })\n\n const glassesHydration = BluetoothSdk.getGlassesStatus()\n .then((status) => {\n if (runId !== projectionRunId || glassesEventSeen) return\n useGlassesStore.getState().setGlassesInfo(status)\n })\n .catch((error) => {\n console.warn(\"GlassesStatusProjection: getGlassesStatus failed\", error)\n })\n\n // Bluetooth-adapter status -> core store.\n unsubs.push(\n BluetoothSdk.onBluetoothStatus((changed) => {\n bluetoothEventSeen = true\n useCoreStore.getState().setCoreInfo(changed)\n }),\n )\n\n // Glasses status -> glasses store (+ optional full-runtime forwarding to local\n // miniapps; clear any stale OTA-available flag on disconnect).\n unsubs.push(\n BluetoothSdk.onGlassesStatus((changed) => {\n glassesEventSeen = true\n useGlassesStore.getState().setGlassesInfo(changed)\n glassesStatusForwarder?.(changed)\n if (changed.connection?.state === \"disconnected\") {\n useGlassesStore.getState().setOtaUpdateAvailable(null)\n }\n }),\n )\n\n hydrationPromise = Promise.allSettled([bluetoothHydration, glassesHydration]).then(() => undefined)\n return hydrationPromise\n}\n\nexport function stopGlassesStatusProjection(): void {\n projectionRunId++\n unsubs.forEach((unsub) => unsub())\n unsubs = []\n glassesStatusForwarder = null\n hydrationPromise = null\n}\n"]}
@@ -0,0 +1,29 @@
1
+ import type { OtaCheckCurrentGlassesResult } from "./OtaUpdateCheckService";
2
+ import { type OtaArtifactDownloadProgress } from "./OtaArtifactDownloader";
3
+ export type HotspotOtaPhase = "idle" | "downloading" | "starting_hotspot" | "joining_hotspot" | "serving";
4
+ export type HotspotOtaProgress = {
5
+ phase: HotspotOtaPhase;
6
+ artifact?: OtaArtifactDownloadProgress;
7
+ };
8
+ export type HotspotOtaErrorCode = "hotspot_wifi_permission_denied" | "hotspot_start_failed" | "hotspot_join_failed" | "hotspot_server_failed";
9
+ export declare class HotspotOtaTransportError extends Error {
10
+ readonly code: HotspotOtaErrorCode;
11
+ constructor(code: HotspotOtaErrorCode, message: string);
12
+ }
13
+ /** Owns the single phone-side endpoint and network lease for one hotspot OTA attempt. */
14
+ declare class HotspotOtaTransport {
15
+ private active;
16
+ private prepared;
17
+ private hotspotRequested;
18
+ private localNetworkConnected;
19
+ private serverStarted;
20
+ private teardownPromise;
21
+ prepare(checkResult: OtaCheckCurrentGlassesResult, onProgress?: (progress: HotspotOtaProgress) => void): Promise<string>;
22
+ /** Android 13+ requires the nearby-WiFi runtime grant before WifiNetworkSpecifier is usable. */
23
+ private ensureAndroidWifiPermission;
24
+ private downloadIosArtifact;
25
+ teardown(): Promise<void>;
26
+ }
27
+ export declare const hotspotOtaTransport: HotspotOtaTransport;
28
+ export {};
29
+ //# sourceMappingURL=HotspotOtaTransport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HotspotOtaTransport.d.ts","sourceRoot":"","sources":["../../src/services/HotspotOtaTransport.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,4BAA4B,EAAC,MAAM,yBAAyB,CAAA;AACzE,OAAO,EAML,KAAK,2BAA2B,EAEjC,MAAM,yBAAyB,CAAA;AAIhC,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,aAAa,GAAG,kBAAkB,GAAG,iBAAiB,GAAG,SAAS,CAAA;AAEzG,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,eAAe,CAAA;IACtB,QAAQ,CAAC,EAAE,2BAA2B,CAAA;CACvC,CAAA;AAED,MAAM,MAAM,mBAAmB,GAC3B,gCAAgC,GAChC,sBAAsB,GACtB,qBAAqB,GACrB,uBAAuB,CAAA;AAE3B,qBAAa,wBAAyB,SAAQ,KAAK;aAE/B,IAAI,EAAE,mBAAmB;gBAAzB,IAAI,EAAE,mBAAmB,EACzC,OAAO,EAAE,MAAM;CAKlB;AAED,yFAAyF;AACzF,cAAM,mBAAmB;IACvB,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,qBAAqB,CAAQ;IACrC,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,eAAe,CAA6B;IAE9C,OAAO,CACX,WAAW,EAAE,4BAA4B,EACzC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,GAClD,OAAO,CAAC,MAAM,CAAC;IAuElB,gGAAgG;YAClF,2BAA2B;IAczC,OAAO,CAAC,mBAAmB,CAa1B;IAEK,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CA4BhC;AAED,eAAO,MAAM,mBAAmB,qBAA4B,CAAA"}