@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,62 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ import type { Translator } from '../core/i18n.js';
3
+ export type HudBand = 'identity' | 'mission' | 'power' | 'learning';
4
+ /**
5
+ * A skill's bar, as `educational/segment-bar.barOf` returns it — the same field names and values, so its `Bar` passes
6
+ * straight in. Written again here because `ui` does not import `educational` (ADR-0173).
7
+ */
8
+ export interface HudBar {
9
+ readonly segmentos: readonly ('azul' | 'verde' | 'vermelho')[];
10
+ readonly cor: 'nenhuma' | 'laranja' | 'roxa';
11
+ }
12
+ export type HudNumber = {
13
+ readonly band: 'identity' | 'mission' | 'power';
14
+ /** The key of what is counted («points», «balls») in the game's dictionary. */
15
+ readonly nameKey: string;
16
+ /** A count, or how many of how many, for seat `seat`. Read on every animation frame while mounted: keep it cheap. */
17
+ readonly value: (seat: number) => number | {
18
+ readonly have: number;
19
+ readonly need: number;
20
+ };
21
+ } | {
22
+ readonly band: 'learning';
23
+ /** The key of the skill's name in the game's dictionary. */
24
+ readonly nameKey: string;
25
+ readonly value: (seat: number) => HudBar;
26
+ };
27
+ /** What the HUD asks of the root's translator: the engine's frames, and the game's declared words. */
28
+ type HudTranslator = Pick<Translator, 't' | 'word'>;
29
+ /** Why a `hud` declaration is malformed; empty when it is well formed. Absent is well formed: no HUD is mounted. */
30
+ export declare function hudNumbersProblems(numbers: unknown): string[];
31
+ /** The HUD row's cells the bands go into (`ui/hud-row`, ADR-0239). */
32
+ export interface HudRowSlots {
33
+ readonly learning: HTMLElement;
34
+ readonly score: HTMLElement;
35
+ }
36
+ export interface HudBandsMounted {
37
+ /** The mission, at the top centre under the quick bar (the name is from when it sat top left). */
38
+ readonly left: HTMLElement;
39
+ /** The power in use, above the score. */
40
+ readonly right: HTMLElement;
41
+ /** The identity numbers — the score — in five digits (ADR-0238). */
42
+ readonly points: HTMLElement;
43
+ readonly learning: HTMLElement;
44
+ /** Rewrites what changed; `true` when a text at the top did, so the caller measures the room again. */
45
+ refresh(): boolean;
46
+ remove(): void;
47
+ }
48
+ /**
49
+ * A count as FIVE DIGITS WITH LEADING ZEROS, clamped to 0…99999 (ADR-0238): 12 is «00012». `shown` is the number those digits
50
+ * say, which is what a listener hears — the same number a sighted child sees, never the zeros.
51
+ */
52
+ export declare function fiveDigits(count: number): {
53
+ readonly digits: string;
54
+ readonly shown: number;
55
+ };
56
+ /**
57
+ * Mounts the bands, one element per declared number, and fills them: the mission in the game region, the rest in the HUD
58
+ * row's cells (`row`). A place with no number is hidden. Without a row every band goes in the region itself — the learning
59
+ * band BEFORE the screen footer when one exists, so the explanation band, drawn later on the same layer, covers it.
60
+ */
61
+ export declare function mountHudBands(tr: HudTranslator, doc: Document, region: HTMLElement, numbers: readonly HudNumber[], seat?: number, row?: HudRowSlots): HudBandsMounted;
62
+ export {};
@@ -0,0 +1,146 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ const HUD_BANDS = ['identity', 'mission', 'power', 'learning'];
3
+ /** ADR-0049 §5: three ten-segment bars are thirty lit elements; a fourth stops being a reading. */
4
+ const MAX_BARS = 3;
5
+ const SEGMENTS = 10;
6
+ /** Why a `hud` declaration is malformed; empty when it is well formed. Absent is well formed: no HUD is mounted. */
7
+ export function hudNumbersProblems(numbers) {
8
+ if (numbers === undefined)
9
+ return [];
10
+ if (!Array.isArray(numbers))
11
+ return ['hud must be a list of numbers'];
12
+ const out = [];
13
+ numbers.forEach((n, i) => {
14
+ if (!n || !HUD_BANDS.includes(n.band))
15
+ out.push(`hud[${i}].band must be one of ${HUD_BANDS.join(', ')}`);
16
+ if (!n || typeof n.nameKey !== 'string' || !n.nameKey.trim())
17
+ out.push(`hud[${i}].nameKey must name what is counted by a key of the game's dictionary`);
18
+ if (!n || typeof n.value !== 'function')
19
+ out.push(`hud[${i}].value must be a function of the seat`);
20
+ });
21
+ const bars = numbers.filter((n) => n?.band === 'learning').length;
22
+ if (bars > MAX_BARS)
23
+ out.push(`hud declares ${bars} learning bars: at most ${MAX_BARS}, one per skill the adult enabled (ADR-0049 §5)`);
24
+ return out;
25
+ }
26
+ /** The highest count five digits hold; a larger score is shown as this (ADR-0238). */
27
+ const MAX_POINTS = 99_999;
28
+ /**
29
+ * A count as FIVE DIGITS WITH LEADING ZEROS, clamped to 0…99999 (ADR-0238): 12 is «00012». `shown` is the number those digits
30
+ * say, which is what a listener hears — the same number a sighted child sees, never the zeros.
31
+ */
32
+ export function fiveDigits(count) {
33
+ const shown = Math.min(MAX_POINTS, Math.max(0, Math.floor(count) || 0));
34
+ return { digits: String(shown).padStart(5, '0'), shown };
35
+ }
36
+ /**
37
+ * What the child reads, and — for the points — what a listener hears instead (`label`): the frame in the dictionary, the name
38
+ * — resolved from the game's key at this refresh (ADR-0232 D3) — through a parameter (pillar 3). A count of objectives keeps
39
+ * its «3 of 10» wherever it is declared.
40
+ */
41
+ function lineFace(t, name, n, seat) {
42
+ const v = n.value(seat);
43
+ if (typeof v !== 'number')
44
+ return { text: t('hud.contador', { have: String(v.have), need: String(v.need), nome: name }), label: null };
45
+ if (n.band !== 'identity')
46
+ return { text: t('hud.numero', { nome: name, valor: String(v) }), label: null };
47
+ const { digits, shown } = fiveDigits(v);
48
+ return { text: digits, label: t('hud.points', { count: String(shown), name }) };
49
+ }
50
+ function barLabel(t, name, bar) {
51
+ const count = (c) => String(bar.segmentos.filter((s) => s === c).length);
52
+ const base = t('hud.barra', { nome: name, azuis: count('azul'), verdes: count('verde'), vermelhos: count('vermelho') });
53
+ return bar.cor === 'roxa' ? `${base}. ${t('hud.barra.sobe')}` : bar.cor === 'laranja' ? `${base}. ${t('hud.barra.desce')}` : base;
54
+ }
55
+ /**
56
+ * Mounts the bands, one element per declared number, and fills them: the mission in the game region, the rest in the HUD
57
+ * row's cells (`row`). A place with no number is hidden. Without a row every band goes in the region itself — the learning
58
+ * band BEFORE the screen footer when one exists, so the explanation band, drawn later on the same layer, covers it.
59
+ */
60
+ export function mountHudBands(tr, doc, region, numbers, seat = 0, row) {
61
+ const { t } = tr;
62
+ const band = (cls, count) => {
63
+ const el = doc.createElement('div');
64
+ el.className = `hud-faixa ${cls}`;
65
+ el.hidden = count === 0;
66
+ return el;
67
+ };
68
+ const texts = numbers.filter((n) => n.band !== 'learning');
69
+ const bars = numbers.filter((n) => n.band === 'learning');
70
+ const ofBand = (b) => texts.filter((n) => n.band === b);
71
+ const left = band('hud-esquerda', ofBand('mission').length);
72
+ const right = band('hud-direita', ofBand('power').length);
73
+ const points = band('hud-points', ofBand('identity').length);
74
+ const learning = band('hud-aprendizagem', bars.length);
75
+ const place = { identity: points, mission: left, power: right };
76
+ const lines = texts.map((n) => {
77
+ const p = doc.createElement('p');
78
+ p.className = 'hud-numero';
79
+ p.dataset.band = n.band;
80
+ place[n.band].appendChild(p);
81
+ return [n, p];
82
+ });
83
+ const bardivs = bars.map((n) => {
84
+ const div = doc.createElement('div');
85
+ div.className = 'hud-barra';
86
+ div.setAttribute('role', 'img');
87
+ for (let i = 0; i < SEGMENTS; i++)
88
+ div.appendChild(doc.createElement('span')).className = 'hud-seg';
89
+ learning.appendChild(div);
90
+ return [n, div];
91
+ });
92
+ region.appendChild(left);
93
+ // the power ABOVE the score (ADR-0239 point 3): the order of the two in their cell is the order on screen
94
+ (row?.score ?? region).append(right, points);
95
+ if (row)
96
+ row.learning.appendChild(learning);
97
+ else
98
+ region.insertBefore(learning, [...region.children].find((c) => c.classList.contains('rodape-da-tela')) ?? null);
99
+ function refresh() {
100
+ let changed = false;
101
+ for (const [n, p] of lines) {
102
+ // a name the game's dictionaries lack hides its line — never its key on screen (`problems` names it)
103
+ const name = tr.word(n.nameKey);
104
+ if (p.hidden !== !name) {
105
+ p.hidden = !name;
106
+ changed = true;
107
+ }
108
+ const face = name ? lineFace(t, name, n, seat) : { text: '', label: null };
109
+ if (p.textContent !== face.text) {
110
+ p.textContent = face.text;
111
+ changed = true;
112
+ }
113
+ // the points are an image of a number for a listener: the name says «12 points», never «zero zero zero one two»
114
+ if (face.label !== null && p.getAttribute('aria-label') !== face.label) {
115
+ p.setAttribute('role', 'img');
116
+ p.setAttribute('aria-label', face.label);
117
+ }
118
+ }
119
+ for (const [n, div] of bardivs) {
120
+ const name = tr.word(n.nameKey);
121
+ div.hidden = !name;
122
+ if (!name)
123
+ continue;
124
+ const bar = n.value(seat);
125
+ const shown = bar.segmentos.slice(-SEGMENTS);
126
+ const label = barLabel(t, name, { segmentos: shown, cor: bar.cor }); // in the key: a language change rewrites it
127
+ const key = `${bar.cor}:${shown.join(',')}:${label}`;
128
+ if (div.dataset.estado === key)
129
+ continue;
130
+ div.dataset.estado = key;
131
+ div.dataset.cor = bar.cor;
132
+ [...div.children].forEach((cell, i) => { cell.dataset.seg = shown[i] ?? 'vazio'; });
133
+ div.setAttribute('aria-label', label);
134
+ }
135
+ return changed;
136
+ }
137
+ refresh();
138
+ return {
139
+ left,
140
+ right,
141
+ points,
142
+ learning,
143
+ refresh,
144
+ remove: () => { left.remove(); points.remove(); right.remove(); learning.remove(); },
145
+ };
146
+ }
@@ -0,0 +1,34 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ /** The row's cells, each a place something else fills: the bands (`ui/hud-bands`), the clock (`ui/session-clock`), the map. */
3
+ export interface HudRow {
4
+ readonly row: HTMLElement;
5
+ /** Bottom left: the learning bars. */
6
+ readonly learning: HTMLElement;
7
+ /** Bottom centre: the session clock. */
8
+ readonly clock: HTMLElement;
9
+ /** Between the centre and the right: the power above the score. */
10
+ readonly score: HTMLElement;
11
+ /** Bottom right: where a game mounts its own map. Empty, it is not drawn (ADR-0239 point 4). */
12
+ readonly map: HTMLElement;
13
+ }
14
+ /**
15
+ * Builds the row in `region`, BEFORE the screen footer when one exists, so the explanation band — drawn later on the same
16
+ * layer — covers it. `null` where the region takes no children.
17
+ */
18
+ export declare function mountHudRow(doc: Document, region: HTMLElement | null): HudRow | null;
19
+ /** What `reserveBottomBand` measures. The pad is the on-screen controller (`#touch-controls`), when the page has one. */
20
+ export interface BottomBandCtx {
21
+ readonly region: HTMLElement | null;
22
+ readonly row: HTMLElement | null;
23
+ readonly pad: HTMLElement | null;
24
+ }
25
+ /**
26
+ * THE ROW FOLLOWS THE PAD AT ONCE (ADR-0239 §6): `measure` runs again whenever the on-screen pad under `host` shows, hides or is
27
+ * rebuilt, by whichever door — a touch, a key, a menu opening or closing (ADR-0166), a new cartridge. A resize and the session
28
+ * clock's tick are not enough: between them the row stood behind the pad for up to a second, and the explanation band that
29
+ * stands where the row stands lay over the pad's START pill. A mutation observer answers before the next frame is drawn.
30
+ * Returns what stops it; nothing is watched where the host has no observer.
31
+ */
32
+ export declare function followThePad(host: Node | null, Observer: typeof MutationObserver | undefined, measure: () => void): () => void;
33
+ /** Measures the bottom and writes `--hud-row-bottom` and `--hud-row-h` on the region (see the header). */
34
+ export declare function reserveBottomBand(ctx: BottomBandCtx): void;
@@ -0,0 +1,80 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // ui/hud-row — THE HUD IS ONE ROW AT THE BOTTOM of the game region (ADR-0239; issue #94), and this module builds the row's
3
+ // cells and measures the room it takes.
4
+ //
5
+ // Left to right: the learning bars · the session clock, in the centre · the score, with the power above it · the game's map.
6
+ // The mission is not here: it sits at the top centre, just under the quick bar (ADR-0239 erratum; `ui/top-band`).
7
+ //
8
+ // WHO SITS OVER WHOM at the bottom (ADR-0239 point 6), written as two variables on the region that the stylesheet reads:
9
+ // · `--hud-row-bottom` — how far above the region's lower edge the row stands: 0, or the height of the on-screen pad's
10
+ // lower parts while the pad shows, so the row sits ABOVE the pad;
11
+ // · `--hud-row-h` — the row's own height, so the sound caption and the button legend sit above it, and a game's workspace
12
+ // ends above it: `--rodape-h` is these two and nothing else, because the caption and the legend are momentary and
13
+ // overlay the workspace while they show (ADR-0239 erratum).
14
+ // The explanation band covers the row while a menu is open: that is the stylesheet's alone.
15
+ //
16
+ // ⚠️ IT RECEIVES THE NODES and reaches no global (ADR-0232), like `ui/top-band`.
17
+ /**
18
+ * Builds the row in `region`, BEFORE the screen footer when one exists, so the explanation band — drawn later on the same
19
+ * layer — covers it. `null` where the region takes no children.
20
+ */
21
+ export function mountHudRow(doc, region) {
22
+ if (!region || typeof region.insertBefore !== 'function')
23
+ return null;
24
+ const cell = (cls) => { const el = doc.createElement('div'); el.className = cls; return el; };
25
+ const row = cell('hud-row');
26
+ const learning = cell('hud-row-cell hud-row-learning');
27
+ const clock = cell('hud-row-cell hud-row-clock');
28
+ const end = cell('hud-row-cell hud-row-end');
29
+ const score = cell('hud-score');
30
+ const map = cell('hud-map');
31
+ end.appendChild(score);
32
+ end.appendChild(map);
33
+ for (const c of [learning, clock, end])
34
+ row.appendChild(c);
35
+ // `children` may be missing in a host double; then there is no footer to go before
36
+ region.insertBefore(row, Array.from(region.children ?? []).find((c) => c.classList.contains('rodape-da-tela')) ?? null);
37
+ return { row, learning, clock, score, map };
38
+ }
39
+ /** A pad part counts when it stands on the region's lower edge — within this many pixels of it. */
40
+ const ON_THE_EDGE_PX = 24;
41
+ /** How high the pad's lower parts reach above the region's lower edge while the pad shows; 0 when it is hidden or absent. */
42
+ function padReach(pad, regionBottom) {
43
+ if (!pad || pad.hidden)
44
+ return 0;
45
+ let reach = 0;
46
+ for (const part of [...pad.children]) {
47
+ const b = part.getBoundingClientRect();
48
+ if (b.height > 0 && regionBottom - b.bottom <= ON_THE_EDGE_PX)
49
+ reach = Math.max(reach, regionBottom - b.top);
50
+ }
51
+ return reach;
52
+ }
53
+ /** The pad, or a part of it, in a mutation: its `hidden` changed, its parts were rebuilt, or it came or went. */
54
+ function aboutThePad(r) {
55
+ return [r.target, ...Array.from(r.addedNodes), ...Array.from(r.removedNodes)].some((n) => !!n.closest?.('#touch-controls'));
56
+ }
57
+ /**
58
+ * THE ROW FOLLOWS THE PAD AT ONCE (ADR-0239 §6): `measure` runs again whenever the on-screen pad under `host` shows, hides or is
59
+ * rebuilt, by whichever door — a touch, a key, a menu opening or closing (ADR-0166), a new cartridge. A resize and the session
60
+ * clock's tick are not enough: between them the row stood behind the pad for up to a second, and the explanation band that
61
+ * stands where the row stands lay over the pad's START pill. A mutation observer answers before the next frame is drawn.
62
+ * Returns what stops it; nothing is watched where the host has no observer.
63
+ */
64
+ export function followThePad(host, Observer, measure) {
65
+ if (!host || typeof Observer !== 'function')
66
+ return () => { };
67
+ const observer = new Observer((records) => { if (records.some(aboutThePad))
68
+ measure(); });
69
+ observer.observe(host, { attributes: true, attributeFilter: ['hidden'], childList: true, subtree: true });
70
+ return () => observer.disconnect();
71
+ }
72
+ /** Measures the bottom and writes `--hud-row-bottom` and `--hud-row-h` on the region (see the header). */
73
+ export function reserveBottomBand(ctx) {
74
+ const { region, row } = ctx;
75
+ if (!region || !row || typeof region.getBoundingClientRect !== 'function')
76
+ return;
77
+ const lift = Math.ceil(padReach(ctx.pad, region.getBoundingClientRect().bottom));
78
+ region.style.setProperty('--hud-row-bottom', `${lift}px`);
79
+ region.style.setProperty('--hud-row-h', `${Math.ceil(row.getBoundingClientRect().height)}px`);
80
+ }
@@ -1,17 +1,15 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
2
  import type { PlayerView } from '../core/entity.js';
3
3
  import type { Objective } from '../core/contract.js';
4
+ import type { Translate } from '../core/i18n.js';
4
5
  import type { DomQuery } from '../core/dom-query.js';
5
- /** Minimal DOM-selector shape (matches ui/dom.ts's `$`). */
6
- export type { DomQuery } from '../core/dom-query.js';
7
- /** Só os campos do jogador que o HUD lê. Estrutural de propósito: o `players[]` real é `unknown[]` no core/state. */
8
- /** O que o HUD lê do JOGADOR: o poder ativo e se ele desistiu. O progresso vem do `Objective`, não daqui —
9
- * `collected` saiu da fatia, e com ele a última coisa que o HUD sabia sobre juntar objetos. */
6
+ /** Only the player fields the HUD reads. Structural on purpose: the real `players[]` is `unknown[]` in core/state. */
7
+ /** What the HUD reads from the PLAYER: the active power and whether they quit. Progress comes from the `Objective`,
8
+ * not from here. */
10
9
  export type HudPlayer = PlayerView<'activePower' | 'quit'>;
11
- /** Grade de telas: 1 → 1×1, 2 → 2×1, 3-4 → 2×2 (a 3ª tela é centralizada na linha de baixo). */
10
+ /** Screen grid: 1 → 1×1, 2 → 2×1, 3-4 → 2×2 (the 3rd screen is centred on the bottom row). */
12
11
  export { screenGrid } from '../core/screens.js';
13
- export type { ScreenGrid } from '../core/screens.js';
14
- /** Retângulo da tela `i` em porcentagens de CSS, já prontas para `style.left/top/width/height`. */
12
+ /** Screen `i`'s rectangle in CSS percentages, ready for `style.left/top/width/height`. */
15
13
  export interface ScreenRect {
16
14
  L: string;
17
15
  T: string;
@@ -19,119 +17,121 @@ export interface ScreenRect {
19
17
  H: string;
20
18
  }
21
19
  /**
22
- * Posição/tamanho da tela `i` numa grade de `n` jogadores. Verbatim de screenRect(i) — que lia `numPlayers`
23
- * global; aqui `n` é parâmetro (mesma conta, testável sem estado). Caso especial preservado: com 3 telas, a
24
- * terceira é centralizada na linha de baixo, para casar com o posicionamento do render (configureRender).
20
+ * Position/size of screen `i` in a grid of `n` players; `n` is a parameter, so it is testable without state. Special
21
+ * case: with 3 screens, the third is centred on the bottom row, to match the renderer's positioning.
25
22
  */
26
23
  export declare function screenRect(i: number, n: number): ScreenRect;
27
- /** Quantas telas o HUD monta: ao menos uma, mesmo antes de `players[]` existir no boot. Verbatim (Math.max(1,…)). */
24
+ /** How many screens the HUD mounts: at least one, even before `players[]` exists at boot. */
28
25
  export declare function screenCount(n: number): number;
29
- /** O texto que o leitor de tela ouve no contador. A MOLDURA é a chave; o NOME do objetivo atravessa por
30
- * parâmetro — a regra do pilar 3 (ADR-0010), a mesma que o currículo segue. */
31
- export declare const contadorLabel: (o: Objective) => string;
26
+ /** The text a screen reader hears on the counter. The FRAME is the key; the objective's NAME passes through as a
27
+ * parameter — pillar 3's rule (ADR-0010), the same the curriculum follows. */
28
+ export declare const counterLabel: (t: Translate, o: Objective) => string;
32
29
  /**
33
- * Markup do contador (objetivo na 1ª coluna, poder na 2ª).
30
+ * The counter's markup (objective in the 1st column, power in the 2nd).
34
31
  *
35
- * O objetivo entra INTEIRO — nome, quanto tem, quanto precisa — em vez de só o alvo numérico, e o ícone entra
36
- * por injeção. É o que tira o desenho da moeda de dentro da engine: o HUD mostra o que o jogo declarou
37
- * (campo 5 do contrato), sem saber se é moeda, palavra ou conta.
32
+ * The objective comes in WHOLE — name, how much you have, how much you need — and the icon by injection: the HUD shows
33
+ * what the game declared (field 5 of the contract), without knowing whether it is a coin, a word or a sum.
38
34
  *
39
- * O `aria-label` é a parte que não é renomeação: sem o nome do objetivo não havia o que dizer, e o contador
40
- * era mudo para quem não vê a tela.
35
+ * The accessible name is set separately (`applyCounterLabel`), because the objective's name is outside data.
41
36
  */
42
- export declare function vphudHtml(objetivo: Objective, icone: string): string;
37
+ export declare function vphudHtml(objective: Objective, icon: string): string;
43
38
  /**
44
- * PÕE O NOME DECLARADO PELO JOGO NO RÓTULO DO LEITOR DE TELA — por atributo, nunca por markup (issue #106).
39
+ * PUTS THE NAME THE GAME DECLARED INTO THE SCREEN READER'S LABEL — by attribute, never by markup (issue #106).
45
40
  *
46
- * ⚠️ ESTE É UM VETOR QUE A AUDITORIA DE 2026-08-26 NÃO TINHA COMO CONHECER, e vale dizer por quê: ela varreu
47
- * por FONTE DE DADO e concluiu, com razão para a época, que nada de fora chegava a markup. Depois disso o
48
- * contrato passou a existir (ADR-0030) e os jogos passaram a viver em REPOSITÓRIOS SEPARADOS, consumindo a
49
- * engine como pacote (ADR-0083). O `name.text` do objetivo é texto de um jogo que esta árvore não revê.
41
+ * ⚠️ The games live in SEPARATE REPOSITORIES and consume the engine as a package (ADR-0083), so the objective's
42
+ * `name.text` is text from a game this tree does not review.
50
43
  *
51
- * ⚠️ E ELE ENTRAVA NUM ATRIBUTO, que é o pior contexto dos dois: dentro de um elemento uma aspa é inofensiva,
52
- * dentro de `aria-label="…"` ela FECHA o atributo e o que vem a seguir vira atributo — um `onmouseover` sem
53
- * precisar de uma única tag.
44
+ * ⚠️ AND IT GOES INTO AN ATTRIBUTE, the worse of the two contexts: inside an element a quote is harmless; inside
45
+ * `aria-label="…"` it CLOSES the attribute and what follows becomes an attribute — an `onmouseover` without a single
46
+ * tag.
54
47
  *
55
- * `setAttribute` escapa por construção, e é por isso que a resposta é «construir nós» e não «escapar à mão»:
56
- * um escape esquecido não deixa rasto; um `setAttribute` esquecido tira o rótulo, e há caso a prendê-lo.
48
+ * `setAttribute` escapes by construction, which is why the answer is building nodes and not escaping by hand: a
49
+ * forgotten escape leaves no trace; a forgotten `setAttribute` removes the label, and a case holds it.
57
50
  */
58
- export declare function aplicarRotuloDoContador(vphud: Element | null, objetivo: Objective): void;
59
- /** Markup do selo "aperte um botão para entrar" (tela criada em jogo, ainda sem dono). `i` é o índice 0-based. */
60
- export declare function waitBadgeHtml(i: number): string;
61
- /** Projeção do HUD de UMA tela: tudo que updateGameHud() escreve no DOM, sem tocar no DOM. */
51
+ export declare function applyCounterLabel(t: Translate, vphud: Element | null, objective: Objective): void;
52
+ /**
53
+ * The markup of the press-a-button-to-join badge (a screen created mid-game, still with no owner). `i` is 0-based.
54
+ *
55
+ * 🔴 FROM THE DICTIONARY, never raw text: it is the only sentence that tells the child who just got a screen HOW to join,
56
+ * and the badge is their whole screen at that instant, not a corner detail.
57
+ *
58
+ * 📌 ITS OWN KEY and not the existing `sr.player.pressToJoin`, although the two look alike: the screen reader's says to
59
+ * press a button, this one says WHICH — your own keyboard or a free controller —, because whoever reads it is looking
60
+ * at a screen with other people around and needs to know it is not just any keyboard. Merging them would erase that
61
+ * half of one of the two.
62
+ */
63
+ export declare function waitBadgeHtml(t: Translate, i: number): string;
64
+ /** The HUD projection of ONE screen: everything updateGameHud() writes to the DOM, without touching the DOM. */
62
65
  export interface HudRowView {
63
- /** Texto do contador: quanto o jogador tem, verbatim (sem formatação nem clamp). */
66
+ /** The counter's text: how much the player has, as given (no formatting nor clamp). */
64
67
  have: string;
65
- /** O que o leitor de tela ouve no contador — reescrito junto com o número, senão ele ficaria falando o
66
- * valor do primeiro quadro a partida inteira. É o defeito que um `aria-label` estático teria. */
68
+ /** What the screen reader hears on the counter — rewritten with the number, otherwise it would keep saying the first
69
+ * frame's value the whole match. That is the defect a static `aria-label` would have. */
67
70
  label: string;
68
- /** Rótulo curto do poder ativo, com o travessão como fallback de poder desconhecido/ausente. */
71
+ /** Short label of the active power, with the dash as the fallback for an unknown/absent power. */
69
72
  power: string;
70
- /** `hidden` do selo "Jogo abandonado": escondido enquanto o jogador NÃO desistiu. */
73
+ /** `hidden` of the quit badge: hidden while the player has NOT quit. */
71
74
  quitHidden: boolean;
72
- /** `style.visibility` do contador: quem desistiu vê tela preta com o selo, sem números. */
75
+ /** The counter's `style.visibility`: whoever quit sees a black screen with the badge, no numbers. */
73
76
  visibility: 'hidden' | 'visible';
74
77
  }
75
78
  /**
76
- * Estado do HUD de um jogador. Verbatim do corpo de updateGameHud(), só que como valor.
77
- * `powerShort` é o POWER_SHORT do game.js (injetado — a mesma FUNÇÃO que game/coin-spawning.ts já recebe).
78
- * Função e não tabela: o texto depende do idioma ATUAL, e uma tabela lida no boot ficaria congelada nele.
79
+ * One player's HUD state, as a value. `powerShort` is injected by the host (the same function other game modules
80
+ * receive). A function and not a table: the text depends on the CURRENT language, and a table read at boot would stay
81
+ * frozen in it.
79
82
  */
80
- export declare function hudRowView(p: HudPlayer, powerShort: (kind: string) => string, objetivo: Objective): HudRowView;
83
+ export declare function hudRowView(t: Translate, p: HudPlayer, powerShort: (kind: string) => string, objective: Objective): HudRowView;
81
84
  export interface HudCtx {
82
- /** Quantos jogadores/telas. Estado de RODADA (ADR-0038): vem da instância que a raiz possui.
83
- * Era `numPlayers`, um `let` de `core/state` importado como binding vivo — e um `let` de módulo
84
- * é compartilhado por qualquer segundo jogo que a mesma página carregue (D13 do `demos`). */
85
+ /** Translates in the page's language — the root's translator (ADR-0232 D3). REQUIRED: text built from nowhere is a raw key. */
86
+ t: Translate;
87
+ /** How many players/screens. ROUND state (ADR-0038): it comes from the instance the root owns — a module `let` would
88
+ * be shared by any second game the same page loads. */
85
89
  getNumPlayers: () => number;
86
- /** Os jogadores. Estado de RODADA, pelo mesmo motivo. `readonly unknown[]` porque cada consumidor
87
- * estreita para a SUA fatia — o tipo real é do jogo, não da engine (ADR-0033). */
90
+ /** The players. ROUND state, for the same reason. `readonly unknown[]` because each consumer narrows to ITS slice —
91
+ * the real type is the game's, not the engine's (ADR-0033). */
88
92
  getPlayers: () => readonly unknown[];
89
- /** Seletor DOM (forma do `$` de ui/dom.ts), injetado — o módulo nunca alcança `document` por global. */
93
+ /** DOM selector (ui/dom.ts's `$` shape), injected — the module never reaches `document` through a global. */
90
94
  $: DomQuery;
91
95
  /**
92
- * POWER_SHORT: rótulos curtos de poder mostrados no HUD. Fica no game.js porque game/coin-spawning.ts
93
- * (showPower) também o recebe — injetar evita a 2ª cópia da tabela.
96
+ * Short power labels shown on the HUD. Injected so the host keeps one table for every module that shows powers.
94
97
  */
95
98
  powerShort: (kind: string) => string;
96
99
  /**
97
- * O OBJETIVO do jogador `i` — campo 5 do contrato (`core/contract.Objective`): o nome do que se junta,
98
- * quanto tem e quanto precisa. FUNÇÃO e não valor, porque `have` muda a cada quadro.
99
- *
100
- * Era `hudTarget: number`, e antes disso `COIN_TARGET` por importação. Cada passo tirou uma coisa que o HUD
101
- * sabia sobre o jogo: primeiro a dependência, agora o assunto.
100
+ * Player `i`'s OBJECTIVE — field 5 of the contract (`core/contract.Objective`): the name of what is collected, how
101
+ * much they have and how much they need. A FUNCTION and not a value, because `have` changes every frame.
102
102
  */
103
103
  hudObjective: (playerIndex: number) => Objective;
104
- /** O ícone do contador. Era o desenho da moeda cravado no markup da engine; é do jogo, como o nome. */
104
+ /** The counter's icon. It is the game's, like the name. */
105
105
  hudIcon: string;
106
106
  /**
107
- * Painel de pausa da tela `i`. NÃO é deste módulo (slice de pausa/ícones): entra por injeção e o HUD só
108
- * anexa o retorno dentro da `.player-screen` correspondente.
107
+ * Screen `i`'s pause panel. NOT this module's: it comes in by injection and the HUD only attaches the result inside
108
+ * the matching `.player-screen`.
109
109
  */
110
110
  buildScreenPause: (i: number) => HTMLElement;
111
111
  /**
112
- * A BARRA RÁPIDA de acessibilidade da tela `i` (ui/pause-icons `buildQuickBar`). Anexada como IRMÃ da
113
- * `.screen-exp`, e não dentro dela: a barra é CONTROLE, e o modo empatia não a alcança (issue #82).
112
+ * Screen `i`'s accessibility QUICK BAR (ui/pause-icons `buildQuickBar`). Attached as a SIBLING of `.screen-exp`, not
113
+ * inside it: the bar is CONTROL, and empathy mode does not reach it (issue #82).
114
114
  */
115
115
  buildQuickBar: (i: number) => HTMLElement;
116
116
  /**
117
- * Chamado no FIM de buildGameHud() com os painéis de pausa recém-criados, em ordem de tela. É o gancho onde o
118
- * game.js reatribui `vpPause` (binding local dele) e roda o que o original rodava depois do laço
119
- * (applyLetra/renderPauseLegend). Opcional: sem ele o HUD monta igual, só não avisa ninguém.
117
+ * Called at the END of buildGameHud() with the freshly created pause panels, in screen order — the hook where the
118
+ * host keeps its references and runs what depends on them. Optional: without it the HUD mounts the same, it just
119
+ * tells nobody.
120
120
  */
121
121
  onScreensBuilt?: (pausePanels: HTMLElement[]) => void;
122
- /** As barras rápidas recém-montadas, na ordem das telas. A raiz guarda para o `getA11yBars`. */
122
+ /** The freshly mounted quick bars, in screen order. The root keeps them for `getA11yBars`. */
123
123
  onBarsBuilt?: (bars: HTMLElement[]) => void;
124
124
  }
125
125
  export interface HudApi {
126
- /** (Re)monta `#game-hud`: uma `.player-screen` por jogador, com HUD, selo de abandono e painel de pausa. */
126
+ /** (Re)mounts `#game-hud`: one `.player-screen` per player, with HUD, quit badge and pause panel. */
127
127
  buildGameHud: () => void;
128
- /** Reescreve moedas/poder e o selo de abandono de todas as telas montadas. Chamado a cada frame. */
128
+ /** Rewrites the objective/power and the quit badge on every mounted screen. Called every frame. */
129
129
  updateGameHud: () => void;
130
- /** Contêiner `.player-screen` da tela `i` (o quiz de MP e outros overlays por jogador penduram aqui). */
130
+ /** Screen `i`'s `.player-screen` container (the multiplayer quiz and other per-player overlays hang here). */
131
131
  getScreen: (i: number) => HTMLElement | null;
132
- /** Cria o selo `.vp-wait` na tela `i` (idempotente: não duplica se já existir). */
132
+ /** Creates the `.vp-wait` badge on screen `i` (idempotent: does not duplicate if it already exists). */
133
133
  showWaitingBadge: (i: number) => void;
134
- /** Remove o selo `.vp-wait` da tela `i` (o jogador entrou). No-op se a tela ou o selo não existirem. */
134
+ /** Removes the `.vp-wait` badge from screen `i` (the player joined). No-op if the screen or the badge does not exist. */
135
135
  clearWaitingBadge: (i: number) => void;
136
136
  }
137
137
  export declare function initHud(ctx: HudCtx): HudApi;