@the-inclusionist/engine 10.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 (528) hide show
  1. package/README.md +32 -1
  2. package/app/css/style.css +216 -42
  3. package/app/public/vendor/fonts-licences/NOTICE.txt +166 -0
  4. package/app/public/vendor/fonts-licences/OFL-1.1.txt +86 -0
  5. package/app/public/vendor/fonts.css +11 -1175
  6. package/dist-pkg/boot/create-game.d.ts +84 -33
  7. package/dist-pkg/boot/create-game.js +708 -307
  8. package/dist-pkg/core/a11y-sr.d.ts +1 -1
  9. package/dist-pkg/core/a11y-sr.js +3 -5
  10. package/dist-pkg/core/accommodations.d.ts +26 -8
  11. package/dist-pkg/core/accommodations.js +27 -10
  12. package/dist-pkg/core/actions.d.ts +39 -10
  13. package/dist-pkg/core/actions.js +28 -6
  14. package/dist-pkg/core/contract.d.ts +0 -2
  15. package/dist-pkg/core/contract.js +0 -2
  16. package/dist-pkg/core/i18n.d.ts +36 -71
  17. package/dist-pkg/core/i18n.js +131 -198
  18. package/dist-pkg/core/session-clock.d.ts +23 -0
  19. package/dist-pkg/core/session-clock.js +37 -0
  20. package/dist-pkg/i18n/en.js +44 -49
  21. package/dist-pkg/i18n/es.js +44 -49
  22. package/dist-pkg/i18n/pt.js +49 -54
  23. package/dist-pkg/input/gamepad.d.ts +42 -11
  24. package/dist-pkg/input/gamepad.js +50 -15
  25. package/dist-pkg/input/key-default.d.ts +30 -0
  26. package/dist-pkg/input/key-default.js +60 -0
  27. package/dist-pkg/input/keyboard-runtime.d.ts +0 -4
  28. package/dist-pkg/input/keyboard.d.ts +0 -1
  29. package/dist-pkg/input/keydown.d.ts +5 -11
  30. package/dist-pkg/input/keydown.js +3 -3
  31. package/dist-pkg/input/latch-edge.d.ts +10 -2
  32. package/dist-pkg/input/latch-edge.js +4 -3
  33. package/dist-pkg/input/latch-scope.d.ts +27 -22
  34. package/dist-pkg/input/latch-scope.js +25 -37
  35. package/dist-pkg/input/latch-store.d.ts +9 -12
  36. package/dist-pkg/input/latch-store.js +13 -18
  37. package/dist-pkg/input/latch-sync.d.ts +5 -4
  38. package/dist-pkg/input/latch-sync.js +5 -5
  39. package/dist-pkg/input/pad-reading.js +7 -2
  40. package/dist-pkg/input/pad-wizard.d.ts +4 -1
  41. package/dist-pkg/input/pad-wizard.js +60 -9
  42. package/dist-pkg/input/switch-scan.d.ts +29 -12
  43. package/dist-pkg/input/switch-scan.js +15 -2
  44. package/dist-pkg/input/touch-bindings.d.ts +3 -6
  45. package/dist-pkg/input/touch.d.ts +17 -2
  46. package/dist-pkg/input/touch.js +55 -17
  47. package/dist-pkg/input/transport-in-use.d.ts +5 -5
  48. package/dist-pkg/input/transport-in-use.js +5 -5
  49. package/dist-pkg/input/transports.d.ts +0 -9
  50. package/dist-pkg/input/transports.js +1 -1
  51. package/dist-pkg/input/virtual-controller.d.ts +39 -3
  52. package/dist-pkg/input/virtual-controller.js +32 -4
  53. package/dist-pkg/input/voice-map.d.ts +27 -11
  54. package/dist-pkg/input/voice-map.js +41 -43
  55. package/dist-pkg/platform/audio-ambient.d.ts +0 -1
  56. package/dist-pkg/platform/audio-ambient.js +3 -1
  57. package/dist-pkg/platform/audio-mixer.js +4 -9
  58. package/dist-pkg/platform/audio-sonar.d.ts +8 -94
  59. package/dist-pkg/platform/audio-sonar.js +22 -207
  60. package/dist-pkg/platform/audio.d.ts +10 -1
  61. package/dist-pkg/platform/audio.js +35 -2
  62. package/dist-pkg/platform/choose-by-voice.d.ts +70 -0
  63. package/dist-pkg/platform/choose-by-voice.js +157 -0
  64. package/dist-pkg/platform/font-library.d.ts +77 -0
  65. package/dist-pkg/platform/font-library.js +98 -0
  66. package/dist-pkg/platform/font-library.json +721 -0
  67. package/dist-pkg/platform/heavy-catalogue.d.ts +46 -0
  68. package/dist-pkg/platform/heavy-catalogue.js +47 -14
  69. package/dist-pkg/platform/heavy-mirror.d.ts +3 -9
  70. package/dist-pkg/platform/heavy-mirror.js +14 -17
  71. package/dist-pkg/platform/heavy.d.ts +40 -8
  72. package/dist-pkg/platform/heavy.js +177 -22
  73. package/dist-pkg/platform/interruptible-speech.d.ts +15 -8
  74. package/dist-pkg/platform/interruptible-speech.js +37 -13
  75. package/dist-pkg/platform/listener-scope.js +22 -13
  76. package/dist-pkg/platform/locale-host.d.ts +7 -3
  77. package/dist-pkg/platform/locale-host.js +13 -2
  78. package/dist-pkg/platform/reading-in-worker.d.ts +24 -0
  79. package/dist-pkg/platform/reading-in-worker.js +38 -0
  80. package/dist-pkg/platform/reading-model.d.ts +21 -0
  81. package/dist-pkg/platform/reading-model.js +25 -0
  82. package/dist-pkg/platform/reading-runtime.js +13 -8
  83. package/dist-pkg/platform/reading.d.ts +12 -1
  84. package/dist-pkg/platform/reading.js +9 -1
  85. package/dist-pkg/platform/speech-recognition.d.ts +10 -1
  86. package/dist-pkg/platform/speech-recognition.js +29 -9
  87. package/dist-pkg/platform/speech.d.ts +10 -1
  88. package/dist-pkg/platform/speech.js +24 -13
  89. package/dist-pkg/platform/tts.d.ts +37 -4
  90. package/dist-pkg/platform/tts.js +279 -57
  91. package/dist-pkg/platform/voice-listener.d.ts +6 -2
  92. package/dist-pkg/platform/voice-listener.js +1 -1
  93. package/dist-pkg/platform/voice-plan.d.ts +13 -0
  94. package/dist-pkg/platform/voice-plan.js +57 -2
  95. package/dist-pkg/platform/vosk-runtime.d.ts +25 -0
  96. package/dist-pkg/platform/vosk-runtime.js +59 -1
  97. package/dist-pkg/platform/vosk-vocabulary.d.ts +6 -0
  98. package/dist-pkg/platform/vosk-vocabulary.js +178 -0
  99. package/dist-pkg/render/crt.d.ts +11 -9
  100. package/dist-pkg/render/crt.js +6 -10
  101. package/dist-pkg/render/cvd-matrices.d.ts +5 -1
  102. package/dist-pkg/render/cvd-matrices.js +5 -1
  103. package/dist-pkg/render/high-contrast.d.ts +1 -2
  104. package/dist-pkg/render/high-contrast.js +5 -1
  105. package/dist-pkg/render/viz-axes.d.ts +9 -0
  106. package/dist-pkg/render/viz-axes.js +15 -2
  107. package/dist-pkg/ui/aac-sets.d.ts +29 -24
  108. package/dist-pkg/ui/aac-sets.js +22 -30
  109. package/dist-pkg/ui/audio-choices.d.ts +10 -5
  110. package/dist-pkg/ui/audio-choices.js +14 -10
  111. package/dist-pkg/ui/camera-control.d.ts +47 -0
  112. package/dist-pkg/ui/camera-control.js +35 -1
  113. package/dist-pkg/ui/declared-words.d.ts +21 -0
  114. package/dist-pkg/ui/declared-words.js +66 -0
  115. package/dist-pkg/ui/drawing-problems.js +4 -3
  116. package/dist-pkg/ui/eye-control.js +17 -17
  117. package/dist-pkg/ui/face-control.js +15 -15
  118. package/dist-pkg/ui/fonts.d.ts +42 -8
  119. package/dist-pkg/ui/fonts.js +58 -24
  120. package/dist-pkg/ui/footer-scroll-driver.d.ts +14 -0
  121. package/dist-pkg/ui/footer-scroll-driver.js +201 -0
  122. package/dist-pkg/ui/footer-scroll.d.ts +38 -0
  123. package/dist-pkg/ui/footer-scroll.js +55 -0
  124. package/dist-pkg/ui/game-options.d.ts +14 -9
  125. package/dist-pkg/ui/game-options.js +41 -21
  126. package/dist-pkg/ui/hand-control.js +15 -15
  127. package/dist-pkg/ui/help-panel.d.ts +19 -8
  128. package/dist-pkg/ui/help-panel.js +15 -5
  129. package/dist-pkg/ui/hud-bands.d.ts +29 -12
  130. package/dist-pkg/ui/hud-bands.js +63 -25
  131. package/dist-pkg/ui/hud-row.d.ts +34 -0
  132. package/dist-pkg/ui/hud-row.js +80 -0
  133. package/dist-pkg/ui/hud.d.ts +0 -3
  134. package/dist-pkg/ui/layout.js +5 -2
  135. package/dist-pkg/ui/libras-avatar-clip.d.ts +30 -0
  136. package/dist-pkg/ui/libras-avatar-clip.js +86 -0
  137. package/dist-pkg/ui/libras-avatar-load.d.ts +52 -0
  138. package/dist-pkg/ui/libras-avatar-load.js +134 -0
  139. package/dist-pkg/ui/libras-avatar-plan.d.ts +102 -0
  140. package/dist-pkg/ui/libras-avatar-plan.js +211 -0
  141. package/dist-pkg/ui/libras-avatar-player.d.ts +28 -0
  142. package/dist-pkg/ui/libras-avatar-player.js +226 -0
  143. package/dist-pkg/ui/libras-avatar-stage.d.ts +37 -0
  144. package/dist-pkg/ui/libras-avatar-stage.js +208 -0
  145. package/dist-pkg/ui/libras-glosses.d.ts +28 -0
  146. package/dist-pkg/ui/libras-glosses.js +161 -0
  147. package/dist-pkg/ui/menu-intent.d.ts +29 -0
  148. package/dist-pkg/ui/menu-intent.js +35 -1
  149. package/dist-pkg/ui/menu-items.d.ts +10 -0
  150. package/dist-pkg/ui/menu-items.js +29 -0
  151. package/dist-pkg/ui/menu-nav.d.ts +40 -4
  152. package/dist-pkg/ui/menu-nav.js +132 -47
  153. package/dist-pkg/ui/panel-widgets.d.ts +34 -0
  154. package/dist-pkg/ui/panel-widgets.js +86 -0
  155. package/dist-pkg/ui/pause-icons.d.ts +30 -14
  156. package/dist-pkg/ui/pause-icons.js +106 -45
  157. package/dist-pkg/ui/scan-overlay.d.ts +3 -3
  158. package/dist-pkg/ui/scan-overlay.js +11 -3
  159. package/dist-pkg/ui/screen-text.d.ts +25 -0
  160. package/dist-pkg/ui/screen-text.js +152 -0
  161. package/dist-pkg/ui/session-clock.d.ts +32 -0
  162. package/dist-pkg/ui/session-clock.js +67 -0
  163. package/dist-pkg/ui/settings-aac.d.ts +3 -1
  164. package/dist-pkg/ui/settings-aac.js +32 -13
  165. package/dist-pkg/ui/settings-audio.d.ts +10 -5
  166. package/dist-pkg/ui/settings-audio.js +101 -35
  167. package/dist-pkg/ui/settings-controls.d.ts +0 -4
  168. package/dist-pkg/ui/settings-mobility.d.ts +3 -6
  169. package/dist-pkg/ui/settings-mobility.js +4 -46
  170. package/dist-pkg/ui/settings-motion.js +2 -2
  171. package/dist-pkg/ui/settings-panel.d.ts +10 -0
  172. package/dist-pkg/ui/settings-panel.js +25 -1
  173. package/dist-pkg/ui/settings-typo.d.ts +5 -6
  174. package/dist-pkg/ui/settings-typo.js +20 -11
  175. package/dist-pkg/ui/settings-visual.js +2 -2
  176. package/dist-pkg/ui/shell.d.ts +1 -3
  177. package/dist-pkg/ui/shell.js +8 -4
  178. package/dist-pkg/ui/title.d.ts +2 -11
  179. package/dist-pkg/ui/title.js +39 -6
  180. package/dist-pkg/ui/top-band.d.ts +5 -3
  181. package/dist-pkg/ui/top-band.js +21 -25
  182. package/dist-pkg/ui/typo-choices.d.ts +3 -3
  183. package/dist-pkg/ui/typo-choices.js +9 -8
  184. package/dist-pkg/ui/vlibras.d.ts +71 -27
  185. package/dist-pkg/ui/vlibras.js +116 -44
  186. package/dist-pkg/ui/voice-control.d.ts +23 -1
  187. package/dist-pkg/ui/voice-control.js +149 -16
  188. package/dist-pkg/ui/voice-settings.d.ts +2 -3
  189. package/dist-pkg/ui/voice-settings.js +53 -3
  190. package/dist-pkg/ui/where-the-child-is.js +2 -2
  191. package/docs/CREDITS.md +122 -10
  192. package/docs/LICENSES.md +36 -7
  193. package/package.json +34 -9
  194. package/scripts/check-cartridge.mjs +78 -0
  195. package/scripts/game-build.d.mts +25 -0
  196. package/scripts/game-build.mjs +144 -0
  197. package/scripts/heavy-into-the-delivery.mjs +284 -40
  198. package/scripts/libras-avatar.json +680 -0
  199. package/scripts/libras-avatar.mjs +246 -0
  200. package/scripts/libras-glosses/gloss.py +95 -0
  201. package/scripts/libras-glosses/pyproject.toml +32 -0
  202. package/scripts/libras-glosses/uv.lock +781 -0
  203. package/scripts/libras-glosses.mjs +351 -0
  204. package/scripts/licences/OFL-1.1.txt +86 -0
  205. package/scripts/licences/UFL-1.0.txt +96 -0
  206. package/scripts/licences/fonts.mjs +389 -0
  207. package/scripts/licences/third-party.mjs +35 -21
  208. package/app/public/vendor/fonts/bitter-var-ext.woff2 +0 -0
  209. package/app/public/vendor/fonts/bitter-var.woff2 +0 -0
  210. package/app/public/vendor/fonts/bodonimoda-var-ext.woff2 +0 -0
  211. package/app/public/vendor/fonts/bodonimoda-var.woff2 +0 -0
  212. package/app/public/vendor/fonts/cat-abril_fatface-400-ext.woff2 +0 -0
  213. package/app/public/vendor/fonts/cat-abril_fatface-400.woff2 +0 -0
  214. package/app/public/vendor/fonts/cat-adlam_display-400-ext.woff2 +0 -0
  215. package/app/public/vendor/fonts/cat-adlam_display-400.woff2 +0 -0
  216. package/app/public/vendor/fonts/cat-agu_display-400-ext.woff2 +0 -0
  217. package/app/public/vendor/fonts/cat-agu_display-400.woff2 +0 -0
  218. package/app/public/vendor/fonts/cat-alfa_slab_one-400-ext.woff2 +0 -0
  219. package/app/public/vendor/fonts/cat-alfa_slab_one-400.woff2 +0 -0
  220. package/app/public/vendor/fonts/cat-are_you_serious-400-ext.woff2 +0 -0
  221. package/app/public/vendor/fonts/cat-are_you_serious-400.woff2 +0 -0
  222. package/app/public/vendor/fonts/cat-asimovian-400-ext.woff2 +0 -0
  223. package/app/public/vendor/fonts/cat-asimovian-400.woff2 +0 -0
  224. package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400-ext.woff2 +0 -0
  225. package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400.woff2 +0 -0
  226. package/app/public/vendor/fonts/cat-bakbak_one-400-ext.woff2 +0 -0
  227. package/app/public/vendor/fonts/cat-bakbak_one-400.woff2 +0 -0
  228. package/app/public/vendor/fonts/cat-bangers-400-ext.woff2 +0 -0
  229. package/app/public/vendor/fonts/cat-bangers-400.woff2 +0 -0
  230. package/app/public/vendor/fonts/cat-barriecito-400-ext.woff2 +0 -0
  231. package/app/public/vendor/fonts/cat-barriecito-400.woff2 +0 -0
  232. package/app/public/vendor/fonts/cat-berkshire_swash-400-ext.woff2 +0 -0
  233. package/app/public/vendor/fonts/cat-berkshire_swash-400.woff2 +0 -0
  234. package/app/public/vendor/fonts/cat-bevan-400-ext.woff2 +0 -0
  235. package/app/public/vendor/fonts/cat-bevan-400.woff2 +0 -0
  236. package/app/public/vendor/fonts/cat-bitcount-400-ext.woff2 +0 -0
  237. package/app/public/vendor/fonts/cat-bitcount-400.woff2 +0 -0
  238. package/app/public/vendor/fonts/cat-bowlby_one_sc-400-ext.woff2 +0 -0
  239. package/app/public/vendor/fonts/cat-bowlby_one_sc-400.woff2 +0 -0
  240. package/app/public/vendor/fonts/cat-bungee_shade-400-ext.woff2 +0 -0
  241. package/app/public/vendor/fonts/cat-bungee_shade-400.woff2 +0 -0
  242. package/app/public/vendor/fonts/cat-charm-400-ext.woff2 +0 -0
  243. package/app/public/vendor/fonts/cat-charm-400.woff2 +0 -0
  244. package/app/public/vendor/fonts/cat-charm-700-ext.woff2 +0 -0
  245. package/app/public/vendor/fonts/cat-charm-700.woff2 +0 -0
  246. package/app/public/vendor/fonts/cat-cherry_bomb_one-400-ext.woff2 +0 -0
  247. package/app/public/vendor/fonts/cat-cherry_bomb_one-400.woff2 +0 -0
  248. package/app/public/vendor/fonts/cat-chokokutai-400-ext.woff2 +0 -0
  249. package/app/public/vendor/fonts/cat-chokokutai-400.woff2 +0 -0
  250. package/app/public/vendor/fonts/cat-chonburi-400-ext.woff2 +0 -0
  251. package/app/public/vendor/fonts/cat-chonburi-400.woff2 +0 -0
  252. package/app/public/vendor/fonts/cat-climate_crisis-400-ext.woff2 +0 -0
  253. package/app/public/vendor/fonts/cat-climate_crisis-400.woff2 +0 -0
  254. package/app/public/vendor/fonts/cat-cookie-400.woff2 +0 -0
  255. package/app/public/vendor/fonts/cat-dela_gothic_one-400-ext.woff2 +0 -0
  256. package/app/public/vendor/fonts/cat-dela_gothic_one-400.woff2 +0 -0
  257. package/app/public/vendor/fonts/cat-fascinate_inline-400-ext.woff2 +0 -0
  258. package/app/public/vendor/fonts/cat-fascinate_inline-400.woff2 +0 -0
  259. package/app/public/vendor/fonts/cat-ga_maamli-400-ext.woff2 +0 -0
  260. package/app/public/vendor/fonts/cat-ga_maamli-400.woff2 +0 -0
  261. package/app/public/vendor/fonts/cat-itim-400-ext.woff2 +0 -0
  262. package/app/public/vendor/fonts/cat-itim-400.woff2 +0 -0
  263. package/app/public/vendor/fonts/cat-jacquard_24-400-ext.woff2 +0 -0
  264. package/app/public/vendor/fonts/cat-jacquard_24-400.woff2 +0 -0
  265. package/app/public/vendor/fonts/cat-kablammo-400-ext.woff2 +0 -0
  266. package/app/public/vendor/fonts/cat-kablammo-400.woff2 +0 -0
  267. package/app/public/vendor/fonts/cat-kalam-400-ext.woff2 +0 -0
  268. package/app/public/vendor/fonts/cat-kalam-400.woff2 +0 -0
  269. package/app/public/vendor/fonts/cat-kalam-700-ext.woff2 +0 -0
  270. package/app/public/vendor/fonts/cat-kalam-700.woff2 +0 -0
  271. package/app/public/vendor/fonts/cat-katibeh-400-ext.woff2 +0 -0
  272. package/app/public/vendor/fonts/cat-katibeh-400.woff2 +0 -0
  273. package/app/public/vendor/fonts/cat-lemonada-400-ext.woff2 +0 -0
  274. package/app/public/vendor/fonts/cat-lemonada-400.woff2 +0 -0
  275. package/app/public/vendor/fonts/cat-lilita_one-400-ext.woff2 +0 -0
  276. package/app/public/vendor/fonts/cat-lilita_one-400.woff2 +0 -0
  277. package/app/public/vendor/fonts/cat-lobster-400-ext.woff2 +0 -0
  278. package/app/public/vendor/fonts/cat-lobster-400.woff2 +0 -0
  279. package/app/public/vendor/fonts/cat-luckiest_guy-400-ext.woff2 +0 -0
  280. package/app/public/vendor/fonts/cat-luckiest_guy-400.woff2 +0 -0
  281. package/app/public/vendor/fonts/cat-marhey-400-ext.woff2 +0 -0
  282. package/app/public/vendor/fonts/cat-marhey-400.woff2 +0 -0
  283. package/app/public/vendor/fonts/cat-modak-400-ext.woff2 +0 -0
  284. package/app/public/vendor/fonts/cat-modak-400.woff2 +0 -0
  285. package/app/public/vendor/fonts/cat-momo_signature-400-ext.woff2 +0 -0
  286. package/app/public/vendor/fonts/cat-momo_signature-400.woff2 +0 -0
  287. package/app/public/vendor/fonts/cat-monofett-400-ext.woff2 +0 -0
  288. package/app/public/vendor/fonts/cat-monofett-400.woff2 +0 -0
  289. package/app/public/vendor/fonts/cat-monomakh-400-ext.woff2 +0 -0
  290. package/app/public/vendor/fonts/cat-monomakh-400.woff2 +0 -0
  291. package/app/public/vendor/fonts/cat-monoton-400-ext.woff2 +0 -0
  292. package/app/public/vendor/fonts/cat-monoton-400.woff2 +0 -0
  293. package/app/public/vendor/fonts/cat-nerko_one-400-ext.woff2 +0 -0
  294. package/app/public/vendor/fonts/cat-nerko_one-400.woff2 +0 -0
  295. package/app/public/vendor/fonts/cat-noto_sans_adlam-400-ext.woff2 +0 -0
  296. package/app/public/vendor/fonts/cat-noto_sans_adlam-400.woff2 +0 -0
  297. package/app/public/vendor/fonts/cat-noto_sans_arabic-400-ext.woff2 +0 -0
  298. package/app/public/vendor/fonts/cat-noto_sans_arabic-400.woff2 +0 -0
  299. package/app/public/vendor/fonts/cat-noto_sans_devanagari-400-ext.woff2 +0 -0
  300. package/app/public/vendor/fonts/cat-noto_sans_devanagari-400.woff2 +0 -0
  301. package/app/public/vendor/fonts/cat-noto_sans_hebrew-400-ext.woff2 +0 -0
  302. package/app/public/vendor/fonts/cat-noto_sans_hebrew-400.woff2 +0 -0
  303. package/app/public/vendor/fonts/cat-noto_sans_jp-400-ext.woff2 +0 -0
  304. package/app/public/vendor/fonts/cat-noto_sans_jp-400.woff2 +0 -0
  305. package/app/public/vendor/fonts/cat-noto_sans_khmer-400-ext.woff2 +0 -0
  306. package/app/public/vendor/fonts/cat-noto_sans_khmer-400.woff2 +0 -0
  307. package/app/public/vendor/fonts/cat-noto_sans_kr-400-ext.woff2 +0 -0
  308. package/app/public/vendor/fonts/cat-noto_sans_kr-400.woff2 +0 -0
  309. package/app/public/vendor/fonts/cat-noto_sans_sc-400-ext.woff2 +0 -0
  310. package/app/public/vendor/fonts/cat-noto_sans_sc-400.woff2 +0 -0
  311. package/app/public/vendor/fonts/cat-noto_sans_thai-400-ext.woff2 +0 -0
  312. package/app/public/vendor/fonts/cat-noto_sans_thai-400.woff2 +0 -0
  313. package/app/public/vendor/fonts/cat-ole-400-ext.woff2 +0 -0
  314. package/app/public/vendor/fonts/cat-ole-400.woff2 +0 -0
  315. package/app/public/vendor/fonts/cat-pacifico-400-ext.woff2 +0 -0
  316. package/app/public/vendor/fonts/cat-pacifico-400.woff2 +0 -0
  317. package/app/public/vendor/fonts/cat-patrick_hand-400-ext.woff2 +0 -0
  318. package/app/public/vendor/fonts/cat-patrick_hand-400.woff2 +0 -0
  319. package/app/public/vendor/fonts/cat-petit_formal_script-400-ext.woff2 +0 -0
  320. package/app/public/vendor/fonts/cat-petit_formal_script-400.woff2 +0 -0
  321. package/app/public/vendor/fonts/cat-pixelify_sans-400-ext.woff2 +0 -0
  322. package/app/public/vendor/fonts/cat-pixelify_sans-400.woff2 +0 -0
  323. package/app/public/vendor/fonts/cat-plaster-400-ext.woff2 +0 -0
  324. package/app/public/vendor/fonts/cat-plaster-400.woff2 +0 -0
  325. package/app/public/vendor/fonts/cat-playwrite_ar_guides-400-0.woff2 +0 -0
  326. package/app/public/vendor/fonts/cat-playwrite_at-400-0.woff2 +0 -0
  327. package/app/public/vendor/fonts/cat-playwrite_at_guides-400-0.woff2 +0 -0
  328. package/app/public/vendor/fonts/cat-playwrite_au_nsw-400-0.woff2 +0 -0
  329. package/app/public/vendor/fonts/cat-playwrite_au_nsw_guides-400-0.woff2 +0 -0
  330. package/app/public/vendor/fonts/cat-playwrite_au_qld-400-0.woff2 +0 -0
  331. package/app/public/vendor/fonts/cat-playwrite_au_qld_guides-400-0.woff2 +0 -0
  332. package/app/public/vendor/fonts/cat-playwrite_au_sa-400-0.woff2 +0 -0
  333. package/app/public/vendor/fonts/cat-playwrite_au_sa_guides-400-0.woff2 +0 -0
  334. package/app/public/vendor/fonts/cat-playwrite_au_tas-400-0.woff2 +0 -0
  335. package/app/public/vendor/fonts/cat-playwrite_au_tas_guides-400-0.woff2 +0 -0
  336. package/app/public/vendor/fonts/cat-playwrite_au_vic-400-0.woff2 +0 -0
  337. package/app/public/vendor/fonts/cat-playwrite_au_vic_guides-400-0.woff2 +0 -0
  338. package/app/public/vendor/fonts/cat-playwrite_be_vlg-400-0.woff2 +0 -0
  339. package/app/public/vendor/fonts/cat-playwrite_be_vlg_guides-400-0.woff2 +0 -0
  340. package/app/public/vendor/fonts/cat-playwrite_be_wal-400-0.woff2 +0 -0
  341. package/app/public/vendor/fonts/cat-playwrite_be_wal_guides-400-0.woff2 +0 -0
  342. package/app/public/vendor/fonts/cat-playwrite_br_guides-400-0.woff2 +0 -0
  343. package/app/public/vendor/fonts/cat-playwrite_ca_guides-400-0.woff2 +0 -0
  344. package/app/public/vendor/fonts/cat-playwrite_cl_guides-400-0.woff2 +0 -0
  345. package/app/public/vendor/fonts/cat-playwrite_co_guides-400-0.woff2 +0 -0
  346. package/app/public/vendor/fonts/cat-playwrite_cu_guides-400-0.woff2 +0 -0
  347. package/app/public/vendor/fonts/cat-playwrite_cz-400-0.woff2 +0 -0
  348. package/app/public/vendor/fonts/cat-playwrite_cz_guides-400-0.woff2 +0 -0
  349. package/app/public/vendor/fonts/cat-playwrite_de_grund-400-0.woff2 +0 -0
  350. package/app/public/vendor/fonts/cat-playwrite_de_grund_guides-400-0.woff2 +0 -0
  351. package/app/public/vendor/fonts/cat-playwrite_de_la-400-0.woff2 +0 -0
  352. package/app/public/vendor/fonts/cat-playwrite_de_la_guides-400-0.woff2 +0 -0
  353. package/app/public/vendor/fonts/cat-playwrite_de_sas-400-0.woff2 +0 -0
  354. package/app/public/vendor/fonts/cat-playwrite_de_sas_guides-400-0.woff2 +0 -0
  355. package/app/public/vendor/fonts/cat-playwrite_de_va-400-0.woff2 +0 -0
  356. package/app/public/vendor/fonts/cat-playwrite_de_va_guides-400-0.woff2 +0 -0
  357. package/app/public/vendor/fonts/cat-playwrite_dk_loopet-400-0.woff2 +0 -0
  358. package/app/public/vendor/fonts/cat-playwrite_dk_loopet_guides-400-0.woff2 +0 -0
  359. package/app/public/vendor/fonts/cat-playwrite_dk_uloopet-400-0.woff2 +0 -0
  360. package/app/public/vendor/fonts/cat-playwrite_dk_uloopet_guides-400-0.woff2 +0 -0
  361. package/app/public/vendor/fonts/cat-playwrite_es_deco_guides-400-0.woff2 +0 -0
  362. package/app/public/vendor/fonts/cat-playwrite_es_guides-400-0.woff2 +0 -0
  363. package/app/public/vendor/fonts/cat-playwrite_fr_moderne-400-0.woff2 +0 -0
  364. package/app/public/vendor/fonts/cat-playwrite_fr_moderne_guides-400-0.woff2 +0 -0
  365. package/app/public/vendor/fonts/cat-playwrite_fr_trad-400-0.woff2 +0 -0
  366. package/app/public/vendor/fonts/cat-playwrite_fr_trad_guides-400-0.woff2 +0 -0
  367. package/app/public/vendor/fonts/cat-playwrite_gb_j_guides-400-0.woff2 +0 -0
  368. package/app/public/vendor/fonts/cat-playwrite_gb_s_guides-400-0.woff2 +0 -0
  369. package/app/public/vendor/fonts/cat-playwrite_hr-400-0.woff2 +0 -0
  370. package/app/public/vendor/fonts/cat-playwrite_hr_guides-400-0.woff2 +0 -0
  371. package/app/public/vendor/fonts/cat-playwrite_hr_lijeva-400-0.woff2 +0 -0
  372. package/app/public/vendor/fonts/cat-playwrite_hr_lijeva_guides-400-0.woff2 +0 -0
  373. package/app/public/vendor/fonts/cat-playwrite_hu-400-0.woff2 +0 -0
  374. package/app/public/vendor/fonts/cat-playwrite_hu_guides-400-0.woff2 +0 -0
  375. package/app/public/vendor/fonts/cat-playwrite_id-400-0.woff2 +0 -0
  376. package/app/public/vendor/fonts/cat-playwrite_id_guides-400-0.woff2 +0 -0
  377. package/app/public/vendor/fonts/cat-playwrite_ie-400-0.woff2 +0 -0
  378. package/app/public/vendor/fonts/cat-playwrite_ie_guides-400-0.woff2 +0 -0
  379. package/app/public/vendor/fonts/cat-playwrite_in-400-0.woff2 +0 -0
  380. package/app/public/vendor/fonts/cat-playwrite_in_guides-400-0.woff2 +0 -0
  381. package/app/public/vendor/fonts/cat-playwrite_is-400-0.woff2 +0 -0
  382. package/app/public/vendor/fonts/cat-playwrite_is_guides-400-0.woff2 +0 -0
  383. package/app/public/vendor/fonts/cat-playwrite_it_moderna-400-0.woff2 +0 -0
  384. package/app/public/vendor/fonts/cat-playwrite_it_moderna_guides-400-0.woff2 +0 -0
  385. package/app/public/vendor/fonts/cat-playwrite_it_trad-400-0.woff2 +0 -0
  386. package/app/public/vendor/fonts/cat-playwrite_it_trad_guides-400-0.woff2 +0 -0
  387. package/app/public/vendor/fonts/cat-playwrite_mx_guides-400-0.woff2 +0 -0
  388. package/app/public/vendor/fonts/cat-playwrite_ng_modern-400-0.woff2 +0 -0
  389. package/app/public/vendor/fonts/cat-playwrite_ng_modern_guides-400-0.woff2 +0 -0
  390. package/app/public/vendor/fonts/cat-playwrite_nl-400-0.woff2 +0 -0
  391. package/app/public/vendor/fonts/cat-playwrite_nl_guides-400-0.woff2 +0 -0
  392. package/app/public/vendor/fonts/cat-playwrite_no-400-0.woff2 +0 -0
  393. package/app/public/vendor/fonts/cat-playwrite_no_guides-400-0.woff2 +0 -0
  394. package/app/public/vendor/fonts/cat-playwrite_nz-400-0.woff2 +0 -0
  395. package/app/public/vendor/fonts/cat-playwrite_nz_basic-400-0.woff2 +0 -0
  396. package/app/public/vendor/fonts/cat-playwrite_nz_basic_guides-400-0.woff2 +0 -0
  397. package/app/public/vendor/fonts/cat-playwrite_nz_guides-400-0.woff2 +0 -0
  398. package/app/public/vendor/fonts/cat-playwrite_pe_guides-400-0.woff2 +0 -0
  399. package/app/public/vendor/fonts/cat-playwrite_pl-400-0.woff2 +0 -0
  400. package/app/public/vendor/fonts/cat-playwrite_pl_guides-400-0.woff2 +0 -0
  401. package/app/public/vendor/fonts/cat-playwrite_pt_guides-400-0.woff2 +0 -0
  402. package/app/public/vendor/fonts/cat-playwrite_ro-400-0.woff2 +0 -0
  403. package/app/public/vendor/fonts/cat-playwrite_ro_guides-400-0.woff2 +0 -0
  404. package/app/public/vendor/fonts/cat-playwrite_sk-400-0.woff2 +0 -0
  405. package/app/public/vendor/fonts/cat-playwrite_sk_guides-400-0.woff2 +0 -0
  406. package/app/public/vendor/fonts/cat-playwrite_tz-400-0.woff2 +0 -0
  407. package/app/public/vendor/fonts/cat-playwrite_tz_guides-400-0.woff2 +0 -0
  408. package/app/public/vendor/fonts/cat-playwrite_us_modern_guides-400-0.woff2 +0 -0
  409. package/app/public/vendor/fonts/cat-playwrite_us_trad_guides-400-0.woff2 +0 -0
  410. package/app/public/vendor/fonts/cat-playwrite_vn-400-0.woff2 +0 -0
  411. package/app/public/vendor/fonts/cat-playwrite_vn_guides-400-0.woff2 +0 -0
  412. package/app/public/vendor/fonts/cat-playwrite_za-400-0.woff2 +0 -0
  413. package/app/public/vendor/fonts/cat-playwrite_za_guides-400-0.woff2 +0 -0
  414. package/app/public/vendor/fonts/cat-potta_one-400-ext.woff2 +0 -0
  415. package/app/public/vendor/fonts/cat-potta_one-400.woff2 +0 -0
  416. package/app/public/vendor/fonts/cat-ranchers-400-ext.woff2 +0 -0
  417. package/app/public/vendor/fonts/cat-ranchers-400.woff2 +0 -0
  418. package/app/public/vendor/fonts/cat-ranga-400-ext.woff2 +0 -0
  419. package/app/public/vendor/fonts/cat-ranga-400.woff2 +0 -0
  420. package/app/public/vendor/fonts/cat-ranga-700-ext.woff2 +0 -0
  421. package/app/public/vendor/fonts/cat-ranga-700.woff2 +0 -0
  422. package/app/public/vendor/fonts/cat-risque-400-ext.woff2 +0 -0
  423. package/app/public/vendor/fonts/cat-risque-400.woff2 +0 -0
  424. package/app/public/vendor/fonts/cat-rowdies-400-ext.woff2 +0 -0
  425. package/app/public/vendor/fonts/cat-rowdies-400.woff2 +0 -0
  426. package/app/public/vendor/fonts/cat-rowdies-700-ext.woff2 +0 -0
  427. package/app/public/vendor/fonts/cat-rowdies-700.woff2 +0 -0
  428. package/app/public/vendor/fonts/cat-ruge_boogie-400-ext.woff2 +0 -0
  429. package/app/public/vendor/fonts/cat-ruge_boogie-400.woff2 +0 -0
  430. package/app/public/vendor/fonts/cat-ruslan_display-400-ext.woff2 +0 -0
  431. package/app/public/vendor/fonts/cat-ruslan_display-400.woff2 +0 -0
  432. package/app/public/vendor/fonts/cat-sacramento-400-ext.woff2 +0 -0
  433. package/app/public/vendor/fonts/cat-sacramento-400.woff2 +0 -0
  434. package/app/public/vendor/fonts/cat-sancreek-400-ext.woff2 +0 -0
  435. package/app/public/vendor/fonts/cat-sancreek-400.woff2 +0 -0
  436. package/app/public/vendor/fonts/cat-sankofa_display-400-ext.woff2 +0 -0
  437. package/app/public/vendor/fonts/cat-sankofa_display-400.woff2 +0 -0
  438. package/app/public/vendor/fonts/cat-sedgwick_ave_display-400-ext.woff2 +0 -0
  439. package/app/public/vendor/fonts/cat-sedgwick_ave_display-400.woff2 +0 -0
  440. package/app/public/vendor/fonts/cat-shantell_sans-400-ext.woff2 +0 -0
  441. package/app/public/vendor/fonts/cat-shantell_sans-400.woff2 +0 -0
  442. package/app/public/vendor/fonts/cat-smokum-400-ext.woff2 +0 -0
  443. package/app/public/vendor/fonts/cat-smokum-400.woff2 +0 -0
  444. package/app/public/vendor/fonts/cat-solitreo-400-ext.woff2 +0 -0
  445. package/app/public/vendor/fonts/cat-solitreo-400.woff2 +0 -0
  446. package/app/public/vendor/fonts/cat-spicy_rice-400-ext.woff2 +0 -0
  447. package/app/public/vendor/fonts/cat-spicy_rice-400.woff2 +0 -0
  448. package/app/public/vendor/fonts/cat-sriracha-400-ext.woff2 +0 -0
  449. package/app/public/vendor/fonts/cat-sriracha-400.woff2 +0 -0
  450. package/app/public/vendor/fonts/cat-srisakdi-400-ext.woff2 +0 -0
  451. package/app/public/vendor/fonts/cat-srisakdi-400.woff2 +0 -0
  452. package/app/public/vendor/fonts/cat-srisakdi-700-ext.woff2 +0 -0
  453. package/app/public/vendor/fonts/cat-srisakdi-700.woff2 +0 -0
  454. package/app/public/vendor/fonts/cat-stix_two_math-400-0.woff2 +0 -0
  455. package/app/public/vendor/fonts/cat-tillana-400-ext.woff2 +0 -0
  456. package/app/public/vendor/fonts/cat-tillana-400.woff2 +0 -0
  457. package/app/public/vendor/fonts/cat-tillana-700-ext.woff2 +0 -0
  458. package/app/public/vendor/fonts/cat-tillana-700.woff2 +0 -0
  459. package/app/public/vendor/fonts/cat-titan_one-400-ext.woff2 +0 -0
  460. package/app/public/vendor/fonts/cat-titan_one-400.woff2 +0 -0
  461. package/app/public/vendor/fonts/cat-yatra_one-400-ext.woff2 +0 -0
  462. package/app/public/vendor/fonts/cat-yatra_one-400.woff2 +0 -0
  463. package/app/public/vendor/fonts/cat-yomogi-400-ext.woff2 +0 -0
  464. package/app/public/vendor/fonts/cat-yomogi-400.woff2 +0 -0
  465. package/app/public/vendor/fonts/dmserifdisplay-400-ext.woff2 +0 -0
  466. package/app/public/vendor/fonts/dmserifdisplay-400.woff2 +0 -0
  467. package/app/public/vendor/fonts/domine-var-ext.woff2 +0 -0
  468. package/app/public/vendor/fonts/domine-var.woff2 +0 -0
  469. package/app/public/vendor/fonts/fondamento-400-ext.woff2 +0 -0
  470. package/app/public/vendor/fonts/fondamento-400.woff2 +0 -0
  471. package/app/public/vendor/fonts/fraunces-var-ext.woff2 +0 -0
  472. package/app/public/vendor/fonts/fraunces-var.woff2 +0 -0
  473. package/app/public/vendor/fonts/fredoka-var-ext.woff2 +0 -0
  474. package/app/public/vendor/fonts/fredoka-var.woff2 +0 -0
  475. package/app/public/vendor/fonts/inter-400.woff2 +0 -0
  476. package/app/public/vendor/fonts/inter-700.woff2 +0 -0
  477. package/app/public/vendor/fonts/jakarta-var-ext.woff2 +0 -0
  478. package/app/public/vendor/fonts/jakarta-var.woff2 +0 -0
  479. package/app/public/vendor/fonts/lato-400.woff2 +0 -0
  480. package/app/public/vendor/fonts/lato-700.woff2 +0 -0
  481. package/app/public/vendor/fonts/literata-400.woff2 +0 -0
  482. package/app/public/vendor/fonts/literata-700.woff2 +0 -0
  483. package/app/public/vendor/fonts/lora-var-ext.woff2 +0 -0
  484. package/app/public/vendor/fonts/lora-var.woff2 +0 -0
  485. package/app/public/vendor/fonts/merriweather-var-ext.woff2 +0 -0
  486. package/app/public/vendor/fonts/merriweather-var.woff2 +0 -0
  487. package/app/public/vendor/fonts/newsreader-400.woff2 +0 -0
  488. package/app/public/vendor/fonts/newsreader-700.woff2 +0 -0
  489. package/app/public/vendor/fonts/notosans-var-ext.woff2 +0 -0
  490. package/app/public/vendor/fonts/notosans-var.woff2 +0 -0
  491. package/app/public/vendor/fonts/nunito-var-ext.woff2 +0 -0
  492. package/app/public/vendor/fonts/nunito-var.woff2 +0 -0
  493. package/app/public/vendor/fonts/opendyslexic-400.woff2 +0 -0
  494. package/app/public/vendor/fonts/opensans-400.woff2 +0 -0
  495. package/app/public/vendor/fonts/opensans-700.woff2 +0 -0
  496. package/app/public/vendor/fonts/pinyon-400.woff2 +0 -0
  497. package/app/public/vendor/fonts/playfair-var-ext.woff2 +0 -0
  498. package/app/public/vendor/fonts/playfair-var.woff2 +0 -0
  499. package/app/public/vendor/fonts/pressstart-400.woff2 +0 -0
  500. package/app/public/vendor/fonts/quattro-400.woff2 +0 -0
  501. package/app/public/vendor/fonts/quattro-700.woff2 +0 -0
  502. package/app/public/vendor/fonts/quicksand-var-ext.woff2 +0 -0
  503. package/app/public/vendor/fonts/quicksand-var.woff2 +0 -0
  504. package/app/public/vendor/fonts/robotoflex-var-ext.woff2 +0 -0
  505. package/app/public/vendor/fonts/robotoflex-var.woff2 +0 -0
  506. package/app/public/vendor/fonts/sora-var-ext.woff2 +0 -0
  507. package/app/public/vendor/fonts/sora-var.woff2 +0 -0
  508. package/app/public/vendor/fonts/sourcesans-400.woff2 +0 -0
  509. package/app/public/vendor/fonts/sourcesans-700.woff2 +0 -0
  510. package/app/public/vendor/fonts/sourceserif-400.woff2 +0 -0
  511. package/app/public/vendor/fonts/sourceserif-700.woff2 +0 -0
  512. package/app/public/vendor/fonts/spacegrotesk-var-ext.woff2 +0 -0
  513. package/app/public/vendor/fonts/spacegrotesk-var.woff2 +0 -0
  514. package/app/public/vendor/fonts/spectral-400-ext.woff2 +0 -0
  515. package/app/public/vendor/fonts/spectral-400.woff2 +0 -0
  516. package/app/public/vendor/fonts/spectral-700-ext.woff2 +0 -0
  517. package/app/public/vendor/fonts/spectral-700.woff2 +0 -0
  518. package/app/public/vendor/fonts/teachers-var-ext.woff2 +0 -0
  519. package/app/public/vendor/fonts/teachers-var.woff2 +0 -0
  520. package/app/public/vendor/fonts/ubuntu-400-ext.woff2 +0 -0
  521. package/app/public/vendor/fonts/ubuntu-400.woff2 +0 -0
  522. package/app/public/vendor/fonts/ubuntu-700-ext.woff2 +0 -0
  523. package/app/public/vendor/fonts/ubuntu-700.woff2 +0 -0
  524. package/app/public/vendor/fonts/ufmag-400.woff2 +0 -0
  525. package/dist-pkg/platform/guide-intensity.d.ts +0 -39
  526. package/dist-pkg/platform/guide-intensity.js +0 -71
  527. package/dist-pkg/ui/latch-refusal.d.ts +0 -33
  528. package/dist-pkg/ui/latch-refusal.js +0 -60
@@ -2,8 +2,6 @@
2
2
  import type { Translate } from '../core/i18n.js';
3
3
  import type { PlayerView } from '../core/entity.js';
4
4
  import { type EdgeFlag } from './edges.js';
5
- /** ui/dom.ts `$` — injected; the module never reaches `document`. */
6
- export type { DomQuery } from '../core/dom-query.js';
7
5
  /** What this module reads and does with a `keydown` `KeyboardEvent`. */
8
6
  export interface KeydownEventLike {
9
7
  code: string;
@@ -23,8 +21,6 @@ export interface KeydownEventLike {
23
21
  export interface KeyupEventLike {
24
22
  code: string;
25
23
  }
26
- /** action -> list of physical codes. */
27
- export type { KeyScheme } from '../core/entity.js';
28
24
  /** The six input edges keydown raises on the player (consumed and cleared by the game's physics). */
29
25
  /**
30
26
  * What this module reads (and writes) of a player — and ONLY that. DERIVED from core/entity.
@@ -48,10 +44,9 @@ export interface ControlsSnapshot {
48
44
  action1: string[];
49
45
  gameKeys: string[];
50
46
  }
51
- /** The title menu's navigation intent — `NavKeys` from input/edges, re-exported under the name this module's callers
52
- * already use (it was a fourth structural copy under another name). */
47
+ /** The title menu's navigation intent — `NavKeys` from input/edges, under the local name this module reads by (it was a
48
+ * fourth structural copy under another name). */
53
49
  import type { NavKeys as TitleNav } from './edges.js';
54
- export type { NavKeys as TitleNav } from './edges.js';
55
50
  /** EVERYTHING the decision needs to know about the world, in one object, built BEFORE any effect. */
56
51
  export interface KeydownSnapshot {
57
52
  /** Is the title screen on top? (Only Player 1 picks the game; the others hear a notice.) */
@@ -161,8 +156,7 @@ export declare const EASY_SHORTCUTS: ReadonlySet<string>;
161
156
  export declare const SCREEN_DIGITS: RegExp;
162
157
  /** Pause: Escape or the MAIN Enter. `NumpadEnter` does NOT pause. */
163
158
  export declare const PAUSE_KEYS: ReadonlySet<string>;
164
- export { EDGE_BY_ACTION, edgeAllowed } from './edges.js';
165
- export type { EdgeFlag } from './edges.js';
159
+ export { EDGE_BY_ACTION } from './edges.js';
166
160
  /** Does the key count as JUMP for anybody? P1's alias OR any player's `action2` (it is what makes "anyone can press
167
161
  * Play again" and "anyone confirms on the title" true). */
168
162
  export declare function isJumpKey(code: string, s: KeydownSnapshot): boolean;
@@ -244,8 +238,8 @@ export interface KeydownCtx {
244
238
  * THIS EDGE IS THIS PLAYER'S, AND IT CAME FROM HERE (ADR-0113 clause 4, issue #127) — `input/state.playerEdge`.
245
239
  *
246
240
  * 🔴 A REQUIRED FIELD: without a feeder, ADR-0109's automaton answers `teclado` for everyone through
247
- * `inputOf(i).inUse` — forever, with no error. Then clause 3's refusal never fires: the child who plays by webcam can
248
- * turn off the latch their input depends on, and nothing says so.
241
+ * `inputOf(i).inUse` — forever, with no error. Then the latch is read and written under the keyboard's key for a child
242
+ * playing by webcam, and the game's default for her device (ADR-0249) never applies.
249
243
  *
250
244
  * ⚠️ AND IT IS HERE THAT IT COUNTS, not on the keyboard, which is already the default: a stamped synthetic event
251
245
  * (`input/synthetic-source`) is how `olhos`/`rosto`/`gestos`/`fala` become the transport in use through this module.
@@ -82,9 +82,9 @@ export const EASY_SHORTCUTS = new Set(['ControlLeft', 'ControlRight', 'ShiftLeft
82
82
  export const SCREEN_DIGITS = /^Digit[1234]$/;
83
83
  /** Pause: Escape or the MAIN Enter. `NumpadEnter` does NOT pause. */
84
84
  export const PAUSE_KEYS = new Set(['Escape', 'Enter']);
85
- // The table and the Easy rule live in input/edges.ts, shared with gamepad and touch-bindings. Re-exported under the old
86
- // name because whoever imports from here (tests and readers) expects to find it here.
87
- export { EDGE_BY_ACTION, edgeAllowed } from './edges.js';
85
+ // The table lives in input/edges.ts, shared with gamepad and touch-bindings. Re-exported under the old name because the
86
+ // engine's tests import it from here.
87
+ export { EDGE_BY_ACTION } from './edges.js';
88
88
  /* --- pure predicates (exported: the test imports the piece instead of repeating the expression) --- */
89
89
  /** Does the key count as JUMP for anybody? P1's alias OR any player's `action2` (it is what makes "anyone can press
90
90
  * Play again" and "anyone confirms on the title" true). */
@@ -17,10 +17,18 @@ export interface LatchedEdgeOptions {
17
17
  readonly store: LatchStore;
18
18
  /** The factory default. `DEFAULTS.toggleMove`, not a hand-written `false`: there is ONE source (ADR-0029). */
19
19
  readonly byDefault?: boolean;
20
+ /**
21
+ * DOES THE MOUNTED GAME HOLD ANY KEY NOW? — `GameDeclaration.holdsKeys` (ADR-0249), the latch's default on eyes, face,
22
+ * gestures and speech. A FUNCTION, called at every edge: a game changes its answer between stages (ADR-0084), and the
23
+ * next command must follow the stage it lands in. REQUIRED, like `holdsKeys` itself: `true` latches a quiz's every word,
24
+ * `false` stops a platform game's «direita» after one step, so no default is safe.
25
+ */
26
+ readonly holdsKeys: () => boolean;
20
27
  }
21
28
  /**
22
- * RETURNS THE `playerEdge` THAT ALSO RESOLVES THE TOGGLE — to hand to `initKeydown` and `initTouchBindings` in place of
23
- * the raw one.
29
+ * RETURNS THE `playerEdge` THAT ALSO RESOLVES THE TOGGLE. The root calls it from the virtual controller's `pressedBy`, the one
30
+ * door every transport's press goes through (ADR-0109 rule 3); a host without that door hands it to `initKeydown`,
31
+ * `initTouchBindings` and `initGamepad` in place of the raw one.
24
32
  *
25
33
  * ⚠️ IT RESOLVES AGAINST `inputOf(player).inUse` AND NOT `origin`, a difference of design and not of behaviour: today the
26
34
  * edge always sets in-use to the origin, so swapping one for the other is an EQUIVALENT mutation — recorded as such in the
@@ -17,8 +17,9 @@
17
17
  import { DEFAULTS } from '../core/setting-defaults.js';
18
18
  import { syncLatch } from './latch-sync.js';
19
19
  /**
20
- * RETURNS THE `playerEdge` THAT ALSO RESOLVES THE TOGGLE — to hand to `initKeydown` and `initTouchBindings` in place of
21
- * the raw one.
20
+ * RETURNS THE `playerEdge` THAT ALSO RESOLVES THE TOGGLE. The root calls it from the virtual controller's `pressedBy`, the one
21
+ * door every transport's press goes through (ADR-0109 rule 3); a host without that door hands it to `initKeydown`,
22
+ * `initTouchBindings` and `initGamepad` in place of the raw one.
22
23
  *
23
24
  * ⚠️ IT RESOLVES AGAINST `inputOf(player).inUse` AND NOT `origin`, a difference of design and not of behaviour: today the
24
25
  * edge always sets in-use to the origin, so swapping one for the other is an EQUIVALENT mutation — recorded as such in the
@@ -38,6 +39,6 @@ export function createLatchedEdge(getPlayers, opts) {
38
39
  // half, because there is nowhere to write it.
39
40
  const p = getPlayers()[player];
40
41
  if (p)
41
- syncLatch(p, latchStore, player, inputOf(player).inUse, fallback);
42
+ syncLatch(p, latchStore, player, inputOf(player).inUse, { byDefault: fallback, gameHoldsKeys: opts.holdsKeys() });
42
43
  };
43
44
  }
@@ -1,26 +1,18 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
2
  /**
3
- * The transports that emit ONE COMMAND AT A TIME, on which the toggle is always on.
3
+ * The transports that emit ONE COMMAND AT A TIME, on which the latch's default is the game's `holdsKeys()` (ADR-0249).
4
4
  *
5
5
  * The values are transport names, which stay Portuguese like the rest of that vocabulary (`teclado`, `toque`): they are
6
6
  * stored, and renaming a stored value loses what the child saved.
7
7
  */
8
8
  export declare const ONE_COMMAND_AT_A_TIME: ReadonlySet<string>;
9
9
  /**
10
- * Is the toggle always on for this transport?
10
+ * Does this transport's latch start where the GAME says (ADR-0249)?
11
11
  *
12
- * ⚠️ "Always on" and "on by default" are different things, and the difference is ADR-0104 §C's: a default can be changed,
13
- * and changing it here would make the control unusable. So the stored value is not even read on these transports — see
14
- * `latchOf`.
12
+ * `true` on the four one-command transports: with nothing stored for them, the latch is the game's `holdsKeys()`. The
13
+ * option is offered on every transport alike; this answers only where the default comes from.
15
14
  */
16
- export declare function latchAlwaysOn(transport: string): boolean;
17
- /**
18
- * Should the option be OFFERED for this transport?
19
- *
20
- * The opposite of `latchAlwaysOn`, with a name of its own because a different caller asks: one decides the state, the
21
- * other whether to draw the button. A panel that drew the button and ignored the click would be worse than not drawing it.
22
- */
23
- export declare function latchIsOptional(transport: string): boolean;
15
+ export declare function latchDefaultFromGame(transport: string): boolean;
24
16
  /**
25
17
  * The toggle's storage key, with the transport in its name.
26
18
  *
@@ -34,11 +26,14 @@ export declare function latchKey(base: string, player: number, transport: string
34
26
  /**
35
27
  * The OLD key, per player and without a transport. Still read, never written again.
36
28
  *
37
- * ⚠️ IT IS INHERITED BY EVERY TRANSPORT, and the choice takes a sentence to explain. The old value was set by the child in
38
- * some context, and there is no way to know which — the key did not record it, which is the defect. The ways out were
39
- * three: lose their setting, guess a transport, or inherit for all. Inheriting for all is the only one that takes nothing
40
- * from whoever depends on the setting, and the leak it keeps lasts only until the child touches the setting once on each
41
- * device. Losing the setting would cost more, and to whoever can least afford it.
29
+ * ⚠️ IT IS INHERITED BY THE KEYBOARD, THE PAD AND TOUCH, and the choice takes a sentence to explain. The old value was set
30
+ * by the child in some context, and there is no way to know which — the key did not record it, which is the defect. The
31
+ * ways out were three: lose their setting, guess a transport, or inherit for all. Inheriting is the only one that takes
32
+ * nothing from whoever depends on the setting, and the leak it keeps lasts only until the child touches the setting once
33
+ * on each device. Losing the setting would cost more, and to whoever can least afford it.
34
+ *
35
+ * 📌 NOT BY THE FOUR ONE-COMMAND TRANSPORTS (ADR-0249): there the default is the game's answer, and a value the child set
36
+ * on the keyboard is not a choice about how a spoken word or a look should behave in this game.
42
37
  *
43
38
  * It is also the pattern this repository chose for this same value before: the old key stays where it is — it is the
44
39
  * child's data, not mine to delete, and keeping it is what makes a way back possible.
@@ -52,15 +47,25 @@ export interface LatchReading {
52
47
  readonly fromLegacy: boolean | null;
53
48
  /** The factory default (`DEFAULTS.toggleMove` / `DEFAULTS.toggleRun`). */
54
49
  readonly byDefault: boolean;
50
+ /**
51
+ * THE GAME'S ANSWER, NOW: `GameDeclaration.holdsKeys()` (ADR-0249). The default on the one-command transports.
52
+ *
53
+ * ⚠️ READ WHEN THE LATCH IS RESOLVED, not once at boot: a game changes it between stages (ADR-0084), and a latch resolved
54
+ * from a stale answer would keep a quiz stage latched because the stage before it held keys. REQUIRED, like `holdsKeys`
55
+ * itself: both values can be wrong, so there is no safe default to fall back on.
56
+ */
57
+ readonly gameHoldsKeys: boolean;
55
58
  }
59
+ /** The two defaults a resolution needs from outside storage — the factory's and the game's. */
60
+ export type LatchDefaults = Pick<LatchReading, 'byDefault' | 'gameHoldsKeys'>;
56
61
  /**
57
62
  * This transport's toggle, resolved.
58
63
  *
59
- * The order: one-command transport → ALWAYS on, and nothing else is read · this transport's value · the legacy value ·
64
+ * The order: this transport's stored value · on a one-command transport, the game's `holdsKeys()` · the legacy value ·
60
65
  * the factory default.
61
66
  *
62
- * ⚠️ THE ONE-COMMAND TRANSPORT COMES FIRST, and not as a shortcut: if it read the stored value first, a child who had
63
- * turned the toggle off on the keyboard would inherit that `false` through the legacy key and be left with a gaze control
64
- * that does not respond — the worst defect possible, on the control of whoever has fewest alternatives.
67
+ * ⚠️ THE STORED VALUE COMES FIRST ON EVERY TRANSPORT (ADR-0249): the child's choice for this device wins over any default,
68
+ * including the game's. And a stored `false` is a VALUE, not an absence — the `!== null` is what keeps a latch the child
69
+ * turned off from coming back by itself.
65
70
  */
66
71
  export declare function latchOf(transport: string, l: LatchReading): boolean;
@@ -14,45 +14,30 @@
14
14
  //
15
15
  // The key mapping is already kept per transport, and always was. This is the same thing.
16
16
  //
17
- // ========================= AND FOR FOUR TRANSPORTS IT IS NO CHOICE AT ALL =========================
18
- // ⚠️ Eyes, face, gestures and speech emit ONE COMMAND AT A TIME. There is no looking left and at the jump button at once;
19
- // no saying two words simultaneously. On them the toggle is not a preference — it is the only way the control works, and
20
- // offering it as an option would offer a child the choice of a control that does not work.
21
- //
22
- // This resolves, in passing, a tension ADR-0084 had with its own rule "a stored value means a choice": the toggle
23
- // switching itself on for the camera was an exception to that rule. It no longer is, because on these transports it was
24
- // never a stored value — it is a property of the transport.
25
- //
26
- // The rule was written before those four transports existed, so they arrived COVERED instead of arriving at an
27
- // exception someone would have to remember to open.
17
+ // ========================= ON FOUR TRANSPORTS THE GAME SETS THE DEFAULT (ADR-0249) =========================
18
+ // Eyes, face, gestures and speech emit ONE COMMAND AT A TIME: a word or a look is a tap, never a hold. Whether that tap
19
+ // should keep going is the GAME's to say — in a platform game «direita» keeps the character walking, in a quiz «abaixo»
20
+ // moves the cursor once — and the game already says it: `GameDeclaration.holdsKeys()`. So on these four the latch STARTS
21
+ // as the game answers, and the child's stored choice for that transport, when there is one, wins (ADR-0104 §C: a default
22
+ // is not a lock). Keyboard, pad and touch keep the factory default and the legacy inheritance below.
28
23
  //
29
24
  // A leaf module: it imports nothing, not even the `platform/storage` whose keys it builds.
30
25
  /**
31
- * The transports that emit ONE COMMAND AT A TIME, on which the toggle is always on.
26
+ * The transports that emit ONE COMMAND AT A TIME, on which the latch's default is the game's `holdsKeys()` (ADR-0249).
32
27
  *
33
28
  * The values are transport names, which stay Portuguese like the rest of that vocabulary (`teclado`, `toque`): they are
34
29
  * stored, and renaming a stored value loses what the child saved.
35
30
  */
36
31
  export const ONE_COMMAND_AT_A_TIME = new Set(['olhos', 'rosto', 'gestos', 'fala']);
37
32
  /**
38
- * Is the toggle always on for this transport?
33
+ * Does this transport's latch start where the GAME says (ADR-0249)?
39
34
  *
40
- * ⚠️ "Always on" and "on by default" are different things, and the difference is ADR-0104 §C's: a default can be changed,
41
- * and changing it here would make the control unusable. So the stored value is not even read on these transports — see
42
- * `latchOf`.
35
+ * `true` on the four one-command transports: with nothing stored for them, the latch is the game's `holdsKeys()`. The
36
+ * option is offered on every transport alike; this answers only where the default comes from.
43
37
  */
44
- export function latchAlwaysOn(transport) {
38
+ export function latchDefaultFromGame(transport) {
45
39
  return ONE_COMMAND_AT_A_TIME.has(transport);
46
40
  }
47
- /**
48
- * Should the option be OFFERED for this transport?
49
- *
50
- * The opposite of `latchAlwaysOn`, with a name of its own because a different caller asks: one decides the state, the
51
- * other whether to draw the button. A panel that drew the button and ignored the click would be worse than not drawing it.
52
- */
53
- export function latchIsOptional(transport) {
54
- return !latchAlwaysOn(transport);
55
- }
56
41
  /**
57
42
  * The toggle's storage key, with the transport in its name.
58
43
  *
@@ -68,11 +53,14 @@ export function latchKey(base, player, transport) {
68
53
  /**
69
54
  * The OLD key, per player and without a transport. Still read, never written again.
70
55
  *
71
- * ⚠️ IT IS INHERITED BY EVERY TRANSPORT, and the choice takes a sentence to explain. The old value was set by the child in
72
- * some context, and there is no way to know which — the key did not record it, which is the defect. The ways out were
73
- * three: lose their setting, guess a transport, or inherit for all. Inheriting for all is the only one that takes nothing
74
- * from whoever depends on the setting, and the leak it keeps lasts only until the child touches the setting once on each
75
- * device. Losing the setting would cost more, and to whoever can least afford it.
56
+ * ⚠️ IT IS INHERITED BY THE KEYBOARD, THE PAD AND TOUCH, and the choice takes a sentence to explain. The old value was set
57
+ * by the child in some context, and there is no way to know which — the key did not record it, which is the defect. The
58
+ * ways out were three: lose their setting, guess a transport, or inherit for all. Inheriting is the only one that takes
59
+ * nothing from whoever depends on the setting, and the leak it keeps lasts only until the child touches the setting once
60
+ * on each device. Losing the setting would cost more, and to whoever can least afford it.
61
+ *
62
+ * 📌 NOT BY THE FOUR ONE-COMMAND TRANSPORTS (ADR-0249): there the default is the game's answer, and a value the child set
63
+ * on the keyboard is not a choice about how a spoken word or a look should behave in this game.
76
64
  *
77
65
  * It is also the pattern this repository chose for this same value before: the old key stays where it is — it is the
78
66
  * child's data, not mine to delete, and keeping it is what makes a way back possible.
@@ -83,18 +71,18 @@ export function legacyLatchKey(base, player) {
83
71
  /**
84
72
  * This transport's toggle, resolved.
85
73
  *
86
- * The order: one-command transport → ALWAYS on, and nothing else is read · this transport's value · the legacy value ·
74
+ * The order: this transport's stored value · on a one-command transport, the game's `holdsKeys()` · the legacy value ·
87
75
  * the factory default.
88
76
  *
89
- * ⚠️ THE ONE-COMMAND TRANSPORT COMES FIRST, and not as a shortcut: if it read the stored value first, a child who had
90
- * turned the toggle off on the keyboard would inherit that `false` through the legacy key and be left with a gaze control
91
- * that does not respond — the worst defect possible, on the control of whoever has fewest alternatives.
77
+ * ⚠️ THE STORED VALUE COMES FIRST ON EVERY TRANSPORT (ADR-0249): the child's choice for this device wins over any default,
78
+ * including the game's. And a stored `false` is a VALUE, not an absence — the `!== null` is what keeps a latch the child
79
+ * turned off from coming back by itself.
92
80
  */
93
81
  export function latchOf(transport, l) {
94
- if (latchAlwaysOn(transport))
95
- return true;
96
82
  if (l.fromTransport !== null)
97
83
  return l.fromTransport;
84
+ if (latchDefaultFromGame(transport))
85
+ return l.gameHoldsKeys;
98
86
  if (l.fromLegacy !== null)
99
87
  return l.fromLegacy;
100
88
  return l.byDefault;
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
- import { type LatchReading } from './latch-scope.js';
2
+ import { type LatchReading, type LatchDefaults } from './latch-scope.js';
3
3
  /** The minimum of `platform/storage` this needs. Injected, so the gate needs no browser. */
4
4
  export interface LatchStore {
5
5
  /** ⚠️ The RAW read, not `getBool`. See `readTriState`. */
@@ -21,24 +21,21 @@ export declare function readTriState(store: LatchStore, key: string): boolean |
21
21
  /**
22
22
  * THE WHOLE READING the rule asks for, built from storage.
23
23
  *
24
- * `base` is `togglemove` or `togglerun` — the two names that already exist in the child's storage.
24
+ * `base` is `togglemove` or `togglerun` — the two names that already exist in the child's storage. `defaults` carries what
25
+ * storage does not know: the factory default and the game's `holdsKeys()` answer now (ADR-0249).
25
26
  */
26
- export declare function readLatch(store: LatchStore, base: string, player: number, transport: string, fallback: boolean): LatchReading;
27
+ export declare function readLatch(store: LatchStore, base: string, player: number, transport: string, defaults: LatchDefaults): LatchReading;
27
28
  /**
28
29
  * THIS PLAYER'S TOGGLE ON THIS TRANSPORT — the whole question, in one call.
29
30
  *
30
31
  * 📌 SWITCHING TRANSPORT SWITCHES THE ANSWER WITHOUT WRITING ANYTHING, clause 1 of ADR-0113 in code: the value belongs to
31
32
  * the controls' mapping, like a caps lock, and changing controls is changing mapping.
32
33
  */
33
- export declare function storedLatch(store: LatchStore, base: string, player: number, transport: string, fallback: boolean): boolean;
34
+ export declare function storedLatch(store: LatchStore, base: string, player: number, transport: string, defaults: LatchDefaults): boolean;
34
35
  /**
35
- * WRITES THE CHILD'S CHOICE for the transport in use. Returns whether it wrote.
36
+ * WRITES THE CHILD'S CHOICE for the transport in use — on EVERY transport (ADR-0249).
36
37
  *
37
- * ⚠️ IT REFUSES ON ONE-COMMAND TRANSPORTS, and the refusal is a returned `false`, not a throw: on eyes, face, gestures and
38
- * speech the toggle is what makes the input work (ADR-0113 clause 3), so there is no choice to write. The caller uses the
39
- * answer to DISABLE the control WITH A REASON — the other half, which lives in the interface, not here.
40
- *
41
- * 📌 Writing anyway would be worse than useless: the child would touch the icon, the value would go to disk, and the game
42
- * would keep ignoring it — a control that lies about having worked.
38
+ * 📌 Eyes, face, gestures and speech included: their latch starts as the game answers `holdsKeys()`, and what is written
39
+ * here is the child changing that default for that device. The stored value is what `latchOf` reads first.
43
40
  */
44
- export declare function writeLatch(write: (key: string, isOn: boolean) => void, base: string, player: number, transport: string, isOn: boolean): boolean;
41
+ export declare function writeLatch(write: (key: string, isOn: boolean) => void, base: string, player: number, transport: string, isOn: boolean): void;
@@ -3,8 +3,8 @@
3
3
  //
4
4
  // ========================= WHAT THIS MODULE IS, AND WHY IT IS APART =========================
5
5
  // `input/latch-scope` is the RULE and touches nothing: it takes a finished `LatchReading` and answers. This module is the
6
- // one thing that was missing between it and the world — whoever goes to storage for the three values the rule asks for,
7
- // and whoever writes what the child chooses.
6
+ // one thing that was missing between it and the world — whoever goes to storage for the two stored values the rule asks
7
+ // for, and whoever writes what the child chooses. The two defaults (the factory's and the game's) arrive as an argument.
8
8
  //
9
9
  // 📌 APART ON PURPOSE, not for tidiness: the rule is pure and has its own gate; mixing storage into it would make every
10
10
  // case of the rule build a fake `localStorage` to assert something that does not depend on it. The same split
@@ -13,7 +13,7 @@
13
13
  // ⚠️ AND WHAT IT DOES NOT DO: it does not know WHICH transport is in use. That is `input/transport-in-use`'s, and it
14
14
  // arrives here as an argument. A storage module that guessed the transport would write one child's choice under another
15
15
  // device's key — in silence, the defect ADR-0113 exists to prevent.
16
- import { latchKey, legacyLatchKey, latchOf, latchIsOptional, } from './latch-scope.js';
16
+ import { latchKey, legacyLatchKey, latchOf, } from './latch-scope.js';
17
17
  /**
18
18
  * THREE STATES, NOT TWO: `true`, `false`, and NEVER WRITTEN.
19
19
  *
@@ -32,13 +32,15 @@ export function readTriState(store, key) {
32
32
  /**
33
33
  * THE WHOLE READING the rule asks for, built from storage.
34
34
  *
35
- * `base` is `togglemove` or `togglerun` — the two names that already exist in the child's storage.
35
+ * `base` is `togglemove` or `togglerun` — the two names that already exist in the child's storage. `defaults` carries what
36
+ * storage does not know: the factory default and the game's `holdsKeys()` answer now (ADR-0249).
36
37
  */
37
- export function readLatch(store, base, player, transport, fallback) {
38
+ export function readLatch(store, base, player, transport, defaults) {
38
39
  return {
39
40
  fromTransport: readTriState(store, latchKey(base, player, transport)),
40
41
  fromLegacy: readTriState(store, legacyLatchKey(base, player)),
41
- byDefault: fallback,
42
+ byDefault: defaults.byDefault,
43
+ gameHoldsKeys: defaults.gameHoldsKeys,
42
44
  };
43
45
  }
44
46
  /**
@@ -47,25 +49,18 @@ export function readLatch(store, base, player, transport, fallback) {
47
49
  * 📌 SWITCHING TRANSPORT SWITCHES THE ANSWER WITHOUT WRITING ANYTHING, clause 1 of ADR-0113 in code: the value belongs to
48
50
  * the controls' mapping, like a caps lock, and changing controls is changing mapping.
49
51
  */
50
- export function storedLatch(store, base, player, transport, fallback) {
51
- return latchOf(transport, readLatch(store, base, player, transport, fallback));
52
+ export function storedLatch(store, base, player, transport, defaults) {
53
+ return latchOf(transport, readLatch(store, base, player, transport, defaults));
52
54
  }
53
55
  /**
54
- * WRITES THE CHILD'S CHOICE for the transport in use. Returns whether it wrote.
56
+ * WRITES THE CHILD'S CHOICE for the transport in use — on EVERY transport (ADR-0249).
55
57
  *
56
- * ⚠️ IT REFUSES ON ONE-COMMAND TRANSPORTS, and the refusal is a returned `false`, not a throw: on eyes, face, gestures and
57
- * speech the toggle is what makes the input work (ADR-0113 clause 3), so there is no choice to write. The caller uses the
58
- * answer to DISABLE the control WITH A REASON — the other half, which lives in the interface, not here.
59
- *
60
- * 📌 Writing anyway would be worse than useless: the child would touch the icon, the value would go to disk, and the game
61
- * would keep ignoring it — a control that lies about having worked.
58
+ * 📌 Eyes, face, gestures and speech included: their latch starts as the game answers `holdsKeys()`, and what is written
59
+ * here is the child changing that default for that device. The stored value is what `latchOf` reads first.
62
60
  */
63
61
  // ⚠️ IT TAKES THE WRITER AND NOT A STORE: the mobility panel already has a `store: { setBool }` injected, and demanding an
64
62
  // object with raw `get`/`set` would force an adapter at the call site — where a second way of writing the same key is
65
63
  // born. A function is the minimum the write needs.
66
64
  export function writeLatch(write, base, player, transport, isOn) {
67
- if (!latchIsOptional(transport))
68
- return false;
69
65
  write(latchKey(base, player, transport), isOn);
70
- return true;
71
66
  }
@@ -1,6 +1,7 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
2
  import type { PlayerView } from '../core/entity.js';
3
3
  import { type LatchStore } from './latch-store.js';
4
+ import type { LatchDefaults } from './latch-scope.js';
4
5
  /**
5
6
  * The MINIMUM OF THE PLAYER the toggle touches — two fields, neither of them part of the game's contract.
6
7
  *
@@ -39,8 +40,8 @@ export declare function applyLatch(p: LatchPlayer, on: boolean): boolean;
39
40
  * the answer **without writing to storage**. A sync that stored the resolved value would erase, on the first edge, the
40
41
  * choice the child made on the other device.
41
42
  *
42
- * ⚠️ AND ON THE FOUR ASSISTED TRANSPORTS IT ANSWERS `true` WITHOUT CONSULTING ANYTHING — the rule lives in `latch-scope`
43
- * with its reason: on eyes, face, gestures and speech the toggle is what makes the input work, and inheriting a `false`
44
- * the child chose on the keyboard would leave them with a gaze control that does not respond.
43
+ * ⚠️ ON THE FOUR ONE-COMMAND TRANSPORTS THE DEFAULT IS THE GAME'S (ADR-0249) — `defaults.gameHoldsKeys`, which the caller
44
+ * reads from `holdsKeys()` when it calls: a platform game keeps walking on «direita», a quiz moves once on «abaixo», and a
45
+ * choice the child stored for that transport wins over both. The rule lives in `latch-scope`.
45
46
  */
46
- export declare function syncLatch(p: LatchPlayer, store: LatchStore, player: number, transport: string, byDefault: boolean): boolean;
47
+ export declare function syncLatch(p: LatchPlayer, store: LatchStore, player: number, transport: string, defaults: LatchDefaults): boolean;
@@ -34,10 +34,10 @@ export function applyLatch(p, on) {
34
34
  * the answer **without writing to storage**. A sync that stored the resolved value would erase, on the first edge, the
35
35
  * choice the child made on the other device.
36
36
  *
37
- * ⚠️ AND ON THE FOUR ASSISTED TRANSPORTS IT ANSWERS `true` WITHOUT CONSULTING ANYTHING — the rule lives in `latch-scope`
38
- * with its reason: on eyes, face, gestures and speech the toggle is what makes the input work, and inheriting a `false`
39
- * the child chose on the keyboard would leave them with a gaze control that does not respond.
37
+ * ⚠️ ON THE FOUR ONE-COMMAND TRANSPORTS THE DEFAULT IS THE GAME'S (ADR-0249) — `defaults.gameHoldsKeys`, which the caller
38
+ * reads from `holdsKeys()` when it calls: a platform game keeps walking on «direita», a quiz moves once on «abaixo», and a
39
+ * choice the child stored for that transport wins over both. The rule lives in `latch-scope`.
40
40
  */
41
- export function syncLatch(p, store, player, transport, byDefault) {
42
- return applyLatch(p, storedLatch(store, BASE_DA_MARCHA, player, transport, byDefault));
41
+ export function syncLatch(p, store, player, transport, defaults) {
42
+ return applyLatch(p, storedLatch(store, BASE_DA_MARCHA, player, transport, defaults));
43
43
  }
@@ -71,13 +71,18 @@ export function bindActive(gp, bd) {
71
71
  return false;
72
72
  }
73
73
  /** The snapshot when the CHILD recorded a map in the wizard: their directions fall back to the standard ones when the
74
- * binding is not active, so the D-pad and the stick stay alive beside what they chose. */
74
+ * binding is not active, so the D-pad and the stick stay alive beside what they chose.
75
+ * ⚠️ `start` and `select` are read AS POSITIONS, as the table's reading does: the wizard asks them and stores them, and a
76
+ * map read without `select` left a mapped pad with no door to the menus — not even as the one-button scan's switch
77
+ * (ADR-0155, ADR-0218 §4). */
75
78
  function actionsFromTheSavedMap(gp, custom) {
76
79
  const A = (k) => bindActive(gp, bindingAt(custom, k));
77
80
  const sd = stdDirs(gp);
78
81
  return {
79
82
  left: A('left') || sd.left, right: A('right') || sd.right, up: A('up') || sd.up, down: A('down') || sd.down,
80
- action2: A('action2'), action1: A('action1'), action4: A('action4'), action3: A('action3'), _start: A('action2') || A('start'), _pause: A('start'),
83
+ action2: A('action2'), action1: A('action1'), action4: A('action4'), action3: A('action3'),
84
+ start: A('start'), select: A('select'),
85
+ _start: A('action2') || A('start'), _pause: A('start'),
81
86
  };
82
87
  }
83
88
  /**
@@ -69,7 +69,10 @@ export interface PadWizardCtx {
69
69
  * the child the fourteen questions again at every visit, in silence. */
70
70
  maps: PadMaps;
71
71
  getGamepads: GetGamepads;
72
- /** The position's name in the GAME's word and the language of now; `null` = the game does not use it (the step is skipped). */
72
+ /**
73
+ * The position's name in the GAME's word and the language of now; `null` = the game does not use it (the step is skipped).
74
+ * ⚠️ Not asked about `start` and `select`: the wizard always asks them, in the engine's words (`SYSTEM_WORDS`).
75
+ */
73
76
  actionLabel: (action: string) => string | null;
74
77
  /** Shows and says the wizard's sentence. */
75
78
  say: (phrase: string) => void;
@@ -1,5 +1,7 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ import { SYSTEM } from '../core/actions.js';
2
3
  import { migrateControlMap } from './vocabulary-migration.js';
4
+ import { buttonName } from './touch.js';
3
5
  export const PADWIZ_ORDER = [
4
6
  // Directions first: they are what the child finds without thinking, and getting all four right gives confidence for
5
7
  // the other ten.
@@ -12,6 +14,29 @@ export const PADWIZ_ORDER = [
12
14
  // System last: `start` and `select` are usually the smallest and most hidden buttons.
13
15
  'start', 'select',
14
16
  ];
17
+ /**
18
+ * 🔴 THE SYSTEM'S TWO ARE ALWAYS ASKED, IN THE ENGINE'S WORDS (ADR-0122, ADR-0144 §1 and its erratum of 2026-09-26, ADR-0155).
19
+ * A game's preset may not name `start` or `select` (ADR-0144 §4, ADR-0155 §4 — refused at boot), so a wizard that asked only
20
+ * what the game names never asked them, and every pad it mapped had no quick pause and no menus: the pause no game may decline,
21
+ * declined by the pad. They are the system's, and `core/actions` (`SYSTEM`) says the engine may name them — the legend printed
22
+ * on the pad. The host's labeller is not asked about them.
23
+ * 📌 Each carries its QUESTION and its NAME: the name is the word the question says (START, SELECT), and it is how the progress
24
+ * line lists the position once mapped — never its id (ADR-0074: no abstract name reaches a person).
25
+ */
26
+ const SYSTEM_WORDS = {
27
+ start: { question: 'pad.wiz.stepStart', name: 'touch.start' },
28
+ select: { question: 'pad.wiz.stepSelect', name: 'touch.select' },
29
+ };
30
+ const systemWords = (action) => (SYSTEM.includes(action) ? SYSTEM_WORDS[action] : null);
31
+ /**
32
+ * 🔴 THE DEFAULT POSITIONS (ADR-0144, erratum of 2026-09-26 — the Dev: «as posições padrões são up, down, left, right, 1, 2, 3, 4,
33
+ * L1, L2, R1, R2, START e SELECT»). A game that names no position still gets a pad the child can map: these fourteen, in this
34
+ * order, each asked by its button's name (`input/touch.buttonName`, ADR-0165 — the names printed on the virtual pad).
35
+ */
36
+ const DEFAULT_ORDER = [
37
+ 'up', 'down', 'left', 'right', 'action1', 'action2', 'action3', 'action4',
38
+ 'leftShoulder', 'leftTrigger', 'rightShoulder', 'rightTrigger', 'start', 'select',
39
+ ];
15
40
  const KEY = (id) => 'incl_padmap_' + id;
16
41
  /**
17
42
  * THE CACHE OF STORED MAPS, one per ROOT (ADR-0232 D4). ⚠️ Not safe to share: two roots on two stores would read each
@@ -41,15 +66,35 @@ export function createPadWizard(ctx) {
41
66
  const { t } = ctx;
42
67
  let padWiz = null;
43
68
  /**
44
- * Walks to the next step THIS game uses, or closes if there is none left. ONE function: after the last named step the
45
- * wizard does not stay open pointing at a position the game does not use.
69
+ * THIS WIZARD'S STEPS, decided when it opens: the game's positions (`PADWIZ_ORDER`, those it names) and then START and SELECT;
70
+ * or, where the game names none, the fourteen defaults (`DEFAULT_ORDER`), all asked, in the engine's words.
71
+ */
72
+ let defaults = false;
73
+ let order = PADWIZ_ORDER;
74
+ const gameNamesAnyPosition = () => PADWIZ_ORDER.some((action) => systemWords(action) === null && !!ctx.actionLabel(action));
75
+ /** Is this step asked? Every default; else the game's positions when it names them; the system's two always (`SYSTEM_WORDS`). */
76
+ const asked = (action) => defaults || systemWords(action) !== null || !!ctx.actionLabel(action);
77
+ /**
78
+ * A position's word, the one its question said: the engine's for START and SELECT and for every default, the game's for the
79
+ * rest. ⚠️ A position the game no longer names (a cartridge mounted mid-wizard) has no word, and is left out rather than shown
80
+ * by its id.
81
+ */
82
+ const wordFor = (action) => {
83
+ const system = systemWords(action);
84
+ if (system)
85
+ return t(system.name);
86
+ return defaults ? buttonName(ctx.t, action) : ctx.actionLabel(action);
87
+ };
88
+ /**
89
+ * Walks to the next step asked, or closes if there is none left. ONE function: after the last step the wizard does not stay
90
+ * open pointing at a position nobody asks.
46
91
  */
47
92
  function advance() {
48
93
  if (!padWiz)
49
94
  return;
50
- while (padWiz.step < PADWIZ_ORDER.length && !ctx.actionLabel(PADWIZ_ORDER[padWiz.step]))
95
+ while (padWiz.step < order.length && !asked(order[padWiz.step]))
51
96
  padWiz.step++;
52
- if (padWiz.step >= PADWIZ_ORDER.length)
97
+ if (padWiz.step >= order.length)
53
98
  closeWizard(true);
54
99
  }
55
100
  function ask() {
@@ -58,21 +103,27 @@ export function createPadWizard(ctx) {
58
103
  advance();
59
104
  if (!padWiz)
60
105
  return; // it closed while advancing
61
- const action = PADWIZ_ORDER[padWiz.step];
62
- ctx.say(t('pad.wiz.step', { n: padWiz.step + 1, total: PADWIZ_ORDER.length, acao: ctx.actionLabel(action) }));
106
+ const action = order[padWiz.step];
107
+ const n = padWiz.step + 1, total = order.length;
108
+ const system = systemWords(action);
109
+ ctx.say(t(system?.question ?? 'pad.wiz.step', { n, total, acao: system ? '' : wordFor(action) }));
63
110
  ctx.onStep?.(action);
64
- // The empty list's dash stays raw on purpose: it is punctuation, not language.
65
- ctx.progress(t('pad.wiz.mapped', { lista: Object.keys(padWiz.map).join(' · ') || '—' }));
111
+ // What is mapped, in the words it was asked with (ADR-0074) — the map's keys are position ids. The empty list's dash stays
112
+ // raw on purpose: it is punctuation, not language.
113
+ const words = Object.keys(padWiz.map).map(wordFor).filter((word) => !!word);
114
+ ctx.progress(t('pad.wiz.mapped', { lista: words.join(' · ') || '—' }));
66
115
  }
67
116
  function wire(bd) {
68
117
  if (!padWiz)
69
118
  return;
70
- padWiz.map[PADWIZ_ORDER[padWiz.step]] = bd;
119
+ padWiz.map[order[padWiz.step]] = bd;
71
120
  padWiz.step++;
72
121
  padWiz.release = true; // requires letting go before the next step
73
122
  advance();
74
123
  }
75
124
  function begin(gi, id, phrase) {
125
+ defaults = !gameNamesAnyPosition();
126
+ order = defaults ? DEFAULT_ORDER : PADWIZ_ORDER;
76
127
  padWiz = { gi, id, step: -1, base: null, map: {}, release: false, baseWait: gi >= 0, axTrack: null, timer: null };
77
128
  ctx.say(phrase);
78
129
  ctx.onStep?.(null);