@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,294 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ /**
3
+ * Builds a menu row: a short label, a hint that goes to the footer, and a control.
4
+ *
5
+ * The row is NOT inserted anywhere — whoever mounts it decides the order, which in this project's menus is part of the
6
+ * decision (ADR-0044 §2).
7
+ */
8
+ export function controlRow(ctx, spec) {
9
+ const rowNode = ctx.create('div');
10
+ rowNode.className = 'ctrl-row';
11
+ const text = ctx.create('span');
12
+ const shortLabel = ctx.create('strong');
13
+ shortLabel.textContent = spec.label;
14
+ text.appendChild(shortLabel);
15
+ if (spec.hint) {
16
+ // ⚠️ ONLY ONE, and it is what `fillExplain` looks for. Two `.opt-hint`s on one row would give the control two
17
+ // descriptions, and the footer would show the first — the other would stay on the row, exactly the defect rule §4
18
+ // exists to prevent.
19
+ const explanation = ctx.create('span');
20
+ explanation.className = 'opt-hint';
21
+ explanation.textContent = spec.hint;
22
+ text.appendChild(explanation);
23
+ }
24
+ rowNode.appendChild(text);
25
+ const control = buildControl(ctx, spec);
26
+ control.id = spec.id;
27
+ control.setAttribute('aria-label', spec.ariaLabel ?? spec.label);
28
+ rowNode.appendChild(control);
29
+ return { row: rowNode, control: control };
30
+ }
31
+ /**
32
+ * REWRITES THE WORDS OF A ROW THAT ALREADY EXISTS — the counterpart of `ui/panel-shell.applyLabels`, one level down.
33
+ *
34
+ * 🔴 The inside of a panel is mounted once, and anything mounted at boot captures the fallback language's text:
35
+ * `initI18n` applies the fallback synchronously and REQUESTS the preferred one, which arrives later — a panel would serve
36
+ * its TITLE in one language and its ROWS in another, on the same screen.
37
+ *
38
+ * ⚠️ AND NO UNIT TEST CATCHES IT, because they all run in a single language.
39
+ *
40
+ * ⚠️ REWRITE AND NOT REBUILD, for the reason `applyLabels` already states: each `ui/settings-*` wires its controls'
41
+ * clicks ONCE, at boot. Remaking the row would leave a control in the document with no listener — a dead button that
42
+ * looks alive (ADR-0106 §5).
43
+ */
44
+ export function labelRow(rowNode, spec) {
45
+ const shortLabel = rowNode.querySelector('strong');
46
+ if (shortLabel)
47
+ shortLabel.textContent = spec.label;
48
+ const explanation = rowNode.querySelector('.opt-hint');
49
+ // ⚠️ A hint that DISAPPEARS has to be erased, not just left unwritten: on a retranslation into a dictionary without
50
+ // the key, the old text would survive and the footer would rest in the previous language.
51
+ if (explanation)
52
+ explanation.textContent = spec.hint ?? '';
53
+ // The control is found by COMPARING its id, not by building a selector from it: a selector needs the id escaped, escaping
54
+ // needs `CSS.escape`, and `CSS` is a browser global that THROWS where it does not exist — it took down a boot in a case's fake
55
+ // document once (2026-09-21). No selector, nothing to escape, no global (ADR-0221 step 7d).
56
+ const control = [...rowNode.querySelectorAll('[id]')].find((el) => el.id === spec.id);
57
+ if (control)
58
+ control.setAttribute('aria-label', spec.ariaLabel ?? spec.label);
59
+ }
60
+ function buildControl(ctx, spec) {
61
+ const controlShape = spec.shape ?? 'interruptor';
62
+ if (controlShape === 'escolha') {
63
+ const s = ctx.create('select');
64
+ s.className = 'vol';
65
+ return s;
66
+ }
67
+ if (controlShape === 'cursor') {
68
+ const i = ctx.create('input');
69
+ i.className = 'vol';
70
+ i.setAttribute('type', 'range');
71
+ // The volume slider's bounds, the same the audio panel reads: 0..100 in steps of 1, converted to the project's
72
+ // 0..1 volume by the panel.
73
+ i.setAttribute('min', '0');
74
+ i.setAttribute('max', '100');
75
+ i.setAttribute('step', '1');
76
+ return i;
77
+ }
78
+ if (controlShape === 'button') {
79
+ /*
80
+ * 🎯 THE ONE SHAPE THAT HOLDS NO VALUE: the others answer "which position am I in", this one DOES something.
81
+ * `ui/settings-controls` demands it — its button opens the capture of a key.
82
+ *
83
+ * 📌 No `aria-pressed` and no `role`: a button that acts already IS a button to whoever listens, and an announced
84
+ * state that does not exist is worse than no state. The panel puts the FACE on it — for remapping, the current
85
+ * keys —, because only the panel knows what the button shows.
86
+ */
87
+ const a = ctx.create('button');
88
+ a.className = 'mode-btn';
89
+ a.setAttribute('type', 'button');
90
+ return a;
91
+ }
92
+ if (controlShape === 'radio') {
93
+ /*
94
+ * 🔴 A CHOICE IS NOT A SWITCH, and the difference is what the ADR-0012 amendment says in so many words: «THE MENU IS
95
+ * A CHOICE, NOT A TOGGLE […] One font is active; the others are alternatives, not switches.» Hence three
96
+ * differences: no `switch` class (which draws a 52×28 px knob, the drawing of a state that does not exist),
97
+ * `role="radio"`, and `aria-checked` instead of `aria-pressed` — independent switches would announce on/off to
98
+ * choose ONE thing.
99
+ *
100
+ * 📌 `ui/settings-typo` demands it. The panel, not the kit, groups the `role="radio"`s in a `role="radiogroup"`,
101
+ * because the panel knows whether exclusivity covers a section or the whole menu.
102
+ */
103
+ const r = ctx.create('button');
104
+ r.className = 'mode-btn';
105
+ r.setAttribute('type', 'button');
106
+ r.setAttribute('role', 'radio');
107
+ r.setAttribute('aria-checked', 'false');
108
+ return r;
109
+ }
110
+ const b = ctx.create('button');
111
+ // `switch` is the class this project's CSS gives switches, and `aria-pressed` is what tells the state to whoever
112
+ // listens. The panel reflects the value; what is born here is the HONEST state of something that has read nothing
113
+ // yet: off.
114
+ b.className = 'mode-btn switch';
115
+ b.setAttribute('type', 'button');
116
+ b.setAttribute('aria-pressed', 'false');
117
+ return b;
118
+ }
119
+ /* ===================== THE SECTION HEADER — whose turn it is to act ===================== */
120
+ /**
121
+ * The header of a panel section: a title and a tag that qualifies it.
122
+ *
123
+ * 📏 It is in the kit because several panels wrote it by hand, with the `.panel-sub__tag` markup copied into each — the
124
+ * same reason as `controlRow`: a rule repeated across files is a rule that drifts.
125
+ *
126
+ * ⚠️ AND IT REFUSES TO EXIST OVER NOTHING, which is the behaviour that makes it worth a function. An "awaiting
127
+ * negotiation" heading with no row under it tells the reader something is there when nothing is, and the person looks
128
+ * for what the title promises. `rows` is the NUMBER of rows the section will have — passing it is what makes this rule
129
+ * exercisable by a case, instead of an `if` no fixed tree reaches.
130
+ *
131
+ * 📌 The title and tag arrive ALREADY TRANSLATED, as in `controlRow`: the kit does not decide language, it builds shape.
132
+ */
133
+ export function sectionHeader(ctx, title, tag, rows) {
134
+ if (rows === 0)
135
+ return null;
136
+ const h = ctx.create('h3');
137
+ h.className = 'panel-sub';
138
+ h.textContent = title + ' ';
139
+ const mark = ctx.create('span');
140
+ mark.className = 'panel-sub__tag';
141
+ mark.textContent = tag;
142
+ h.appendChild(mark);
143
+ return h;
144
+ }
145
+ /**
146
+ * The next step, CLAMPED at the ends — not a ring, and the difference is the decision.
147
+ *
148
+ * ⚠️ In a ring, right from the largest position would return to off: whoever adjusts looking for the maximum would pass
149
+ * it without warning and switch off what they wanted to raise. Clamped, the end is a wall you feel — the number of
150
+ * players, the model the Dev gave, does not wrap either.
151
+ */
152
+ export function nextStep(from, total, delta) {
153
+ if (total <= 0)
154
+ return 0;
155
+ return Math.max(0, Math.min(total - 1, from + Math.sign(delta)));
156
+ }
157
+ /**
158
+ * Builds the control: ONE focusable element (`role="spinbutton"`) with the two arrows inside.
159
+ *
160
+ * ⚠️ THE ARROWS ARE NOT BUTTONS, on purpose: menu navigation treats every `button` as an item, and three items for one
161
+ * adjustment would make the cursor stop twice on nameless arrows. Focus belongs to the control; the arrows are FINGER
162
+ * targets (`data-passo`), outside the accessibility tree — whoever listens gets the `aria-valuetext`.
163
+ *
164
+ * The control emits `passo` (`CustomEvent<number>`, -1 or +1): a tapped arrow emits it from here, and the keyboard's and
165
+ * controller's left and right emit it through `ui/menu-nav`. The user listens to a single event.
166
+ */
167
+ export function mountSteps(ctx, spec) {
168
+ const el = ctx.create('div');
169
+ el.className = 'passos';
170
+ el.setAttribute('role', 'spinbutton');
171
+ el.setAttribute('tabindex', '0');
172
+ el.setAttribute('data-passos', '');
173
+ const arrow = (delta, glyph) => {
174
+ const s = ctx.create('span');
175
+ s.className = 'passo-seta';
176
+ s.setAttribute('data-passo', String(delta));
177
+ s.setAttribute('aria-hidden', 'true');
178
+ s.textContent = glyph;
179
+ s.addEventListener('click', () => el.dispatchEvent(new CustomEvent('passo', { detail: delta, bubbles: true })));
180
+ return s;
181
+ };
182
+ const value = ctx.create('span');
183
+ value.className = 'passo-valor';
184
+ el.appendChild(arrow(-1, '◀'));
185
+ el.appendChild(value);
186
+ el.appendChild(arrow(1, '▶'));
187
+ updateSteps(el, spec);
188
+ return el;
189
+ }
190
+ /* ===================== ONE EXCLUSIVE CHOICE, DRAWN BY ITS SIZE (ADR-0130 rule 3 and erratum) ===================== */
191
+ /**
192
+ * How many positions still CYCLE. The Dev's number (ADR-0130 erratum, 2026-09-12): «Acima de cinco itens deve ser dropdown».
193
+ * Five or fewer are one row «◀ Label: value ▶» — every position is one step away and the row always says where it is;
194
+ * more than five, a dropdown, because a cycle that long is walked more than it is chosen.
195
+ */
196
+ export const MAX_CYCLE_POSITIONS = 5;
197
+ /**
198
+ * Builds the control for ONE EXCLUSIVE CHOICE, and its SIZE picks the control, not the panel's author (ADR-0130 rule 3):
199
+ * up to `MAX_CYCLE_POSITIONS` a steps control (`mountSteps`), more a `<select>`. A choice whose size depends on the moment —
200
+ * the game's named positions, the audio outputs plugged in — takes the control its size asks for NOW, drawn again when it
201
+ * changes.
202
+ *
203
+ * Both shapes answer the same way, so whoever builds a row does not branch: `pick(value)` runs when the child chooses, the
204
+ * value in use is in `data-value`, and a bubbling `change` follows the pick — a list that listens for `change` hears either.
205
+ * A value not among the positions shows the first, as a `<select>` does.
206
+ */
207
+ export function mountChoice(ctx, spec, pick) {
208
+ if (spec.values.length <= MAX_CYCLE_POSITIONS) {
209
+ const steps = mountSteps(ctx, stepsOf(spec));
210
+ writeCycle(steps, spec);
211
+ steps.addEventListener('passo', (ev) => {
212
+ // read back from the element, never from this closure: an `updateChoice` since may have brought other words
213
+ const live = readCycle(steps);
214
+ const from = indexOfValue(live);
215
+ const to = nextStep(from, live.values.length, ev.detail);
216
+ if (to === from)
217
+ return; // at the wall nothing moved, and nothing is picked
218
+ const value = live.values[to].value;
219
+ writeCycle(steps, { ...live, current: value });
220
+ pick(value);
221
+ steps.dispatchEvent(new Event('change', { bubbles: true }));
222
+ });
223
+ return steps;
224
+ }
225
+ const list = ctx.create('select');
226
+ list.className = 'vol';
227
+ fillList(list, spec);
228
+ list.addEventListener('change', () => { list.dataset.value = list.value; pick(list.value); });
229
+ return list;
230
+ }
231
+ /** Where the current value sits among the positions; one not among them shows the first, as a `<select>` does. */
232
+ const indexOfValue = (s) => Math.max(0, s.values.findIndex((v) => v.value === s.current));
233
+ const stepsOf = (s) => ({ label: s.label, values: s.values.map((v) => v.label), current: indexOfValue(s) });
234
+ /**
235
+ * A cycle row keeps its whole choice ON THE ELEMENT — the positions in `data-positions`, the value in `data-value`, the
236
+ * name in `aria-label` — so the control carries no state of its own that a redraw could leave behind.
237
+ */
238
+ function writeCycle(el, s) {
239
+ el.dataset.positions = JSON.stringify(s.values);
240
+ el.dataset.value = s.current;
241
+ updateSteps(el, stepsOf(s));
242
+ }
243
+ function readCycle(el) {
244
+ return {
245
+ label: el.getAttribute('aria-label') ?? '',
246
+ values: JSON.parse(el.dataset.positions ?? '[]'),
247
+ current: el.dataset.value ?? '',
248
+ };
249
+ }
250
+ function fillList(list, s) {
251
+ // a `<select>` whose label is a sibling is announced as «combo box» and nothing else without its own name
252
+ list.setAttribute('aria-label', s.label);
253
+ while (list.firstChild)
254
+ list.removeChild(list.firstChild);
255
+ for (const v of s.values) {
256
+ const option = list.ownerDocument.createElement('option');
257
+ option.value = v.value;
258
+ option.textContent = v.label; // text, never markup: a game's word goes through here
259
+ list.appendChild(option);
260
+ }
261
+ list.value = s.current;
262
+ list.dataset.value = list.value;
263
+ }
264
+ /**
265
+ * REWRITES a choice built by `mountChoice`: its name, its positions' words and the value in use — the redraw a panel does
266
+ * on every open, after a language change or when the value moved elsewhere. The SHAPE stays: a choice whose size can
267
+ * cross five is built again, not updated.
268
+ */
269
+ export function updateChoice(el, spec) {
270
+ if (el.tagName === 'SELECT')
271
+ fillList(el, spec);
272
+ // read by the attribute `writeCycle` always writes, and not by `hasAttribute`: a host's minimal document may lack it
273
+ else if (el.dataset?.positions !== undefined)
274
+ writeCycle(el, spec);
275
+ }
276
+ /** Reflects the current position: the written value, what is heard, and the ends that no longer move. */
277
+ export function updateSteps(el, spec) {
278
+ const lastIndex = Math.max(0, spec.values.length - 1);
279
+ const from = Math.max(0, Math.min(lastIndex, spec.current));
280
+ const text = spec.values[from] ?? '';
281
+ el.setAttribute('aria-label', spec.label);
282
+ el.setAttribute('aria-valuemin', '0');
283
+ el.setAttribute('aria-valuemax', String(lastIndex));
284
+ el.setAttribute('aria-valuenow', String(from));
285
+ el.setAttribute('aria-valuetext', text);
286
+ const value = el.querySelector('.passo-valor');
287
+ // THE LABEL GOES INTO THE TEXT: the whole row is the control, «◀ Cantos arredondados: pequeno ▶». Whoever listens gets
288
+ // the same in two parts — the name in `aria-label` and the position in `aria-valuetext` —, without the name repeated.
289
+ if (value)
290
+ value.textContent = spec.label ? `${spec.label}: ${text}` : text;
291
+ // The end that no longer moves is marked — otherwise a wall's arrow looks like a broken button.
292
+ el.querySelector('[data-passo="-1"]')?.classList.toggle('no-limite', from === 0);
293
+ el.querySelector('[data-passo="1"]')?.classList.toggle('no-limite', from === lastIndex);
294
+ }
@@ -0,0 +1,35 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ /** One row of the per-screen pause menu. `letra` marks the label that ABC/abc rewrites live. */
3
+ export interface PauseBtnDef {
4
+ readonly act: string;
5
+ /**
6
+ * RAW label, used only when the button has a dynamic label (`dynamicLabel`/`level`).
7
+ *
8
+ * Optional because `pmBtnMarkup` resolves every ordinary button through `t('pause.' + act)`, so text here would
9
+ * never reach a screen — it would be raw text inside an ENGINE module, waiting for someone to trust it. No entry
10
+ * today sets a dynamic label; the `pause.*` key is the source, and it exists in all three languages.
11
+ */
12
+ readonly lbl?: string;
13
+ readonly dynamicLabel?: boolean;
14
+ readonly level?: boolean;
15
+ }
16
+ /** The pause menu's items — MENU DATA, so it lives with the other menu tables. The pause slice (ui/pause-icons)
17
+ * receives it through its own ctx instead of re-declaring it; nobody owns two copies of a list of buttons. */
18
+ export declare const PM_BTNS: readonly PauseBtnDef[];
19
+ /**
20
+ * THE THIRD LIST: what belongs to THIS game (ADR-0146, ADR-0145).
21
+ *
22
+ * ⚠️ IT STARTS WITH THE BACK ITEM AND NOTHING ELSE, and the emptiness is the decision: the engine does not know what a
23
+ * game has of its own — the game declares it. A list the engine filled in would be the wheelchair in chess again.
24
+ *
25
+ * 📌 And that is why the door drops by itself: `rootThatActs` drops a door whose room is empty, and with this list
26
+ * reduced to `pmback` that is exactly the case of a game that declares nothing.
27
+ */
28
+ export declare const PM_GAME_BTNS: readonly PauseBtnDef[];
29
+ /**
30
+ * THE INCLUSION SETTINGS SUBMENU — the panels, in the order the Dev dictated (ADR-0151).
31
+ *
32
+ * The way out comes FIRST here too, for the same reason `resume` comes first there: ADR-0044's rule is about menus,
33
+ * not about one menu. A submenu you cannot leave is the same trap, one level down.
34
+ */
35
+ export declare const PM_OPTIONS_BTNS: readonly PauseBtnDef[];
@@ -0,0 +1,66 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // ui/pause-buttons — the items of the pause card the engine mounts: root, the game's options and the inclusion settings.
3
+ //
4
+ // Menu data for `ui/pause-icons`. They lived in `ui/activities-menu`, the platformer's title menu, which left the engine
5
+ // (ADR-0174, issue #171); the card is the engine's, so its buttons stay.
6
+ /** The pause menu's items — MENU DATA, so it lives with the other menu tables. The pause slice (ui/pause-icons)
7
+ * receives it through its own ctx instead of re-declaring it; nobody owns two copies of a list of buttons. */
8
+ export const PM_BTNS = [
9
+ // ===================== THE ORDER IS THE DECISION (ADR-0044 §2) =====================
10
+ // A menu you cannot leave is a trap, and the trap costs most to whoever cannot see it. `resume` comes FIRST because
11
+ // that is what a pause is for. `quit` comes LAST because it is its least wanted outcome — and, since the list is a
12
+ // RING, one key UP from `resume` reaches it: far in reading order, near to the finger.
13
+ //
14
+ // The settings panels live in `PM_OPTIONS_BTNS`.
15
+ //
16
+ // 🔴 SIX (ADR-0151), and the number is MEASURED, not taste: at 640×360, the target screen, seven items fit exactly
17
+ // and more overflow, while the target ruler is already at its floor (ADR-0095: «tela menor mostra menos itens, não
18
+ // alvos menores»).
19
+ //
20
+ // 📌 The accessibility bar and the print view are reached through SELECT — «basta apertar SELECT que se tem a visão
21
+ // apropriada pra print», in the Dev's words. Their `act`s still exist and work for whoever passes a list of their own.
22
+ { act: 'resume' },
23
+ // Help — how to play comes SECOND: it is the first thing someone who paused without knowing how to play looks for.
24
+ { act: 'ajuda' },
25
+ // ⚠️ The `act` stays `addplayer` and the LABEL is the number of players (ADR-0147 §3): `ui/shell.ts` implements
26
+ // `pauseActs.addplayer`, and cases in `shell.browser.test.js` call it.
27
+ { act: 'addplayer' },
28
+ // Inclusion settings: what the child CARRIES between games (ADR-0146, named by ADR-0151).
29
+ { act: 'options' },
30
+ // Game options: what belongs to THIS game. The door drops by itself when the game declares nothing of its own.
31
+ { act: 'opcoesdojogo' },
32
+ { act: 'quit' },
33
+ ];
34
+ /**
35
+ * THE THIRD LIST: what belongs to THIS game (ADR-0146, ADR-0145).
36
+ *
37
+ * ⚠️ IT STARTS WITH THE BACK ITEM AND NOTHING ELSE, and the emptiness is the decision: the engine does not know what a
38
+ * game has of its own — the game declares it. A list the engine filled in would be the wheelchair in chess again.
39
+ *
40
+ * 📌 And that is why the door drops by itself: `rootThatActs` drops a door whose room is empty, and with this list
41
+ * reduced to `pmback` that is exactly the case of a game that declares nothing.
42
+ */
43
+ export const PM_GAME_BTNS = [
44
+ { act: 'pmback' },
45
+ ];
46
+ /**
47
+ * THE INCLUSION SETTINGS SUBMENU — the panels, in the order the Dev dictated (ADR-0151).
48
+ *
49
+ * The way out comes FIRST here too, for the same reason `resume` comes first there: ADR-0044's rule is about menus,
50
+ * not about one menu. A submenu you cannot leave is the same trap, one level down.
51
+ */
52
+ export const PM_OPTIONS_BTNS = [
53
+ // 📌 Not here, and each has somewhere to go (ADR-0151): letter case walks the communication cycle of the bar's
54
+ // eleventh button, and typography — «quem escolhe a tipografia é o jogo, o jogador escolhe suas fontes via o menu de
55
+ // acessibilidade rápida».
56
+ // 📏 AND THE NUMBER IS WHAT FITS at 640×360; the submenu has its own case in the 44 px gate, not only the root.
57
+ // ✅ The audio panel (music, ambience, interaction, earcons), separate from hearing accessibility, is listed because
58
+ // the panel it opens exists — a door to a panel that does not exist would be ADR-0106 §5's dead button.
59
+ { act: 'pmback' },
60
+ { act: 'empatia' },
61
+ { act: 'audio' },
62
+ { act: 'som' },
63
+ { act: 'motora' },
64
+ { act: 'visual' },
65
+ { act: 'anim' },
66
+ ];