@glassly/engine 0.1.0-dev.99 → 0.2.8-dev.445

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 (501) hide show
  1. package/README.md +28 -0
  2. package/build/engine.d.ts +32 -10
  3. package/build/engine.d.ts.map +1 -1
  4. package/build/engine.js +24 -16
  5. package/build/engine.js.map +1 -1
  6. package/build/facades/dev.d.ts +9 -0
  7. package/build/facades/dev.d.ts.map +1 -1
  8. package/build/facades/dev.js +9 -0
  9. package/build/facades/dev.js.map +1 -1
  10. package/build/facades/display.d.ts +10 -3
  11. package/build/facades/display.d.ts.map +1 -1
  12. package/build/facades/display.js +22 -8
  13. package/build/facades/display.js.map +1 -1
  14. package/build/facades/displayMirror.d.ts +11 -0
  15. package/build/facades/displayMirror.d.ts.map +1 -1
  16. package/build/facades/displayMirror.js +22 -0
  17. package/build/facades/displayMirror.js.map +1 -1
  18. package/build/facades/glasses.d.ts +31 -1
  19. package/build/facades/glasses.d.ts.map +1 -1
  20. package/build/facades/glasses.js +51 -0
  21. package/build/facades/glasses.js.map +1 -1
  22. package/build/facades/memory.d.ts +0 -6
  23. package/build/facades/memory.d.ts.map +1 -1
  24. package/build/facades/memory.js +1 -9
  25. package/build/facades/memory.js.map +1 -1
  26. package/build/facades/miniapps.d.ts +3 -1
  27. package/build/facades/miniapps.d.ts.map +1 -1
  28. package/build/facades/miniapps.js +3 -1
  29. package/build/facades/miniapps.js.map +1 -1
  30. package/build/facades/pairing.d.ts.map +1 -1
  31. package/build/facades/pairing.js +5 -4
  32. package/build/facades/pairing.js.map +1 -1
  33. package/build/facades/permissions.d.ts +2 -0
  34. package/build/facades/permissions.d.ts.map +1 -1
  35. package/build/facades/permissions.js +48 -0
  36. package/build/facades/permissions.js.map +1 -1
  37. package/build/facades/phoneNotifications.d.ts +20 -9
  38. package/build/facades/phoneNotifications.d.ts.map +1 -1
  39. package/build/facades/phoneNotifications.js +33 -26
  40. package/build/facades/phoneNotifications.js.map +1 -1
  41. package/build/facades/settings.d.ts.map +1 -1
  42. package/build/facades/settings.js +1 -2
  43. package/build/facades/settings.js.map +1 -1
  44. package/build/generated/releaseMetadata.js +4 -4
  45. package/build/generated/releaseMetadata.js.map +1 -1
  46. package/build/index.d.ts +6 -4
  47. package/build/index.d.ts.map +1 -1
  48. package/build/index.js +5 -4
  49. package/build/index.js.map +1 -1
  50. package/build/react/MentraLiveOtaFlow.js +2 -2
  51. package/build/react/MentraLiveOtaFlow.js.map +1 -1
  52. package/build/react/useMentraLiveOta.d.ts.map +1 -1
  53. package/build/react/useMentraLiveOta.js +8 -7
  54. package/build/react/useMentraLiveOta.js.map +1 -1
  55. package/build/runtime/config.d.ts +1 -1
  56. package/build/runtime/config.d.ts.map +1 -1
  57. package/build/runtime/config.js.map +1 -1
  58. package/build/services/AppRegistry.d.ts +4 -1
  59. package/build/services/AppRegistry.d.ts.map +1 -1
  60. package/build/services/AppRegistry.js +21 -1
  61. package/build/services/AppRegistry.js.map +1 -1
  62. package/build/services/BlobStore.d.ts +2 -2
  63. package/build/services/BlobStore.js +3 -3
  64. package/build/services/BlobStore.js.map +1 -1
  65. package/build/services/CloudClientService.d.ts +7 -3
  66. package/build/services/CloudClientService.d.ts.map +1 -1
  67. package/build/services/CloudClientService.js +34 -9
  68. package/build/services/CloudClientService.js.map +1 -1
  69. package/build/services/DevServerBridge.d.ts +1 -18
  70. package/build/services/DevServerBridge.d.ts.map +1 -1
  71. package/build/services/DevServerBridge.js +9 -8
  72. package/build/services/DevServerBridge.js.map +1 -1
  73. package/build/services/DeviceEventRouter.d.ts.map +1 -1
  74. package/build/services/DeviceEventRouter.js +58 -71
  75. package/build/services/DeviceEventRouter.js.map +1 -1
  76. package/build/services/DisplayDiagnostics.d.ts +5 -0
  77. package/build/services/DisplayDiagnostics.d.ts.map +1 -0
  78. package/build/services/DisplayDiagnostics.js +105 -0
  79. package/build/services/DisplayDiagnostics.js.map +1 -0
  80. package/build/services/DisplayProcessor.d.ts +6 -7
  81. package/build/services/DisplayProcessor.d.ts.map +1 -1
  82. package/build/services/DisplayProcessor.js +17 -45
  83. package/build/services/DisplayProcessor.js.map +1 -1
  84. package/build/services/GestureDotsService.d.ts +10 -4
  85. package/build/services/GestureDotsService.d.ts.map +1 -1
  86. package/build/services/GestureDotsService.js +70 -16
  87. package/build/services/GestureDotsService.js.map +1 -1
  88. package/build/services/GlassesKeyboardInput.d.ts +77 -0
  89. package/build/services/GlassesKeyboardInput.d.ts.map +1 -0
  90. package/build/services/GlassesKeyboardInput.js +261 -0
  91. package/build/services/GlassesKeyboardInput.js.map +1 -0
  92. package/build/services/GlassesSensorService.d.ts +47 -0
  93. package/build/services/GlassesSensorService.d.ts.map +1 -0
  94. package/build/services/GlassesSensorService.js +242 -0
  95. package/build/services/GlassesSensorService.js.map +1 -0
  96. package/build/services/GlassesTouchInput.d.ts +14 -0
  97. package/build/services/GlassesTouchInput.d.ts.map +1 -0
  98. package/build/services/GlassesTouchInput.js +107 -0
  99. package/build/services/GlassesTouchInput.js.map +1 -0
  100. package/build/services/HeadingService.d.ts +0 -6
  101. package/build/services/HeadingService.d.ts.map +1 -1
  102. package/build/services/HeadingService.js +0 -27
  103. package/build/services/HeadingService.js.map +1 -1
  104. package/build/services/HotspotShutdown.d.ts.map +1 -1
  105. package/build/services/HotspotShutdown.js +2 -1
  106. package/build/services/HotspotShutdown.js.map +1 -1
  107. package/build/services/JSCrashloopReportService.js +2 -2
  108. package/build/services/JSCrashloopReportService.js.map +1 -1
  109. package/build/services/JSRouter.d.ts +6 -4
  110. package/build/services/JSRouter.d.ts.map +1 -1
  111. package/build/services/JSRouter.js +15 -13
  112. package/build/services/JSRouter.js.map +1 -1
  113. package/build/services/LocalDisplayManager.d.ts +35 -7
  114. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  115. package/build/services/LocalDisplayManager.js +105 -27
  116. package/build/services/LocalDisplayManager.js.map +1 -1
  117. package/build/services/LocalMiniappDataMigration.d.ts +1 -1
  118. package/build/services/LocalMiniappDataMigration.js +1 -1
  119. package/build/services/LocalMiniappDataMigration.js.map +1 -1
  120. package/build/services/LocalMiniappRuntime.d.ts +64 -11
  121. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  122. package/build/services/LocalMiniappRuntime.js +441 -35
  123. package/build/services/LocalMiniappRuntime.js.map +1 -1
  124. package/build/services/LocalSttFallbackCoordinator.d.ts +3 -0
  125. package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
  126. package/build/services/LocalSttFallbackCoordinator.js +27 -8
  127. package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
  128. package/build/services/MemoryStore.d.ts +8 -33
  129. package/build/services/MemoryStore.d.ts.map +1 -1
  130. package/build/services/MemoryStore.js +30 -56
  131. package/build/services/MemoryStore.js.map +1 -1
  132. package/build/services/MiniappEngine.d.ts +3 -3
  133. package/build/services/MiniappEngine.js +7 -7
  134. package/build/services/MiniappEngine.js.map +1 -1
  135. package/build/services/MiniappLauncher.d.ts +8 -0
  136. package/build/services/MiniappLauncher.d.ts.map +1 -1
  137. package/build/services/MiniappLauncher.js +19 -1
  138. package/build/services/MiniappLauncher.js.map +1 -1
  139. package/build/services/MirrorService.d.ts +24 -0
  140. package/build/services/MirrorService.d.ts.map +1 -0
  141. package/build/services/MirrorService.js +132 -0
  142. package/build/services/MirrorService.js.map +1 -0
  143. package/build/services/NativeNavigationService.d.ts +2 -3
  144. package/build/services/NativeNavigationService.d.ts.map +1 -1
  145. package/build/services/NativeNavigationService.js +24 -21
  146. package/build/services/NativeNavigationService.js.map +1 -1
  147. package/build/services/NavigationHandlers.d.ts.map +1 -1
  148. package/build/services/NavigationHandlers.js +10 -5
  149. package/build/services/NavigationHandlers.js.map +1 -1
  150. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  151. package/build/services/OtaInstallCoordinator.js +24 -23
  152. package/build/services/OtaInstallCoordinator.js.map +1 -1
  153. package/build/services/PairedGlassesLatch.d.ts +7 -0
  154. package/build/services/PairedGlassesLatch.d.ts.map +1 -0
  155. package/build/services/PairedGlassesLatch.js +38 -0
  156. package/build/services/PairedGlassesLatch.js.map +1 -0
  157. package/build/services/PhoneActivity.d.ts +23 -0
  158. package/build/services/PhoneActivity.d.ts.map +1 -0
  159. package/build/services/PhoneActivity.js +111 -0
  160. package/build/services/PhoneActivity.js.map +1 -0
  161. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -1
  162. package/build/services/PhoneCameraFovCoordinator.js +4 -3
  163. package/build/services/PhoneCameraFovCoordinator.js.map +1 -1
  164. package/build/services/PhoneNotificationsSync.d.ts +40 -6
  165. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  166. package/build/services/PhoneNotificationsSync.js +160 -84
  167. package/build/services/PhoneNotificationsSync.js.map +1 -1
  168. package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
  169. package/build/services/PhonePhotoCoordinator.js +6 -5
  170. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  171. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  172. package/build/services/PhoneStreamCoordinator.js +8 -7
  173. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  174. package/build/services/STTModelManager.d.ts +3 -0
  175. package/build/services/STTModelManager.d.ts.map +1 -1
  176. package/build/services/STTModelManager.js +15 -1
  177. package/build/services/STTModelManager.js.map +1 -1
  178. package/build/services/SceneRenderer.d.ts +43 -2
  179. package/build/services/SceneRenderer.d.ts.map +1 -1
  180. package/build/services/SceneRenderer.js +123 -8
  181. package/build/services/SceneRenderer.js.map +1 -1
  182. package/build/services/StreamLifecycleController.d.ts.map +1 -1
  183. package/build/services/StreamLifecycleController.js +6 -14
  184. package/build/services/StreamLifecycleController.js.map +1 -1
  185. package/build/services/TTSModelManager.js +1 -1
  186. package/build/services/TTSModelManager.js.map +1 -1
  187. package/build/services/UIRouter.d.ts +2 -2
  188. package/build/services/UIRouter.js +5 -5
  189. package/build/services/UIRouter.js.map +1 -1
  190. package/build/services/asg/galleryPathMigration.js +1 -1
  191. package/build/services/asg/galleryPathMigration.js.map +1 -1
  192. package/build/services/asg/gallerySyncService.js +2 -2
  193. package/build/services/asg/gallerySyncService.js.map +1 -1
  194. package/build/services/asg/localStorageService.d.ts.map +1 -1
  195. package/build/services/asg/localStorageService.js +3 -3
  196. package/build/services/asg/localStorageService.js.map +1 -1
  197. package/build/services/debug/DashboardOpenTrace.d.ts +32 -0
  198. package/build/services/debug/DashboardOpenTrace.d.ts.map +1 -0
  199. package/build/services/debug/DashboardOpenTrace.js +128 -0
  200. package/build/services/debug/DashboardOpenTrace.js.map +1 -0
  201. package/build/services/debug/dashboardOpenTimeline.d.ts +77 -0
  202. package/build/services/debug/dashboardOpenTimeline.d.ts.map +1 -0
  203. package/build/services/debug/dashboardOpenTimeline.js +195 -0
  204. package/build/services/debug/dashboardOpenTimeline.js.map +1 -0
  205. package/build/services/effectiveCapabilities.d.ts.map +1 -1
  206. package/build/services/effectiveCapabilities.js +25 -13
  207. package/build/services/effectiveCapabilities.js.map +1 -1
  208. package/build/services/gestureClaims.d.ts +34 -15
  209. package/build/services/gestureClaims.d.ts.map +1 -1
  210. package/build/services/gestureClaims.js +42 -21
  211. package/build/services/gestureClaims.js.map +1 -1
  212. package/build/services/manifestFields.d.ts +9 -0
  213. package/build/services/manifestFields.d.ts.map +1 -0
  214. package/build/services/manifestFields.js +26 -0
  215. package/build/services/manifestFields.js.map +1 -0
  216. package/build/services/memoryStoreInstance.d.ts +0 -10
  217. package/build/services/memoryStoreInstance.d.ts.map +1 -1
  218. package/build/services/memoryStoreInstance.js +2 -31
  219. package/build/services/memoryStoreInstance.js.map +1 -1
  220. package/build/services/mirrorSnapshot.d.ts +16 -0
  221. package/build/services/mirrorSnapshot.d.ts.map +1 -0
  222. package/build/services/mirrorSnapshot.js +102 -0
  223. package/build/services/mirrorSnapshot.js.map +1 -0
  224. package/build/services/nativeNavigationGate.d.ts +8 -0
  225. package/build/services/nativeNavigationGate.d.ts.map +1 -0
  226. package/build/services/nativeNavigationGate.js +12 -0
  227. package/build/services/nativeNavigationGate.js.map +1 -0
  228. package/build/services/notificationAppCatalog.d.ts +7 -0
  229. package/build/services/notificationAppCatalog.d.ts.map +1 -0
  230. package/build/services/notificationAppCatalog.js +16 -0
  231. package/build/services/notificationAppCatalog.js.map +1 -0
  232. package/build/services/notifications/notificationPolicy.d.ts +55 -0
  233. package/build/services/notifications/notificationPolicy.d.ts.map +1 -0
  234. package/build/services/notifications/notificationPolicy.js +41 -0
  235. package/build/services/notifications/notificationPolicy.js.map +1 -0
  236. package/build/services/pages/OverlayPages.d.ts +26 -0
  237. package/build/services/pages/OverlayPages.d.ts.map +1 -0
  238. package/build/services/pages/OverlayPages.js +80 -0
  239. package/build/services/pages/OverlayPages.js.map +1 -0
  240. package/build/services/pages/PageHost.d.ts +32 -0
  241. package/build/services/pages/PageHost.d.ts.map +1 -0
  242. package/build/services/pages/PageHost.js +99 -0
  243. package/build/services/pages/PageHost.js.map +1 -0
  244. package/build/services/pages/overlayApps.d.ts +25 -0
  245. package/build/services/pages/overlayApps.d.ts.map +1 -0
  246. package/build/services/pages/overlayApps.js +66 -0
  247. package/build/services/pages/overlayApps.js.map +1 -0
  248. package/build/services/pages/pageEligibility.d.ts +9 -0
  249. package/build/services/pages/pageEligibility.d.ts.map +1 -0
  250. package/build/services/pages/pageEligibility.js +27 -0
  251. package/build/services/pages/pageEligibility.js.map +1 -0
  252. package/build/services/settingsBridge.d.ts +58 -0
  253. package/build/services/settingsBridge.d.ts.map +1 -0
  254. package/build/services/settingsBridge.js +90 -0
  255. package/build/services/settingsBridge.js.map +1 -0
  256. package/build/services/speakerProfileStoreInstance.js +1 -1
  257. package/build/services/speakerProfileStoreInstance.js.map +1 -1
  258. package/build/services/uiShim.d.ts +1 -1
  259. package/build/services/uiShim.js +4 -4
  260. package/build/services/uiShim.js.map +1 -1
  261. package/build/stores/appVisibility.d.ts +28 -0
  262. package/build/stores/appVisibility.d.ts.map +1 -1
  263. package/build/stores/appVisibility.js +34 -0
  264. package/build/stores/appVisibility.js.map +1 -1
  265. package/build/stores/apps.d.ts +13 -0
  266. package/build/stores/apps.d.ts.map +1 -1
  267. package/build/stores/apps.js +66 -12
  268. package/build/stores/apps.js.map +1 -1
  269. package/build/stores/bluetoothSettingKeys.js +1 -1
  270. package/build/stores/bluetoothSettingKeys.js.map +1 -1
  271. package/build/stores/display.d.ts +3 -3
  272. package/build/stores/display.d.ts.map +1 -1
  273. package/build/stores/display.js +16 -4
  274. package/build/stores/display.js.map +1 -1
  275. package/build/stores/glasses.d.ts.map +1 -1
  276. package/build/stores/glasses.js +14 -1
  277. package/build/stores/glasses.js.map +1 -1
  278. package/build/stores/settings.d.ts +1 -0
  279. package/build/stores/settings.d.ts.map +1 -1
  280. package/build/stores/settings.js +170 -44
  281. package/build/stores/settings.js.map +1 -1
  282. package/build/types/applet.d.ts +14 -1
  283. package/build/types/applet.d.ts.map +1 -1
  284. package/build/types/applet.js.map +1 -1
  285. package/build/types/capabilities/even-realities-g2.d.ts.map +1 -1
  286. package/build/types/capabilities/even-realities-g2.js +5 -0
  287. package/build/types/capabilities/even-realities-g2.js.map +1 -1
  288. package/build/types/capabilities/simulated-glasses.d.ts +1 -1
  289. package/build/types/capabilities/simulated-glasses.d.ts.map +1 -1
  290. package/build/types/capabilities/simulated-glasses.js +7 -4
  291. package/build/types/capabilities/simulated-glasses.js.map +1 -1
  292. package/build/types/hardware.d.ts +20 -1
  293. package/build/types/hardware.d.ts.map +1 -1
  294. package/build/types/hardware.js +2 -0
  295. package/build/types/hardware.js.map +1 -1
  296. package/build/types/index.d.ts +1 -0
  297. package/build/types/index.d.ts.map +1 -1
  298. package/build/types/index.js +1 -0
  299. package/build/types/index.js.map +1 -1
  300. package/build/utils/debouncedPatch.d.ts +3 -1
  301. package/build/utils/debouncedPatch.d.ts.map +1 -1
  302. package/build/utils/debouncedPatch.js +6 -3
  303. package/build/utils/debouncedPatch.js.map +1 -1
  304. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  305. package/build/utils/devMiniappLaunch.js +4 -3
  306. package/build/utils/devMiniappLaunch.js.map +1 -1
  307. package/build/utils/display/measurer/TextMeasurer.d.ts +2 -159
  308. package/build/utils/display/measurer/TextMeasurer.d.ts.map +1 -1
  309. package/build/utils/display/measurer/TextMeasurer.js +2 -272
  310. package/build/utils/display/measurer/TextMeasurer.js.map +1 -1
  311. package/build/utils/display/measurer/script-detection.d.ts +1 -52
  312. package/build/utils/display/measurer/script-detection.d.ts.map +1 -1
  313. package/build/utils/display/measurer/script-detection.js +2 -183
  314. package/build/utils/display/measurer/script-detection.js.map +1 -1
  315. package/build/utils/display/pixelArt.d.ts +3 -0
  316. package/build/utils/display/pixelArt.d.ts.map +1 -0
  317. package/build/utils/display/pixelArt.js +3 -0
  318. package/build/utils/display/pixelArt.js.map +1 -0
  319. package/build/utils/display/profiles/g1.d.ts +1 -32
  320. package/build/utils/display/profiles/g1.d.ts.map +1 -1
  321. package/build/utils/display/profiles/g1.js +2 -212
  322. package/build/utils/display/profiles/g1.js.map +1 -1
  323. package/build/utils/display/profiles/g2.d.ts +1 -12
  324. package/build/utils/display/profiles/g2.d.ts.map +1 -1
  325. package/build/utils/display/profiles/g2.js +2 -33
  326. package/build/utils/display/profiles/g2.js.map +1 -1
  327. package/build/utils/display/profiles/nex.d.ts +1 -9
  328. package/build/utils/display/profiles/nex.d.ts.map +1 -1
  329. package/build/utils/display/profiles/nex.js +2 -149
  330. package/build/utils/display/profiles/nex.js.map +1 -1
  331. package/build/utils/display/profiles/types.d.ts +1 -102
  332. package/build/utils/display/profiles/types.d.ts.map +1 -1
  333. package/build/utils/display/profiles/types.js.map +1 -1
  334. package/build/utils/display/profiles/z100.d.ts +1 -32
  335. package/build/utils/display/profiles/z100.d.ts.map +1 -1
  336. package/build/utils/display/profiles/z100.js +2 -181
  337. package/build/utils/display/profiles/z100.js.map +1 -1
  338. package/build/utils/display/scene/degrade.d.ts.map +1 -1
  339. package/build/utils/display/scene/degrade.js +4 -1
  340. package/build/utils/display/scene/degrade.js.map +1 -1
  341. package/build/utils/display/scene/differ.d.ts +13 -1
  342. package/build/utils/display/scene/differ.d.ts.map +1 -1
  343. package/build/utils/display/scene/differ.js +22 -0
  344. package/build/utils/display/scene/differ.js.map +1 -1
  345. package/build/utils/display/scene/index.d.ts +1 -1
  346. package/build/utils/display/scene/index.d.ts.map +1 -1
  347. package/build/utils/display/scene/index.js.map +1 -1
  348. package/build/utils/display/scene/process.d.ts.map +1 -1
  349. package/build/utils/display/scene/process.js +183 -11
  350. package/build/utils/display/scene/process.js.map +1 -1
  351. package/build/utils/display/scene/store.d.ts +1 -1
  352. package/build/utils/display/scene/store.d.ts.map +1 -1
  353. package/build/utils/display/scene/store.js +0 -0
  354. package/build/utils/display/scene/store.js.map +1 -1
  355. package/build/utils/display/scene/svgPath.d.ts +9 -0
  356. package/build/utils/display/scene/svgPath.d.ts.map +1 -0
  357. package/build/utils/display/scene/svgPath.js +167 -0
  358. package/build/utils/display/scene/svgPath.js.map +1 -0
  359. package/build/utils/display/scene/types.d.ts +2 -142
  360. package/build/utils/display/scene/types.d.ts.map +1 -1
  361. package/build/utils/display/scene/types.js +0 -0
  362. package/build/utils/display/scene/types.js.map +1 -1
  363. package/build/utils/display/wrapper/TextWrapper.d.ts +1 -101
  364. package/build/utils/display/wrapper/TextWrapper.d.ts.map +1 -1
  365. package/build/utils/display/wrapper/TextWrapper.js +2 -470
  366. package/build/utils/display/wrapper/TextWrapper.js.map +1 -1
  367. package/build/utils/display/wrapper/types.d.ts +2 -74
  368. package/build/utils/display/wrapper/types.d.ts.map +1 -1
  369. package/build/utils/display/wrapper/types.js +2 -10
  370. package/build/utils/display/wrapper/types.js.map +1 -1
  371. package/build/utils/hardware/hardware.js +1 -1
  372. package/build/utils/hardware/hardware.js.map +1 -1
  373. package/build/utils/timers/timers.d.ts.map +1 -1
  374. package/build/utils/timers/timers.js +26 -4
  375. package/build/utils/timers/timers.js.map +1 -1
  376. package/package.json +8 -8
  377. package/src/engine.ts +24 -15
  378. package/src/facades/dev.ts +10 -0
  379. package/src/facades/display.ts +21 -8
  380. package/src/facades/displayMirror.ts +29 -0
  381. package/src/facades/glasses.ts +61 -1
  382. package/src/facades/memory.ts +1 -12
  383. package/src/facades/miniapps.ts +4 -1
  384. package/src/facades/pairing.ts +8 -6
  385. package/src/facades/permissions.ts +46 -0
  386. package/src/facades/phoneNotifications.ts +45 -26
  387. package/src/facades/settings.ts +1 -2
  388. package/src/generated/releaseMetadata.ts +4 -4
  389. package/src/index.ts +6 -9
  390. package/src/react/MentraLiveOtaFlow.tsx +2 -2
  391. package/src/react/useMentraLiveOta.ts +14 -8
  392. package/src/runtime/config.ts +1 -1
  393. package/src/services/AppRegistry.ts +43 -7
  394. package/src/services/BlobStore.ts +3 -3
  395. package/src/services/CloudClientService.ts +37 -10
  396. package/src/services/DevServerBridge.ts +12 -10
  397. package/src/services/DeviceEventRouter.ts +73 -74
  398. package/src/services/DisplayDiagnostics.ts +107 -0
  399. package/src/services/DisplayProcessor.ts +20 -55
  400. package/src/services/GestureDotsService.ts +77 -16
  401. package/src/services/GlassesKeyboardInput.ts +306 -0
  402. package/src/services/GlassesSensorService.ts +233 -0
  403. package/src/services/GlassesTouchInput.ts +128 -0
  404. package/src/services/HeadingService.ts +0 -24
  405. package/src/services/HotspotShutdown.ts +3 -1
  406. package/src/services/JSCrashloopReportService.ts +2 -2
  407. package/src/services/JSRouter.ts +29 -14
  408. package/src/services/LocalDisplayManager.ts +112 -26
  409. package/src/services/LocalMiniappDataMigration.ts +1 -1
  410. package/src/services/LocalMiniappRuntime.ts +500 -43
  411. package/src/services/LocalSttFallbackCoordinator.ts +28 -7
  412. package/src/services/MemoryStore.ts +32 -80
  413. package/src/services/MiniappEngine.ts +7 -7
  414. package/src/services/MiniappLauncher.ts +25 -1
  415. package/src/services/MirrorService.ts +139 -0
  416. package/src/services/NativeNavigationService.ts +29 -25
  417. package/src/services/NavigationHandlers.ts +10 -5
  418. package/src/services/OtaInstallCoordinator.ts +36 -34
  419. package/src/services/PairedGlassesLatch.ts +39 -0
  420. package/src/services/PhoneActivity.ts +116 -0
  421. package/src/services/PhoneCameraFovCoordinator.ts +6 -4
  422. package/src/services/PhoneNotificationsSync.ts +185 -103
  423. package/src/services/PhonePhotoCoordinator.ts +9 -10
  424. package/src/services/PhoneStreamCoordinator.ts +13 -11
  425. package/src/services/STTModelManager.ts +15 -1
  426. package/src/services/SceneRenderer.ts +148 -10
  427. package/src/services/StreamLifecycleController.ts +9 -7
  428. package/src/services/TTSModelManager.ts +1 -1
  429. package/src/services/UIRouter.ts +5 -5
  430. package/src/services/asg/galleryPathMigration.ts +1 -1
  431. package/src/services/asg/gallerySyncService.ts +2 -2
  432. package/src/services/asg/localStorageService.ts +3 -3
  433. package/src/services/debug/DashboardOpenTrace.ts +153 -0
  434. package/src/services/debug/dashboardOpenTimeline.ts +237 -0
  435. package/src/services/effectiveCapabilities.ts +32 -13
  436. package/src/services/gestureClaims.ts +72 -23
  437. package/src/services/manifestFields.ts +23 -0
  438. package/src/services/memoryStoreInstance.ts +2 -34
  439. package/src/services/mirrorSnapshot.ts +116 -0
  440. package/src/services/nativeNavigationGate.ts +14 -0
  441. package/src/services/notificationAppCatalog.ts +21 -0
  442. package/src/services/notifications/notificationPolicy.ts +87 -0
  443. package/src/services/pages/OverlayPages.ts +86 -0
  444. package/src/services/pages/PageHost.ts +116 -0
  445. package/src/services/pages/overlayApps.ts +72 -0
  446. package/src/services/pages/pageEligibility.ts +30 -0
  447. package/src/services/settingsBridge.ts +111 -0
  448. package/src/services/speakerProfileStoreInstance.ts +1 -1
  449. package/src/services/uiShim.ts +4 -4
  450. package/src/stores/appVisibility.ts +45 -0
  451. package/src/stores/apps.ts +110 -32
  452. package/src/stores/bluetoothSettingKeys.ts +1 -1
  453. package/src/stores/display.ts +18 -7
  454. package/src/stores/glasses.ts +15 -1
  455. package/src/stores/settings.ts +175 -51
  456. package/src/types/applet.ts +14 -1
  457. package/src/types/capabilities/even-realities-g2.ts +6 -0
  458. package/src/types/capabilities/simulated-glasses.ts +8 -4
  459. package/src/types/hardware.ts +34 -1
  460. package/src/types/index.ts +1 -0
  461. package/src/utils/debouncedPatch.ts +8 -4
  462. package/src/utils/devMiniappLaunch.ts +5 -3
  463. package/src/utils/display/measurer/TextMeasurer.ts +3 -346
  464. package/src/utils/display/measurer/script-detection.ts +10 -218
  465. package/src/utils/display/pixelArt.ts +3 -0
  466. package/src/utils/display/profiles/g1.ts +2 -236
  467. package/src/utils/display/profiles/g2.ts +2 -39
  468. package/src/utils/display/profiles/nex.ts +2 -166
  469. package/src/utils/display/profiles/types.ts +9 -132
  470. package/src/utils/display/profiles/z100.ts +2 -198
  471. package/src/utils/display/scene/degrade.ts +4 -1
  472. package/src/utils/display/scene/differ.ts +25 -1
  473. package/src/utils/display/scene/index.ts +5 -0
  474. package/src/utils/display/scene/process.ts +196 -13
  475. package/src/utils/display/scene/store.ts +0 -0
  476. package/src/utils/display/scene/svgPath.ts +163 -0
  477. package/src/utils/display/scene/types.ts +0 -0
  478. package/src/utils/display/wrapper/TextWrapper.ts +2 -546
  479. package/src/utils/display/wrapper/types.ts +3 -102
  480. package/src/utils/hardware/hardware.ts +1 -1
  481. package/src/utils/timers/timers.ts +32 -4
  482. package/build/services/CustomDashboardModel.d.ts +0 -48
  483. package/build/services/CustomDashboardModel.d.ts.map +0 -1
  484. package/build/services/CustomDashboardModel.js +0 -73
  485. package/build/services/CustomDashboardModel.js.map +0 -1
  486. package/build/services/CustomDashboardService.d.ts +0 -63
  487. package/build/services/CustomDashboardService.d.ts.map +0 -1
  488. package/build/services/CustomDashboardService.js +0 -576
  489. package/build/services/CustomDashboardService.js.map +0 -1
  490. package/build/services/DashboardCoordinator.d.ts +0 -26
  491. package/build/services/DashboardCoordinator.d.ts.map +0 -1
  492. package/build/services/DashboardCoordinator.js +0 -125
  493. package/build/services/DashboardCoordinator.js.map +0 -1
  494. package/build/services/iosNotificationAppCatalog.d.ts +0 -13
  495. package/build/services/iosNotificationAppCatalog.d.ts.map +0 -1
  496. package/build/services/iosNotificationAppCatalog.js +0 -28
  497. package/build/services/iosNotificationAppCatalog.js.map +0 -1
  498. package/src/services/CustomDashboardModel.ts +0 -83
  499. package/src/services/CustomDashboardService.ts +0 -598
  500. package/src/services/DashboardCoordinator.ts +0 -121
  501. package/src/services/iosNotificationAppCatalog.ts +0 -39
@@ -1,33 +1,2 @@
1
- import { DisplayProfile } from "./types";
2
- /**
3
- * Vuzix Z100 Smart Glasses Display Profile
4
- *
5
- * The Z100 has a green monochrome display with 640x480 resolution.
6
- * It uses the Vuzix Ultralite SDK and Noto Sans font family.
7
- *
8
- * Display specs:
9
- * - Resolution: 640x480
10
- * - Usable text width: ~390px (empirically tested - SDK applies margins)
11
- * - Color: Green monochrome
12
- * - Max text lines: 7
13
- * - Font: Noto Sans Regular at 21px
14
- * - No bitmap support via text commands
15
- * - Adjustable brightness
16
- *
17
- * NOTE: The Vuzix Ultralite SDK handles text rendering internally and applies
18
- * its own margins/padding. The usable text width is significantly less than
19
- * the physical 640px resolution. Empirical testing shows ~42 characters of
20
- * mixed text (387px measured) fits on one line before the SDK wraps.
21
- */
22
- export declare const Z100_PROFILE: DisplayProfile;
23
- /**
24
- * Get the hyphen width for Z100 in pixels.
25
- * Used for line breaking calculations.
26
- */
27
- export declare const Z100_HYPHEN_WIDTH_PX = 7;
28
- /**
29
- * Get the space width for Z100 in pixels.
30
- * Used for column alignment calculations.
31
- */
32
- export declare const Z100_SPACE_WIDTH_PX = 5;
1
+ export { Z100_PROFILE, Z100_HYPHEN_WIDTH_PX, Z100_SPACE_WIDTH_PX } from "@glassly/miniapp/display";
33
2
  //# sourceMappingURL=z100.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"z100.d.ts","sourceRoot":"","sources":["../../../../src/utils/display/profiles/z100.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,SAAS,CAAA;AAyHtC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,YAAY,EAAE,cA4C1B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAA;AAErC;;;GAGG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAA"}
1
+ {"version":3,"file":"z100.d.ts","sourceRoot":"","sources":["../../../../src/utils/display/profiles/z100.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAC,MAAM,0BAA0B,CAAA"}
@@ -1,182 +1,3 @@
1
- /**
2
- * Vuzix Z100 glyph widths - extracted from NotoSans-Regular.ttf at 21px
3
- *
4
- * These are pixel widths at the default font size used by the Z100 display.
5
- * The Z100 uses Noto Sans as its system font.
6
- *
7
- * Extracted using: node scripts/extract-font-metrics.js NotoSans-Regular.ttf 21
8
- */
9
- const Z100_GLYPH_WIDTHS = {
10
- // Space and punctuation
11
- " ": 5,
12
- "!": 6,
13
- '"': 9,
14
- "#": 14,
15
- "$": 12,
16
- "%": 17,
17
- "&": 15,
18
- "'": 5,
19
- "(": 6,
20
- ")": 6,
21
- "*": 12,
22
- "+": 12,
23
- ",": 6,
24
- "-": 7, // Hyphen width - important for line breaking
25
- ".": 6,
26
- "/": 8,
27
- // Numbers
28
- "0": 12,
29
- "1": 12,
30
- "2": 12,
31
- "3": 12,
32
- "4": 12,
33
- "5": 12,
34
- "6": 12,
35
- "7": 12,
36
- "8": 12,
37
- "9": 12,
38
- // More punctuation
39
- ":": 6,
40
- ";": 6,
41
- "<": 12,
42
- "=": 12,
43
- ">": 12,
44
- "?": 9,
45
- "@": 19,
46
- // Uppercase
47
- "A": 13,
48
- "B": 14,
49
- "C": 13,
50
- "D": 15,
51
- "E": 12,
52
- "F": 11,
53
- "G": 15,
54
- "H": 16,
55
- "I": 7,
56
- "J": 6,
57
- "K": 13,
58
- "L": 11,
59
- "M": 19,
60
- "N": 16,
61
- "O": 16,
62
- "P": 13,
63
- "Q": 16,
64
- "R": 13,
65
- "S": 12,
66
- "T": 12,
67
- "U": 15,
68
- "V": 13,
69
- "W": 20,
70
- "X": 12,
71
- "Y": 12,
72
- "Z": 12,
73
- // Brackets & special
74
- "[": 7,
75
- "\\": 8,
76
- "]": 7,
77
- "^": 12,
78
- "_": 9,
79
- "`": 6,
80
- // Lowercase
81
- "a": 12,
82
- "b": 13,
83
- "c": 10,
84
- "d": 13,
85
- "e": 12,
86
- "f": 7,
87
- "g": 13,
88
- "h": 13,
89
- "i": 5,
90
- "j": 5,
91
- "k": 11,
92
- "l": 5,
93
- "m": 20,
94
- "n": 13,
95
- "o": 13,
96
- "p": 13,
97
- "q": 13,
98
- "r": 9,
99
- "s": 10,
100
- "t": 8,
101
- "u": 13,
102
- "v": 11,
103
- "w": 17,
104
- "x": 11,
105
- "y": 11,
106
- "z": 10,
107
- // More special
108
- "{": 8,
109
- "|": 12,
110
- "}": 8,
111
- "~": 12,
112
- };
113
- /**
114
- * Vuzix Z100 Smart Glasses Display Profile
115
- *
116
- * The Z100 has a green monochrome display with 640x480 resolution.
117
- * It uses the Vuzix Ultralite SDK and Noto Sans font family.
118
- *
119
- * Display specs:
120
- * - Resolution: 640x480
121
- * - Usable text width: ~390px (empirically tested - SDK applies margins)
122
- * - Color: Green monochrome
123
- * - Max text lines: 7
124
- * - Font: Noto Sans Regular at 21px
125
- * - No bitmap support via text commands
126
- * - Adjustable brightness
127
- *
128
- * NOTE: The Vuzix Ultralite SDK handles text rendering internally and applies
129
- * its own margins/padding. The usable text width is significantly less than
130
- * the physical 640px resolution. Empirical testing shows ~42 characters of
131
- * mixed text (387px measured) fits on one line before the SDK wraps.
132
- */
133
- export const Z100_PROFILE = {
134
- id: "vuzix-z100",
135
- name: "Vuzix Z100",
136
- // Display dimensions
137
- // Empirically tested: ~42 chars of mixed text (387px) fits before SDK wraps
138
- // Using 390px to account for measurement variance
139
- displayWidthPx: 390,
140
- maxLines: 7,
141
- // BLE constraints
142
- // Z100 uses Vuzix Ultralite SDK which handles chunking internally
143
- // These are conservative values for direct BLE if needed
144
- maxPayloadBytes: 512,
145
- bleChunkSize: 180,
146
- // Font metrics - Noto Sans Regular at 21px
147
- fontMetrics: {
148
- glyphWidths: new Map(Object.entries(Z100_GLYPH_WIDTHS)),
149
- defaultGlyphWidth: 12, // Average width from extracted metrics
150
- // Z100 uses direct pixel widths, no render formula needed
151
- renderFormula: (glyphWidth) => glyphWidth,
152
- // Uniform-width scripts for CJK and other non-Latin
153
- // Noto Sans CJK characters are typically wider
154
- uniformScripts: {
155
- cjk: 21, // Full-width CJK characters
156
- hiragana: 21,
157
- katakana: 21,
158
- korean: 21,
159
- cyrillic: 14, // Cyrillic is similar to Latin in Noto Sans
160
- },
161
- fallback: {
162
- latinMaxWidth: 20, // 'W' and 'm' are the widest at 20px
163
- unknownBehavior: "useLatinMax",
164
- },
165
- },
166
- constraints: {
167
- minCharsBeforeHyphen: 3,
168
- noStartChars: [".", ",", "!", "?", ":", ";", ")", "]", "}", "。", ",", "!", "?", ":", ";", ")", "】", "」"],
169
- noEndChars: ["(", "[", "{", "(", "【", "「"],
170
- },
171
- };
172
- /**
173
- * Get the hyphen width for Z100 in pixels.
174
- * Used for line breaking calculations.
175
- */
176
- export const Z100_HYPHEN_WIDTH_PX = 7;
177
- /**
178
- * Get the space width for Z100 in pixels.
179
- * Used for column alignment calculations.
180
- */
181
- export const Z100_SPACE_WIDTH_PX = 5;
1
+ // Moved into the SDK (@glassly/miniapp/display) so miniapps lay text out the way the host measures it; this path re-exports it for the engine.
2
+ export { Z100_PROFILE, Z100_HYPHEN_WIDTH_PX, Z100_SPACE_WIDTH_PX } from "@glassly/miniapp/display";
182
3
  //# sourceMappingURL=z100.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"z100.js","sourceRoot":"","sources":["../../../../src/utils/display/profiles/z100.ts"],"names":[],"mappings":"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","sourcesContent":["import {DisplayProfile} from \"./types\"\n\n/**\n * Vuzix Z100 glyph widths - extracted from NotoSans-Regular.ttf at 21px\n *\n * These are pixel widths at the default font size used by the Z100 display.\n * The Z100 uses Noto Sans as its system font.\n *\n * Extracted using: node scripts/extract-font-metrics.js NotoSans-Regular.ttf 21\n */\nconst Z100_GLYPH_WIDTHS: Record<string, number> = {\n // Space and punctuation\n \" \": 5,\n \"!\": 6,\n '\"': 9,\n \"#\": 14,\n \"$\": 12,\n \"%\": 17,\n \"&\": 15,\n \"'\": 5,\n \"(\": 6,\n \")\": 6,\n \"*\": 12,\n \"+\": 12,\n \",\": 6,\n \"-\": 7, // Hyphen width - important for line breaking\n \".\": 6,\n \"/\": 8,\n\n // Numbers\n \"0\": 12,\n \"1\": 12,\n \"2\": 12,\n \"3\": 12,\n \"4\": 12,\n \"5\": 12,\n \"6\": 12,\n \"7\": 12,\n \"8\": 12,\n \"9\": 12,\n\n // More punctuation\n \":\": 6,\n \";\": 6,\n \"<\": 12,\n \"=\": 12,\n \">\": 12,\n \"?\": 9,\n \"@\": 19,\n\n // Uppercase\n \"A\": 13,\n \"B\": 14,\n \"C\": 13,\n \"D\": 15,\n \"E\": 12,\n \"F\": 11,\n \"G\": 15,\n \"H\": 16,\n \"I\": 7,\n \"J\": 6,\n \"K\": 13,\n \"L\": 11,\n \"M\": 19,\n \"N\": 16,\n \"O\": 16,\n \"P\": 13,\n \"Q\": 16,\n \"R\": 13,\n \"S\": 12,\n \"T\": 12,\n \"U\": 15,\n \"V\": 13,\n \"W\": 20,\n \"X\": 12,\n \"Y\": 12,\n \"Z\": 12,\n\n // Brackets & special\n \"[\": 7,\n \"\\\\\": 8,\n \"]\": 7,\n \"^\": 12,\n \"_\": 9,\n \"`\": 6,\n\n // Lowercase\n \"a\": 12,\n \"b\": 13,\n \"c\": 10,\n \"d\": 13,\n \"e\": 12,\n \"f\": 7,\n \"g\": 13,\n \"h\": 13,\n \"i\": 5,\n \"j\": 5,\n \"k\": 11,\n \"l\": 5,\n \"m\": 20,\n \"n\": 13,\n \"o\": 13,\n \"p\": 13,\n \"q\": 13,\n \"r\": 9,\n \"s\": 10,\n \"t\": 8,\n \"u\": 13,\n \"v\": 11,\n \"w\": 17,\n \"x\": 11,\n \"y\": 11,\n \"z\": 10,\n\n // More special\n \"{\": 8,\n \"|\": 12,\n \"}\": 8,\n \"~\": 12,\n}\n\n/**\n * Vuzix Z100 Smart Glasses Display Profile\n *\n * The Z100 has a green monochrome display with 640x480 resolution.\n * It uses the Vuzix Ultralite SDK and Noto Sans font family.\n *\n * Display specs:\n * - Resolution: 640x480\n * - Usable text width: ~390px (empirically tested - SDK applies margins)\n * - Color: Green monochrome\n * - Max text lines: 7\n * - Font: Noto Sans Regular at 21px\n * - No bitmap support via text commands\n * - Adjustable brightness\n *\n * NOTE: The Vuzix Ultralite SDK handles text rendering internally and applies\n * its own margins/padding. The usable text width is significantly less than\n * the physical 640px resolution. Empirical testing shows ~42 characters of\n * mixed text (387px measured) fits on one line before the SDK wraps.\n */\nexport const Z100_PROFILE: DisplayProfile = {\n id: \"vuzix-z100\",\n name: \"Vuzix Z100\",\n\n // Display dimensions\n // Empirically tested: ~42 chars of mixed text (387px) fits before SDK wraps\n // Using 390px to account for measurement variance\n displayWidthPx: 390,\n maxLines: 7,\n\n // BLE constraints\n // Z100 uses Vuzix Ultralite SDK which handles chunking internally\n // These are conservative values for direct BLE if needed\n maxPayloadBytes: 512,\n bleChunkSize: 180,\n\n // Font metrics - Noto Sans Regular at 21px\n fontMetrics: {\n glyphWidths: new Map(Object.entries(Z100_GLYPH_WIDTHS)),\n defaultGlyphWidth: 12, // Average width from extracted metrics\n // Z100 uses direct pixel widths, no render formula needed\n renderFormula: (glyphWidth: number) => glyphWidth,\n\n // Uniform-width scripts for CJK and other non-Latin\n // Noto Sans CJK characters are typically wider\n uniformScripts: {\n cjk: 21, // Full-width CJK characters\n hiragana: 21,\n katakana: 21,\n korean: 21,\n cyrillic: 14, // Cyrillic is similar to Latin in Noto Sans\n },\n\n fallback: {\n latinMaxWidth: 20, // 'W' and 'm' are the widest at 20px\n unknownBehavior: \"useLatinMax\",\n },\n },\n\n constraints: {\n minCharsBeforeHyphen: 3,\n noStartChars: [\".\", \",\", \"!\", \"?\", \":\", \";\", \")\", \"]\", \"}\", \"。\", \",\", \"!\", \"?\", \":\", \";\", \")\", \"】\", \"」\"],\n noEndChars: [\"(\", \"[\", \"{\", \"(\", \"【\", \"「\"],\n },\n}\n\n/**\n * Get the hyphen width for Z100 in pixels.\n * Used for line breaking calculations.\n */\nexport const Z100_HYPHEN_WIDTH_PX = 7\n\n/**\n * Get the space width for Z100 in pixels.\n * Used for column alignment calculations.\n */\nexport const Z100_SPACE_WIDTH_PX = 5\n"]}
1
+ {"version":3,"file":"z100.js","sourceRoot":"","sources":["../../../../src/utils/display/profiles/z100.ts"],"names":[],"mappings":"AAAA,+IAA+I;AAC/I,OAAO,EAAC,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAC,MAAM,0BAA0B,CAAA","sourcesContent":["// Moved into the SDK (@glassly/miniapp/display) so miniapps lay text out the way the host measures it; this path re-exports it for the engine.\nexport {Z100_PROFILE, Z100_HYPHEN_WIDTH_PX, Z100_SPACE_WIDTH_PX} from \"@glassly/miniapp/display\"\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"degrade.d.ts","sourceRoot":"","sources":["../../../../src/utils/display/scene/degrade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,SAAS,CAAA;AAE9C,MAAM,WAAW,aAAa;IAC5B,+FAA+F;IAC/F,MAAM,EAAE;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAC,GAAG,IAAI,CAAA;IAC3D,QAAQ,EAAE,OAAO,CAAA;IACjB,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAYD,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,GAAG,aAAa,CA8C/E"}
1
+ {"version":3,"file":"degrade.d.ts","sourceRoot":"","sources":["../../../../src/utils/display/scene/degrade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,SAAS,CAAA;AAE9C,MAAM,WAAW,aAAa;IAC5B,+FAA+F;IAC/F,MAAM,EAAE;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAC,GAAG,IAAI,CAAA;IAC3D,QAAQ,EAAE,OAAO,CAAA;IACjB,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAYD,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,GAAG,aAAa,CAiD/E"}
@@ -22,6 +22,9 @@ export function degradeScene(input) {
22
22
  let degraded = false;
23
23
  const texts = [];
24
24
  input.forEach((el, index) => {
25
+ if (el && typeof el === "object" && Array.isArray(el.points)) {
26
+ return; // vector shapes: decoration on a text wall
27
+ }
25
28
  if (!el || typeof el !== "object" || !el.box) {
26
29
  // Malformed element — report it like the positioning pipeline does
27
30
  // instead of silently pretending the render was clean.
@@ -36,7 +39,7 @@ export function degradeScene(input) {
36
39
  dropped.push(el.id ?? `image[${index}]`);
37
40
  degraded = true;
38
41
  }
39
- // rects: silent drop — pure decoration on a text wall.
42
+ // rects and other shapes: silent drop — pure decoration on a text wall.
40
43
  });
41
44
  if (texts.length === 0) {
42
45
  return { layout: null, degraded, dropped };
@@ -1 +1 @@
1
- {"version":3,"file":"degrade.js","sourceRoot":"","sources":["../../../../src/utils/display/scene/degrade.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Degrade — compile a scene for devices that can't position elements\n * (`canPosition: false`: G1, Z100). Output is a LEGACY layout that rides the\n * existing display path — DisplayProcessor wraps it there, exactly as today,\n * which is what keeps sugar byte-identical on old hardware (spec §2/§5:\n * degrade output must be UNWRAPPED; wrapping twice breaks the goldens).\n *\n * Rules (design doc §3.4.8): content-preserving, never-erroring,\n * honestly-reported. Text collapses in reading order (y, then x) joined by\n * blank lines; EXACTLY two text elements sharing a y-range with disjoint\n * x-ranges become a double_text_wall (ColumnComposer path downstream); rects\n * drop silently (decoration); images drop + report.\n */\n\nimport type {SceneElementInput} from \"./types\"\n\nexport interface DegradedScene {\n /** Legacy layout for the existing display path, or null for an empty scene (caller clears). */\n layout: {layoutType: string; [key: string]: unknown} | null\n degraded: boolean\n dropped: string[]\n}\n\ntype TextEl = Extract<SceneElementInput, {type: \"text\"}>\n\nfunction yOverlap(a: TextEl, b: TextEl): boolean {\n return a.box.y < b.box.y + b.box.h && b.box.y < a.box.y + a.box.h\n}\n\nfunction xDisjoint(a: TextEl, b: TextEl): boolean {\n return a.box.x + a.box.w <= b.box.x || b.box.x + b.box.w <= a.box.x\n}\n\nexport function degradeScene(input: readonly SceneElementInput[]): DegradedScene {\n const dropped: string[] = []\n let degraded = false\n\n const texts: TextEl[] = []\n input.forEach((el, index) => {\n if (!el || typeof el !== \"object\" || !el.box) {\n // Malformed element — report it like the positioning pipeline does\n // instead of silently pretending the render was clean.\n dropped.push((el as {id?: string} | null)?.id ?? `element[${index}]`)\n degraded = true\n return\n }\n if (el.type === \"text\") {\n texts.push(el)\n } else if (el.type === \"image\") {\n dropped.push(el.id ?? `image[${index}]`)\n degraded = true\n }\n // rects: silent drop — pure decoration on a text wall.\n })\n\n if (texts.length === 0) {\n return {layout: null, degraded, dropped}\n }\n\n // Row exception: exactly 2 columns with clean separation — the shipped\n // double_text_wall mechanism (scope guard: nothing fancier; this is NOT a\n // layout engine).\n if (texts.length === 2 && yOverlap(texts[0], texts[1]) && xDisjoint(texts[0], texts[1])) {\n const [left, right] = texts[0].box.x <= texts[1].box.x ? [texts[0], texts[1]] : [texts[1], texts[0]]\n return {\n layout: {layoutType: \"double_text_wall\", topText: left.text ?? \"\", bottomText: right.text ?? \"\"},\n degraded,\n dropped,\n }\n }\n\n // Reading order: y, then x; join with blank lines. Downstream wrap clips\n // overflow per the device profile.\n const ordered = [...texts].sort((a, b) => a.box.y - b.box.y || a.box.x - b.box.x)\n const text = ordered\n .map((t) => t.text ?? \"\")\n .filter((t) => t.length > 0)\n .join(\"\\n\\n\")\n return {layout: {layoutType: \"text_wall\", text}, degraded, dropped}\n}\n"]}
1
+ {"version":3,"file":"degrade.js","sourceRoot":"","sources":["../../../../src/utils/display/scene/degrade.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Degrade — compile a scene for devices that can't position elements\n * (`canPosition: false`: G1, Z100). Output is a LEGACY layout that rides the\n * existing display path — DisplayProcessor wraps it there, exactly as today,\n * which is what keeps sugar byte-identical on old hardware (spec §2/§5:\n * degrade output must be UNWRAPPED; wrapping twice breaks the goldens).\n *\n * Rules (design doc §3.4.8): content-preserving, never-erroring,\n * honestly-reported. Text collapses in reading order (y, then x) joined by\n * blank lines; EXACTLY two text elements sharing a y-range with disjoint\n * x-ranges become a double_text_wall (ColumnComposer path downstream); rects\n * drop silently (decoration); images drop + report.\n */\n\nimport type {SceneElementInput} from \"./types\"\n\nexport interface DegradedScene {\n /** Legacy layout for the existing display path, or null for an empty scene (caller clears). */\n layout: {layoutType: string; [key: string]: unknown} | null\n degraded: boolean\n dropped: string[]\n}\n\ntype TextEl = Extract<SceneElementInput, {type: \"text\"}>\n\nfunction yOverlap(a: TextEl, b: TextEl): boolean {\n return a.box.y < b.box.y + b.box.h && b.box.y < a.box.y + a.box.h\n}\n\nfunction xDisjoint(a: TextEl, b: TextEl): boolean {\n return a.box.x + a.box.w <= b.box.x || b.box.x + b.box.w <= a.box.x\n}\n\nexport function degradeScene(input: readonly SceneElementInput[]): DegradedScene {\n const dropped: string[] = []\n let degraded = false\n\n const texts: TextEl[] = []\n input.forEach((el, index) => {\n if (el && typeof el === \"object\" && Array.isArray((el as {points?: unknown}).points)) {\n return // vector shapes: decoration on a text wall\n }\n if (!el || typeof el !== \"object\" || !el.box) {\n // Malformed element — report it like the positioning pipeline does\n // instead of silently pretending the render was clean.\n dropped.push((el as {id?: string} | null)?.id ?? `element[${index}]`)\n degraded = true\n return\n }\n if (el.type === \"text\") {\n texts.push(el)\n } else if (el.type === \"image\") {\n dropped.push(el.id ?? `image[${index}]`)\n degraded = true\n }\n // rects and other shapes: silent drop — pure decoration on a text wall.\n })\n\n if (texts.length === 0) {\n return {layout: null, degraded, dropped}\n }\n\n // Row exception: exactly 2 columns with clean separation — the shipped\n // double_text_wall mechanism (scope guard: nothing fancier; this is NOT a\n // layout engine).\n if (texts.length === 2 && yOverlap(texts[0], texts[1]) && xDisjoint(texts[0], texts[1])) {\n const [left, right] = texts[0].box.x <= texts[1].box.x ? [texts[0], texts[1]] : [texts[1], texts[0]]\n return {\n layout: {layoutType: \"double_text_wall\", topText: left.text ?? \"\", bottomText: right.text ?? \"\"},\n degraded,\n dropped,\n }\n }\n\n // Reading order: y, then x; join with blank lines. Downstream wrap clips\n // overflow per the device profile.\n const ordered = [...texts].sort((a, b) => a.box.y - b.box.y || a.box.x - b.box.x)\n const text = ordered\n .map((t) => t.text ?? \"\")\n .filter((t) => t.length > 0)\n .join(\"\\n\\n\")\n return {layout: {layoutType: \"text_wall\", text}, degraded, dropped}\n}\n"]}
@@ -14,15 +14,27 @@
14
14
  * synthesized id from the caller (SceneStore counter). Synthesized ids are
15
15
  * prefixed "~" so they can never collide with app-supplied ids.
16
16
  */
17
- import type { FrameElement, SceneBox, SceneElementType } from "./types";
17
+ import type { FrameElement, SceneBox, SceneElementType, ScenePoint, SceneTransition } from "./types";
18
18
  /** A processed (clamped/wrapped) element, pre-diff: id optional, no annotation yet. */
19
19
  export interface DiffableElement {
20
+ /** SVG path and its checked firmware command stream (Q4 coordinates). */
21
+ d?: string;
22
+ path?: number[];
23
+ pathScale?: number;
24
+ fillRule?: "nonzero" | "evenodd";
25
+ rotation?: number;
26
+ pivot?: ScenePoint;
27
+ depth?: number;
20
28
  id?: string;
21
29
  type: SceneElementType;
22
30
  box: SceneBox;
23
31
  text?: string;
24
32
  data?: string;
25
33
  style?: FrameElement["style"];
34
+ points?: ScenePoint[];
35
+ startDeg?: number;
36
+ endDeg?: number;
37
+ transition?: SceneTransition;
26
38
  contentHash: string;
27
39
  }
28
40
  export interface DiffResult {
@@ -1 +1 @@
1
- {"version":3,"file":"differ.d.ts","sourceRoot":"","sources":["../../../../src/utils/display/scene/differ.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAC,YAAY,EAAE,QAAQ,EAAe,gBAAgB,EAAC,MAAM,SAAS,CAAA;AAGlF,uFAAuF;AACvF,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,gBAAgB,CAAA;IACtB,GAAG,EAAE,QAAQ,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAA;IAC7B,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,YAAY,EAAE,CAAA;IACxB,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAyBD;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,SAAS,YAAY,EAAE,EAC7B,IAAI,EAAE,SAAS,eAAe,EAAE,EAChC,eAAe,EAAE,MAAM,MAAM,GAC5B,UAAU,CA2DZ"}
1
+ {"version":3,"file":"differ.d.ts","sourceRoot":"","sources":["../../../../src/utils/display/scene/differ.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAC,YAAY,EAAE,QAAQ,EAAe,gBAAgB,EAAE,UAAU,EAAE,eAAe,EAAC,MAAM,SAAS,CAAA;AAG/G,uFAAuF;AACvF,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,CAAC,CAAC,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,gBAAgB,CAAA;IACtB,GAAG,EAAE,QAAQ,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAA;IAC7B,MAAM,CAAC,EAAE,UAAU,EAAE,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,YAAY,EAAE,CAAA;IACxB,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAoCD;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,SAAS,YAAY,EAAE,EAC7B,IAAI,EAAE,SAAS,eAAe,EAAE,EAChC,eAAe,EAAE,MAAM,MAAM,GAC5B,UAAU,CA2DZ"}
@@ -39,6 +39,28 @@ function buildFrameElement(el, id, change) {
39
39
  out.data = el.data;
40
40
  if (el.style !== undefined)
41
41
  out.style = el.style;
42
+ if (el.points !== undefined)
43
+ out.points = el.points;
44
+ if (el.startDeg !== undefined)
45
+ out.startDeg = el.startDeg;
46
+ if (el.endDeg !== undefined)
47
+ out.endDeg = el.endDeg;
48
+ if (el.transition !== undefined)
49
+ out.transition = el.transition;
50
+ if (el.d !== undefined)
51
+ out.d = el.d;
52
+ if (el.path !== undefined)
53
+ out.path = el.path;
54
+ if (el.pathScale !== undefined)
55
+ out.pathScale = el.pathScale;
56
+ if (el.fillRule !== undefined)
57
+ out.fillRule = el.fillRule;
58
+ if (el.rotation !== undefined)
59
+ out.rotation = el.rotation;
60
+ if (el.pivot !== undefined)
61
+ out.pivot = el.pivot;
62
+ if (el.depth !== undefined)
63
+ out.depth = el.depth;
42
64
  return out;
43
65
  }
44
66
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"differ.js","sourceRoot":"","sources":["../../../../src/utils/display/scene/differ.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Scene differ — matches elements between the last frame sent to the device and\n * the next scene, and classifies each element's change. Pure set arithmetic:\n * nothing in here is device-specific (spec §1).\n *\n * Matching rules (design doc §3.4.1, in order):\n * 1. same explicit `id` + same `type` ⇒ same element\n * 2. no id: same `type` + identical box ⇒ same element\n * 3. no id: same `type`, by order among the still-unmatched\n * 4. anything unmatched in prev ⇒ removed; unmatched in next ⇒ created\n *\n * Matched no-id elements INHERIT the previous element's assigned id so the\n * device-side id⇒firmware-component mapping stays stable; fresh elements get a\n * synthesized id from the caller (SceneStore counter). Synthesized ids are\n * prefixed \"~\" so they can never collide with app-supplied ids.\n */\n\nimport type {FrameElement, SceneBox, SceneChange, SceneElementType} from \"./types\"\nimport {boxesEqual} from \"./types\"\n\n/** A processed (clamped/wrapped) element, pre-diff: id optional, no annotation yet. */\nexport interface DiffableElement {\n id?: string\n type: SceneElementType\n box: SceneBox\n text?: string\n data?: string\n style?: FrameElement[\"style\"]\n contentHash: string\n}\n\nexport interface DiffResult {\n elements: FrameElement[]\n removed: string[]\n}\n\nfunction classify(prev: FrameElement, next: DiffableElement): SceneChange {\n if (!boxesEqual(prev.box, next.box)) return \"moved\"\n if (prev.contentHash !== next.contentHash) return \"updated\"\n return \"unchanged\"\n}\n\n/**\n * Assemble the annotated FrameElement, OMITTING optional fields that are\n * undefined. A present key with an `undefined` value cannot cross the Expo\n * Android bridge — its `Map<String, Any>` converter rejects it (\"Value is\n * undefined, expected an Object\"), which surfaces as ERR_UNEXPECTED from\n * displayEvent. (iOS's `[String: Any]` bridge silently drops nils, so the\n * defect was invisible there.) Keeping the keys absent — not undefined —\n * matches the optional-field contract in types.ts.\n */\nfunction buildFrameElement(el: DiffableElement, id: string, change: SceneChange): FrameElement {\n const out: FrameElement = {id, type: el.type, box: el.box, contentHash: el.contentHash, change}\n if (el.text !== undefined) out.text = el.text\n if (el.data !== undefined) out.data = el.data\n if (el.style !== undefined) out.style = el.style\n return out\n}\n\n/**\n * Diff `next` against `prev` (the last frame sent for this app/view/device;\n * empty array for a fresh scene). `nextSyntheticId` mints ids for elements the\n * app didn't name — must be stable per (app, view) across calls (SceneStore).\n */\nexport function diffScene(\n prev: readonly FrameElement[],\n next: readonly DiffableElement[],\n nextSyntheticId: () => string,\n): DiffResult {\n const prevUnmatched = new Set(prev.map((_, i) => i))\n const prevByExplicitId = new Map<string, number>()\n prev.forEach((el, i) => {\n if (!el.id.startsWith(\"~\")) prevByExplicitId.set(`${el.type}:${el.id}`, i)\n })\n\n // matches[nextIndex] = prevIndex | undefined\n const matches: (number | undefined)[] = new Array(next.length).fill(undefined)\n\n // Pass 1: explicit id + type.\n next.forEach((el, i) => {\n if (!el.id) return\n const j = prevByExplicitId.get(`${el.type}:${el.id}`)\n if (j !== undefined && prevUnmatched.has(j)) {\n matches[i] = j\n prevUnmatched.delete(j)\n }\n })\n\n // Pass 2: no-id elements match a no-id prev element of the same type with an\n // identical box.\n next.forEach((el, i) => {\n if (el.id || matches[i] !== undefined) return\n for (const j of prevUnmatched) {\n const p = prev[j]\n if (p.id.startsWith(\"~\") && p.type === el.type && boxesEqual(p.box, el.box)) {\n matches[i] = j\n prevUnmatched.delete(j)\n break\n }\n }\n })\n\n // Pass 3: remaining no-id elements match remaining no-id prev of the same\n // type in order (k-th unmatched text ↔ k-th unmatched text).\n next.forEach((el, i) => {\n if (el.id || matches[i] !== undefined) return\n for (const j of prevUnmatched) {\n const p = prev[j]\n if (p.id.startsWith(\"~\") && p.type === el.type) {\n matches[i] = j\n prevUnmatched.delete(j)\n break\n }\n }\n })\n\n const elements: FrameElement[] = next.map((el, i) => {\n const j = matches[i]\n if (j !== undefined) {\n const p = prev[j]\n return buildFrameElement(el, el.id ?? p.id, classify(p, el))\n }\n return buildFrameElement(el, el.id ?? nextSyntheticId(), \"created\")\n })\n\n const removed = [...prevUnmatched].map((j) => prev[j].id)\n return {elements, removed}\n}\n"]}
1
+ {"version":3,"file":"differ.js","sourceRoot":"","sources":["../../../../src/utils/display/scene/differ.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Scene differ — matches elements between the last frame sent to the device and\n * the next scene, and classifies each element's change. Pure set arithmetic:\n * nothing in here is device-specific (spec §1).\n *\n * Matching rules (design doc §3.4.1, in order):\n * 1. same explicit `id` + same `type` ⇒ same element\n * 2. no id: same `type` + identical box ⇒ same element\n * 3. no id: same `type`, by order among the still-unmatched\n * 4. anything unmatched in prev ⇒ removed; unmatched in next ⇒ created\n *\n * Matched no-id elements INHERIT the previous element's assigned id so the\n * device-side id⇒firmware-component mapping stays stable; fresh elements get a\n * synthesized id from the caller (SceneStore counter). Synthesized ids are\n * prefixed \"~\" so they can never collide with app-supplied ids.\n */\n\nimport type {FrameElement, SceneBox, SceneChange, SceneElementType, ScenePoint, SceneTransition} from \"./types\"\nimport {boxesEqual} from \"./types\"\n\n/** A processed (clamped/wrapped) element, pre-diff: id optional, no annotation yet. */\nexport interface DiffableElement {\n /** SVG path and its checked firmware command stream (Q4 coordinates). */\n d?: string\n path?: number[]\n pathScale?: number\n fillRule?: \"nonzero\" | \"evenodd\"\n rotation?: number\n pivot?: ScenePoint\n depth?: number\n\n id?: string\n type: SceneElementType\n box: SceneBox\n text?: string\n data?: string\n style?: FrameElement[\"style\"]\n points?: ScenePoint[]\n startDeg?: number\n endDeg?: number\n transition?: SceneTransition\n contentHash: string\n}\n\nexport interface DiffResult {\n elements: FrameElement[]\n removed: string[]\n}\n\nfunction classify(prev: FrameElement, next: DiffableElement): SceneChange {\n if (!boxesEqual(prev.box, next.box)) return \"moved\"\n if (prev.contentHash !== next.contentHash) return \"updated\"\n return \"unchanged\"\n}\n\n/**\n * Assemble the annotated FrameElement, OMITTING optional fields that are\n * undefined. A present key with an `undefined` value cannot cross the Expo\n * Android bridge — its `Map<String, Any>` converter rejects it (\"Value is\n * undefined, expected an Object\"), which surfaces as ERR_UNEXPECTED from\n * displayEvent. (iOS's `[String: Any]` bridge silently drops nils, so the\n * defect was invisible there.) Keeping the keys absent — not undefined —\n * matches the optional-field contract in types.ts.\n */\nfunction buildFrameElement(el: DiffableElement, id: string, change: SceneChange): FrameElement {\n const out: FrameElement = {id, type: el.type, box: el.box, contentHash: el.contentHash, change}\n if (el.text !== undefined) out.text = el.text\n if (el.data !== undefined) out.data = el.data\n if (el.style !== undefined) out.style = el.style\n if (el.points !== undefined) out.points = el.points\n if (el.startDeg !== undefined) out.startDeg = el.startDeg\n if (el.endDeg !== undefined) out.endDeg = el.endDeg\n if (el.transition !== undefined) out.transition = el.transition\n if (el.d !== undefined) out.d = el.d\n if (el.path !== undefined) out.path = el.path\n if (el.pathScale !== undefined) out.pathScale = el.pathScale\n if (el.fillRule !== undefined) out.fillRule = el.fillRule\n if (el.rotation !== undefined) out.rotation = el.rotation\n if (el.pivot !== undefined) out.pivot = el.pivot\n if (el.depth !== undefined) out.depth = el.depth\n return out\n}\n\n/**\n * Diff `next` against `prev` (the last frame sent for this app/view/device;\n * empty array for a fresh scene). `nextSyntheticId` mints ids for elements the\n * app didn't name — must be stable per (app, view) across calls (SceneStore).\n */\nexport function diffScene(\n prev: readonly FrameElement[],\n next: readonly DiffableElement[],\n nextSyntheticId: () => string,\n): DiffResult {\n const prevUnmatched = new Set(prev.map((_, i) => i))\n const prevByExplicitId = new Map<string, number>()\n prev.forEach((el, i) => {\n if (!el.id.startsWith(\"~\")) prevByExplicitId.set(`${el.type}:${el.id}`, i)\n })\n\n // matches[nextIndex] = prevIndex | undefined\n const matches: (number | undefined)[] = new Array(next.length).fill(undefined)\n\n // Pass 1: explicit id + type.\n next.forEach((el, i) => {\n if (!el.id) return\n const j = prevByExplicitId.get(`${el.type}:${el.id}`)\n if (j !== undefined && prevUnmatched.has(j)) {\n matches[i] = j\n prevUnmatched.delete(j)\n }\n })\n\n // Pass 2: no-id elements match a no-id prev element of the same type with an\n // identical box.\n next.forEach((el, i) => {\n if (el.id || matches[i] !== undefined) return\n for (const j of prevUnmatched) {\n const p = prev[j]\n if (p.id.startsWith(\"~\") && p.type === el.type && boxesEqual(p.box, el.box)) {\n matches[i] = j\n prevUnmatched.delete(j)\n break\n }\n }\n })\n\n // Pass 3: remaining no-id elements match remaining no-id prev of the same\n // type in order (k-th unmatched text ↔ k-th unmatched text).\n next.forEach((el, i) => {\n if (el.id || matches[i] !== undefined) return\n for (const j of prevUnmatched) {\n const p = prev[j]\n if (p.id.startsWith(\"~\") && p.type === el.type) {\n matches[i] = j\n prevUnmatched.delete(j)\n break\n }\n }\n })\n\n const elements: FrameElement[] = next.map((el, i) => {\n const j = matches[i]\n if (j !== undefined) {\n const p = prev[j]\n return buildFrameElement(el, el.id ?? p.id, classify(p, el))\n }\n return buildFrameElement(el, el.id ?? nextSyntheticId(), \"created\")\n })\n\n const removed = [...prevUnmatched].map((j) => prev[j].id)\n return {elements, removed}\n}\n"]}
@@ -1,4 +1,4 @@
1
- export type { FrameElement, SceneAnchor, SceneBox, SceneBoxInput, SceneBreakMode, SceneChange, SceneDisplayCapabilities, SceneElementInput, SceneElementType, SceneFrame, SceneProcessResult, SceneRectStyle, SceneTextStyle, } from "./types";
1
+ export type { FrameElement, SceneAnchor, SceneBox, SceneBoxInput, SceneBreakMode, SceneChange, SceneDisplayCapabilities, SceneElementInput, SceneElementType, SceneFrame, SceneImageStyle, ScenePoint, SceneProcessResult, SceneRectStyle, SceneShapeStyle, SceneStrokeStyle, SceneTextStyle, SceneTransition, } from "./types";
2
2
  export { boxesEqual, contentHash, elementContentHash } from "./types";
3
3
  export { resolveAnchors } from "./anchor";
4
4
  export type { DiffResult, DiffableElement } from "./differ";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/display/scene/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,aAAa,EACb,cAAc,EACd,WAAW,EACX,wBAAwB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,cAAc,GACf,MAAM,SAAS,CAAA;AAChB,OAAO,EAAC,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAC,MAAM,SAAS,CAAA;AACnE,OAAO,EAAC,cAAc,EAAC,MAAM,UAAU,CAAA;AACvC,YAAY,EAAC,UAAU,EAAE,eAAe,EAAC,MAAM,UAAU,CAAA;AACzD,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAA;AAClC,YAAY,EAAC,cAAc,EAAC,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAC,YAAY,EAAE,mBAAmB,EAAC,MAAM,WAAW,CAAA;AAC3D,YAAY,EAAC,aAAa,EAAC,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAC,YAAY,EAAC,MAAM,WAAW,CAAA;AACtC,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/display/scene/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,aAAa,EACb,cAAc,EACd,WAAW,EACX,wBAAwB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,eAAe,GAChB,MAAM,SAAS,CAAA;AAChB,OAAO,EAAC,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAC,MAAM,SAAS,CAAA;AACnE,OAAO,EAAC,cAAc,EAAC,MAAM,UAAU,CAAA;AACvC,YAAY,EAAC,UAAU,EAAE,eAAe,EAAC,MAAM,UAAU,CAAA;AACzD,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAA;AAClC,YAAY,EAAC,cAAc,EAAC,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAC,YAAY,EAAE,mBAAmB,EAAC,MAAM,WAAW,CAAA;AAC3D,YAAY,EAAC,aAAa,EAAC,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAC,YAAY,EAAC,MAAM,WAAW,CAAA;AACtC,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/display/scene/index.ts"],"names":[],"mappings":"AAeA,OAAO,EAAC,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAC,MAAM,SAAS,CAAA;AACnE,OAAO,EAAC,cAAc,EAAC,MAAM,UAAU,CAAA;AAEvC,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAA;AAElC,OAAO,EAAC,YAAY,EAAE,mBAAmB,EAAC,MAAM,WAAW,CAAA;AAE3D,OAAO,EAAC,YAAY,EAAC,MAAM,WAAW,CAAA;AACtC,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAA","sourcesContent":["export type {\n FrameElement,\n SceneAnchor,\n SceneBox,\n SceneBoxInput,\n SceneBreakMode,\n SceneChange,\n SceneDisplayCapabilities,\n SceneElementInput,\n SceneElementType,\n SceneFrame,\n SceneProcessResult,\n SceneRectStyle,\n SceneTextStyle,\n} from \"./types\"\nexport {boxesEqual, contentHash, elementContentHash} from \"./types\"\nexport {resolveAnchors} from \"./anchor\"\nexport type {DiffResult, DiffableElement} from \"./differ\"\nexport {diffScene} from \"./differ\"\nexport type {ProcessedScene} from \"./process\"\nexport {processScene, profileLineHeightPx} from \"./process\"\nexport type {DegradedScene} from \"./degrade\"\nexport {degradeScene} from \"./degrade\"\nexport {SceneStore} from \"./store\"\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/display/scene/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAC,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAC,MAAM,SAAS,CAAA;AACnE,OAAO,EAAC,cAAc,EAAC,MAAM,UAAU,CAAA;AAEvC,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAA;AAElC,OAAO,EAAC,YAAY,EAAE,mBAAmB,EAAC,MAAM,WAAW,CAAA;AAE3D,OAAO,EAAC,YAAY,EAAC,MAAM,WAAW,CAAA;AACtC,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAA","sourcesContent":["export type {\n FrameElement,\n SceneAnchor,\n SceneBox,\n SceneBoxInput,\n SceneBreakMode,\n SceneChange,\n SceneDisplayCapabilities,\n SceneElementInput,\n SceneElementType,\n SceneFrame,\n SceneImageStyle,\n ScenePoint,\n SceneProcessResult,\n SceneRectStyle,\n SceneShapeStyle,\n SceneStrokeStyle,\n SceneTextStyle,\n SceneTransition,\n} from \"./types\"\nexport {boxesEqual, contentHash, elementContentHash} from \"./types\"\nexport {resolveAnchors} from \"./anchor\"\nexport type {DiffResult, DiffableElement} from \"./differ\"\nexport {diffScene} from \"./differ\"\nexport type {ProcessedScene} from \"./process\"\nexport {processScene, profileLineHeightPx} from \"./process\"\nexport type {DegradedScene} from \"./degrade\"\nexport {degradeScene} from \"./degrade\"\nexport {SceneStore} from \"./store\"\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../../../src/utils/display/scene/process.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,UAAU,CAAA;AAC7C,OAAO,KAAK,EAAW,wBAAwB,EAAE,iBAAiB,EAAiB,MAAM,SAAS,CAAA;AAGlG,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,QAAQ,EAAE,OAAO,CAAA;IACjB,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAyBD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEjG;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,SAAS,iBAAiB,EAAE,EACnC,IAAI,EAAE,wBAAwB,EAC9B,OAAO,EAAE,cAAc,GACtB,cAAc,CA+JhB"}
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../../../src/utils/display/scene/process.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,UAAU,CAAA;AAC7C,OAAO,KAAK,EAGV,wBAAwB,EACxB,iBAAiB,EAIlB,MAAM,SAAS,CAAA;AAGhB,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,QAAQ,EAAE,OAAO,CAAA;IACjB,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAsDD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEjG;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,SAAS,iBAAiB,EAAE,EACnC,IAAI,EAAE,wBAAwB,EAC9B,OAAO,EAAE,cAAc,GACtB,cAAc,CAgThB"}