@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.
- package/README.md +32 -1
- package/app/css/style.css +216 -42
- package/app/public/vendor/fonts-licences/NOTICE.txt +166 -0
- package/app/public/vendor/fonts-licences/OFL-1.1.txt +86 -0
- package/app/public/vendor/fonts.css +11 -1175
- package/dist-pkg/boot/create-game.d.ts +84 -33
- package/dist-pkg/boot/create-game.js +708 -307
- package/dist-pkg/core/a11y-sr.d.ts +1 -1
- package/dist-pkg/core/a11y-sr.js +3 -5
- package/dist-pkg/core/accommodations.d.ts +26 -8
- package/dist-pkg/core/accommodations.js +27 -10
- package/dist-pkg/core/actions.d.ts +39 -10
- package/dist-pkg/core/actions.js +28 -6
- package/dist-pkg/core/contract.d.ts +0 -2
- package/dist-pkg/core/contract.js +0 -2
- package/dist-pkg/core/i18n.d.ts +36 -71
- package/dist-pkg/core/i18n.js +131 -198
- package/dist-pkg/core/session-clock.d.ts +23 -0
- package/dist-pkg/core/session-clock.js +37 -0
- package/dist-pkg/i18n/en.js +44 -49
- package/dist-pkg/i18n/es.js +44 -49
- package/dist-pkg/i18n/pt.js +49 -54
- package/dist-pkg/input/gamepad.d.ts +42 -11
- package/dist-pkg/input/gamepad.js +50 -15
- package/dist-pkg/input/key-default.d.ts +30 -0
- package/dist-pkg/input/key-default.js +60 -0
- package/dist-pkg/input/keyboard-runtime.d.ts +0 -4
- package/dist-pkg/input/keyboard.d.ts +0 -1
- package/dist-pkg/input/keydown.d.ts +5 -11
- package/dist-pkg/input/keydown.js +3 -3
- package/dist-pkg/input/latch-edge.d.ts +10 -2
- package/dist-pkg/input/latch-edge.js +4 -3
- package/dist-pkg/input/latch-scope.d.ts +27 -22
- package/dist-pkg/input/latch-scope.js +25 -37
- package/dist-pkg/input/latch-store.d.ts +9 -12
- package/dist-pkg/input/latch-store.js +13 -18
- package/dist-pkg/input/latch-sync.d.ts +5 -4
- package/dist-pkg/input/latch-sync.js +5 -5
- package/dist-pkg/input/pad-reading.js +7 -2
- package/dist-pkg/input/pad-wizard.d.ts +4 -1
- package/dist-pkg/input/pad-wizard.js +60 -9
- package/dist-pkg/input/switch-scan.d.ts +29 -12
- package/dist-pkg/input/switch-scan.js +15 -2
- package/dist-pkg/input/touch-bindings.d.ts +3 -6
- package/dist-pkg/input/touch.d.ts +17 -2
- package/dist-pkg/input/touch.js +55 -17
- package/dist-pkg/input/transport-in-use.d.ts +5 -5
- package/dist-pkg/input/transport-in-use.js +5 -5
- package/dist-pkg/input/transports.d.ts +0 -9
- package/dist-pkg/input/transports.js +1 -1
- package/dist-pkg/input/virtual-controller.d.ts +39 -3
- package/dist-pkg/input/virtual-controller.js +32 -4
- package/dist-pkg/input/voice-map.d.ts +27 -11
- package/dist-pkg/input/voice-map.js +41 -43
- package/dist-pkg/platform/audio-ambient.d.ts +0 -1
- package/dist-pkg/platform/audio-ambient.js +3 -1
- package/dist-pkg/platform/audio-mixer.js +4 -9
- package/dist-pkg/platform/audio-sonar.d.ts +8 -94
- package/dist-pkg/platform/audio-sonar.js +22 -207
- package/dist-pkg/platform/audio.d.ts +10 -1
- package/dist-pkg/platform/audio.js +35 -2
- package/dist-pkg/platform/choose-by-voice.d.ts +70 -0
- package/dist-pkg/platform/choose-by-voice.js +157 -0
- package/dist-pkg/platform/font-library.d.ts +77 -0
- package/dist-pkg/platform/font-library.js +98 -0
- package/dist-pkg/platform/font-library.json +721 -0
- package/dist-pkg/platform/heavy-catalogue.d.ts +46 -0
- package/dist-pkg/platform/heavy-catalogue.js +47 -14
- package/dist-pkg/platform/heavy-mirror.d.ts +3 -9
- package/dist-pkg/platform/heavy-mirror.js +14 -17
- package/dist-pkg/platform/heavy.d.ts +40 -8
- package/dist-pkg/platform/heavy.js +177 -22
- package/dist-pkg/platform/interruptible-speech.d.ts +15 -8
- package/dist-pkg/platform/interruptible-speech.js +37 -13
- package/dist-pkg/platform/listener-scope.js +22 -13
- package/dist-pkg/platform/locale-host.d.ts +7 -3
- package/dist-pkg/platform/locale-host.js +13 -2
- package/dist-pkg/platform/reading-in-worker.d.ts +24 -0
- package/dist-pkg/platform/reading-in-worker.js +38 -0
- package/dist-pkg/platform/reading-model.d.ts +21 -0
- package/dist-pkg/platform/reading-model.js +25 -0
- package/dist-pkg/platform/reading-runtime.js +13 -8
- package/dist-pkg/platform/reading.d.ts +12 -1
- package/dist-pkg/platform/reading.js +9 -1
- package/dist-pkg/platform/speech-recognition.d.ts +10 -1
- package/dist-pkg/platform/speech-recognition.js +29 -9
- package/dist-pkg/platform/speech.d.ts +10 -1
- package/dist-pkg/platform/speech.js +24 -13
- package/dist-pkg/platform/tts.d.ts +37 -4
- package/dist-pkg/platform/tts.js +279 -57
- package/dist-pkg/platform/voice-listener.d.ts +6 -2
- package/dist-pkg/platform/voice-listener.js +1 -1
- package/dist-pkg/platform/voice-plan.d.ts +13 -0
- package/dist-pkg/platform/voice-plan.js +57 -2
- package/dist-pkg/platform/vosk-runtime.d.ts +25 -0
- package/dist-pkg/platform/vosk-runtime.js +59 -1
- package/dist-pkg/platform/vosk-vocabulary.d.ts +6 -0
- package/dist-pkg/platform/vosk-vocabulary.js +178 -0
- package/dist-pkg/render/crt.d.ts +11 -9
- package/dist-pkg/render/crt.js +6 -10
- package/dist-pkg/render/cvd-matrices.d.ts +5 -1
- package/dist-pkg/render/cvd-matrices.js +5 -1
- package/dist-pkg/render/high-contrast.d.ts +1 -2
- package/dist-pkg/render/high-contrast.js +5 -1
- package/dist-pkg/render/viz-axes.d.ts +9 -0
- package/dist-pkg/render/viz-axes.js +15 -2
- package/dist-pkg/ui/aac-sets.d.ts +29 -24
- package/dist-pkg/ui/aac-sets.js +22 -30
- package/dist-pkg/ui/audio-choices.d.ts +10 -5
- package/dist-pkg/ui/audio-choices.js +14 -10
- package/dist-pkg/ui/camera-control.d.ts +47 -0
- package/dist-pkg/ui/camera-control.js +35 -1
- package/dist-pkg/ui/declared-words.d.ts +21 -0
- package/dist-pkg/ui/declared-words.js +66 -0
- package/dist-pkg/ui/drawing-problems.js +4 -3
- package/dist-pkg/ui/eye-control.js +17 -17
- package/dist-pkg/ui/face-control.js +15 -15
- package/dist-pkg/ui/fonts.d.ts +42 -8
- package/dist-pkg/ui/fonts.js +58 -24
- package/dist-pkg/ui/footer-scroll-driver.d.ts +14 -0
- package/dist-pkg/ui/footer-scroll-driver.js +201 -0
- package/dist-pkg/ui/footer-scroll.d.ts +38 -0
- package/dist-pkg/ui/footer-scroll.js +55 -0
- package/dist-pkg/ui/game-options.d.ts +14 -9
- package/dist-pkg/ui/game-options.js +41 -21
- package/dist-pkg/ui/hand-control.js +15 -15
- package/dist-pkg/ui/help-panel.d.ts +19 -8
- package/dist-pkg/ui/help-panel.js +15 -5
- package/dist-pkg/ui/hud-bands.d.ts +29 -12
- package/dist-pkg/ui/hud-bands.js +63 -25
- package/dist-pkg/ui/hud-row.d.ts +34 -0
- package/dist-pkg/ui/hud-row.js +80 -0
- package/dist-pkg/ui/hud.d.ts +0 -3
- package/dist-pkg/ui/layout.js +5 -2
- package/dist-pkg/ui/libras-avatar-clip.d.ts +30 -0
- package/dist-pkg/ui/libras-avatar-clip.js +86 -0
- package/dist-pkg/ui/libras-avatar-load.d.ts +52 -0
- package/dist-pkg/ui/libras-avatar-load.js +134 -0
- package/dist-pkg/ui/libras-avatar-plan.d.ts +102 -0
- package/dist-pkg/ui/libras-avatar-plan.js +211 -0
- package/dist-pkg/ui/libras-avatar-player.d.ts +28 -0
- package/dist-pkg/ui/libras-avatar-player.js +226 -0
- package/dist-pkg/ui/libras-avatar-stage.d.ts +37 -0
- package/dist-pkg/ui/libras-avatar-stage.js +208 -0
- package/dist-pkg/ui/libras-glosses.d.ts +28 -0
- package/dist-pkg/ui/libras-glosses.js +161 -0
- package/dist-pkg/ui/menu-intent.d.ts +29 -0
- package/dist-pkg/ui/menu-intent.js +35 -1
- package/dist-pkg/ui/menu-items.d.ts +10 -0
- package/dist-pkg/ui/menu-items.js +29 -0
- package/dist-pkg/ui/menu-nav.d.ts +40 -4
- package/dist-pkg/ui/menu-nav.js +132 -47
- package/dist-pkg/ui/panel-widgets.d.ts +34 -0
- package/dist-pkg/ui/panel-widgets.js +86 -0
- package/dist-pkg/ui/pause-icons.d.ts +30 -14
- package/dist-pkg/ui/pause-icons.js +106 -45
- package/dist-pkg/ui/scan-overlay.d.ts +3 -3
- package/dist-pkg/ui/scan-overlay.js +11 -3
- package/dist-pkg/ui/screen-text.d.ts +25 -0
- package/dist-pkg/ui/screen-text.js +152 -0
- package/dist-pkg/ui/session-clock.d.ts +32 -0
- package/dist-pkg/ui/session-clock.js +67 -0
- package/dist-pkg/ui/settings-aac.d.ts +3 -1
- package/dist-pkg/ui/settings-aac.js +32 -13
- package/dist-pkg/ui/settings-audio.d.ts +10 -5
- package/dist-pkg/ui/settings-audio.js +101 -35
- package/dist-pkg/ui/settings-controls.d.ts +0 -4
- package/dist-pkg/ui/settings-mobility.d.ts +3 -6
- package/dist-pkg/ui/settings-mobility.js +4 -46
- package/dist-pkg/ui/settings-motion.js +2 -2
- package/dist-pkg/ui/settings-panel.d.ts +10 -0
- package/dist-pkg/ui/settings-panel.js +25 -1
- package/dist-pkg/ui/settings-typo.d.ts +5 -6
- package/dist-pkg/ui/settings-typo.js +20 -11
- package/dist-pkg/ui/settings-visual.js +2 -2
- package/dist-pkg/ui/shell.d.ts +1 -3
- package/dist-pkg/ui/shell.js +8 -4
- package/dist-pkg/ui/title.d.ts +2 -11
- package/dist-pkg/ui/title.js +39 -6
- package/dist-pkg/ui/top-band.d.ts +5 -3
- package/dist-pkg/ui/top-band.js +21 -25
- package/dist-pkg/ui/typo-choices.d.ts +3 -3
- package/dist-pkg/ui/typo-choices.js +9 -8
- package/dist-pkg/ui/vlibras.d.ts +71 -27
- package/dist-pkg/ui/vlibras.js +116 -44
- package/dist-pkg/ui/voice-control.d.ts +23 -1
- package/dist-pkg/ui/voice-control.js +149 -16
- package/dist-pkg/ui/voice-settings.d.ts +2 -3
- package/dist-pkg/ui/voice-settings.js +53 -3
- package/dist-pkg/ui/where-the-child-is.js +2 -2
- package/docs/CREDITS.md +122 -10
- package/docs/LICENSES.md +36 -7
- package/package.json +34 -9
- package/scripts/check-cartridge.mjs +78 -0
- package/scripts/game-build.d.mts +25 -0
- package/scripts/game-build.mjs +144 -0
- package/scripts/heavy-into-the-delivery.mjs +284 -40
- package/scripts/libras-avatar.json +680 -0
- package/scripts/libras-avatar.mjs +246 -0
- package/scripts/libras-glosses/gloss.py +95 -0
- package/scripts/libras-glosses/pyproject.toml +32 -0
- package/scripts/libras-glosses/uv.lock +781 -0
- package/scripts/libras-glosses.mjs +351 -0
- package/scripts/licences/OFL-1.1.txt +86 -0
- package/scripts/licences/UFL-1.0.txt +96 -0
- package/scripts/licences/fonts.mjs +389 -0
- package/scripts/licences/third-party.mjs +35 -21
- package/app/public/vendor/fonts/bitter-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/bitter-var.woff2 +0 -0
- package/app/public/vendor/fonts/bodonimoda-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/bodonimoda-var.woff2 +0 -0
- package/app/public/vendor/fonts/cat-abril_fatface-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-abril_fatface-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-adlam_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-adlam_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-agu_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-agu_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-alfa_slab_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-alfa_slab_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-are_you_serious-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-are_you_serious-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-asimovian-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-asimovian-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-atkinson_hyperlegible_next-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bakbak_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bakbak_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bangers-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bangers-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-barriecito-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-barriecito-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-berkshire_swash-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-berkshire_swash-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bevan-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bevan-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bitcount-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bitcount-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bowlby_one_sc-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bowlby_one_sc-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bungee_shade-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-bungee_shade-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-charm-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-cherry_bomb_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-cherry_bomb_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chokokutai-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chokokutai-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chonburi-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-chonburi-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-climate_crisis-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-climate_crisis-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-cookie-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-dela_gothic_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-dela_gothic_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-fascinate_inline-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-fascinate_inline-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ga_maamli-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ga_maamli-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-itim-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-itim-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-jacquard_24-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-jacquard_24-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kablammo-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kablammo-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-kalam-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-katibeh-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-katibeh-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lemonada-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lemonada-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lilita_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lilita_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lobster-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-lobster-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-luckiest_guy-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-luckiest_guy-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-marhey-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-marhey-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-modak-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-modak-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-momo_signature-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-momo_signature-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monofett-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monofett-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monomakh-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monomakh-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monoton-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-monoton-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-nerko_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-nerko_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_adlam-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_adlam-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_arabic-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_arabic-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_devanagari-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_devanagari-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_hebrew-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_hebrew-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_jp-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_jp-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_khmer-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_khmer-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_kr-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_kr-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_sc-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_sc-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_thai-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-noto_sans_thai-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ole-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ole-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pacifico-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pacifico-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-patrick_hand-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-patrick_hand-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-petit_formal_script-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-petit_formal_script-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pixelify_sans-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-pixelify_sans-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-plaster-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-plaster-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ar_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_at-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_at_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_nsw-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_nsw_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_qld-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_qld_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_sa-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_sa_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_tas-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_tas_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_vic-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_au_vic_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_vlg-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_vlg_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_wal-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_be_wal_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_br_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ca_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cl_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_co_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cu_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cz-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_cz_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_grund-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_grund_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_la-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_la_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_sas-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_sas_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_va-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_de_va_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_loopet-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_loopet_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_uloopet-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_dk_uloopet_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_es_deco_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_es_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_moderne-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_moderne_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_trad-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_fr_trad_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_gb_j_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_gb_s_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr_lijeva-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hr_lijeva_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hu-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_hu_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_id-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_id_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ie-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ie_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_in-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_in_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_is-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_is_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_moderna-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_moderna_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_trad-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_it_trad_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_mx_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ng_modern-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ng_modern_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nl-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nl_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_no-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_no_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz_basic-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz_basic_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_nz_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pe_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pl-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pl_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_pt_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ro-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_ro_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_sk-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_sk_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_tz-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_tz_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_us_modern_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_us_trad_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_vn-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_vn_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_za-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-playwrite_za_guides-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-potta_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-potta_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranchers-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranchers-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ranga-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-risque-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-risque-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-rowdies-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruge_boogie-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruge_boogie-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruslan_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-ruslan_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sacramento-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sacramento-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sancreek-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sancreek-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sankofa_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sankofa_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sedgwick_ave_display-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sedgwick_ave_display-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-shantell_sans-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-shantell_sans-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-smokum-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-smokum-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-solitreo-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-solitreo-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-spicy_rice-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-spicy_rice-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sriracha-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-sriracha-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-srisakdi-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-stix_two_math-400-0.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-tillana-700.woff2 +0 -0
- package/app/public/vendor/fonts/cat-titan_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-titan_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yatra_one-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yatra_one-400.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yomogi-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/cat-yomogi-400.woff2 +0 -0
- package/app/public/vendor/fonts/dmserifdisplay-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/dmserifdisplay-400.woff2 +0 -0
- package/app/public/vendor/fonts/domine-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/domine-var.woff2 +0 -0
- package/app/public/vendor/fonts/fondamento-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/fondamento-400.woff2 +0 -0
- package/app/public/vendor/fonts/fraunces-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/fraunces-var.woff2 +0 -0
- package/app/public/vendor/fonts/fredoka-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/fredoka-var.woff2 +0 -0
- package/app/public/vendor/fonts/inter-400.woff2 +0 -0
- package/app/public/vendor/fonts/inter-700.woff2 +0 -0
- package/app/public/vendor/fonts/jakarta-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/jakarta-var.woff2 +0 -0
- package/app/public/vendor/fonts/lato-400.woff2 +0 -0
- package/app/public/vendor/fonts/lato-700.woff2 +0 -0
- package/app/public/vendor/fonts/literata-400.woff2 +0 -0
- package/app/public/vendor/fonts/literata-700.woff2 +0 -0
- package/app/public/vendor/fonts/lora-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/lora-var.woff2 +0 -0
- package/app/public/vendor/fonts/merriweather-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/merriweather-var.woff2 +0 -0
- package/app/public/vendor/fonts/newsreader-400.woff2 +0 -0
- package/app/public/vendor/fonts/newsreader-700.woff2 +0 -0
- package/app/public/vendor/fonts/notosans-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/notosans-var.woff2 +0 -0
- package/app/public/vendor/fonts/nunito-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/nunito-var.woff2 +0 -0
- package/app/public/vendor/fonts/opendyslexic-400.woff2 +0 -0
- package/app/public/vendor/fonts/opensans-400.woff2 +0 -0
- package/app/public/vendor/fonts/opensans-700.woff2 +0 -0
- package/app/public/vendor/fonts/pinyon-400.woff2 +0 -0
- package/app/public/vendor/fonts/playfair-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/playfair-var.woff2 +0 -0
- package/app/public/vendor/fonts/pressstart-400.woff2 +0 -0
- package/app/public/vendor/fonts/quattro-400.woff2 +0 -0
- package/app/public/vendor/fonts/quattro-700.woff2 +0 -0
- package/app/public/vendor/fonts/quicksand-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/quicksand-var.woff2 +0 -0
- package/app/public/vendor/fonts/robotoflex-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/robotoflex-var.woff2 +0 -0
- package/app/public/vendor/fonts/sora-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/sora-var.woff2 +0 -0
- package/app/public/vendor/fonts/sourcesans-400.woff2 +0 -0
- package/app/public/vendor/fonts/sourcesans-700.woff2 +0 -0
- package/app/public/vendor/fonts/sourceserif-400.woff2 +0 -0
- package/app/public/vendor/fonts/sourceserif-700.woff2 +0 -0
- package/app/public/vendor/fonts/spacegrotesk-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/spacegrotesk-var.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-400.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/spectral-700.woff2 +0 -0
- package/app/public/vendor/fonts/teachers-var-ext.woff2 +0 -0
- package/app/public/vendor/fonts/teachers-var.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-400-ext.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-400.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-700-ext.woff2 +0 -0
- package/app/public/vendor/fonts/ubuntu-700.woff2 +0 -0
- package/app/public/vendor/fonts/ufmag-400.woff2 +0 -0
- package/dist-pkg/platform/guide-intensity.d.ts +0 -39
- package/dist-pkg/platform/guide-intensity.js +0 -71
- package/dist-pkg/ui/latch-refusal.d.ts +0 -33
- package/dist-pkg/ui/latch-refusal.js +0 -60
|
@@ -30,6 +30,8 @@ export const OVERLAY_SCOPE_SELECTOR = '#game-region .overlay';
|
|
|
30
30
|
* the point of use runs on every `fillExplain`.
|
|
31
31
|
*/
|
|
32
32
|
export const EXPLAIN_IDLE = 'menu.explainIdle';
|
|
33
|
+
/** The pause cards: the layer under the first overlay, since a panel opens from the card's options list. */
|
|
34
|
+
const PAUSE_CARD_SCOPE_SELECTOR = '#game-region .screen-pause';
|
|
33
35
|
/** Initial z-index of the stack: the first overlay brought to the front gets 61. */
|
|
34
36
|
export const OVERLAY_BASE_Z = 60;
|
|
35
37
|
// ---------------------------------------------------------------------------------------------------------
|
|
@@ -198,10 +200,27 @@ export function initSettingsPanel(ctx) {
|
|
|
198
200
|
if (focusable && opener !== el && !isInside)
|
|
199
201
|
openerOf.set(el.id, opener);
|
|
200
202
|
el.style.zIndex = String(++ovZ);
|
|
203
|
+
syncLayers();
|
|
201
204
|
const card = el.querySelector('.overlay__card');
|
|
202
205
|
if (card)
|
|
203
206
|
fillExplain(card);
|
|
204
207
|
}
|
|
208
|
+
/*
|
|
209
|
+
* 🔴 THE MODAL BOUNDARY IS AT THE FRONT CARD, and only there (ADR-0130 rule 1: «focus, escape and the modal boundary all
|
|
210
|
+
* have to be right for each layer»). Every dialog card says `aria-modal="true"`, so with a panel open over another there
|
|
211
|
+
* were two modal dialogs alive at once, and which one a screen reader treats as THE dialog is left to each reader's
|
|
212
|
+
* heuristics — the lower card's rows could be reached by a virtual cursor while the child is in the front one. `inert`
|
|
213
|
+
* takes every layer under the front one out of the accessibility tree, the tab order and the pointer, by the platform's
|
|
214
|
+
* own rule rather than by a reader's guess. Only VISIBLE layers are made inert; a hidden one is left clean, so it opens
|
|
215
|
+
* clean.
|
|
216
|
+
*/
|
|
217
|
+
function syncLayers() {
|
|
218
|
+
const top = topVisibleOverlay();
|
|
219
|
+
for (const o of ctx.$$(OVERLAY_SCOPE_SELECTOR))
|
|
220
|
+
o.inert = !!top && !o.hidden && o !== top;
|
|
221
|
+
for (const c of ctx.$$(PAUSE_CARD_SCOPE_SELECTOR))
|
|
222
|
+
c.inert = !!top && !c.hidden;
|
|
223
|
+
}
|
|
205
224
|
/**
|
|
206
225
|
* Returns focus to whoever opened dialog `id`. True if it succeeded.
|
|
207
226
|
*
|
|
@@ -213,6 +232,8 @@ export function initSettingsPanel(ctx) {
|
|
|
213
232
|
* another that already closed, and then the caller decides (hence the boolean).
|
|
214
233
|
*/
|
|
215
234
|
function restoreFocus(id) {
|
|
235
|
+
// the layer below comes out of `inert` BEFORE the focus goes back into it: an inert element refuses focus
|
|
236
|
+
syncLayers();
|
|
216
237
|
const opener = openerOf.get(id);
|
|
217
238
|
openerOf.delete(id);
|
|
218
239
|
if (!opener)
|
|
@@ -234,6 +255,9 @@ export function initSettingsPanel(ctx) {
|
|
|
234
255
|
if (!entry)
|
|
235
256
|
return false;
|
|
236
257
|
entry.close();
|
|
258
|
+
// a closer that returns no focus (a host's own, or `menu-nav.dialogBack`'s fallback) still has to leave the boundary at
|
|
259
|
+
// the card now in front, before `dialogBack` puts the focus there — an inert card refuses it
|
|
260
|
+
syncLayers();
|
|
237
261
|
return true;
|
|
238
262
|
}
|
|
239
263
|
function escapeTarget() {
|
|
@@ -252,7 +276,7 @@ export function initSettingsPanel(ctx) {
|
|
|
252
276
|
return topByZ(visible, ctx.computedZ);
|
|
253
277
|
}
|
|
254
278
|
return {
|
|
255
|
-
frontOverlay, fillExplain, register, closeById, escapeTarget, topVisibleOverlay, restoreFocus,
|
|
279
|
+
frontOverlay, fillExplain, register, closeById, escapeTarget, topVisibleOverlay, restoreFocus, syncLayers,
|
|
256
280
|
registeredIds: () => [...registry.keys()],
|
|
257
281
|
};
|
|
258
282
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
2
|
import type { Translate } from '../core/i18n.js';
|
|
3
|
-
/** Minimal DOM-selector shape (matches ui/dom.ts's `$`). */
|
|
4
|
-
export type { DomQuery } from '../core/dom-query.js';
|
|
5
3
|
/** Minimal platform/storage.ts shape this module needs (get/set only — no direct localStorage access). */
|
|
6
4
|
export interface TypoStore {
|
|
7
5
|
get(key: string, fallback?: string | null): string | null;
|
|
@@ -32,13 +30,14 @@ export interface SettingsTypoCtx {
|
|
|
32
30
|
/**
|
|
33
31
|
* IS THIS FAMILY INSTALLED ON THE DEVICE? — in production, `(f) => doc.fonts.check(\`16px "${f}"\`)`.
|
|
34
32
|
*
|
|
35
|
-
* It turns ADR-0012's «enquanto» into code:
|
|
36
|
-
*
|
|
33
|
+
* It turns ADR-0012's «enquanto» into code: an `off` face stays disabled WHILE none of its families is present, and
|
|
34
|
+
* becomes available again when the adult installs one. (The ronde no longer depends on it: its stack ends in the
|
|
35
|
+
* packaged Cookie, ADR-0154.)
|
|
37
36
|
*
|
|
38
37
|
* ⚠️ INJECTED, and `document.fonts` is NEVER read here, by the rule this file already follows for `$`: a browser
|
|
39
38
|
* global in a module that runs in node is a boot waiting to crash.
|
|
40
|
-
* 📌 OPTIONAL, and here the default really is safe: with no detector
|
|
41
|
-
*
|
|
39
|
+
* 📌 OPTIONAL, and here the default really is safe: with no detector an `off` row stays disabled WITH its message, and
|
|
40
|
+
* the message says what to install. The default state is actionable.
|
|
42
41
|
*/
|
|
43
42
|
fontInstalled?: (family: string) => boolean;
|
|
44
43
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// `root` (the element the chosen font is applied to — document.documentElement in production). Overlay open/close
|
|
5
5
|
// plumbing (frontOverlay, focus management, Escape handling) is the SHARED helper every settings panel uses. The font
|
|
6
6
|
// catalog itself (FONT_GROUPS/FONT_BY_KEY) lives in ./fonts.js — imported here, never duplicated.
|
|
7
|
-
import { FONT_BY_KEY, DEFAULT_FONT_KEY, faceAvailable, faceScale } from './fonts.js';
|
|
7
|
+
import { FONT_BY_KEY, DEFAULT_FONT_KEY, faceAvailable, faceScale, familyStack } from './fonts.js';
|
|
8
8
|
import { markChanged, markMenuChanged, CHANGED_CLASS } from './changed-mark.js';
|
|
9
9
|
// ---------------------------------------------------------------------------------------------
|
|
10
10
|
// Pure logic (no `document`, testable in node)
|
|
@@ -17,8 +17,7 @@ import { controlRow, labelRow, sectionHeader } from './panel-widgets.js';
|
|
|
17
17
|
/*
|
|
18
18
|
* 🎯 WHAT A TYPOGRAPHY CHOICE IS lives in `./typo-choices.js`, and this file keeps the work its name always described:
|
|
19
19
|
* finding the nodes it reaches and never created, wiring them, and reflecting the choice. No alias left behind — a
|
|
20
|
-
* re-export would keep alive a path nothing here uses
|
|
21
|
-
* re-exports (#204).
|
|
20
|
+
* re-export would keep alive a published path nothing here uses, surface with no consumer (#204).
|
|
22
21
|
*/
|
|
23
22
|
import { typoGroups, typoRowSpec, fontCssTarget } from './typo-choices.js';
|
|
24
23
|
/**
|
|
@@ -77,8 +76,9 @@ export function mountTypoInside(t, ctx, list, fontKey, isInstalled) {
|
|
|
77
76
|
/** What the kit does not know about a face: the face itself on the label, and the note in the reading face. */
|
|
78
77
|
function dressRow(where, row) {
|
|
79
78
|
const label = where.querySelector(':scope > span');
|
|
79
|
+
// the whole stack, each family quoted: the ronde's label must draw in Cookie on a device without the three (ADR-0154)
|
|
80
80
|
if (label)
|
|
81
|
-
label.style.fontFamily =
|
|
81
|
+
label.style.fontFamily = familyStack(row.fam);
|
|
82
82
|
const note = where.querySelector('.opt-hint');
|
|
83
83
|
if (note) {
|
|
84
84
|
note.style.fontFamily = 'var(--font)';
|
|
@@ -90,8 +90,8 @@ function dressRow(where, row) {
|
|
|
90
90
|
*
|
|
91
91
|
* 🔴 THE ● / ○ MARK EXISTS BECAUSE COLOUR IS NOT STATE (see `CHOSEN_MARK`).
|
|
92
92
|
*
|
|
93
|
-
* 📌 THE LOCK is reflected and not built, because it can CHANGE: `
|
|
94
|
-
* installs one of the faces
|
|
93
|
+
* 📌 THE LOCK is reflected and not built, because it can CHANGE: an `off` face becomes available the instant the adult
|
|
94
|
+
* installs one of the faces its message names (ADR-0012, the word «enquanto»).
|
|
95
95
|
*/
|
|
96
96
|
function reflectTypo(list, fontKey, isInstalled) {
|
|
97
97
|
// Walks what EXISTS in the list, not the catalogue: reflecting is about the nodes already there, and asking the
|
|
@@ -120,14 +120,16 @@ export function initSettingsTypo(ctx) {
|
|
|
120
120
|
find: (sel) => ctx.$(sel),
|
|
121
121
|
create: (tag) => list.ownerDocument.createElement(tag),
|
|
122
122
|
});
|
|
123
|
-
function setFont(k, announce = false) {
|
|
123
|
+
function setFont(k, announce = false) { choose(k, announce, true); }
|
|
124
|
+
function choose(k, announce, persist) {
|
|
124
125
|
const it = FONT_BY_KEY[k];
|
|
125
126
|
// The SAME function as the other two readings: a face the list shows clickable has to be accepted here, and one it
|
|
126
127
|
// shows grey has to be refused. Three answers to the same question drift.
|
|
127
128
|
if (!it || !faceAvailable(it, ctx.fontInstalled))
|
|
128
129
|
return;
|
|
129
130
|
fontKey = k;
|
|
130
|
-
|
|
131
|
+
if (persist)
|
|
132
|
+
persistFontKey(ctx.store, k);
|
|
131
133
|
const target = fontCssTarget(k, it);
|
|
132
134
|
ctx.root.dataset.fonte = target.font;
|
|
133
135
|
/*
|
|
@@ -151,7 +153,7 @@ export function initSettingsTypo(ctx) {
|
|
|
151
153
|
ctx.root.style.setProperty('--fonte-escala', String(faceScale(it)));
|
|
152
154
|
const pv = ctx.$('#typo-preview');
|
|
153
155
|
if (pv)
|
|
154
|
-
pv.style.fontFamily =
|
|
156
|
+
pv.style.fontFamily = familyStack(it.fam);
|
|
155
157
|
if (announce)
|
|
156
158
|
ctx.srSay(t('sr.typo.font', { fam: it.fam }));
|
|
157
159
|
}
|
|
@@ -181,7 +183,7 @@ export function initSettingsTypo(ctx) {
|
|
|
181
183
|
const cur = FONT_BY_KEY[fontKey];
|
|
182
184
|
const pv = ctx.$('#typo-preview');
|
|
183
185
|
if (pv && cur)
|
|
184
|
-
pv.style.fontFamily =
|
|
186
|
+
pv.style.fontFamily = familyStack(cur.fam);
|
|
185
187
|
refreshMarks();
|
|
186
188
|
// THE LAST THING IN RENDER, and it has to be: the rows were just relabelled with the prose inside them.
|
|
187
189
|
ctx.fillExplain?.(ctx.$('#typo .overlay__card'));
|
|
@@ -216,6 +218,13 @@ export function initSettingsTypo(ctx) {
|
|
|
216
218
|
render();
|
|
217
219
|
ctx.srSay(t('sr.typo.reset', { fam: FONT_BY_KEY[DEFAULT_FONT_KEY].fam }));
|
|
218
220
|
});
|
|
219
|
-
|
|
221
|
+
/*
|
|
222
|
+
* Applies the persisted font at boot. 📌 A stored face THIS page does not have — a library family its game did not declare
|
|
223
|
+
* (ADR-0255) — is drawn as the default and NOT written over: the choice stays stored for a game that declares the family, and
|
|
224
|
+
* `getFontKey` answers the face really drawn instead of one the page cannot draw.
|
|
225
|
+
*/
|
|
226
|
+
const stored = FONT_BY_KEY[fontKey];
|
|
227
|
+
const drawable = !!stored && faceAvailable(stored, ctx.fontInstalled);
|
|
228
|
+
choose(drawable ? fontKey : DEFAULT_FONT_KEY, false, drawable);
|
|
220
229
|
return { render, setFont, getFontKey: () => fontKey };
|
|
221
230
|
}
|
|
@@ -14,8 +14,8 @@ import { DEFAULTS } from '../core/setting-defaults.js';
|
|
|
14
14
|
* `tests/settings-visual.node.test.js` imports exactly those names, and the node project mounts no document — so whoever
|
|
15
15
|
* wrote those cases had to know where this panel stops being a panel.
|
|
16
16
|
*
|
|
17
|
-
* ⚠️ NO ALIAS: a re-export would keep alive a path nothing in here uses
|
|
18
|
-
*
|
|
17
|
+
* ⚠️ NO ALIAS: a re-export would keep alive a published path nothing in here uses — surface with no consumer
|
|
18
|
+
* (issue #204).
|
|
19
19
|
*/
|
|
20
20
|
import { ROLE_KEYS, ROLE_LABELS, LQ_STEPS, lqLabel, lqPosition, clampSelectedPlayer, rgbToHex, onOffLabel, resolveVisualMode, VISUAL_MODES, } from './visual-choices.js';
|
|
21
21
|
// The default of the TWO AXES (ADR-0076/#104). The mark asks the new model, not the p.viz mirror.
|
package/dist-pkg/ui/shell.d.ts
CHANGED
|
@@ -3,8 +3,6 @@ import type { Translate } from '../core/i18n.js';
|
|
|
3
3
|
import type { DomQuery } from '../core/dom-query.js';
|
|
4
4
|
import type { PadMap } from '../input/pad-reading.js';
|
|
5
5
|
import type { SceneFacts } from '../core/scenes.js';
|
|
6
|
-
/** ui/dom.ts `$` — injected so a node test can pass a fake DOM. */
|
|
7
|
-
export type { DomQuery } from '../core/dom-query.js';
|
|
8
6
|
/** The part of `Window` that `printMode` uses (adding and removing a listener in CAPTURE, and the 80 ms delay). */
|
|
9
7
|
export interface ShellWindow {
|
|
10
8
|
addEventListener(type: string, fn: (e: Event) => void, capture: boolean): void;
|
|
@@ -28,7 +26,6 @@ export type PhaseFocus = 'game-region' | 'pause-menu' | 'title-button';
|
|
|
28
26
|
* What the scene on top asks of the document — a projection of the scene facts, with no field depending on history (the
|
|
29
27
|
* one that would, `#touch-controls`, lives in `touchControlsPlan`, apart on purpose).
|
|
30
28
|
*/
|
|
31
|
-
export type { SceneFacts } from '../core/scenes.js';
|
|
32
29
|
export interface PhaseView {
|
|
33
30
|
/** `#title-overlay`.hidden — the splash only shows on the title. */
|
|
34
31
|
titleOverlayHidden: boolean;
|
|
@@ -226,3 +223,4 @@ export interface ShellApi {
|
|
|
226
223
|
pauseActs: PauseActs;
|
|
227
224
|
}
|
|
228
225
|
export declare function initShell(ctx: ShellCtx): ShellApi;
|
|
226
|
+
export {};
|
package/dist-pkg/ui/shell.js
CHANGED
|
@@ -31,6 +31,7 @@ import { PAD_DESIGNS, PAD_GLYPH_SPOKEN } from '../input/devices.js'; // a DATA l
|
|
|
31
31
|
// ONE constant, not a repeated selector: the pause card has more than one list (ADR-0044 item 5), and whoever scans raw
|
|
32
32
|
// `.pm-btn` also sees the hidden ones.
|
|
33
33
|
import { PM_VISIBLE_ITEMS } from './pause-icons.js';
|
|
34
|
+
import { keepInView } from './menu-items.js';
|
|
34
35
|
// `SceneFacts` lives in `core/scenes`, beside the stack that produces them — it is an ENGINE type.
|
|
35
36
|
/** Every question the scene change asks of the scene, asked at once. */
|
|
36
37
|
export function phaseView(f) {
|
|
@@ -209,8 +210,10 @@ export function initShell(ctx) {
|
|
|
209
210
|
ctx.getPauseScreens().forEach((sp) => {
|
|
210
211
|
const items = [...sp.querySelectorAll(PM_VISIBLE_ITEMS)];
|
|
211
212
|
items.forEach((b) => b.classList.remove('pm-sel'));
|
|
212
|
-
if (items[0])
|
|
213
|
-
items[0].classList.add('pm-sel');
|
|
213
|
+
if (items[0]) {
|
|
214
|
+
items[0].classList.add('pm-sel');
|
|
215
|
+
keepInView(items[0]);
|
|
216
|
+
} // the 1st item (Continue), and in view (issue #134)
|
|
214
217
|
});
|
|
215
218
|
}
|
|
216
219
|
function printMode() {
|
|
@@ -319,8 +322,9 @@ export function initShell(ctx) {
|
|
|
319
322
|
// acted (pauseActor) — the panel opens on their tab.
|
|
320
323
|
const pauseActs = {
|
|
321
324
|
resume: () => ctx.resumeGame(),
|
|
322
|
-
// The door to the Augmentative and Alternative Communication menu (ADR-0028)
|
|
323
|
-
//
|
|
325
|
+
// The door to the Augmentative and Alternative Communication menu (ADR-0028). DISABLED while no pictogram set is
|
|
326
|
+
// licensed (ADR-0233 erratum): `ui/pause-icons` locks the `caa` item and `ui/settings-aac`'s `open` refuses, both
|
|
327
|
+
// saying only «menu disabled».
|
|
324
328
|
caa: () => ctx.openAac(),
|
|
325
329
|
nivel: () => ctx.setQuizLevel(ctx.getQuizLevel() % 5 + 1, true), // cycles 1..5
|
|
326
330
|
tipo: () => ctx.openTypo(),
|
package/dist-pkg/ui/title.d.ts
CHANGED
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
2
|
import type { DomQuery } from '../core/dom-query.js';
|
|
3
|
-
/** Minimal DOM-selector shape (matches ui/dom.ts's `$`). */
|
|
4
|
-
export type { DomQuery } from '../core/dom-query.js';
|
|
5
3
|
export type TitleMenuId = 'tm-main' | 'tm-alf' | 'tm-mat' | 'tm-tab' | 'tm-fr' | 'tm-cen';
|
|
6
|
-
/**
|
|
7
|
-
* The 6 submenus of the title screen, in the order they are hidden/shown.
|
|
8
|
-
*
|
|
9
|
-
* The ORDERED array is the source and the Set is derived from it, not the other way round. A Set carries no
|
|
10
|
-
* order in its type, so a reader that has to scan the submenus in order to find the visible one would otherwise
|
|
11
|
-
* declare its own array of the same six ids, kept in step by discipline alone. One list.
|
|
12
|
-
*/
|
|
13
|
-
export declare const TITLE_MENU_IDS_ORDERED: readonly TitleMenuId[];
|
|
14
4
|
export declare const TITLE_MENU_IDS: ReadonlySet<TitleMenuId>;
|
|
15
5
|
export declare function isTitleMenuId(v: string): v is TitleMenuId;
|
|
16
6
|
export interface TitleCtx {
|
|
@@ -18,7 +8,8 @@ export interface TitleCtx {
|
|
|
18
8
|
$: DomQuery;
|
|
19
9
|
}
|
|
20
10
|
export interface TitleApi {
|
|
21
|
-
/** Shows `which` and hides the other 5 submenus; toggles legend/title-block
|
|
11
|
+
/** Shows `which` and hides the other 5 submenus; toggles legend/title-block. Focus: going IN, the first button; coming
|
|
12
|
+
* BACK to a menu left on the way in, the item that opened the next one (ADR-0130 rule 1). */
|
|
22
13
|
show: (which: TitleMenuId) => void;
|
|
23
14
|
}
|
|
24
15
|
export interface TitleMenuView {
|
package/dist-pkg/ui/title.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
2
|
// ui/title — title-screen submenu NAVIGATION. Shows one submenu (`tm-main`/`tm-alf`/`tm-mat`/`tm-tab`/`tm-fr`/`tm-cen`)
|
|
3
3
|
// and hides the rest, toggles the footer legend (only on `tm-main`) and the game-title block (only on `tm-main` —
|
|
4
|
-
// submenus show their own `.tm-title` instead), then focuses the first button of the now-visible submenu
|
|
4
|
+
// submenus show their own `.tm-title` instead), then focuses the first button of the now-visible submenu — or, coming
|
|
5
|
+
// back to a menu left on the way in, the item that opened the next one (ADR-0130 rule 1). DI via
|
|
5
6
|
// initTitle(ctx): only `$` (DOM selector, ui/dom.ts shape) is needed — the transition carries no message of its own
|
|
6
7
|
// (the caller picks what to announce per transition; announcing here too would double-speak). Building the submenu
|
|
7
8
|
// markup, the footer legend, arrow-key traversal and the click/keydown wiring belong to the game that owns the title
|
|
@@ -13,7 +14,7 @@
|
|
|
13
14
|
* order in its type, so a reader that has to scan the submenus in order to find the visible one would otherwise
|
|
14
15
|
* declare its own array of the same six ids, kept in step by discipline alone. One list.
|
|
15
16
|
*/
|
|
16
|
-
|
|
17
|
+
const TITLE_MENU_IDS_ORDERED = [
|
|
17
18
|
'tm-main', 'tm-alf', 'tm-mat', 'tm-tab', 'tm-fr', 'tm-cen',
|
|
18
19
|
];
|
|
19
20
|
export const TITLE_MENU_IDS = new Set(TITLE_MENU_IDS_ORDERED);
|
|
@@ -32,11 +33,41 @@ export function computeTitleMenuView(which) {
|
|
|
32
33
|
titleBlockDisplay: which === 'tm-main' ? '' : 'none',
|
|
33
34
|
};
|
|
34
35
|
}
|
|
35
|
-
// ---------------------------------------------------------------------------------------------
|
|
36
|
-
// DOM-facing (thin) — requires `document`/injected ctx
|
|
37
|
-
// ---------------------------------------------------------------------------------------------
|
|
38
36
|
export function initTitle(ctx) {
|
|
37
|
+
/*
|
|
38
|
+
* THE WAY IN, so the way out lands where the child was (ADR-0130 rule 1). `show` stays a «goto» — a game calls
|
|
39
|
+
* `show('tm-main')` for its «Voltar» and nothing else — and the trail tells the two apart: a menu already on the trail is
|
|
40
|
+
* a way BACK, which pops to it and returns the cursor to the item that opened the next menu; any other is a way IN,
|
|
41
|
+
* which records the item that opened it. The menus stay one at a time on screen: whether the cards behind stay visible
|
|
42
|
+
* is left open by the record.
|
|
43
|
+
*/
|
|
44
|
+
const trail = [];
|
|
45
|
+
/** The menu on screen now, and the item inside it that has focus — the opener, if the next `show` goes in. */
|
|
46
|
+
function where() {
|
|
47
|
+
for (const id of TITLE_MENU_IDS_ORDERED) {
|
|
48
|
+
const el = ctx.$('#' + id);
|
|
49
|
+
if (!el || el.hidden)
|
|
50
|
+
continue;
|
|
51
|
+
const focused = el.ownerDocument.activeElement;
|
|
52
|
+
return { menu: id, opener: focused && focused !== el && el.contains(focused) ? focused : null };
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
/** Where the cursor lands: the recorded opener when coming back to a menu on the trail, else `null` (item 1). */
|
|
57
|
+
function walk(which) {
|
|
58
|
+
const back = trail.findIndex((step) => step.menu === which);
|
|
59
|
+
if (back >= 0) {
|
|
60
|
+
const { opener } = trail[back];
|
|
61
|
+
trail.length = back;
|
|
62
|
+
return opener;
|
|
63
|
+
}
|
|
64
|
+
const here = where();
|
|
65
|
+
if (here && here.menu !== which)
|
|
66
|
+
trail.push(here);
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
39
69
|
function show(which) {
|
|
70
|
+
const opener = walk(which);
|
|
40
71
|
const view = computeTitleMenuView(which);
|
|
41
72
|
for (const [id, hide] of view.hidden) {
|
|
42
73
|
const el = ctx.$('#' + id);
|
|
@@ -50,7 +81,9 @@ export function initTitle(ctx) {
|
|
|
50
81
|
if (tb)
|
|
51
82
|
tb.style.display = view.titleBlockDisplay;
|
|
52
83
|
const activeEl = ctx.$('#' + which);
|
|
53
|
-
|
|
84
|
+
// the opener only while it is still an item of this menu: a game may have rebuilt the menu since
|
|
85
|
+
const cameFrom = opener && activeEl?.contains(opener) ? opener : null;
|
|
86
|
+
const b = cameFrom ?? (activeEl && activeEl.querySelector('button'));
|
|
54
87
|
if (b)
|
|
55
88
|
b.focus();
|
|
56
89
|
}
|
|
@@ -6,16 +6,18 @@ export interface TopBandCtx {
|
|
|
6
6
|
/** The accessibility bar. ⚠️ Absent = a ZERO band: there is nothing to reserve, and reserving anyway would take the
|
|
7
7
|
* first line of the screen from the game — 12% of the height at 640×360. */
|
|
8
8
|
readonly bar: HTMLElement | null;
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* The HUD column that sits at the TOP, when mounted: the mission's, centred under the bar (ADR-0239 erratum). The rest of
|
|
11
|
+
* the HUD is a row at the bottom (`ui/hud-row`), and counting it here would give the game's top to the bottom row.
|
|
12
|
+
*/
|
|
10
13
|
readonly hud: {
|
|
11
14
|
readonly left: HTMLElement;
|
|
12
|
-
readonly right: HTMLElement;
|
|
13
15
|
} | null;
|
|
14
16
|
/** `getComputedStyle`, injected. Absent in a document that lacks it, and then the name line is not measured. */
|
|
15
17
|
readonly computedStyle?: (el: HTMLElement) => CSSStyleDeclaration;
|
|
16
18
|
}
|
|
17
19
|
/**
|
|
18
|
-
* Measures the top and writes `--scan-top` and `--barra-a11y-h` on the region.
|
|
20
|
+
* Measures the top and writes `--hud-mission-top`, `--scan-top` and `--barra-a11y-h` on the region.
|
|
19
21
|
*
|
|
20
22
|
* 🔴 THE SCAN CHIP TAKES ROOM FOR THE SAME REASON AS THE NAME LINE (ADR-0218): it is HUD, and HUD that does not reserve its
|
|
21
23
|
* space is the engine writing over the game. But it is PLACED by `--scan-top`, written BEFORE it widens the room; see
|
package/dist-pkg/ui/top-band.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
2
|
// ui/top-band.ts — HOW MUCH SPACE THE ENGINE KEEPS FOR ITSELF AT THE TOP OF THE SCREEN (ADR-0148 §3; issue #160).
|
|
3
3
|
//
|
|
4
|
-
// The engine draws things over the game — the accessibility bar, the name of the pointed icon, the
|
|
5
|
-
// the scan chip — and the game has to know how much of the top is not its own. This module measures what is there and
|
|
6
|
-
// writes
|
|
4
|
+
// The engine draws things over the game — the accessibility bar, the name of the pointed icon, the HUD's mission line
|
|
5
|
+
// under the bar (the rest of the HUD is a row at the bottom, `ui/hud-row`) and the scan chip — and the game has to know how much of the top is not its own. This module measures what is there and
|
|
6
|
+
// writes three variables on the region: `--barra-a11y-h`, the whole band, `--scan-top`, where the chip sits, and
|
|
7
|
+
// `--hud-mission-top`, where the mission stands under the bar (0 with no bar) — which the stylesheet reads for the bands a
|
|
8
|
+
// caller mounts on the region with no HUD row, since those never pass through here.
|
|
7
9
|
//
|
|
8
10
|
// 📌 It is a calculation, not wiring, which is exactly what a composition root should not hold (Seemann; Fowler): a root
|
|
9
11
|
// is large because it connects many things, not because it decides (ADR-0221).
|
|
@@ -50,31 +52,20 @@ function barRoom(ctx, top) {
|
|
|
50
52
|
return { room: bottom - top + breath, breath };
|
|
51
53
|
}
|
|
52
54
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
55
|
+
* Where the mission sits, and the room it asks for: TOP CENTRE, just under the quick bar (ADR-0239 erratum), a light gap
|
|
56
|
+
* below the bar's own box. 📌 The bar's momentary name line may cover it while a name shows — the Dev's call: «a legenda é
|
|
57
|
+
* momentânea, a escrita da missão aparece o tempo todo» — so the mission is placed by the BAR and not by the name line, and
|
|
58
|
+
* the room below the top counts whichever of the two reaches lower.
|
|
57
59
|
*/
|
|
58
|
-
function hudRoom(ctx, top, breath, room) {
|
|
59
|
-
const { region,
|
|
60
|
-
if (!region || !hud)
|
|
60
|
+
function hudRoom(ctx, top, breath, room, under) {
|
|
61
|
+
const { region, hud } = ctx;
|
|
62
|
+
if (!region || !hud || hud.left.hidden)
|
|
61
63
|
return room;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const gap = Math.max(breath, 4);
|
|
65
|
-
let out = room;
|
|
66
|
-
if (!hud.left.hidden) {
|
|
67
|
-
hud.left.style.maxWidth = barBox ? `${Math.max(0, Math.floor(barBox.left - regionBox.left - 2 * gap))}px` : '';
|
|
68
|
-
out = Math.max(out, hud.left.getBoundingClientRect().bottom - top + gap);
|
|
69
|
-
}
|
|
70
|
-
if (!hud.right.hidden) {
|
|
71
|
-
hud.right.style.maxWidth = barBox ? `${Math.max(0, Math.floor(regionBox.right - barBox.right - 2 * gap))}px` : '';
|
|
72
|
-
out = Math.max(out, hud.right.getBoundingClientRect().bottom - top + gap);
|
|
73
|
-
}
|
|
74
|
-
return out;
|
|
64
|
+
hud.left.style.top = under;
|
|
65
|
+
return Math.max(room, hud.left.getBoundingClientRect().bottom - top + Math.max(breath, 4));
|
|
75
66
|
}
|
|
76
67
|
/**
|
|
77
|
-
* Measures the top and writes `--scan-top` and `--barra-a11y-h` on the region.
|
|
68
|
+
* Measures the top and writes `--hud-mission-top`, `--scan-top` and `--barra-a11y-h` on the region.
|
|
78
69
|
*
|
|
79
70
|
* 🔴 THE SCAN CHIP TAKES ROOM FOR THE SAME REASON AS THE NAME LINE (ADR-0218): it is HUD, and HUD that does not reserve its
|
|
80
71
|
* space is the engine writing over the game. But it is PLACED by `--scan-top`, written BEFORE it widens the room; see
|
|
@@ -91,7 +82,12 @@ export function reserveTopBand(ctx) {
|
|
|
91
82
|
}
|
|
92
83
|
const top = region.getBoundingClientRect().top;
|
|
93
84
|
const { room: barPart, breath } = barRoom(ctx, top);
|
|
94
|
-
|
|
85
|
+
// the mission's place: just under the bar's own box, by the light gap — also for bands a caller mounts on the region with no
|
|
86
|
+
// row, which the stylesheet places by `--hud-mission-top`; with no bar there is nothing to stand under, and '' removes it
|
|
87
|
+
const barBox = ctx.bar && typeof ctx.bar.getBoundingClientRect === 'function' ? ctx.bar.getBoundingClientRect() : null;
|
|
88
|
+
const under = barBox ? `${Math.ceil(barBox.bottom - top + Math.max(breath, 4))}px` : '';
|
|
89
|
+
region.style.setProperty('--hud-mission-top', under);
|
|
90
|
+
let room = hudRoom(ctx, top, breath, barPart, under);
|
|
95
91
|
region.style.setProperty('--scan-top', `${Math.ceil(Math.max(0, room - breath))}px`);
|
|
96
92
|
const chip = region.querySelector('.scan-now');
|
|
97
93
|
if (chip && !chip.hidden)
|
|
@@ -39,7 +39,7 @@ export interface TypoRow {
|
|
|
39
39
|
fam: string;
|
|
40
40
|
selected: boolean;
|
|
41
41
|
disabled: boolean;
|
|
42
|
-
/** Description (+ "— <off reason>" when disabled), or '' when there is none. */
|
|
42
|
+
/** Description (+ "— <notice>") (+ "— <off reason>" when disabled), or '' when there is none. */
|
|
43
43
|
note: string;
|
|
44
44
|
}
|
|
45
45
|
export interface TypoGroupView {
|
|
@@ -50,8 +50,8 @@ export interface TypoGroupView {
|
|
|
50
50
|
* ONE row of the list, from a catalogue face. A function of its own so the gate of the `.off` mechanism can exercise it
|
|
51
51
|
* with a FAKE face: a case that depends on the catalogue's composition fails every time the roster changes.
|
|
52
52
|
*
|
|
53
|
-
* The
|
|
54
|
-
*
|
|
53
|
+
* The note is up to three halves: the description, the `notice` that always speaks (the ronde's three faces to install,
|
|
54
|
+
* ADR-0154), and the `off` reason while the face is disabled.
|
|
55
55
|
*/
|
|
56
56
|
export declare function fontRow(t: Translate, it: FontItem, fontKey: string, installed?: (family: string) => boolean): TypoRow;
|
|
57
57
|
/** Pure view-model for the typography list: which row is selected/disabled and its note, per catalog group. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
import { FONT_GROUPS, FONT_BY_KEY, fontRole, faceAvailable } from './fonts.js';
|
|
2
|
+
import { FONT_GROUPS, FONT_BY_KEY, fontRole, faceAvailable, familyStack } from './fonts.js';
|
|
3
3
|
/**
|
|
4
4
|
* A key is selectable when it exists in the catalog, is not marked `.off` (licence pending, etc.) — and is
|
|
5
5
|
* `geral`.
|
|
@@ -29,24 +29,25 @@ export function fontCssTarget(k, it) {
|
|
|
29
29
|
// `joined` is the word the field's own documentation uses — "is this a JOINED face?".
|
|
30
30
|
const joined = it.fb === 'cursive';
|
|
31
31
|
const suffix = it.fb === 'serif' ? ',Georgia,serif' : joined ? ',cursive' : '';
|
|
32
|
-
|
|
32
|
+
// Each family quoted on its own (`familyStack`): the ronde's stack must reach Cookie, its packaged fallback (ADR-0154).
|
|
33
|
+
return { font: 'custom', customFamily: `${familyStack(it.fam)}${suffix}`, cursive: joined };
|
|
33
34
|
}
|
|
34
35
|
/**
|
|
35
36
|
* ONE row of the list, from a catalogue face. A function of its own so the gate of the `.off` mechanism can exercise it
|
|
36
37
|
* with a FAKE face: a case that depends on the catalogue's composition fails every time the roster changes.
|
|
37
38
|
*
|
|
38
|
-
* The
|
|
39
|
-
*
|
|
39
|
+
* The note is up to three halves: the description, the `notice` that always speaks (the ronde's three faces to install,
|
|
40
|
+
* ADR-0154), and the `off` reason while the face is disabled.
|
|
40
41
|
*/
|
|
41
42
|
export function fontRow(t, it, fontKey, installed) {
|
|
42
43
|
// ⚠️ THE SAME question `isSelectableFont` asks, through the SAME function. Two answers would give a clickable row the
|
|
43
44
|
// click refuses — or, worse, a grey row that `resolveFontKey` accepts by another path. "Not available" and "cannot be
|
|
44
45
|
// chosen" have to be the same statement.
|
|
45
46
|
const disabled = !faceAvailable(it, installed);
|
|
46
|
-
// `d` and `off` hold KEYS too. The dash joining them is punctuation, not a sentence — the
|
|
47
|
-
// and each translates on its own.
|
|
48
|
-
const
|
|
49
|
-
|
|
47
|
+
// `d`, `notice` and `off` hold KEYS too. The dash joining them is punctuation, not a sentence — the halves are
|
|
48
|
+
// independent and each translates on its own.
|
|
49
|
+
const note = [it.d, it.notice, disabled ? it.off : undefined]
|
|
50
|
+
.filter((k) => !!k).map((k) => t(k)).join(' — ');
|
|
50
51
|
return { key: it.k, fam: it.fam, selected: fontKey === it.k, disabled, note };
|
|
51
52
|
}
|
|
52
53
|
/** Pure view-model for the typography list: which row is selected/disabled and its note, per catalog group. */
|
package/dist-pkg/ui/vlibras.d.ts
CHANGED
|
@@ -1,34 +1,78 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
2
|
import type { Translate } from '../core/i18n.js';
|
|
3
3
|
import type { Store } from '../platform/storage.js';
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
readonly
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
readonly
|
|
14
|
-
|
|
15
|
-
|
|
4
|
+
/**
|
|
5
|
+
* What a sign request comes back with: signed — and, when part of the text was left out, what and why (`unsigned`) — or why
|
|
6
|
+
* not. The reason and the part left out go into `problems`.
|
|
7
|
+
*/
|
|
8
|
+
export type SignResult = {
|
|
9
|
+
readonly signed: true;
|
|
10
|
+
readonly unsigned?: string;
|
|
11
|
+
} | {
|
|
12
|
+
readonly signed: false;
|
|
13
|
+
readonly reason: string;
|
|
14
|
+
};
|
|
15
|
+
/** A player of Libras: whatever signs, or a test's double. */
|
|
16
|
+
export interface Interpreter {
|
|
17
|
+
/** Signs exactly this text, in front of the screen; resolves with whether it could. */
|
|
18
|
+
readonly sign: (text: string) => Promise<SignResult>;
|
|
19
|
+
/** Takes the interpreter off the screen: deaf mode was turned off. */
|
|
20
|
+
readonly hide: () => void;
|
|
21
|
+
/** Releases the player: its root is gone. */
|
|
22
|
+
readonly dispose: () => void;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Why a delivery that carries no Libras player cannot sign, and the fix — the ONE reason both `NO_INTERPRETER` and the free
|
|
26
|
+
* player give for it, so `problems` says the same thing whichever of them answered.
|
|
27
|
+
*/
|
|
28
|
+
export declare const LIBRAS_NOT_INSTALLED = "a Libras player is not installed in this delivery \u2014 build it with `inclusionist-heavy <folder> --libras`";
|
|
29
|
+
/** The interpreter of a delivery that carries no Libras player (ADR-0234): it signs nothing and says why, and how to fix it. */
|
|
30
|
+
export declare const NO_INTERPRETER: Interpreter;
|
|
31
|
+
/** Where the person's choice is kept: the page's store, built by the root (ADR-0232, issue #207). */
|
|
32
|
+
export type DeafModeStore = Pick<Store, 'getBool' | 'setBool'>;
|
|
33
|
+
/** What a deaf mode is built over. Every port is the root's. */
|
|
34
|
+
export interface DeafModePorts {
|
|
35
|
+
/** The page's store: the choice is read once, at build, and written at each toggle. */
|
|
36
|
+
readonly store: DeafModeStore;
|
|
37
|
+
/** The child's captions setting, read live: with deaf mode off it alone decides whether a sound is captioned. */
|
|
38
|
+
readonly captionsSetting: () => boolean;
|
|
39
|
+
/** The root's translator: what the child is told comes out in the page's language. */
|
|
40
|
+
readonly t: Translate;
|
|
41
|
+
/** Who signs. */
|
|
42
|
+
readonly interpreter: Interpreter;
|
|
43
|
+
/**
|
|
44
|
+
* The narration: what the sonar's text does with deaf mode off. `seat`, the player who pressed, when the sonar knows it: then
|
|
45
|
+
* the reading takes turns with the other players' (ADR-0234, errata 2026-09-26).
|
|
46
|
+
*/
|
|
47
|
+
readonly speak: (text: string, seat?: number) => void;
|
|
48
|
+
/** The caption host, which writes while deaf mode is on (`Engine.captionSound`). */
|
|
49
|
+
readonly caption: (text: string) => void;
|
|
50
|
+
/** The announcer: what the child is told about the interpreter. */
|
|
51
|
+
readonly tell: (text: string) => void;
|
|
52
|
+
/** A line of `problems`; each distinct line is reported once. */
|
|
53
|
+
readonly report: (line: string) => void;
|
|
16
54
|
}
|
|
17
55
|
/** One root's deaf mode. */
|
|
18
|
-
export interface
|
|
19
|
-
/** Is deaf mode on?
|
|
20
|
-
readonly
|
|
21
|
-
/** Turns deaf mode on
|
|
22
|
-
readonly toggle: (
|
|
23
|
-
/**
|
|
24
|
-
readonly
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
|
|
56
|
+
export interface DeafMode {
|
|
57
|
+
/** Is deaf mode on? The person's choice — never a player's state. */
|
|
58
|
+
readonly isOn: () => boolean;
|
|
59
|
+
/** Turns deaf mode on or off. It always flips: the state is ours. Off, the interpreter leaves the screen. */
|
|
60
|
+
readonly toggle: () => void;
|
|
61
|
+
/** Does a sound get its caption now? Deaf mode on, or the captions setting on — every sound is captioned in deaf mode. */
|
|
62
|
+
readonly captionsOn: () => boolean;
|
|
63
|
+
/**
|
|
64
|
+
* What the sonar found: captioned and handed to the interpreter with deaf mode on, spoken with it off — by `seat`'s turn, when
|
|
65
|
+
* the player who pressed is known (`speak`).
|
|
66
|
+
*/
|
|
67
|
+
readonly sonar: (text: string, seat?: number) => void;
|
|
68
|
+
/** Runs `fn` when the mode turns on or off (a host's reflow); returns its release. */
|
|
28
69
|
readonly onChange: (fn: () => void) => () => void;
|
|
70
|
+
/** Releases the interpreter; an answer still on its way is dropped. */
|
|
71
|
+
readonly dispose: () => void;
|
|
29
72
|
}
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
73
|
+
/** The line `problems` gets when the interpreter cannot sign: the subject, the child's cost and the fix (ADR-0169). */
|
|
74
|
+
export declare function signingUnavailableLine(reason: string): string;
|
|
75
|
+
/** The line `problems` gets when the interpreter signed a text but left part of it out: what, the child's cost, the fix. */
|
|
76
|
+
export declare function signedInPartLine(unsigned: string): string;
|
|
77
|
+
/** Builds a deaf mode. The stored choice is read here, at build, never at import (ADR-0232). */
|
|
78
|
+
export declare function createDeafMode({ store, captionsSetting, t, interpreter, speak, caption, tell, report }: DeafModePorts): DeafMode;
|