@the-inclusionist/engine 9.0.0 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (532) hide show
  1. package/README.md +120 -78
  2. package/app/css/style.css +761 -377
  3. package/app/public/vendor/fonts/playwrite-cu.woff2 +0 -0
  4. package/app/public/vendor/fonts/playwrite-es-deco.woff2 +0 -0
  5. package/app/public/vendor/fonts/playwrite-es.woff2 +0 -0
  6. package/app/public/vendor/fonts/playwrite-gb-j.woff2 +0 -0
  7. package/app/public/vendor/fonts/playwrite-gb-s.woff2 +0 -0
  8. package/app/public/vendor/fonts/playwrite-pe.woff2 +0 -0
  9. package/app/public/vendor/fonts/playwrite-pt.woff2 +0 -0
  10. package/app/public/vendor/fonts-licences/NOTICE.txt +166 -0
  11. package/app/public/vendor/fonts-licences/OFL-1.1.txt +86 -0
  12. package/app/public/vendor/fonts.css +36 -84
  13. package/dist-pkg/boot/create-game.d.ts +499 -219
  14. package/dist-pkg/boot/create-game.js +3944 -562
  15. package/dist-pkg/core/a11y-sr.d.ts +25 -3
  16. package/dist-pkg/core/a11y-sr.js +38 -19
  17. package/dist-pkg/core/accessible-label.d.ts +17 -0
  18. package/dist-pkg/core/accessible-label.js +37 -0
  19. package/dist-pkg/core/accommodation-subjects.d.ts +26 -0
  20. package/dist-pkg/core/accommodation-subjects.js +32 -0
  21. package/dist-pkg/core/accommodations.d.ts +125 -0
  22. package/dist-pkg/core/accommodations.js +195 -0
  23. package/dist-pkg/core/actions.d.ts +108 -55
  24. package/dist-pkg/core/actions.js +122 -71
  25. package/dist-pkg/core/calm-mode.d.ts +31 -0
  26. package/dist-pkg/core/calm-mode.js +47 -0
  27. package/dist-pkg/core/camera-cycle.d.ts +15 -0
  28. package/dist-pkg/core/camera-cycle.js +7 -0
  29. package/dist-pkg/core/caption-duration.d.ts +15 -0
  30. package/dist-pkg/core/caption-duration.js +19 -0
  31. package/dist-pkg/core/cartridge-problems.d.ts +34 -0
  32. package/dist-pkg/core/cartridge-problems.js +53 -0
  33. package/dist-pkg/core/constants.d.ts +0 -54
  34. package/dist-pkg/core/constants.js +9 -76
  35. package/dist-pkg/core/contract.d.ts +142 -164
  36. package/dist-pkg/core/contract.js +222 -208
  37. package/dist-pkg/core/dom-query.d.ts +4 -4
  38. package/dist-pkg/core/dom-query.js +12 -20
  39. package/dist-pkg/core/entity.d.ts +62 -77
  40. package/dist-pkg/core/entity.js +18 -32
  41. package/dist-pkg/core/escape-html.d.ts +9 -10
  42. package/dist-pkg/core/escape-html.js +16 -20
  43. package/dist-pkg/core/flash-threshold.d.ts +17 -0
  44. package/dist-pkg/core/flash-threshold.js +113 -0
  45. package/dist-pkg/core/game-speed.d.ts +11 -0
  46. package/dist-pkg/core/game-speed.js +16 -0
  47. package/dist-pkg/core/genres.d.ts +20 -0
  48. package/dist-pkg/core/genres.js +44 -0
  49. package/dist-pkg/core/i18n.d.ts +71 -60
  50. package/dist-pkg/core/i18n.js +186 -200
  51. package/dist-pkg/core/loop.d.ts +17 -6
  52. package/dist-pkg/core/loop.js +26 -26
  53. package/dist-pkg/core/pause-icon-catalogue.d.ts +15 -0
  54. package/dist-pkg/core/pause-icon-catalogue.js +54 -0
  55. package/dist-pkg/core/ring.d.ts +17 -0
  56. package/dist-pkg/core/ring.js +29 -0
  57. package/dist-pkg/core/rng.d.ts +7 -12
  58. package/dist-pkg/core/rng.js +23 -53
  59. package/dist-pkg/core/route.d.ts +26 -26
  60. package/dist-pkg/core/route.js +126 -121
  61. package/dist-pkg/core/scenes.d.ts +37 -40
  62. package/dist-pkg/core/scenes.js +41 -43
  63. package/dist-pkg/core/screens.d.ts +4 -4
  64. package/dist-pkg/core/screens.js +11 -16
  65. package/dist-pkg/core/session-clock.d.ts +23 -0
  66. package/dist-pkg/core/session-clock.js +37 -0
  67. package/dist-pkg/core/setting-defaults.d.ts +61 -0
  68. package/dist-pkg/core/setting-defaults.js +66 -0
  69. package/dist-pkg/core/speech-rate.d.ts +29 -0
  70. package/dist-pkg/core/speech-rate.js +47 -0
  71. package/dist-pkg/core/state.d.ts +118 -118
  72. package/dist-pkg/core/state.js +322 -297
  73. package/dist-pkg/core/visual-cycles.d.ts +30 -0
  74. package/dist-pkg/core/visual-cycles.js +52 -0
  75. package/dist-pkg/core/visual-state.d.ts +13 -0
  76. package/dist-pkg/core/visual-state.js +6 -0
  77. package/dist-pkg/educational/activities-registry.d.ts +1 -1
  78. package/dist-pkg/educational/activities-registry.js +9 -8
  79. package/dist-pkg/educational/adaptive-engine.d.ts +11 -11
  80. package/dist-pkg/educational/adaptive-engine.js +17 -17
  81. package/dist-pkg/educational/segment-bar.d.ts +12 -12
  82. package/dist-pkg/educational/segment-bar.js +9 -9
  83. package/dist-pkg/i18n/en.js +324 -223
  84. package/dist-pkg/i18n/es.js +323 -223
  85. package/dist-pkg/i18n/pt.js +348 -226
  86. package/dist-pkg/input/default-bindings.d.ts +37 -38
  87. package/dist-pkg/input/default-bindings.js +127 -144
  88. package/dist-pkg/input/devices.d.ts +7 -7
  89. package/dist-pkg/input/devices.js +17 -16
  90. package/dist-pkg/input/edges.d.ts +23 -32
  91. package/dist-pkg/input/edges.js +23 -28
  92. package/dist-pkg/input/empathy-filter.d.ts +22 -0
  93. package/dist-pkg/input/empathy-filter.js +34 -0
  94. package/dist-pkg/input/face-map.d.ts +96 -0
  95. package/dist-pkg/input/face-map.js +255 -0
  96. package/dist-pkg/input/face-signals.d.ts +40 -0
  97. package/dist-pkg/input/face-signals.js +48 -0
  98. package/dist-pkg/input/gamepad.d.ts +195 -145
  99. package/dist-pkg/input/gamepad.js +383 -556
  100. package/dist-pkg/input/gaze-cycle.d.ts +64 -0
  101. package/dist-pkg/input/gaze-cycle.js +133 -0
  102. package/dist-pkg/input/gaze-relative.d.ts +68 -0
  103. package/dist-pkg/input/gaze-relative.js +142 -0
  104. package/dist-pkg/input/hand-map.d.ts +28 -0
  105. package/dist-pkg/input/hand-map.js +142 -0
  106. package/dist-pkg/input/input-cooldown.d.ts +17 -0
  107. package/dist-pkg/input/input-cooldown.js +39 -0
  108. package/dist-pkg/input/key-default.d.ts +30 -0
  109. package/dist-pkg/input/key-default.js +60 -0
  110. package/dist-pkg/input/keyboard-runtime.d.ts +15 -21
  111. package/dist-pkg/input/keyboard-runtime.js +23 -27
  112. package/dist-pkg/input/keyboard.d.ts +68 -63
  113. package/dist-pkg/input/keyboard.js +83 -105
  114. package/dist-pkg/input/keydown.d.ts +123 -137
  115. package/dist-pkg/input/keydown.js +284 -289
  116. package/dist-pkg/input/latch-edge.d.ts +33 -21
  117. package/dist-pkg/input/latch-edge.js +34 -35
  118. package/dist-pkg/input/latch-scope.d.ts +51 -50
  119. package/dist-pkg/input/latch-scope.js +61 -82
  120. package/dist-pkg/input/latch-store.d.ts +26 -30
  121. package/dist-pkg/input/latch-store.js +42 -50
  122. package/dist-pkg/input/latch-sync.d.ts +29 -29
  123. package/dist-pkg/input/latch-sync.js +25 -25
  124. package/dist-pkg/input/latch.d.ts +14 -17
  125. package/dist-pkg/input/latch.js +29 -37
  126. package/dist-pkg/input/pad-defaults.d.ts +13 -16
  127. package/dist-pkg/input/pad-defaults.js +21 -28
  128. package/dist-pkg/input/pad-reading.d.ts +76 -0
  129. package/dist-pkg/input/pad-reading.js +169 -0
  130. package/dist-pkg/input/pad-wizard.d.ts +99 -0
  131. package/dist-pkg/input/pad-wizard.js +256 -0
  132. package/dist-pkg/input/pointer-space.d.ts +19 -20
  133. package/dist-pkg/input/pointer-space.js +27 -32
  134. package/dist-pkg/input/pointer.d.ts +39 -40
  135. package/dist-pkg/input/pointer.js +42 -45
  136. package/dist-pkg/input/state.d.ts +101 -89
  137. package/dist-pkg/input/state.js +54 -134
  138. package/dist-pkg/input/switch-scan.d.ts +59 -0
  139. package/dist-pkg/input/switch-scan.js +67 -0
  140. package/dist-pkg/input/synthetic-source.d.ts +42 -0
  141. package/dist-pkg/input/synthetic-source.js +57 -0
  142. package/dist-pkg/input/touch-bindings.d.ts +127 -116
  143. package/dist-pkg/input/touch-bindings.js +158 -173
  144. package/dist-pkg/input/touch.d.ts +147 -72
  145. package/dist-pkg/input/touch.js +362 -126
  146. package/dist-pkg/input/transport-in-use.d.ts +107 -0
  147. package/dist-pkg/input/transport-in-use.js +130 -0
  148. package/dist-pkg/input/transports.d.ts +90 -117
  149. package/dist-pkg/input/transports.js +104 -106
  150. package/dist-pkg/input/virtual-controller.d.ts +82 -0
  151. package/dist-pkg/input/virtual-controller.js +69 -0
  152. package/dist-pkg/input/vocabulary-migration.d.ts +50 -49
  153. package/dist-pkg/input/vocabulary-migration.js +80 -79
  154. package/dist-pkg/input/voice-map.d.ts +59 -0
  155. package/dist-pkg/input/voice-map.js +123 -0
  156. package/dist-pkg/platform/audio-ambient.d.ts +13 -2
  157. package/dist-pkg/platform/audio-ambient.js +14 -14
  158. package/dist-pkg/platform/audio-earcons.d.ts +20 -19
  159. package/dist-pkg/platform/audio-earcons.js +51 -42
  160. package/dist-pkg/platform/audio-jingles.js +9 -10
  161. package/dist-pkg/platform/audio-mixer.d.ts +14 -2
  162. package/dist-pkg/platform/audio-mixer.js +31 -39
  163. package/dist-pkg/platform/audio-sonar.d.ts +49 -152
  164. package/dist-pkg/platform/audio-sonar.js +124 -302
  165. package/dist-pkg/platform/audio.d.ts +62 -19
  166. package/dist-pkg/platform/audio.js +193 -168
  167. package/dist-pkg/platform/choose-by-voice.d.ts +70 -0
  168. package/dist-pkg/platform/choose-by-voice.js +157 -0
  169. package/dist-pkg/platform/flash-sampler.d.ts +19 -0
  170. package/dist-pkg/platform/flash-sampler.js +79 -0
  171. package/dist-pkg/platform/font-library.d.ts +77 -0
  172. package/dist-pkg/platform/font-library.js +98 -0
  173. package/dist-pkg/platform/font-library.json +721 -0
  174. package/dist-pkg/platform/heavy-catalogue.d.ts +77 -0
  175. package/dist-pkg/platform/heavy-catalogue.js +256 -0
  176. package/dist-pkg/platform/heavy-mirror.d.ts +20 -0
  177. package/dist-pkg/platform/heavy-mirror.js +73 -0
  178. package/dist-pkg/platform/heavy.d.ts +136 -0
  179. package/dist-pkg/platform/heavy.js +324 -0
  180. package/dist-pkg/platform/interruptible-speech.d.ts +23 -16
  181. package/dist-pkg/platform/interruptible-speech.js +77 -54
  182. package/dist-pkg/platform/kokoro-port.d.ts +27 -0
  183. package/dist-pkg/platform/kokoro-port.js +50 -0
  184. package/dist-pkg/platform/kokoro-runtime.d.ts +20 -0
  185. package/dist-pkg/platform/kokoro-runtime.js +52 -0
  186. package/dist-pkg/platform/kokoro.d.ts +70 -0
  187. package/dist-pkg/platform/kokoro.js +133 -0
  188. package/dist-pkg/platform/listener-scope.d.ts +12 -0
  189. package/dist-pkg/platform/listener-scope.js +90 -0
  190. package/dist-pkg/platform/locale-host.d.ts +14 -0
  191. package/dist-pkg/platform/locale-host.js +45 -0
  192. package/dist-pkg/platform/microphone.d.ts +51 -0
  193. package/dist-pkg/platform/microphone.js +118 -0
  194. package/dist-pkg/platform/onnx-runtime.d.ts +34 -0
  195. package/dist-pkg/platform/onnx-runtime.js +42 -0
  196. package/dist-pkg/platform/reading-in-worker.d.ts +64 -0
  197. package/dist-pkg/platform/reading-in-worker.js +125 -0
  198. package/dist-pkg/platform/reading-model.d.ts +94 -0
  199. package/dist-pkg/platform/reading-model.js +272 -0
  200. package/dist-pkg/platform/reading-runtime.d.ts +24 -0
  201. package/dist-pkg/platform/reading-runtime.js +164 -0
  202. package/dist-pkg/platform/reading-worker.d.ts +41 -0
  203. package/dist-pkg/platform/reading-worker.js +58 -0
  204. package/dist-pkg/platform/reading.d.ts +80 -0
  205. package/dist-pkg/platform/reading.js +136 -0
  206. package/dist-pkg/platform/speech-recognition.d.ts +60 -0
  207. package/dist-pkg/platform/speech-recognition.js +104 -0
  208. package/dist-pkg/platform/speech.d.ts +23 -1
  209. package/dist-pkg/platform/speech.js +29 -18
  210. package/dist-pkg/platform/storage-keys.d.ts +96 -0
  211. package/dist-pkg/platform/storage-keys.js +106 -0
  212. package/dist-pkg/platform/storage.d.ts +46 -111
  213. package/dist-pkg/platform/storage.js +104 -169
  214. package/dist-pkg/platform/tts.d.ts +85 -39
  215. package/dist-pkg/platform/tts.js +447 -127
  216. package/dist-pkg/platform/vision-loop.d.ts +23 -0
  217. package/dist-pkg/platform/vision-loop.js +56 -0
  218. package/dist-pkg/platform/vision.d.ts +132 -0
  219. package/dist-pkg/platform/vision.js +117 -0
  220. package/dist-pkg/platform/voice-listener.d.ts +40 -0
  221. package/dist-pkg/platform/voice-listener.js +88 -0
  222. package/dist-pkg/platform/voice-plan.d.ts +15 -98
  223. package/dist-pkg/platform/voice-plan.js +56 -143
  224. package/dist-pkg/platform/vosk-runtime.d.ts +96 -0
  225. package/dist-pkg/platform/vosk-runtime.js +151 -0
  226. package/dist-pkg/platform/vosk-vocabulary.d.ts +6 -0
  227. package/dist-pkg/platform/vosk-vocabulary.js +178 -0
  228. package/dist-pkg/render/canvas.d.ts +13 -7
  229. package/dist-pkg/render/canvas.js +13 -13
  230. package/dist-pkg/render/crt.d.ts +48 -12
  231. package/dist-pkg/render/crt.js +78 -80
  232. package/dist-pkg/render/cvd-matrices.d.ts +22 -18
  233. package/dist-pkg/render/cvd-matrices.js +37 -38
  234. package/dist-pkg/render/hc-role-data.d.ts +7 -7
  235. package/dist-pkg/render/hc-role-data.js +14 -14
  236. package/dist-pkg/render/high-contrast.d.ts +67 -56
  237. package/dist-pkg/render/high-contrast.js +226 -217
  238. package/dist-pkg/render/low-vision-drawing.d.ts +5 -0
  239. package/dist-pkg/render/low-vision-drawing.js +46 -0
  240. package/dist-pkg/render/lq-filter.d.ts +32 -20
  241. package/dist-pkg/render/lq-filter.js +59 -65
  242. package/dist-pkg/render/port.d.ts +86 -88
  243. package/dist-pkg/render/port.js +17 -23
  244. package/dist-pkg/render/screen-pipeline.d.ts +42 -42
  245. package/dist-pkg/render/screen-pipeline.js +80 -87
  246. package/dist-pkg/render/sprite-fx.d.ts +2 -1
  247. package/dist-pkg/render/sprite-fx.js +16 -14
  248. package/dist-pkg/render/viewports.d.ts +20 -15
  249. package/dist-pkg/render/viewports.js +83 -114
  250. package/dist-pkg/render/viz-axes-labels.d.ts +47 -0
  251. package/dist-pkg/render/viz-axes-labels.js +88 -0
  252. package/dist-pkg/render/viz-axes.d.ts +89 -86
  253. package/dist-pkg/render/viz-axes.js +128 -116
  254. package/dist-pkg/render/viz-modes.d.ts +28 -29
  255. package/dist-pkg/render/viz-modes.js +40 -45
  256. package/dist-pkg/render/viz-refusal.d.ts +32 -0
  257. package/dist-pkg/render/viz-refusal.js +57 -0
  258. package/dist-pkg/render/viz-setters.d.ts +104 -66
  259. package/dist-pkg/render/viz-setters.js +182 -191
  260. package/dist-pkg/ui/aac-sets.d.ts +45 -0
  261. package/dist-pkg/ui/aac-sets.js +41 -0
  262. package/dist-pkg/ui/audio-choices.d.ts +68 -0
  263. package/dist-pkg/ui/audio-choices.js +98 -0
  264. package/dist-pkg/ui/audio-rows-that-apply.d.ts +12 -0
  265. package/dist-pkg/ui/audio-rows-that-apply.js +43 -0
  266. package/dist-pkg/ui/camera-control.d.ts +53 -0
  267. package/dist-pkg/ui/camera-control.js +48 -0
  268. package/dist-pkg/ui/changed-mark.d.ts +9 -8
  269. package/dist-pkg/ui/changed-mark.js +22 -53
  270. package/dist-pkg/ui/control-choices.d.ts +37 -0
  271. package/dist-pkg/ui/control-choices.js +84 -0
  272. package/dist-pkg/ui/debug-panel.d.ts +59 -43
  273. package/dist-pkg/ui/debug-panel.js +68 -69
  274. package/dist-pkg/ui/declared-words.d.ts +21 -0
  275. package/dist-pkg/ui/declared-words.js +66 -0
  276. package/dist-pkg/ui/dom.d.ts +10 -14
  277. package/dist-pkg/ui/dom.js +10 -47
  278. package/dist-pkg/ui/drawing-problems.d.ts +25 -0
  279. package/dist-pkg/ui/drawing-problems.js +94 -0
  280. package/dist-pkg/ui/eye-control.d.ts +36 -0
  281. package/dist-pkg/ui/eye-control.js +178 -0
  282. package/dist-pkg/ui/face-control.d.ts +25 -0
  283. package/dist-pkg/ui/face-control.js +183 -0
  284. package/dist-pkg/ui/focus-trap.d.ts +39 -49
  285. package/dist-pkg/ui/focus-trap.js +56 -65
  286. package/dist-pkg/ui/fonts.d.ts +157 -68
  287. package/dist-pkg/ui/fonts.js +305 -115
  288. package/dist-pkg/ui/footer-scroll-driver.d.ts +14 -0
  289. package/dist-pkg/ui/footer-scroll-driver.js +201 -0
  290. package/dist-pkg/ui/footer-scroll.d.ts +38 -0
  291. package/dist-pkg/ui/footer-scroll.js +55 -0
  292. package/dist-pkg/ui/game-options.d.ts +47 -0
  293. package/dist-pkg/ui/game-options.js +158 -0
  294. package/dist-pkg/ui/gaze-overlay.d.ts +64 -0
  295. package/dist-pkg/ui/gaze-overlay.js +165 -0
  296. package/dist-pkg/ui/hand-control.d.ts +25 -0
  297. package/dist-pkg/ui/hand-control.js +143 -0
  298. package/dist-pkg/ui/help-panel.d.ts +87 -0
  299. package/dist-pkg/ui/help-panel.js +242 -0
  300. package/dist-pkg/ui/hud-bands.d.ts +62 -0
  301. package/dist-pkg/ui/hud-bands.js +146 -0
  302. package/dist-pkg/ui/hud-row.d.ts +34 -0
  303. package/dist-pkg/ui/hud-row.js +80 -0
  304. package/dist-pkg/ui/hud.d.ts +73 -73
  305. package/dist-pkg/ui/hud.js +94 -98
  306. package/dist-pkg/ui/item-announcement.d.ts +13 -12
  307. package/dist-pkg/ui/item-announcement.js +25 -26
  308. package/dist-pkg/ui/layout.d.ts +103 -28
  309. package/dist-pkg/ui/layout.js +117 -99
  310. package/dist-pkg/ui/libras-avatar-clip.d.ts +30 -0
  311. package/dist-pkg/ui/libras-avatar-clip.js +86 -0
  312. package/dist-pkg/ui/libras-avatar-load.d.ts +52 -0
  313. package/dist-pkg/ui/libras-avatar-load.js +134 -0
  314. package/dist-pkg/ui/libras-avatar-plan.d.ts +102 -0
  315. package/dist-pkg/ui/libras-avatar-plan.js +211 -0
  316. package/dist-pkg/ui/libras-avatar-player.d.ts +28 -0
  317. package/dist-pkg/ui/libras-avatar-player.js +226 -0
  318. package/dist-pkg/ui/libras-avatar-stage.d.ts +37 -0
  319. package/dist-pkg/ui/libras-avatar-stage.js +208 -0
  320. package/dist-pkg/ui/libras-glosses.d.ts +28 -0
  321. package/dist-pkg/ui/libras-glosses.js +161 -0
  322. package/dist-pkg/ui/locale-flags.d.ts +16 -0
  323. package/dist-pkg/ui/locale-flags.js +30 -0
  324. package/dist-pkg/ui/loop-crash.d.ts +17 -17
  325. package/dist-pkg/ui/loop-crash.js +33 -62
  326. package/dist-pkg/ui/menu-intent.d.ts +61 -0
  327. package/dist-pkg/ui/menu-intent.js +88 -0
  328. package/dist-pkg/ui/menu-items.d.ts +20 -0
  329. package/dist-pkg/ui/menu-items.js +51 -0
  330. package/dist-pkg/ui/menu-nav.d.ts +98 -92
  331. package/dist-pkg/ui/menu-nav.js +398 -286
  332. package/dist-pkg/ui/mobility-choices.d.ts +26 -0
  333. package/dist-pkg/ui/mobility-choices.js +41 -0
  334. package/dist-pkg/ui/motion-choices.d.ts +31 -0
  335. package/dist-pkg/ui/motion-choices.js +68 -0
  336. package/dist-pkg/ui/motion-scene.d.ts +24 -19
  337. package/dist-pkg/ui/motion-scene.js +29 -61
  338. package/dist-pkg/ui/mount-panel.d.ts +81 -0
  339. package/dist-pkg/ui/mount-panel.js +61 -0
  340. package/dist-pkg/ui/panel-shell.d.ts +65 -31
  341. package/dist-pkg/ui/panel-shell.js +92 -66
  342. package/dist-pkg/ui/panel-widgets.d.ts +150 -0
  343. package/dist-pkg/ui/panel-widgets.js +294 -0
  344. package/dist-pkg/ui/pause-buttons.d.ts +35 -0
  345. package/dist-pkg/ui/pause-buttons.js +66 -0
  346. package/dist-pkg/ui/pause-icons.d.ts +261 -347
  347. package/dist-pkg/ui/pause-icons.js +671 -601
  348. package/dist-pkg/ui/pause-markup.d.ts +86 -0
  349. package/dist-pkg/ui/pause-markup.js +125 -0
  350. package/dist-pkg/ui/reach-notice.d.ts +22 -23
  351. package/dist-pkg/ui/reach-notice.js +55 -58
  352. package/dist-pkg/ui/scan-overlay.d.ts +23 -0
  353. package/dist-pkg/ui/scan-overlay.js +50 -0
  354. package/dist-pkg/ui/screen-text.d.ts +25 -0
  355. package/dist-pkg/ui/screen-text.js +152 -0
  356. package/dist-pkg/ui/session-clock.d.ts +32 -0
  357. package/dist-pkg/ui/session-clock.js +67 -0
  358. package/dist-pkg/ui/settings-aac.d.ts +70 -0
  359. package/dist-pkg/ui/settings-aac.js +208 -0
  360. package/dist-pkg/ui/settings-audio.d.ts +97 -114
  361. package/dist-pkg/ui/settings-audio.js +493 -425
  362. package/dist-pkg/ui/settings-controls.d.ts +53 -96
  363. package/dist-pkg/ui/settings-controls.js +143 -215
  364. package/dist-pkg/ui/settings-empathy.d.ts +39 -30
  365. package/dist-pkg/ui/settings-empathy.js +53 -60
  366. package/dist-pkg/ui/settings-mobility.d.ts +192 -0
  367. package/dist-pkg/ui/settings-mobility.js +332 -0
  368. package/dist-pkg/ui/settings-motion.d.ts +91 -70
  369. package/dist-pkg/ui/settings-motion.js +287 -198
  370. package/dist-pkg/ui/settings-panel.d.ts +58 -45
  371. package/dist-pkg/ui/settings-panel.js +189 -94
  372. package/dist-pkg/ui/settings-typo.d.ts +29 -78
  373. package/dist-pkg/ui/settings-typo.js +158 -129
  374. package/dist-pkg/ui/settings-visual.d.ts +29 -87
  375. package/dist-pkg/ui/settings-visual.js +240 -193
  376. package/dist-pkg/ui/shell.d.ts +112 -135
  377. package/dist-pkg/ui/shell.js +148 -217
  378. package/dist-pkg/ui/simulation-list.d.ts +27 -0
  379. package/dist-pkg/ui/simulation-list.js +76 -0
  380. package/dist-pkg/ui/simulation-over-the-world.d.ts +23 -0
  381. package/dist-pkg/ui/simulation-over-the-world.js +131 -0
  382. package/dist-pkg/ui/simulation-refusal.d.ts +5 -31
  383. package/dist-pkg/ui/simulation-refusal.js +8 -56
  384. package/dist-pkg/ui/switchable-control.d.ts +11 -0
  385. package/dist-pkg/ui/switchable-control.js +19 -0
  386. package/dist-pkg/ui/title.d.ts +3 -12
  387. package/dist-pkg/ui/title.js +49 -18
  388. package/dist-pkg/ui/top-band.d.ts +26 -0
  389. package/dist-pkg/ui/top-band.js +96 -0
  390. package/dist-pkg/ui/typo-choices.d.ts +71 -0
  391. package/dist-pkg/ui/typo-choices.js +85 -0
  392. package/dist-pkg/ui/visual-axes-panel.d.ts +11 -47
  393. package/dist-pkg/ui/visual-axes-panel.js +12 -94
  394. package/dist-pkg/ui/visual-choices.d.ts +77 -0
  395. package/dist-pkg/ui/visual-choices.js +107 -0
  396. package/dist-pkg/ui/vlibras.d.ts +77 -10
  397. package/dist-pkg/ui/vlibras.js +130 -81
  398. package/dist-pkg/ui/voice-control.d.ts +68 -0
  399. package/dist-pkg/ui/voice-control.js +276 -0
  400. package/dist-pkg/ui/voice-settings.d.ts +95 -0
  401. package/dist-pkg/ui/voice-settings.js +352 -0
  402. package/dist-pkg/ui/where-the-child-is.d.ts +31 -0
  403. package/dist-pkg/ui/where-the-child-is.js +70 -0
  404. package/docs/CREDITS.md +300 -44
  405. package/docs/LICENSES.md +189 -145
  406. package/package.json +51 -27
  407. package/scripts/check-cartridge.mjs +78 -0
  408. package/scripts/game-build.d.mts +25 -0
  409. package/scripts/game-build.mjs +144 -0
  410. package/scripts/heavy-into-the-delivery.mjs +388 -0
  411. package/scripts/libras-avatar.json +680 -0
  412. package/scripts/libras-avatar.mjs +246 -0
  413. package/scripts/libras-glosses/gloss.py +95 -0
  414. package/scripts/libras-glosses/pyproject.toml +32 -0
  415. package/scripts/libras-glosses/uv.lock +781 -0
  416. package/scripts/libras-glosses.mjs +351 -0
  417. package/scripts/licences/Apache-2.0.txt +176 -0
  418. package/scripts/licences/GPL-3.0.txt +674 -0
  419. package/scripts/licences/MIT.txt +17 -0
  420. package/scripts/licences/OFL-1.1.txt +86 -0
  421. package/scripts/licences/UFL-1.0.txt +96 -0
  422. package/scripts/licences/fonts.mjs +389 -0
  423. package/scripts/licences/third-party.mjs +301 -0
  424. package/scripts/licences/vosk-browser.NOTICE.txt +268 -0
  425. package/app/public/vendor/fonts/comicneue-400.woff2 +0 -0
  426. package/app/public/vendor/fonts/comicneue-700.woff2 +0 -0
  427. package/app/public/vendor/fonts/fondamento-400-ext.woff2 +0 -0
  428. package/app/public/vendor/fonts/fondamento-400.woff2 +0 -0
  429. package/app/public/vendor/fonts/inter-400.woff2 +0 -0
  430. package/app/public/vendor/fonts/inter-700.woff2 +0 -0
  431. package/app/public/vendor/fonts/lato-400.woff2 +0 -0
  432. package/app/public/vendor/fonts/lato-700.woff2 +0 -0
  433. package/app/public/vendor/fonts/literata-400.woff2 +0 -0
  434. package/app/public/vendor/fonts/literata-700.woff2 +0 -0
  435. package/app/public/vendor/fonts/newsreader-400.woff2 +0 -0
  436. package/app/public/vendor/fonts/newsreader-700.woff2 +0 -0
  437. package/app/public/vendor/fonts/opendyslexic-400.woff2 +0 -0
  438. package/app/public/vendor/fonts/opensans-400.woff2 +0 -0
  439. package/app/public/vendor/fonts/opensans-700.woff2 +0 -0
  440. package/app/public/vendor/fonts/pinyon-400.woff2 +0 -0
  441. package/app/public/vendor/fonts/pressstart-400.woff2 +0 -0
  442. package/app/public/vendor/fonts/quattro-400.woff2 +0 -0
  443. package/app/public/vendor/fonts/quattro-700.woff2 +0 -0
  444. package/app/public/vendor/fonts/sourcesans-400.woff2 +0 -0
  445. package/app/public/vendor/fonts/sourcesans-700.woff2 +0 -0
  446. package/app/public/vendor/fonts/sourceserif-400.woff2 +0 -0
  447. package/app/public/vendor/fonts/sourceserif-700.woff2 +0 -0
  448. package/app/public/vendor/fonts/ufmag-400.woff2 +0 -0
  449. package/dist-pkg/core/anel.d.ts +0 -17
  450. package/dist-pkg/core/anel.js +0 -31
  451. package/dist-pkg/core/collision.d.ts +0 -21
  452. package/dist-pkg/core/collision.js +0 -62
  453. package/dist-pkg/core/layers.d.ts +0 -63
  454. package/dist-pkg/core/layers.js +0 -95
  455. package/dist-pkg/core/letter-grid.d.ts +0 -55
  456. package/dist-pkg/core/letter-grid.js +0 -116
  457. package/dist-pkg/core/password.d.ts +0 -34
  458. package/dist-pkg/core/password.js +0 -205
  459. package/dist-pkg/core/rotulo-acessivel.d.ts +0 -17
  460. package/dist-pkg/core/rotulo-acessivel.js +0 -41
  461. package/dist-pkg/core/run-state.d.ts +0 -115
  462. package/dist-pkg/core/run-state.js +0 -40
  463. package/dist-pkg/core/tiles.d.ts +0 -12
  464. package/dist-pkg/core/tiles.js +0 -61
  465. package/dist-pkg/core/world.d.ts +0 -4
  466. package/dist-pkg/core/world.js +0 -58
  467. package/dist-pkg/input/origem-sintetica.d.ts +0 -44
  468. package/dist-pkg/input/origem-sintetica.js +0 -60
  469. package/dist-pkg/input/transporte-em-uso.d.ts +0 -101
  470. package/dist-pkg/input/transporte-em-uso.js +0 -130
  471. package/dist-pkg/platform/audio-nav.d.ts +0 -51
  472. package/dist-pkg/platform/audio-nav.js +0 -99
  473. package/dist-pkg/platform/guide-intensity.d.ts +0 -40
  474. package/dist-pkg/platform/guide-intensity.js +0 -73
  475. package/dist-pkg/platform/pesados-catalogo.d.ts +0 -14
  476. package/dist-pkg/platform/pesados-catalogo.js +0 -177
  477. package/dist-pkg/platform/pesados.d.ts +0 -31
  478. package/dist-pkg/platform/pesados.js +0 -75
  479. package/dist-pkg/platform/vozes-prontas.d.ts +0 -28
  480. package/dist-pkg/platform/vozes-prontas.js +0 -61
  481. package/dist-pkg/render/camera.d.ts +0 -58
  482. package/dist-pkg/render/camera.js +0 -105
  483. package/dist-pkg/render/cenario-data.d.ts +0 -127
  484. package/dist-pkg/render/cenario-data.js +0 -145
  485. package/dist-pkg/render/city-tex.d.ts +0 -63
  486. package/dist-pkg/render/city-tex.js +0 -228
  487. package/dist-pkg/render/city-tiles.d.ts +0 -11
  488. package/dist-pkg/render/city-tiles.js +0 -140
  489. package/dist-pkg/render/draw.d.ts +0 -149
  490. package/dist-pkg/render/draw.js +0 -231
  491. package/dist-pkg/render/fx.d.ts +0 -63
  492. package/dist-pkg/render/fx.js +0 -123
  493. package/dist-pkg/render/minimap.d.ts +0 -11
  494. package/dist-pkg/render/minimap.js +0 -94
  495. package/dist-pkg/render/parallax.d.ts +0 -85
  496. package/dist-pkg/render/parallax.js +0 -158
  497. package/dist-pkg/render/player-anim.d.ts +0 -71
  498. package/dist-pkg/render/player-anim.js +0 -152
  499. package/dist-pkg/render/recycling-tex.d.ts +0 -48
  500. package/dist-pkg/render/recycling-tex.js +0 -164
  501. package/dist-pkg/render/scene-city.d.ts +0 -77
  502. package/dist-pkg/render/scene-city.js +0 -181
  503. package/dist-pkg/render/scene-parallax.d.ts +0 -72
  504. package/dist-pkg/render/scene-parallax.js +0 -426
  505. package/dist-pkg/render/scene-sky.d.ts +0 -126
  506. package/dist-pkg/render/scene-sky.js +0 -295
  507. package/dist-pkg/render/set-cenario.d.ts +0 -54
  508. package/dist-pkg/render/set-cenario.js +0 -103
  509. package/dist-pkg/render/textures.d.ts +0 -75
  510. package/dist-pkg/render/textures.js +0 -240
  511. package/dist-pkg/render/title-scene.d.ts +0 -46
  512. package/dist-pkg/render/title-scene.js +0 -75
  513. package/dist-pkg/render/weather.d.ts +0 -96
  514. package/dist-pkg/render/weather.js +0 -171
  515. package/dist-pkg/render/wheelchair-sprites.d.ts +0 -32
  516. package/dist-pkg/render/wheelchair-sprites.js +0 -69
  517. package/dist-pkg/render/world-tex.d.ts +0 -18
  518. package/dist-pkg/render/world-tex.js +0 -87
  519. package/dist-pkg/ui/activities-menu.d.ts +0 -258
  520. package/dist-pkg/ui/activities-menu.js +0 -648
  521. package/dist-pkg/ui/caa-sets.d.ts +0 -39
  522. package/dist-pkg/ui/caa-sets.js +0 -65
  523. package/dist-pkg/ui/latch-refusal.d.ts +0 -32
  524. package/dist-pkg/ui/latch-refusal.js +0 -60
  525. package/dist-pkg/ui/map-hub.d.ts +0 -56
  526. package/dist-pkg/ui/map-hub.js +0 -138
  527. package/dist-pkg/ui/settings-caa.d.ts +0 -45
  528. package/dist-pkg/ui/settings-caa.js +0 -137
  529. package/dist-pkg/ui/settings-motor.d.ts +0 -175
  530. package/dist-pkg/ui/settings-motor.js +0 -342
  531. package/dist-pkg/ui/webcam.d.ts +0 -7
  532. package/dist-pkg/ui/webcam.js +0 -93
@@ -0,0 +1,61 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ import type { NavKeys } from '../input/edges.js';
3
+ import type { Action } from '../core/actions.js';
4
+ /**
5
+ * The position a menu reads as «yes»: confirming the item under the cursor. Named once because a second reader presses it —
6
+ * the voice, which puts the cursor on an item said by name and confirms it the way every transport does (ADR-0194 §2).
7
+ */
8
+ export declare const MENU_CONFIRM: Action;
9
+ /** Confirm/enter. `NumpadEnter` counts here (but does NOT pause — see `input/keydown`). */
10
+ export declare const KEY_YES: ReadonlySet<string>;
11
+ /** Back. ⚠️ DEFECT 2: `Escape` is the SAME intent as the gamepad's "special" action. */
12
+ export declare const KEY_NO: ReadonlySet<string>;
13
+ export declare const KEY_UP: ReadonlySet<string>;
14
+ export declare const KEY_DOWN: ReadonlySet<string>;
15
+ export declare const KEY_LEFT: ReadonlySet<string>;
16
+ export declare const KEY_RIGHT: ReadonlySet<string>;
17
+ /**
18
+ * Translates (physical key, the key owner's remapped action) → intent. `act` is `null` when the key belongs to no
19
+ * player (a generic key).
20
+ */
21
+ export declare function menuKeyIntent(code: string, act: string | null): NavKeys;
22
+ /** A step of a menu one-button scanning offers — what a menu does, not a key (ADR-0218 erratum of 2026-09-26). */
23
+ export type MenuStep = 'next' | 'previous' | 'confirm' | 'back' | 'increase' | 'decrease';
24
+ /**
25
+ * WHAT ONE-BUTTON SCANNING OFFERS INSIDE A MENU, in order after «cancel» (interface log 2026-09-26). By how often a child needs
26
+ * each: every menu here is a ring, so «next» alone reaches every item, and it comes first; «confirm» ends every choice; «back»
27
+ * leaves — the quick pause, a sub-list, a panel, the card —; «previous» is a shortcut the ring already covers, so it waits last.
28
+ */
29
+ export declare const MENU_SCAN: readonly MenuStep[];
30
+ /**
31
+ * WHAT THE CONTROL UNDER A MENU'S CURSOR LETS A SIDEWAYS STEP DO — the question `ui/menu-nav` answers with the rule its left
32
+ * and right keys follow: `item` has no value (a button, a switch, the quick bar, the pause card); `list` is a `<select>`, whose
33
+ * value left and right step and whose «confirm» goes round; `value` is a slider or a ⯇ ⯈ steps control, which left and right
34
+ * adjust and «confirm» leaves untouched.
35
+ */
36
+ export type MenuCursor = 'item' | 'list' | 'value';
37
+ /**
38
+ * THE PASS IN A MENU, for the control under its cursor (ADR-0218 erratum; interface log 2026-09-26, the sideways step). Only a
39
+ * control with a value offers «increase» and «decrease» — they come right after «next», which keeps its place as the first
40
+ * step of every menu — and a slider or a steps control does not offer «confirm», which does nothing there: a cycle never
41
+ * stops on a position that does nothing (ADR-0155).
42
+ */
43
+ export declare function menuScanFor(cursor: MenuCursor): readonly MenuStep[];
44
+ export declare function menuStepKeys(step: MenuStep): NavKeys;
45
+ /** `select` with left/right: one step, WITHOUT wrapping — adjusting a VALUE is not navigating a list. */
46
+ export declare function selectStep(selectedIndex: number, optionsLen: number, delta: number): number;
47
+ /** `select` with "yes": one step, WITH wrapping. That is the deliberate difference between confirming and adjusting. */
48
+ export declare function selectWrap(selectedIndex: number, optionsLen: number): number;
49
+ /** `input[type=range]` with left/right: one `step` (default 1), clamped between `min` and `max`. */
50
+ export declare function rangeStep(value: number, min: number, max: number, step: number, delta: number): number;
51
+ /**
52
+ * THE CURSOR STEP IN THE PAUSE MENU — a RING, because the pause card is one list (ADR-0044, items 1 and 7).
53
+ *
54
+ * XAG 106 allows wrapping for a LINEAR menu and FORBIDS it for a two-dimensional grid — in a grid, wrapping
55
+ * teleports the cursor to the other corner and the person loses track of where they are. With the icon bar in the
56
+ * HUD, the card is a single list, so wrapping is the recommended behaviour rather than a forbidden one — and there
57
+ * are no zone-crossing rules for a child to discover without seeing.
58
+ *
59
+ * What it buys: `quit` is ONE key UP from `resume`. Last to be read, next to the finger.
60
+ */
61
+ export declare function stepInPause(len: number, idx: number, k: NavKeys): number;
@@ -0,0 +1,88 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ import { stepInRing } from '../core/ring.js';
3
+ /**
4
+ * The position a menu reads as «yes»: confirming the item under the cursor. Named once because a second reader presses it —
5
+ * the voice, which puts the cursor on an item said by name and confirms it the way every transport does (ADR-0194 §2).
6
+ */
7
+ export const MENU_CONFIRM = 'action2';
8
+ /* The GENERIC key tables (the ones that hold for any player, even with no remap). They are `Set`s because that is
9
+ what they are — membership, not order — and because a named `Set` keeps the table auditable from outside (the
10
+ test imports the constant instead of repeating the literals). */
11
+ /** Confirm/enter. `NumpadEnter` counts here (but does NOT pause — see `input/keydown`). */
12
+ export const KEY_YES = new Set(['Space', 'KeyJ', 'Enter', 'NumpadEnter']);
13
+ /** Back. ⚠️ DEFECT 2: `Escape` is the SAME intent as the gamepad's "special" action. */
14
+ export const KEY_NO = new Set(['Escape']);
15
+ export const KEY_UP = new Set(['ArrowUp', 'KeyW']);
16
+ export const KEY_DOWN = new Set(['ArrowDown', 'KeyS']);
17
+ export const KEY_LEFT = new Set(['ArrowLeft', 'KeyA']);
18
+ export const KEY_RIGHT = new Set(['ArrowRight', 'KeyD']);
19
+ /**
20
+ * Translates (physical key, the key owner's remapped action) → intent. `act` is `null` when the key belongs to no
21
+ * player (a generic key).
22
+ */
23
+ export function menuKeyIntent(code, act) {
24
+ return {
25
+ yes: KEY_YES.has(code) || act === MENU_CONFIRM,
26
+ no: KEY_NO.has(code) || act === 'action3',
27
+ up: KEY_UP.has(code) || act === 'up',
28
+ down: KEY_DOWN.has(code) || act === 'down',
29
+ left: KEY_LEFT.has(code) || act === 'left',
30
+ right: KEY_RIGHT.has(code) || act === 'right',
31
+ };
32
+ }
33
+ /**
34
+ * WHAT ONE-BUTTON SCANNING OFFERS INSIDE A MENU, in order after «cancel» (interface log 2026-09-26). By how often a child needs
35
+ * each: every menu here is a ring, so «next» alone reaches every item, and it comes first; «confirm» ends every choice; «back»
36
+ * leaves — the quick pause, a sub-list, a panel, the card —; «previous» is a shortcut the ring already covers, so it waits last.
37
+ */
38
+ export const MENU_SCAN = ['next', 'confirm', 'back', 'previous'];
39
+ /**
40
+ * THE PASS IN A MENU, for the control under its cursor (ADR-0218 erratum; interface log 2026-09-26, the sideways step). Only a
41
+ * control with a value offers «increase» and «decrease» — they come right after «next», which keeps its place as the first
42
+ * step of every menu — and a slider or a steps control does not offer «confirm», which does nothing there: a cycle never
43
+ * stops on a position that does nothing (ADR-0155).
44
+ */
45
+ export function menuScanFor(cursor) {
46
+ if (cursor === 'item')
47
+ return MENU_SCAN;
48
+ const sideways = ['next', 'increase', 'decrease'];
49
+ return cursor === 'list' ? [...sideways, 'confirm', 'back', 'previous'] : [...sideways, 'back', 'previous'];
50
+ }
51
+ /**
52
+ * The intent a step is — the one a key with that meaning would carry, so it moves a menu the way the key does. «increase» is the
53
+ * right key and «decrease» the left one: the same step a keyboard adjusts a value with.
54
+ */
55
+ const STEP_INTENT = {
56
+ next: { down: true }, previous: { up: true }, confirm: { yes: true }, back: { no: true },
57
+ increase: { right: true }, decrease: { left: true },
58
+ };
59
+ export function menuStepKeys(step) {
60
+ return { ...STEP_INTENT[step] };
61
+ }
62
+ /** `select` with left/right: one step, WITHOUT wrapping — adjusting a VALUE is not navigating a list. */
63
+ export function selectStep(selectedIndex, optionsLen, delta) {
64
+ return Math.max(0, Math.min(optionsLen - 1, selectedIndex + delta));
65
+ }
66
+ /** `select` with "yes": one step, WITH wrapping. That is the deliberate difference between confirming and adjusting. */
67
+ export function selectWrap(selectedIndex, optionsLen) {
68
+ return (selectedIndex + 1) % optionsLen;
69
+ }
70
+ /** `input[type=range]` with left/right: one `step` (default 1), clamped between `min` and `max`. */
71
+ export function rangeStep(value, min, max, step, delta) {
72
+ const st = step || 1; // a missing/0/NaN step becomes 1
73
+ return Math.max(min, Math.min(max, value + delta * st));
74
+ }
75
+ /**
76
+ * THE CURSOR STEP IN THE PAUSE MENU — a RING, because the pause card is one list (ADR-0044, items 1 and 7).
77
+ *
78
+ * XAG 106 allows wrapping for a LINEAR menu and FORBIDS it for a two-dimensional grid — in a grid, wrapping
79
+ * teleports the cursor to the other corner and the person loses track of where they are. With the icon bar in the
80
+ * HUD, the card is a single list, so wrapping is the recommended behaviour rather than a forbidden one — and there
81
+ * are no zone-crossing rules for a child to discover without seeing.
82
+ *
83
+ * What it buys: `quit` is ONE key UP from `resume`. Last to be read, next to the finger.
84
+ */
85
+ export function stepInPause(len, idx, k) {
86
+ const d = (k.down || k.right) ? 1 : -1;
87
+ return stepInRing(len, idx < 0 ? 0 : idx, d);
88
+ }
@@ -0,0 +1,20 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ /** The controls that are a stop of the cursor. `[data-passos]` is ONE stop: its arrows are finger targets. */
3
+ export declare const ITEM_SELECTOR = "button:not([disabled]), select:not([disabled]), input[type=range]:not([disabled]), [data-passos]";
4
+ /**
5
+ * The stops of a card, in reading order — only the ones laid out.
6
+ *
7
+ * `offsetParent === null` = out of the layout flow (hidden, `display:none`, or inside a hidden tab). Without it the
8
+ * cursor lands on an invisible control and the screen reader announces something nobody sees.
9
+ */
10
+ export declare function navigableItems(card: ParentNode): HTMLElement[];
11
+ /**
12
+ * KEEPS A MENU ITEM WHOLLY IN VIEW inside the box that scrolls it — the card, never the page (the Dev: the page itself
13
+ * does not scroll). A cursor that walks off the visible part of a list is a cursor the child has lost: this is what makes
14
+ * a list longer than the screen usable, whatever moved the cursor (issue #134, the Dev's «os menus não rolam»).
15
+ *
16
+ * The box's `scroll-padding` is honoured, so the band of explanation at the bottom of the screen, which the card runs
17
+ * under, never covers the item. Nothing moves when the item is already in view. A document with no layout (a node
18
+ * double) is left alone.
19
+ */
20
+ export declare function keepInView(item: HTMLElement): void;
@@ -0,0 +1,51 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // ui/menu-items — WHAT COUNTS AS A MENU ITEM: the stops of the cursor, whose position the spoken index says.
3
+ //
4
+ // The list of stops lives HERE, once, and everything that speaks a place or keeps focus by place reads it: a second
5
+ // copy of the selector is how «2 de 7» and the item the cursor is on drift apart. (Until ADR-0167 it also drew a
6
+ // visible number per stop; that left — the place is heard, after the name.)
7
+ //
8
+ // And how a stop is kept in view inside the card that scrolls it (`keepInView`), which every mover of a cursor shares.
9
+ //
10
+ // 📌 A LEAF, importing nothing: `ui/mount-panel` needs the stops and must not pull `ui/menu-nav`, which pulls the
11
+ // whole pause slice.
12
+ /** The controls that are a stop of the cursor. `[data-passos]` is ONE stop: its arrows are finger targets. */
13
+ export const ITEM_SELECTOR = 'button:not([disabled]), select:not([disabled]), input[type=range]:not([disabled]), [data-passos]';
14
+ /**
15
+ * The stops of a card, in reading order — only the ones laid out.
16
+ *
17
+ * `offsetParent === null` = out of the layout flow (hidden, `display:none`, or inside a hidden tab). Without it the
18
+ * cursor lands on an invisible control and the screen reader announces something nobody sees.
19
+ */
20
+ export function navigableItems(card) {
21
+ return [...card.querySelectorAll(ITEM_SELECTOR)].filter((el) => el.offsetParent !== null);
22
+ }
23
+ // 🔴 `numerarItens` AND `ATRIBUTO_DO_NUMERO` LEFT (ADR-0167): no stop shows a number. The list above still gives the
24
+ // spoken index its position — «…, 2 de 7» after the name, from `ui/item-announcement.announceItem`.
25
+ /**
26
+ * KEEPS A MENU ITEM WHOLLY IN VIEW inside the box that scrolls it — the card, never the page (the Dev: the page itself
27
+ * does not scroll). A cursor that walks off the visible part of a list is a cursor the child has lost: this is what makes
28
+ * a list longer than the screen usable, whatever moved the cursor (issue #134, the Dev's «os menus não rolam»).
29
+ *
30
+ * The box's `scroll-padding` is honoured, so the band of explanation at the bottom of the screen, which the card runs
31
+ * under, never covers the item. Nothing moves when the item is already in view. A document with no layout (a node
32
+ * double) is left alone.
33
+ */
34
+ export function keepInView(item) {
35
+ const view = item.ownerDocument?.defaultView;
36
+ if (!view || typeof item.getBoundingClientRect !== 'function')
37
+ return;
38
+ let box = item.parentElement;
39
+ while (box && !(/(auto|scroll)/.test(view.getComputedStyle(box).overflowY) && box.scrollHeight > box.clientHeight))
40
+ box = box.parentElement;
41
+ if (!box || box === item.ownerDocument.documentElement || box === item.ownerDocument.body)
42
+ return;
43
+ const style = view.getComputedStyle(box);
44
+ const top = box.getBoundingClientRect().top + box.clientTop + (parseFloat(style.scrollPaddingTop) || 0);
45
+ const bottom = box.getBoundingClientRect().top + box.clientTop + box.clientHeight - (parseFloat(style.scrollPaddingBottom) || 0);
46
+ const r = item.getBoundingClientRect();
47
+ if (r.top < top)
48
+ box.scrollTop -= top - r.top;
49
+ else if (r.bottom > bottom)
50
+ box.scrollTop += Math.min(r.bottom - bottom, r.top - top); // a tall item shows its top
51
+ }
@@ -1,141 +1,147 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
- /** ui/dom.ts `$` — injetado; o módulo nunca alcança `document`. */
3
- export type { DomQuery } from '../core/dom-query.js';
4
- /** A intenção, não a tecla. Definição única em input/edges; aqui só reexportada. */
2
+ /** The intent, not the key. Defined once in input/edges. */
5
3
  import type { NavKeys } from '../input/edges.js';
6
- export type { NavKeys } from '../input/edges.js';
7
- /** O que este módulo lê de um `KeyboardEvent`. */
4
+ /** What this module reads from a `KeyboardEvent`. */
8
5
  export interface NavKeyEvent {
9
6
  code: string;
10
7
  preventDefault(): void;
11
8
  stopPropagation(): void;
12
9
  }
13
- /** Confirma/entra. `NumpadEnter` conta aqui (mas NÃO pausa: ver o ouvinte de bolha do game.js). */
14
- export declare const KEY_YES: ReadonlySet<string>;
15
- /** Volta. ⚠️ DEFEITO 2: `Escape` é a MESMA intenção que a ação "especial" do gamepad. Verbatim. */
16
- export declare const KEY_NO: ReadonlySet<string>;
17
- export declare const KEY_UP: ReadonlySet<string>;
18
- export declare const KEY_DOWN: ReadonlySet<string>;
19
- export declare const KEY_LEFT: ReadonlySet<string>;
20
- export declare const KEY_RIGHT: ReadonlySet<string>;
21
- /**
22
- * Traduz (tecla física, ação remapeada do dono da tecla) → intenção. `act` é `null` quando a tecla não é de
23
- * nenhum jogador (tecla genérica). Verbatim das seis linhas de `menuNavKey`.
24
- */
25
- export declare function menuKeyIntent(code: string, act: string | null): NavKeys;
26
10
  import type { EventTargetLike } from '../input/touch-bindings.js';
27
11
  import type { DomQuery } from '../core/dom-query.js';
12
+ import type { Translate } from '../core/i18n.js';
13
+ import { type MenuCursor } from './menu-intent.js';
28
14
  export { hasNavIntent as hasIntent } from '../input/edges.js';
29
- export { passoNoAnel } from '../core/anel.js';
30
- /** `select` com esquerda/direita: um passo, SEM dar a volta — ajustar VALOR não é navegar lista (ver acima). */
31
- export declare function selectStep(selectedIndex: number, optionsLen: number, delta: number): number;
32
- /** `select` com "sim": um passo, COM volta. É a diferença deliberada entre confirmar e ajustar. */
33
- export declare function selectWrap(selectedIndex: number, optionsLen: number): number;
34
- /** `input[type=range]` com esquerda/direita: um `step` (default 1), preso entre `min` e `max`. */
35
- export declare function rangeStep(value: number, min: number, max: number, step: number, delta: number): number;
36
- /**
37
- * O PASSO DO CURSOR NO MENU DE PAUSA — um ANEL, agora que a pausa é uma lista (ADR-0044, itens 1 e 7).
38
- *
39
- * ISTO SUBSTITUI `pauseGridMove`, e a substituição é o desfecho do ADR-0044, não uma limpeza. O que havia
40
- * era uma GRADE de duas zonas — a barra de dez ícones em cima, a lista de itens em duas colunas embaixo — e
41
- * uma fronteira entre elas com quatro regras próprias ("de cima, 'baixo' cai sempre no primeiro item", "da
42
- * primeira linha, 'cima' sobe para o ícone de mesmo índice", …). Cada regra dessas era uma coisa a mais para
43
- * a criança descobrir sem ver, e nenhuma delas era descobrível: só se aprendia esbarrando.
44
- *
45
- * A XAG 106 permite laço para menu LINEAR e o PROÍBE para grade de duas dimensões — numa grade, dar a volta
46
- * teleporta o cursor para o outro canto e a pessoa perde a noção de onde está. Era por isso que o anel do
47
- * item 1 valia para todo menu do jogo MENOS este. Com a barra no HUD (item 7), o cartão passou a ter uma
48
- * lista só, e o laço deixou de ser proibido para virar o recomendado.
49
- *
50
- * O que se ganha em troca das quatro regras: `quit` fica a UMA tecla para CIMA de `resume`. Último na
51
- * leitura, vizinho no dedo.
52
- */
53
- export declare function passoNaPausa(len: number, idx: number, k: NavKeys): number;
15
+ export { stepInRing } from '../core/ring.js';
54
16
  export interface MenuNavCtx {
55
- /** ui/dom.ts `$` — só para achar `#padwiz`. */
17
+ /** Translates in the page's language — the root's translator (ADR-0232 D3). REQUIRED: text built from nowhere is a raw key. */
18
+ t: Translate;
19
+ /** ui/dom.ts `$` — only to find `#padwiz`. */
56
20
  $: DomQuery;
57
- /** `document.activeElement` — injetado para o teste node poder simular foco sem DOM. */
21
+ /** `document.activeElement` — injected so a node test can simulate focus without a DOM. */
58
22
  getActiveElement: () => Element | null;
59
- /** O overlay VISÍVEL de z-index mais alto dentro de `#game-region`. É o `sharedDialogOpen` original. */
23
+ /** The VISIBLE overlay with the highest z-index inside `#game-region`. */
60
24
  topVisibleOverlay: () => HTMLElement | null;
61
- /** `overlays.closeById(id)` — true se havia entrada registrada para aquele diálogo. */
25
+ /** `overlays.closeById(id)` — true if that dialog had a registered entry. */
62
26
  closeById: (id: string) => boolean;
63
- /** `vpPause[i]` — o menu de pausa da tela do jogador `i`. `buildGameHud` REATRIBUI a array. */
27
+ /** The pause card of player `i`'s screen, looked up when asked. */
64
28
  getPauseMenu: (playerIndex: number) => HTMLElement | null | undefined;
65
- /** ui/shell.ts via o envelope içado do game.js. `no` na raiz do menu de pausa volta ao jogo. */
29
+ /** Changes the game phase. `no` at the pause card's root goes back to the game. */
66
30
  setPhase: (p: 'title' | 'playing' | 'paused') => void;
67
- /** `let pauseActor` do game.js: "sim" no menu de pausa marca QUEM agiu (o submenu abre na aba dele).
68
- * ui/pause-icons.ts já recebe o mesmo setter — o `let` continua sendo do game.js, com seis leitores. */
31
+ /** «Yes» on the pause card marks WHO acted (the options open on that player's tab). `ui/pause-icons` receives the
32
+ * same setter. */
69
33
  setPauseActor: (playerIndex: number) => void;
70
34
  /**
71
- * ESTE É O MOMENTO DE NAVEGAR MENU? Se `false`, toda tecla passa direto.
72
- *
73
- * Era `if (phase !== 'paused') return`, com `phase` vindo por IMPORTAÇÃO de `core/state` — e o segundo
74
- * consumidor mostrou o preço (achado 10 de `consumer-quiz`): um quiz cujos ajustes estão SEMPRE disponíveis
75
- * precisava se declarar "pausado" para poder navegar os próprios menus. Não havia como trazer o próprio
76
- * modelo de fases, porque não havia por onde.
35
+ * IS THIS A MOMENT TO NAVIGATE A MENU? If `false`, every key passes through.
77
36
  *
78
- * A pergunta injetada é PROPOSITALMENTE um booleano, e não a fase. Injetar `getPhase()` teria consertado a
79
- * importação e mantido a mentira: o consumidor continuaria obrigado a devolver a string `'paused'`, que é
80
- * um conceito do jogo de plataforma. Perguntando "dá para navegar agora?", o jogo de plataforma responde
81
- * `phase === 'paused'` e um quiz responde `true` — cada um na sua língua, e nenhum dos dois mentindo.
37
+ * A boolean on purpose, not the phase: asking for the phase would oblige every game to answer with the string
38
+ * `'paused'`, a platformer's concept. Asked «can a menu be navigated now?», a platformer answers `phase === 'paused'`
39
+ * and a quiz whose settings are always open answers `true` — each in its own terms, neither pretending.
82
40
  */
83
41
  isNavigable: () => boolean;
84
42
  /**
85
- * `core/a11y-sr.srSay` — a região `aria-live` "polite". INJETADO porque ela alcança o `document` na hora da
86
- * chamada, e este módulo não pode alcançar documento nenhum por conta própria.
43
+ * `core/a11y-sr.srSay` — the «polite» `aria-live` region. INJECTED because it reaches the `document` when called, and
44
+ * this module reaches no document on its own.
87
45
  *
88
- * O menu de PAUSA precisa dela e os diálogos não: eles selecionam por FOCO, e o leitor de tela anuncia o
89
- * foco sozinho. A pausa seleciona por CLASSE (`.pm-sel`), porque é desenhada dentro da tela do jogador —
90
- * e classe nenhuma dispara anúncio. Sem esta injeção o menu é mudo para quem o navega por escuta.
46
+ * The PAUSE card needs it and the dialogs do not: dialogs select by FOCUS, which a screen reader announces by itself.
47
+ * The pause card selects by CLASS (`.pm-sel`), because it is drawn inside the player's screen — and no class fires an
48
+ * announcement. Without this the card is silent to whoever navigates it by ear.
91
49
  */
92
- srSay: (texto: string) => void;
50
+ srSay: (text: string) => void;
93
51
  /**
94
- * O índice "N de M" está ligado? (ADR-0044, item 3, e a XAG 106 exige que ele possa ser desligado.)
52
+ * Is the «N of M» index on? (ADR-0044 item 3; XAG 106 requires that it can be turned off.)
95
53
  *
96
- * PERGUNTADO ao ctx e não lido de `core/state`, e o motivo é o mesmo do `isNavigable`: enquanto este módulo
97
- * importava `core/state`, um segundo jogo não tinha como trazer o próprio modelo — o quiz teve de se
98
- * declarar "pausado" para navegar os menus dele. `tests/menu-nav.node.test.js` reprova se a aresta voltar,
99
- * e ela quase voltou por aqui: eu tinha escrito o `import` antes de o gate me lembrar.
54
+ * ASKED of the ctx rather than read from `core/state`, for the same reason as `isNavigable`: a game answers in its own
55
+ * model. `tests/menu-nav.node.test.js` fails if the import of `core/state` comes back.
100
56
  */
101
- comIndice: () => boolean;
57
+ withIndex: () => boolean;
58
+ /** Writes the reason of a locked pause item in the screen footer, or clears it with `null` (ADR-0161). Optional. */
59
+ explainItem?: (text: string | null) => void;
102
60
  /**
103
- * A tela `i` está no modo `accessibility` (ADR-0044, item 7)? Perguntado ANTES de `isNavigable`, porque
104
- * esse modo roda com o jogo ANDANDO — é a única coisa deste módulo que age fora da pausa.
61
+ * Is screen `i` on the quick bar (ADR-0044 item 7)? Asked BEFORE `isNavigable`, because the bar works with the game
62
+ * RUNNING — the only thing in this module that acts outside the pause.
105
63
  */
106
- naBarraDe: (i: number) => boolean;
107
- /** Um passo dentro da barra rápida da tela `i`. */
64
+ onBar: (i: number) => boolean;
65
+ /** One step inside screen `i`'s quick bar. */
108
66
  navBar: (i: number, k: NavKeys) => void;
109
- /** ui/settings-controls.ts: um remap em andamento consome a tecla — o menu não pode roubá-la. */
67
+ /** ui/settings-controls.ts: a remap in progress consumes the key — the menu must not steal it. */
110
68
  isCapturing: () => boolean;
111
- /** input/gamepad.ts: o assistente de mapeamento fica POR CIMA de tudo; só Escape (cancela) o alcança. */
69
+ /** Closes the controller-mapping panel (`#padwiz`), which sits ON TOP of everything; only Escape (cancel) reaches it. */
112
70
  closePadWiz: (save: boolean) => void;
113
- /** input/keyboard-runtime.ts: de quem é esta tecla? (-1 = genérica). */
71
+ /** input/keyboard-runtime.ts: whose key is this? (-1 = generic). */
114
72
  whichPlayer: (code: string) => number;
115
- /** input/keyboard-runtime.ts: que ação esta tecla é PARA aquele jogador (respeitando o remap)? */
73
+ /**
74
+ * Does player `i` steer this screen's menus — the dialog on top and the pause card? On a screen several players share, only
75
+ * the first does (ADR-0144, erratum of 2026-09-26): another player's direction, confirm and back move, press and close nothing.
76
+ * Absent: every player does — each has a screen of her own. The quick bar is asked per player already (`onBar`).
77
+ */
78
+ leadsTheScreen?: (i: number) => boolean;
79
+ /** input/keyboard-runtime.ts: which action is this key FOR that player (honouring the remap)? */
116
80
  actionOf: (code: string, playerIndex: number) => string | null;
117
- /** `window` — só para `attach()` instalar o ouvinte em CAPTURA, exatamente como o game.js fazia. */
118
- /** A escuta de teclado dos menus. Ver `EventTargetLike` em input/touch-bindings. */
81
+ /** Where `attach()` installs the menus' listeners, in CAPTURE. See `EventTargetLike` in input/touch-bindings. */
119
82
  win: EventTargetLike;
120
83
  }
121
84
  export interface MenuNavApi {
122
- /** O overlay visível mais alto (alias de `topVisibleOverlay` — ver "a duplicação que esta extração curou"). */
85
+ /** The highest visible overlay (an alias of `topVisibleOverlay` — see the header). */
123
86
  sharedDialogOpen: () => HTMLElement | null;
124
- /** Os controles NAVEGÁVEIS de um menu: habilitados E visíveis (`offsetParent !== null`). */
87
+ /** A menu's NAVIGABLE controls: enabled AND visible (`offsetParent !== null`). */
125
88
  menuItems: (menu: HTMLElement) => HTMLElement[];
126
- /** Foca o item atual (se já for um deles) ou o primeiro. Sai calado com `menu` nulo — ver o DEFEITO 1. */
89
+ /** Focuses the current item (if the focus is already on one) or the first. Leaves quietly with a null `menu` — see DEFECT 1. */
127
90
  menuFocus: (menu: HTMLElement | null) => void;
128
- /** Fecha o diálogo e tenta devolver o foco ao que ficou por baixo. */
91
+ /** Closes the dialog and tries to give the focus back to what is left underneath. */
129
92
  dialogBack: (menu: HTMLElement) => void;
130
- /** Um passo de navegação DENTRO de um diálogo de configuração. */
93
+ /** One navigation step INSIDE a settings dialog. */
131
94
  navDialog: (menu: HTMLElement, k: NavKeys) => void;
132
- /** Marca `el` como o item selecionado de `menu` e atualiza a legenda dos ícones. */
95
+ /** Marks `el` as `menu`'s selected item. */
133
96
  pauseSetSel: (menu: HTMLElement, el: HTMLElement | null | undefined) => void;
134
- /** Um passo de navegação DENTRO de um menu de pausa (barra de ícones + grade de itens). */
97
+ /** One navigation step INSIDE a pause card (its items; the quick bar is not in the card). */
135
98
  navPause: (menu: HTMLElement, playerIndex: number, k: NavKeys) => void;
136
- /** O tradutor de teclado. Exportado à parte para o teste disparar sem depender da fase de propagação. */
99
+ /** The keyboard translator. Exported on its own so a test can fire it without depending on the propagation phase. */
137
100
  menuNavKey: (e: NavKeyEvent) => void;
138
- /** Instala `menuNavKey` em CAPTURA na janela — verbatim do game.js. */
101
+ /**
102
+ * Did the menus CONSUME this key event? `stopPropagation()` keeps it from the nodes further on, not from the listeners after
103
+ * `menuNavKey` on the same window capture — and the keyboard conductor is one. It asks here, so a key that moved, confirmed
104
+ * or CLOSED a menu is never also played in the same event (ADR-0111 erratum of 2026-09-26): with the menu already closed,
105
+ * «is a menu open?» answers no, and resume was answering a question too.
106
+ */
107
+ consumed: (e: object) => boolean;
108
+ /**
109
+ * ONE STEP OF A MENU WITH NO KEY: the intents move the menu a key of player `playerIndex` would move now — the quick bar,
110
+ * the dialog on top or that player's open pause card — through the same path and guards as `menuNavKey`. Answers whether a
111
+ * menu took it. One-button scanning is the caller (ADR-0218 erratum of 2026-09-26): its press is not a menu key.
112
+ */
113
+ navIntent: (playerIndex: number, keys: NavKeys) => boolean;
114
+ /**
115
+ * WHAT A SIDEWAYS STEP OF PLAYER `playerIndex` WOULD DO NOW (ADR-0218 erratum; one-button scanning offers «increase» and
116
+ * «decrease» only where they act): the kind of the control under the cursor of the panel on top — the focused item, or the
117
+ * first, where a step enters — under the guards a name said by voice has; `item` wherever a step would adjust nothing: the
118
+ * quick bar, a pause card, no menu, a remap, the controller-mapping panel.
119
+ */
120
+ underCursor: (playerIndex: number) => MenuCursor;
121
+ /**
122
+ * THE NAMES A CHILD CAN SAY (ADR-0194 §1): the accessible names of the items a key of player `playerIndex` would move now —
123
+ * the dialog on top, else that player's open pause card — and none while a key would move no menu. LOCKED items are in it
124
+ * (ADR-0194 §5): saying one confirms it like any transport, and a locked item confirmed says its reason and does nothing.
125
+ */
126
+ itemNames: (playerIndex: number) => string[];
127
+ /**
128
+ * PUTS THE CURSOR on the item with this accessible name, without activating it and without announcing it — the menu the
129
+ * name belongs to is the one `itemNames` reads. The caller then confirms through the virtual controller like any
130
+ * transport (ADR-0194 §2). `false` when no such item is there now: nothing moved.
131
+ */
132
+ pointAt: (name: string, playerIndex: number) => boolean;
133
+ /** Installs `menuNavKey` on the window, in CAPTURE. */
139
134
  attach: () => void;
140
135
  }
136
+ /**
137
+ * The parts a panel control SAYS (ADR-0159 rule 1, XAG 106: «Gamma, slider, 38%, 6 of 9»): the label with the ROLE, and
138
+ * the VALUE. The index is added by `announceItem`.
139
+ *
140
+ * The label is the row's `<strong>` when the control lives in one (it is what is SEEN, and a switch's text is its state,
141
+ * not its name); outside a row, or on a slider with a name of its own («Volume de Música»), it is the accessible name.
142
+ */
143
+ export declare function controlParts(t: Translate, el: HTMLElement): {
144
+ label: string;
145
+ state: string;
146
+ };
141
147
  export declare function initMenuNav(ctx: MenuNavCtx): MenuNavApi;