@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,59 +1,68 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
- // platform/audio-earcons — earcons (ícones sonoros) do jogo + a ponte com as LEGENDAS visuais (a11y surdez).
3
- // Tier 2 do áudio, rodada 2. Depende das primitivas de platform/audio (SFX/ensureAC/catNode/audioOut/noiseHit) e,
4
- // por injeção, do estado de legenda que VIVE no game.js (captionsOn é alternado pela UI; showCaption toca o #caption
5
- // e é reusado por win()). Injeção por closure (padrão Tier 1).
6
- // sfx(name) — toca o earcon da tabela SFX (oscilador) E, se as legendas estão ON e o earcon tem `.cap`, mostra a
7
- // legenda ANTES de checar o som → um jogador surdo "vê" o som mesmo com o áudio desligado.
8
- // doorSound(mat) — porta: rangido (madeira, sawtooth) ou clangor (ferro, square) + baque de ruído (noiseHit).
9
- // Extraído do game.js. Ver docs/5-Refactoring/plano-modularizacao-mapa.md (Tier 2, áudio rodada 2).
10
- import { t } from '../core/i18n.js'; // item 19: `cap` guarda CHAVE, e quem exibe resolve
2
+ // platform/audio-earcons — a game's earcons (sound icons) + the bridge to the visual CAPTIONS (deaf accessibility).
3
+ // It depends on platform/audio's primitives and, by injection, on the host's caption state. Injection by closure.
4
+ // sfx(name) — plays the earcon from the table (an oscillator) AND, when captions are ON and the earcon has a `.cap`,
5
+ // shows the caption BEFORE checking the sound → a deaf player "sees" the sound even with audio off.
6
+ // doorSound(mat) — a door: a creak (wood, sawtooth) or a clang (iron, square) + a noise thud (noiseHit).
11
7
  export function createAudioEarcons(ctx) {
8
+ const { t } = ctx;
9
+ /** Whether a sound may play at all: the game's sound on, and a volume above zero. */
10
+ const audible = () => ctx.getSoundOn() && ctx.getVolume() > 0;
11
+ /** A category's bus; without one, the master; without that, the device itself. */
12
+ const busFor = (cat, ac) => ctx.catNode(cat) || ctx.audioOut() || ac.destination;
12
13
  function sfx(name) {
13
14
  const c = ctx.SFX[name];
14
15
  if (!c)
15
16
  return;
16
- // LEGENDA primeiro (visual + aria-live via role=status) — e RESOLVIDA no ponto de uso: `cap` guarda a
17
- // CHAVE desde o item 19, porque a tabela vive no jogo e uma tabela de `const` com texto congelaria no
18
- // idioma do boot. Quem exibe resolve; é a mesma regra de `render/viz-modes`.
17
+ // The CAPTION first (visual + aria-live through role=status) — and RESOLVED where it is used: `cap` holds the KEY,
18
+ // because the table lives in the game and a `const` table of text would freeze in the boot's language.
19
19
  if (ctx.getCaptionsOn() && c.cap)
20
20
  ctx.showCaption(t(c.cap));
21
- if (!ctx.getSoundOn() || ctx.getVolume() <= 0)
22
- return; // ...só então o som — surdez: a legenda já saiu
21
+ if (!audible())
22
+ return; // ...only then the sound — for a deaf player the caption is already out
23
23
  try {
24
- const ac = ctx.ensureAC();
25
- if (!ac)
26
- return;
27
- const o = ac.createOscillator(), g = ac.createGain();
28
- o.type = c.t;
29
- o.frequency.value = c.f;
30
- g.gain.value = 0.0001;
31
- o.connect(g).connect(ctx.catNode('earcons') || ctx.audioOut() || ac.destination);
32
- const t = ac.currentTime, vol = ctx.getVolume();
33
- // A FIGURA, quando a tabela pede uma (#124). `setValueAtTime` antes da rampa como no `doorSound`: sem
34
- // ele o ponto de partida da curva fica por conta da implementação, e o glissando começa onde calhar.
35
- //
36
- // ⚠️ AS DUAS GUARDAS SÃO NECESSÁRIAS E NÃO ZELO. `exponentialRampToValueAtTime` LANÇA com alvo zero ou
37
- // negativo — uma tabela com `f2: 0` mataria o earcon inteiro pelo `catch`, em silêncio. E `f2 === f`
38
- // não é rampa nenhuma: pedi-la ao navegador seria trabalho para produzir a nota parada que já havia.
39
- if (typeof c.f2 === 'number' && c.f2 > 0 && c.f2 !== c.f) {
40
- o.frequency.setValueAtTime(c.f, t);
41
- o.frequency.exponentialRampToValueAtTime(c.f2, t + c.d);
42
- }
43
- g.gain.exponentialRampToValueAtTime(Math.max(0.02, 0.25 * vol), t + 0.01);
44
- g.gain.exponentialRampToValueAtTime(0.0001, t + c.d);
45
- o.start(t);
46
- o.stop(t + c.d + 0.02);
24
+ play(c);
47
25
  }
48
- catch (e) { /* Web Audio indisponível */ }
26
+ catch (e) { /* no Web Audio */ }
27
+ }
28
+ /** One earcon: its timbre, its figure when the table asks for one, a peak that follows the master volume, and its length. */
29
+ function play(c) {
30
+ const ac = ctx.ensureAC();
31
+ if (!ac)
32
+ return;
33
+ const o = ac.createOscillator(), g = ac.createGain();
34
+ o.type = c.t;
35
+ o.frequency.value = c.f;
36
+ g.gain.value = 0.0001;
37
+ o.connect(g).connect(busFor('earcons', ac));
38
+ const now = ac.currentTime, vol = ctx.getVolume();
39
+ glide(o, c, now);
40
+ g.gain.exponentialRampToValueAtTime(Math.max(0.02, 0.25 * vol), now + 0.01);
41
+ g.gain.exponentialRampToValueAtTime(0.0001, now + c.d);
42
+ o.start(now);
43
+ o.stop(now + c.d + 0.02);
44
+ }
45
+ /**
46
+ * THE FIGURE, when the table asks for one (#124). `setValueAtTime` before the ramp as in `doorSound`: without it the
47
+ * curve's starting point is up to the implementation, and the glissando starts wherever it happens to.
48
+ *
49
+ * ⚠️ THE TWO GUARDS ARE NEEDED, NOT FUSSINESS. `exponentialRampToValueAtTime` THROWS on a zero or negative target — a
50
+ * table with `f2: 0` would kill the whole earcon through the `catch`, in silence. And `f2 === f` is no ramp at all:
51
+ * asking the browser for it would be work to produce the held note that was already there.
52
+ */
53
+ function glide(o, c, now) {
54
+ if (typeof c.f2 !== 'number' || c.f2 <= 0 || c.f2 === c.f)
55
+ return;
56
+ o.frequency.setValueAtTime(c.f, now);
57
+ o.frequency.exponentialRampToValueAtTime(c.f2, now + c.d);
49
58
  }
50
59
  function doorSound(mat) {
51
- if (!ctx.getSoundOn() || ctx.getVolume() <= 0)
60
+ if (!audible())
52
61
  return;
53
62
  const ac = ctx.ensureAC();
54
63
  if (!ac)
55
64
  return;
56
- try { // porta: rangido (madeira) ou clangor (ferro) + baque
65
+ try { // a door: a creak (wood) or a clang (iron) + a thud
57
66
  const o = ac.createOscillator(), g = ac.createGain(), t = ac.currentTime, vol = ctx.getVolume();
58
67
  o.type = mat === 'ferro' ? 'square' : 'sawtooth';
59
68
  o.frequency.setValueAtTime(mat === 'ferro' ? 520 : 200, t);
@@ -61,12 +70,12 @@ export function createAudioEarcons(ctx) {
61
70
  g.gain.setValueAtTime(0.0001, t);
62
71
  g.gain.exponentialRampToValueAtTime(0.14 * vol, t + 0.03);
63
72
  g.gain.exponentialRampToValueAtTime(0.0001, t + 0.35);
64
- o.connect(g).connect(ctx.catNode('interact') || ctx.audioOut() || ac.destination);
73
+ o.connect(g).connect(busFor('interact', ac));
65
74
  o.start(t);
66
75
  o.stop(t + 0.4);
67
76
  ctx.noiseHit(mat === 'ferro' ? 'ferro' : 'madeira');
68
77
  }
69
- catch (e) { /* Web Audio indisponível */ }
78
+ catch (e) { /* no Web Audio */ }
70
79
  }
71
80
  return { sfx, doorSound };
72
81
  }
@@ -1,13 +1,12 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
- // platform/audio-jingles — recompensas sonoras (jingles) SEM estado de jogo: vitória, enigma resolvido e fogos.
3
- // Primeiro passo do Tier 2 (áudio): o cluster mais puro — só depende das primitivas de platform/audio (tone/ensureAC/
4
- // catNode/audioOut) + soundOn/volume vivos. Sem tiles, players, coins nem DOM. Injeção por closure (padrão Tier 1).
5
- // playVictory — jingle 8-bit ascendente (C5 E5 G5 C6 B5 E6) + 4 fogos de artifício.
6
- // playPuzzleSolved — frase DOCE senoidal ascendente (E5 G5 B5 E6 + C6 de fundo), Zelda OoT; NUNCA agressiva (José).
7
- // firework — assobio subindo (sine 300→1200 Hz) + estouro/crepitar (5 osciladores square); usado por playVictory.
8
- // Extraído do game.js (linhas 625-633). Ver docs/5-Refactoring/plano-modularizacao-mapa.md (Tier 2, áudio rodada 1).
2
+ // platform/audio-jingles — sound rewards (jingles) with NO game state: victory, puzzle solved and fireworks.
3
+ // It depends only on the primitives of platform/audio (tone/ensureAC/catNode/audioOut) plus the live soundOn/volume — no
4
+ // tiles, players, coins or DOM. Injection by closure.
5
+ // playVictory — a rising 8-bit jingle (C5 E5 G5 C6 B5 E6) + 4 fireworks.
6
+ // playPuzzleSolved — a SWEET rising sine phrase (E5 G5 B5 E6 over a C6), Zelda OoT; NEVER aggressive (the Dev's call).
7
+ // firework — a rising whistle (sine 300→1200 Hz) + burst/crackle (5 square oscillators); used by playVictory.
9
8
  export function createAudioJingles(ctx) {
10
- // Fogos: só osciladores crus (não usam `tone`), então guardam soundOn/volume aqui e escalam o ganho pelo volume.
9
+ // Fireworks: raw oscillators only (no `tone`), so they check soundOn/volume here and scale the gain by the volume.
11
10
  function firework(when) {
12
11
  if (!ctx.getSoundOn() || ctx.getVolume() <= 0)
13
12
  return;
@@ -19,7 +18,7 @@ export function createAudioJingles(ctx) {
19
18
  const o = ac.createOscillator(), g = ac.createGain();
20
19
  o.type = 'sine';
21
20
  o.frequency.setValueAtTime(300, t);
22
- o.frequency.exponentialRampToValueAtTime(1200, t + 0.35); // assobio subindo
21
+ o.frequency.exponentialRampToValueAtTime(1200, t + 0.35); // rising whistle
23
22
  const out = ctx.catNode('earcons') || ctx.audioOut() || ac.destination;
24
23
  g.gain.setValueAtTime(0.0001, t);
25
24
  g.gain.exponentialRampToValueAtTime(0.12 * vol, t + 0.05);
@@ -38,7 +37,7 @@ export function createAudioJingles(ctx) {
38
37
  po.stop(tt + 0.11);
39
38
  });
40
39
  }
41
- catch (e) { /* Web Audio indisponível */ }
40
+ catch (e) { /* no Web Audio */ }
42
41
  }
43
42
  function playVictory() {
44
43
  [[523, 0], [659, 0.12], [784, 0.24], [1047, 0.36], [988, 0.52], [1319, 0.64]]
@@ -1,4 +1,5 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ import type { Store } from './storage.js';
2
3
  type AudioCat = {
3
4
  k: string;
4
5
  lbl: string;
@@ -7,8 +8,19 @@ type AudioCatState = {
7
8
  on: boolean;
8
9
  vol: number;
9
10
  };
11
+ /** What the mixer is read and written through: the page's store, built by the root (ADR-0232, issue #207). */
12
+ export type AudioCatStore = Pick<Store, 'getJSON' | 'setJSON'>;
10
13
  export declare const AUDIO_CATS: AudioCat[];
14
+ /**
15
+ * A category's FACTORY state. It has a name because two places need it: the boot's read (when nothing is stored) and
16
+ * the hearing menu's "restore defaults" (ADR-0028). Writing `k !== 'tts'` and `0.8` in both would be the ownerless copy
17
+ * this repository has seen diverge — and here the divergence would put the child in a third state, neither theirs nor
18
+ * the factory's.
19
+ *
20
+ * What is STORED overrides it, deliberately: a stored value means someone MOVED that control, and the child's choice is
21
+ * not mine to undo.
22
+ */
11
23
  export declare function defaultAudioCat(k: string): AudioCatState;
12
- export declare function loadAudioCat(): Record<string, AudioCatState>;
13
- export declare function saveAudioCat(k: string, obj: AudioCatState): void;
24
+ export declare function loadAudioCat(store: AudioCatStore): Record<string, AudioCatState>;
25
+ export declare function saveAudioCat(store: AudioCatStore, k: string, obj: AudioCatState): void;
14
26
  export {};
@@ -1,51 +1,43 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
- // platform/audio-mixer.ts — categorias do mixer de áudio (dados) + carga/persistência. Módulo-folha (storage).
3
- // O grafo de áudio (catNode/setCatGain/_catNodes/audioCtx) e o objeto audioCat VIVO ficam no game.js — aqui só
4
- // a lista das categorias, o estado inicial (com o default TTS-off) e o save por categoria. (Fase 2, áudio)
5
- import * as store from './storage.js';
2
+ // 🔴 There is no `other` category (ADR-0151, erratum): «O que esta categoria controla? Nada. Então pra que?» (the Dev).
3
+ // 📏 Measured: no sound was routed through it — a volume with nothing underneath, the dead button of ADR-0106 §5.
4
+ // 🔴 `lbl` is an i18n KEY since 2026-09-12 (ADR-0158). The labels were raw Portuguese with examples in parentheses —
5
+ // «Sons ambiente (água, rua, trânsito, folhas, chuva)» — and a page in English showed them as they were (measured in
6
+ // dist). ⚠️ The examples are GONE, not moved to a hint: water, doors, coins are one game's sounds, and the engine does
7
+ // not describe a game it does not know (the Dev: «Não se faz abstração sem precisar»).
6
8
  export const AUDIO_CATS = [
7
- { k: 'music', lbl: 'Música' }, { k: 'ambient', lbl: 'Sons ambiente (água, rua, trânsito, folhas, chuva)' },
8
- { k: 'interact', lbl: 'Efeitos de interação (passos, portas, escada)' }, { k: 'earcons', lbl: 'Earcons (pulo, moeda, dano…)' },
9
- { k: 'other', lbl: 'Outros efeitos' }, { k: 'tts', lbl: 'Narração (TTS)' }, { k: 'sonar', lbl: 'Sonar' },
10
- { k: 'guard', lbl: 'Guarda de beirada' }, { k: 'guide', lbl: 'Pista / guia auditivo' },
9
+ { k: 'music', lbl: 'audio.cat.music' },
10
+ { k: 'ambient', lbl: 'audio.cat.ambient' },
11
+ { k: 'interact', lbl: 'audio.cat.interact' },
12
+ { k: 'earcons', lbl: 'audio.cat.earcons' },
13
+ { k: 'tts', lbl: 'audio.cat.tts' },
14
+ { k: 'sonar', lbl: 'audio.cat.sonar' },
15
+ // 🔴 `guard` and `guide` LEFT (ADR-0258, the Dev: «Saem.»): the engine plays nothing in either since the guide moved to the
16
+ // platformer (ADR-0257); a level stored for them stays in the child's storage and is read by nobody.
11
17
  ];
12
- // Estado inicial por categoria. O que estiver SALVO sobrepõe o default — e isso é deliberado: um valor salvo
13
- // significa que alguém MEXEU naquele controle, e a escolha da criança não é minha para desfazer. Quem já
14
- // tinha ligado o guia continua com ele ligado.
15
18
  /**
16
- * O estado de FÁBRICA de uma categoria. Existe com nome porque dois lugares precisam dele: a leitura do boot
17
- * (quando nada foi salvo) e o "restaurar padrões" do menu auditivo (ADR-0028). Escrever `k !== 'tts'` e `0.8`
18
- * nos dois seria a mesma cópia sem dono que este repositório já viu divergir — e aqui a divergência colocaria
19
- * a criança num terceiro estado, nem o dela nem o de fábrica.
20
- */
21
- /**
22
- * As categorias que nascem DESLIGADAS, e o motivo de cada uma. Lista com razão escrita, e não um `k !== 'x'`
23
- * pendurado numa expressão — a próxima que entrar precisa dizer por quê.
24
- *
25
- * · `tts` — voz robótica irrita e sobrecarrega pessoas com TEA. Quem precisa liga no menu. (O TTS do
26
- * letramento é o `gameSay()`, independente disto e sempre ativo.)
19
+ * The categories born OFF, and the reason for each. A list with its reason written down, not a `k !== 'x'` hanging in an
20
+ * expression — the next one to join has to say why.
27
21
  *
28
- * · `guide` — o BEACON do guia auditivo, DESLIGADO desde 2026-08-26 por decisão do Dev, e é uma medida
29
- * PROVISÓRIA que não deve virar permanente sem alguém a rever.
22
+ * · `tts` — a robotic voice irritates and overloads autistic people. Whoever needs it turns it on in the menu. (The
23
+ * literacy voice is `gameSay()`, independent of this and always on.)
30
24
  *
31
- * O que ele faz hoje: um `triangle` de 0,12 s apontado para o alvo mais próximo, a cada 0,8 s, PARA
32
- * SEMPRE — sem depender de movimento, de tecla ou de nada ter mudado. No modo cego `needsAudioCues` é
33
- * sempre verdadeiro, então a criança que mais precisa de pistas é a que ouve o bipe a partida inteira.
34
- *
35
- * O veredito do Dev: "um ping é a pior escolha possível, tenebroso para quem tem TEA". Não é a FREQUÊNCIA
36
- * que está errada — é o bipe. Reduzi-lo a "só andando" deixaria a mesma coisa doendo menos vezes.
25
+ * (`guide`, born off by the Dev's decision on the old beacon, left with its category — ADR-0258.)
26
+ */
27
+ const BORN_OFF = new Set(['tts']);
28
+ /**
29
+ * A category's FACTORY state. It has a name because two places need it: the boot's read (when nothing is stored) and
30
+ * the hearing menu's "restore defaults" (ADR-0028). Writing `k !== 'tts'` and `0.8` in both would be the ownerless copy
31
+ * this repository has seen diverge — and here the divergence would put the child in a third state, neither theirs nor
32
+ * the factory's.
37
33
  *
38
- * O substituto que ele descreveu é maior que uma troca de som e por isso não entra junto: uma música que
39
- * fica mais intensa conforme se aproxima, e ANTES dela é preciso MAPEAR A ROTA — preencher o mapa com as
40
- * direções por onde há ar ou água, para que a pista siga um caminho navegável em vez de apontar em linha
41
- * reta para dentro de uma parede. Está registrado como issue; até ela existir, o silêncio é melhor que o
42
- * bipe, e a criança que quiser o bipe continua podendo ligá-lo no menu auditivo.
34
+ * What is STORED overrides it, deliberately: a stored value means someone MOVED that control, and the child's choice is
35
+ * not mine to undo.
43
36
  */
44
- const NASCEM_DESLIGADAS = new Set(['tts', 'guide']);
45
37
  export function defaultAudioCat(k) {
46
- return { on: !NASCEM_DESLIGADAS.has(k), vol: 0.8 };
38
+ return { on: !BORN_OFF.has(k), vol: 0.8 };
47
39
  }
48
- export function loadAudioCat() {
40
+ export function loadAudioCat(store) {
49
41
  const cat = {};
50
42
  AUDIO_CATS.forEach((c) => {
51
43
  const d = defaultAudioCat(c.k);
@@ -59,4 +51,4 @@ export function loadAudioCat() {
59
51
  });
60
52
  return cat;
61
53
  }
62
- export function saveAudioCat(k, obj) { store.setJSON('incl_audiocat_' + k, obj); }
54
+ export function saveAudioCat(store, k, obj) { store.setJSON('incl_audiocat_' + k, obj); }
@@ -1,31 +1,31 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
- import { type Spot, type Topology, type Speakable, type Role } from '../core/contract.js';
2
+ import { type Spot, type Topology, type Speakable } from '../core/contract.js';
3
+ import type { Translate } from '../core/i18n.js';
3
4
  export type SinkAC = AudioContext & {
4
5
  setSinkId?: (id: string) => Promise<void>;
5
6
  };
6
7
  /**
7
- * Quantos PASSOS da métrica declarada saturam o estéreo. Além disto, "à direita" é só à direita.
8
+ * How many STEPS of the declared metric saturate the stereo. Beyond this, "to the right" is just to the right.
8
9
  *
9
- * ⚠️ ONZE NÃO É NÚMERO NOVO — é o que a plataforma sempre teve, relido na régua certa. O denominador antigo
10
- * era `LOGICAL_W * 0.55 = 320 × 0,55 = 176` pixels, e a plataforma declara `unit: TILE` = 16: são **exatamente
11
- * 11 tiles**. Reescrever em passos preserva o que essa criança já ouve, letra por letra, e passa a dizer o
12
- * mesmo em qualquer gênero — 11 casas num tabuleiro, 11 metros num campo.
10
+ * ⚠️ ELEVEN IS NOT A NEW NUMBER — it is what the platformer always had, reread on the right ruler. The old denominator was
11
+ * `LOGICAL_W * 0.55 = 320 × 0.55 = 176` pixels, and the platformer declares `unit: TILE` = 16: **exactly 11 tiles**.
12
+ * Rewriting it in steps keeps what that child already hears, and says the same in any genre — 11 squares on a board,
13
+ * 11 metres on a pitch.
13
14
  *
14
- * E encaixa na régua que o resto do módulo já usa: `chaveDeDistancia` corta "muito perto" em 4 passos e
15
- * "perto" em 9. O estéreo satura logo depois de a coisa passar a ser "longe", que é onde a direção deixa de
16
- * precisar de mais precisão.
15
+ * And it fits the ruler the rest of the module uses: `distanceKey` cuts "very near" at 4 steps and "near" at 9. The
16
+ * stereo saturates just after the thing becomes "far", which is where direction stops needing more precision.
17
17
  */
18
18
  export declare const PAN_PACES = 11;
19
19
  /**
20
- * Quanto vale UM passo, em unidades do mundo. Zero = este espaço não tem lado.
20
+ * What ONE step is worth, in world units. Zero = this space has no sides.
21
21
  *
22
- * Contínuo: o `unit` declarado. Grade: uma célula, por definição. Lista: nada — `hotspots` é uma ordem, não
23
- * uma geometria, e inventar-lhe uma largura de estéreo seria apontar para um lado que não existe.
22
+ * Continuous: the declared `unit`. Grid: one cell, by definition. List: nothing — `hotspots` is an order, not a geometry,
23
+ * and inventing a stereo width for it would point at a side that does not exist.
24
24
  */
25
- export declare function passoDoMundo(topo: Topology): number;
25
+ export declare function worldStep(shape: Topology): number;
26
26
  /**
27
- * O jogador visto pela navegação sonora. É a fatia MÍNIMA, e ela encolheu com o corte: `facing` ficou com a
28
- * bengala (é ela que bate "à frente") e `wnT` com o nado. Sobrou identidade, posição, visão e o dispositivo.
27
+ * The player as navigation by sound sees them. The MINIMAL slice, which shrank with the cut: `facing` stayed with the cane
28
+ * (it is the cane that taps "ahead") and `wnT` with swimming. What remains is identity, position, sight and the device.
29
29
  */
30
30
  export interface SonarPlayer extends PlayerAudioOut {
31
31
  readonly i: number;
@@ -33,179 +33,76 @@ export interface SonarPlayer extends PlayerAudioOut {
33
33
  readonly y: number;
34
34
  readonly audioSink?: string | null;
35
35
  }
36
- /** O grafo contínuo do guia: oscilador → passa-baixo → ganho → panorâmica → categoria `guide`. */
37
- export interface GuiaVivo {
38
- /** O contexto que o construiu — é dele que sai o `currentTime` de cada `setTargetAtTime`. */
39
- readonly ac: AudioContext;
40
- readonly osc: OscillatorNode;
41
- readonly filtro: BiquadFilterNode;
42
- readonly ganho: GainNode;
43
- /** `null` em motor sem `createStereoPanner` — o guia fica mono em vez de não existir. */
44
- readonly panner: StereoPannerNode | null;
45
- /** Quadros desde a última vez que a ROTA foi recalculada. A rota é cara; o som não pode esperar por ela. */
46
- desdeARota: number;
47
- /** O último `passos` medido. É daqui que a intensidade sai a cada quadro. */
48
- passos: number;
49
- /** A última panorâmica medida, pelo mesmo motivo: ela vem do alvo, que só se procura com a rota. */
50
- pan: number;
51
- }
52
- /**
53
- * ⚠️ O TIMBRE TEM DE TER HARMÓNICOS, e isto é requisito técnico, não gosto.
54
- *
55
- * O eixo do #84 item 2 é o BRILHO, e brilho é um passa-baixo a abrir e a fechar. **Um passa-baixo sobre uma
56
- * onda `sine` não faz absolutamente nada**: a senoide não tem nada acima da fundamental para o filtro cortar,
57
- * e o guia ficaria com um eixo morto e só o volume a trabalhar. A dente-de-serra é a mais rica das quatro
58
- * ondas do Web Audio — tem TODOS os harmónicos —, e é por isso que ela é a escolha.
59
- *
60
- * E ela resolve, de graça, a outra restrição do plano: o sonar e a bengala usam `sine`. Um timbre diferente
61
- * era exigência de não colidirem no mesmo canal; aqui o timbre diferente É o mecanismo.
62
- */
63
- export declare const GUIA_TIPO: OscillatorType;
64
- /**
65
- * A fundamental do guia, fixa.
66
- *
67
- * ⚠️ FIXA DE PROPÓSITO: a ALTURA já é a linguagem do sonar (`380 + 740 * near`, mais perto = mais agudo). Se o
68
- * guia também subisse de tom, os dois estariam a dizer a mesma coisa pelo mesmo meio, e quem ouve os dois ao
69
- * mesmo tempo não teria como separá-los. O guia diz distância por brilho; o sonar, por altura.
70
- */
71
- export declare const GUIA_HZ = 220;
72
- /**
73
- * Quantos quadros entre dois cálculos de rota.
74
- *
75
- * ⚠️ A ROTA É UMA BUSCA EM LARGURA, e o `__incl.update(dt)` conta QUADROS: correr uma BFS a cada quadro num
76
- * mapa de plataforma gasta o orçamento do quadro inteiro no aparelho-alvo (Positivo/Chromebook, pilar 1). Doze
77
- * quadros são ~0,2 s a 60 fps — mais depressa do que a criança anda um passo, e o som não espera por eles: a
78
- * intensidade é reescrita TODO quadro, com o `passos` que a última rota deixou.
79
- */
80
- export declare const QUADROS_ENTRE_ROTAS = 12;
81
- /**
82
- * O tecto de pontos da rota do guia. Bem abaixo dos 4096 do `core/route`, e o próprio módulo diz porquê:
83
- * «uma pista por quadro tolera muito menos do que um cálculo ao carregar a fase». Estourar devolve `null`, que
84
- * é «não sei» — e o guia cai na reta, que ainda soa.
85
- */
86
- export declare const ORCAMENTO_DA_ROTA = 1024;
87
- /**
88
- * O ganho de base do guia, antes de a intensidade e o volume mestre o multiplicarem.
89
- *
90
- * ⚠️ MAIS BAIXO DO QUE O BIPE QUE ELE SUBSTITUI (0,11), e não por engano: um som que **nunca para** é
91
- * percebido como mais alto do que um transiente do mesmo pico, e cansa por permanência em vez de por
92
- * intensidade — exactamente o que o modo TEA existe para não fazer.
93
- */
94
- export declare const GUIA_VOL = 0.06;
95
- /** Constante de tempo do `setTargetAtTime`. Curta o bastante para acompanhar o passo, longa o bastante para
96
- * que a mudança seja um deslize e não um degrau — um degrau a cada rota seria um bipe outra vez. */
97
- export declare const TAU_DO_GUIA = 0.08;
98
36
  /**
99
- * A SAÍDA DEDICADA de um jogador, e este módulo é o DONO dela: é aqui que os dois campos NASCEM
100
- * (`new AC()` + `createGain()`, logo abaixo). Pelo ADR-0039 o dono declara onde o campo nasce, e o
101
- * `core/entity` não os menciona — eles não são da entidade da engine, são rascunho que o áudio pendura
102
- * no jogador.
37
+ * A player's DEDICATED OUTPUT, and this module OWNS it: it is here the two fields are BORN (`new AC()` + `createGain()`,
38
+ * below). By ADR-0039 the owner declares where a field is born, and `core/entity` does not mention them — they are not
39
+ * the engine entity's, they are scratch the audio hangs on the player.
103
40
  *
104
- * `_acOut` admite `null` porque `ui/settings-audio` escreve `null` nos dois ao trocar de dispositivo.
105
- * Enquanto o `core/entity` dizia `unknown`, essa escrita passava sem que ninguém visse que o dono
106
- * declarava `GainNode` sem nulo — as duas descrições discordavam e o `unknown` era o que as escondia.
41
+ * `_acOut` allows `null` because the audio panel writes `null` to both when the device changes; an `unknown` on the
42
+ * entity used to hide that the owner declared a non-null `GainNode`.
107
43
  */
108
44
  export interface PlayerAudioOut {
109
45
  _ac?: SinkAC | null;
110
46
  _acOut?: GainNode | null;
111
- /**
112
- * O GRAFO VIVO DO GUIA deste jogador, e mora AQUI, ao lado dos outros dois, pelo mesmo motivo que eles
113
- * (ADR-0039: o dono declara onde o campo nasce; ADR-0033: a entidade da engine declara o que a ENGINE
114
- * possui, e um oscilador não é dela). `null`/ausente = calado.
115
- *
116
- * ⚠️ ELE PRECISA DE SOBREVIVER AOS QUADROS, e é aí que ele difere de tudo o resto neste ficheiro. O sonar e
117
- * o bipe antigo criavam um oscilador, tocavam-no e deitavam-no fora; uma presença CONTÍNUA (#84 item 2) é um
118
- * oscilador que FICA, com o filtro e o ganho a mover-se por baixo dele. É por isso que ele tem de estar
119
- * pendurado no jogador: não há outro lugar onde algo por jogador dure de um quadro para o outro.
120
- *
121
- * ⚠️ E É POR ISSO QUE `desligarGuia` EXISTE. Um campo que dura é um campo que vaza: sem alguém a pará-lo,
122
- * desligar a categoria `guide` no mixer deixaria o som a tocar.
123
- */
124
- _guia?: GuiaVivo | null;
125
47
  }
126
48
  export interface PlayerCtxOut {
127
49
  ac: AudioContext;
128
50
  out: GainNode;
129
51
  }
130
52
  export interface SonarCtx {
131
- /** Campo 1: a métrica. Função, porque um jogo com fases troca de topologia entre elas. */
53
+ /** Translates in the page's language — the root's translator (ADR-0232 D3). REQUIRED: text built from nowhere is a raw key. */
54
+ t: Translate;
55
+ /** Field 1: the metric. A function, because a game with stages changes topology between them. */
132
56
  topology: () => Topology;
133
- /** Campo 5, metade "alvo": onde estão os alvos ainda válidos deste jogador. Vazio = nada a apontar. */
57
+ /** Field 5, the "target" half: where this player's still-valid targets are. Empty = nothing to point at. */
134
58
  targetsOf: (playerIndex: number) => readonly Spot[];
135
- /** Campo 3: como se chama o que está ali. `null` = sem nome, e o anúncio cai no genérico. */
59
+ /** Field 3: what the thing there is called. `null` = no name, and the announcement falls back to the generic. */
136
60
  nameAt: (at: Spot) => Speakable | null;
137
- /**
138
- * Campo 2: o que há neste ponto. É o que o `core/route` atravessa (ou não) para achar o caminho.
139
- *
140
- * ⚠️ OPCIONAL AQUI, e obrigatório na `GameDeclaration` — a diferença não é descuido. Tornar um campo do
141
- * `SonarCtx` obrigatório quebra todo o consumidor que já monta este ctx à mão, e o `create-game` (que é
142
- * quem o monta de verdade) sempre o tem, porque o `validateDeclaration` o exige. Ausente aqui, o guia não
143
- * fica calado: ele cai na distância em reta, que é o que ele já fazia antes desta mudança.
144
- */
145
- roleAt?: (at: Spot) => Role;
146
61
  tonePan: (freq: number, dur: number, cat: string, pan?: number | null, vol?: number, type?: OscillatorType, pc?: PlayerCtxOut | null) => void;
147
62
  srSay: (text: string) => void;
148
- narrate: (text: string) => void;
149
63
  /**
150
- * O barramento de uma categoria do mixer. A MESMA forma que `audio-ambient`, `audio-earcons`, `audio-jingles`
151
- * e `tts` já recebem — o guia deixou de poder usar o `tonePan` porque `tonePan` toca e esquece, e uma
152
- * presença contínua é um grafo que FICA.
153
- *
154
- * Opcional pelo mesmo motivo que o `roleAt`: quem não o injectar cai no `audioOut` e, na falta dele, no
155
- * `destination`. O que se perde é o cursor da categoria `guide`, não o som.
64
+ * Speaks the sonar's words. `seat` is the player who pressed: a reading takes turns with the other players' and cuts that
65
+ * player's own (ADR-0234, errata 2026-09-26 — the root's narration does it; a ctx built by hand may ignore it).
156
66
  */
157
- catNode?: (cat: string) => AudioNode | null;
158
- /** O nó mestre, recuo do `catNode`. */
159
- audioOut?: () => AudioNode | null;
67
+ narrate: (text: string, seat: number) => void;
160
68
  /**
161
- * O volume mestre (0..1), que cada síntese multiplica por si — o `_masterGain` do `platform/audio` é o mudo
162
- * da pausa, não o cursor. Ausente = 1: o guia soa, e ignora o cursor. Por isso o `create-game` injecta-o.
69
+ * WHAT IS ON THE SCREEN NOW, as text in reading order — `''` when there is none the engine can read (ADR-0234: «sonar do que
70
+ * está na tela»). With text, the sonar's WORDS are that text, read at the press; the tone still points at the nearest
71
+ * target. Without (a world drawn on a canvas, or no text), the words are the navigation sentence. Absent: always the latter.
163
72
  */
164
- getVolume?: () => number;
73
+ screenText?: () => string;
165
74
  /**
166
- * Esta criança tem a visão comprometida — cegueira simulada ou baixa visão?
75
+ * Is this child's sight impaired — simulated blindness or low vision?
167
76
  *
168
- * ⚠️ SUBSTITUIU O `VIZ_BY_KEY` EM 2026-09-08 (#104), e a troca encolheu este módulo em vez de o migrar.
169
- * Ele recebia a TABELA de modos de render e atravessava-a com `pl.viz`; agora recebe a RESPOSTA. Quem a dá
170
- * é a raiz de composição, que conhece os dois eixos e pode importar de `render/` — o que este ficheiro,
171
- * estando em `platform/`, não pode sem inverter uma aresta de camada.
77
+ * ⚠️ It replaced the table of render modes (#104), and the swap shrank this module instead of migrating it: it used to
78
+ * receive the TABLE and walk it with `pl.viz`; now it receives the ANSWER. The composition root gives it — it knows the
79
+ * two axes and may import `render/`, which this file, in `platform/`, cannot without inverting a layer edge.
172
80
  *
173
- * O `pl` inteiro e não o índice: quem responde já tem o jogador em mão, e passar o índice obrigaria a raiz
174
- * a procurá-lo outra vez numa lista que ela acabou de percorrer.
81
+ * The whole `pl` and not the index: whoever answers already has the player in hand.
175
82
  */
176
- visaoComprometida: (pl: SonarPlayer) => boolean;
177
- getModoCego: () => boolean;
178
- /** Largura LÓGICA da tela. É do console, não do gênero — por isso ctx, e não campo de contrato. */
83
+ visionImpaired: (pl: SonarPlayer) => boolean;
84
+ getBlindMode: () => boolean;
179
85
  /**
180
- * @deprecated ⚠️ SEM LEITOR DESDE 2026-09-07 (#121). Era o denominador do pan, e era o defeito: media a
181
- * largura do estéreo em pixels de ecrã e dividia por ela uma distância de MUNDO. Agora a largura vem da
182
- * topologia (`PAN_PACES * passoDoMundo`).
86
+ * @deprecated ⚠️ NO READER (#121). It was the pan's denominator, and it was the defect: it measured the stereo width in
87
+ * screen pixels and divided a WORLD distance by it. The width now comes from the topology (`PAN_PACES * worldStep`).
183
88
  *
184
- * Ficou OPCIONAL em vez de removido — tornar um campo obrigatório em opcional é compatível para trás, e
185
- * quem já o injecta continua a compilar. Removê-lo de vez é candidato ao próximo major.
89
+ * It stayed OPTIONAL instead of removed — making a required field optional is backward compatible. Removing it for good
90
+ * is a candidate for the next major.
186
91
  */
187
92
  LOGICAL_W?: number;
188
- getPlayers: () => SonarPlayer[];
189
93
  getNumPlayers: () => number;
190
- getAudioCtx: () => AudioContext | null;
191
- getSoundOn: () => boolean;
192
- getAudioCat: () => Record<string, {
193
- on: boolean;
194
- }> | null;
94
+ /**
95
+ * Makes a NEW AudioContext, or `null` where the host has none: each player with an audio device of their own gets one, so
96
+ * `setSinkId` can send that child's cues to that device. The root's maker, from `host.win` — the same one its `createAudio`
97
+ * receives. REQUIRED (ADR-0232 D4): a default would be the page's window reached from `platform/`.
98
+ */
99
+ newContext: () => AudioContext | null;
195
100
  }
196
101
  export interface AudioSonar {
197
102
  playerCtx: (pl: SonarPlayer) => PlayerCtxOut | null;
198
103
  panFor: (wx: number, pl: SonarPlayer) => number;
199
104
  needsAudioCues: (pl: SonarPlayer) => boolean;
200
105
  sonar: (pl: SonarPlayer) => void;
201
- updateGuide: () => void;
202
106
  readonly sonarCount: number;
203
- /**
204
- * ⚠️ MUDOU DE SIGNIFICADO com o #84 item 2, e o número passa a ser muito maior. Contava BIPES (um a cada 48
205
- * quadros); conta agora QUADROS EM QUE O GUIA SOA, porque não há mais nada discreto para contar — é essa a
206
- * mudança. Quem o lê para dizer «o guia está a funcionar» continua certo; quem o lesse para dizer «tocou
207
- * três vezes» estaria a perguntar por uma coisa que deixou de existir.
208
- */
209
- readonly guideCount: number;
210
107
  }
211
108
  export declare function createAudioSonar(ctx: SonarCtx): AudioSonar;