@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
@@ -1,207 +1,139 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
- // ui/shell.ts — A CASCA: em que TELA o jogo está, e o que a tela liga e desliga ao trocar.
2
+ // ui/shell.ts — THE SHELL: which SCREEN the game is on (title, playing, paused), and what the screen turns on and off
3
+ // when it changes.
3
4
  //
4
- // Este módulo responde a UMA pergunta: "estamos no título, jogando ou pausados — e o que isso significa para o
5
- // documento?". Ele é o irmão de cima de tudo o que já saiu: game/session.ts decide o que é uma RODADA,
6
- // render/draw.ts decide o que é um QUADRO, e aqui se decide o que é uma TELA. Nada aqui sabe de física, de
7
- // moeda ou de pixel; tudo aqui sabe de `hidden`, de foco, de mudo e do menu de pausa.
5
+ // It knows nothing of physics or pixels; it knows `hidden`, focus, mute and the pause cards. `createGame` does NOT mount
6
+ // it — nothing in `app/js` calls `initShell`. It is a published kit for a game that has a title screen and wants the
7
+ // engine's projection of scenes onto the document; several of its ctx fields (`setQuizLevel`, `openTypo`, the pause
8
+ // actions) are one game's vocabulary.
8
9
  //
9
- // O QUE VEIO, E DE ONDE (bloco "E14: shell — título/splash + pausa" do game.js)
10
- // · `setPhase(p)` — a reação de UI à troca de fase. O VALOR continua em core/state.ts (setPhaseValue);
11
- // o que mora aqui é só a consequência visível.
12
- // · `pauseActs` — a tabela de ações dos `.pm-btn` do menu de pausa (por tela).
13
- // · `pauseSelect()` — põe o 1º item (Continuar) selecionado em cada tela de pausa.
14
- // · `printMode()` — esconde as pausas para ver a tela limpa; qualquer botão volta.
15
- // · `togglePause()` — jogando ⇄ pausado.
16
- // · `updateTitleLegend()`— a legenda de dispositivo do splash (2 linhas de "chips": movimento/pausa e os 4
17
- // botões de ação, com o que está CONFIGURADO para o Jogador 1).
10
+ // WHY `projectScene` IS NOT A STATE MACHINE WITH A TRANSITION TABLE. There are three scenes and every transition between
11
+ // them is legal — no guard, no named event, no entry/exit hook beyond the body below. A `Map<[from, to], handler>` would
12
+ // forbid no illegal state (there is none) and turn a block read top to bottom into a jump. What IS worth it is separating
13
+ // the DECISION from the EFFECT: `phaseView(facts)` returns everything a scene asks of the document, and `applyPhaseView`
14
+ // is the only part that touches it. The decision is then testable in the `node` project, and a sign error (the title
15
+ // overlay visible during play, sound not muted on pause — accessibility broken silently) becomes an assertion instead of a
16
+ // symptom found by playing. `ui/title.ts` made the same move with `computeTitleMenuView`.
17
+ // The only part with MEMORY — giving the touch controls back on resume, from the `dataset.wasOn` written on pause — is
18
+ // `touchControlsPlan`, a pure function of (scene facts, previous state, number of screens).
18
19
  //
19
- // POR QUE `setPhase` NÃO VIROU UMA MÁQUINA DE ESTADOS COM TABELA DE TRANSIÇÃO — E O QUE VIROU NO LUGAR
20
- // O pedido do projeto era transformar a sequência de `if`s numa máquina de estados de verdade. Olhei e a
21
- // resposta honesta é: metade sim, metade não, e a metade que vale não é a que o nome sugere.
22
- // · NÃO vale a tabela de transição. São TRÊS estados e as nove transições são todas legais — de qualquer
23
- // fase para qualquer fase, sem guarda, sem evento nomeado, sem hook de entrada/saída além do corpo que já
24
- // está aqui. Uma `Map<[from,to], handler>` sobre isso não impede nenhum estado ilegal (não existe nenhum),
25
- // não descreve nada que o código já não diga, e troca um bloco linear que se lê de cima a baixo por uma
26
- // indireção que obriga a saltar. Seria cerimônia sobre três estados. Não fiz.
27
- // · VALE, e muito, separar a DECISÃO do EFEITO. Os `if`s do original não são transições: são nove perguntas
28
- // diferentes feitas à MESMA fase (`p!=='playing'`, `p!=='title'`, `p!=='paused'`, `p==='paused'`…),
29
- // espalhadas no meio de nove escritas no DOM. Isso é uma PROJEÇÃO pura da fase disfarçada de sequência
30
- // imperativa. Extraí a projeção — `phaseView(p)` devolve o registro completo do que a fase manda fazer, e
31
- // `applyPhaseView` é a única parte que toca o documento. O ganho é concreto e não é estético: a decisão
32
- // passa a ser testável no project `node`, sem DOM, sem PIXI e sem áudio, e um erro de sinal num `!==`
33
- // (o tipo de erro que aqui deixa a11y quebrada em silêncio: overlay do título visível durante o jogo,
34
- // áudio não silenciado na pausa) vira uma asserção em vez de um sintoma que só aparece jogando.
35
- // É o mesmo movimento que ui/title.ts já fez com `computeTitleMenuView`, e por isso é o precedente da casa.
36
- // · O único pedaço com MEMÓRIA (e portanto o único candidato legítimo a "estado") é a restauração dos
37
- // controles de toque, que depende do `dataset.wasOn` gravado na pausa anterior. Esse virou
38
- // `touchControlsPlan(...)`, uma função pura de (fase, wasOn, escondido, nº de telas) → (escondido', wasOn').
39
- // Ver, logo abaixo, o defeito que essa separação tornou visível.
20
+ // WHAT IS NOT HERE: the `.pm-btn`/`.pi-btn` markup and click delegation belong to `ui/pause-icons`, which reads this
21
+ // module's action table through `getPauseActs()`. Opening and closing the settings panels belongs to
22
+ // `ui/settings-panel` and the `ui/settings-*` panels; `pauseActs` only CALLS them, by injection.
40
23
  //
41
- // O QUE FICOU DE FORA, E POR QUÊ
42
- // · `fpsTick` — a fronteira listava, mas ele não é casca: é instrumentação de HUD (escreve `#hud-fps` e
43
- // `#hud-fpsmin`), tem três contadores próprios de módulo e é chamado do laço a cada quadro, não na troca de
44
- // tela. Trazê-lo para cá acoplaria o "em que tela estamos" ao "quantos quadros por segundo" sem nenhum
45
- // parentesco. O precedente da casa já é esse: ui/layout.ts diz, no cabeçalho, "fpsTick/configureRender
46
- // seguem no game.js (outro concern)". Não forcei; segue no game.js, e o lar natural dele, quando chegar a
47
- // vez, é ui/hud.ts.
48
- // · `padKind()` — NÃO extraí porque JÁ ESTÁ EXTRAÍDO: `input/touch.ts` exporta `padKind()` desde a Onda A,
49
- // com o corpo idêntico ao do game.js, e o cabeçalho de lá registra que a cópia é órfã. A que sobrou no
50
- // game.js é código morto duplicado (nenhum chamador — ver o relatório). O certo é apagá-la, não mudá-la
51
- // de lugar mais uma vez.
52
- // · `updateTitleLegend()` — a fronteira deixava em aberto se ela é de shell ou de menu-nav. É de SHELL, e a
53
- // razão é simples: ela não navega nada. Não lê foco, não trata tecla, não anda entre itens; ela pinta o
54
- // rodapé de UMA tela específica (o título) com a configuração de entrada vigente, e quem a chama é o
55
- // próprio `setPhase('title')`. Se morasse em ui/menu-nav, a casca precisaria importar o módulo de
56
- // navegação só para desenhar uma legenda, e a dependência apontaria para o lado errado (a casca chamando o
57
- // teclado). Ficando aqui, ui/menu-nav não precisa saber que existe uma tela de título.
58
- // · O `.pm-btn`/`.pi-btn` (markup e delegação de clique) é de ui/pause-icons.ts, que já os constrói e já
59
- // consome esta tabela por `getPauseActs()`. Aqui está só a TABELA, não o botão.
60
- // · Abrir/fechar os nove diálogos de configuração é de ui/settings-panel.ts + ui/settings-*.ts. `pauseActs`
61
- // apenas os CHAMA, por injeção.
24
+ // INJECTION: every entry of `pauseActs` is a callback resolved when it is CALLED, so the host can wire the shell before
25
+ // the panels it opens exist. The number of players and the players are asked through getters: they are round state,
26
+ // owned by the host, and a module-level binding would be shared by a second game on the same page.
62
27
  //
63
- // INJEÇÃO E ORDEM DE BOOT (a armadilha desta etapa)
64
- // · `phase` e `numPlayers` NÃO entram por getter, e isso é de propósito: eles deixaram de ser `let` do
65
- // game.js na Fase 2 e hoje são bindings vivos de core/state.ts. Importá-los direto é exatamente o que
66
- // game/session.ts e input/touch.ts já fazem — um getter aqui seria uma indireção sobre uma indireção.
67
- // Quem AINDA é `let` do game.js entra por getter: `vpPause` (reatribuído por `buildGameHud`) e
68
- // `pauseActor` (reatribuído por seis lugares, incluindo o ctx do gamepad).
69
- // · TODA entrada de `pauseActs` é um callback, e não um valor, porque `initShell` precisa poder ser chamado
70
- // no lugar do bloco E14 (linha ~1373 do game.js) enquanto quase tudo o que a tabela chama — `openTypo`,
71
- // `openAudio`, `openMovement`, `openVisual`, `openHelp`, `quitGame`, `fitsN`, `joinPlayer` — são
72
- // `function` içadas OU `const` declarados depois (`motor`, `motion`, `empathy`, `hud`, `selVizPlayer`).
73
- // Com callbacks, a resolução acontece na CHAMADA (sempre pós-boot) e não na montagem do ctx.
74
- // · `setPhase` é chamado de fora por game/session.ts, input/gamepad.ts, game/attract.ts e
75
- // ui/activities-menu.ts, todos com o ctx montado ANTES do ponto de extração. Por isso o game.js deve
76
- // manter um envelope `function setPhase(p){ shell.setPhase(p); }` — declaração de função, içada — em vez
77
- // de trocar as quatro fiações. É o mesmo padrão já usado lá para `hideTouchControls`, `showTouchControls`,
78
- // `restartGame`, `fitsN`, `joinPlayer` e `quitGame`.
79
- // · O original protegia duas chamadas com `typeof pauseSelect==='function'` / `typeof reflectPauseIcons===
80
- // 'function'`. Eram guardas de TDZ do tempo do monólito; aqui `pauseSelect` é função local (sempre
81
- // definida) e `reflectPauseIcons` é injetada (sempre função). Verifiquei que `reflectPauseIcons` é `const`
82
- // declarado no game.js MUITO antes de a primeira pausa acontecer, então as guardas nunca foram falsas em
83
- // execução real — removê-las não muda comportamento, só tira ruído. Registrado aqui porque é a única
84
- // linha que não é cópia literal.
85
- //
86
- // SEM I/O NO IMPORT: o corpo do módulo só declara dados e funções puras. Todo efeito passa por `initShell`.
87
- // GUARDAS: cada consulta ao DOM passa por guarda de nulo, como manda a casa — é o que permite rodar no project
88
- // `node` com um `$` falso que devolve `null`.
89
- //
90
- // Ver docs/5-Refactoring/plano-modularizacao-mapa.md (C3).
91
- import { t } from '../core/i18n.js';
92
- import { PAD_DESIGNS, PAD_GLYPH_SPOKEN } from '../input/devices.js'; // módulo-folha de DADOS (zero deps) — importado, não injetado
93
- // UMA constante, e não um seletor repetido: com o submenu de opções (ADR-0044, item 5) o cartão de pausa passou
94
- // a ter DUAS listas, e quem varrer `.pm-btn` cru enxerga também a que está escondida.
95
- import { PM_ITENS_VISIVEIS } from './pause-icons.js';
96
- // `FatosDaCena` mora em `core/scenes`, ao lado da pilha que os produz — é tipo de ENGINE, e precisa ser
97
- // alcançável também por `game/`, que não pode importar de `ui/`. Ver o cabeçalho de lá.
98
- /** Verbatim das nove perguntas que o `setPhase` do game.js fazia à fase, agora feitas de uma vez só. */
28
+ // NO I/O ON IMPORT: the module body only declares data and pure functions. Every effect goes through `initShell`.
29
+ // GUARDS: every DOM lookup is null-guarded, which is what lets the `node` project run it with a fake `$` returning `null`.
30
+ import { PAD_DESIGNS, PAD_GLYPH_SPOKEN } from '../input/devices.js'; // a DATA leaf module (zero deps) — imported, not injected
31
+ // ONE constant, not a repeated selector: the pause card has more than one list (ADR-0044 item 5), and whoever scans raw
32
+ // `.pm-btn` also sees the hidden ones.
33
+ import { PM_VISIBLE_ITEMS } from './pause-icons.js';
34
+ import { keepInView } from './menu-items.js';
35
+ // `SceneFacts` lives in `core/scenes`, beside the stack that produces them — it is an ENGINE type.
36
+ /** Every question the scene change asks of the scene, asked at once. */
99
37
  export function phaseView(f) {
100
38
  return {
101
- titleOverlayHidden: !f.telaDeTitulo,
102
- screenPauseHidden: !f.menuDePausa,
103
- masterMuted: !f.mundoRodando,
104
- hideTouchControls: !f.mundoRodando,
105
- pausePressed: f.menuDePausa,
106
- focus: f.mundoRodando ? 'game-region' : f.menuDePausa ? 'pause-menu' : 'title-button',
39
+ titleOverlayHidden: !f.titleScreen,
40
+ screenPauseHidden: !f.pauseMenu,
41
+ masterMuted: !f.worldRunning,
42
+ hideTouchControls: !f.worldRunning,
43
+ pausePressed: f.pauseMenu,
44
+ focus: f.worldRunning ? 'game-region' : f.pauseMenu ? 'pause-menu' : 'title-button',
107
45
  };
108
46
  }
109
47
  /**
110
- * O ÚNICO pedaço de `setPhase` com memória: esconder os controles de toque ao pausar (guardando que estavam
111
- * ligados) e devolvê-los ao retomar. Pura, e por isso pinável sem navegador.
48
+ * The ONE part of a scene change with memory: hide the touch controls on pause (recording that they were on) and give them
49
+ * back on resume. Pure, so it can be pinned without a browser.
112
50
  *
113
- * O estado que chega aqui é o de ANTES de `hideTouchControls()` — quem chama lê primeiro e esconde depois.
114
- * Já foi o contrário, e o efeito era que `wasOn` nunca era gravado (o plano via o pad como se já estivesse
115
- * desligado): pausar no celular sumia com o direcional virtual e retomar não o devolvia.
51
+ * The state that arrives here is the one from BEFORE `hideTouchControls()` — the caller reads first and hides after.
52
+ * The other order never records `wasOn` (the plan sees the pad already off), and resuming on a phone would not give the
53
+ * virtual d-pad back.
116
54
  */
117
55
  export function touchControlsPlan(f, st, screens) {
118
- if (f.menuDePausa) {
56
+ if (f.pauseMenu) {
119
57
  if (!st.hidden)
120
- return { hidden: true, wasOn: true }; // guarda que estava ligado e esconde
121
- return st; // já escondido: nada muda (nem `wasOn`)
58
+ return { hidden: true, wasOn: true }; // record that it was on, and hide
59
+ return st; // already hidden: nothing changes (not even `wasOn`)
122
60
  }
123
- if (f.mundoRodando) {
61
+ if (f.worldRunning) {
124
62
  return { hidden: st.wasOn && screens <= 1 ? false : st.hidden, wasOn: false };
125
63
  }
126
- return { hidden: true, wasOn: false }; // título (ou qualquer cena que não seja jogo nem pausa): some e esquece
64
+ return { hidden: true, wasOn: false }; // the title (or any scene that is neither play nor pause): hide and forget
127
65
  }
128
66
  // ---------------------------------------------------------------------------------------------------------
129
- // LEGENDA DO TÍTULO — a parte pura (montar as duas linhas de chips a partir dos glifos escolhidos)
67
+ // THE TITLE LEGEND — the pure part (building the two rows of chips from the chosen glyphs)
130
68
  // ---------------------------------------------------------------------------------------------------------
131
- /** Um "chip" da legenda: o glifo (com cor de fundo opcional) seguido da palavra que ele significa. */
69
+ /** One legend «chip»: the glyph (with an optional background colour) followed by the word it stands for. */
132
70
  export function chip(txt, col, word) {
133
71
  return `<span class="lg"><span class="lg-ico"${col ? ` style="background:${col}"` : ''}>${txt}</span>${word ? ' ' + word : ''}</span>`;
134
72
  }
135
73
  /**
136
- * O nome FALADO de um glifo de controle. Glifo que já se lê passa intocado.
74
+ * The SPOKEN name of a controller glyph. A glyph that already reads as a word passes untouched.
137
75
  *
138
- * Ver `PAD_GLYPH_SPOKEN` em `input/devices`: a tabela guarda CHAVES e não texto, porque ela é uma `const` de
139
- * módulo avaliada uma vez no import — texto já resolvido congelaria o idioma no boot. Quem resolve é aqui, a
140
- * cada chamada, com o idioma vigente naquele instante.
76
+ * `PAD_GLYPH_SPOKEN` in `input/devices` holds KEYS, not text, because it is a module `const` evaluated once on import —
77
+ * resolved text would freeze the language at boot. It is resolved here, on each call, in the language of that moment.
141
78
  */
142
- export function glifoFalado(g) {
79
+ export function spokenGlyph(t, g) {
143
80
  const k = PAD_GLYPH_SPOKEN[g];
144
81
  return k ? t(k) : g;
145
82
  }
146
83
  /**
147
- * A LEGENDA DA PAUSA — duas camadas no mesmo lugar (ADR-0044, item 4).
148
- *
149
- * Ela dizia qual botão confirma e qual volta, e carregava `aria-hidden="true"` — ou seja, era invisível
150
- * justamente para quem não pode ver o glifo. A XAG 106 manda narrar exatamente isto ("A to Select").
84
+ * THE PAUSE LEGEND — two layers in the same place (ADR-0044 item 4).
151
85
  *
152
- * Mas só tirar o atributo devolveria o ruído que provavelmente o motivou: um leitor de tela lê `✕` como
153
- * "sinal de multiplicação". Então os CHIPS ficam visíveis e mudos, e ao lado nasce UMA frase só para leitor
154
- * de tela, com os glifos já traduzidos em palavra. Duas leituras da mesma informação, cada uma no sentido
155
- * que a alcança.
86
+ * It says which button confirms and which goes back, and XAG 106 asks for exactly this to be narrated ("A to Select").
87
+ * The CHIPS stay visible and silent — a screen reader would read `✕` as a multiplication sign — and beside them a single
88
+ * sentence exists for screen readers only, with the glyphs already turned into words. Two readings of the same
89
+ * information, each in the sense that reaches it.
156
90
  *
157
- * Recebe os pares `[glifo, cor]` que `simNaoGlyphs` escolhe a partir do desenho do controle — a inversão
158
- * PlayStation/Nintendo (onde "sim" é o botão 1) já vem decidida de lá.
91
+ * Takes the `[glyph, colour]` pairs of the pad's design by position: yes is the south button (A · ✕ · B) and no the east one
92
+ * (B · ◯ · A) on every design — no design swaps them (the Dev's association, ADR-0013 erratum).
159
93
  */
160
- export function pauseLegendHtml(sim, nao) {
161
- const mudo = (g, palavra) => `<span class="lg" aria-hidden="true"><span class="lg-ico" style="background:${g[1]}">${g[0]}</span> ${palavra}</span>`;
162
- const falada = t('menu.legendSpoken', { sim: glifoFalado(sim[0]), nao: glifoFalado(nao[0]) });
163
- return mudo(sim, t('menu.yes')) + mudo(nao, t('menu.no')) + `<span class="sr-only">${falada}</span>`;
94
+ export function pauseLegendHtml(t, sim, no) {
95
+ const silentLegend = (g, word) => `<span class="lg" aria-hidden="true"><span class="lg-ico" style="background:${g[1]}">${g[0]}</span> ${word}</span>`;
96
+ const spoken = t('menu.legendSpoken', { sim: spokenGlyph(t, sim[0]), nao: spokenGlyph(t, no[0]) });
97
+ return silentLegend(sim, t('menu.yes')) + silentLegend(no, t('menu.no')) + `<span class="sr-only">${spoken}</span>`;
164
98
  }
165
99
  /**
166
- * Linha 1 da legenda: direcional + START/Enter. Igual para toque e gamepad; o teclado sobrescreve os rótulos.
100
+ * Legend row 1: the d-pad and START/Enter. The same for touch and gamepad; the keyboard overrides the labels.
167
101
  *
168
- * As palavras vêm de `legend.*` e são resolvidas AQUI, a cada chamada — não numa tabela de módulo, que
169
- * congelaria o idioma no boot. Registro CURTO de propósito: esta fileira fica embaixo de um glifo e não tem
170
- * largura para o "Correr / interagir" que a lista de mapeamento usa (ver a nota em pt.ts).
102
+ * The words come from `legend.*` and are resolved HERE, on each call — not in a module table, which would freeze the
103
+ * language at boot. The SHORT register on purpose: this row sits under a glyph and has no room for the longer wording the
104
+ * remapping list uses.
171
105
  */
172
- export function legendRow1(dirTxt, pauseTxt) {
106
+ export function legendRow1(t, dirTxt, pauseTxt) {
173
107
  return chip(dirTxt, null, t('legend.move')) + chip(pauseTxt, null, t('legend.pause'));
174
108
  }
175
109
  /**
176
- * Linha 2 da legenda: os botões de ação, na ordem dos glifos.
110
+ * Legend row 2: the action buttons, in glyph order.
177
111
  *
178
- * ⚠️ AS PALAVRAS DEIXARAM DE ESTAR AQUI. Esta função dizia `t('legend.jump')`, `t('legend.run')` — o
179
- * vocabulário da plataforma dentro de um módulo de engine, e a engine a afirmar que todo jogo tem pular,
180
- * especial, correr e trocar, nessa ordem. Agora `rotulo` é perguntado ao jogo (a versão CURTA, ver
181
- * `ActionWord.short`), e uma posição que o jogo não nomeia não vira ficha nenhuma.
112
+ * The words are asked of the GAME (`wordFor`, the SHORT version — see `ActionWord.short`): the engine does not assume
113
+ * every game has jump, special, run and swap. A position the game does not name becomes no chip at all.
182
114
  */
183
- export function legendRow2(g, rotulo) {
184
- const ORDEM = ['action2', 'action3', 'action1', 'action4'];
185
- return ORDEM.map((a) => {
186
- const palavra = rotulo(a);
187
- return palavra ? chip(g[a][0], g[a][1], palavra) : '';
115
+ export function legendRow2(g, wordFor) {
116
+ const GLYPH_ORDER = ['action2', 'action3', 'action1', 'action4'];
117
+ return GLYPH_ORDER.map((a) => {
118
+ const word = wordFor(a);
119
+ return word ? chip(g[a][0], g[a][1], word) : '';
188
120
  }).join('');
189
121
  }
190
- /** O innerHTML final de `#title-legend`: duas `.lg-row`. */
122
+ /** The final innerHTML of `#title-legend`: two `.lg-row`. */
191
123
  export function legendHtml(l1, l2) {
192
124
  return `<span class="lg-row">${l1}</span><span class="lg-row">${l2}</span>`;
193
125
  }
194
126
  /**
195
- * Glifos de um pad FÍSICO. `layout` sai de `padLayoutFromId` (só quando `mapping === 'standard'`; fora do
196
- * padrão é sempre 'generic'), e `custom` é o mapa do assistente (só consultado FORA do padrão). Verbatim:
197
- * um botão sem entrada no mapa custom cai no índice default ('0'..'3'), e um índice que o design não conhece
198
- * vira o par `[índice, '#3a4a6a']` — o cinza de fallback.
127
+ * The glyphs of a PHYSICAL pad. `layout` comes from `padLayoutFromId` (only when `mapping === 'standard'`; off-standard it
128
+ * is always 'generic'), and `custom` is the wizard's map (only consulted OFF the standard). A button with no entry in the
129
+ * custom map falls back to its default index ('0'..'3'), and an index the design does not know becomes the pair
130
+ * `[index, '#3a4a6a']` — the fallback grey.
199
131
  */
200
132
  export function padActionGlyphs(layout, custom) {
201
133
  const set = PAD_DESIGNS[layout] || PAD_DESIGNS.generic;
202
- // O `typeof b === 'object'` não é cerimônia: o `PadMap` admite `boolean` além de `PadBinding` — é o
203
- // sentinela `_skip: true` do assistente de mapeamento. As quatro chaves lidas aqui nunca são ele, então
204
- // em execução nada muda; o que muda é que a leitura passa a PERGUNTAR em vez de supor.
134
+ // The `typeof b === 'object'` is not ceremony: a `PadMap` admits a `boolean` besides a `PadBinding` — the mapping
135
+ // wizard's `_skip: true` sentinel. The four keys read here are never it, so nothing changes at run time; what changes is
136
+ // that the read ASKS instead of assuming.
205
137
  const bOf = (k, def) => {
206
138
  const b = custom && custom[k];
207
139
  return b && typeof b === 'object' && typeof b.b === 'number' ? String(b.b) : def;
@@ -209,14 +141,14 @@ export function padActionGlyphs(layout, custom) {
209
141
  const gy = (k) => set[k] || [k, '#3a4a6a'];
210
142
  return { action2: gy(bOf('action2', '0')), action3: gy(bOf('action3', '1')), action1: gy(bOf('action1', '2')), action4: gy(bOf('action4', '3')) };
211
143
  }
212
- /** Glifos do joystick VIRTUAL (toque): sempre o design 'generic' (0/1/2/3), sem mapa custom. */
144
+ /** The glyphs of the VIRTUAL (touch) pad: always the 'generic' design (0/1/2/3), no custom map. */
213
145
  export function touchActionGlyphs() {
214
146
  return padActionGlyphs('generic', null);
215
147
  }
216
148
  /**
217
- * Escolhe QUAL gamepad a legenda descreve: o do Jogador 1, se ele tiver um associado (`players[0].pad`);
218
- * senão o primeiro conectado. Verbatim do laço do game.js — inclusive o detalhe de que, com `p1pad >= 0` e
219
- * nenhum pad daquele índice presente, o resultado é `null` (a legenda cai no teclado) em vez de pegar outro.
149
+ * Chooses WHICH gamepad the legend describes: Player 1's, if they have one (`players[0].pad`); otherwise the first one
150
+ * connected. With `p1pad >= 0` and no pad of that index present, the result is `null` (the legend falls back to the
151
+ * keyboard) rather than picking another.
220
152
  */
221
153
  export function pickLegendPad(pads, p1pad) {
222
154
  let gp = null;
@@ -235,54 +167,57 @@ export function pickLegendPad(pads, p1pad) {
235
167
  return gp;
236
168
  }
237
169
  export function initShell(ctx) {
238
- /* ===================== a legenda do título ===================== */
239
- /** Linha 1+2 quando não há toque nem gamepad: as teclas REALMENTE configuradas do Jogador 1. */
170
+ const { t } = ctx;
171
+ /* ===================== the title legend ===================== */
172
+ /** Rows 1 and 2 when there is neither touch nor a gamepad: Player 1's ACTUALLY configured keys. */
240
173
  function keyboardLegend() {
241
174
  const m = ctx.kbFor(0);
242
175
  const K = (a) => ctx.keyName((m[a] || [])[0] || '?');
243
- const l1 = legendRow1(`${K('up')} ${K('left')} ${K('down')} ${K('right')}`, 'Enter');
244
- const l2 = legendRow2({ action2: [K('action2'), null], action3: [K('action3'), null], action1: [K('action1'), null], action4: [K('action4'), null] }, ctx.rotuloCurto);
176
+ const l1 = legendRow1(t, `${K('up')} ${K('left')} ${K('down')} ${K('right')}`, 'Enter');
177
+ const l2 = legendRow2({ action2: [K('action2'), null], action3: [K('action3'), null], action1: [K('action1'), null], action4: [K('action4'), null] }, ctx.shortLabel);
245
178
  return [l1, l2];
246
179
  }
247
180
  function updateTitleLegend() {
248
181
  const el = ctx.$('#title-legend');
249
182
  if (!el)
250
- return; // 2 LINHAS, com o que está CONFIGURADO p/ o jogador da tela
183
+ return; // 2 ROWS, with what is CONFIGURED for the screen's player
251
184
  let l1, l2;
252
- if (ctx.isTouchMode()) { // joystick VIRTUAL: 0/1/2/3 + START
253
- l1 = legendRow1('✜', 'START');
254
- l2 = legendRow2(touchActionGlyphs(), ctx.rotuloCurto);
185
+ if (ctx.isTouchMode()) { // VIRTUAL pad: 0/1/2/3 + START
186
+ l1 = legendRow1(t, '✜', 'START');
187
+ l2 = legendRow2(touchActionGlyphs(), ctx.shortLabel);
255
188
  }
256
189
  else {
257
190
  const p0 = ctx.getPlayers()[0];
258
191
  const p1pad = p0 && typeof p0.pad === 'number' && p0.pad >= 0 ? p0.pad : -1;
259
192
  const gp = pickLegendPad(ctx.getGamepads(), p1pad);
260
- if (gp) { // joystick FÍSICO: design do modelo + mapa custom do wizard
193
+ if (gp) { // PHYSICAL pad: the model's design + the wizard's custom map
261
194
  const layout = gp.mapping === 'standard' ? ctx.padLayoutFromId(gp.id) : 'generic';
262
195
  const custom = gp.mapping !== 'standard' ? ctx.padMapFor(gp.id) : null;
263
- l1 = legendRow1('✜', 'START');
264
- l2 = legendRow2(padActionGlyphs(layout, custom), ctx.rotuloCurto);
196
+ l1 = legendRow1(t, '✜', 'START');
197
+ l2 = legendRow2(padActionGlyphs(layout, custom), ctx.shortLabel);
265
198
  }
266
199
  else {
267
- [l1, l2] = keyboardLegend(); // TECLADO: teclas configuradas (remap respeitado)
200
+ [l1, l2] = keyboardLegend(); // KEYBOARD: the configured keys (remap honoured)
268
201
  }
269
202
  }
270
203
  el.innerHTML = legendHtml(l1, l2);
271
204
  const w = ctx.$('#title-wait');
272
205
  if (w)
273
- w.hidden = ctx.getNumPlayers() <= 1; // MP: aviso "Aguarde o Jogador 1"
206
+ w.hidden = ctx.getNumPlayers() <= 1; // multiplayer: the «wait for Player 1» notice
274
207
  }
275
- /* ===================== seleção e Print ===================== */
208
+ /* ===================== selection and Print ===================== */
276
209
  function pauseSelect() {
277
210
  ctx.getPauseScreens().forEach((sp) => {
278
- const items = [...sp.querySelectorAll(PM_ITENS_VISIVEIS)];
211
+ const items = [...sp.querySelectorAll(PM_VISIBLE_ITEMS)];
279
212
  items.forEach((b) => b.classList.remove('pm-sel'));
280
- if (items[0])
281
- items[0].classList.add('pm-sel'); // 1º item (Continuar) selecionado em cada tela
213
+ if (items[0]) {
214
+ items[0].classList.add('pm-sel');
215
+ keepInView(items[0]);
216
+ } // the 1st item (Continue), and in view (issue #134)
282
217
  });
283
218
  }
284
219
  function printMode() {
285
- ctx.getPauseScreens().forEach((sp) => { sp.hidden = true; }); // vê a tela limpa; qualquer botão volta
220
+ ctx.getPauseScreens().forEach((sp) => { sp.hidden = true; }); // see the screen clean; any button brings them back
286
221
  const back = (e) => {
287
222
  if (e && e.preventDefault) {
288
223
  try {
@@ -292,41 +227,40 @@ export function initShell(ctx) {
292
227
  }
293
228
  ctx.win.removeEventListener('keydown', back, true);
294
229
  ctx.win.removeEventListener('pointerdown', back, true);
295
- if (ctx.fatosDaCena().menuDePausa) {
230
+ if (ctx.sceneFacts().pauseMenu) {
296
231
  ctx.getPauseScreens().forEach((sp) => { sp.hidden = false; });
297
232
  pauseSelect();
298
233
  }
299
234
  };
300
- // 80ms de atraso: o próprio evento que ACIONOU o Print não pode ser o que o desfaz.
235
+ // An 80 ms delay: the very event that TRIGGERED Print must not be the one that undoes it.
301
236
  ctx.win.setTimeout(() => {
302
237
  ctx.win.addEventListener('keydown', back, true);
303
238
  ctx.win.addEventListener('pointerdown', back, true);
304
239
  }, 80);
305
240
  ctx.srSay(t('sr.print.on'));
306
241
  }
307
- /* ===================== a troca de fase ===================== */
308
- /** A metade IMPURA: pega a projeção pronta e a carimba no documento. */
242
+ /* ===================== the scene change ===================== */
243
+ /** The IMPURE half: takes the ready projection and stamps it on the document. */
309
244
  function applyPhaseView(v) {
310
- // A pausa GLOBAL não é procurada: ela foi aposentada na Etapa 2, e a casca deixou de a segurar em
311
- // 2026-09-08. Ver a nota no `PhaseView`, onde o campo estava.
312
- const t = ctx.$('#title-overlay');
313
- if (t)
314
- t.hidden = v.titleOverlayHidden;
245
+ // There is no global pause overlay to look for — see the note in `PhaseView`.
246
+ const title = ctx.$('#title-overlay');
247
+ if (title)
248
+ title.hidden = v.titleOverlayHidden;
315
249
  ctx.getPauseScreens().forEach((sp) => { sp.hidden = v.screenPauseHidden; });
316
250
  }
317
- /** O estado do `#touch-controls` ANTES de qualquer coisa desta troca de fase mexer nele. */
251
+ /** The state of `#touch-controls` BEFORE anything in this scene change touches it. */
318
252
  function readTouchControls() {
319
253
  const tc = ctx.$('#touch-controls');
320
254
  return tc ? { hidden: tc.hidden, wasOn: tc.dataset.wasOn === '1' } : null;
321
255
  }
322
- /** A metade IMPURA do plano de toque: recebe o estado lido ANTES do hide e grava o plano de volta. */
256
+ /** The IMPURE half of the touch plan: receives the state read BEFORE the hide and writes the plan back. */
323
257
  function applyTouchControls(f, before) {
324
258
  const tc = ctx.$('#touch-controls');
325
259
  if (!tc || !before)
326
260
  return;
327
261
  const after = touchControlsPlan(f, before, ctx.getNumPlayers());
328
- // Só escreve o que MUDOU — é o que torna o applier equivalente linha a linha ao original (que, no ramo
329
- // 'paused' já-escondido, não toca em nada; e cujos `delete` nos outros ramos são no-op quando não havia flag).
262
+ // Writes only what CHANGED: on pause with the pad already hidden nothing is touched, and removing a flag that was
263
+ // never set is not attempted.
330
264
  if (after.hidden !== before.hidden)
331
265
  tc.hidden = after.hidden;
332
266
  if (after.wasOn !== before.wasOn) {
@@ -354,29 +288,26 @@ export function initShell(ctx) {
354
288
  b.focus();
355
289
  }
356
290
  /**
357
- * Projeta a cena do topo no documento. Chamada pela raiz DEPOIS de ela mexer na pilha — a casca não empilha
358
- * nem desempilha, e é essa separação que faz o `Phase` sumir daqui: quem troca de cena sabe os nomes, quem
359
- * projeta só precisa dos três fatos.
291
+ * Projects the scene on top onto the document. Called by the root AFTER it changes the stack — the shell neither pushes
292
+ * nor pops: whoever changes scenes knows their names, whoever projects only needs the three facts.
360
293
  */
361
- function aplicarCena() {
362
- const f = ctx.fatosDaCena();
294
+ function projectScene() {
295
+ const f = ctx.sceneFacts();
363
296
  const v = phaseView(f);
364
- // LER ANTES DE ESCONDER. Era aqui o defeito: `hideTouchControls()` roda logo abaixo e já põe `tc.hidden`
365
- // em true, então o plano — que rodava depois — via o pad como se ele já estivesse desligado, nunca gravava
366
- // o `wasOn`, e o ramo que o traz de volta ao retomar era inalcançável. No celular: pausar sumia com o
367
- // direcional e retomar não o devolvia.
368
- const antesDoHide = readTouchControls();
297
+ // READ BEFORE HIDING: `hideTouchControls()` below already sets `tc.hidden`, and a plan that read after it would see the
298
+ // pad as already off, never record `wasOn`, and never give the d-pad back on resume.
299
+ const touchStateBeforeHiding = readTouchControls();
369
300
  if (v.hideTouchControls)
370
- ctx.hideTouchControls(); // menu ativo (título/pausa) = sem controle virtual
371
- // GAG: na pausa, silencia TODO o som do jogo (loops de ambiente/chuva inclusive) — volta ao retomar.
301
+ ctx.hideTouchControls(); // an active menu (title or pause) = no virtual controller
302
+ // GAG: on pause, ALL the game's sound goes quiet (ambient and rain loops included) — it comes back on resume.
372
303
  ctx.setMasterMuted(v.masterMuted);
373
304
  applyPhaseView(v);
374
- applyTouchControls(f, antesDoHide); // o estado é o de ANTES do hide — ver o comentário acima
375
- // ORDEM verbatim: o aria-pressed vem DEPOIS do bloco de toque.
305
+ applyTouchControls(f, touchStateBeforeHiding); // the state from BEFORE the hide — see above
306
+ // `aria-pressed` comes AFTER the touch block.
376
307
  //
377
- // No TÍTULO o atributo SAI, em vez de virar `false`. Ali o botão significa "iniciar", e `aria-pressed`
378
- // num botão que não alterna nada faz o leitor de tela anunciar um estado que não existe — pior que não
379
- // anunciar nada. `titleOverlayHidden` é verdadeiro fora do título.
308
+ // On the TITLE the attribute is REMOVED rather than set to `false`. There the button means «start», and
309
+ // `aria-pressed` on a button that toggles nothing makes a screen reader announce a state that does not exist — worse
310
+ // than announcing nothing. `titleOverlayHidden` is true outside the title.
380
311
  const pb = ctx.$('#touch-start');
381
312
  if (pb) {
382
313
  if (v.titleOverlayHidden)
@@ -386,18 +317,18 @@ export function initShell(ctx) {
386
317
  }
387
318
  applyFocus(v.focus);
388
319
  }
389
- /* ===================== a tabela do menu de pausa ===================== */
390
- // Ações do menu de pausa (compartilhadas pelos menus por tela). Ao abrir um submenu de a11y, escopa ao
391
- // jogador que agiu (pauseActor) — o diálogo abre na aba dele.
320
+ /* ===================== the pause card's table ===================== */
321
+ // The pause card's actions (shared by the per-screen cards). Opening an accessibility panel scopes it to the player who
322
+ // acted (pauseActor) — the panel opens on their tab.
392
323
  const pauseActs = {
393
- resume: () => ctx.retomarJogo(),
394
- // O botão ABC era um CICLO de duas posições; virou a porta do menu de CAA (ADR-0028), onde a caixa da
395
- // letra é uma escolha entre outras. Ele não sumiu — quem usava o atalho continua a um clique da escolha,
396
- // em vez de ter de descobrir onde ela foi parar. A ação `letra` sumiu junto com o ciclo: um nome por coisa.
397
- caa: () => ctx.openCaa(),
398
- nivel: () => ctx.setQuizLevel(ctx.getQuizLevel() % 5 + 1, true), // L3: cicla 1..5
324
+ resume: () => ctx.resumeGame(),
325
+ // The door to the Augmentative and Alternative Communication menu (ADR-0028). DISABLED while no pictogram set is
326
+ // licensed (ADR-0233 erratum): `ui/pause-icons` locks the `caa` item and `ui/settings-aac`'s `open` refuses, both
327
+ // saying only «menu disabled».
328
+ caa: () => ctx.openAac(),
329
+ nivel: () => ctx.setQuizLevel(ctx.getQuizLevel() % 5 + 1, true), // cycles 1..5
399
330
  tipo: () => ctx.openTypo(),
400
- // R-splash 2: só AUMENTA (nunca diminui); a tela nova ESPERA um botão do jogador entrar
331
+ // Only ever ADDS a player (never removes); the new screen WAITS for its player to press a button
401
332
  addplayer: () => {
402
333
  const n = ctx.getNumPlayers();
403
334
  if (n >= 4) {
@@ -413,11 +344,11 @@ export function initShell(ctx) {
413
344
  const p = ctx.getPlayers()[ctx.getNumPlayers() - 1];
414
345
  p.waiting = true;
415
346
  ctx.showWaitingBadge(p.i);
416
- ctx.retomarJogo();
347
+ ctx.resumeGame();
417
348
  ctx.srAlert(t('sr.player.pressToJoin', { n: p.i + 1 }));
418
349
  },
419
350
  audio: () => ctx.openAudio(),
420
- motora: () => { ctx.setMotorPlayer(ctx.getPauseActor()); ctx.openMovement(); },
351
+ motora: () => { ctx.setMobilityPlayer(ctx.getPauseActor()); ctx.openMovement(); },
421
352
  anim: () => { ctx.setMotionPlayer(ctx.getPauseActor()); ctx.openMotion(); },
422
353
  visual: () => { ctx.setSelVizPlayer(ctx.getPauseActor()); ctx.openVisual(); },
423
354
  empatia: () => { ctx.setSelVizPlayer(ctx.getPauseActor()); ctx.openEmpathy(); },
@@ -425,5 +356,5 @@ export function initShell(ctx) {
425
356
  quit: () => ctx.quitGame(),
426
357
  ajuda: () => ctx.openHelp(),
427
358
  };
428
- return { aplicarCena, pauseSelect, printMode, updateTitleLegend, pauseActs };
359
+ return { applyScene: projectScene, pauseSelect, printMode, updateTitleLegend, pauseActs };
429
360
  }